git: 5a7a7bbc47d3 - main - devel/cbang: adding C!, a library of cross-platform C++ utilities

From: Thierry Thomas <thierry_at_FreeBSD.org>
Date: Sun, 08 May 2022 15:58:59 UTC
The branch main has been updated by thierry:

URL: https://cgit.FreeBSD.org/ports/commit/?id=5a7a7bbc47d30559fa28b7665a49a4256befad49

commit 5a7a7bbc47d30559fa28b7665a49a4256befad49
Author:     Thierry Thomas <thierry@FreeBSD.org>
AuthorDate: 2022-05-08 15:55:52 +0000
Commit:     Thierry Thomas <thierry@FreeBSD.org>
CommitDate: 2022-05-08 15:58:31 +0000

    devel/cbang: adding C!, a library of cross-platform C++ utilities
    
    This is a prerequisite to port CAMotics.
    
    PR:             262763
---
 devel/Makefile                                     |   1 +
 devel/cbang/Makefile                               |  66 ++++
 devel/cbang/distinfo                               |   3 +
 .../cbang/files/patch-config_cbang_____init____.py |  10 +
 .../files/patch-config_compiler_____init____.py    |  11 +
 .../cbang/files/patch-src_cbang_js_v8_Context.cpp  |  15 +
 .../cbang/files/patch-src_cbang_net_IPAddress.cpp  |  12 +
 devel/cbang/files/patch-src_cbang_net_Swab.h       |  14 +
 .../cbang/files/patch-src_cbang_os_SystemInfo.cpp  |  34 ++
 devel/cbang/files/patch-tests_testHarness          | 375 +++++++++++++++++++
 devel/cbang/pkg-descr                              |   7 +
 devel/cbang/pkg-plist                              | 398 +++++++++++++++++++++
 12 files changed, 946 insertions(+)

diff --git a/devel/Makefile b/devel/Makefile
index 3e4ade2f1701..99dead5bba2d 100644
--- a/devel/Makefile
+++ b/devel/Makefile
@@ -316,6 +316,7 @@
     SUBDIR += cargo-generate
     SUBDIR += cask
     SUBDIR += catch
+    SUBDIR += cbang
     SUBDIR += cbrowser
     SUBDIR += cc65
     SUBDIR += ccache
diff --git a/devel/cbang/Makefile b/devel/cbang/Makefile
new file mode 100644
index 000000000000..1a19fcee7d9f
--- /dev/null
+++ b/devel/cbang/Makefile
@@ -0,0 +1,66 @@
+# Created by: thierry@pompo.net
+
+PORTNAME=	cbang
+PORTVERSION=	1.6.1
+CATEGORIES=	devel
+
+MAINTAINER=	thierry@FreeBSD.org
+COMMENT=	C! (cbang) is a library of cross-platform C++ utilities
+
+LICENSE=	LGPL21
+
+BUILD_DEPENDS=	boost-libs>0:devel/boost-libs
+LIB_DEPENDS=	libv8.so:lang/v8		\
+		libre2.so:devel/re2		\
+		liblz4.so:archivers/liblz4	\
+		libevent.so:devel/libevent	\
+		libexpat.so:textproc/expat2	\
+		libyaml.so:textproc/libyaml	\
+		libsnappy.so:archivers/snappy	\
+		libsysinfo.so:devel/libsysinfo	\
+		libleveldb.so:databases/leveldb
+
+USE_GITHUB=	yes
+GH_ACCOUNT=	CauldronDevelopmentLLC
+
+USES=		compiler:c++14-lang localbase mysql:client python:test scons	\
+		sqlite ssl
+USE_LDCONFIG=	yes
+
+OPTIONS_DEFINE=		DEBUG DOCS
+DEBUG_BUILD_DEPENDS=	gnulibiberty>0:devel/gnulibiberty
+DEBUG_LIB_DEPENDS=	libbfd.so:devel/libbfd
+
+MAKE_ARGS+=	cc="${CC}"	\
+		cxx="${CXX}"	\
+		cxxstd="c++14"	\
+		ccflags="${CCFLAGS}"	\
+		cxxflags="${CXXFLAGS}"	\
+		libpath="${LIBPATH}"	\
+		sharedlib=1	\
+		prefix="${STAGEDIR}${PREFIX}"	\
+		compiler="${CHOSEN_COMPILER_TYPE:C/gcc/gnu/}"	\
+		disable_local="zlib bzip2 lz4 sqlite3 expat libevent re2 libyaml"
+# With boost in disable_local, libcbang-boost.a is not built
+#		disable_local="zlib bzip2 lz4 sqlite3 expat boost libevent re2 libyaml"
+MAKE_ENV+=	LIBPATH="${LIBPATH}"	\
+		LIBRARY_PATH="${LIBPATH}:${LIBPATH}/mysql"
+LIBVER=		1.3.3
+PLIST_SUB=	VER=${LIBVER}
+
+TEST_WRKSRC=	${WRKSRC}/tests
+DO_MAKE_TEST=	${SETENV} ${TEST_ENV} ${MAKE_CMD} ${MAKE_FLAGS} ${MAKEFILE} ${TEST_ARGS}
+
+pre-configure:
+	${REINPLACE_CMD} -e 's|%%PYTHON_CMD%%|${PYTHON_CMD}|'	\
+		${TEST_WRKSRC}/testHarness
+
+post-install:
+	cd ${STAGEDIR}${PREFIX}/lib &&	\
+		${LN} -sf libcbang0.so.${LIBVER} libcbang0.so	&&	\
+		${LN} -sf libcbang0.so.${LIBVER} libcbang0.so.1
+
+do-test:
+	(cd ${TEST_WRKSRC} && ${DO_MAKE_TEST} && ./testHarness)
+
+.include <bsd.port.mk>
diff --git a/devel/cbang/distinfo b/devel/cbang/distinfo
new file mode 100644
index 000000000000..f8b754e16ab4
--- /dev/null
+++ b/devel/cbang/distinfo
@@ -0,0 +1,3 @@
+TIMESTAMP = 1651868853
+SHA256 (CauldronDevelopmentLLC-cbang-1.6.1_GH0.tar.gz) = c59f54cd15fc8aaea09aa6c4a9f69995ed7cbfe179a50a179a162e501516c8a5
+SIZE (CauldronDevelopmentLLC-cbang-1.6.1_GH0.tar.gz) = 4789245
diff --git a/devel/cbang/files/patch-config_cbang_____init____.py b/devel/cbang/files/patch-config_cbang_____init____.py
new file mode 100644
index 000000000000..1079051ff3cb
--- /dev/null
+++ b/devel/cbang/files/patch-config_cbang_____init____.py
@@ -0,0 +1,10 @@
+--- config/cbang/__init__.py.orig	2021-08-10 22:46:49 UTC
++++ config/cbang/__init__.py
+@@ -99,6 +99,7 @@ def configure(conf):
+ 
+     conf.CBRequireLib('cbang-boost')
+     conf.CBRequireLib('cbang')
++    conf.CBRequireLib('sysinfo')
+     conf.CBRequireCXXHeader('cbang/Exception.h')
+     env.CBDefine('HAVE_CBANG')
+ 
diff --git a/devel/cbang/files/patch-config_compiler_____init____.py b/devel/cbang/files/patch-config_compiler_____init____.py
new file mode 100644
index 000000000000..5acf518338de
--- /dev/null
+++ b/devel/cbang/files/patch-config_compiler_____init____.py
@@ -0,0 +1,11 @@
+--- config/compiler/__init__.py.orig	2021-08-10 22:46:49 UTC
++++ config/compiler/__init__.py
+@@ -308,7 +308,7 @@ def configure(conf, cstd = 'c99'):
+     # Optimizations
+     if optimize:
+         if compiler_mode == 'gnu':
+-            env.AppendUnique(CCFLAGS = ['-O3', '-funroll-loops'])
++            env.AppendUnique(CCFLAGS = ['-funroll-loops'])
+ 
+         elif compiler_mode == 'msvc':
+             env.AppendUnique(CCFLAGS = ['/O2', '/Zc:throwingNew'])
diff --git a/devel/cbang/files/patch-src_cbang_js_v8_Context.cpp b/devel/cbang/files/patch-src_cbang_js_v8_Context.cpp
new file mode 100644
index 000000000000..01f0bf8823b3
--- /dev/null
+++ b/devel/cbang/files/patch-src_cbang_js_v8_Context.cpp
@@ -0,0 +1,15 @@
+--- src/cbang/js/v8/Context.cpp.orig	2021-08-10 22:46:49 UTC
++++ src/cbang/js/v8/Context.cpp
+@@ -50,7 +50,12 @@ Value Context::eval(const InputSource &src) {
+   v8::Local<v8::String> origin;
+   string filename = src.getName();
+   if (!filename.empty()) origin = Value::createString(filename);
++
++#if V8_MAJOR_VERSION < 10
+   v8::ScriptOrigin sOrigin(origin);
++#else
++  v8::ScriptOrigin sOrigin(Value::getIso(), origin);
++#endif
+ 
+   // Get script source
+   auto source = Value::createString(src.toString());
diff --git a/devel/cbang/files/patch-src_cbang_net_IPAddress.cpp b/devel/cbang/files/patch-src_cbang_net_IPAddress.cpp
new file mode 100644
index 000000000000..ab1d9c8d52fb
--- /dev/null
+++ b/devel/cbang/files/patch-src_cbang_net_IPAddress.cpp
@@ -0,0 +1,12 @@
+--- src/cbang/net/IPAddress.cpp.orig	2021-08-10 22:46:49 UTC
++++ src/cbang/net/IPAddress.cpp
+@@ -50,6 +50,9 @@
+ #else
+ #include <sys/types.h>
+ #include <sys/socket.h>
++#  ifdef __FreeBSD__
++#include <netinet/in.h>
++#  endif
+ #include <netdb.h>
+ #endif
+ 
diff --git a/devel/cbang/files/patch-src_cbang_net_Swab.h b/devel/cbang/files/patch-src_cbang_net_Swab.h
new file mode 100644
index 000000000000..0c35b3f259de
--- /dev/null
+++ b/devel/cbang/files/patch-src_cbang_net_Swab.h
@@ -0,0 +1,14 @@
+--- src/cbang/net/Swab.h.orig	2021-08-10 22:46:49 UTC
++++ src/cbang/net/Swab.h
+@@ -42,7 +42,10 @@
+ #elif __APPLE__
+ #include <machine/endian.h>
+ 
+-#else // POSIX systems
++#elif __FreeBSD__
++#include <sys/endian.h>
++
++#else // other POSIX systems
+ #include <endian.h>
+ #endif
+ 
diff --git a/devel/cbang/files/patch-src_cbang_os_SystemInfo.cpp b/devel/cbang/files/patch-src_cbang_os_SystemInfo.cpp
new file mode 100644
index 000000000000..f2519cae29f0
--- /dev/null
+++ b/devel/cbang/files/patch-src_cbang_os_SystemInfo.cpp
@@ -0,0 +1,34 @@
+--- src/cbang/os/SystemInfo.cpp.orig	2021-08-10 22:46:49 UTC
++++ src/cbang/os/SystemInfo.cpp
+@@ -64,6 +64,13 @@
+ 
+ #include "MacOSUtilities.h"
+ 
++#elif defined(__FreeBSD__)
++#include <sys/sysinfo.h>
++#include <sys/utsname.h>
++#include <sys/sysctl.h>
++#include <sys/ucred.h>
++#include <unistd.h>
++
+ #else // !_MSC_VER && !__APPLE__
+ #include <sys/sysinfo.h>
+ #include <sys/utsname.h>
+@@ -90,7 +97,7 @@ uint32_t SystemInfo::getCPUCount() const {
+   GetSystemInfo(&sysinfo);
+   return sysinfo.dwNumberOfProcessors;
+ 
+-#elif defined(__APPLE__) || defined(__FreeBSD__)
++#elif defined(__APPLE__)
+   int nm[2];
+   size_t length = 4;
+   uint32_t count;
+@@ -127,7 +134,7 @@ uint64_t SystemInfo::getMemoryInfo(memory_info_t type)
+     return (uint64_t)(info.ullAvailPhys + info.ullAvailPageFile);
+   }
+ 
+-#elif defined(__APPLE__) || defined(__FreeBSD__)
++#elif defined(__APPLE__)
+   if (type == MEM_INFO_TOTAL) {
+     int64_t memory;
+     int mib[2];
diff --git a/devel/cbang/files/patch-tests_testHarness b/devel/cbang/files/patch-tests_testHarness
new file mode 100644
index 000000000000..069e90c92696
--- /dev/null
+++ b/devel/cbang/files/patch-tests_testHarness
@@ -0,0 +1,375 @@
+--- tests/testHarness.orig	2021-08-10 22:46:49 UTC
++++ tests/testHarness
+@@ -1,4 +1,4 @@
+-#!/usr/bin/env python2
++#! %%PYTHON_CMD%%
+ # -*- mode: python -*-
+ #
+ #  This software is available as Open-Source software under the
+@@ -50,9 +50,14 @@ import sqlite3
+ import copy
+ import operator
+ import json
+-from StringIO import StringIO
++from six import string_types
+ 
+ try:
++  from io import StringIO
++except:
++  from StringIO import StringIO
++
++try:
+   from collections import OrderedDict
+ except:
+   def OrderedDict():
+@@ -105,8 +110,8 @@ def bar():
+ 
+ def labeled_bar(label):
+   length = len(label) + 2
+-  width1 = (screen_width - length) / 2
+-  width2 = screen_width - length - width1
++  width1 = int((screen_width - length) / 2)
++  width2 = int(screen_width - length - width1)
+ 
+   str = width1 * '*' + ' ' + label + ' ' + width2 * '*' + '\n'
+ 
+@@ -135,7 +140,7 @@ def ensure_parent_dir(file):
+ 
+ def copy_pattern(pattern, dst, ignores = []):
+   # shutil.ignore_patterns() is only in v2.6
+-  ignore = lambda dir, files: filter(lambda f: f in ignores, files)
++  ignore = lambda dir, files: list(filter(lambda f: f in ignores, files))
+ 
+   for path in glob.glob(pattern):
+     dir, file = os.path.split(path)
+@@ -155,7 +160,7 @@ def read_file(path):
+   f = None
+ 
+   try:
+-    f = open(path, 'r')
++    f = open(path, 'rt')
+     return f.read()
+ 
+   finally:
+@@ -174,7 +179,7 @@ def write_file(path, data):
+ 
+ 
+ def split_cmd_line(cmd):
+-  if isinstance(cmd, basestring): return shlex.split(str(cmd))
++  if isinstance(cmd, string_types): return shlex.split(str(cmd))
+   return cmd
+ 
+ 
+@@ -207,21 +212,20 @@ def execute_proc(command, timeout, **kwargs):
+       if timeout and timeout < start - time.time():
+         if sys.platform == 'win32': proc.kill()
+         else: os.killpg(proc.pid)
+-        raise Exception, 'Timedout'
++        raise Exception('Timedout')
+       time.sleep(0.1)
+ 
+     return proc.returncode
+ 
+-  except Exception, e:
+-    raise Exception, 'Running: ' + ' '.join(command) + \
+-        '\nCaused by:' + str(e)
++  except Exception as e:
++    raise Exception('Running: ' + ' '.join(command) + '\nCaused by:' + str(e))
+ 
+ 
+ def remove_tree(path):
+   mode = os.stat(path).st_mode
+ 
+   if not os.path.islink(path) and os.path.isdir(path):
+-    if (mode & 0700) != 0700: os.chmod(path, mode | 0700)
++    if (mode & 0o0700) != 0o0700: os.chmod(path, mode | 0o0700)
+ 
+     for name in os.listdir(path):
+       remove_tree(path + '/' + name)
+@@ -229,8 +233,8 @@ def remove_tree(path):
+     os.rmdir(path)
+ 
+   else:
+-    if sys.platform == 'win32' and (mode & 0200) != 0200:
+-      os.chmod(path, mode | 0200)
++    if sys.platform == 'win32' and (mode & 0o0200) != 0o0200:
++      os.chmod(path, mode | 0o0200)
+     os.remove(path)
+ 
+ 
+@@ -258,13 +262,13 @@ class Logger:
+ 
+ 
+   def push(self, key):
+-    #print 'JSON push(%s)' % key
++    #print('JSON push(%s)' % key)
+     self.back()[key] = OrderedDict()
+     self.stack.append(self.back()[key])
+ 
+ 
+   def pop(self, key):
+-    #print 'JSON pop(%s)' % key
++    #print('JSON pop(%s)' % key)
+     self.stack.pop()
+ 
+ 
+@@ -556,7 +560,7 @@ class ReplaceFilter:
+     if replace is None: replace = ['']
+     if isinstance(replace, list): self.replace = replace
+     else: self.replace = list([replace])
+-    self.replace = map(str, self.replace)
++    self.replace = list(map(str, self.replace))
+ 
+ 
+   def __call__(self, line):
+@@ -585,10 +589,10 @@ class CheckFile(Check):
+     self.reason = filename
+     self.exists = exists
+ 
+-    if isinstance(filter, basestring): filter = MatchFilter(filter)
++    if isinstance(filter, string_types): filter = MatchFilter(filter)
+     if isinstance(filter, (list, tuple)):
+       if not filter[0] in filter_classes:
+-        raise 'Invalid filter "%s"' % filter[0]
++        raise Exception('Invalid filter "%s"' % filter[0])
+ 
+       klass = filter_classes[filter[0]]
+       filter = klass(*filter[1:])
+@@ -782,7 +786,7 @@ class CheckFilePattern(CheckFile):
+ 
+       return CheckFile.check(self, test)
+ 
+-    except Exception, e:
++    except Exception as e:
+       if options.verbose: output_stream.write(str(e))
+       return FAILED
+ 
+@@ -810,7 +814,7 @@ class Table:
+     self.number = number
+     self.header = header
+ 
+-    self.widths = map(lambda x: 0, range(columns))
++    self.widths = list(map(lambda x: 0, range(columns)))
+     self.rows = []
+ 
+ 
+@@ -862,8 +866,8 @@ class Table:
+ 
+     # Check row width
+     if self.columns != len(row):
+-      raise Exception, \
+-          'Row has ' + len(row) + ' columns, expected ' + self.columns
++      raise Exception('Row has ' + len(row) + ' columns, expected ' +
++                      self.columns)
+ 
+     self.rows.append(row)
+ 
+@@ -879,8 +883,8 @@ class Table:
+ 
+ 
+   def bar(self):
+-    return self.do_row(map(lambda x: x * self.row_sep, self.widths),
+-                       self.corner, self.row_sep)
++    return self.do_row(list(map(lambda x: x * self.row_sep, self.widths),
++                            self.corner, self.row_sep))
+ 
+ 
+   def __str__(self):
+@@ -892,8 +896,8 @@ class Table:
+ 
+     first = True
+     for row in self.rows:
+-      row = map(lambda cell, width:
+-                  cell.center(width, self.padding), row, self.widths)
++      row = list(map(lambda cell, width:
++                     cell.center(width, self.padding), row, self.widths))
+       s += self.do_row(row, self.col_sep, self.padding)
+       if self.separate_rows or (self.header and first):
+         s += self.bar()
+@@ -913,8 +917,8 @@ class CheckDB(CheckFile):
+       if col[0] == '"': return col
+       else: return '"%s"' % col
+ 
+-    if cols is not None: cols = map(quote_column, cols)
+-    if orderBy is not None: orderBy = map(quote_column, orderBy)
++    if cols is not None: cols = list(map(quote_column, cols))
++    if orderBy is not None: orderBy = list(map(quote_column, orderBy))
+ 
+     self.db = db
+     self.sql = sql
+@@ -923,7 +927,7 @@ class CheckDB(CheckFile):
+ 
+     if sql is None:
+       if cols is None or table is None:
+-        raise Exception, 'Must set either "sql" or "cols" and "table"'
++        raise Exception('Must set either "sql" or "cols" and "table"')
+       if orderBy is None: orderBy = [cols[0]]
+       self.sql = 'SELECT ' + ', '.join(cols) + ' FROM "' + table + \
+           '" ORDER BY ' + ', '.join(orderBy)
+@@ -931,8 +935,8 @@ class CheckDB(CheckFile):
+ 
+   def check(self, test):
+     # Clean up column names
+-    header = map(lambda x: x.split()[len(x.split()) - 1], self.cols)
+-    header = map(lambda x: x.strip(' "\''), header)
++    header = list(map(lambda x: x.split()[len(x.split()) - 1], self.cols))
++    header = list(map(lambda x: x.strip(' "\''), header))
+ 
+     table = Table(len(header), 0, separate_rows = False, number = True)
+     table.add_row(header)
+@@ -946,9 +950,9 @@ class CheckDB(CheckFile):
+       conn = sqlite3.connect(db)
+       c = conn.cursor()
+       c.execute(self.sql)
+-      for row in c: table.add_row(map(str, row))
++      for row in c: table.add_row(list(map(str, row)))
+       c.close()
+-    except Exception, e: return FAILED
++    except Exception as e: return FAILED
+ 
+     # Write
+     write_file(self.get_output(test),
+@@ -1027,7 +1031,7 @@ class Unit:
+       if os.path.exists(path):
+         self.config.update(json.loads(read_file(path)))
+ 
+-    except Exception, e:
++    except Exception as e:
+       raise HarnessError('Failed to parse test.json file in %s: %s' % (
+          self.get_full_name(), e))
+ 
+@@ -1041,12 +1045,13 @@ class Unit:
+       for check in checks:
+         if isinstance(check, Check): self.check.add(check)
+         else:
+-          if isinstance(check, basestring):
++          if isinstance(check, string_types):
+             check = [check]
+ 
+           if isinstance(check, (list, tuple)) and len(check):
+             if not check[0] in check_classes:
+-              raise 'Invalid check "%s" in %s' % (check[0], self.name)
++              raise Exception('Invalid check "%s" in %s' %
++                              (check[0], self.name))
+ 
+             klass = check_classes[check[0]]
+             self.check.add(klass(*check[1:]))
+@@ -1064,11 +1069,11 @@ class Unit:
+ 
+   def config_get_list(self, name, default = None, split = str.split):
+     value = self.config.get(name, default)
+-    if isinstance(value, basestring): value = split(value)
++    if isinstance(value, string_types): value = split(value)
+ 
+     try:
+-      return map(lambda item: item % self.config, value)
+-    except Exception, e:
++      return list(map(lambda item: item % self.config, value))
++    except Exception as e:
+       raise HarnessError('Error resolving %s "%s": %s' % (name, value, e))
+ 
+ 
+@@ -1141,11 +1146,11 @@ class Unit:
+   def get_stdin_file(self):
+     stdin = self.config.get('stdin', None)
+ 
+-    if isinstance(stdin, basestring): return StringIO(stdin)
++    if isinstance(stdin, string_types): return StringIO(stdin)
+ 
+     if stdin is None and 'stdin_file' in self.config:
+       path = self.config_get('stdin_file')
+-      if os.path.exists(path): return open(path, 'r')
++      if os.path.exists(path): return open(path, 'rb')
+ 
+     return stdin
+ 
+@@ -1170,8 +1175,8 @@ class Unit:
+ 
+     # Resolve command vars refs
+     try:
+-      command = map(lambda s: s % self.config, command)
+-    except Exception, e:
++      command = list(map(lambda s: s % self.config, command))
++    except Exception as e:
+       raise HarnessError('Error resolving command "%s": %s' % (command, e))
+ 
+     return command
+@@ -1245,7 +1250,7 @@ class Unit:
+       self.status = self.check.check(self)
+ 
+       # Check status
+-      if self.status is None: raise Exception, 'Test result not set'
++      if self.status is None: raise Exception('Test result not set')
+       self.reason = self.check.reason
+ 
+     # Logging
+@@ -1343,12 +1348,12 @@ class Test(Unit):
+ 
+   def initialize(self):
+     if self.units is None: Unit.initialize(self)
+-    else: map(Unit.initialize, self.units)
++    else: list(map(Unit.initialize, self.units))
+ 
+ 
+   def reset(self):
+     if self.units is None: Unit.reset(self)
+-    else: map(Unit.reset, self.units)
++    else: list(map(Unit.reset, self.units))
+ 
+ 
+   def view(self):
+@@ -1455,7 +1460,7 @@ class TestSuite:
+     if os.path.exists(path):
+       try:
+         self.config.update(json.loads(read_file(path)))
+-      except Exception, e:
++      except Exception as e:
+         raise HarnessError('Failed to parse suite test.json: ' + str(e))
+ 
+       if 'command' in self.config:
+@@ -1575,8 +1580,8 @@ class TestSuite:
+       env.update(globals())
+ 
+       try: execfile(script, env)
+-      except Exception, e:
+-        raise Exception, 'Exception in "%s": %s' % (script, str(e))
++      except Exception as e:
++        raise Exception('Exception in "%s": %s' % (script, str(e)))
+ 
+       if not 'Suite' in env:
+         raise HarnessError(
+@@ -1655,7 +1660,7 @@ class TestSuite:
+     errStr = "'%s' not found and variable '%s' not set" % (name, conf_name)
+     if home_var is not None and home_var in os.environ:
+       errStr += ' and ' + home_var + '=' + os.environ[home_var]
+-    raise Exception, errStr
++    raise Exception(errStr)
+ 
+ 
+ class TestResults:
+@@ -1893,7 +1898,7 @@ options, args = parser.parse_args()
+ # Change dir
+ if options.chdir is not None:
+   os.chdir(options.chdir)
+-  if options.verbose: print "Changed directory: " + os.getcwd()
++  if options.verbose: print("Changed directory: " + os.getcwd())
+ 
+ # Load config file
+ if options.config is not None: config_file = options.config
+@@ -1925,14 +1930,14 @@ if options.valgrind:
+ 
+ if options.dump_config:
+   for name, value in config.items():
+-    print "%s=%s" % (name, value)
++    print("%s=%s" % (name, value))
+   sys.exit(0)
+ 
+ # Run
+ try:
+   sys.exit(TestHarness(config).run(cmd_args))
+ 
+-except HarnessError, e:
++except HarnessError as e:
+   sys.stdout.flush()
+   if e.show_usage: parser.error(e.msg)
+   else: sys.stderr.write('ERROR: ' + e.msg + '\n')
diff --git a/devel/cbang/pkg-descr b/devel/cbang/pkg-descr
new file mode 100644
index 000000000000..1e8da4c165e9
--- /dev/null
+++ b/devel/cbang/pkg-descr
@@ -0,0 +1,7 @@
+The C! (aka C Bang or cbang) library is a collection of C++ utility libraries
+developed over the course of +10 years and several major C++ application
+development projects. It should compile and run on FreeBSD, Windows, Linux and
+OSX using a modern C++ compiler.
+
+WWW: https://cbang.org/
+WWW: https://github.com/CauldronDevelopmentLLC/cbang/
diff --git a/devel/cbang/pkg-plist b/devel/cbang/pkg-plist
new file mode 100644
index 000000000000..1f99887662a8
--- /dev/null
+++ b/devel/cbang/pkg-plist
@@ -0,0 +1,398 @@
+include/cbang/Application.h
+include/cbang/ApplicationMain.h
+include/cbang/Catch.h
+include/cbang/Deallocators.h
+include/cbang/Errors.h
+include/cbang/Exception.h
+include/cbang/FileLocation.h
+include/cbang/Info.h
+include/cbang/LocationRange.h
+include/cbang/Math.h
+include/cbang/Packed.h
+include/cbang/RefCounter.h
+include/cbang/SStream.h
+include/cbang/ServerApplication.h
+include/cbang/SmartPointer.h
+include/cbang/StdTypes.h
+include/cbang/String.h
+include/cbang/Throw.h
+include/cbang/Zap.h
+include/cbang/acmev2/Account.h
+include/cbang/acmev2/KeyCert.h
+include/cbang/auth/FacebookOAuth2.h
+include/cbang/auth/GitHubOAuth2.h
+include/cbang/auth/GoogleOAuth2.h
+include/cbang/auth/OAuth2.h
+include/cbang/buffer/Buffer.h
+include/cbang/buffer/BufferDevice.h
+include/cbang/buffer/MemoryBuffer.h
+include/cbang/config/CommandLine.h
+include/cbang/config/Constraint.h
+include/cbang/config/EnumConstraint.h
+include/cbang/config/MaxConstraint.h
+include/cbang/config/MinConstraint.h
+include/cbang/config/MinMaxConstraint.h
+include/cbang/config/Option.h
+include/cbang/config/OptionAction.h
+include/cbang/config/OptionActionSet.h
+include/cbang/config/OptionCategory.h
+include/cbang/config/OptionMap.h
+include/cbang/config/OptionProxy.h
+include/cbang/config/OptionScriptHandler.h
+include/cbang/config/Options.h
+include/cbang/db/AsyncLevelDB.h
+include/cbang/db/Backup.h
+include/cbang/db/Blob.h
+include/cbang/db/Column.h
+include/cbang/db/ColumnDef.h
+include/cbang/db/Database.h
+include/cbang/db/LevelDB.h
+include/cbang/db/MakeTable.def
+include/cbang/db/MakeTableImpl.def
+include/cbang/db/NameValueTable.h
+include/cbang/db/Parameter.h
+include/cbang/db/Schema.h
+include/cbang/db/Statement.h
+include/cbang/db/TableDef.h
+include/cbang/db/Transaction.h
+include/cbang/db/Types.h
+include/cbang/debug/BacktraceDebugger.h
+include/cbang/debug/Debugger.h
+include/cbang/debug/Demangle.h
+include/cbang/debug/StackFrame.h
+include/cbang/debug/StackTrace.h
+include/cbang/enum/CPUExtendedFeature.h
+include/cbang/enum/CPUFeature.h
+include/cbang/enum/CPUFeature80000001.h
+include/cbang/enum/Compression.h
+include/cbang/enum/Enumeration.h
+include/cbang/enum/EnumerationManager.h
+include/cbang/enum/MakeEnumeration.def
+include/cbang/enum/MakeEnumerationImpl.def
+include/cbang/enum/ProcessPriority.h
+include/cbang/enum/ThreadsType.h
+include/cbang/geom/AxisAngle.h
+include/cbang/geom/Matrix.h
+include/cbang/geom/Path.h
+include/cbang/geom/Quaternion.h
+include/cbang/geom/Rectangle.h
+include/cbang/geom/Segment.h
+include/cbang/geom/Triangle.h
+include/cbang/geom/Vector.h
+include/cbang/gpu/CUDALibrary.h
+include/cbang/gpu/ComputeDevice.h
+include/cbang/gpu/GPU.h
+include/cbang/gpu/GPUIndex.h
+include/cbang/gpu/GPUResource.h
+include/cbang/gpu/GPUType.h
+include/cbang/gpu/GPUVendor.h
+include/cbang/gpu/OpenCLLibrary.h
+include/cbang/http/ACLWebPageHandler.h
+include/cbang/http/ChunkedStreamFilter.h
+include/cbang/http/Connection.h
+include/cbang/http/ConnectionDevice.h
+include/cbang/http/ConnectionQueue.h
+include/cbang/http/ContentTypes.h
+include/cbang/http/Context.h
+include/cbang/http/Cookie.h
+include/cbang/http/FileWebPageHandler.h
+include/cbang/http/Handler.h
+include/cbang/http/Header.h
+include/cbang/http/Message.h
+include/cbang/http/MethodWebPageHandler.h
+include/cbang/http/ProxyManager.h
+include/cbang/http/RegexWebPageHandler.h
+include/cbang/http/Request.h
+include/cbang/http/RequestMethod.h
+include/cbang/http/ResourceWebPageHandler.h
+include/cbang/http/Response.h
+include/cbang/http/ScriptWebPageHandler.h
+include/cbang/http/ScriptedWebContext.h
+include/cbang/http/ScriptedWebHandler.h
+include/cbang/http/Server.h
+include/cbang/http/Session.h
+include/cbang/http/SessionFactory.h
+include/cbang/http/SessionManager.h
+include/cbang/http/SessionsTable.h
+include/cbang/http/StatusCode.h
+include/cbang/http/Transaction.h
+include/cbang/http/WebContext.h
+include/cbang/http/WebContextMethods.h
+include/cbang/http/WebHandler.h
+include/cbang/http/WebPageHandler.h
+include/cbang/http/WebPageHandlerGroup.h
+include/cbang/http/WebServer.h
+include/cbang/io/File.h
+include/cbang/io/FileFactory.h
+include/cbang/io/FileInterface.h
+include/cbang/io/IO.h
+include/cbang/io/InputSource.h
+include/cbang/io/OutputSink.h
+include/cbang/io/Parser.h
+include/cbang/io/Reader.h
+include/cbang/io/StringInputSource.h
+include/cbang/io/StringStreamInputSource.h
+include/cbang/io/UnixFile.h
+include/cbang/io/Writer.h
+include/cbang/iostream/ArrayDevice.h
+include/cbang/iostream/BZip2Compressor.h
+include/cbang/iostream/BZip2Decompressor.h
+include/cbang/iostream/Base64Encoder.h
+include/cbang/iostream/CipherStream.h
+include/cbang/iostream/CompressionFilter.h
+include/cbang/iostream/CountingStreamFilter.h
+include/cbang/iostream/LZ4Compressor.h
+include/cbang/iostream/LZ4Decompressor.h
+include/cbang/iostream/LineBufferDevice.h
+include/cbang/iostream/NullDevice.h
+include/cbang/iostream/PacifierCallback.h
+include/cbang/iostream/Serializable.h
+include/cbang/iostream/StreamLimiter.h
+include/cbang/iostream/TeeFilter.h
+include/cbang/iostream/Transfer.h
+include/cbang/iostream/UpdateStreamFilter.h
+include/cbang/iostream/VectorDevice.h
+include/cbang/js/BakedCallback.h
+include/cbang/js/Callback.h
+include/cbang/js/ConsoleModule.h
+include/cbang/js/Factory.h
+include/cbang/js/Function.h
+include/cbang/js/Impl.h
+include/cbang/js/JSInterrupted.h
+include/cbang/js/Javascript.h
+include/cbang/js/MethodCallback.h
+include/cbang/js/Module.h
+include/cbang/js/NativeModule.h
+include/cbang/js/PathResolver.h
+include/cbang/js/RawMethodCallback.h
+include/cbang/js/Scope.h
+include/cbang/js/Signature.h
+include/cbang/js/Sink.h
+include/cbang/js/StackTrace.h
+include/cbang/js/StdModule.h
+include/cbang/js/Value.h
+include/cbang/js/v8/Context.h
+include/cbang/js/v8/Factory.h
+include/cbang/js/v8/JSImpl.h
+include/cbang/js/v8/V8.h
+include/cbang/js/v8/Value.h
+include/cbang/js/v8/ValueRef.h
+include/cbang/json/BufferWriter.h
+include/cbang/json/Builder.h
+include/cbang/json/Dict.h
+include/cbang/json/Factory.h
+include/cbang/json/False.h
+include/cbang/json/Filter.h
+include/cbang/json/Integer.h
+include/cbang/json/JSON.h
+include/cbang/json/KeywordFilter.h
+include/cbang/json/KeywordsFilter.h
+include/cbang/json/List.h
+include/cbang/json/Null.h
+include/cbang/json/NullSink.h
+include/cbang/json/Number.h
+include/cbang/json/Observable.h
+include/cbang/json/Path.h
+include/cbang/json/ProxySink.h
+include/cbang/json/Reader.h
+include/cbang/json/Serializable.h
+include/cbang/json/Sink.h
+include/cbang/json/String.h
+include/cbang/json/TeeSink.h
+include/cbang/json/True.h
+include/cbang/json/Undefined.h
+include/cbang/json/Value.h
+include/cbang/json/ValueType.h
+include/cbang/json/ValueTypes.def
+include/cbang/json/Writer.h
+include/cbang/json/YAMLMergeSink.h
+include/cbang/json/YAMLReader.h
+include/cbang/log/AsyncCopyStreamToLog.h
+include/cbang/log/LogDevice.h
+include/cbang/log/LogLineBuffer.h
+include/cbang/log/Logger.h
+include/cbang/log/SmartLogPrefix.h
+include/cbang/log/TailFileToLog.h
+include/cbang/net/Base64.h
+include/cbang/net/IPAddress.h
+include/cbang/net/IPAddressFilter.h
+include/cbang/net/IPAddressRange.h
+include/cbang/net/IPRangeSet.h
+include/cbang/net/Session.h
+include/cbang/net/SessionManager.h
+include/cbang/net/Swab.h
+include/cbang/net/URI.h
+include/cbang/openssl/BIMemory.h
+include/cbang/openssl/BIOFStream.h
+include/cbang/openssl/BIOMemory.h
+include/cbang/openssl/BIOStream.h
+include/cbang/openssl/BIStream.h
+include/cbang/openssl/BOMemory.h
+include/cbang/openssl/BOStream.h
+include/cbang/openssl/BStream.h
+include/cbang/openssl/BigNum.h
+include/cbang/openssl/CRL.h
+include/cbang/openssl/CSR.h
+include/cbang/openssl/Certificate.h
+include/cbang/openssl/CertificateChain.h
+include/cbang/openssl/CertificateContext.h
+include/cbang/openssl/CertificateStore.h
+include/cbang/openssl/CertificateStoreContext.h
+include/cbang/openssl/Cipher.h
+include/cbang/openssl/Digest.h
+include/cbang/openssl/DigestStreamFilter.h
+include/cbang/openssl/Extension.h
+include/cbang/openssl/KeyContext.h
+include/cbang/openssl/KeyGenCallback.h
+include/cbang/openssl/KeyGenPacifier.h
+include/cbang/openssl/KeyPair.h
+include/cbang/openssl/PasswordCallback.h
+include/cbang/openssl/RSA.h
+include/cbang/openssl/Revoked.h
+include/cbang/openssl/SSL.h
+include/cbang/openssl/SSLContext.h
+include/cbang/openssl/SecurityUtilities.h
+include/cbang/openssl/XORStreamFilter.h
+include/cbang/os/CPUID.h
+include/cbang/os/Condition.h
+include/cbang/os/Directory.h
+include/cbang/os/DirectoryWalker.h
+include/cbang/os/DynamicLibrary.h
+include/cbang/os/ExitSignalHandler.h
+include/cbang/os/Glob.h
+include/cbang/os/MacOSUtilities.h
+include/cbang/os/Mutex.h
+include/cbang/os/MutexPrivate.h
+include/cbang/os/PowerManagement.h
+include/cbang/os/ProcessLock.h
+include/cbang/os/RWLock.h
+include/cbang/os/Semaphore.h
+include/cbang/os/SignalHandler.h
+include/cbang/os/SignalManager.h
+include/cbang/os/Subprocess.h
+include/cbang/os/SysError.h
+include/cbang/os/SystemInfo.h
+include/cbang/os/SystemUtilities.h
+include/cbang/os/TemporaryDirectory.h
+include/cbang/os/Thread.h
+include/cbang/os/ThreadLocalStorage.h
+include/cbang/os/ThreadPool.h
+include/cbang/os/ThreadPoolFunc.h
+include/cbang/os/Win32EventLog.h
+include/cbang/os/Win32Registry.h
+include/cbang/os/Win32Utilities.h
+include/cbang/packet/EnumerationPacketField.h
+include/cbang/packet/FPPacketField.h
+include/cbang/packet/Packet.h
+include/cbang/packet/PacketField.h
+include/cbang/packet/StringPacketField.h
+include/cbang/parse/ASTNode.h
+include/cbang/parse/ParseScope.h
+include/cbang/parse/Scanner.h
+include/cbang/parse/Token.h
+include/cbang/parse/Tokenizer.h
+include/cbang/pci/PCIDevice.h
+include/cbang/pci/PCIInfo.h
+include/cbang/pci/PCIVendor.h
+include/cbang/script/Arguments.h
+include/cbang/script/BareMemberFunctor.h
+include/cbang/script/Connection.h
+include/cbang/script/Context.h
+include/cbang/script/Entity.h
+include/cbang/script/Environment.h
+include/cbang/script/Function.h
+include/cbang/script/Functor.h
+include/cbang/script/Handler.h
+include/cbang/script/KeywordArguments.h
+include/cbang/script/MemberFunctor.h
+include/cbang/script/Processor.h
+include/cbang/script/Server.h
+include/cbang/script/StdLibrary.h
+include/cbang/script/Variable.h
+include/cbang/socket/BIOSocketImpl.h
+include/cbang/socket/Socket.h
+include/cbang/socket/SocketConnection.h
+include/cbang/socket/SocketDebugConnection.h
+include/cbang/socket/SocketDebugImpl.h
+include/cbang/socket/SocketDebugger.h
+include/cbang/socket/SocketDefaultImpl.h
+include/cbang/socket/SocketDevice.h
+include/cbang/socket/SocketImpl.h
+include/cbang/socket/SocketSSLImpl.h
+include/cbang/socket/SocketServer.h
+include/cbang/socket/SocketSet.h
+include/cbang/socket/SocketType.h
+include/cbang/socket/Winsock.h
+include/cbang/struct/MakeStruct.def
+include/cbang/struct/MakeStructImpl.def
+include/cbang/tar/Tar.h
+include/cbang/tar/TarFileReader.h
+include/cbang/tar/TarFileWriter.h
+include/cbang/tar/TarHeader.h
+include/cbang/time/HumanTime.h
*** 66 LINES SKIPPED ***