diff options
401 files changed, 3505 insertions, 5881 deletions
@@ -1,3 +1,4 @@ bin *.pyc *.sw? +tags diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e0e648c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "ice"] + path = ice + url = https://github.com/zeroc-ice/ice + branch = 3.7 diff --git a/Jamroot.jam b/Jamroot.jam index 9d19983..ce7995c 100644 --- a/Jamroot.jam +++ b/Jamroot.jam @@ -2,18 +2,26 @@ import os ; import slice ; using gcc : : [ os.environ CXX ] ; +using pkg-config ; +import pkg-config ; -variant component ; +variant coverage : debug ; project : requirements - <variant>release:<cflags>"-std=c++1y" - <variant>release:<linkflags>"-Wl,-z,defs,--warn-once" - <variant>debug:<cflags>"-W -Wall -Werror -Wwrite-strings -std=c++1y" - <variant>debug:<linkflags>"-Wl,-z,defs,--warn-once" - <variant>component:<cflags>"-W -Wall -Werror -Wwrite-strings -std=c++1y -fPIC" - <variant>component:<linkflags>"-Wl,-z,lazy,--warn-once,-fPIC" + <define>ICE_CPP11_MAPPING + <cxxflags>"-std=c++17 -fvisibility=hidden -fvisibility-inlines-hidden" + <linkflags>"-Wl,--warn-once,--gc-sections" + <variant>release:<cxxflags>"-flto=2" + <variant>release:<linkflags>"-flto=2" + <variant>debug:<cxxflags>"-W -Wall -Werror -Wextra" + <variant>debug:<linkflags>"-Wl,-z,defs" + <variant>coverage:<cxxflags>"--coverage" + <variant>coverage:<linkflags>"--coverage" ; +build-project project2 ; + +pkg-config.import libxmlpp : : <name>libxml++-3.0 ; +pkg-config.import glibmm : : <name>glibmm-2.4 ; -alias all : project2 netfs libjsonpp p2pvr libtmdb slicer ; diff --git a/ice b/ice new file mode 160000 +Subproject e9e8a21c572af0761b69f7c30e7fc3592280bf4 diff --git a/pkg-config.jam b/pkg-config.jam new file mode 100644 index 0000000..2efa9cf --- /dev/null +++ b/pkg-config.jam @@ -0,0 +1,485 @@ +#| +Copyright 2019 Dmitry Arkhipov +Distributed under the Boost Software License, Version 1.0. (See +accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +|# + + +import "class" : new ; +import common ; +import errors ; +import feature ; +import os ; +import param ; +import project ; +import regex ; +import sequence ; +import string ; +import targets ; + + +#| tag::doc[] + += pkg-config +The *pkg-config* program is used to retrieve information about installed +libraries in the system. It retrieves information about packages from special +metadata files. These files are named after the package, and have a `.pc` +extension. The package name specified to *pkg-config* is defined to be the name +of the metadata file, minus the `.pc` extension. + +|# # end::doc[] + + +#| tag::doc[] + +== Feature: `pkg-config` + +Selects one of the initialized `pkg-config` configurations. This feature is +`propagated` to dependencies. Its use is dicussed in +section <<pkg-config-init>>. + +|# # end::doc[] + +feature.feature pkg-config : : propagated ; + + +#| tag::doc[] + +== Feature: `pkg-config-define` + +This `free` feature adds a variable assignment to pkg-config invocation. For +example, + +[source, jam] +---- +pkg-config.import mypackage : requirements <pkg-config-define>key=value ; +---- + +is equivalent to invoking on the comand line + +[source, shell] +---- +pkg-config --define-variable=key=value mypackage ; +---- + +|# # end::doc[] + +feature.feature pkg-config-define : : free ; + + +#| tag::doc[] + +== Rule: `import` + +Main target rule that imports a *pkg-config* package. When its consumer targets +are built, *pkg-config* command will be invoked with arguments that depend on +current property set. The features that have an effect are: + +* `<pkg-config-define>`: adds a `--define-variable` argument; +* `<link>`: adds `--static` argument when `<link>static`; +* `<link>`: adds `--static` argument when `<link>static`; +* `<name>`: specifies package name (target name is used instead if the property + is not present); +* `<version>`: specifies package version range, can be used multiple times and + should be a dot-separated sequence of numbers optionally prefixed with `=`, + `<`, `>`, `<=` or `>=`. + +Example: + +[source, jam] +---- +pkg-config.import my-package + : requirements <name>my_package <version><4 <version>>=3.1 ; +---- + +|# # end::doc[] + + +rule import + ( target-name + : sources * + : requirements * + : default-build * + : usage-requirements * + ) +{ + param.handle-named-params + sources requirements default-build usage-requirements ; + targets.create-metatarget pkg-config-target + : [ project.current ] + : $(target-name) + : $(sources) + : $(requirements) + : $(default-build) + : $(usage-requirements) + ; +} + + +#| tag::doc[] + +== Initialization [[ pkg-config-init ]] + +To use the `pkg-config` tool you need to declare it in a configuration file +with the `using` rule: + +[source, jam] +---- +using pkg-config : [config] : [command] ... : [ options ] ... ; +---- + + +* `config`: the name of initialized configuration. The name can be omitted, in + which case the configuration will become the default one. +* `command`: the command, with any extra arguments, to execute. If no command + is given, first `PKG_CONFIG` environment variable is checked, and if its + empty the string `pkg-config` is used. +* `options`: options that modify `pkg-config` behavior. Allowed options are: + * `<path>`: sets `PKG_CONFIG_PATH` environment variable; + multiple occurences are allowed. + * `<libdir>`: sets `PKG_CONFIG_LIBDIR` environment variable; + multiple occurences are allowed. + * `<allow-system-cflags>`: sets `PKG_CONFIG_ALLOW_SYSTEM_CFLAGS` + environment variable; multiple occurences are allowed. + * `<allow-system-libs>`: sets `PKG_CONFIG_ALLOW_SYSTEM_LIBS` + environment variable; multiple occurences are allowed. + * `<sysroot>`: sets `PKG_CONFIG_SYSROOT_DIR` environment variable; + multiple occurences are allowed. + * `<variable>`: adds a variable definition argument to command invocation; + multiple occurences are allowed. + +|# # end::doc[] + +rule init ( config ? : command * : options * ) +{ + config ?= [ default-config ] ; + + local tool = [ os.environ PKG_CONFIG ] ; + tool ?= pkg-config ; + command = + [ common.get-invocation-command pkg-config : $(tool) : $(command) ] ; + + configure $(config) : $(command) : $(options) ; + $(.configs).use $(config) ; +} + + +rule run ( config ? : args * ) +{ + config ?= [ default-config ] ; + + local command = [ $(.configs).get $(config) : command ] ; + command = "$(command) $(args:J= )" ; + + local output = [ SHELL "$(command)" : exit-status ] ; + if 0 != $(output[2]) + { + errors.error "pkg-config: command '$(command)' resulted in error:" + [ common.newline-char ] $(output[1]) ; + } + + local ws = [ string.whitespace ] ; + output = [ regex.split $(output[1]) "[$(ws)]" ] ; + return [ sequence.filter non-empty : $(output) ] ; +} + + +#| tag::doc[] + +== Class `pkg-config-target` + +[source, jam] +---- +class pkg-config-target : alias-target-class { + rule construct ( name : sources * : property-set ) + rule version ( property-set ) + rule variable ( name : property-set ) +} +---- + +The class of objects returned by `import` rule. The objects themselves could be +useful in situations that require more complicated logic for consuming a +package. See <<pkg-config-tips>> for examples. + +. `rule construct ( name : sources * : property-set )` + Overrides `alias-target.construct`. + +. `rule version ( property-set )` + Returns the package's version, in the context of `property-set`. + +. `rule variable ( name : property-set )` + Returns the value of variable `name` in the package, in the context of + `property-set`. + + +|# # end::doc[] + +class pkg-config-target : alias-target-class +{ + import pkg-config ; + import regex ; + + rule construct ( name : sources * : property-set ) + { + local config = [ $(property-set).get <pkg-config> ] ; + local args = [ common-arguments $(name) : $(property-set) ] ; + return + [ property-set.create + [ compile-flags $(config) $(property-set) : $(args) ] + [ link-flags $(config) $(property-set) : $(args) ] + ] ; + } + + rule version ( property-set ) + { + local config = [ $(property-set).get <pkg-config> ] ; + local args = [ common-arguments [ name ] : $(property-set) ] ; + local version = [ pkg-config.run $(config) : --modversion $(args) ] ; + return [ regex.split $(version) "\\." ] ; + } + + rule variable ( name : property-set ) + { + local config = [ $(property-set).get <pkg-config> ] ; + local args = [ common-arguments [ name ] : $(property-set) ] ; + return [ pkg-config.run $(config) : --variable=$(name) $(args) ] ; + } + + local rule common-arguments ( name : property-set ) + { + local defines = [ $(property-set).get <pkg-config-define> ] ; + local args = --define-variable=$(defines) ; + if [ $(property-set).get <link> ] = static + { + args += --static ; + } + return $(args) [ get-package-request $(property-set) $(name) ] ; + } + + local rule get-package-request ( property-set name ) + { + local pkg-name = [ $(property-set).get <name> ] ; + pkg-name ?= $(name) ; + if $(pkg-name[2]) + { + errors.error "multiple package names were specified for target " + "'$(name)': $(pkg-name)" ; + } + + local versions ; + for local version in [ $(property-set).get <version> ] + { + local match = [ MATCH "^(<=)(.*)" : $(version) ] ; + match ?= [ MATCH "^(>=)(.*)" : $(version) ] ; + match ?= [ MATCH "^([><=])(.*)" : $(version) ] ; + if $(match) + { + version = " $(match:J= )" ; + } + else + { + version = " = $(version)" ; + } + versions += $(version) ; + } + versions ?= "" ; + + return "'$(pkg-name)"$(versions)"'" ; + } + + local rule link-flags ( config property-set : args * ) + { + local flags = [ pkg-config.run $(config) : --libs $(args) ] ; + return <linkflags>$(flags) ; + } + + local rule compile-flags ( config property-set : args * ) + { + local flags = [ pkg-config.run $(config) : --cflags $(args) ] ; + return <cflags>$(flags) ; + } +} + + +local rule default-config ( ) +{ + return default ; +} + + +local rule configure ( config : command + : options * ) +{ + $(.configs).register $(config) ; + + local path ; + local libdir ; + local allow-system-cflags ; + local allow-system-libs ; + local sysroot ; + local defines ; + for local opt in $(options) + { + switch $(opt:G) + { + case <path> : path += $(opt:G=) ; + case <libdir> : libdir += $(opt:G=) ; + case <allow-system-cflags> : allow-system-cflags += $(opt:G=) ; + case <allow-system-libs> : allow-system-libs += $(opt:G=) ; + case <sysroot> : sysroot += $(opt:G=) ; + case <variable> : defines += $(opt:G=) ; + case * : + errors.error "pkg-config: invalid property '$(opt)' was " + "specified for configuration '$(config)'." ; + } + } + + for local opt in allow-system-cflags allow-system-libs + { + if ! $($(opt)) in "on" off + { + errors.error "pkg-config: invalid value '$($(opt))' was specified " + "for option <$(opt)> of configuration '$(config)'." + [ common.newline-char ] "Available values are 'on' and 'off'" ; + } + } + + if $(sysroot[2]) + { + errors.error "pkg-config: several values were specified for option " + "<sysroot> of configuration '$(config)'." + [ common.newline-char ] "Only one value is allowed." ; + } + + local sep = [ os.path-separator ] ; + path = [ envar-set-command PKG_CONFIG_PATH : $(path:J=$(sep)) ] ; + libdir = [ envar-set-command PKG_CONFIG_LIBDIR : $(libdir:J=$(sep)) ] ; + sysroot = [ envar-set-command PKG_CONFIG_SYSROOT_DIR : $(sysroot) ] ; + allow-cflags = + [ envar-set-command PKG_CONFIG_ALLOW_SYSTEM_CFLAGS + : $(allow-cflags) + : 1 + ] ; + allow-libs = + [ envar-set-command PKG_CONFIG_ALLOW_SYSTEM_LIBS + : $(allow-libs) + : 1 + ] ; + + command += --print-errors --errors-to-stdout --define-variable=$(defines) ; + $(.configs).set $(config) + : command + : "$(path)$(libdir)$(sysroot)$(allow-cflags)$(allow-libs)$(command:J= )" + ; + + feature.extend pkg-config : $(config) ; +} + + +local rule envar-set-command ( envar : value * : implied-value * ) +{ + if $(value) + { + if $(implied-value) + { + value = $(implied-value) ; + } + return [ common.path-variable-setting-command $(envar) : $(value) ] ; + } + else + { + return "" ; + } +} + + +local rule non-empty ( string ) +{ + if $(string) != "" { return true ; } +} + + +.configs = [ new configurations ] ; + + +#| tag::doc[] + +== Tips [[pkg-config-tips]] + + +=== Using several configurations + +Suppose, you have 2 collections of `.pc` files: one for platform A, and another +for platform B. You can initialize 2 configurations of `pkg-config` tool each +corresponding to specific collection: + +[source, jam] +---- +using pkg-config : A : : <libdir>path/to/collection/A ; +using pkg-config : B : : <libdir>path/to/collection/B ; +---- + +Then, you can specify that builds for platform A should use configuration A, +while builds for B should use configuration B: + +[source, jam] +---- +project + : requirements + <target-os>A-os,<architecture>A-arch:<pkg-config>A + <target-os>B-os,<architecture>B-arch:<pkg-config>B + ; +---- + +Thanks to the fact, that `project-config`, `user-config` and `site-config` +modules are parents of jamroot module, you can put it in any of those files.o + + +=== Choosing the package name based on the property set + +Since a file for a package should be named after the package suffixed with +`.pc`, some projects came up with naming schemes in order to allow simultaneous +installation of several major versions or build variants. In order to pick the +specific name corresponding to the build request you can use `<conditional>` +property in requirements: + +[source, jam] +---- +pkg-config.import mypackage : requirements <conditional>@infer-name ; + +rule infer-name ( properties * ) +{ + local name = mypackage ; + local variant = [ property.select <variant> : $(properties) ] ; + if $(variant) = debug + { + name += -d ; + } + return <name>$(name) ; +} +---- + +The `common.format-name` rule can be very useful in this situation. + + +=== Modify usage requirements based on package version or variable + +Sometimes you need to apply some logic based on package's version or a +variable that it defines. For that you can use `<conditional>` property in +usage requirements: + +---- +mypackage = + [ pkg-config.import mypackage : usage-requirements <conditional>@define_ns + ] ; + +rule extra-props ( properties * ) +{ + local ps = [ property-set.create $(properties) ] ; + local prefix = [ $(mypackage).variable name_prefix : $(ps) ] ; + prefix += [ $(mypackage).version $(ps) ] ; + return <define>$(prefix:J=_) ; +} +---- + +|# # end::doc[] diff --git a/project2/Doxyfile b/project2/Doxyfile index 8c2cb5f..0de5676 100644 --- a/project2/Doxyfile +++ b/project2/Doxyfile @@ -612,10 +612,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = . \ - ../libdbpp \ - ../libpqpp \ - ../libodbcpp +INPUT = . # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is diff --git a/project2/Jamfile.jam b/project2/Jamfile.jam index cb99d35..9a36ada 100644 --- a/project2/Jamfile.jam +++ b/project2/Jamfile.jam @@ -1,10 +1,7 @@ import package ; import feature : feature ; -feature odbc : yes no : propagated ; -feature pq : yes no : propagated ; -feature mysql : yes no : propagated ; -feature sqlite : yes no : propagated ; +lib adhocutil : : : : <include>/usr/include/adhocutil ; alias p2parts : : : : <library>url//p2url @@ -19,11 +16,6 @@ alias p2parts : : : : <library>compression//p2compression <library>streams//p2streams <library>basics//p2basics - <library>lib//p2lib - <odbc>yes:<library>sql//p2sqlmodODBC - <pq>yes:<library>sql//p2sqlmodPQ - <mysql>yes:<library>sql//p2sqlmodMySQL - <sqlite>yes:<library>sql//p2sqlmodSQLite ; alias p2daemonparts : : : : @@ -33,18 +25,15 @@ alias p2daemonparts : : : : build-project console ; build-project cgi ; build-project daemon ; +build-project ice ; # Ensure tests are run (final targets don't reference projects, but specific libraries) build-project common//unittests ; build-project basics//unittests ; build-project ice//unittests ; -build-project sql//unittests ; build-project xml//unittests ; build-project files//unittests ; explicit install ; -package.install install : : finalbin : finallib ; -package.install installheaders : <install-source-root>. : : : [ glob-tree *.h ] ; -package.install installheadersmisc : : : : [ glob ../libmisc/*.h : ../libmisc/threads.h ] ; -package.install installheadersdb : : : : [ glob ../libdbpp/*.h ] ; +package.install install : <install-source-root>. : finalbin : finallib : [ glob-tree *.h : unittests ] ; diff --git a/project2/basics/Jamfile.jam b/project2/basics/Jamfile.jam index 19726d9..3a53d54 100644 --- a/project2/basics/Jamfile.jam +++ b/project2/basics/Jamfile.jam @@ -2,25 +2,24 @@ alias glibmm : : : : <cflags>"`pkg-config --cflags glibmm-2.4`" <linkflags>"`pkg-config --libs glibmm-2.4`" ; -lib boost_filesystem : : <name>boost_filesystem ; +lib stdc++fs ; lib dl ; build-project unittests ; cpp-pch pch : pch.hpp : - <include>../../libmisc - <library>glibmm + <library>glibmm <library>../common//p2common ; lib p2basics : + pch [ glob-tree *.cpp : unittests ] : <include>. - <include>../../libmisc <library>glibmm <library>dl - <library>boost_filesystem + <library>stdc++fs <library>../common//p2common : : <include>. diff --git a/project2/basics/aggregates/avg.cpp b/project2/basics/aggregates/avg.cpp index 900bc5f..0547120 100644 --- a/project2/basics/aggregates/avg.cpp +++ b/project2/basics/aggregates/avg.cpp @@ -26,5 +26,5 @@ class Average : public ValueAggregate { mutable std::list<double> vals; }; -DECLARE_LOADER("average", Average); +NAMEDFACTORY("average", Average, ValueAggregateFactory); diff --git a/project2/basics/aggregates/count.cpp b/project2/basics/aggregates/count.cpp index be22783..3d47b34 100644 --- a/project2/basics/aggregates/count.cpp +++ b/project2/basics/aggregates/count.cpp @@ -25,6 +25,5 @@ class Count : public ValueAggregate { mutable int c; }; -DECLARE_LOADER("count", Count); - +NAMEDFACTORY("count", Count, ValueAggregateFactory); diff --git a/project2/basics/aggregates/countDistinct.cpp b/project2/basics/aggregates/countDistinct.cpp index 205b932..9acba4c 100644 --- a/project2/basics/aggregates/countDistinct.cpp +++ b/project2/basics/aggregates/countDistinct.cpp @@ -22,5 +22,5 @@ class CountDistinct : public ValueAggregate { mutable std::set<VariableType> result; }; -DECLARE_LOADER("countdistinct", CountDistinct); +NAMEDFACTORY("countdistinct", CountDistinct, ValueAggregateFactory); diff --git a/project2/basics/aggregates/distinct.cpp b/project2/basics/aggregates/distinct.cpp index 33d71b0..c7f5fe0 100644 --- a/project2/basics/aggregates/distinct.cpp +++ b/project2/basics/aggregates/distinct.cpp @@ -24,4 +24,5 @@ class Distinct : public SetAggregate { mutable std::set<VariableType> result; }; -DECLARE_LOADER("distinct", Distinct); +NAMEDFACTORY("distinct", Distinct, SetAggregateFactory); + diff --git a/project2/basics/aggregates/join.cpp b/project2/basics/aggregates/join.cpp index 405c093..695626f 100644 --- a/project2/basics/aggregates/join.cpp +++ b/project2/basics/aggregates/join.cpp @@ -31,5 +31,5 @@ class Join : public ValueAggregate { Variable sep; }; -DECLARE_LOADER("join", Join); +NAMEDFACTORY("join", Join, ValueAggregateFactory); diff --git a/project2/basics/aggregates/max.cpp b/project2/basics/aggregates/max.cpp index 6304647..a193ed4 100644 --- a/project2/basics/aggregates/max.cpp +++ b/project2/basics/aggregates/max.cpp @@ -22,6 +22,5 @@ class Max : public ValueAggregate { mutable VariableType result; }; -DECLARE_LOADER("max", Max); - +NAMEDFACTORY("max", Max, ValueAggregateFactory); diff --git a/project2/basics/aggregates/min.cpp b/project2/basics/aggregates/min.cpp index 75b0b87..f5e442c 100644 --- a/project2/basics/aggregates/min.cpp +++ b/project2/basics/aggregates/min.cpp @@ -28,5 +28,5 @@ class Min : public ValueAggregate { mutable bool first; }; -DECLARE_LOADER("min", Min); +NAMEDFACTORY("min", Min, ValueAggregateFactory); diff --git a/project2/basics/aggregates/sum.cpp b/project2/basics/aggregates/sum.cpp index 68a9cd4..bdbf229 100644 --- a/project2/basics/aggregates/sum.cpp +++ b/project2/basics/aggregates/sum.cpp @@ -23,5 +23,5 @@ class Sum : public ValueAggregate { mutable double sum; }; -DECLARE_LOADER("sum", Sum); +NAMEDFACTORY("sum", Sum, ValueAggregateFactory); diff --git a/project2/basics/caches/memoryCache.cpp b/project2/basics/caches/memoryCache.cpp index 6e5aab6..04f5344 100644 --- a/project2/basics/caches/memoryCache.cpp +++ b/project2/basics/caches/memoryCache.cpp @@ -24,17 +24,18 @@ class MemoryCache : public RowSetCache { return *columns; } RowAttribute resolveAttr(const Glib::ustring & attrName) const { - return boost::bind(&safeMapLookup<AttributeDoesNotExist, AttrMap>, attrs, attrName); + return boost::bind(&AdHoc::safeMapLookup<AttributeDoesNotExist, AttrMap>, attrs, attrName); } private: friend class CachedRowSet; const Columns * columns; AttrMap attrs; }; - typedef boost::shared_ptr<MemoryCacheRow> MemoryCacheRowPtr; + typedef std::shared_ptr<MemoryCacheRow> MemoryCacheRowPtr; typedef std::list<MemoryCacheRowPtr> DataCache; CachedRowSet(const std::vector<VariableType> & k) : + SourceObject(ScriptNodePtr()), RowSet(NULL), key(k), createdAt(time(NULL)), @@ -55,14 +56,14 @@ class MemoryCache : public RowSetCache { void addNamedValue(const Glib::ustring & name, const VariableType & value) const { if (cur->fields.size() <= col) { cur->fields.resize(col + 1); - columns.insert(new Column(col, name)); + columns.insert(std::make_shared<Column>(col, name)); } cur->fields[col++] = value; } void addNewRow(const Glib::ustring&) const { col = 0; - cur = MemoryCacheRowPtr(new MemoryCacheRow(&columns)); + cur = std::make_shared<MemoryCacheRow>(&columns); } void finishRow() const { @@ -80,8 +81,8 @@ class MemoryCache : public RowSetCache { mutable MemoryCacheRowPtr cur; }; - typedef boost::intrusive_ptr<CachedRowSet> CachedRowSetPtr; - typedef boost::intrusive_ptr<const CachedRowSet> CachedRowSetCPtr; + typedef std::shared_ptr<CachedRowSet> CachedRowSetPtr; + typedef std::shared_ptr<const CachedRowSet> CachedRowSetCPtr; struct IndexByKey { }; struct IndexByTime { }; @@ -95,6 +96,7 @@ class MemoryCache : public RowSetCache { > > CacheStore; MemoryCache(ScriptNodePtr p) : + SourceObject(p), RowSetCache(p) { } @@ -113,7 +115,7 @@ class MemoryCache : public RowSetCache { } RowSetPresenterPtr openFor(ExecContext * ec, const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) { - return (cur = new CachedRowSet(makeKey(ec, n, f, ps))); + return (cur = std::make_shared<CachedRowSet>(makeKey(ec, n, f, ps))); } void save(ExecContext *, const Glib::ustring & , const Glib::ustring & , const IHaveParameters * ) { @@ -138,14 +140,14 @@ class MemoryCache : public RowSetCache { CachedRowSetPtr cur; - friend class CustomMemoryCacheLoader; + friend class CustomMemoryCacheFactory; static time_t CacheLife; static CacheStore Store; }; time_t MemoryCache::CacheLife; MemoryCache::CacheStore MemoryCache::Store; -class CustomMemoryCacheLoader : public ElementLoader::For<MemoryCache> { +class CustomMemoryCacheFactory : public RowSetCacheFactory::For<MemoryCache>, public LifeCycle { public: void onPeriodic() override { typedef MemoryCache::CacheStore::index<MemoryCache::IndexByTime>::type::iterator iter; @@ -156,10 +158,10 @@ class CustomMemoryCacheLoader : public ElementLoader::For<MemoryCache> { INITOPTIONS; }; -DECLARE_CUSTOM_LOADER("memorycache", CustomMemoryCacheLoader); +NAMEDPLUGIN("memorycache", CustomMemoryCacheFactory, RowSetCacheFactory); -DECLARE_OPTIONS(CustomMemoryCacheLoader, "Memory Cache options") +DECLARE_OPTIONS(CustomMemoryCacheFactory, "Memory Cache options") ("cache.memory.life", Options::value(&MemoryCache::CacheLife, 3600), "The age of cache entries after which they are removed (seconds)") -END_OPTIONS(CustomMemoryCacheLoader); +END_OPTIONS(CustomMemoryCacheFactory); diff --git a/project2/basics/functions/dates.cpp b/project2/basics/functions/dates.cpp index b19b921..90708d3 100644 --- a/project2/basics/functions/dates.cpp +++ b/project2/basics/functions/dates.cpp @@ -18,14 +18,14 @@ class ParseDate : public VariableImpl { } VariableType value(ExecContext * ec) const { - const char * s = string(ec); - const char * f = format(ec); + const std::string s = string(ec); + const std::string f = format(ec); struct tm tm; memset(&tm, 0, sizeof(struct tm)); mktime(&tm); - const char * e = strptime(s, f, &tm); + const char * e = strptime(s.c_str(), f.c_str(), &tm); if (!e || *e) { - Logger()->messagef(LOG_ERR, "%s: check failed (parse) for '%s' against '%s' (remaining chars='%s')", + Logger()->messagebf(LOG_ERR, "%s: check failed (parse) for '%s' against '%s' (remaining chars='%s')", __PRETTY_FUNCTION__, s, f, e); throw DateParseError(string(ec), format(ec)); } @@ -35,7 +35,7 @@ class ParseDate : public VariableImpl { Variable string; Variable format; }; -DECLARE_COMPONENT_LOADER("parsedate", ParseDate, VariableLoader); +NAMEDFACTORY("parsedate", ParseDate, VariableFactory); class FormatDate : public VariableImpl { public: @@ -49,7 +49,7 @@ class FormatDate : public VariableImpl { std::stringstream ss; boost::date_time::time_facet<boost::posix_time::ptime, char> * ft = new boost::date_time::time_facet<boost::posix_time::ptime, char>(); ss.imbue(std::locale(ss.getloc(), ft)); - ft->format(format(ec)); + ft->format(format(ec).as<std::string>().c_str()); ss << boost::get<boost::posix_time::ptime>(date(ec)); return ss.str(); } @@ -57,7 +57,7 @@ class FormatDate : public VariableImpl { Variable date; Variable format; }; -DECLARE_COMPONENT_LOADER("formatdate", FormatDate, VariableLoader); +NAMEDFACTORY("formatdate", FormatDate, VariableFactory); class AdjustDate : public VariableImpl { public: @@ -74,7 +74,7 @@ class AdjustDate : public VariableImpl { Variable date; Variable offset; }; -DECLARE_COMPONENT_LOADER("adjustdate", AdjustDate, VariableLoader); +NAMEDFACTORY("adjustdate", AdjustDate, VariableFactory); class CurrentDate : public VariableImpl { public: @@ -86,5 +86,5 @@ class CurrentDate : public VariableImpl { return boost::posix_time::microsec_clock::universal_time(); } }; -DECLARE_COMPONENT_LOADER("currentdate", CurrentDate, VariableLoader); +NAMEDFACTORY("currentdate", CurrentDate, VariableFactory); diff --git a/project2/basics/functions/strings.cpp b/project2/basics/functions/strings.cpp index 735a781..640cfb3 100644 --- a/project2/basics/functions/strings.cpp +++ b/project2/basics/functions/strings.cpp @@ -23,6 +23,6 @@ class Trim : public VariableImpl { private: Variable string; }; -DECLARE_COMPONENT_LOADER("trim", Trim, VariableLoader); +NAMEDFACTORY("trim", Trim, VariableFactory); diff --git a/project2/common/if.cpp b/project2/basics/if.cpp index bdd9835..4500335 100644 --- a/project2/common/if.cpp +++ b/project2/basics/if.cpp @@ -4,8 +4,10 @@ #include "scriptLoader.h" #include <boost/bind.hpp> #include <algorithm> +#include <task.h> -DECLARE_LOADER("if", If); +NAMEDFACTORY("if", If, ViewFactory); +NAMEDFACTORY("if", If, TaskFactory); StaticMessageException(NoTestsToPerform, "No tests to perform"); If::If(ScriptNodePtr e) : @@ -13,9 +15,9 @@ If::If(ScriptNodePtr e) : IHaveSubTasks(e), View(e) { - e->script->loader.addLoadTarget(e, Storer::into<ElementLoader>(&normal)); - e->script->loader.addLoadTarget(e, Storer::into<ElementLoader>(&subViews)); - e->script->loader.addLoadTarget(e, Storer::into<ElementLoader>(&test)); + e->script.lock()->loader.addLoadTarget(e, Storer::into<TaskFactory>(&normal)); + e->script.lock()->loader.addLoadTarget(e, Storer::into<ViewFactory>(&subViews)); + e->script.lock()->loader.addLoadTarget(e, Storer::into<TestFactory>(&test)); } bool diff --git a/project2/common/if.h b/project2/basics/if.h index 64f885b..a626bcc 100644 --- a/project2/common/if.h +++ b/project2/basics/if.h @@ -6,7 +6,7 @@ #include "test.h" /// Project2 component to conditionally execute its children -class If : public IHaveSubTasks, public View { +class DLL_PUBLIC If : public IHaveSubTasks, public View { public: If(ScriptNodePtr); diff --git a/project2/basics/loggers/consoleLog.cpp b/project2/basics/loggers/consoleLog.cpp index de45245..a88e6b2 100644 --- a/project2/basics/loggers/consoleLog.cpp +++ b/project2/basics/loggers/consoleLog.cpp @@ -1,5 +1,5 @@ -#include "logger.h" -#include "options.h" +#include <loggerFactory.impl.h> +#include <options.h> /// Logger that writes to the console class ConsoleLogDriver : public LogDriverBase { @@ -25,5 +25,5 @@ END_OPTIONS(ConsoleLogDriver); int ConsoleLogDriver::level; -DECLARE_LOGGER_LOADER("console", ConsoleLogDriver); +DECLARE_LOGGER("console", ConsoleLogDriver); diff --git a/project2/basics/loggers/syslogLog.cpp b/project2/basics/loggers/syslogLog.cpp index 8e58326..cb026c6 100644 --- a/project2/basics/loggers/syslogLog.cpp +++ b/project2/basics/loggers/syslogLog.cpp @@ -1,5 +1,5 @@ -#include "logger.h" -#include "options.h" +#include <loggerFactory.impl.h> +#include <options.h> /// Logger that writes to syslog class SyslogLogDriver : public LogDriverBase { @@ -35,5 +35,5 @@ END_OPTIONS(SyslogLogDriver); int SyslogLogDriver::level; std::string SyslogLogDriver::ident; -DECLARE_LOGGER_LOADER("syslog", SyslogLogDriver); +DECLARE_LOGGER("syslog", SyslogLogDriver); diff --git a/project2/basics/options/flagSet.h b/project2/basics/options/flagSet.h index 0e7830f..e956e8a 100644 --- a/project2/basics/options/flagSet.h +++ b/project2/basics/options/flagSet.h @@ -2,8 +2,9 @@ #define OPTIONS_FLAGSET_H #include <options.h> +#include <visibility.h> -class OptionFlagSet : public Options::Target { +class DLL_PUBLIC OptionFlagSet : public Options::Target { public: OptionFlagSet(bool * target); diff --git a/project2/basics/options/preload.cpp b/project2/basics/options/preload.cpp index 5cf42e8..1968023 100644 --- a/project2/basics/options/preload.cpp +++ b/project2/basics/options/preload.cpp @@ -2,12 +2,12 @@ #include <options.h> #include <library.h> #include <appInstance.h> -#include <boost/filesystem/path.hpp> +#include <filesystem> #include <map> #include <dlfcn.h> #include <logger.h> -using namespace boost::filesystem; +using namespace std::filesystem; class Preload { public: @@ -19,23 +19,24 @@ class Preload { static void LoadLibrary(const VariableType & librarypath) { - const auto beforeOpts = InstanceSet<Options>::GetAll(); + const auto beforeOpts = AdHoc::PluginManager::getDefault()->getAll<Options>(); - void * handle = dlopen(librarypath, RTLD_GLOBAL | RTLD_NOW); + std::string path(librarypath.as<std::string>()); + void * handle = dlopen(path.c_str(), RTLD_GLOBAL | RTLD_NOW); if (handle) { - Logger()->messagebf(LOG_DEBUG, "Loaded library '%s'", librarypath.as<std::string>()); + Logger()->messagebf(LOG_DEBUG, "Loaded library '%s'", path); } else { const char * dlerr = dlerror(); - Logger()->messagebf(LOG_ERR, "Failed to load library '%s' (%s)", librarypath.as<std::string>(), dlerr); + Logger()->messagebf(LOG_ERR, "Failed to load library '%s' (%s)", path, dlerr); throw LoadLibraryFailed(librarypath, dlerr); } libs[librarypath.as<std::string>()] = boost::shared_ptr<void>(handle, &dlclose); - const auto afterOpts = InstanceSet<Options>::GetAll(); + const auto afterOpts = AdHoc::PluginManager::getDefault()->getAll<Options>(); for (const auto & opt : afterOpts) { if (std::find(beforeOpts.begin(), beforeOpts.end(), opt) == beforeOpts.end()) { - opt->reset(); + opt->implementation()->reset(); } } } diff --git a/project2/basics/options/showHelp.cpp b/project2/basics/options/showHelp.cpp index 86dbc6f..0b32043 100644 --- a/project2/basics/options/showHelp.cpp +++ b/project2/basics/options/showHelp.cpp @@ -8,11 +8,13 @@ void ShowHelpComponent::onConfigLoad() if (!showHelp) return; fprintf(stdout, "Help\n"); - InstanceSet<Options>::OnAll(boost::bind(&ShowHelpComponent::outputOptions, this, _1)); + for (auto opts : AdHoc::PluginManager::getDefault()->getAll<Options>()) { + outputOptions(opts->implementation()); + } exit(1); } -void ShowHelpComponent::outputOptions(const Options * options) const +void ShowHelpComponent::outputOptions(std::shared_ptr<const Options> options) const { fprintf(stdout, " * %s\n", options->name.c_str()); for (const auto & option : options->allOptions()) { @@ -23,9 +25,9 @@ void ShowHelpComponent::outputOptions(const Options * options) const Options::TargetPtr ShowHelpComponent::Option() { - return new OptionFlagSet(&showHelp); + return std::make_shared<OptionFlagSet>(&showHelp); } bool ShowHelpComponent::showHelp; -DECLARE_COMPONENT("ShowHelpComponent", ShowHelpComponent); +NAMEDPLUGIN("ShowHelpComponent", ShowHelpComponent, LifeCycle); diff --git a/project2/basics/options/showHelp.h b/project2/basics/options/showHelp.h index 75fb4cb..a0878fe 100644 --- a/project2/basics/options/showHelp.h +++ b/project2/basics/options/showHelp.h @@ -1,16 +1,17 @@ #ifndef SHOWHELP_H #define SHOWHELP_H -#include <componentLoader.h> #include <options.h> +#include <lifeCycle.h> +#include <visibility.h> -class ShowHelpComponent : public ComponentLoader { +class DLL_PUBLIC ShowHelpComponent : public LifeCycle { public: void onConfigLoad() override; static Options::TargetPtr Option(); private: - void outputOptions(const Options * options) const; + void outputOptions(std::shared_ptr<const Options> options) const; static bool showHelp; }; diff --git a/project2/basics/pch.hpp b/project2/basics/pch.hpp index 67ec9b4..2bbfaf4 100644 --- a/project2/basics/pch.hpp +++ b/project2/basics/pch.hpp @@ -2,25 +2,14 @@ #ifndef COMMON_PCH #define COMMON_PCH -#include <aggregate.h> #include <algorithm> #include <boost/algorithm/string/predicate.hpp> #include <boost/bind.hpp> #include <boost/date_time.hpp> -#include <boost/filesystem/operations.hpp> -#include <commonObjects.h> -#include <iHaveParameters.h> #include <iostream> #include <list> -#include <logger.h> -#include <rowProcessor.h> -#include <rowSet.h> -#include <safeMapFind.h> -#include <scriptLoader.h> -#include <scripts.h> -#include <scriptStorage.h> -#include <test.h> -#include <variables.h> +#include <boost/variant/variant_fwd.hpp> +#include <boost/function/function_fwd.hpp> #endif #endif diff --git a/project2/common/iterate.cpp b/project2/basics/tasks/iterate.cpp index ae73cdb..6ab1260 100644 --- a/project2/common/iterate.cpp +++ b/project2/basics/tasks/iterate.cpp @@ -3,16 +3,15 @@ #include "logger.h" #include <boost/bind.hpp> #include "scriptLoader.h" -#include "scopeObject.h" -DECLARE_LOADER("iterate", Iterate); +NAMEDFACTORY("iterate", Iterate, TaskFactory); Iterate::Iterate(ScriptNodePtr p) : SourceObject(p), IHaveSubTasks(p), RowProcessor(p) { - p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&normal)); + p->script.lock()->loader.addLoadTarget(p, Storer::into<TaskFactory>(&normal)); } Iterate::~Iterate() diff --git a/project2/common/iterate.h b/project2/basics/tasks/iterate.h index 2afbe98..ca3a7ba 100644 --- a/project2/common/iterate.h +++ b/project2/basics/tasks/iterate.h @@ -6,10 +6,10 @@ #include "scriptStorage.h" class Iterate; -typedef boost::intrusive_ptr<Iterate> IteratePtr; +typedef std::shared_ptr<Iterate> IteratePtr; /// Project2 component to iterate over a row set, executing its children for each record -class Iterate : public IHaveSubTasks, public RowProcessor { +class DLL_PUBLIC Iterate : public IHaveSubTasks, public RowProcessor { public: Iterate(ScriptNodePtr p); virtual ~Iterate(); diff --git a/project2/basics/tasks/session/sessionClearTask.cpp b/project2/basics/tasks/session/sessionClearTask.cpp index 8a21791..2b016be 100644 --- a/project2/basics/tasks/session/sessionClearTask.cpp +++ b/project2/basics/tasks/session/sessionClearTask.cpp @@ -4,7 +4,7 @@ #include "session.h" #include "execContext.h" -DECLARE_LOADER("sessionclear", SessionClearTask); +NAMEDFACTORY("sessionclear", SessionClearTask, TaskFactory); SessionClearTask::SessionClearTask(ScriptNodePtr p) : SourceObject(p), diff --git a/project2/basics/tasks/session/sessionClearTask.h b/project2/basics/tasks/session/sessionClearTask.h index ead88bf..d5103a5 100644 --- a/project2/basics/tasks/session/sessionClearTask.h +++ b/project2/basics/tasks/session/sessionClearTask.h @@ -10,7 +10,7 @@ class CommonObjects; /// Project2 component to remove a variable from the session -class SessionClearTask : public Task { +class DLL_PUBLIC SessionClearTask : public Task { public: SessionClearTask(ScriptNodePtr p); virtual ~SessionClearTask(); diff --git a/project2/basics/tasks/session/sessionSetTask.cpp b/project2/basics/tasks/session/sessionSetTask.cpp index 120dd06..f009e46 100644 --- a/project2/basics/tasks/session/sessionSetTask.cpp +++ b/project2/basics/tasks/session/sessionSetTask.cpp @@ -4,7 +4,7 @@ #include "session.h" #include "execContext.h" -DECLARE_LOADER("sessionset", SessionSetTask); +NAMEDFACTORY("sessionset", SessionSetTask, TaskFactory); SessionSetTask::SessionSetTask(ScriptNodePtr p) : SourceObject(p), diff --git a/project2/basics/tasks/session/sessionSetTask.h b/project2/basics/tasks/session/sessionSetTask.h index d38c216..51222c0 100644 --- a/project2/basics/tasks/session/sessionSetTask.h +++ b/project2/basics/tasks/session/sessionSetTask.h @@ -11,7 +11,7 @@ class CommonObjects; /// Project2 component to add/update a variable in the session -class SessionSetTask : public Task { +class DLL_PUBLIC SessionSetTask : public Task { public: SessionSetTask(ScriptNodePtr p); virtual ~SessionSetTask(); diff --git a/project2/basics/tasks/structExceptHandling.cpp b/project2/basics/tasks/structExceptHandling.cpp index b79dae6..b77a4a8 100644 --- a/project2/basics/tasks/structExceptHandling.cpp +++ b/project2/basics/tasks/structExceptHandling.cpp @@ -3,16 +3,17 @@ #include "scriptLoader.h" #include "scriptStorage.h" #include "scripts.h" +#include <task.h> -DECLARE_LOADER("handler", StructuredExceptionHandler); +NAMEDFACTORY("handler", StructuredExceptionHandler, TaskFactory); StructuredExceptionHandler::StructuredExceptionHandler(ScriptNodePtr e) : SourceObject(e), IHaveSubTasks(e) { - e->script->loader.addLoadTargetSub(e, "try", true, Storer::into<ElementLoader>(&normal)); - e->script->loader.addLoadTargetSub(e, "catch", false, Storer::into<ElementLoader>(&catches)); - e->script->loader.addLoadTargetSub(e, "finally", false, Storer::into<ElementLoader>(&finallies)); + e->script.lock()->loader.addLoadTargetSub(e, "try", true, Storer::into<TaskFactory>(&normal)); + e->script.lock()->loader.addLoadTargetSub(e, "catch", false, Storer::into<TaskFactory>(&catches)); + e->script.lock()->loader.addLoadTargetSub(e, "finally", false, Storer::into<TaskFactory>(&finallies)); } void diff --git a/project2/basics/tasks/structExceptHandling.h b/project2/basics/tasks/structExceptHandling.h index b6702f1..e6f0398 100644 --- a/project2/basics/tasks/structExceptHandling.h +++ b/project2/basics/tasks/structExceptHandling.h @@ -3,7 +3,7 @@ #include "iHaveSubTasks.h" -class StructuredExceptionHandler : public IHaveSubTasks { +class DLL_PUBLIC StructuredExceptionHandler : public IHaveSubTasks { public: StructuredExceptionHandler(ScriptNodePtr); diff --git a/project2/basics/tests/compoundTest.cpp b/project2/basics/tests/compoundTest.cpp index 3799d06..2b9d1d7 100644 --- a/project2/basics/tests/compoundTest.cpp +++ b/project2/basics/tests/compoundTest.cpp @@ -10,7 +10,7 @@ CompoundTest::CompoundTest(ScriptNodePtr s) : SourceObject(s), Test(s) { - s->script->loader.addLoadTarget(s, Storer::into<ElementLoader>(&tests)); + s->script.lock()->loader.addLoadTarget(s, Storer::into<TestFactory>(&tests)); } class All : public CompoundTest { @@ -26,7 +26,7 @@ class All : public CompoundTest { return (std::find_if(tests.begin(), tests.end(), !boost::bind(&Test::passes, _1, ec)) == tests.end()); } }; -DECLARE_LOADER("all", All); +NAMEDFACTORY("all", All, TestFactory); class Any : public CompoundTest { public: @@ -41,7 +41,7 @@ class Any : public CompoundTest { return (std::find_if(tests.begin(), tests.end(), boost::bind(&Test::passes, _1, ec)) != tests.end()); } }; -DECLARE_LOADER("any", Any); +NAMEDFACTORY("any", Any, TestFactory); class None : public CompoundTest { public: @@ -56,7 +56,7 @@ class None : public CompoundTest { return (std::find_if(tests.begin(), tests.end(), boost::bind(&Test::passes, _1, ec)) == tests.end()); } }; -DECLARE_LOADER("none", None); +NAMEDFACTORY("none", None, TestFactory); class Not : public Test { public: @@ -64,7 +64,7 @@ class Not : public Test { SourceObject(s), Test(s) { - s->script->loader.addLoadTarget(s, Storer::into<ElementLoader>(&test)); + s->script.lock()->loader.addLoadTarget(s, Storer::into<TestFactory>(&test)); } bool passes(ExecContext * ec) const { if (!test) { @@ -75,4 +75,4 @@ class Not : public Test { private: TestPtr test; }; -DECLARE_LOADER("not", Not); +NAMEDFACTORY("not", Not, TestFactory); diff --git a/project2/basics/tests/compoundTest.h b/project2/basics/tests/compoundTest.h index cc213c3..182ed0e 100644 --- a/project2/basics/tests/compoundTest.h +++ b/project2/basics/tests/compoundTest.h @@ -4,7 +4,7 @@ #include <test.h> #include "scriptStorage.h" -class CompoundTest : public Test { +class DLL_PUBLIC CompoundTest : public Test { public: CompoundTest(ScriptNodePtr); diff --git a/project2/basics/tests/equals.cpp b/project2/basics/tests/equals.cpp index 425d317..3f32053 100644 --- a/project2/basics/tests/equals.cpp +++ b/project2/basics/tests/equals.cpp @@ -16,9 +16,9 @@ class Equals : public Test { bool passes(ExecContext * ec) const { return (a(ec) == b(ec)); } - + private: Variable a, b; }; -DECLARE_LOADER("equals", Equals); +NAMEDFACTORY("equals", Equals, TestFactory); diff --git a/project2/basics/tests/greaterthan.cpp b/project2/basics/tests/greaterthan.cpp index b43cef1..01e5812 100644 --- a/project2/basics/tests/greaterthan.cpp +++ b/project2/basics/tests/greaterthan.cpp @@ -16,9 +16,9 @@ class GreaterThan : public Test { bool passes(ExecContext * ec) const { return (a(ec) > b(ec)); } - + private: Variable a, b; }; -DECLARE_LOADER("greaterthan", GreaterThan); +NAMEDFACTORY("greaterthan", GreaterThan, TestFactory); diff --git a/project2/basics/tests/greaterthanorequal.cpp b/project2/basics/tests/greaterthanorequal.cpp index 67328b2..f5f0124 100644 --- a/project2/basics/tests/greaterthanorequal.cpp +++ b/project2/basics/tests/greaterthanorequal.cpp @@ -16,9 +16,9 @@ class GreaterThanOrEqual : public Test { bool passes(ExecContext * ec) const { return (a(ec) >= b(ec)); } - + private: Variable a, b; }; -DECLARE_LOADER("greaterthanorequal", GreaterThanOrEqual); +NAMEDFACTORY("greaterthanorequal", GreaterThanOrEqual, TestFactory); diff --git a/project2/basics/tests/isdistinct.cpp b/project2/basics/tests/isdistinct.cpp index 47ed647..2c95535 100644 --- a/project2/basics/tests/isdistinct.cpp +++ b/project2/basics/tests/isdistinct.cpp @@ -37,4 +37,5 @@ class IsDistinct : public Test, IHaveParameters { typedef std::set<Vars> Rows; mutable Rows previous; }; -DECLARE_LOADER("isdistinct", IsDistinct); +NAMEDFACTORY("isdistinct", IsDistinct, TestFactory); + diff --git a/project2/basics/tests/isuniq.cpp b/project2/basics/tests/isuniq.cpp index dc71ac5..295be40 100644 --- a/project2/basics/tests/isuniq.cpp +++ b/project2/basics/tests/isuniq.cpp @@ -45,4 +45,5 @@ class IsUniq : public Test, IHaveParameters { typedef std::vector<VariableType> Vars; mutable Vars previous; }; -DECLARE_LOADER("isuniq", IsUniq); +NAMEDFACTORY("isuniq", IsUniq, TestFactory); + diff --git a/project2/basics/tests/lessthan.cpp b/project2/basics/tests/lessthan.cpp index f040532..3f172ef 100644 --- a/project2/basics/tests/lessthan.cpp +++ b/project2/basics/tests/lessthan.cpp @@ -16,9 +16,9 @@ class LessThan : public Test { bool passes(ExecContext * ec) const { return (a(ec) < b(ec)); } - + private: Variable a, b; }; -DECLARE_LOADER("lessthan", LessThan); +NAMEDFACTORY("lessthan", LessThan, TestFactory); diff --git a/project2/basics/tests/lessthanorequal.cpp b/project2/basics/tests/lessthanorequal.cpp index 1cb0e9e..8a64e01 100644 --- a/project2/basics/tests/lessthanorequal.cpp +++ b/project2/basics/tests/lessthanorequal.cpp @@ -16,9 +16,9 @@ class LessThanOrEqual : public Test { bool passes(ExecContext * ec) const { return (a(ec) <= b(ec)); } - + private: Variable a, b; }; -DECLARE_LOADER("lessthanorequal", LessThanOrEqual); +NAMEDFACTORY("lessthanorequal", LessThanOrEqual, TestFactory); diff --git a/project2/basics/tests/notequals.cpp b/project2/basics/tests/notequals.cpp index aeb784e..bbf3186 100644 --- a/project2/basics/tests/notequals.cpp +++ b/project2/basics/tests/notequals.cpp @@ -16,9 +16,9 @@ class NotEquals : public Test { bool passes(ExecContext * ec) const { return (a(ec) != b(ec)); } - + private: Variable a, b; }; -DECLARE_LOADER("notequals", NotEquals); +NAMEDFACTORY("notequals", NotEquals, TestFactory); diff --git a/project2/basics/tests/validDateCheck.cpp b/project2/basics/tests/validDateCheck.cpp index b1ab5a3..a17933f 100644 --- a/project2/basics/tests/validDateCheck.cpp +++ b/project2/basics/tests/validDateCheck.cpp @@ -27,17 +27,17 @@ class ValidDateTest : public Test { struct tm tm, ftm; memset(&tm, 0, sizeof(struct tm)); mktime(&tm); - const char * at = applyTo(ec); - const char * f = format(ec); - const char * s = strptime(at, f, &tm); + const std::string at = applyTo(ec); + const std::string f = format(ec); + const char * s = strptime(at.c_str(), f.c_str(), &tm); if (!s || *s) { - Logger()->messagef(warnLev, "%s: check failed (parse) for '%s' against '%s'", + Logger()->messagebf(warnLev, "%s: check failed (parse) for '%s' against '%s'", __PRETTY_FUNCTION__, at, f); return false; } ftm = tm; if (mktime(&ftm) == -1) { - Logger()->messagef(warnLev, "%s: check failed (normalise) for '%s' against '%s'", + Logger()->messagebf(warnLev, "%s: check failed (normalise) for '%s' against '%s'", __PRETTY_FUNCTION__, at, f); return false; } @@ -51,7 +51,7 @@ class ValidDateTest : public Test { tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); Logger()->messagef(LOG_INFO, "ftm: %d %d %d %d %d %d", ftm.tm_year, ftm.tm_mon, ftm.tm_mday, ftm.tm_hour, ftm.tm_min, ftm.tm_sec); - Logger()->messagef(warnLev, "%s: check failed (verify) for '%s' against '%s'", + Logger()->messagebf(warnLev, "%s: check failed (verify) for '%s' against '%s'", __PRETTY_FUNCTION__, at, f); return false; } @@ -62,5 +62,5 @@ class ValidDateTest : public Test { int warnLev; }; -DECLARE_LOADER("validdatetest", ValidDateTest); +NAMEDFACTORY("validdatetest", ValidDateTest, TestFactory); diff --git a/project2/basics/unittests/Jamfile.jam b/project2/basics/unittests/Jamfile.jam index 167c7c6..5892cd9 100644 --- a/project2/basics/unittests/Jamfile.jam +++ b/project2/basics/unittests/Jamfile.jam @@ -6,26 +6,30 @@ lib dummylib : <library>../../common//p2common ; -unit-test testLibraries : +path-constant me : . ; + +run testLibraries.cpp - : - <dependency>dummylib + : : dummylib : <library>../../common//p2common <library>..//p2basics <library>../../ut//p2ut - <library>..//boost_filesystem + <library>..//stdc++fs + : + testLibraries : ; -path-constant me : . ; - -unit-test standardTests : +run [ glob *.cpp : testLibraries.cpp dummylib.cpp ] - : + : : : <define>ROOT=\"$(me)\" <library>../../common//p2common <library>..//p2basics <library>../../ut//p2ut <library>../../xml//p2xml - <library>..//boost_filesystem + <library>../../url//p2url + <library>..//stdc++fs + : + standardTests : ; diff --git a/project2/basics/unittests/dummylib.cpp b/project2/basics/unittests/dummylib.cpp index 2e919a0..a493f3c 100644 --- a/project2/basics/unittests/dummylib.cpp +++ b/project2/basics/unittests/dummylib.cpp @@ -13,5 +13,5 @@ class DummyTask : public Task { } }; -DECLARE_LOADER("DummyTask", DummyTask); +NAMEDFACTORY("DummyTask", DummyTask, TaskFactory); diff --git a/project2/basics/unittests/testLibraries.cpp b/project2/basics/unittests/testLibraries.cpp index e48d77e..c43d382 100644 --- a/project2/basics/unittests/testLibraries.cpp +++ b/project2/basics/unittests/testLibraries.cpp @@ -1,12 +1,16 @@ #define BOOST_TEST_MODULE Client #include <boost/test/unit_test.hpp> -#include <boost/filesystem/convenience.hpp> +#include <filesystem> #include <testOptionsSource.h> #include <exceptions.h> #include <library.h> +#include <task.h> #include <testAppInstance.h> -const auto self = boost::filesystem::canonical("/proc/self/exe"); +#define XSTR(s) STR(s) +#define STR(s) #s +const std::filesystem::path root(XSTR(ROOT)); +const auto self = std::filesystem::canonical("/proc/self/exe"); BOOST_FIXTURE_TEST_SUITE( Core, TestAppInstance ); @@ -21,18 +25,23 @@ BOOST_AUTO_TEST_CASE( load_missing_library ) BOOST_AUTO_TEST_CASE( load_and_unload_library ) { - BOOST_REQUIRE_THROW(ElementLoader::getFor("DummyTask"), NotSupported); + // Path to test lib needs passing in + BOOST_REQUIRE_EQUAL(2, args.size()); + auto libraryPath = args[1]; + BOOST_REQUIRE(std::filesystem::exists(libraryPath)); + + BOOST_REQUIRE_THROW(TaskFactory::get("DummyTask"), AdHoc::NoSuchPluginException); BOOST_TEST_CHECKPOINT("Configure (load)"); TestOptionsSource::LoadTestOptions({ - { "library", (self.parent_path() / "libdummylib.so").string() } + { "library", libraryPath } }); BOOST_TEST_CHECKPOINT("Verify"); - BOOST_REQUIRE(ElementLoader::getFor("DummyTask")); + BOOST_REQUIRE(TaskFactory::get("DummyTask")); BOOST_TEST_CHECKPOINT("Configure (empty)"); TestOptionsSource::LoadTestOptions({ }); - BOOST_REQUIRE_THROW(ElementLoader::getFor("DummyTask"), NotSupported); + BOOST_REQUIRE_THROW(TaskFactory::get("DummyTask"), AdHoc::NoSuchPluginException); } BOOST_AUTO_TEST_SUITE_END(); diff --git a/project2/basics/unittests/testViews.cpp b/project2/basics/unittests/testViews.cpp index a2ea224..1dbb30e 100644 --- a/project2/basics/unittests/testViews.cpp +++ b/project2/basics/unittests/testViews.cpp @@ -1,22 +1,22 @@ #define BOOST_TEST_MODULE Views #include <boost/test/unit_test.hpp> -#include <boost/filesystem/operations.hpp> +#include <filesystem> #include <xmlScriptParser.h> #include <testOptionsSource.h> #include <testScriptHost.h> #include <definedDirs.h> #include <testAppInstance.h> -boost::intrusive_ptr<TestScriptHost> -executeRowViewTest(ExecContext * ec, const boost::filesystem::path & script, const boost::filesystem::path & expected) +std::shared_ptr<TestScriptHost> +executeRowViewTest(ExecContext * ec, const std::filesystem::path & script, const std::filesystem::path & expected) { TestOptionsSource::LoadTestOptions({ - { "common.datasourceRoot", RootDir.string() }, - { "application.dataroot", ("file://" / RootDir / "data").string() }, + { "common.datasourceRoot", rootDir.string() }, + { "application.dataroot", "file://" + (rootDir / "data").string() }, }); BOOST_TEST_CHECKPOINT("Load"); - ScriptReaderPtr r = new XmlScriptParser(script); - boost::intrusive_ptr<TestScriptHost> sr = new TestScriptHost(r); + ScriptReaderPtr r = std::make_shared<XmlScriptParser>(script); + std::shared_ptr<TestScriptHost> sr = std::make_shared<TestScriptHost>(r); BOOST_TEST_CHECKPOINT("Execute"); sr->process(ec); BOOST_TEST_CHECKPOINT("Compare"); @@ -28,17 +28,17 @@ BOOST_FIXTURE_TEST_SUITE( Core, TestAppInstance ); BOOST_AUTO_TEST_CASE( test_rowview_unsetcolumns ) { - executeRowViewTest(this, RootDir / "test_rowview_unsetcolumns.xml", RootDir / "expected" / "test_rowview_unsetcolumns.log"); + executeRowViewTest(this, rootDir / "test_rowview_unsetcolumns.xml", rootDir / "expected" / "test_rowview_unsetcolumns.log"); } BOOST_AUTO_TEST_CASE( test_rowview_nocolumns ) { - executeRowViewTest(this, RootDir / "test_rowview_nocolumns.xml", RootDir / "expected" / "test_rowview_nocolumns.log"); + executeRowViewTest(this, rootDir / "test_rowview_nocolumns.xml", rootDir / "expected" / "test_rowview_nocolumns.log"); } BOOST_AUTO_TEST_CASE( test_rowview_columns ) { - executeRowViewTest(this, RootDir / "test_rowview_columns.xml", RootDir / "expected" / "test_rowview_columns.log"); + executeRowViewTest(this, rootDir / "test_rowview_columns.xml", rootDir / "expected" / "test_rowview_columns.log"); } BOOST_AUTO_TEST_SUITE_END(); diff --git a/project2/basics/views/autotree.cpp b/project2/basics/views/autotree.cpp index 2f5bb68..f96888e 100644 --- a/project2/basics/views/autotree.cpp +++ b/project2/basics/views/autotree.cpp @@ -1,12 +1,10 @@ #include <pch.hpp> #include "autotree.h" #include "presenter.h" -#include "scopeObject.h" #include "scriptLoader.h" -#include "scopeObject.h" #include <boost/bind.hpp> -DECLARE_LOADER("autotree", AutoTree); +NAMEDFACTORY("autotree", AutoTree, ViewFactory); AutoTree::AutoTree(ScriptNodePtr p) : SourceObject(p), @@ -57,7 +55,7 @@ AutoTreeNode::AutoTreeNode(ScriptNodePtr sn, unsigned int p, unsigned int d) : includes.insert({n->value("name", NULL).as<Glib::ustring>(), Variable::fromScriptNode(n)} ); } if (sn->valueExists("tree")) { - tree = new AutoTreeNode(sn->child("tree"), pos + keys.size(), depth + 1); + tree = std::make_shared<AutoTreeNode>(sn->child("tree"), pos + keys.size(), depth + 1); } } diff --git a/project2/basics/views/autotree.h b/project2/basics/views/autotree.h index 48f46be..9276bab 100644 --- a/project2/basics/views/autotree.h +++ b/project2/basics/views/autotree.h @@ -1,15 +1,14 @@ #ifndef AUTOTREE_H #define AUTOTREE_H -#include <boost/intrusive_ptr.hpp> #include "rowProcessor.h" #include "view.h" #include "aggregate.h" class AutoTreeNode; -typedef boost::intrusive_ptr<const AutoTreeNode> AutoTreeNodePtr; +typedef std::shared_ptr<const AutoTreeNode> AutoTreeNodePtr; -class AutoTreeState { +class DLL_PUBLIC AutoTreeState { public: typedef boost::tuple<bool, bool> Opened; @@ -17,7 +16,7 @@ class AutoTreeState { std::vector<VariableType> values; }; -class AutoTreeNode : public IntrusivePtrBase { +class DLL_PUBLIC AutoTreeNode { public: typedef std::map<Glib::ustring, Variable> Values; @@ -29,7 +28,7 @@ class AutoTreeNode : public IntrusivePtrBase { void closeArray(const MultiRowSetPresenter * p, ExecContext *, AutoTreeState & state) const; void closeObject(const MultiRowSetPresenter * p, ExecContext *, AutoTreeState & state) const; AutoTreeNodePtr child() const; - + protected: private: @@ -44,7 +43,7 @@ class AutoTreeNode : public IntrusivePtrBase { }; /// Project2 component to create tree output based on a records in a row set -class AutoTree : public View, public RowProcessor { +class DLL_PUBLIC AutoTree : public View, public RowProcessor { public: AutoTree(ScriptNodePtr); virtual ~AutoTree(); diff --git a/project2/basics/views/flatView.cpp b/project2/basics/views/flatView.cpp index af49d0d..36c0427 100644 --- a/project2/basics/views/flatView.cpp +++ b/project2/basics/views/flatView.cpp @@ -1,12 +1,12 @@ #include "pch.hpp" #include "flatView.h" #include "presenter.h" -#include "scopeObject.h" #include "scriptLoader.h" -#include "scopeObject.h" #include <boost/bind.hpp> +#include <factory.impl.h> -DECLARE_LOADER("flatview", FlatView); +NAMEDFACTORY("flatview", FlatView, FlatViewFactory); +INSTANTIATEFACTORY(FlatView, std::shared_ptr<const ScriptNode>); FlatView::FlatView(ScriptNodePtr p) : SourceObject(p), diff --git a/project2/basics/views/flatView.h b/project2/basics/views/flatView.h index 5dc24dc..72acabc 100644 --- a/project2/basics/views/flatView.h +++ b/project2/basics/views/flatView.h @@ -5,9 +5,10 @@ #include "rowProcessor.h" #include "view.h" #include "aggregate.h" +#include <visibility.h> /// Project2 component to create output based on a records in a flat row set -class FlatView : public SourceObject, public RowProcessor { +class DLL_PUBLIC FlatView : public SourceObject, public RowProcessor { public: FlatView(ScriptNodePtr); virtual ~FlatView(); @@ -23,6 +24,7 @@ class FlatView : public SourceObject, public RowProcessor { typedef std::map<Glib::ustring, Variable> Columns; Columns viewColumns; }; +typedef AdHoc::Factory<FlatView, std::shared_ptr<const ScriptNode>> FlatViewFactory; #endif diff --git a/project2/basics/views/rowView.cpp b/project2/basics/views/rowView.cpp index 9727480..f5e108b 100644 --- a/project2/basics/views/rowView.cpp +++ b/project2/basics/views/rowView.cpp @@ -1,12 +1,11 @@ #include <pch.hpp> #include "rowView.h" #include "presenter.h" -#include "scopeObject.h" #include "scriptLoader.h" -#include "scopeObject.h" +#include <scopeExit.h> #include <boost/bind.hpp> -DECLARE_LOADER("view", RowView); +NAMEDFACTORY("view", RowView, ViewFactory); RowView::RowView(ScriptNodePtr p) : SourceObject(p), @@ -24,9 +23,9 @@ RowView::RowView(ScriptNodePtr p) : viewColumns->insert(Columns::value_type(node->get_name(), Variable(node))); } } - p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&subViews)); - p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&valueAggregates)); - p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&setAggregates)); + p->script.lock()->loader.addLoadTarget(p, Storer::into<ViewFactory>(&subViews)); + p->script.lock()->loader.addLoadTarget(p, Storer::into<ValueAggregateFactory>(&valueAggregates)); + p->script.lock()->loader.addLoadTarget(p, Storer::into<SetAggregateFactory>(&setAggregates)); } RowView::~RowView() @@ -73,10 +72,10 @@ RowView::execute(const MultiRowSetPresenter * p, ExecContext * ec) const p->addNewRowSet(rootName(ec)); } bool rowsFound = false; - ScopeObject pres(rootName(ec).isNull() ? ScopeObject::Event() : boost::bind(&MultiRowSetPresenter::finishRowSet, p)); + AdHoc::ScopeExit pres(rootName(ec).isNull() ? AdHoc::ScopeExit::Event() : boost::bind(&MultiRowSetPresenter::finishRowSet, p)); { p->addNewArray(recordName(ec), true); - ScopeObject pres(boost::bind(&MultiRowSetPresenter::finishArray, p, true)); + AdHoc::ScopeExit pres(boost::bind(&MultiRowSetPresenter::finishArray, p, true)); RowProcessor::execute(ec, boost::bind(&RowView::rowReady, this, _1, p, ec, boost::ref(rowsFound))); } if (required(ec) && !rowsFound) { @@ -85,7 +84,7 @@ RowView::execute(const MultiRowSetPresenter * p, ExecContext * ec) const for (SetAggregateCPtr s : setAggregates) { p->addNewArray(s->name, false); - ScopeObject pres(boost::bind(&MultiRowSetPresenter::finishArray, p, false)); + AdHoc::ScopeExit pres(boost::bind(&MultiRowSetPresenter::finishArray, p, false)); s->onResultValues(boost::bind(&MultiRowSetPresenter::addNamedValue, p, "value", _1)); s->reset(); } diff --git a/project2/basics/views/rowView.h b/project2/basics/views/rowView.h index a65ea69..1ace513 100644 --- a/project2/basics/views/rowView.h +++ b/project2/basics/views/rowView.h @@ -8,7 +8,7 @@ #include "aggregate.h" /// Project2 component to create output based on a records in a row set -class RowView : public View, public RowProcessor { +class DLL_PUBLIC RowView : public View, public RowProcessor { public: RowView(ScriptNodePtr); virtual ~RowView(); diff --git a/project2/basics/views/singleton.cpp b/project2/basics/views/singleton.cpp index c67fb12..913776a 100644 --- a/project2/basics/views/singleton.cpp +++ b/project2/basics/views/singleton.cpp @@ -2,7 +2,7 @@ #include "view.h" #include "iHaveParameters.h" #include "presenter.h" -#include "scopeObject.h" +#include <scopeExit.h> class Singleton : public View { public: @@ -14,12 +14,12 @@ class Singleton : public View { for (ScriptNodePtr node : p->childrenIn("columns")) { viewColumns.insert(Columns::value_type(node->get_name(), Variable(node))); } - p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&subViews)); + p->script.lock()->loader.addLoadTarget(p, Storer::into<ViewFactory>(&subViews)); } void execute(const MultiRowSetPresenter * p, ExecContext * ec) const { p->addNewRowSet(rootName(ec)); - ScopeObject pres(boost::bind(&MultiRowSetPresenter::finishRowSet, p)); + AdHoc::ScopeExit pres(boost::bind(&MultiRowSetPresenter::finishRowSet, p)); for (const Columns::value_type & col : viewColumns) { p->addNamedValue(col.first, col.second(ec)); } @@ -40,5 +40,5 @@ class Singleton : public View { typedef ANONSTORAGEOF(View) SubViews; SubViews subViews; }; -DECLARE_LOADER("singleton", Singleton); +NAMEDFACTORY("singleton", Singleton, ViewFactory); diff --git a/project2/basics/views/viewGroup.cpp b/project2/basics/views/viewGroup.cpp index 0049e9d..591babd 100644 --- a/project2/basics/views/viewGroup.cpp +++ b/project2/basics/views/viewGroup.cpp @@ -7,7 +7,7 @@ class ViewGroup : public View { SourceObject(s), View(s) { - s->script->loader.addLoadTarget(s, Storer::into<ElementLoader>(&subViews)); + s->script.lock()->loader.addLoadTarget(s, Storer::into<ViewFactory>(&subViews)); } void execute(const MultiRowSetPresenter * presenter, ExecContext * ec) const @@ -23,4 +23,4 @@ class ViewGroup : public View { SubViews subViews; }; -DECLARE_LOADER("viewgroup", ViewGroup); +NAMEDFACTORY("viewgroup", ViewGroup, ViewFactory); diff --git a/project2/cgi/FCgiIO.cpp b/project2/cgi/FCgiIO.cpp index e47b62e..9d26329 100644 --- a/project2/cgi/FCgiIO.cpp +++ b/project2/cgi/FCgiIO.cpp @@ -83,7 +83,7 @@ cgicc::FCgiIO::getenv(const char *varName) std::string cgicc::FCgiIO::getenv(const std::string & varName) const { - return defaultMapFind(fEnv, varName, ""); + return AdHoc::defaultMapLookup(fEnv, varName, std::string()); } std::ostream & diff --git a/project2/cgi/Jamfile.jam b/project2/cgi/Jamfile.jam index 14b681e..9f47a72 100644 --- a/project2/cgi/Jamfile.jam +++ b/project2/cgi/Jamfile.jam @@ -2,18 +2,17 @@ alias glibmm : : : : <cflags>"`pkg-config --cflags glibmm-2.4`" <linkflags>"`pkg-config --libs glibmm-2.4`" ; -lib boost_filesystem : : <name>boost_filesystem ; +lib stdc++fs ; lib cgicc : : <name>cgicc ; lib fcgi : : <name>fcgi ; lib fcgi++ : : <name>fcgi++ ; lib gcrypt : : <name>gcrypt ; cpp-pch pch : pch.hpp : - <include>../../libmisc <library>cgicc <library>glibmm <library>../common//p2common - <library>boost_filesystem + <library>stdc++fs <library>../xml//p2xml ; lib p2cgicommon : @@ -21,12 +20,11 @@ lib p2cgicommon : [ glob cgi*.cpp ] : <include>. - <include>../libmisc <library>cgicc <library>glibmm <library>../common//p2common - <library>../lib//p2lib - <library>boost_filesystem + <library>..//adhocutil + <library>stdc++fs <library>../xml//p2xml <library>gcrypt : : @@ -39,7 +37,6 @@ exe p2cgi : p2webCgi.cpp : <library>p2cgicommon - <include>../../libmisc ; exe p2fcgi : @@ -48,8 +45,7 @@ exe p2fcgi : fcgi : <library>p2cgicommon - <library>boost_filesystem - <include>../../libmisc + <library>stdc++fs ; exe testCgi : @@ -57,5 +53,4 @@ exe testCgi : : <library>p2cgicommon <library>../cli//p2cli - <include>../../libmisc ; diff --git a/project2/cgi/cgiAppEngine.cpp b/project2/cgi/cgiAppEngine.cpp index 7de9218..7f5195b 100644 --- a/project2/cgi/cgiAppEngine.cpp +++ b/project2/cgi/cgiAppEngine.cpp @@ -6,10 +6,9 @@ #include <cgicc/HTTPHeader.h> #include <cgicc/HTTPStatusHeader.h> #include "cgiRequestContext.h" -#include "iterate.h" #include <boost/bind.hpp> #include "ostreamWrapper.h" -#include "scopeObject.h" +#include "scopeExit.h" #include "logger.h" #include <boost/date_time/microsec_time_clock.hpp> #include <boost/uuid/uuid_io.hpp> @@ -37,7 +36,7 @@ std::string CgiApplicationEngine::onErrorPresent; std::string CgiApplicationEngine::defaultPresenter; SessionContainerPtr CgiApplicationEngine::sessionsContainer; std::string CgiApplicationEngine::sessionCookie; -boost::shared_ptr<RouterLoader> CgiApplicationEngine::router; +std::shared_ptr<const RouterFactory> CgiApplicationEngine::router; CgiApplicationEngine::PlatformHostnameList CgiApplicationEngine::platHosts; class PlatformHostnameTarget : public Options::Target { @@ -87,13 +86,13 @@ DECLARE_OPTIONS(CgiApplicationEngine, "Project2 CGI options") "The present script to use when the requested script (or child) fails") ("cgi.dumpDataDoc", Options::value(&dumpdatadoc), "Write a copy of the data document before sending it to the web server") -("cgi.sessionModule", Options::function([](const VariableType & m) { sessionsContainer = SessionContainerLoader::createNew(m); }, "xml"), +("cgi.sessionModule", Options::function([](const VariableType & m) { sessionsContainer = SessionContainerFactory::createNew(m); }, "xml"), "The module with which to implement session management") ("cgi.sessionCookie", Options::value(&sessionCookie, "sessionID"), "The name of the cookie for storing session IDs") -("cgi.hostRegex", new PlatformHostnameTarget(), +("cgi.hostRegex", std::make_shared<PlatformHostnameTarget>(), "Regular expression used to define a hostname -> platform association") -("cgi.router", Options::function([](const VariableType & r) { router = RouterLoader::getFor(r); }, "simple"), +("cgi.router", Options::function([](const VariableType & r) { router = RouterFactory::get(r); }, "simple"), "Implemenation of router model to map request paths to scripts") END_OPTIONS(CgiApplicationEngine); @@ -112,7 +111,7 @@ finalTransformSource(TransformSourcePtr ts) return ts; } for (const Targets::value_type & t : ts->getTargets()) { - if (TransformSource * tr = dynamic_cast<TransformSource *>(t.first.get())) { + if (auto tr = std::dynamic_pointer_cast<TransformSource>(t.first)) { if (TransformSourcePtr f = finalTransformSource(tr)) { return f; } @@ -129,22 +128,22 @@ CgiApplicationEngine::process(std::ostream & IO, CgiRequestContext * crc) const crc->startTime = boost::date_time::microsec_clock<boost::posix_time::ptime>::universal_time(); bool triedNotFound = false; bool triedOnError = false; - NextStage currentStage = NextStage(new InitialStage()); + NextStage currentStage = NextStage(std::make_shared<InitialStage>()); do { try { currentStage = currentStage.get<0>()->run(crc); } catch (const CheckHost::CheckFailure & cf) { - currentStage = NextStage(new PresentStage(ScriptReader::resolveScript(presentRoot, cf.failedCheck->present(crc), false), crc)); + currentStage = NextStage(std::make_shared<PresentStage>(ScriptReader::resolveScript(presentRoot, cf.failedCheck->present(crc), false), crc)); } catch (const ScriptNotFound & nf) { Logger()->messagebf(LOG_ERR, "%s: Resource not found: %s", __FUNCTION__, nf.what()); if (notFoundPresent.empty() || triedNotFound) { - currentStage = NextStage(new DefaultNotFoundStage(nf)); + currentStage = NextStage(std::make_shared<DefaultNotFoundStage>(nf)); } else { triedNotFound = true; - currentStage = NextStage(new CustomNotFoundStage(nf, ScriptReader::resolveScript(errorPresentRoot, notFoundPresent, false), crc)); + currentStage = NextStage(std::make_shared<CustomNotFoundStage>(nf, ScriptReader::resolveScript(errorPresentRoot, notFoundPresent, false), crc)); } } catch (const std::exception & ex) { @@ -152,11 +151,11 @@ CgiApplicationEngine::process(std::ostream & IO, CgiRequestContext * crc) const Logger()->messagebf(LOG_WARNING, "%s: Error processing stage: %s (what: %s)", __FUNCTION__, buf, ex.what()); free(buf); if (onErrorPresent.empty() || triedOnError) { - currentStage = NextStage(new DefaultErrorStage(ex, crc)); + currentStage = NextStage(std::make_shared<DefaultErrorStage>(ex, crc)); } else { triedNotFound = true; - currentStage = NextStage(new CustomErrorStage(ex, ScriptReader::resolveScript(errorPresentRoot, onErrorPresent, false), crc)); + currentStage = NextStage(std::make_shared<CustomErrorStage>(ex, ScriptReader::resolveScript(errorPresentRoot, onErrorPresent, false), crc)); } } } while (currentStage.get<0>()); @@ -175,14 +174,14 @@ CgiApplicationEngine::process(std::ostream & IO, CgiRequestContext * crc) const } if (TransformSourcePtr ts = currentStage.get<2>()) { TransformSourcePtr final = finalTransformSource(ts); - ScopeObject emptyFinal([final] { final->clearTargets(); }); + AdHoc::ScopeExit emptyFinal([final] { final->clearTargets(); }); boost::shared_ptr<std::fstream> ddd; - ostreamWrapper * osw = NULL; - ScopeObject removeDdd([ts, &osw] { if (osw) { ts->removeTarget(osw); } }); + std::shared_ptr<ostreamWrapper> osw; + AdHoc::ScopeExit removeDdd([ts, &osw] { if (osw) { ts->removeTarget(osw); } }); if (!dumpdatadoc.empty()) { ddd = boost::shared_ptr<std::fstream>(new std::fstream(dumpdatadoc.c_str(), std::fstream::trunc | std::fstream::out)); if (ddd->good()) { - ts->addTarget(osw = new ostreamWrapper(*ddd), crc, NULL); + ts->addTarget(osw = std::make_shared<ostreamWrapper>(*ddd), crc, NULL); } else { ddd.reset(); @@ -197,14 +196,14 @@ CgiApplicationEngine::process(std::ostream & IO, CgiRequestContext * crc) const p->flushCache(); } if (rs->caches.front()->check(0, crc)) { - ScopeObject emptyFinal([rs] { rs->caches.front()->clearTargets(); }); - rs->caches.front()->addTarget(new CgiResult(header, IO, + AdHoc::ScopeExit emptyFinal([rs] { rs->caches.front()->clearTargets(); }); + rs->caches.front()->addTarget(std::make_shared<CgiResult>(header, IO, rs && rs->outputOptions ? rs->outputOptions->Encoding(crc).as<std::string>() : OutputOptions::encoding), crc, NULL); rs->caches.front()->doTransforms(crc); return; } } - final->addTarget(new CgiResult(header, IO, + final->addTarget(std::make_shared<CgiResult>(header, IO, rs && rs->outputOptions ? rs->outputOptions->Encoding(crc).as<std::string>() : OutputOptions::encoding), crc, NULL); ts->doTransforms(crc); } @@ -319,7 +318,7 @@ CgiApplicationEngine::process(std::ostream & IO, cgicc::CgiInput * cgii, const C boost::function<std::string()> sn = boost::bind(&CgiEnvInput::getenv, &cgienv, "SERVER_NAME"); OptionsSource::loadSources(boost::bind(&CgiApplicationEngine::derivedPlatform, sn)); CgiRequestContext crc(cgii, cgienv); - Plugable::onAllComponents(boost::bind(&ComponentLoader::onBefore, _1)); + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onBefore, _1)); Logger()->messagebf(LOG_DEBUG, "%s: Processing request (%s)", __FUNCTION__, crc.getRedirectURL()); process(IO, &crc); Logger()->messagef(LOG_DEBUG, "%s: Completed request", __FUNCTION__); diff --git a/project2/cgi/cgiAppEngine.h b/project2/cgi/cgiAppEngine.h index 83b34d5..3c9ba13 100644 --- a/project2/cgi/cgiAppEngine.h +++ b/project2/cgi/cgiAppEngine.h @@ -10,13 +10,13 @@ #include "xmlPresenter.h" #include "presenterCache.h" #include "sessionContainer.h" -#include <boost/intrusive_ptr.hpp> #include <boost/tuple/tuple.hpp> #include "cgiOutputOptions.h" #include "cgiHttpHeader.h" #include "cgiRequestContext.h" #include <cgicc/Cgicc.h> #include <appInstance.h> +#include <visibility.h> class Session; namespace cgicc { @@ -24,9 +24,9 @@ namespace cgicc { class CgiEnvironment; } -class CgiApplicationEngine : AppInstance { +class DLL_PUBLIC CgiApplicationEngine : AppInstance { public: - typedef boost::shared_ptr<Project2HttpHeader> HttpHeaderPtr; + typedef std::shared_ptr<Project2HttpHeader> HttpHeaderPtr; typedef std::pair<Glib::ustring, Glib::RefPtr<Glib::Regex>> PlatformHostname; typedef std::vector<PlatformHostname> PlatformHostnameList; @@ -52,18 +52,18 @@ class CgiApplicationEngine : AppInstance { public: class Stage; class ResponseStage; - typedef boost::intrusive_ptr<Stage> StagePtr; - typedef boost::intrusive_ptr<ResponseStage> ResponseStagePtr; + typedef std::shared_ptr<Stage> StagePtr; + typedef std::shared_ptr<ResponseStage> ResponseStagePtr; typedef boost::tuple<StagePtr, ResponseStagePtr, TransformSourcePtr, MultiRowSetPresenterPtr> NextStage; /// Base class for a stage iteration that should eventually produce a response for the client - class Stage : public virtual IntrusivePtrBase { + class Stage { public: virtual ~Stage() = 0; virtual NextStage run(CgiRequestContext *) = 0; }; /// Base class for a stage that can be a response to the client - class ResponseStage : public Stage { + class ResponseStage : public Stage, public std::enable_shared_from_this<ResponseStage> { public: typedef ANONORDEREDSTORAGEOF(PresenterCache) PresenterCaches; @@ -103,7 +103,7 @@ class CgiApplicationEngine : AppInstance { virtual HttpHeaderPtr getHeader(CgiRequestContext *) const; protected: HttpHeaderPtr header; - LazyPointer<MultiRowSetPresenter> presenter; + AdHoc::LazyPointer<MultiRowSetPresenter> presenter; }; /// Stage to return previous cached output @@ -161,7 +161,7 @@ class CgiApplicationEngine : AppInstance { INITOPTIONS; static PlatformHostnameList platHosts; - static boost::shared_ptr<RouterLoader> router; + static std::shared_ptr<const RouterFactory> router; static SessionContainerPtr sessionsContainer; static std::string sessionCookie; private: diff --git a/project2/cgi/cgiContentNegotiate.cpp b/project2/cgi/cgiContentNegotiate.cpp index 2494ba8..d72967a 100644 --- a/project2/cgi/cgiContentNegotiate.cpp +++ b/project2/cgi/cgiContentNegotiate.cpp @@ -3,9 +3,9 @@ #include <boost/tokenizer.hpp> #include <boost/bind.hpp> -class ContentNegotiateLoader : public PresenterLoader { +class ContentNegotiateFactory : public PresenterFactory { public: - MultiRowSetPresenter * create(const ScriptNodePtr & s, const ObjectSource & os, ExecContext * const & ec) const + MultiRowSetPresenterPtr create(std::shared_ptr<const ScriptNode> const & s, const ObjectSource & os, ExecContext * const & ec) const override { auto accept = static_cast<const CgiRequestContext *>(ec)->getAccept(); typedef boost::tokenizer<boost::char_separator<char>> tokenizer; @@ -14,15 +14,15 @@ class ContentNegotiateLoader : public PresenterLoader { if (mimetype == "*/*") break; for (const auto & t : mappedTypes) { if (t->Matches(mimetype)) { - return PresenterLoader::getFor(t->present)->create(s, os, ec); + return PresenterFactory::createNew(t->present, s, os, ec); } } } - return PresenterLoader::getFor((*mappedTypes.begin())->present)->create(s, os, ec); + return PresenterFactory::createNew((*mappedTypes.begin())->present, s, os, ec); } INITOPTIONS; - class MappedType : public IntrusivePtrBase { + class MappedType { public: MappedType(const std::string & val) : accept(val.substr(0, val.find('='))), @@ -38,20 +38,20 @@ class ContentNegotiateLoader : public PresenterLoader { const std::string accept; const std::string present; }; - typedef boost::intrusive_ptr<MappedType> MappedTypePtr; + typedef std::shared_ptr<MappedType> MappedTypePtr; typedef std::vector<MappedTypePtr> MappedTypes; static MappedTypes mappedTypes; bool cacheable() const { return false; } }; -ContentNegotiateLoader::MappedTypes ContentNegotiateLoader::mappedTypes; +ContentNegotiateFactory::MappedTypes ContentNegotiateFactory::mappedTypes; -DECLARE_CUSTOM_COMPONENT_LOADER("contentnegotiate", ContentNegotiateLoader, ContentNegotiateLoader, PresenterLoader); +NAMEDPLUGIN("contentnegotiate", ContentNegotiateFactory, PresenterFactory); -DECLARE_OPTIONS(ContentNegotiateLoader, "Content negotiation options") +DECLARE_OPTIONS(ContentNegotiateFactory, "Content negotiation options") ("cgi.contentnegotiation.mappedtype", Options::functions( - [](const VariableType & v) { mappedTypes.push_back(new MappedType(v)); }, + [](const VariableType & v) { mappedTypes.push_back(std::make_shared<MappedType>(v)); }, boost::bind(&MappedTypes::clear, &mappedTypes)), "mimetype=presenter list of types to negotiate") -END_OPTIONS(ContentNegotiateLoader) +END_OPTIONS(ContentNegotiateFactory) diff --git a/project2/cgi/cgiEnvInput.h b/project2/cgi/cgiEnvInput.h index 2704fd5..62b24ca 100644 --- a/project2/cgi/cgiEnvInput.h +++ b/project2/cgi/cgiEnvInput.h @@ -2,8 +2,9 @@ #define CGIENVINPUT #include <string> +#include <visibility.h> -class CgiEnvInput { +class DLL_PUBLIC CgiEnvInput { public: virtual std::string getenv(const std::string & varName) const = 0; }; diff --git a/project2/cgi/cgiOutputOptions.cpp b/project2/cgi/cgiOutputOptions.cpp index de3d291..a199701 100644 --- a/project2/cgi/cgiOutputOptions.cpp +++ b/project2/cgi/cgiOutputOptions.cpp @@ -1,6 +1,6 @@ #include "cgiOutputOptions.h" #include "scripts.h" -#include "instanceStore.impl.h" +#include <factory.impl.h> bool OutputOptions::core; bool OutputOptions::session; @@ -21,7 +21,7 @@ OutputOptions::OutputOptions(ScriptNodePtr p) : { } -DECLARE_OPTIONS(OutputOptionsLoader, "CGI default output options") +DECLARE_OPTIONS(OutputOptions, "CGI default output options") ("cgi.output.encoding", Options::value(&OutputOptions::encoding, "utf-8"), "Default out encoding") ("cgi.output.core", Options::value(&OutputOptions::core, true), "Core messages") ("cgi.output.session", Options::value(&OutputOptions::session, true), "Session values") @@ -29,13 +29,8 @@ DECLARE_OPTIONS(OutputOptionsLoader, "CGI default output options") ("cgi.output.environment", Options::value(&OutputOptions::environment, true), "Environment") ("cgi.output.url", Options::value(&OutputOptions::url, true), "URL breakdown") ("cgi.output.parameters", Options::value(&OutputOptions::parameters, true), "Parameters") -END_OPTIONS(OutputOptionsLoader) +END_OPTIONS(OutputOptions) -OutputOptionsPtr -OutputOptionsLoader::create(ScriptNodePtr e) const { - return new OutputOptions(e); -} - -DECLARE_CUSTOM_COMPONENT_LOADER("outputoptions", OutputOptions, OutputOptionsLoader, OutputOptionsLoader) -INSTANTIATESTORE(std::string, OutputOptionsLoader); +NAMEDFACTORY("outputoptions", OutputOptions, OutputOptionsFactory) +INSTANTIATEFACTORY(OutputOptions, std::shared_ptr<const ScriptNode>); diff --git a/project2/cgi/cgiOutputOptions.h b/project2/cgi/cgiOutputOptions.h index be2c452..55d75c7 100644 --- a/project2/cgi/cgiOutputOptions.h +++ b/project2/cgi/cgiOutputOptions.h @@ -1,11 +1,10 @@ #ifndef OUTPUTOPTIONS_H #define OUTPUTOPTIONS_H -#include "intrusivePtrBase.h" #include "options.h" #include "variables.h" -class OutputOptions : public IntrusivePtrBase { +class DLL_PUBLIC OutputOptions : public Something { public: OutputOptions(ScriptNodePtr); @@ -17,8 +16,9 @@ class OutputOptions : public IntrusivePtrBase { const Variable URL; const Variable Parameters; + INITOPTIONS; + // defaults - friend class OutputOptionsLoader; static std::string encoding; private: static bool core; @@ -28,14 +28,7 @@ class OutputOptions : public IntrusivePtrBase { static bool url; static bool parameters; }; -typedef boost::intrusive_ptr<OutputOptions> OutputOptionsPtr; - -class OutputOptionsLoader : public ComponentLoader { - public: - typedef std::string KeyType; - - OutputOptionsPtr create(ScriptNodePtr e) const; - INITOPTIONS; -}; +typedef std::shared_ptr<OutputOptions> OutputOptionsPtr; +typedef AdHoc::Factory<OutputOptions, std::shared_ptr<const ScriptNode>> OutputOptionsFactory; #endif diff --git a/project2/cgi/cgiProgRouter.cpp b/project2/cgi/cgiProgRouter.cpp index 1d69151..3070c91 100644 --- a/project2/cgi/cgiProgRouter.cpp +++ b/project2/cgi/cgiProgRouter.cpp @@ -1,5 +1,5 @@ #include <pch.hpp> -#include <boost/filesystem/path.hpp> +#include <filesystem> #include <boost/algorithm/string/predicate.hpp> #include "cgiRequestContext.h" #include "commonObjects.h" @@ -9,11 +9,15 @@ #include "scriptStorage.h" #include "rowSet.h" #include "exceptions.h" +#include <factory.impl.h> typedef std::map<std::string, std::string> VarMap; class RoutingTable { public: + class Route; + typedef AdHoc::Factory<RoutingTable::Route, std::shared_ptr<const ScriptNode>> RouteFactory; + void loadRoutesFromFile(const std::string & routeFile) { routeScriptPath = routeFile; if (routeFile.empty()) { @@ -38,7 +42,7 @@ class RoutingTable { void setRouteScript() { routeScript = ScriptReader::resolveScript(CommonObjects::datasourceRoot, routeScriptPath, true); - routeScript->loader.addLoadTarget(routeScript->root(), Storer::into<ElementLoader>(&routes)); + routeScript->loader.addLoadTarget(routeScript->root(), Storer::into<RouteFactory>(&routes)); routes.clear(); routeScript->load(NULL, true); } @@ -55,11 +59,11 @@ class RoutingTable { throw ScriptNotFound("routed", path); } - class RouteElem : public IntrusivePtrBase { + class RouteElem { public: virtual bool matches(const std::string &, VarMap & vars) const = 0; }; - typedef boost::intrusive_ptr<RouteElem> RouteElemPtr; + typedef std::shared_ptr<RouteElem> RouteElemPtr; class RouteLiteral : public RouteElem { public: @@ -79,7 +83,7 @@ class RoutingTable { } const std::string variable; }; - + class Route : public SourceObject { public: Route(ScriptNodePtr s) : @@ -87,23 +91,23 @@ class RoutingTable { present(s->value("present", NULL).as<std::string>()), path(s->value("path", NULL).as<std::string>()) { - boost::filesystem::path fspath = path; - boost::filesystem::path::iterator p = fspath.begin(); + std::filesystem::path fspath = path; + std::filesystem::path::iterator p = fspath.begin(); p++; while(p != fspath.end() && p->string() != ".") { switch (p->string().front()) { case '{': - routeElems.push_back(new RouteVar(p->string())); + routeElems.push_back(std::make_shared<RouteVar>(p->string())); break; default: - routeElems.push_back(new RouteLiteral(p->string())); + routeElems.push_back(std::make_shared<RouteLiteral>(p->string())); break; } p++; } } - bool matches(const boost::filesystem::path & path, VarMap & vars) const { - boost::filesystem::path::iterator p = path.begin(); + bool matches(const std::filesystem::path & path, VarMap & vars) const { + std::filesystem::path::iterator p = path.begin(); p++; for (RouteElems::const_iterator re = routeElems.begin(); re != routeElems.end() || p != path.end(); re++) { if (re == routeElems.end() || p == path.end() || !(*re)->matches(p->string(), vars)) { @@ -118,18 +122,17 @@ class RoutingTable { const std::string present; const std::string path; }; - typedef boost::intrusive_ptr<Route> RoutePtr; + typedef std::shared_ptr<Route> RoutePtr; std::list<RoutePtr> routes; }; -typedef RoutingTable::Route Route; -DECLARE_LOADER("route", Route); +NAMEDFACTORY("route", RoutingTable::Route, RoutingTable::RouteFactory); class ProgRouter; -class ProgRouterLoader : public RouterLoader::For<ProgRouter> { +class ProgRouterFactory : public RouterFactory::For<ProgRouter>, public LifeCycle { public: - void onBefore() + void onBefore() override { routingTable.onBefore(); } @@ -139,14 +142,14 @@ class ProgRouterLoader : public RouterLoader::For<ProgRouter> { INITOPTIONS; }; -RoutingTable ProgRouterLoader::routingTable; +RoutingTable ProgRouterFactory::routingTable; -DECLARE_OPTIONS(ProgRouterLoader, "CGI Programmable Router options") +DECLARE_OPTIONS(ProgRouterFactory, "CGI Programmable Router options") ("cgi.progRouter.routes", Options::functions( boost::bind(&RoutingTable::loadRoutesFromFile, &routingTable, _1), boost::bind(&RoutingTable::clearRoutes, &routingTable)), "Script file defining web service routes") -END_OPTIONS(ProgRouterLoader); +END_OPTIONS(ProgRouterFactory); SimpleMessageException(UriElementNotFound); @@ -156,21 +159,21 @@ class ProgRouter : public Router { path(p) { } std::string route() const { - return ProgRouterLoader::routingTable.present(path, vars); + return ProgRouterFactory::routingTable.present(path, vars); } bool isDefault() const { return false; } VariableType routeParameter(const VariableType & vp) const { - return safeMapLookup<UriElementNotFound>(vars, vp); + return AdHoc::safeMapLookup<UriElementNotFound>(vars, vp); } unsigned int parameterCount() const { return vars.size(); } void present(const MultiRowSetPresenter * p) const { p->addNewArray("uriElem", true); - boost::filesystem::path y(path); - boost::filesystem::path::iterator pathPart = y.begin(); + std::filesystem::path y(path); + std::filesystem::path::iterator pathPart = y.begin(); while(++pathPart != y.end()) { p->addNamedValue("uriElem", pathPart->string()); } @@ -189,17 +192,18 @@ class ProgRouter : public Router { mutable VarMap vars; }; -DECLARE_CUSTOM_COMPONENT_LOADER("progRouter", ProgRouter, ProgRouterLoader, RouterLoader); +NAMEDPLUGIN("progRouter", ProgRouterFactory, RouterFactory); class Routes : public RowSet { public: Routes(ScriptNodePtr s) : + SourceObject(s), RowSet(s) { } class RouteRowState : public RowState { public: RouteRowState() { - columns.insert(new Column(0, "present")); - columns.insert(new Column(1, "path")); + columns.insert(std::make_shared<Column>(0, "present")); + columns.insert(std::make_shared<Column>(1, "path")); fields.resize(2); } const Columns & getColumns() const { return columns; } @@ -209,7 +213,7 @@ class Routes : public RowSet { void execute(const Glib::ustring & filter, const RowProcessorCallback & rp, ExecContext *) const { RouteRowState rs; - for (const auto & r : ProgRouterLoader::routingTable.routes) { + for (const auto & r : ProgRouterFactory::routingTable.routes) { if (boost::algorithm::starts_with(r->path, filter)) { rs.fields[0] = VariableType(r->present); rs.fields[1] = VariableType(r->path); @@ -219,5 +223,6 @@ class Routes : public RowSet { } }; -DECLARE_LOADER("routes", Routes); +NAMEDFACTORY("routes", Routes, RowSetFactory); +INSTANTIATEFACTORY(RoutingTable::Route, std::shared_ptr<const ScriptNode>); diff --git a/project2/cgi/cgiRequestContext.cpp b/project2/cgi/cgiRequestContext.cpp index 636d2f6..94d0973 100644 --- a/project2/cgi/cgiRequestContext.cpp +++ b/project2/cgi/cgiRequestContext.cpp @@ -13,7 +13,7 @@ CgiRequestContext::CgiRequestContext(cgicc::CgiInput * i, const CgiEnvInput & e) : cgi(i), - router(boost::bind(&RouterLoader::create, boost::cref(CgiApplicationEngine::router), getRedirectURL())), + router(boost::bind(&RouterFactory::create, boost::cref(CgiApplicationEngine::router), getRedirectURL())), cgienv(e), session(boost::bind(&CgiRequestContext::getSessionInternal, this)) { @@ -60,7 +60,17 @@ CgiRequestContext::getRequestMethod() const std::string CgiRequestContext::getRedirectURL() const { - return cgi.getEnvironment().getRedirectURL(); + auto rdurl = cgi.getEnvironment().getRedirectURL(); + auto css = (int)rdurl.find("://"); + if (css > -1) { + auto s = rdurl.find('/', css + 3); + auto qm = (int)rdurl.find('?', s); + if (qm > -1) { + return rdurl.substr(s, qm - s); + } + return rdurl.substr(s); + } + return rdurl; } std::string diff --git a/project2/cgi/cgiRequestContext.h b/project2/cgi/cgiRequestContext.h index 9501a20..1728103 100644 --- a/project2/cgi/cgiRequestContext.h +++ b/project2/cgi/cgiRequestContext.h @@ -19,7 +19,7 @@ namespace Glib { class Regex; } -class CgiRequestContext : public ExecContext { +class DLL_PUBLIC CgiRequestContext : public ExecContext { public: typedef std::string ETag; typedef std::vector<ETag> ETags; @@ -42,14 +42,14 @@ class CgiRequestContext : public ExecContext { time_t getRequestModifiedSince() const; std::string getCookieValue(const std::string & name) const; boost::optional<RangeRequest> getRequestRange() const; - LazyPointer<Router> router; + AdHoc::LazyPointer<Router> router; boost::posix_time::ptime startTime; boost::posix_time::ptime endTime; private: const CgiEnvInput & cgienv; - LazyPointer<Session> session; + AdHoc::LazyPointer<Session> session; SessionPtr getSessionInternal() const; }; diff --git a/project2/cgi/cgiRequestID.cpp b/project2/cgi/cgiRequestID.cpp index 60baa1e..88c212c 100644 --- a/project2/cgi/cgiRequestID.cpp +++ b/project2/cgi/cgiRequestID.cpp @@ -4,7 +4,7 @@ #include <scriptLoader.h> #include <scriptStorage.h> #include <gcrypt.h> -#include <scopeObject.h> +#include <scopeExit.h> #include <iomanip> /// Variable implementation that returns a unique ID for a page request @@ -19,7 +19,7 @@ class CgiRequestID : public VariableImplDyn { { gcry_md_hd_t state; gcry_md_open(&state, GCRY_MD_SHA1, 0); - ScopeObject gcryClose([&state] { gcry_md_close(state); }); + AdHoc::ScopeExit gcryClose([&state] { gcry_md_close(state); }); auto crc = static_cast<const CgiRequestContext *>(ec); gcryApplyString(state, crc->getRedirectURL()); @@ -50,6 +50,5 @@ class CgiRequestID : public VariableImplDyn { return hashstr.str(); } }; -DECLARE_COMPONENT_LOADER("requestid", CgiRequestID, VariableLoader); - +NAMEDFACTORY("requestid", CgiRequestID, VariableFactory); diff --git a/project2/cgi/cgiResult.h b/project2/cgi/cgiResult.h index 35165c8..ce28ca7 100644 --- a/project2/cgi/cgiResult.h +++ b/project2/cgi/cgiResult.h @@ -4,7 +4,7 @@ #include "transform.h" #include "cgiAppEngine.h" -class CgiResult : public TransformChainLink { +class DLL_PUBLIC CgiResult : public TransformChainLink { public: CgiResult(CgiApplicationEngine::HttpHeaderPtr & h, std::ostream & s, const std::string & e) : header(h), diff --git a/project2/cgi/cgiResultStatic.cpp b/project2/cgi/cgiResultStatic.cpp index ab4ff43..8abeb05 100644 --- a/project2/cgi/cgiResultStatic.cpp +++ b/project2/cgi/cgiResultStatic.cpp @@ -15,8 +15,13 @@ class StaticToCgiResult : public TransformImpl<StaticContent, CgiResult> { cr->header->addHeader("Last-Modified", buf); cr->header->addHeader("Etag", sc->getSHA1()); cr->header->addHeader("Cache-Control", "must-revalidate"); - cr->header->render(cr->stream); - sc->writeTo(cr->stream); + try { + cr->header->render(cr->stream); + sc->writeTo(cr->stream); + } + catch (const std::ios_base::failure &) { + // ignore (client may have gone away) + } } }; DECLARE_TRANSFORM(StaticToCgiResult); diff --git a/project2/cgi/cgiResultWritable.cpp b/project2/cgi/cgiResultWritable.cpp index 1364456..45e2a2a 100644 --- a/project2/cgi/cgiResultWritable.cpp +++ b/project2/cgi/cgiResultWritable.cpp @@ -30,8 +30,13 @@ class WritableToCgiResult : public TransformImpl<WritableContent, CgiResult> { strftime(buf, sizeof(buf), "%a, %d %b %Y %T %z", &stm); cr->header->addHeader("Last-Modified", buf); } - cr->header->render(cr->stream); - wc->writeTo(cr->stream, cr->encoding, ec); + try { + cr->header->render(cr->stream); + wc->writeTo(cr->stream, cr->encoding, ec); + } + catch (const std::ios_base::failure &) { + // ignore (client may have gone away) + } } }; DECLARE_TRANSFORM(WritableToCgiResult); diff --git a/project2/cgi/cgiRouter.cpp b/project2/cgi/cgiRouter.cpp index dc77c40..ebf8eb0 100644 --- a/project2/cgi/cgiRouter.cpp +++ b/project2/cgi/cgiRouter.cpp @@ -1,5 +1,5 @@ #include "cgiRouter.h" -#include "instanceStore.impl.h" +#include <factory.impl.h> -INSTANTIATESTORE(std::string, RouterLoader); +INSTANTIATEFACTORY(Router, const std::string &); diff --git a/project2/cgi/cgiRouter.h b/project2/cgi/cgiRouter.h index 9e9c621..7c9137e 100644 --- a/project2/cgi/cgiRouter.h +++ b/project2/cgi/cgiRouter.h @@ -3,10 +3,11 @@ #include <variables.h> #include <scriptLoader.h> +#include <factory.h> class MultiRowSetPresenter; -class Router : public IntrusivePtrBase { +class DLL_PUBLIC Router { public: virtual bool isDefault() const = 0; virtual std::string route() const = 0; @@ -14,8 +15,8 @@ class Router : public IntrusivePtrBase { virtual unsigned int parameterCount() const = 0; virtual void present(const MultiRowSetPresenter * p) const = 0; }; -typedef boost::intrusive_ptr<Router> RouterPtr; -typedef GenLoader<Router, std::string, const std::string &> RouterLoader; +typedef std::shared_ptr<Router> RouterPtr; +typedef AdHoc::Factory<Router, const std::string &> RouterFactory; #endif diff --git a/project2/cgi/cgiSimpleRouter.cpp b/project2/cgi/cgiSimpleRouter.cpp index b67848e..0eaea0f 100644 --- a/project2/cgi/cgiSimpleRouter.cpp +++ b/project2/cgi/cgiSimpleRouter.cpp @@ -1,15 +1,15 @@ #include "cgiRequestContext.h" -#include <boost/filesystem/path.hpp> +#include <filesystem> #include "scriptLoader.h" #include "presenter.h" SimpleNumericException(UriElementOutOfRange); std::vector<std::string> -makeVector(const boost::filesystem::path & y) +makeVector(const std::filesystem::path & y) { std::vector<std::string> r; - boost::filesystem::path::iterator p = y.begin(); + std::filesystem::path::iterator p = y.begin(); p++; while(p != y.end()) { r.push_back((p++)->string()); @@ -41,8 +41,8 @@ class SimpleRouter : public Router { } void present(const MultiRowSetPresenter * p) const { p->addNewArray("uriElem", true); - boost::filesystem::path y(path); - boost::filesystem::path::iterator pathPart = y.begin(); + std::filesystem::path y(path); + std::filesystem::path::iterator pathPart = y.begin(); while(++pathPart != y.end()) { p->addNamedValue("uriElem", pathPart->string()); } @@ -54,5 +54,5 @@ class SimpleRouter : public Router { std::vector<std::string> elems; }; -DECLARE_GENERIC_LOADER("simple", RouterLoader, SimpleRouter); +NAMEDFACTORY("simple", SimpleRouter, RouterFactory); diff --git a/project2/cgi/cgiStageCacheHit.cpp b/project2/cgi/cgiStageCacheHit.cpp index 3a6a665..a069dc8 100644 --- a/project2/cgi/cgiStageCacheHit.cpp +++ b/project2/cgi/cgiStageCacheHit.cpp @@ -13,12 +13,12 @@ CgiApplicationEngine::CacheHitStage::CacheHitStage(ScriptNodePtr s, PresenterCac CgiApplicationEngine::NextStage CgiApplicationEngine::CacheHitStage::run(CgiRequestContext *) { - return NextStage(NULL, this, pc, NULL); + return NextStage(NULL, shared_from_this(), pc, NULL); } CgiApplicationEngine::HttpHeaderPtr CgiApplicationEngine::CacheHitStage::getHeader(CgiRequestContext *) const { - return HttpHeaderPtr(new Project2HttpHeader("200 OK")); + return std::make_shared<Project2HttpHeader>("200 OK"); } diff --git a/project2/cgi/cgiStageDefaultError.cpp b/project2/cgi/cgiStageDefaultError.cpp index d230a21..f4c1df9 100644 --- a/project2/cgi/cgiStageDefaultError.cpp +++ b/project2/cgi/cgiStageDefaultError.cpp @@ -11,12 +11,12 @@ CgiApplicationEngine::DefaultErrorStage::DefaultErrorStage(const std::exception CgiApplicationEngine::ResponseStage(NULL), buf(__cxxabiv1::__cxa_demangle(typeid(ex).name(), NULL, NULL, NULL)), what(ex.what()), - pres(new XmlPresenter(DefaultErrorStageResp, CgiApplicationEngine::errorTransformStyle, CgiApplicationEngine::errorContentType)) + pres(std::make_shared<XmlPresenter>(DefaultErrorStageResp, CgiApplicationEngine::errorTransformStyle, CgiApplicationEngine::errorContentType)) { - auto xp = dynamic_cast<TransformSource *>(pres.get()); - auto cp = dynamic_cast<ContentPresenter *>(pres.get()); + auto xp = std::dynamic_pointer_cast<TransformSource>(pres); + auto cp = std::dynamic_pointer_cast<ContentPresenter>(pres); if (xp && cp && cp->contentType == CgiApplicationEngine::transformContentType) { - auto h = TransformTargetLoader::getFor(CgiApplicationEngine::transformTargetType)->create(root, Default); + auto h = TransformTargetFactory::createNew(CgiApplicationEngine::transformTargetType, root, Default); xp->addTarget(h, crc, root); } } @@ -38,6 +38,6 @@ CgiApplicationEngine::DefaultErrorStage::run(CgiRequestContext * crc) pres->init(crc); pres->addNamedValue("error-type", Scripts::scriptNamespacePrefix, buf); pres->addNamedValue("error-what", Scripts::scriptNamespacePrefix, what.c_str()); - return NextStage(NULL, this, pres.get(), pres.get()); + return NextStage(NULL, shared_from_this(), pres, pres); } diff --git a/project2/cgi/cgiStageDefaultNotFound.cpp b/project2/cgi/cgiStageDefaultNotFound.cpp index ad4c697..c6b6f1e 100644 --- a/project2/cgi/cgiStageDefaultNotFound.cpp +++ b/project2/cgi/cgiStageDefaultNotFound.cpp @@ -16,7 +16,7 @@ CgiApplicationEngine::DefaultNotFoundStage::DefaultNotFoundStage(const ScriptNot CgiApplicationEngine::HttpHeaderPtr CgiApplicationEngine::DefaultNotFoundStage::getHeader(CgiRequestContext *) const { - return HttpHeaderPtr(new Project2HttpHeader("404 Not found")); + return std::make_shared<Project2HttpHeader>("404 Not found"); } CgiApplicationEngine::NextStage @@ -24,6 +24,6 @@ CgiApplicationEngine::DefaultNotFoundStage::run(CgiRequestContext * crc) { pres->init(crc); pres->addNamedValue("missing-resource", Scripts::scriptNamespacePrefix, nf.what()); - return NextStage(NULL, this, pres.get(), pres.get()); + return NextStage(NULL, shared_from_this(), pres, pres); } diff --git a/project2/cgi/cgiStageFail.cpp b/project2/cgi/cgiStageFail.cpp index 461c8a7..a111a96 100644 --- a/project2/cgi/cgiStageFail.cpp +++ b/project2/cgi/cgiStageFail.cpp @@ -22,7 +22,7 @@ namespace CgiApplicationExtras { CgiApplicationEngine::NextStage run(CgiRequestContext *) { - return CgiApplicationEngine::NextStage(NULL, this, NULL, NULL); + return CgiApplicationEngine::NextStage(NULL, shared_from_this(), NULL, NULL); } private: const int code; @@ -46,6 +46,5 @@ namespace CgiApplicationExtras { }; } -typedef CgiApplicationExtras::CgiFail cgif; -DECLARE_LOADER("cgifail", cgif); +NAMEDFACTORY("cgifail", CgiApplicationExtras::CgiFail, ViewFactory); diff --git a/project2/cgi/cgiStageInitial.cpp b/project2/cgi/cgiStageInitial.cpp index 1326af8..dbc58fd 100644 --- a/project2/cgi/cgiStageInitial.cpp +++ b/project2/cgi/cgiStageInitial.cpp @@ -7,11 +7,11 @@ CgiApplicationEngine::NextStage CgiApplicationEngine::InitialStage::run(CgiRequestContext * crc) { if (crc->getRequestMethod() == "POST") { - return NextStage(new RequestStage(ScriptReader::resolveScript(CgiApplicationEngine::requestRoot, + return NextStage(std::make_shared<RequestStage>(ScriptReader::resolveScript(CgiApplicationEngine::requestRoot, crc->router->route(), false))); } else { - return NextStage(new PresentStage(ScriptReader::resolveScript(CgiApplicationEngine::presentRoot, + return NextStage(std::make_shared<PresentStage>(ScriptReader::resolveScript(CgiApplicationEngine::presentRoot, crc->router->isDefault() ? CgiApplicationEngine::defaultPresent : crc->router->route(), false), crc)); } } diff --git a/project2/cgi/cgiStagePresent.cpp b/project2/cgi/cgiStagePresent.cpp index a708bc0..0a8c086 100644 --- a/project2/cgi/cgiStagePresent.cpp +++ b/project2/cgi/cgiStagePresent.cpp @@ -11,19 +11,19 @@ CgiApplicationEngine::PresentStage::PresentStage(ScriptReaderPtr s, CgiRequestCo CheckHost(s->root()), ViewHost(s->root()), presenter([this, crc] { - auto p = PresenterLoader::getFor(CgiApplicationEngine::defaultPresenter)->create(root, Default, crc); - auto xp = dynamic_cast<TransformSource *>(p); - auto cp = dynamic_cast<ContentPresenter *>(p); + auto p = PresenterFactory::createNew(CgiApplicationEngine::defaultPresenter, root, Default, crc); + auto xp = std::dynamic_pointer_cast<TransformSource>(p); + auto cp = std::dynamic_pointer_cast<ContentPresenter>(p); if (xp && cp && cp->contentType == CgiApplicationEngine::transformContentType) { - auto h = TransformTargetLoader::getFor(CgiApplicationEngine::transformTargetType)->create(root, Default); + auto h = TransformTargetFactory::createNew(CgiApplicationEngine::transformTargetType, root, Default); xp->addTarget(h, crc, root); } return p; }) { - s->loader.addLoadTarget(s->root(), Storer::into<OutputOptionsLoader>(&outputOptions)); - s->loader.addLoadTarget(s->root(), Storer::into<PresenterLoader>(&presenter, Scripted, crc)); - s->loader.addLoadTarget(s->root(), Storer::into<ElementLoader>(&caches)); + s->loader.addLoadTarget(s->root(), Storer::into<OutputOptionsFactory>(&outputOptions)); + s->loader.addLoadTarget(s->root(), Storer::into<PresenterFactory>(&presenter, Scripted, crc)); + s->loader.addLoadTarget(s->root(), Storer::into<PresenterCacheFactory>(&caches)); } CgiApplicationEngine::NextStage @@ -34,12 +34,12 @@ CgiApplicationEngine::PresentStage::run(CgiRequestContext * crc) time_t reqMS = crc->getRequestModifiedSince(); CgiRequestContext::ETags etags = crc->getRequestETags(); for (const PresenterCachePtr & pc : caches) { - if (pc->check(root->script->modifiedTime(), crc)) { - if (reqMS >= pc->getModifiedTime() && (etags.empty() || containerContains(etags, pc->getSHA1()))) { - header = HttpHeaderPtr(new Project2HttpHeader("304 Not Modified")); - return NextStage(NULL, this, NULL, NULL); + if (pc->check(root->script.lock()->modifiedTime(), crc)) { + if (reqMS >= pc->getModifiedTime() && (etags.empty() || AdHoc::containerContains(etags, pc->getSHA1()))) { + header = std::make_shared<Project2HttpHeader>("304 Not Modified"); + return NextStage(NULL, shared_from_this(), NULL, NULL); } - CacheHitStage * chs = new CacheHitStage(root, pc); + auto chs = std::make_shared<CacheHitStage>(root, pc); chs->caches = backFill; return NextStage(NULL, chs, pc, NULL); } @@ -49,18 +49,18 @@ CgiApplicationEngine::PresentStage::run(CgiRequestContext * crc) } try { executeViews(crc); - header = HttpHeaderPtr(new Project2HttpHeader("200 OK")); - return NextStage(NULL, this, boost::dynamic_pointer_cast<TransformSource>(presenter), presenter); + header = std::make_shared<Project2HttpHeader>("200 OK"); + return NextStage(NULL, shared_from_this(), std::dynamic_pointer_cast<TransformSource>(presenter.deref()), presenter); } - catch (EmptyRequiredRows) { - header = HttpHeaderPtr(new Project2HttpHeader("404 Not found")); - return NextStage(NULL, this, boost::dynamic_pointer_cast<TransformSource>(presenter), presenter); + catch (const EmptyRequiredRows &) { + header = std::make_shared<Project2HttpHeader>("404 Not found"); + return NextStage(NULL, shared_from_this(), std::dynamic_pointer_cast<TransformSource>(presenter.deref()), presenter); } - catch (ResponseStagePtr & p) { - return NextStage(NULL, p, boost::dynamic_pointer_cast<TransformSource>(p), boost::dynamic_pointer_cast<Presenter>(p)); + catch (const ResponseStagePtr & p) { + return NextStage(NULL, p, std::dynamic_pointer_cast<TransformSource>(p), std::dynamic_pointer_cast<Presenter>(p)); } - catch (StagePtr & p) { - return NextStage(p, NULL, boost::dynamic_pointer_cast<TransformSource>(p), boost::dynamic_pointer_cast<Presenter>(p)); + catch (const StagePtr & p) { + return NextStage(p, NULL, std::dynamic_pointer_cast<TransformSource>(p), std::dynamic_pointer_cast<Presenter>(p)); } } diff --git a/project2/cgi/cgiStageRedirect.cpp b/project2/cgi/cgiStageRedirect.cpp index d6fee08..ba9e37d 100644 --- a/project2/cgi/cgiStageRedirect.cpp +++ b/project2/cgi/cgiStageRedirect.cpp @@ -14,14 +14,14 @@ namespace CgiApplicationExtras { CgiApplicationEngine::HttpHeaderPtr getHeader(CgiRequestContext *) const { - Project2HttpHeader * header = new Project2HttpHeader("301 Moved Permanently"); + auto header = std::make_shared<Project2HttpHeader>("301 Moved Permanently"); header->addHeader("Location", url); return CgiApplicationEngine::HttpHeaderPtr(header); } CgiApplicationEngine::NextStage run(CgiRequestContext *) { - return CgiApplicationEngine::NextStage(NULL, this, NULL, NULL); + return CgiApplicationEngine::NextStage(NULL, shared_from_this(), NULL, NULL); } private: const std::string url; @@ -35,12 +35,12 @@ namespace CgiApplicationExtras { url(e, "url") { } void execute(const MultiRowSetPresenter *, ExecContext * ec) const { - throw CgiApplicationEngine::ResponseStagePtr(new RedirectStage(url(ec))); + throw std::make_shared<RedirectStage>(url(ec)); } private: Variable url; }; } -typedef CgiApplicationExtras::CgiRedirect cgird; -DECLARE_LOADER("cgiredirect", cgird); +NAMEDFACTORY("cgiredirect", CgiApplicationExtras::CgiRedirect, ViewFactory); + diff --git a/project2/cgi/cgiStageRequest.cpp b/project2/cgi/cgiStageRequest.cpp index 1cf03c9..d58cf38 100644 --- a/project2/cgi/cgiStageRequest.cpp +++ b/project2/cgi/cgiStageRequest.cpp @@ -21,23 +21,23 @@ CgiApplicationEngine::RequestStage::run(CgiRequestContext * ec) runChecks(ec); execute(ec); if (!present(ec).isNull()) { - return NextStage(new PresentStage(ScriptReader::resolveScript(CgiApplicationEngine::presentRoot, present(ec), false), ec), this); + return NextStage(std::make_shared<PresentStage>(ScriptReader::resolveScript(CgiApplicationEngine::presentRoot, present(ec), false), ec), shared_from_this()); } - return NextStage(NULL, this); + return NextStage(NULL, shared_from_this()); } CgiApplicationEngine::HttpHeaderPtr CgiApplicationEngine::RequestStage::getHeader(CgiRequestContext * ec) const { - Project2HttpHeader * header; + HttpHeaderPtr header; if (redirect(ec).isNull()) { - header = new Project2HttpHeader("200 OK"); + header = std::make_shared<Project2HttpHeader>("200 OK"); } else { - header = new Project2HttpHeader("301 Moved Permanently"); + header = std::make_shared<Project2HttpHeader>("301 Moved Permanently"); header->addHeader("Location", redirect(ec)); } header->addHeader("Cache-control", "no-cache"); - return HttpHeaderPtr(header); + return header; } diff --git a/project2/cgi/cgiUriParam.cpp b/project2/cgi/cgiUriParam.cpp index 985048d..edce6f8 100644 --- a/project2/cgi/cgiUriParam.cpp +++ b/project2/cgi/cgiUriParam.cpp @@ -27,5 +27,5 @@ class VariableUri : public VariableImplDyn { private: Variable index; }; -DECLARE_COMPONENT_LOADER("uri", VariableUri, VariableLoader); +NAMEDFACTORY("uri", VariableUri, VariableFactory); diff --git a/project2/cgi/p2webCgi.cpp b/project2/cgi/p2webCgi.cpp index a4e2328..33e1b8b 100644 --- a/project2/cgi/p2webCgi.cpp +++ b/project2/cgi/p2webCgi.cpp @@ -14,12 +14,12 @@ class GetEnv : public CgiEnvInput { int main(void) { - Plugable::onAllComponents(boost::bind(&ComponentLoader::onBegin, _1)); + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onBegin, _1)); CgiApplicationEngine app; GetEnv ge; app.process(std::cout, NULL, ge); - Plugable::onAllComponents(boost::bind(&ComponentLoader::onIteration, _1)); - Plugable::onAllComponents(boost::bind(&ComponentLoader::onPeriodic, _1)); - Plugable::onAllComponents(boost::bind(&ComponentLoader::onIdle, _1)); + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onIteration, _1)); + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onPeriodic, _1)); + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onIdle, _1)); } diff --git a/project2/cgi/p2webFCgi.cpp b/project2/cgi/p2webFCgi.cpp index 42a99bc..1a63346 100644 --- a/project2/cgi/p2webFCgi.cpp +++ b/project2/cgi/p2webFCgi.cpp @@ -1,7 +1,7 @@ #include "FCgiIO.h" #include "cgiAppEngine.h" #include <boost/bind.hpp> -#include <boost/filesystem/convenience.hpp> +#include <filesystem> time_t lastPeriodic = 0; time_t periodicDelay = 600; @@ -11,7 +11,7 @@ void p2webPeriodic() { time(&lastPeriodic); - Plugable::onAllComponents(boost::bind(&ComponentLoader::onPeriodic, _1)); + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onPeriodic, _1)); } static @@ -21,7 +21,7 @@ p2webGoingIdle(int) if (time(NULL) > lastPeriodic + periodicDelay) { p2webPeriodic(); } - Plugable::onAllComponents(boost::bind(&ComponentLoader::onIdle, _1)); + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onIdle, _1)); } int @@ -40,15 +40,16 @@ main(void) fprintf(stderr, "Failed to set signal handler\n"); } alarm(60); - Plugable::onAllComponents(boost::bind(&ComponentLoader::onBegin, _1)); + auto initial_path(std::filesystem::current_path()); + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onBegin, _1)); CgiApplicationEngine app; while (FCGX_Accept_r(&request) == 0) { alarm(0); cgicc::FCgiIO IO(request); - boost::filesystem::current_path(boost::filesystem::initial_path()); + std::filesystem::current_path(initial_path); app.process(IO, &IO, IO); FCGX_Finish_r(&request); - Plugable::onAllComponents(boost::bind(&ComponentLoader::onIteration, _1)); + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onIteration, _1)); if (time(NULL) > lastPeriodic + periodicDelay) { p2webPeriodic(); } diff --git a/project2/cgi/pch.hpp b/project2/cgi/pch.hpp index 065558b..125c912 100644 --- a/project2/cgi/pch.hpp +++ b/project2/cgi/pch.hpp @@ -2,11 +2,9 @@ #ifndef CGI_PCH #define CGI_PCH -#include "cgiRequestContext.h" -#include "cgiHttpHeader.h" -#include "scriptLoader.h" +#include <boost/tuple/tuple.hpp> +#include <boost/variant/variant_fwd.hpp> #include <boost/bind.hpp> -#include "options.h" #include <cgicc/CgiEnvironment.h> #include <cgicc/Cgicc.h> #include <cgicc/HTTPContentHeader.h> diff --git a/project2/cgi/testCgi.cpp b/project2/cgi/testCgi.cpp index 196ecc3..b1a5a3b 100644 --- a/project2/cgi/testCgi.cpp +++ b/project2/cgi/testCgi.cpp @@ -16,7 +16,9 @@ class TestInput : public cgicc::CgiInput, public CgiEnvInput { class TestConfigConsumer : public ConfigConsumer { public: void operator()(const Glib::ustring & n, const Glib::ustring & p, const Glib::ustring & v, const Options::CurrentPlatform & cp) const { - InstanceSet<Options>::OnAll(boost::bind(&Options::consume, _1, n, p, v, cp)); + for (auto opts : AdHoc::PluginManager::getDefault()->getAll<Options>()) { + opts->implementation()->consume(n, p, v, cp); + } } const Options::Option * get(const Glib::ustring &) const { return NULL; @@ -27,29 +29,30 @@ class TestInput : public cgicc::CgiInput, public CgiEnvInput { typedef std::map<std::string, StrPtr> OptStore; TestInput(int argc, char ** argv) { - OptionsSources::Add("_1", new FileOptions(".testCgi.settings")); - OptionsSources::Add("_2", new CommandLineArguments(argc, argv, - [](const char * url) { urls.push_back(url); })); + AdHoc::PluginManager::getDefault()->create<OptionsSource, FileOptions>( + "_1", __FILE__, __LINE__, ".testCgi.settings"); + AdHoc::PluginManager::getDefault()->create<OptionsSource, CommandLineArguments>( + "_2", __FILE__, __LINE__, argc, argv, [](const char * url) { urls.push_back(url); }); } ~TestInput() { - OptionsSources::Remove("_1"); - OptionsSources::Remove("_2"); + AdHoc::PluginManager::getDefault()->remove<OptionsSource>("_1"); + AdHoc::PluginManager::getDefault()->remove<OptionsSource>("_2"); } std::string getenv(const std::string & varName) const { StrPtr def(new std::string()); - return *defaultMapFind(optStore(), varName, def); + return *AdHoc::defaultMapLookup(optStore(), varName, def); } virtual std::string getenv(const char * varName) { StrPtr def(new std::string()); - return *defaultMapFind(optStore(), varName, def); + return *AdHoc::defaultMapLookup(optStore(), varName, def); } void run() { - Plugable::onAllComponents(boost::bind(&ComponentLoader::onBegin, _1)); + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onBegin, _1)); CgiApplicationEngine app; boost::function<std::string()> sn = boost::bind(&CgiEnvInput::getenv, this, "SERVER_NAME"); OptionsSource::loadSources(boost::bind(&CgiApplicationEngine::derivedPlatform, sn)); @@ -77,11 +80,11 @@ class TestInput : public cgicc::CgiInput, public CgiEnvInput { optStore()["QUERY_STRING"] = StrPtr(new std::string()); } app.process(std::cout, this, *this); - Plugable::onAllComponents(boost::bind(&ComponentLoader::onIteration, _1)); + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onIteration, _1)); } - Plugable::onAllComponents(boost::bind(&ComponentLoader::onPeriodic, _1)); + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onPeriodic, _1)); } - Plugable::onAllComponents(boost::bind(&ComponentLoader::onIdle, _1)); + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onIdle, _1)); } INITOPTIONS; diff --git a/project2/cli/Jamfile.jam b/project2/cli/Jamfile.jam index 28487aa..1fdcd0d 100644 --- a/project2/cli/Jamfile.jam +++ b/project2/cli/Jamfile.jam @@ -7,7 +7,6 @@ lib p2cli : [ glob *.cpp ] : <include>. - <include>../../libmisc <library>glibmm <library>../common//p2common : : diff --git a/project2/cli/claOptions.h b/project2/cli/claOptions.h index 3f13b4b..d178720 100644 --- a/project2/cli/claOptions.h +++ b/project2/cli/claOptions.h @@ -2,12 +2,13 @@ #define CLAOPTIONS_H #include "../common/optionsSource.h" +#include <visibility.h> -class CommandLineArguments : public OptionsSource { +class DLL_PUBLIC CommandLineArguments : public OptionsSource { public: typedef boost::function<void(const char * const)> Others; CommandLineArguments(int c, const char * const * v, const Others &); - void loadInto(const ConfigConsumer & consume, const Options::CurrentPlatform & platform) const; + void loadInto(const ConfigConsumer & consume, const Options::CurrentPlatform & platform) const override; boost::posix_time::ptime modifiedTime() const override; private: diff --git a/project2/common/Jamfile.jam b/project2/common/Jamfile.jam index 6514b1e..c9c683e 100644 --- a/project2/common/Jamfile.jam +++ b/project2/common/Jamfile.jam @@ -3,32 +3,28 @@ alias glibmm : : : : <linkflags>"`pkg-config --libs glibmm-2.4`" ; lib dl : : <name>dl ; -lib boost_system : : <name>boost_system ; -lib boost_filesystem : : <name>boost_filesystem ; +lib stdc++fs ; lib boost_date_time : : <name>boost_date_time ; build-project unittests ; cpp-pch pch : pch.hpp : - <include>../../libmisc - <library>../lib//p2lib + <library>..//adhocutil <library>glibmm ; lib p2common : pch - [ glob-tree *.cpp : unittests ] + [ glob-tree *.cpp : unittests library.cpp ] : <include>. <library>glibmm <library>dl - <library>boost_system - <library>boost_filesystem + <library>stdc++fs <library>boost_date_time - <library>../lib//p2lib + <library>..//adhocutil : : <include>. - <library>boost_system - <library>../lib//p2lib + <library>..//adhocutil ; diff --git a/project2/common/aggregate.cpp b/project2/common/aggregate.cpp index ee7c871..42e1a42 100644 --- a/project2/common/aggregate.cpp +++ b/project2/common/aggregate.cpp @@ -1,4 +1,5 @@ #include "aggregate.h" +#include <factory.impl.h> Aggregate::Aggregate(ScriptNodePtr s) : SourceObject(s), @@ -22,3 +23,6 @@ Aggregate::pushValue(ExecContext * ec) const pushValue(value(ec), ec); } +INSTANTIATEFACTORY(ValueAggregate, std::shared_ptr<const ScriptNode>); +INSTANTIATEFACTORY(SetAggregate, std::shared_ptr<const ScriptNode>); + diff --git a/project2/common/aggregate.h b/project2/common/aggregate.h index 7f33b6b..222cf09 100644 --- a/project2/common/aggregate.h +++ b/project2/common/aggregate.h @@ -4,8 +4,9 @@ #include "scripts.h" #include "variables.h" #include <boost/function.hpp> +#include <visibility.h> -class Aggregate : public SourceObject { +class DLL_PUBLIC Aggregate : public SourceObject { public: Aggregate(ScriptNodePtr); @@ -17,21 +18,23 @@ class Aggregate : public SourceObject { Variable value; }; -class ValueAggregate : public Aggregate { +class DLL_PUBLIC ValueAggregate : public Aggregate { public: ValueAggregate(ScriptNodePtr); virtual VariableType resultValue() const = 0; }; -typedef boost::intrusive_ptr<const ValueAggregate> ValueAggregateCPtr; +typedef std::shared_ptr<const ValueAggregate> ValueAggregateCPtr; +typedef AdHoc::Factory<ValueAggregate, std::shared_ptr<const ScriptNode>> ValueAggregateFactory; -class SetAggregate : public Aggregate { +class DLL_PUBLIC SetAggregate : public Aggregate { public: typedef boost::function1<void, VariableType> UseAgg; SetAggregate(ScriptNodePtr); virtual void onResultValues(const UseAgg &) const = 0; }; -typedef boost::intrusive_ptr<const SetAggregate> SetAggregateCPtr; +typedef std::shared_ptr<const SetAggregate> SetAggregateCPtr; +typedef AdHoc::Factory<SetAggregate, std::shared_ptr<const ScriptNode>> SetAggregateFactory; #endif diff --git a/project2/common/appInstance.cpp b/project2/common/appInstance.cpp index 72d34a9..3f8ab58 100644 --- a/project2/common/appInstance.cpp +++ b/project2/common/appInstance.cpp @@ -13,9 +13,7 @@ AppInstance::AppInstance() AppInstance::~AppInstance() { - if (_current != this) { - throw std::runtime_error("All kinds of bad, destroying a non-current AppInstance"); - } + BOOST_ASSERT_MSG(_current == this, "All kinds of bad, destroying a non-current AppInstance"); _current = NULL; } diff --git a/project2/common/appInstance.h b/project2/common/appInstance.h index 50ade4d..4494b5e 100644 --- a/project2/common/appInstance.h +++ b/project2/common/appInstance.h @@ -3,8 +3,9 @@ #include <set> #include "scripts.h" +#include <visibility.h> -class AppInstance { +class DLL_PUBLIC AppInstance { public: typedef std::map<ScriptReader::ScriptKey, ScriptReaderPtr> ScriptCache; diff --git a/project2/common/check.cpp b/project2/common/check.cpp index d288e2f..3a29a9b 100644 --- a/project2/common/check.cpp +++ b/project2/common/check.cpp @@ -2,8 +2,9 @@ #include "check.h" #include "scriptLoader.h" #include "scriptStorage.h" +#include <factory.impl.h> -DECLARE_LOADER("check", Check); +NAMEDFACTORY("check", Check, CheckFactory); StaticMessageException(NoTestsToPerform, "No tests to perform"); Check::Check(ScriptNodePtr p) : @@ -12,7 +13,7 @@ Check::Check(ScriptNodePtr p) : group(p, "group", "default"), present(p, "present", "") { - p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&test)); + p->script.lock()->loader.addLoadTarget(p, Storer::into<TestFactory>(&test)); } Check::~Check() @@ -28,3 +29,5 @@ Check::performCheck(ExecContext * ec) const return test->passes(ec); } +INSTANTIATEFACTORY(Check, std::shared_ptr<const ScriptNode>); + diff --git a/project2/common/check.h b/project2/common/check.h index dc97f8f..73dbacb 100644 --- a/project2/common/check.h +++ b/project2/common/check.h @@ -4,11 +4,12 @@ #include "sourceObject.h" #include "variables.h" #include "test.h" +#include <visibility.h> class ExecContext; /// Base class for Project2 compoments that perform checks -class Check : public SourceObject { +class DLL_PUBLIC Check : public SourceObject { public: Check(ScriptNodePtr p); virtual ~Check(); @@ -20,7 +21,8 @@ class Check : public SourceObject { const Variable present; TestPtr test; }; -typedef boost::intrusive_ptr<const Check> CheckCPtr; +typedef std::shared_ptr<const Check> CheckCPtr; +typedef AdHoc::Factory<Check, std::shared_ptr<const ScriptNode>> CheckFactory; #endif diff --git a/project2/common/checkHost.cpp b/project2/common/checkHost.cpp index a900d7a..8784ad9 100644 --- a/project2/common/checkHost.cpp +++ b/project2/common/checkHost.cpp @@ -5,7 +5,7 @@ CheckHost::CheckHost(ScriptNodePtr s) : CommonObjects(s) { - s->script->loader.addLoadTarget(s, Storer::into<ElementLoader>(&checks)); + s->script.lock()->loader.addLoadTarget(s, Storer::into<CheckFactory>(&checks)); } CheckHost::~CheckHost() diff --git a/project2/common/checkHost.h b/project2/common/checkHost.h index f404d9e..46b5a04 100644 --- a/project2/common/checkHost.h +++ b/project2/common/checkHost.h @@ -6,8 +6,9 @@ #include <set> #include <boost/function.hpp> #include "commonObjects.h" +#include <visibility.h> -class CheckHost : virtual public CommonObjects { +class DLL_PUBLIC CheckHost : virtual public CommonObjects { public: class CheckFailure : std::exception { public: diff --git a/project2/common/chronoHelpers.h b/project2/common/chronoHelpers.h new file mode 100644 index 0000000..7bf1650 --- /dev/null +++ b/project2/common/chronoHelpers.h @@ -0,0 +1,12 @@ +#ifndef COMMON_CHRONOHELPERS_H +#define COMMON_CHRONOHELPERS_H + +template<typename time_point> +std::time_t +to_time_t(const time_point & t) +{ + return std::chrono::duration_cast<std::chrono::seconds>(t.time_since_epoch()).count(); +} + +#endif + diff --git a/project2/common/columns.cpp b/project2/common/columns.cpp index f98c4e5..bcb3655 100644 --- a/project2/common/columns.cpp +++ b/project2/common/columns.cpp @@ -18,9 +18,9 @@ Column::Column(unsigned int i, const Glib::ustring & n, const Variable & v) : { } -Column * +std::shared_ptr<Column> Column::make(unsigned int idx, ScriptNodePtr p) { - return new Column(idx, p); + return std::make_shared<Column>(idx, p); } diff --git a/project2/common/columns.h b/project2/common/columns.h index d3e2c97..5845c72 100644 --- a/project2/common/columns.h +++ b/project2/common/columns.h @@ -5,14 +5,15 @@ #include <boost/multi_index_container.hpp> #include <boost/multi_index/member.hpp> #include <boost/multi_index/ordered_index.hpp> +#include <visibility.h> -class Column : public IntrusivePtrBase { +class DLL_PUBLIC Column { public: Column(unsigned int idx, ScriptNodePtr p); Column(unsigned int i, const Glib::ustring & n, const Variable & v = Variable(Null())); virtual ~Column() = default; - static Column * make(unsigned int idx, ScriptNodePtr p); + static std::shared_ptr<Column> make(unsigned int idx, ScriptNodePtr p); const unsigned int idx; const Glib::ustring name; @@ -22,7 +23,7 @@ class Column : public IntrusivePtrBase { struct byColIdx {}; struct byColName {}; -typedef boost::intrusive_ptr<Column> ColumnPtr; +typedef std::shared_ptr<Column> ColumnPtr; typedef boost::multi_index::multi_index_container<ColumnPtr, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< diff --git a/project2/common/commonObjects.cpp b/project2/common/commonObjects.cpp index a25bb9f..4cf0d9a 100644 --- a/project2/common/commonObjects.cpp +++ b/project2/common/commonObjects.cpp @@ -19,7 +19,7 @@ CommonObjects::CommonObjects(ScriptNodePtr s) : script(s->script), scriptLoaded(false) { - s->script->loader.addLoadTarget(s, Storer::into<ElementLoader>(&rowSets)); + s->script.lock()->loader.addLoadTarget(s, Storer::into<RowSetFactory>(&rowSets)); } CommonObjects::~CommonObjects() @@ -29,16 +29,16 @@ CommonObjects::~CommonObjects() RowSetPtr CommonObjects::getSource(const std::string & name) const { - return safeMapLookup<DataSourceNotFound>(rowSets, name); + return AdHoc::safeMapLookup<DataSourceNotFound>(rowSets, name); } CommonObjects::DataSources::const_iterator CommonObjects::loadDataSource(const std::string & name) const { ScriptReaderPtr dbs = ScriptReader::resolveScript(datasourceRoot, name, true); - dbs->loader.addLoadTarget(dbs->root(), Storer::into<ElementLoader>(&datasources)); + dbs->loader.addLoadTarget(dbs->root(), Storer::into<DataSourceFactory>(&datasources)); dbs->load(NULL, false); - return safeMapFind<DataSourceNotFound>(datasources, name); + return AdHoc::safeMapFind<DataSourceNotFound>(datasources, name); } void diff --git a/project2/common/commonObjects.h b/project2/common/commonObjects.h index 788e3bd..7ea914d 100644 --- a/project2/common/commonObjects.h +++ b/project2/common/commonObjects.h @@ -5,8 +5,9 @@ #include "rowSet.h" #include "scriptStorage.h" #include "options.h" +#include <visibility.h> -class CommonObjects : public virtual IntrusivePtrBase { +class DLL_PUBLIC CommonObjects { public: typedef STORAGEOF(RowSet) RowSets; typedef STORAGEOF(DataSource) DataSources; @@ -26,7 +27,7 @@ class CommonObjects : public virtual IntrusivePtrBase { if (i == datasources.end()) { i = loadDataSource(name); } - DataSourceType * s = boost::dynamic_pointer_cast<DataSourceType>(i->second).get(); + DataSourceType * s = std::dynamic_pointer_cast<DataSourceType>(i->second).get(); if (!s) { throw DataSourceNotCompatible(name); } diff --git a/project2/common/componentLoader.cpp b/project2/common/componentLoader.cpp deleted file mode 100644 index 56eb833..0000000 --- a/project2/common/componentLoader.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "componentLoader.h" - -ComponentLoader::~ComponentLoader() -{ -} - -void -ComponentLoader::onBegin() -{ -} - -void -ComponentLoader::onBefore() -{ -} - -void -ComponentLoader::onIdle() -{ -} - -void -ComponentLoader::onIteration() -{ -} - -void -ComponentLoader::onPeriodic() -{ -} - -void -ComponentLoader::onConfigLoad() -{ -} - - diff --git a/project2/common/dataSource.cpp b/project2/common/dataSource.cpp index b5760c5..1c20056 100644 --- a/project2/common/dataSource.cpp +++ b/project2/common/dataSource.cpp @@ -1,9 +1,12 @@ #include <pch.hpp> #include "dataSource.h" #include "scripts.h" +#include <factory.impl.h> DataSource::DataSource(ScriptNodePtr p) : SourceObject(p) { } +INSTANTIATEFACTORY(DataSource, std::shared_ptr<const ScriptNode>); + diff --git a/project2/common/dataSource.h b/project2/common/dataSource.h index bd7170f..c5326e5 100644 --- a/project2/common/dataSource.h +++ b/project2/common/dataSource.h @@ -3,12 +3,13 @@ #include <boost/intrusive_ptr.hpp> #include "sourceObject.h" +#include <visibility.h> class DataSource; -typedef boost::intrusive_ptr<DataSource> DataSourcePtr; +typedef std::shared_ptr<DataSource> DataSourcePtr; /// Base class for data sources providing transaction support -class DataSource : public SourceObject { +class DLL_PUBLIC DataSource : public SourceObject { public: DataSource(ScriptNodePtr p); virtual ~DataSource() = default; @@ -17,6 +18,7 @@ class DataSource : public SourceObject { virtual void commit() { }; virtual void rollback() { }; }; +typedef AdHoc::Factory<DataSource, std::shared_ptr<const ScriptNode>> DataSourceFactory; #endif diff --git a/project2/common/definedColumns.h b/project2/common/definedColumns.h index 2f53669..1afb305 100644 --- a/project2/common/definedColumns.h +++ b/project2/common/definedColumns.h @@ -4,15 +4,16 @@ #include "variables.h" #include "rowSet.h" #include "columns.h" +#include <visibility.h> -class DefinedColumns { +class DLL_PUBLIC DefinedColumns { public: - typedef boost::function2<Column *, unsigned int, ScriptNodePtr> ColCreator; + typedef boost::function2<std::shared_ptr<Column>, unsigned int, ScriptNodePtr> ColCreator; DefinedColumns(ScriptNodePtr p, const Glib::ustring & colPath, const ColCreator & func); Columns columns; }; -class ColumnValues : public RowState { +class DLL_PUBLIC ColumnValues : public RowState { public: ColumnValues(const DefinedColumns *); virtual ~ColumnValues(); diff --git a/project2/common/exceptions.h b/project2/common/exceptions.h index 1051220..1642e1a 100644 --- a/project2/common/exceptions.h +++ b/project2/common/exceptions.h @@ -3,8 +3,9 @@ #include <stdexcept> #include <boost/optional.hpp> +#include <visibility.h> -class MsgBufferedException : public std::exception { +class DLL_PUBLIC MsgBufferedException : public std::exception { public: inline ~MsgBufferedException() throw() { } const char * what() const throw(); @@ -14,7 +15,7 @@ class MsgBufferedException : public std::exception { mutable boost::optional<std::string> buf; }; -class numeric_error : public MsgBufferedException { +class DLL_PUBLIC numeric_error : public MsgBufferedException { public: numeric_error(int); protected: @@ -23,7 +24,7 @@ class numeric_error : public MsgBufferedException { int err; }; -class syscall_error : public MsgBufferedException { +class DLL_PUBLIC syscall_error : public MsgBufferedException { public: syscall_error(int); protected: @@ -32,7 +33,7 @@ class syscall_error : public MsgBufferedException { int err; }; -class two_part_error : public MsgBufferedException { +class DLL_PUBLIC two_part_error : public MsgBufferedException { public: two_part_error(const std::string & what1, const std::string & what2); ~two_part_error() throw(); diff --git a/project2/common/execContext.cpp b/project2/common/execContext.cpp index bbec92a..aaf725e 100644 --- a/project2/common/execContext.cpp +++ b/project2/common/execContext.cpp @@ -10,7 +10,7 @@ ExecContext::logMessage(bool writeLog, const Glib::ustring & g, const Glib::ustr if (writeLog) { Logger()->messagebf(LOG_NOTICE, "%s: %s: %s", __PRETTY_FUNCTION__, g, m); } - messages.push_back(new Message(g, m)); + messages.push_back(std::make_shared<Message>(g, m)); } void diff --git a/project2/common/execContext.h b/project2/common/execContext.h index 86438bd..30e2e0e 100644 --- a/project2/common/execContext.h +++ b/project2/common/execContext.h @@ -2,25 +2,25 @@ #define EXECCONTEXT_H #include <glibmm/ustring.h> -#include <boost/intrusive_ptr.hpp> #include <list> #include "variableType.h" #include "session.h" +#include <visibility.h> class MultiRowSetPresenter; class RowState; class IHaveParameters; -class ExecContext { +class DLL_PUBLIC ExecContext { public: - class Message : public IntrusivePtrBase { + class Message { public: Message(const Glib::ustring & g, const Glib::ustring & m); const Glib::ustring group; const Glib::ustring message; }; - typedef boost::intrusive_ptr<Message> MessagePtr; + typedef std::shared_ptr<Message> MessagePtr; typedef std::list<MessagePtr> Messages; typedef std::vector<const RowState *> RowValuesStack; typedef std::vector<const IHaveParameters *> ParameterStack; diff --git a/project2/common/fileStrmVarWriter.h b/project2/common/fileStrmVarWriter.h index dd43473..dd125c4 100644 --- a/project2/common/fileStrmVarWriter.h +++ b/project2/common/fileStrmVarWriter.h @@ -2,8 +2,9 @@ #define FILESTREAMVARWRITER_H #include "variables.h" +#include <visibility.h> -class FileStreamVariableWriter : public boost::static_visitor<> { +class DLL_PUBLIC FileStreamVariableWriter : public boost::static_visitor<> { public: FileStreamVariableWriter(FILE *, bool quoting); ~FileStreamVariableWriter(); diff --git a/project2/common/genLoader.h b/project2/common/genLoader.h deleted file mode 100644 index 2e4300b..0000000 --- a/project2/common/genLoader.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef GENLOADER_H -#define GENLOADER_H - -#include "componentLoader.h" -#include "plugable.h" - -template <class Impl, class Key, typename... Params> -class GenLoader : public ComponentLoader { - public: - typedef Key KeyType; - typedef GenLoader<Impl, KeyType, Params...> Self; - - template <class T, class BaseLoader = Self> - class For : public BaseLoader { - public: - inline Impl * create(const Params & ... p) const - { - return new T(p...); - } - }; - - virtual Impl * create(const Params & ...) const = 0; - - template <class E = NotSupported> - inline static Impl * createNew(const KeyType & n, const Params & ... p) - { - return InstanceMap<Self, KeyType>::template Get<E>(n)->create(p...); - } - - template <class E = NotSupported> - inline static boost::shared_ptr<Self> getFor(const KeyType & n) - { - return InstanceMap<Self, KeyType>::template Get<E>(n); - } -}; - -#endif - diff --git a/project2/common/iHaveParameters.cpp b/project2/common/iHaveParameters.cpp index cb9241a..b63acb3 100644 --- a/project2/common/iHaveParameters.cpp +++ b/project2/common/iHaveParameters.cpp @@ -17,7 +17,7 @@ IHaveParameters::~IHaveParameters() VariableType IHaveParameters::getParameter(const Glib::ustring & name, ExecContext * ec) const { - return safeMapLookup<ParamNotFound>(parameters, name)(ec); + return AdHoc::safeMapLookup<ParamNotFound>(parameters, name)(ec); } const IHaveParameters::Parameters & diff --git a/project2/common/iHaveParameters.h b/project2/common/iHaveParameters.h index bab4592..e76de52 100644 --- a/project2/common/iHaveParameters.h +++ b/project2/common/iHaveParameters.h @@ -1,13 +1,12 @@ #ifndef IHAVEPARAMETERS #define IHAVEPARAMETERS -#include <boost/intrusive_ptr.hpp> #include <vector> #include "variables.h" -#include "intrusivePtrBase.h" +#include <visibility.h> /// Mix-in base class to store parameters for component execution -class IHaveParameters { +class DLL_PUBLIC IHaveParameters { public: typedef std::map<Glib::ustring, Variable> Parameters; diff --git a/project2/common/iHaveSubTasks.cpp b/project2/common/iHaveSubTasks.cpp index 6371475..578601f 100644 --- a/project2/common/iHaveSubTasks.cpp +++ b/project2/common/iHaveSubTasks.cpp @@ -3,7 +3,7 @@ IHaveSubTasks::IHaveSubTasks(ScriptNodePtr e) : SourceObject(e), - NoOutputExecute(e) + Task(e) { } diff --git a/project2/common/iHaveSubTasks.h b/project2/common/iHaveSubTasks.h index 3e7d16c..433899d 100644 --- a/project2/common/iHaveSubTasks.h +++ b/project2/common/iHaveSubTasks.h @@ -1,12 +1,14 @@ #ifndef HASSUBTASKS_H #define HASSUBTASKS_H -#include "noOutputExecute.h" +#include "task.h" +#include "scriptStorage.h" +#include <visibility.h> /// Base class for Project2 compoments that perform actions, but product no output -class IHaveSubTasks : public NoOutputExecute { +class DLL_PUBLIC IHaveSubTasks : public Task { public: - typedef ANONORDEREDSTORAGEOF(NoOutputExecute) Tasks; + typedef ANONORDEREDSTORAGEOF(Task) Tasks; IHaveSubTasks(ScriptNodePtr p); virtual ~IHaveSubTasks(); diff --git a/project2/common/instanceStore.h b/project2/common/instanceStore.h deleted file mode 100644 index fc57be7..0000000 --- a/project2/common/instanceStore.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef INSTANCESTORE_H -#define INSTANCESTORE_H - -#include <boost/function.hpp> -#include <set> -#include <map> -#include <safeMapFind.h> - -/// A static collection of any type, specifically with automatically cleaned up storage of a function static variable -// which makes it safe to use in constructor functions. -template <class Type, class StoreType> -class InstanceStore { - public: - static const StoreType & GetAll(); - static void Add(const typename StoreType::value_type & p); - - protected: - static void prune(); - static StoreType * & getInstances(); -}; - -/// Keyed collection of instances -template <class Type, class KeyType> -class InstanceMap : public InstanceStore<Type, std::map<KeyType, boost::shared_ptr<Type>>> { - public: - typedef std::map<KeyType, boost::shared_ptr<Type>> Store; - typedef InstanceStore<Type, std::map<KeyType, boost::shared_ptr<Type>>> IStore; - typedef typename Store::value_type Value; - - static void Add(const KeyType & k, Type * p); - static void Add(const KeyType & k, const boost::shared_ptr<Type> & p); - static void Remove(const KeyType &); - - template <class E> static boost::shared_ptr<Type> Get(const KeyType & n) - { - return safeMapLookup<E>(InstanceStore<Type, Store>::GetAll(), n); - } - - static void OnEach(const boost::function<void(const Value &)> & func); -}; - -/// Anonymous collection of instances -template <class Type> -class InstanceSet : public InstanceStore<Type, std::set<boost::shared_ptr<Type>>> { - public: - typedef InstanceStore<Type, std::set<boost::shared_ptr<Type>>> IStore; - static void OnAll(const boost::function<void(Type *)> & func); - static void Remove(const boost::shared_ptr<Type> &); -}; - -#endif - diff --git a/project2/common/instanceStore.impl.h b/project2/common/instanceStore.impl.h deleted file mode 100644 index 2a2f497..0000000 --- a/project2/common/instanceStore.impl.h +++ /dev/null @@ -1,97 +0,0 @@ -#include "instanceStore.h" -#include <boost/assert.hpp> - -template <class Type, class StoreType> -const StoreType & -InstanceStore<Type, StoreType>::GetAll() -{ - return *getInstances(); -} - -template <class Type, class StoreType> -void -InstanceStore<Type, StoreType>::Add(const typename StoreType::value_type & p) -{ - getInstances()->insert(p); -} - -template <class Type, class StoreType> -void -InstanceStore<Type, StoreType>::prune() -{ - auto & ps = getInstances(); - if (ps->empty()) { - delete ps; - ps = NULL; - } -} - -template <class Type, class StoreType> -StoreType * & -InstanceStore<Type, StoreType>::getInstances() -{ - static StoreType * instances = NULL; - if (!instances) { - instances = new StoreType(); - } - return instances; -} - -template <class Type, class KeyType> -void -InstanceMap<Type, KeyType>::Add(const KeyType & k, Type * p) -{ - BOOST_ASSERT(IStore::getInstances()->find(k) == IStore::getInstances()->end()); - IStore::Add(Value(k, boost::shared_ptr<Type>(p))); -} - -template <class Type, class KeyType> -void -InstanceMap<Type, KeyType>::Add(const KeyType & k, const boost::shared_ptr<Type> & p) -{ - BOOST_ASSERT(IStore::getInstances()->find(k) == IStore::getInstances()->end()); - IStore::Add(Value(k, p)); -} - -template <class Type, class KeyType> -void -InstanceMap<Type, KeyType>::Remove(const KeyType & k) -{ - IStore::getInstances()->erase(k); - IStore::prune(); -} - -template <class Type, class KeyType> -void -InstanceMap<Type, KeyType>::OnEach(const boost::function<void(const Value &)> & func) -{ - for (const auto & l : IStore::GetAll()) { - func(l); - } - IStore::prune(); -} - -template <class Type> -void -InstanceSet<Type>::OnAll(const boost::function<void(Type *)> & func) -{ - for (const auto & l : IStore::GetAll()) { - func(l.get()); - } - IStore::prune(); -} - -template <class Type> -void -InstanceSet<Type>::Remove(const boost::shared_ptr<Type> & p) -{ - IStore::getInstances()->erase(p); - IStore::prune(); -} - -#define INSTANTIATESTORE(K, T) \ -template class InstanceStore<T, std::map<K, boost::shared_ptr<T>>>; \ -template class InstanceMap<T, K>; \ -template class InstanceStore<T, std::set<boost::shared_ptr<T>>>; \ -template class InstanceSet<T> - diff --git a/project2/common/library.cpp b/project2/common/library.cpp index 11dadb3..136e9d4 100644 --- a/project2/common/library.cpp +++ b/project2/common/library.cpp @@ -23,7 +23,7 @@ Library::~Library() } STORAGEOF(Library) libraries; -class LibraryLoader : public ElementLoader::For<Library> { +class LibraryLoader : public ScriptNodeFactory::For<Library>, public LifeCycle { public: void onIteration() override { @@ -31,6 +31,5 @@ class LibraryLoader : public ElementLoader::For<Library> { } }; -DECLARE_CUSTOM_LOADER("library", LibraryLoader); - +NAMEDPLUGIN("library", LibraryLoader, ScriptNodeFactory); diff --git a/project2/common/lifeCycle.cpp b/project2/common/lifeCycle.cpp new file mode 100644 index 0000000..420632c --- /dev/null +++ b/project2/common/lifeCycle.cpp @@ -0,0 +1,50 @@ +#include "lifeCycle.h" +#include <boost/function.hpp> +#include <plugins.impl.h> + +LifeCycle::~LifeCycle() +{ +} + +void +LifeCycle::onBegin() +{ +} + +void +LifeCycle::onBefore() +{ +} + +void +LifeCycle::onIdle() +{ +} + +void +LifeCycle::onIteration() +{ +} + +void +LifeCycle::onPeriodic() +{ +} + +void +LifeCycle::onConfigLoad() +{ +} + +void +LifeCycle::onAllComponents(const boost::function<void(LifeCycle *)> & func) +{ + for(auto p : AdHoc::PluginManager::getDefault()->getAll()) { + if (auto c = std::dynamic_pointer_cast<LifeCycle>(p->instance())) { + func(c.get()); + } + } +} + +INSTANTIATEPLUGINOF(LifeCycle); + diff --git a/project2/common/componentLoader.h b/project2/common/lifeCycle.h index 45664e3..0e24581 100644 --- a/project2/common/componentLoader.h +++ b/project2/common/lifeCycle.h @@ -1,12 +1,15 @@ -#ifndef COMPONENTLOADER_H -#define COMPONENTLOADER_H +#ifndef LIFECYCLE_H +#define LIFECYCLE_H -#include "plugable.h" +#include <plugins.h> +#include <boost/function/function_fwd.hpp> +#include <visibility.h> /// Helper for loading and maintaining Project2 components -class ComponentLoader { +class DLL_PUBLIC LifeCycle : public virtual AdHoc::AbstractPluginImplementation { public: - virtual ~ComponentLoader() = 0; + virtual ~LifeCycle() = 0; + virtual void onBegin(); // App engine start up (before settings are processed) virtual void onBefore(); // Before the app engine processes a request (after settings are processed) virtual void onIdle(); // When the app engine goes idle @@ -14,14 +17,10 @@ class ComponentLoader { virtual void onPeriodic(); // When the app engine feels like it virtual void onConfigLoad(); // When the environment reloads the configuration virtual bool cacheable() const { return true; } // The component can be cached for next run -}; -typedef PluginsSameBase<ComponentLoader, std::string> Components; -#define DECLARE_COMPONENT(Id, Inst) \ - static void init_optionsSource_##Type() __attribute__ ((constructor(200))); \ - static void init_optionsSource_##Type() { Components::Add(Id, new Inst()); } \ - static void kill_optionsSource_##Type() __attribute__ ((destructor(200))); \ - static void kill_optionsSource_##Type() { Components::Remove(Id); } + static void onAllComponents(const boost::function<void(LifeCycle *)> & func); +}; +typedef AdHoc::PluginOf<LifeCycle> LifeCycleComponentPlugin; #endif diff --git a/project2/common/logger.cpp b/project2/common/logger.cpp index 95c2b15..40a72b0 100644 --- a/project2/common/logger.cpp +++ b/project2/common/logger.cpp @@ -2,7 +2,7 @@ #define SYSLOG_NAMES 1 // Enables the definition of names in syslog.h #include "logger.h" -#include "instanceStore.impl.h" +#include "loggerFactory.h" Log Logger::log; @@ -17,7 +17,7 @@ Log::~Log() } void -Log::setLoggerAt(LogDriverLoader * ldr, int level) +Log::setLoggerAt(LogDriverFactory * ldr, int level) { if (level == -1) { logs.erase(ldr); @@ -26,9 +26,9 @@ Log::setLoggerAt(LogDriverLoader * ldr, int level) logs[ldr] = ldr->create(); } lowestLevel = -1; - for (const auto & log : InstanceSet<LogDriverLoader>::GetAll()) { - if (log->loggerLevel() > lowestLevel) { - lowestLevel = log->loggerLevel(); + for (const auto & log : AdHoc::PluginManager::getDefault()->getAll<LogDriverFactory>()) { + if (log->implementation()->loggerLevel() > lowestLevel) { + lowestLevel = log->implementation()->loggerLevel(); } } } @@ -81,19 +81,10 @@ Log::vmessagef(int priority, const char * msgfmt, va_list va) const free(msg); } + Log * Logger::operator->() const { return &log; } -LogDriverBase::LogDriverBase() -{ -} - -LogDriverBase::~LogDriverBase() -{ -} - -INSTANTIATESTORE(std::string, LogDriverLoader); - diff --git a/project2/common/logger.h b/project2/common/logger.h index 7f6e7a0..d5c3c01 100644 --- a/project2/common/logger.h +++ b/project2/common/logger.h @@ -3,45 +3,31 @@ #include <map> #include <stdarg.h> -#include <stdlib.h> #include <syslog.h> // Pulled in for easy client lookups of LOG_* priorties -#include <boost/intrusive_ptr.hpp> -#include <boost/format.hpp> -#include "intrusivePtrBase.h" -#include "genLoader.h" -#include <misc.h> - -/// Base class for classes providing a logging facility -class LogDriverBase : public virtual IntrusivePtrBase { - public: - LogDriverBase(); - virtual ~LogDriverBase(); - - virtual void message(int priority, const char * msg) const = 0; -}; - -class LogDriverLoader : public GenLoader<LogDriverBase, std::string> { - public: - virtual int loggerLevel() const = 0; -}; - -class Log { +#include <boost/format/format_fwd.hpp> +#include <buffer.h> +#include <visibility.h> +#include "lifeCycle.h" + +class LogDriverBase; +class LogDriverFactory; +class DLL_PUBLIC Log { public: - typedef boost::intrusive_ptr<LogDriverBase> LogDriverBasePtr; - typedef std::map<LogDriverLoader *, LogDriverBasePtr> LogDrivers; + typedef std::shared_ptr<LogDriverBase> LogDriverBasePtr; + typedef std::map<LogDriverFactory *, LogDriverBasePtr> LogDrivers; Log(); ~Log(); - void setLoggerAt(LogDriverLoader *, int level); + void setLoggerAt(LogDriverFactory *, int level); void message(int priority, const char * msg) const; void messagef(int priority, const char * msgfmt, ...) const __attribute__ ((format (printf, 3, 4))); template <typename... Args> void messagebf(int priority, const char * msgfmt, const Args & ... args) const { if (priority > lowestLevel) return; - boost::shared_ptr<boost::format> fmt = getFormat(msgfmt); - messagebf(priority, *fmt, args...); + boost::format fmt = AdHoc::Buffer::getFormat(msgfmt); + messagebf(priority, fmt, args...); } void vmessagef(int priority, const char * msgfmt, va_list) const; @@ -54,46 +40,18 @@ class Log { messagebf(priority, f, otherargs...); } void messagebf(int priority, const boost::format & f) const; + static boost::shared_ptr<boost::format> getFormat(const std::string & msgfmt); LogDrivers logs; int lowestLevel; int nextId; }; -class Logger { +class DLL_PUBLIC Logger { public: Log * operator->() const; private: static Log log; }; -template<typename LoggerType> -class LogDriverLoaderImpl : public LogDriverLoader::For<LoggerType, LogDriverLoader> { - public: - LogDriverLoaderImpl() : - level(LoggerType::level) - { - } - virtual void onConfigLoad() override { - Logger()->setLoggerAt(this, level); - if (level == -1) { - instance.reset(); - } - } - inline LoggerType * create() const { - if (!instance) { - instance = new LoggerType(); - } - return instance.get(); - } - int loggerLevel() const { - return level; - } - const int & level; - private: - mutable boost::intrusive_ptr<LoggerType> instance; -}; -#define DECLARE_LOGGER_LOADER(N, T) \ - DECLARE_CUSTOM_COMPONENT_LOADER(N, T, LogDriverLoaderImpl<T>, LogDriverLoader); - #endif diff --git a/project2/common/loggerFactory.cpp b/project2/common/loggerFactory.cpp new file mode 100644 index 0000000..b1d75d1 --- /dev/null +++ b/project2/common/loggerFactory.cpp @@ -0,0 +1,14 @@ +#include "loggerFactory.h" +#include <factory.impl.h> + +LogDriverBase::LogDriverBase() +{ +} + +LogDriverBase::~LogDriverBase() +{ +} + +template class AdHoc::Factory<LogDriverBase>; +INSTANTIATEPLUGINOF(LogDriverFactory) + diff --git a/project2/common/loggerFactory.h b/project2/common/loggerFactory.h new file mode 100644 index 0000000..780cbcc --- /dev/null +++ b/project2/common/loggerFactory.h @@ -0,0 +1,39 @@ +#ifndef LOGGERFACTORY_H +#define LOGGERFACTORY_H + +#include <factory.h> +#include "lifeCycle.h" +#include "logger.h" +#include <visibility.h> + +/// Base class for classes providing a logging facility +class DLL_PUBLIC LogDriverBase { + public: + LogDriverBase(); + virtual ~LogDriverBase(); + + virtual void message(int priority, const char * msg) const = 0; +}; + +class DLL_PUBLIC LogDriverFactory : public AdHoc::Factory<LogDriverBase> { + public: + virtual int loggerLevel() const = 0; +}; + +template<typename LoggerType> +class LogDriverFactoryImpl : public LogDriverFactory, public LifeCycle { + public: + LogDriverFactoryImpl(); + + virtual void onConfigLoad() override; + inline std::shared_ptr<LogDriverBase> create() const override; + int loggerLevel() const override; + + const int & level; + + protected: + mutable std::shared_ptr<LoggerType> instance; +}; + +#endif + diff --git a/project2/common/loggerFactory.impl.h b/project2/common/loggerFactory.impl.h new file mode 100644 index 0000000..2488c6e --- /dev/null +++ b/project2/common/loggerFactory.impl.h @@ -0,0 +1,43 @@ +#ifndef LOGGERFACTORY_IMPL_H +#define LOGGERFACTORY_IMPL_H + +#include "loggerFactory.h" + +template<typename T> +LogDriverFactoryImpl<T>::LogDriverFactoryImpl() : + level(T::level) +{ +} + +template<typename T> +void +LogDriverFactoryImpl<T>::onConfigLoad() +{ + Logger()->setLoggerAt(this, level); + if (level == -1) { + instance.reset(); + } +} + +template<typename T> +std::shared_ptr<LogDriverBase> +LogDriverFactoryImpl<T>::create() const +{ + if (!instance) { + instance = std::make_shared<T>(); + } + return instance; +} + +template<typename T> +int +LogDriverFactoryImpl<T>::loggerLevel() const +{ + return level; +} + +#define DECLARE_LOGGER(N, T) \ + NAMEDPLUGIN(N, LogDriverFactoryImpl<T>, LogDriverFactory) + +#endif + diff --git a/project2/common/noOutputExecute.cpp b/project2/common/noOutputExecute.cpp deleted file mode 100644 index bed7bf0..0000000 --- a/project2/common/noOutputExecute.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include <pch.hpp> -#include "noOutputExecute.h" - -NoOutputExecute::NoOutputExecute(ScriptNodePtr p) : - SourceObject(p) -{ -} - -NoOutputExecute::NoOutputExecute(const std::string & n) : - SourceObject(n) -{ -} - -NoOutputExecute::~NoOutputExecute() -{ -} - diff --git a/project2/common/noOutputExecute.h b/project2/common/noOutputExecute.h deleted file mode 100644 index 61d03b5..0000000 --- a/project2/common/noOutputExecute.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef NOOUTPUTEXECUTE_H -#define NOOUTPUTEXECUTE_H - -#include "sourceObject.h" -#include "scriptStorage.h" - -class NoOutputExecute; -class ExecContext; -typedef boost::intrusive_ptr<NoOutputExecute> NoOutputExecutePtr; - -/// Base class for Project2 compoments that perform actions, but product no output -class NoOutputExecute : public virtual SourceObject { - public: - NoOutputExecute(ScriptNodePtr p); - NoOutputExecute(const std::string & n); - - virtual ~NoOutputExecute(); - - virtual void execute(ExecContext *) const = 0; -}; - -#endif - diff --git a/project2/common/options.cpp b/project2/common/options.cpp index c1ed762..20577eb 100644 --- a/project2/common/options.cpp +++ b/project2/common/options.cpp @@ -1,6 +1,6 @@ #include <pch.hpp> #include "options.h" -#include "instanceStore.impl.h" +#include <plugins.impl.h> class NamedOption : public Options::Option { public: @@ -75,7 +75,7 @@ Options::Options(Glib::ustring const & n) : Options & Options::operator()(const Glib::ustring & n, TargetPtr t, const Glib::ustring & d) { - options.push_back(new NamedOption(n, t, d)); + options.push_back(std::make_shared<NamedOption>(n, t, d)); return *this; } @@ -84,7 +84,7 @@ Options::operator()(const Glib::ustring & a) { for (OptionList::const_reverse_iterator i = options.rbegin(); i != options.rend(); ++i) { if (const NamedOption * no = dynamic_cast<const NamedOption *>(i->get())) { - options.push_back(new OptionAlias(a, no)); + options.push_back(std::make_shared<OptionAlias>(a, no)); break; } } @@ -169,5 +169,5 @@ Options::InstanceTarget::assign(const VariableType & value) const assigner(value); } -INSTANTIATESTORE(std::string, Options); +INSTANTIATEPLUGINOF(Options); diff --git a/project2/common/options.h b/project2/common/options.h index 3a7a28b..0d61d2f 100644 --- a/project2/common/options.h +++ b/project2/common/options.h @@ -2,29 +2,29 @@ #define OPTIONS_H #include <glibmm/ustring.h> -#include <intrusivePtrBase.h> #include <vector> #include <list> #include <boost/bind.hpp> #include <boost/function.hpp> #include <boost/utility/enable_if.hpp> #include "variableType.h" -#include "plugable.h" +#include <plugins.h> +#include <visibility.h> -class Options { +class DLL_PUBLIC Options : public AdHoc::AbstractPluginImplementation { public: class Target; enum TargetState { Default = 1, Global = 2, Platform = 3 }; typedef boost::function<const Glib::ustring &()> CurrentPlatform; - class Target : public IntrusivePtrBase { + class Target { public: virtual void reset() const = 0; virtual bool paramRequired() const = 0; virtual void consume(const Glib::ustring & platform, const VariableType & value, const CurrentPlatform & currentPlatform) const = 0; }; - typedef boost::intrusive_ptr<Target> TargetPtr; + typedef std::shared_ptr<Target> TargetPtr; typedef boost::function<void(const VariableType &)> Assigner; typedef boost::function<void()> Resetter; @@ -41,7 +41,7 @@ class Options { Resetter resetter; }; - class Option : public IntrusivePtrBase { + class Option { public: virtual void reset() const = 0; virtual bool paramRequired() const = 0; @@ -50,7 +50,7 @@ class Options { virtual bool accepts(const Glib::ustring & name) const = 0; virtual void consume(const Glib::ustring & name, const Glib::ustring & platform, const VariableType & value, const CurrentPlatform & currentPlatform) const = 0; }; - typedef boost::intrusive_ptr<Option> OptionPtr; + typedef std::shared_ptr<Option> OptionPtr; typedef std::list<OptionPtr> OptionList; Options(const Glib::ustring & name); @@ -63,7 +63,7 @@ class Options { static TargetPtr value(T * t, const D & d = D(), typename boost::enable_if<std::is_convertible<VariableType, T>, dummy>::type = 0) { - return new InstanceTarget( + return std::make_shared<InstanceTarget>( [t](const VariableType & v) { *t = v.as<T>(); }, [t, d]() { *t = d; }); } @@ -72,20 +72,20 @@ class Options { static TargetPtr value(T * t, const D & d = D(), typename boost::disable_if<std::is_convertible<VariableType, T>, dummy>::type = 0) { - return new InstanceTarget( - [t](const VariableType & v) { *t = v; }, + return std::make_shared<InstanceTarget>( + [t](const VariableType & v) { *t = v.as<std::string>(); }, [t, d]() { *t = d; }); } template <typename D> static TargetPtr function(const Assigner & assigner, const D & d) { - return new InstanceTarget(assigner, boost::bind(assigner, d)); + return std::make_shared<InstanceTarget>(assigner, boost::bind(assigner, d)); } static TargetPtr functions(const Assigner & assigner, const Resetter & resetter) { - return new InstanceTarget(assigner, resetter); + return std::make_shared<InstanceTarget>(assigner, resetter); } void reset() const; @@ -99,22 +99,20 @@ class Options { OptionList options; }; -// Registration helpers -// These work pluggable component style -typedef PluginsSameBase<Options, std::string> OptionsSets; - #define DECLARE_OPTIONS(Type, Label) \ static void init_options_##Type() __attribute__ ((constructor(200))); \ static void init_options_##Type() { \ - Options * o = new Options(Label); \ + auto o = std::make_shared<Options>(Label); \ Type::InitOptions(*o); \ - OptionsSets::Add(#Type, o); } \ + AdHoc::PluginManager::getDefault()->add<Options>(o, #Type, __FILE__, __LINE__); } \ void Type::InitOptions(Options & o) { o #define END_OPTIONS(Type) \ ;} \ static void kill_options_##Type() __attribute__ ((destructor(200))); \ - static void kill_options_##Type() { OptionsSets::Remove(#Type); } + static void kill_options_##Type() { \ + AdHoc::PluginManager::getDefault()->remove<Options>(#Type); \ + } #define INITOPTIONS \ static void InitOptions(Options &) diff --git a/project2/common/optionsSource.cpp b/project2/common/optionsSource.cpp index 0e1d751..8f94e3b 100644 --- a/project2/common/optionsSource.cpp +++ b/project2/common/optionsSource.cpp @@ -1,46 +1,83 @@ #include "optionsSource.h" #include "logger.h" -#include "instanceStore.impl.h" +#include <plugins.impl.h> class DefaultConfigConsumer : public ConfigConsumer { public: void operator()(const Glib::ustring & n, const Glib::ustring & p, const Glib::ustring & v, const Options::CurrentPlatform & cp) const { - InstanceSet<Options>::OnAll(boost::bind(&Options::consume, _1, n, p, v, cp)); + for (auto opts : AdHoc::PluginManager::getDefault()->getAll<Options>()) { + opts->implementation()->consume(n, p, v, cp); + } } const Options::Option * get(const Glib::ustring & n) const { - const Options::Option * rtn = NULL; - InstanceSet<Options>::OnAll([n,&rtn](const Options * os) { - const Options::Option * o = os->find(n); + for (auto opts : AdHoc::PluginManager::getDefault()->getAll<Options>()) { + const Options::Option * o = opts->implementation()->find(n); if (o) { - rtn = o; + return o; } - }); - return rtn; + } + return nullptr; } }; boost::posix_time::ptime OptionsSource::loadedTime = boost::posix_time::special_values::neg_infin; +template <typename X> +std::set<X *> +raw(const std::set<std::shared_ptr<X>> & xs) +{ + std::set<X *> y; + for (const auto & x : xs) { + y.insert(x.get()); + } + return y; +} + +void +OptionsSource::resetOptions() +{ + auto options = raw(AdHoc::PluginManager::getDefault()->getAll<Options>()); + decltype(options) resetConfigs; + while (options != resetConfigs) { + for (auto opts : options) { + if (resetConfigs.find(opts) == resetConfigs.end()) { + opts->implementation()->reset(); + resetConfigs.insert(opts); + auto newOptions = raw(AdHoc::PluginManager::getDefault()->getAll<Options>()); + if (newOptions != options) { + options = newOptions; + break; + } + } + } + } +} + void OptionsSource::loadSources(const Options::CurrentPlatform & platform) { - const auto & configs = InstanceSet<OptionsSource>::GetAll(); - if (std::find_if(configs.begin(), configs.end(), [](const OptionsSourcePtr & c) { return c->modifiedTime() > loadedTime; }) != configs.end()) { - InstanceSet<Options>::OnAll(boost::bind(&Options::reset, _1)); + auto configs = raw(AdHoc::PluginManager::getDefault()->getAll<OptionsSource>()); + if (std::find_if(configs.begin(), configs.end(), [](const AdHoc::PluginOf<OptionsSource> * c) { return c->implementation()->modifiedTime() > loadedTime; }) != configs.end()) { + resetOptions(); DefaultConfigConsumer dcc; - std::set<boost::shared_ptr<OptionsSource>> loadedConfigs; - while (loadedConfigs.size() != configs.size()) { + decltype(configs) loadedConfigs; + while (loadedConfigs != configs) { for (const auto & c : configs) { if (loadedConfigs.find(c) == loadedConfigs.end()) { - c->loadInto(dcc, platform); + c->implementation()->loadInto(dcc, platform); loadedConfigs.insert(c); + auto newConfigs = raw(AdHoc::PluginManager::getDefault()->getAll<OptionsSource>()); + if (newConfigs != configs) { + configs = newConfigs; + break; + } } } } - Plugable::onAllComponents(boost::bind(&ComponentLoader::onConfigLoad, _1)); - + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onConfigLoad, _1)); + loadedTime = boost::posix_time::microsec_clock::universal_time(); Logger()->messagebf(LOG_DEBUG, "Loaded configuration at %s", loadedTime); } @@ -49,15 +86,15 @@ OptionsSource::loadSources(const Options::CurrentPlatform & platform) void OptionsSource::loadSource(const Options::CurrentPlatform & platform, OptionsSourcePtr opts) { - InstanceSet<Options>::OnAll(boost::bind(&Options::reset, _1)); + resetOptions(); DefaultConfigConsumer dcc; opts->loadInto(dcc, platform); - Plugable::onAllComponents(boost::bind(&ComponentLoader::onConfigLoad, _1)); + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onConfigLoad, _1)); loadedTime = boost::posix_time::microsec_clock::universal_time(); Logger()->messagebf(LOG_DEBUG, "Loaded configuration at %s", loadedTime); } -INSTANTIATESTORE(std::string, OptionsSource); +INSTANTIATEPLUGINOF(OptionsSource); diff --git a/project2/common/optionsSource.h b/project2/common/optionsSource.h index 7f1deee..86ebbe9 100644 --- a/project2/common/optionsSource.h +++ b/project2/common/optionsSource.h @@ -4,7 +4,7 @@ #include <boost/function.hpp> #include <boost/date_time/posix_time/posix_time_types.hpp> #include <glibmm/ustring.h> -#include <intrusivePtrBase.h> +#include <visibility.h> #include "scriptLoader.h" #include "options.h" @@ -18,7 +18,7 @@ class OptionsSource; typedef boost::shared_ptr<OptionsSource> OptionsSourcePtr; /// Base class of things that load options -class OptionsSource { +class DLL_PUBLIC OptionsSource : public AdHoc::AbstractPluginImplementation { public: virtual ~OptionsSource() = default; @@ -29,15 +29,13 @@ class OptionsSource { static void loadSource(const Options::CurrentPlatform & platform, OptionsSourcePtr opts); private: + static void resetOptions(); + static boost::posix_time::ptime loadedTime; }; -typedef PluginsSameBase<OptionsSource, std::string> OptionsSources; #define DECLARE_OPTIONSSOURCE(Id, Inst) \ - static void init_optionsSource() __attribute__ ((constructor(200))); \ - static void init_optionsSource() { OptionsSources::Add(Id, Inst); } \ - static void kill_optionsSource() __attribute__ ((destructor(200))); \ - static void kill_optionsSource() { OptionsSources::Remove(Id); } + NAMEDPLUGIN(Id, Inst, OptionsSource) #endif diff --git a/project2/common/pch.hpp b/project2/common/pch.hpp index a18ebbb..757f7ea 100644 --- a/project2/common/pch.hpp +++ b/project2/common/pch.hpp @@ -5,17 +5,10 @@ #include <algorithm> #include <boost/any.hpp> #include <boost/bind.hpp> -#include <boost/filesystem/path.hpp> -#include <boost/function.hpp> -#include <boost/intrusive_ptr.hpp> -#include <boost/multi_index_container.hpp> -#include <boost/multi_index/member.hpp> -#include <boost/multi_index/ordered_index.hpp> -#include "options.h" +#include <boost/function/function_fwd.hpp> #include <boost/shared_ptr.hpp> -#include <boost/variant.hpp> +#include <boost/variant/variant_fwd.hpp> #include <glibmm/ustring.h> -#include <intrusivePtrBase.h> #include <iostream> #include <list> #include <map> @@ -25,13 +18,6 @@ #include <string.h> #include <string> #include <vector> -#include "scriptStorage.h" -#include "scriptLoader.h" -#include "plugable.h" -#include "variables.h" -#include "variableType.h" -#include "sourceObject.h" -#include "scripts.h" #endif #endif diff --git a/project2/common/plugable.cpp b/project2/common/plugable.cpp deleted file mode 100644 index 969f530..0000000 --- a/project2/common/plugable.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "plugable.h" - -void -Plugable::onAllComponents(const boost::function<void(ComponentLoader *)> & func) -{ - InstanceSet<ComponentLoader>::OnAll(func); -} - diff --git a/project2/common/plugable.h b/project2/common/plugable.h deleted file mode 100644 index eaccd49..0000000 --- a/project2/common/plugable.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef PLUGABLE_H -#define PLUGABLE_H - -#include <boost/function.hpp> -#include <boost/shared_ptr.hpp> -#include "instanceStore.h" -#include "exceptions.h" - -class ComponentLoader; - -class Plugable : public InstanceSet<ComponentLoader> { - public: - static void onAllComponents(const boost::function<void(ComponentLoader *)> & func); -}; - -/// All loaders, keyed by string, enum, int, etc -template<class Base, class Key, class AnonBase> -class PluginsDiffBase { - public: - typedef Key KeyType; - typedef InstanceMap<Base, KeyType> Map; - typedef InstanceSet<Base> Set; - typedef InstanceSet<AnonBase> AnonSet; - - static void Add(const KeyType & k, Base * i) - { - auto p = boost::shared_ptr<Base>(i); - Map::Add(k, p); - Set::Add(p); - AnonSet::Add(p); - } - - static void Remove(const KeyType & k) - { - auto p = Map::GetAll().find(k)->second; - Set::Remove(p); - AnonSet::Remove(p); - Map::Remove(k); - } -}; - -template<class Base, class Key> -class PluginsSameBase { - public: - typedef Key KeyType; - typedef InstanceMap<Base, KeyType> Map; - typedef InstanceSet<Base> Set; - - static void Add(const KeyType & k, Base * i) - { - auto p = boost::shared_ptr<Base>(i); - Map::Add(k, p); - Set::Add(p); - } - - static void Remove(const KeyType & k) - { - Set::Remove(Map::GetAll().find(k)->second); - Map::Remove(k); - } -}; - -#define TOKENPASTE(x, y) x ## y -#define TOKENPASTE2(x, y) TOKENPASTE(x, y) -#define DECLARE_CUSTOM_COMPONENT_LOADER(Key, Impl, Loader, BaseLoader) \ -namespace TOKENPASTE2(Impl, __LINE__) { \ - static void init_loader_##Impl() __attribute__ ((constructor(201))); \ - static void init_loader_##Impl() { PluginsDiffBase<BaseLoader, BaseLoader::KeyType, ComponentLoader>::Add(Key, new Loader()); } \ - static void kill_loader_##Impl() __attribute__ ((destructor(201))); \ - static void kill_loader_##Impl() { PluginsDiffBase<BaseLoader, BaseLoader::KeyType, ComponentLoader>::Remove(Key); } \ -} -#define DECLARE_CUSTOM_LOADER(Key, T) \ - DECLARE_CUSTOM_COMPONENT_LOADER(Key, T, T, ElementLoader) -#define DECLARE_COMPONENT_LOADER(Key, Type, BaseLoader) \ - DECLARE_CUSTOM_COMPONENT_LOADER(Key, Type, BaseLoader::For<Type>, BaseLoader) -#define DECLARE_LOADER(Key, Loader) \ - DECLARE_COMPONENT_LOADER(Key, Loader, ElementLoader) -#define DECLARE_GENERIC_LOADER(Key, B, T) \ - DECLARE_CUSTOM_COMPONENT_LOADER(Key, T, B::For<T>, B); - -#endif - diff --git a/project2/common/presenter.cpp b/project2/common/presenter.cpp index 012020d..5636452 100644 --- a/project2/common/presenter.cpp +++ b/project2/common/presenter.cpp @@ -1,7 +1,8 @@ #include <pch.hpp> +#include "scripts.h" +#include "execContext.h" #include "presenter.h" -#include "dataSource.h" -#include "instanceStore.impl.h" +#include <factory.impl.h> NameValuePairPresenter::NameValuePairPresenter() { @@ -120,5 +121,5 @@ MultiRowSetPresenter::finalizeContent() const { } -INSTANTIATESTORE(std::string, PresenterLoader); +INSTANTIATEFACTORY(MultiRowSetPresenter, std::shared_ptr<const ScriptNode>, const ObjectSource &, ExecContext *); diff --git a/project2/common/presenter.h b/project2/common/presenter.h index 107e878..1a0e718 100644 --- a/project2/common/presenter.h +++ b/project2/common/presenter.h @@ -1,14 +1,14 @@ #ifndef PRESENTER_H #define PRESENTER_H -#include <boost/intrusive_ptr.hpp> #include <boost/shared_ptr.hpp> #include <boost/function.hpp> #include <glibmm/ustring.h> #include "view.h" #include "scriptLoader.h" +#include <visibility.h> -class NameValuePairPresenter : public virtual IntrusivePtrBase { +class DLL_PUBLIC NameValuePairPresenter : public virtual Something { public: NameValuePairPresenter(); virtual ~NameValuePairPresenter(); @@ -17,7 +17,7 @@ class NameValuePairPresenter : public virtual IntrusivePtrBase { virtual void addAttribute(const Glib::ustring & name, const VariableType & value) const; }; -class RowSetPresenter : public NameValuePairPresenter { +class DLL_PUBLIC RowSetPresenter : public NameValuePairPresenter { public: RowSetPresenter(); virtual ~RowSetPresenter() = 0; @@ -26,7 +26,7 @@ class RowSetPresenter : public NameValuePairPresenter { virtual void finishRow() const = 0; }; -class MultiRowSetPresenter : public RowSetPresenter { +class DLL_PUBLIC MultiRowSetPresenter : public RowSetPresenter { public: MultiRowSetPresenter(ObjectSource); virtual ~MultiRowSetPresenter() = 0; @@ -43,7 +43,7 @@ class MultiRowSetPresenter : public RowSetPresenter { virtual void finalizeContent() const; }; -class Presenter : public MultiRowSetPresenter { +class DLL_PUBLIC Presenter : public MultiRowSetPresenter { public: Presenter(ObjectSource); virtual ~Presenter() = 0; @@ -65,19 +65,19 @@ class Presenter : public MultiRowSetPresenter { void finishRowSet() const; }; -class ContentPresenter { +class DLL_PUBLIC ContentPresenter { public: ContentPresenter(const Glib::ustring & contentType); const Glib::ustring contentType; }; -typedef boost::intrusive_ptr<const Presenter> PresenterCPtr; -typedef boost::intrusive_ptr<Presenter> PresenterPtr; -typedef boost::intrusive_ptr<RowSetPresenter> RowSetPresenterPtr; -typedef boost::intrusive_ptr<MultiRowSetPresenter> MultiRowSetPresenterPtr; -typedef boost::intrusive_ptr<NameValuePairPresenter> NameValuePairPresenterPtr; +typedef std::shared_ptr<const Presenter> PresenterCPtr; +typedef std::shared_ptr<Presenter> PresenterPtr; +typedef std::shared_ptr<RowSetPresenter> RowSetPresenterPtr; +typedef std::shared_ptr<MultiRowSetPresenter> MultiRowSetPresenterPtr; +typedef std::shared_ptr<NameValuePairPresenter> NameValuePairPresenterPtr; -typedef GenLoader<MultiRowSetPresenter, std::string, ScriptNodePtr, ObjectSource, ExecContext *> PresenterLoader; +typedef AdHoc::Factory<MultiRowSetPresenter, std::shared_ptr<const ScriptNode>, const ObjectSource &, ExecContext *> PresenterFactory; #endif diff --git a/project2/common/presenterCache.cpp b/project2/common/presenterCache.cpp index 78122d0..b1b2c94 100644 --- a/project2/common/presenterCache.cpp +++ b/project2/common/presenterCache.cpp @@ -1,4 +1,5 @@ #include "presenterCache.h" +#include <factory.impl.h> PresenterCache::PresenterCache(ScriptNodePtr s) : SourceObject(s), @@ -12,6 +13,8 @@ PresenterCache::flushCache() { } +INSTANTIATEFACTORY(PresenterCache, std::shared_ptr<const ScriptNode>); + class WriteToCache : public TransformImpl<WritableContent, PresenterCache> { public: void transform(const WritableContent * wc, PresenterCache * pc, ExecContext * ec) const { diff --git a/project2/common/presenterCache.h b/project2/common/presenterCache.h index b0adab8..dba90d0 100644 --- a/project2/common/presenterCache.h +++ b/project2/common/presenterCache.h @@ -4,8 +4,9 @@ #include "transform.h" #include "scripts.h" #include "iHaveParameters.h" +#include <visibility.h> -class PresenterCache : public SourceObject, public virtual TransformSource, public StaticContent, public SourceOf<StaticContent>, public IHaveParameters { +class DLL_PUBLIC PresenterCache : public SourceObject, public virtual TransformSource, public StaticContent, public SourceOf<StaticContent>, public IHaveParameters { public: PresenterCache(ScriptNodePtr); virtual bool check(time_t scriptMtime, ExecContext *) const = 0; @@ -14,6 +15,7 @@ class PresenterCache : public SourceObject, public virtual TransformSource, publ virtual void flushCache(); const std::string encoding; }; -typedef boost::intrusive_ptr<PresenterCache> PresenterCachePtr; +typedef std::shared_ptr<PresenterCache> PresenterCachePtr; +typedef AdHoc::Factory<PresenterCache, std::shared_ptr<const ScriptNode>> PresenterCacheFactory; #endif diff --git a/project2/common/rowProcessor.cpp b/project2/common/rowProcessor.cpp index 5156f62..c6a1042 100644 --- a/project2/common/rowProcessor.cpp +++ b/project2/common/rowProcessor.cpp @@ -2,7 +2,7 @@ #include "rowProcessor.h" #include "logger.h" #include "commonObjects.h" -#include "scopeObject.h" +#include <scopeExit.h> #include <boost/algorithm/string/predicate.hpp> #include "execContext.h" @@ -13,8 +13,8 @@ RowProcessor::RowProcessor(ScriptNodePtr p) : CROE(p->value("cacheRowsOnError", false, NULL)), IRSE(p->value("ignoreRowSourceError", false, NULL)) { - p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&caches)); - p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&tests)); + p->script.lock()->loader.addLoadTarget(p, Storer::into<RowSetCacheFactory>(&caches)); + p->script.lock()->loader.addLoadTarget(p, Storer::into<TestFactory>(&tests)); } void @@ -27,7 +27,7 @@ void RowProcessor::execute(ExecContext * ec, const RowProcessorCallback & cb) const { ec->ParametersPush(this); - ScopeObject _ihp( + AdHoc::ScopeExit _ihp( boost::bind(&ExecContext::ParametersPop, ec), boost::bind(&RowProcessor::saveCaches, this, ec), boost::bind((CROE ? &RowProcessor::saveCaches : &RowProcessor::discardCaches), this, ec), @@ -43,7 +43,7 @@ RowProcessor::execute(ExecContext * ec, const RowProcessorCallback & cb) const } Logger()->messagebf(LOG_DEBUG, "Executing from source '%s'", source->name); if (const SourceObject * so = dynamic_cast<const SourceObject *>(this)) { - ScopeObject onComplete(boost::bind(&SourceObject::send, so, Complete)); + AdHoc::ScopeExit onComplete(boost::bind(&SourceObject::send, so, Complete)); } const auto rowReadyCallback = boost::bind(&RowProcessor::rowReadyInternal, this, _1, cb, ec); if (IRSE) { diff --git a/project2/common/rowProcessor.h b/project2/common/rowProcessor.h index ca36b32..990b228 100644 --- a/project2/common/rowProcessor.h +++ b/project2/common/rowProcessor.h @@ -8,12 +8,13 @@ #include "rowSetCache.h" #include "test.h" #include "scriptStorage.h" +#include <visibility.h> class Presenter; class ExecContext; /// Base class for Project2 components that work with row sets -class RowProcessor : public IHaveParameters { +class DLL_PUBLIC RowProcessor : public IHaveParameters { public: enum EventIDs { Complete }; RowProcessor(ScriptNodePtr); @@ -25,7 +26,7 @@ class RowProcessor : public IHaveParameters { const bool IRSE; protected: - boost::intrusive_ptr<RowSet> source; + std::shared_ptr<RowSet> source; void execute(ExecContext *, const RowProcessorCallback &) const; private: diff --git a/project2/common/rowSet.cpp b/project2/common/rowSet.cpp index cb7dd31..8b99586 100644 --- a/project2/common/rowSet.cpp +++ b/project2/common/rowSet.cpp @@ -1,11 +1,12 @@ #include <pch.hpp> #include "rowSet.h" #include "commonObjects.h" -#include "scopeObject.h" +#include <scopeExit.h> #include "logger.h" #include "variables.h" #include <boost/bind.hpp> #include "execContext.h" +#include <factory.impl.h> RowSet::RowSet(ScriptNodePtr p) : SourceObject(p) @@ -22,7 +23,7 @@ RowState::process(ExecContext * ec, const RowProcessorCallback & rp, bool r) { rowNum += 1; ec->RowValuesPush(this); - ScopeObject s(boost::bind(&ExecContext::RowValuesPop, ec)); + AdHoc::ScopeExit s(boost::bind(&ExecContext::RowValuesPop, ec)); rp(this); if (r) { reset(); @@ -87,3 +88,5 @@ RowState::foreachAttr(const AttrAction &) const // rowNum is magic, so it doesn't count :) } +INSTANTIATEFACTORY(RowSet, std::shared_ptr<const ScriptNode>); + diff --git a/project2/common/rowSet.h b/project2/common/rowSet.h index f36f79f..eef887a 100644 --- a/project2/common/rowSet.h +++ b/project2/common/rowSet.h @@ -7,17 +7,18 @@ #include "exceptions.h" #include "columns.h" #include <boost/function.hpp> +#include <visibility.h> class RowSet; class VariableType; class RowState; -typedef boost::intrusive_ptr<RowSet> RowSetPtr; -typedef boost::intrusive_ptr<const RowSet> ConstRowSetPtr; +typedef std::shared_ptr<RowSet> RowSetPtr; +typedef std::shared_ptr<const RowSet> ConstRowSetPtr; typedef boost::function<void(const RowState *)> RowProcessorCallback; /// Base class for Project2 components that provide a row set representation of data -class RowSet : public SourceObject { +class DLL_PUBLIC RowSet : public virtual SourceObject { public: SimpleNumericException(ParentOutOfRange); SimpleMessageException(FieldDoesNotExist); @@ -29,7 +30,7 @@ class RowSet : public SourceObject { virtual void execute(const Glib::ustring &, const RowProcessorCallback &, ExecContext *) const = 0; }; -class RowState { +class DLL_PUBLIC RowState { public: RowState(); virtual ~RowState() = default; @@ -55,6 +56,7 @@ class RowState { private: unsigned int rowNum; }; +typedef AdHoc::Factory<RowSet, std::shared_ptr<const ScriptNode>> RowSetFactory; #endif diff --git a/project2/common/rowSetCache.cpp b/project2/common/rowSetCache.cpp index 95a949b..a4df9b1 100644 --- a/project2/common/rowSetCache.cpp +++ b/project2/common/rowSetCache.cpp @@ -4,10 +4,11 @@ #include "rowProcessor.h" #include "logger.h" #include <glibmm/exception.h> +#include <factory.impl.h> RowSetCache::RowSetCache(ScriptNodePtr p) : - IHaveParameters(p), SourceObject(p), + IHaveParameters(p), inherit(p->value("inherit", true, NULL).as<bool>()) { } @@ -47,3 +48,5 @@ RowSetCache::applyKeys(ExecContext * ec, const KeyApplier & f, const IHaveParame } } +INSTANTIATEFACTORY(RowSetCache, std::shared_ptr<const ScriptNode>); + diff --git a/project2/common/rowSetCache.h b/project2/common/rowSetCache.h index 055b07e..c600a15 100644 --- a/project2/common/rowSetCache.h +++ b/project2/common/rowSetCache.h @@ -5,12 +5,13 @@ #include "presenter.h" #include "iHaveParameters.h" #include "rowSet.h" +#include <visibility.h> class RowSet; class RowState; -typedef boost::intrusive_ptr<const RowSet> RowSetCPtr; +typedef std::shared_ptr<const RowSet> RowSetCPtr; -class RowSetCache : public IHaveParameters, public SourceObject { +class DLL_PUBLIC RowSetCache : public IHaveParameters, public virtual SourceObject { public: RowSetCache(ScriptNodePtr p); @@ -25,7 +26,8 @@ class RowSetCache : public IHaveParameters, public SourceObject { void applyKeys(ExecContext * ec, const KeyApplier & f, const IHaveParameters * ps) const; const bool inherit; }; -typedef boost::intrusive_ptr<RowSetCache> RowSetCachePtr; +typedef std::shared_ptr<RowSetCache> RowSetCachePtr; +typedef AdHoc::Factory<RowSetCache, std::shared_ptr<const ScriptNode>> RowSetCacheFactory; #endif diff --git a/project2/common/scriptLoader.cpp b/project2/common/scriptLoader.cpp index 56461d9..e7eb41b 100644 --- a/project2/common/scriptLoader.cpp +++ b/project2/common/scriptLoader.cpp @@ -1,16 +1,12 @@ #include <pch.hpp> -#include "scopeObject.h" #include "scriptLoader.h" #include "scriptStorage.h" #include "library.h" #include <boost/shared_ptr.hpp> #include <boost/function.hpp> #include <boost/function_equal.hpp> -#include "instanceStore.impl.h" #include "appInstance.h" - -typedef std::map<std::string, boost::shared_ptr<ElementLoader> > ElementLoaderMap; -typedef std::set<boost::shared_ptr<ComponentLoader> > ComponentLoaderSet; +#include <factory.impl.h> LoaderBase::LoaderBase() : recursive(true) @@ -22,15 +18,15 @@ LoaderBase::~LoaderBase() } void -LoaderBase::addLoadTarget(ScriptNodePtr src, boost::intrusive_ptr<Storer> target) { +LoaderBase::addLoadTarget(ScriptNodePtr src, std::shared_ptr<Storer> target) { targets[src].push_back(target); } void -LoaderBase::addLoadTargetSub(ScriptNodePtr src, const Glib::ustring & name, bool required, boost::intrusive_ptr<Storer> target) +LoaderBase::addLoadTargetSub(ScriptNodePtr src, const Glib::ustring & name, bool required, std::shared_ptr<Storer> target) { if (ScriptNodePtr c = getSub(src, name, required)) { - src->script->loader.addLoadTarget(c, target); + src->script.lock()->loader.addLoadTarget(c, target); } } @@ -69,14 +65,14 @@ LoaderBase::collectAll(ScriptNodePtr node, LoadedObjects & loadedObjects, bool c node->obj = s->create(node); break; } - catch (const NotSupported &) { + catch (const AdHoc::NoSuchPluginException &) { } } if (!node->obj) { throw NotSupported(node->get_name()); } } - if (SourceObjectPtr p = boost::dynamic_pointer_cast<SourceObject>(node->obj)) { + if (SourceObjectPtr p = std::dynamic_pointer_cast<SourceObject>(node->obj)) { loadedObjects.insert(p.get()); } for (const StorerPtr & s : sts) { @@ -100,9 +96,8 @@ LoaderBase::collectAll(ScriptNodePtr node, LoadedObjects & loadedObjects, bool c } void -LoaderBase::collectAll(const CommonObjects * co, bool childrenOnly, ScriptNodePtr node) +LoaderBase::collectAll(const CommonObjects * co, bool childrenOnly) { - addLoadTarget(node, Storer::into<ElementLoader>(&libraries)); Targets::iterator i; LoadedObjects loadedObjects; while ((i = targets.begin()) != targets.end()) { @@ -116,5 +111,5 @@ LoaderBase::collectAll(const CommonObjects * co, bool childrenOnly, ScriptNodePt } } -INSTANTIATESTORE(std::string, ScriptReaderLoader); +INSTANTIATEFACTORY(ScriptReader, const std::string &, const std::string &); diff --git a/project2/common/scriptLoader.h b/project2/common/scriptLoader.h index ca888cf..c9c48b5 100644 --- a/project2/common/scriptLoader.h +++ b/project2/common/scriptLoader.h @@ -3,25 +3,23 @@ #include <set> #include <string> -#include <boost/intrusive_ptr.hpp> -#include "intrusivePtrBase.h" #include "sourceObject.h" -#include "genLoader.h" +#include <factory.h> #include "scripts_fwd.h" #include <glibmm/ustring.h> #include <map> #include <vector> +#include <visibility.h> -class ComponentLoader; class CommonObjects; class Storer; class ScriptReader; class SourceObject; -typedef boost::intrusive_ptr<SourceObject> SourceObjectPtr; +typedef std::shared_ptr<SourceObject> SourceObjectPtr; -class LoaderBase { +class DLL_PUBLIC LoaderBase { public: - typedef boost::intrusive_ptr<Storer> StorerPtr; + typedef std::shared_ptr<Storer> StorerPtr; typedef std::vector<StorerPtr> StorerPtrs; typedef std::map<ScriptNodePtr, StorerPtrs> Targets; typedef std::set<SourceObject *> LoadedObjects; @@ -29,9 +27,9 @@ class LoaderBase { LoaderBase(); virtual ~LoaderBase(); - void collectAll(const CommonObjects * co, bool childrenOnly, ScriptNodePtr script); - void addLoadTarget(ScriptNodePtr src, boost::intrusive_ptr<Storer> target); - void addLoadTargetSub(ScriptNodePtr src, const Glib::ustring & name, bool required, boost::intrusive_ptr<Storer> target); + void collectAll(const CommonObjects * co, bool childrenOnly); + void addLoadTarget(ScriptNodePtr src, std::shared_ptr<Storer> target); + void addLoadTargetSub(ScriptNodePtr src, const Glib::ustring & name, bool required, std::shared_ptr<Storer> target); void discardLoadTargets(); private: @@ -45,8 +43,5 @@ class LoaderBase { const Glib::ustring ns; }; -/// Helper for loading and maintaining Project2 script components -typedef GenLoader<SourceObject, std::string, ScriptNodePtr> ElementLoader; - #endif diff --git a/project2/common/scriptStorage.h b/project2/common/scriptStorage.h index cb947aa..dd9da8b 100644 --- a/project2/common/scriptStorage.h +++ b/project2/common/scriptStorage.h @@ -5,58 +5,62 @@ #include "scriptLoader.h" #include "exceptions.h" #include "scripts.h" +#include "lifeCycle.h" #include <set> #include <list> #include <map> -#include <boost/intrusive_ptr.hpp> #include <boost/bind.hpp> #include <boost/function.hpp> SimpleMessageException(StoreFailed); #define STORAGEOF(X) \ - std::map<std::string, boost::intrusive_ptr<X> > + std::map<std::string, std::shared_ptr<X> > #define ANONORDEREDSTORAGEOF(X) \ - std::list<boost::intrusive_ptr<X> > + std::list<std::shared_ptr<X> > #define ANONSTORAGEOF(X) \ - std::set<boost::intrusive_ptr<X> > + std::set<std::shared_ptr<X> > class Storer; template <class X, class L> class StorerBase; -typedef boost::intrusive_ptr<Storer> StorerPtr; -class Storer : public virtual IntrusivePtrBase { +typedef std::shared_ptr<Storer> StorerPtr; +class Storer { public: template <class L, typename PtrOfX, typename... C> - static boost::intrusive_ptr<StorerBase<typename PtrOfX::element_type, L> > into(PtrOfX * obj, const C & ... c); + static std::shared_ptr<StorerBase<typename PtrOfX::element_type, L> > into(PtrOfX * obj, const C & ... c); template <class L, class X, typename... C> - static boost::intrusive_ptr<StorerBase<X, L> > into(STORAGEOF(X) * map, const C & ... c); + static std::shared_ptr<StorerBase<X, L> > into(STORAGEOF(X) * map, const C & ... c); template <class L, class X, typename... C> - static boost::intrusive_ptr<StorerBase<X, L> > into(ANONSTORAGEOF(X) * set, const C & ... c); + static std::shared_ptr<StorerBase<X, L> > into(ANONSTORAGEOF(X) * set, const C & ... c); template <class L, class X, typename... C> - static boost::intrusive_ptr<StorerBase<X, L> > into(ANONORDEREDSTORAGEOF(X) * list, const C & ... c); + static std::shared_ptr<StorerBase<X, L> > into(ANONORDEREDSTORAGEOF(X) * list, const C & ... c); - virtual boost::intrusive_ptr<IntrusivePtrBase> create(ScriptNodePtr) const = 0; - virtual bool save(boost::intrusive_ptr<IntrusivePtrBase>, ScriptNodePtr) = 0; - virtual bool cacheable(ScriptNodePtr) const { return true; } + virtual std::shared_ptr<Something> create(std::shared_ptr<const ScriptNode>) const = 0; + virtual bool save(std::shared_ptr<Something>, std::shared_ptr<const ScriptNode>) = 0; + virtual bool cacheable(std::shared_ptr<const ScriptNode>) const { return true; } }; template <class X, class L> class StorerBase : public Storer { public: - typedef boost::function2<boost::intrusive_ptr<IntrusivePtrBase>, L *, ScriptNodePtr> Creator; + typedef boost::function2<std::shared_ptr<Something>, std::shared_ptr<const L>, std::shared_ptr<const ScriptNode>> Creator; StorerBase(const Creator & c) : creator(c) { } - boost::intrusive_ptr<IntrusivePtrBase> create(ScriptNodePtr p) const { - return creator(InstanceMap<L, std::string>::template Get<NotSupported>(p->get_name()).get(), p); + std::shared_ptr<Something> create(std::shared_ptr<const ScriptNode> p) const { + return creator(L::get(p->get_name()), p); } - bool cacheable(ScriptNodePtr p) const { - return InstanceMap<L, std::string>::template Get<NotSupported>(p->get_name())->cacheable(); + bool cacheable(std::shared_ptr<const ScriptNode> p) const { + auto f = AdHoc::PluginManager::getDefault()->get<L>(p->get_name()); + if (auto c = std::dynamic_pointer_cast<const LifeCycle>(f->implementation())) { + return c->cacheable(); + } + return true; } - bool save(boost::intrusive_ptr<IntrusivePtrBase> o, ScriptNodePtr name) { - boost::intrusive_ptr<X> O = boost::dynamic_pointer_cast<X>(o); + bool save(std::shared_ptr<Something> o, std::shared_ptr<const ScriptNode> name) { + std::shared_ptr<X> O = std::dynamic_pointer_cast<X>(o); if (O) { if (!insert(O)) { throw StoreFailed(name->get_name()); @@ -64,7 +68,7 @@ class StorerBase : public Storer { } return (O != NULL); } - virtual bool insert(boost::intrusive_ptr<X>) = 0; + virtual bool insert(std::shared_ptr<X>) = 0; private: Creator creator; }; @@ -76,7 +80,7 @@ class StorerImpl : public StorerBase<X, L> { StorerImpl(M * o, const typename StorerBase<X, L>::Creator & c) : StorerBase<X, L>(c), obj(o) { } - bool insert(boost::intrusive_ptr<X> O) + bool insert(std::shared_ptr<X> O) { *obj = O; return true; @@ -90,7 +94,7 @@ class StorerImpl<X, STORAGEOF(X), L> : public StorerBase<X, L> { StorerImpl(STORAGEOF(X) * m, const typename StorerBase<X, L>::Creator & c) : StorerBase<X, L>(c), map(m) { } - bool insert(boost::intrusive_ptr<X> O) + bool insert(std::shared_ptr<X> O) { return map->insert(typename Map::value_type(O->name, O)).second; } @@ -103,7 +107,7 @@ class StorerImpl<X, ANONSTORAGEOF(X), L> : public StorerBase<X, L> { StorerImpl(ANONSTORAGEOF(X) * m, const typename StorerBase<X, L>::Creator & c) : StorerBase<X, L>(c), map(m) { } - bool insert(boost::intrusive_ptr<X> O) + bool insert(std::shared_ptr<X> O) { map->insert(O); return true; @@ -117,7 +121,7 @@ class StorerImpl<X, ANONORDEREDSTORAGEOF(X), L> : public StorerBase<X, L> { StorerImpl(ANONORDEREDSTORAGEOF(X) * m, const typename StorerBase<X, L>::Creator & c) : StorerBase<X, L>(c), map(m) { } - bool insert(boost::intrusive_ptr<X> O) + bool insert(std::shared_ptr<X> O) { map->push_back(O); return true; @@ -126,27 +130,27 @@ class StorerImpl<X, ANONORDEREDSTORAGEOF(X), L> : public StorerBase<X, L> { }; template <class L, class PtrOfX, typename... C> -boost::intrusive_ptr<StorerBase<typename PtrOfX::element_type, L> > +std::shared_ptr<StorerBase<typename PtrOfX::element_type, L> > Storer::into(PtrOfX * obj, const C & ... c) { - return new StorerImpl<typename PtrOfX::element_type, PtrOfX, L>(obj, boost::bind(&L::create, _1, _2, c...)); + return std::make_shared<StorerImpl<typename PtrOfX::element_type, PtrOfX, L>>(obj, boost::bind(&L::create, _1, _2, c...)); } template <class L, class X, typename... C> -boost::intrusive_ptr<StorerBase<X, L> > +std::shared_ptr<StorerBase<X, L> > Storer::into(STORAGEOF(X) * map, const C & ... c) { - return new StorerImpl<X, STORAGEOF(X), L>(map, boost::bind(&L::create, _1, _2, c...)); + return std::make_shared<StorerImpl<X, STORAGEOF(X), L>>(map, boost::bind(&L::create, _1, _2, c...)); } template <class L, class X, typename... C> -boost::intrusive_ptr<StorerBase<X, L> > +std::shared_ptr<StorerBase<X, L> > Storer::into(ANONSTORAGEOF(X) * set, const C & ... c) { - return new StorerImpl<X, ANONSTORAGEOF(X), L>(set, boost::bind(&L::create, _1, _2, c...)); + return std::make_shared<StorerImpl<X, ANONSTORAGEOF(X), L>>(set, boost::bind(&L::create, _1, _2, c...)); } template <class L, class X, typename... C> -boost::intrusive_ptr<StorerBase<X, L> > +std::shared_ptr<StorerBase<X, L> > Storer::into(ANONORDEREDSTORAGEOF(X) * list, const C & ... c) { - return new StorerImpl<X, ANONORDEREDSTORAGEOF(X), L>(list, boost::bind(&L::create, _1, _2, c...)); + return std::make_shared<StorerImpl<X, ANONORDEREDSTORAGEOF(X), L>>(list, boost::bind(&L::create, _1, _2, c...)); } #endif diff --git a/project2/common/scripts.cpp b/project2/common/scripts.cpp index ff80870..5f4ba64 100644 --- a/project2/common/scripts.cpp +++ b/project2/common/scripts.cpp @@ -1,8 +1,9 @@ #include "scripts.h" #include <algorithm> #include "variables/fixed.h" -#include <boost/filesystem/convenience.hpp> +#include <filesystem> #include "appInstance.h" +#include <plugins.impl.h> DECLARE_OPTIONS(Scripts, "Project2 Script options") ("common.namespace", Options::value(&scriptNamespace, "http://project2.randomdan.homeip.net"), @@ -15,18 +16,18 @@ std::string Scripts::scriptNamespacePrefix; std::string Scripts::scriptNamespace; ScriptNode::ScriptNode(ScriptReaderPtr s) : - script(s.get()) + script(s) { } -VariableImpl * +Variable::VariableImplPtr ScriptNode::variable(const Glib::ustring & n, const VariableType & def) const { try { return variable(n); } catch (const ValueNotFound &) { - return new VariableFixed(def); + return std::make_shared<VariableFixed>(def); } } @@ -61,13 +62,16 @@ ScriptNode::value(const Glib::ustring & n, ExecContext * ec) const void ScriptReader::load(const CommonObjects * co, bool childrenOnly) const { - loader.collectAll(co, childrenOnly, root()); + loader.collectAll(co, childrenOnly); } ScriptReaderPtr ScriptReader::resolveScript(const std::string & group, const std::string & name, bool ii) { - boost::filesystem::path e(name); + std::filesystem::path e(name); + if (e.is_absolute()) { + e = e.lexically_relative("/"); + } while (!e.empty()) { ScriptKey sk(group, e.string()); ScriptReaderPtr rs = AppInstance::current().cachedScript(sk); @@ -75,8 +79,8 @@ ScriptReader::resolveScript(const std::string & group, const std::string & name, return rs; } else { - for (const auto & rl : InstanceSet<ScriptReaderLoader>::GetAll()) { - rs = rl->resolveScript(group, e.string()); + for (const auto & rl : AdHoc::PluginManager::getDefault()->getAll<ScriptReaderFactory>()) { + rs = rl->implementation()->create(group, e.string()); if (rs) { AppInstance::current().cacheScript(sk, rs); return rs; diff --git a/project2/common/scripts.h b/project2/common/scripts.h index 8bf450d..2d1dcc4 100644 --- a/project2/common/scripts.h +++ b/project2/common/scripts.h @@ -1,8 +1,6 @@ #ifndef SCRIPTS_H #define SCRIPTS_H -#include "intrusivePtrBase.h" -#include <boost/intrusive_ptr.hpp> #include <boost/tuple/tuple.hpp> #include <boost/function.hpp> #include <boost/optional.hpp> @@ -12,6 +10,7 @@ #include "variableType.h" #include "options.h" #include <vector> +#include <visibility.h> SimpleMessageException(ValueNotFound); SimpleMessage2Exception(ScriptNotFound); @@ -20,14 +19,14 @@ SimpleMessage2Exception(DependencyNotFound); class VariableImpl; class ExecContext; -class Scripts { +class DLL_PUBLIC Scripts { public: INITOPTIONS; static std::string scriptNamespace; static std::string scriptNamespacePrefix; }; -class ScriptNode : public IntrusivePtrBase { +class DLL_PUBLIC ScriptNode { public: ScriptNode(ScriptReaderPtr); virtual ~ScriptNode() { } @@ -49,20 +48,20 @@ class ScriptNode : public IntrusivePtrBase { virtual bool valueExists(const Glib::ustring & name) const = 0; virtual bool applyValue(const Glib::ustring & name, VariableType & target, ExecContext *) const = 0; - virtual VariableImpl * variable(const boost::optional<Glib::ustring> & defaultSource = boost::optional<Glib::ustring>()) const = 0; - virtual VariableImpl * variable(const Glib::ustring & name) const = 0; - VariableImpl * variable(const Glib::ustring & name, const VariableType & def) const; + virtual std::shared_ptr<VariableImpl> variable(const boost::optional<Glib::ustring> & defaultSource = boost::optional<Glib::ustring>()) const = 0; + virtual std::shared_ptr<VariableImpl> variable(const Glib::ustring & name) const = 0; + std::shared_ptr<VariableImpl> variable(const Glib::ustring & name, const VariableType & def) const; VariableType value(const Glib::ustring & name, ExecContext *) const; VariableType value(const Glib::ustring & name, const VariableType & def, ExecContext *) const; virtual void composeWithCallbacks(const LiteralCallback &, const NodeCallback &) const = 0; - const ScriptReader * script; + std::weak_ptr<const ScriptReader> script; private: friend class LoaderBase; - mutable boost::intrusive_ptr<IntrusivePtrBase> obj; + mutable std::shared_ptr<Something> obj; }; -class ScriptReader : public virtual IntrusivePtrBase { +class DLL_PUBLIC ScriptReader { public: typedef boost::tuple<const std::string, const std::string> ScriptKey; @@ -80,13 +79,7 @@ class ScriptReader : public virtual IntrusivePtrBase { mutable std::map<std::string, SourceObject *> namedComponents; }; -/// Base class to implement script reader modules -class ScriptReaderLoader : public ComponentLoader { - public: - typedef std::string KeyType; - - virtual ScriptReaderPtr resolveScript(const std::string & group, const std::string & name) const = 0; -}; +typedef AdHoc::Factory<ScriptReader, const std::string &, const std::string &> ScriptReaderFactory; #endif diff --git a/project2/common/scripts_fwd.h b/project2/common/scripts_fwd.h index 7d5ed00..92f8e31 100644 --- a/project2/common/scripts_fwd.h +++ b/project2/common/scripts_fwd.h @@ -2,10 +2,12 @@ #define SCRIPTS_FWD_H #include <boost/intrusive_ptr.hpp> +#include <visibility.h> -class ScriptNode; -class ScriptReader; -typedef boost::intrusive_ptr<const ScriptNode> ScriptNodePtr; -typedef boost::intrusive_ptr<const ScriptReader> ScriptReaderPtr; +class DLL_PUBLIC Something; +class DLL_PUBLIC ScriptNode; +class DLL_PUBLIC ScriptReader; +typedef std::shared_ptr<const ScriptNode> ScriptNodePtr; +typedef std::shared_ptr<const ScriptReader> ScriptReaderPtr; #endif diff --git a/project2/common/session.cpp b/project2/common/session.cpp index cba5397..716c8b0 100644 --- a/project2/common/session.cpp +++ b/project2/common/session.cpp @@ -37,7 +37,7 @@ Session::Empty() const VariableType Session::GetValue(const Glib::ustring & name) const { - return safeMapLookup<VariableNotFound>(vars, name); + return AdHoc::safeMapLookup<VariableNotFound>(vars, name); } void diff --git a/project2/common/session.h b/project2/common/session.h index 24b021e..4e9f277 100644 --- a/project2/common/session.h +++ b/project2/common/session.h @@ -4,14 +4,13 @@ #include <boost/uuid/uuid.hpp> #include <map> #include <glibmm/ustring.h> -#include <boost/intrusive_ptr.hpp> #include <boost/function.hpp> -#include "intrusivePtrBase.h" #include "variables.h" #include "exceptions.h" +#include <visibility.h> /// Base class for classes implementing session variable storage -class Session : public virtual IntrusivePtrBase { +class DLL_PUBLIC Session { public: SimpleMessageException(VariableNotFound); typedef std::map<Glib::ustring, VariableType> Values; @@ -39,7 +38,7 @@ class Session : public virtual IntrusivePtrBase { private: mutable boost::uuids::uuid id; }; -typedef boost::intrusive_ptr<Session> SessionPtr; +typedef std::shared_ptr<Session> SessionPtr; #endif diff --git a/project2/common/sessionContainer.cpp b/project2/common/sessionContainer.cpp index ae82dd9..debc216 100644 --- a/project2/common/sessionContainer.cpp +++ b/project2/common/sessionContainer.cpp @@ -1,6 +1,6 @@ #include <pch.hpp> #include "sessionContainer.h" -#include "instanceStore.impl.h" +#include <factory.impl.h> SessionContainer::SessionContainer() { @@ -22,11 +22,11 @@ SessionContainer::GetSession(const boost::uuids::uuid & id) const { SessionPtr s; if (id.is_nil() || !(s = getSession(id))) { - s = new Session(); + s = std::make_shared<Session>(); } s->ExpiryTime(time(NULL) + sessionTimeOut); return s; } -INSTANTIATESTORE(std::string, SessionContainerLoader); +INSTANTIATEVOIDFACTORY(SessionContainer); diff --git a/project2/common/sessionContainer.h b/project2/common/sessionContainer.h index b842457..e7df250 100644 --- a/project2/common/sessionContainer.h +++ b/project2/common/sessionContainer.h @@ -2,11 +2,12 @@ #define SESSIONCONTAINER_H #include <boost/uuid/uuid.hpp> -#include <intrusivePtrBase.h> #include "session.h" #include "options.h" +#include <factory.h> +#include <visibility.h> -class SessionContainer : public IntrusivePtrBase { +class DLL_PUBLIC SessionContainer { public: SessionContainer(); virtual ~SessionContainer() = 0; @@ -20,8 +21,8 @@ class SessionContainer : public IntrusivePtrBase { protected: virtual SessionPtr getSession(const boost::uuids::uuid & sid) const = 0; }; -typedef boost::intrusive_ptr<SessionContainer> SessionContainerPtr; -typedef GenLoader<SessionContainer, std::string> SessionContainerLoader; +typedef std::shared_ptr<SessionContainer> SessionContainerPtr; +typedef AdHoc::Factory<SessionContainer> SessionContainerFactory; #endif diff --git a/project2/common/sourceObject.cpp b/project2/common/sourceObject.cpp index 6ddec89..2c4845d 100644 --- a/project2/common/sourceObject.cpp +++ b/project2/common/sourceObject.cpp @@ -1,5 +1,4 @@ #include <pch.hpp> -#include "instanceStore.impl.h" #include "sourceObject.h" #include "exceptions.h" #include "safeMapFind.h" @@ -13,13 +12,12 @@ SourceObject::SourceObject(ScriptNodePtr p) : order(loadOrder++), script(p->script) { - script->namedComponents[name] = this; + script.lock()->namedComponents[name] = this; } SourceObject::SourceObject(const std::string & n) : name(n), - order(loadOrder++), - script(NULL) + order(loadOrder++) { } @@ -45,9 +43,6 @@ SourceObject::registerFor(int eventID, const Event & event) const SourceObject * SourceObject::findComponent(const std::string & name) const { - return safeMapLookup<ComponentNotFound>(script->namedComponents, name); + return AdHoc::safeMapLookup<ComponentNotFound>(script.lock()->namedComponents, name); } -INSTANTIATESTORE(std::string, ComponentLoader); -INSTANTIATESTORE(std::string, ElementLoader); - diff --git a/project2/common/sourceObject.h b/project2/common/sourceObject.h index 1af9ceb..e5244f0 100644 --- a/project2/common/sourceObject.h +++ b/project2/common/sourceObject.h @@ -1,21 +1,25 @@ #ifndef SOURCEOBJECT_H #define SOURCEOBJECT_H -#include <boost/intrusive_ptr.hpp> #include <boost/function.hpp> #include <string> #include <map> -#include "intrusivePtrBase.h" +#include <visibility.h> #include "scriptLoader.h" #include "scripts_fwd.h" -enum ObjectSource { +enum DLL_PUBLIC ObjectSource { Default, Scripted }; class CommonObjects; +class DLL_PUBLIC Something { + public: + virtual ~Something() = default; +}; + /// Base class for all Project2 components that can be placed in a Project2 script -class SourceObject : public virtual IntrusivePtrBase { +class DLL_PUBLIC SourceObject : public virtual Something { public: typedef int EventID; typedef boost::function<void()> Event; @@ -40,7 +44,7 @@ class SourceObject : public virtual IntrusivePtrBase { static unsigned int loadOrder; mutable Events events; - const ScriptReader * const script; + std::weak_ptr<const ScriptReader> const script; }; #endif diff --git a/project2/common/stream.cpp b/project2/common/stream.cpp index 0db9225..05bf0ea 100644 --- a/project2/common/stream.cpp +++ b/project2/common/stream.cpp @@ -1,5 +1,6 @@ #include "stream.h" #include <boost/bind.hpp> +#include <factory.impl.h> Glib::ustring Stream::getContentType(ExecContext *) const @@ -20,3 +21,5 @@ Stream::writeTo(std::ostream & os, const std::string &, ExecContext * ec) const runStream(boost::bind(&Stream::write, &os, _1, _2), ec); } +INSTANTIATEFACTORY(Stream, std::shared_ptr<const ScriptNode>); + diff --git a/project2/common/stream.h b/project2/common/stream.h index bf0dc41..7b4c25d 100644 --- a/project2/common/stream.h +++ b/project2/common/stream.h @@ -4,10 +4,11 @@ #include "sourceObject.h" #include <boost/function.hpp> #include "transform.h" +#include <visibility.h> class ExecContext; -class Stream : public SourceObject, public WritableContent { +class DLL_PUBLIC Stream : public SourceObject, public WritableContent { public: template<typename... X> Stream(const X &... x) : SourceObject(x...) { } @@ -20,7 +21,8 @@ class Stream : public SourceObject, public WritableContent { protected: static size_t write(std::ostream * os, const char * data, size_t len); }; -typedef boost::intrusive_ptr<Stream> StreamPtr; +typedef std::shared_ptr<Stream> StreamPtr; +typedef AdHoc::Factory<Stream, std::shared_ptr<const ScriptNode>> StreamFactory; #endif diff --git a/project2/common/task.cpp b/project2/common/task.cpp index 2cfe761..263304e 100644 --- a/project2/common/task.cpp +++ b/project2/common/task.cpp @@ -1,9 +1,14 @@ #include <pch.hpp> #include "task.h" +#include <factory.impl.h> Task::Task(ScriptNodePtr p) : - SourceObject(p), - NoOutputExecute(p) + SourceObject(p) +{ +} + +Task::Task(const std::string & n) : + SourceObject(n) { } @@ -11,3 +16,5 @@ Task::~Task() { } +INSTANTIATEFACTORY(Task, std::shared_ptr<const ScriptNode>); + diff --git a/project2/common/task.h b/project2/common/task.h index 15ccfbd..6db6fd6 100644 --- a/project2/common/task.h +++ b/project2/common/task.h @@ -2,15 +2,18 @@ #define TASK_H #include "sourceObject.h" -#include "noOutputExecute.h" +#include "execContext.h" +#include <visibility.h> /// Base class for Project2 components that perform some specific task -class Task : public NoOutputExecute { +class DLL_PUBLIC Task : public virtual SourceObject { public: Task(ScriptNodePtr p); + Task(const std::string & name); virtual ~Task(); virtual void execute(ExecContext *) const = 0; }; +typedef AdHoc::Factory<Task, std::shared_ptr<const ScriptNode>> TaskFactory; #endif diff --git a/project2/common/taskHost.cpp b/project2/common/taskHost.cpp index 943e09a..8dd3fdb 100644 --- a/project2/common/taskHost.cpp +++ b/project2/common/taskHost.cpp @@ -1,8 +1,8 @@ #include <pch.hpp> #include "taskHost.h" -#include "noOutputExecute.h" +#include "task.h" #include "dataSource.h" -#include "scopeObject.h" +#include <scopeExit.h> #include "scriptLoader.h" #include "commonObjects.h" @@ -12,7 +12,7 @@ TaskHost::TaskHost(ScriptNodePtr s) : CheckHost(s), IHaveSubTasks(s) { - s->script->loader.addLoadTarget(s, Storer::into<ElementLoader>(&tasks)); + s->script.lock()->loader.addLoadTarget(s, Storer::into<TaskFactory>(&tasks)); } TaskHost::~TaskHost() @@ -29,7 +29,7 @@ void TaskHost::execute(ExecContext * ec) const { loadScriptComponents(); - ScopeObject txHandler(ScopeObject::Event(), boost::bind(&TaskHost::commitAll, this), boost::bind(&TaskHost::rollbackAll, this)); + AdHoc::ScopeExit txHandler(AdHoc::ScopeExit::Event(), boost::bind(&TaskHost::commitAll, this), boost::bind(&TaskHost::rollbackAll, this)); run(tasks, ec); } diff --git a/project2/common/taskHost.h b/project2/common/taskHost.h index e4b8b3a..ed9bc1b 100644 --- a/project2/common/taskHost.h +++ b/project2/common/taskHost.h @@ -5,11 +5,9 @@ #include "checkHost.h" #include "iHaveSubTasks.h" #include "commonObjects.h" +#include <visibility.h> -class NoOutputExecute; -class DataSource; - -class TaskHost : public IHaveSubTasks, virtual public CheckHost, virtual public CommonObjects { +class DLL_PUBLIC TaskHost : public IHaveSubTasks, virtual public CheckHost, virtual public CommonObjects { protected: TaskHost(ScriptNodePtr script); virtual ~TaskHost(); diff --git a/project2/common/test.cpp b/project2/common/test.cpp index 427848a..aa500d6 100644 --- a/project2/common/test.cpp +++ b/project2/common/test.cpp @@ -1,7 +1,8 @@ #include "test.h" +#include <factory.impl.h> Test::Test(ScriptNodePtr s) : - SourceObject(s) + SourceObject(s.get()) { } @@ -10,3 +11,5 @@ Test::reset() const { } +INSTANTIATEFACTORY(Test, std::shared_ptr<const ScriptNode>); + diff --git a/project2/common/test.h b/project2/common/test.h index 7cf563c..73ce61a 100644 --- a/project2/common/test.h +++ b/project2/common/test.h @@ -3,15 +3,17 @@ #include "sourceObject.h" #include "scripts.h" +#include <visibility.h> class ExecContext; -class Test : public virtual SourceObject { +class DLL_PUBLIC Test : public virtual SourceObject { public: Test(ScriptNodePtr); virtual bool passes(ExecContext *) const = 0; virtual void reset() const; }; -typedef boost::intrusive_ptr<const Test> TestPtr; +typedef std::shared_ptr<const Test> TestPtr; +typedef AdHoc::Factory<Test, std::shared_ptr<const ScriptNode>> TestFactory; #endif diff --git a/project2/common/transform.cpp b/project2/common/transform.cpp index 37173c7..cf32ead 100644 --- a/project2/common/transform.cpp +++ b/project2/common/transform.cpp @@ -3,7 +3,7 @@ #include "logger.h" #include "ostreamWrapper.h" #include "scriptStorage.h" -#include "instanceStore.impl.h" +#include <factory.impl.h> class TransformTargetStorer : public Storer { public: @@ -11,13 +11,13 @@ class TransformTargetStorer : public Storer { transformSource(ts) { } - boost::intrusive_ptr<IntrusivePtrBase> create(ScriptNodePtr p) const + std::shared_ptr<Something> create(std::shared_ptr<const ScriptNode> p) const { - return InstanceMap<TransformTargetLoader, std::string>::Get<NotSupported>(p->get_name())->create(p, Scripted); + return TransformTargetFactory::createNew(p->get_name(), p, Scripted); } - bool save(boost::intrusive_ptr<IntrusivePtrBase> o, ScriptNodePtr s) + bool save(std::shared_ptr<Something> o, std::shared_ptr<const ScriptNode> s) { - TransformChainLinkPtr O = boost::dynamic_pointer_cast<TransformChainLink>(o); + TransformChainLinkPtr O = std::dynamic_pointer_cast<TransformChainLink>(o); if (O) { transformSource->addTarget(O, NULL, s); } @@ -34,7 +34,7 @@ TransformSource::TransformSource() TransformSource::TransformSource(ScriptNodePtr s, ObjectSource os) { if (os == Scripted) { - s->script->loader.addLoadTarget(s, new TransformTargetStorer(this)); + s->script.lock()->loader.addLoadTarget(s, std::make_shared<TransformTargetStorer>(this)); } } @@ -42,12 +42,12 @@ TransformChainLink::~TransformChainLink() { } -typedef std::map<std::string, boost::shared_ptr<TransformLoader> > TransformLoaderMap; +typedef std::map<std::string, std::shared_ptr<TransformFactory> > TransformFactoryMap; void TransformSource::addTarget(TransformChainLinkPtr tcl, ExecContext * ec, ScriptNodePtr e) { - for (const auto & tl : InstanceSet<TransformLoader>::GetAll()) { - TransformPtr t = tl->create(); + for (const auto & tl : AdHoc::PluginManager::getDefault()->getAll<TransformFactory>()) { + TransformPtr t = tl->implementation()->create(); if (t->canTransform(this, tcl.get())) { if (e) { t->configure(e, ec); @@ -106,6 +106,6 @@ class TransformStaticContentToStdStream : public TransformImpl<StaticContent, os }; DECLARE_TRANSFORM(TransformStaticContentToStdStream); -INSTANTIATESTORE(std::string, TransformLoader); -INSTANTIATESTORE(std::string, TransformTargetLoader); +INSTANTIATEVOIDFACTORY(Transform); +INSTANTIATEFACTORY(TransformChainLink, std::shared_ptr<const ScriptNode>, ObjectSource); diff --git a/project2/common/transform.h b/project2/common/transform.h index 7a46c7f..86bc275 100644 --- a/project2/common/transform.h +++ b/project2/common/transform.h @@ -1,25 +1,25 @@ #ifndef TRANSFORM_H #define TRANSFORM_H -#include <boost/intrusive_ptr.hpp> -#include "intrusivePtrBase.h" #include "scriptLoader.h" #include <map> +#include <factory.h> #include "range.h" +#include <visibility.h> class ExecContext; -class TransformChainLink : public virtual IntrusivePtrBase { +class DLL_PUBLIC TransformChainLink : public virtual Something { public: virtual ~TransformChainLink() = 0; }; -typedef boost::intrusive_ptr<TransformChainLink> TransformChainLinkPtr; +typedef std::shared_ptr<TransformChainLink> TransformChainLinkPtr; class Transform; -typedef boost::intrusive_ptr<Transform> TransformPtr; +typedef std::shared_ptr<Transform> TransformPtr; typedef std::map<TransformChainLinkPtr, TransformPtr> Targets; -class TransformSource : public TransformChainLink { +class DLL_PUBLIC TransformSource : public TransformChainLink { public: TransformSource(); TransformSource(ScriptNodePtr, ObjectSource); @@ -32,7 +32,7 @@ class TransformSource : public TransformChainLink { virtual const TransformChainLink * object() const { return this; } Targets targets; }; -typedef boost::intrusive_ptr<TransformSource> TransformSourcePtr; +typedef std::shared_ptr<TransformSource> TransformSourcePtr; template <class X> class SourceOf : public virtual TransformSource { @@ -42,18 +42,18 @@ class SourceOf : public virtual TransformSource { virtual operator const X * () const = 0; }; -class Transform : public virtual IntrusivePtrBase { +class DLL_PUBLIC Transform { public: virtual void transform(const TransformSource * src, TransformChainLink * dest, ExecContext *) const = 0; virtual bool canTransform(const TransformSource * src, TransformChainLink * dest) const = 0; virtual void configure(ScriptNodePtr, ExecContext *) { }; }; -typedef GenLoader<Transform, std::string> TransformLoader; -#define DECLARE_TRANSFORM(T) DECLARE_COMPONENT_LOADER(#T, T, TransformLoader) +typedef AdHoc::Factory<Transform> TransformFactory; +#define DECLARE_TRANSFORM(T) NAMEDFACTORY(#T, T, TransformFactory) -typedef GenLoader<TransformChainLink, std::string, ScriptNodePtr, ObjectSource> TransformTargetLoader; -#define DECLARE_TRANSFORMTARGET(N, T) DECLARE_COMPONENT_LOADER(N, T, TransformTargetLoader) +typedef AdHoc::Factory<TransformChainLink, std::shared_ptr<const ScriptNode>, ObjectSource> TransformTargetFactory; +#define DECLARE_TRANSFORMTARGET(N, T) NAMEDFACTORY(N, T, TransformTargetFactory) template <class Source, class Destination> class TransformImpl : public Transform { @@ -69,7 +69,7 @@ class TransformImpl : public Transform { } }; -class WritableContent { +class DLL_PUBLIC WritableContent { public: enum Class { ClassPlain = 1, @@ -85,7 +85,7 @@ class WritableContent { virtual void writeTo(std::ostream &, const std::string & encoding, ExecContext *) const = 0; }; -class StaticContent { +class DLL_PUBLIC StaticContent { public: virtual Glib::ustring getContentType() const = 0; virtual Glib::ustring getEncoding() const = 0; diff --git a/project2/common/unittests/Jamfile.jam b/project2/common/unittests/Jamfile.jam index 540c1e0..4feafab 100644 --- a/project2/common/unittests/Jamfile.jam +++ b/project2/common/unittests/Jamfile.jam @@ -1,9 +1,11 @@ import testing ; -unit-test testConfig : +run testConfig.cpp - : + : : : <library>../../ut//p2ut <library>..//p2common + : + testConfig : ; diff --git a/project2/common/unittests/testConfig.cpp b/project2/common/unittests/testConfig.cpp index 8c25394..664fe16 100644 --- a/project2/common/unittests/testConfig.cpp +++ b/project2/common/unittests/testConfig.cpp @@ -9,7 +9,7 @@ BOOST_AUTO_TEST_CASE( config_application_value ) TestOptionsSource::LoadTestOptions({ { "application.data", "testvalue" } }); - Variable::VariableImplPtr c = VariableLoader::createNew("config", new TestScriptNode({ + Variable::VariableImplPtr c = VariableFactory::createNew("config", std::make_shared<TestScriptNode, TestScriptNode::Vars>({ { "name", VariableType("data") } })); BOOST_REQUIRE(c); diff --git a/project2/common/variableConvert.cpp b/project2/common/variableConvert.cpp index 2c6e49a..b3d3432 100644 --- a/project2/common/variableConvert.cpp +++ b/project2/common/variableConvert.cpp @@ -1,4 +1,5 @@ #include <pch.hpp> +#define BOOST_NO_CXX14_DECLTYPE_AUTO #include "variables.h" #include "exceptions.h" #include <boost/lexical_cast.hpp> @@ -69,30 +70,6 @@ class ConvertVisitorStdString : public boost::static_visitor<const std::string & private: const VariableType * var; }; -// Convert to char * (with std::string storage) -class ConvertVisitorCharStar : public boost::static_visitor<const char *> { - public: - ConvertVisitorCharStar(const VariableType * v) : var(v) { - } - const char * operator()(const Glib::ustring & r) const { - return r.c_str(); - } - const char * operator()(const boost::posix_time::time_duration & r) const { - CONVERTF(const Glib::ustring, boost::posix_time::to_simple_string, c_str); - } - const char * operator()(const boost::posix_time::ptime & r) const { - CONVERTF(const Glib::ustring, boost::posix_time::to_iso_extended_string, c_str); - } - const char * operator()(const Null &) const { - return NULL; - } - template <typename T> - const char * operator()(const T & r) const { - CONVERTF(const Glib::ustring, boost::lexical_cast<Glib::ustring>, c_str); - } - private: - const VariableType * var; -}; // Convert to numeric type template <typename DestType> class ConvertVisitor : public boost::static_visitor<DestType> { @@ -193,6 +170,7 @@ class ConvertVisitorBool : public boost::static_visitor<bool> { } const VariableType * var; }; + VariableType::operator const Glib::ustring &() const { return boost::apply_visitor(ConvertVisitorGlibUstring(this), *this); @@ -201,13 +179,9 @@ VariableType::operator const std::string &() const { return boost::apply_visitor(ConvertVisitorStdString(this), *this); } -VariableType::operator const char *() const +VariableType::operator std::string_view() const { - return boost::apply_visitor(ConvertVisitorCharStar(this), *this); -} -VariableType::operator const unsigned char *() const -{ - return reinterpret_cast<const unsigned char *>(boost::apply_visitor(ConvertVisitorCharStar(this), *this)); + return boost::apply_visitor(ConvertVisitorStdString(this), *this); } VariableType::operator int() const { @@ -237,3 +211,4 @@ VariableType::operator bool() const { return boost::apply_visitor(ConvertVisitorBool(this), *this); } + diff --git a/project2/common/variableType.cpp b/project2/common/variableType.cpp index 2902638..c9213c0 100644 --- a/project2/common/variableType.cpp +++ b/project2/common/variableType.cpp @@ -1,6 +1,7 @@ #include <pch.hpp> #include "variableType.h" #include "logger.h" +#include "exceptions.h" #include <boost/date_time/posix_time/posix_time.hpp> #include <boost/algorithm/string/predicate.hpp> @@ -145,7 +146,7 @@ VTCONSN(long long int, int64_t); VTCONSN(long long unsigned int, int64_t); VTCONSD(std::string, Glib::ustring); VTCONSD(char * const, Glib::ustring); -VTCONSC(unsigned char * const, Glib::ustring, const char * const); +VTCONSC(unsigned char * const, Glib::ustring, const char *); VariableType::VariableType(const struct tm & vt) : _VT(boost::posix_time::ptime_from_tm(vt)) diff --git a/project2/common/variableType.h b/project2/common/variableType.h index f2a6890..70d6b4a 100644 --- a/project2/common/variableType.h +++ b/project2/common/variableType.h @@ -7,6 +7,7 @@ #include <glibmm/ustring.h> #include <boost/variant.hpp> #include <boost/optional.hpp> +#include <visibility.h> enum VT_typeID { DefaultType, @@ -29,10 +30,10 @@ class Null { bool operator==(const Null &) const { return true; } }; -std::basic_ostream<char> & operator<<(std::basic_ostream<char> &, const Null &); -std::basic_ostream<unsigned char> & operator<<(std::basic_ostream<unsigned char> &, const Null &); +DLL_PUBLIC std::basic_ostream<char> & operator<<(std::basic_ostream<char> &, const Null &); +DLL_PUBLIC std::basic_ostream<unsigned char> & operator<<(std::basic_ostream<unsigned char> &, const Null &); -class Boolean { +class DLL_PUBLIC Boolean { public: Boolean(bool v); bool operator<(const Boolean &) const; @@ -40,8 +41,8 @@ class Boolean { bool value; }; -std::basic_ostream<char> & operator<<(std::basic_ostream<char> &, const Boolean &); -std::basic_ostream<unsigned char> & operator<<(std::basic_ostream<unsigned char> &, const Boolean &); +DLL_PUBLIC std::basic_ostream<char> & operator<<(std::basic_ostream<char> &, const Boolean &); +DLL_PUBLIC std::basic_ostream<unsigned char> & operator<<(std::basic_ostream<unsigned char> &, const Boolean &); typedef boost::variant< // Other @@ -57,7 +58,7 @@ typedef boost::variant< boost::posix_time::ptime > _VT; -class VariableType : public _VT { +class DLL_PUBLIC VariableType : public _VT { public: VariableType(const unsigned char * const & t); VariableType(const char * const & t); @@ -79,6 +80,8 @@ class VariableType : public _VT { VariableType(); VariableType(const VariableType &); + VariableType & operator=(const VariableType &) = default; + static VariableType make(const Glib::ustring & src, VT_typeID format); static VariableType make(const Glib::ustring & src); static VT_typeID getTypeFromName(const std::string & src); @@ -92,8 +95,7 @@ class VariableType : public _VT { operator const Glib::ustring &() const; operator const std::string &() const; - operator const char *() const; - operator const unsigned char *() const; + operator std::string_view() const; operator long long int() const; operator long int() const; operator int() const; diff --git a/project2/common/variables.cpp b/project2/common/variables.cpp index 87673a7..6cc5a71 100644 --- a/project2/common/variables.cpp +++ b/project2/common/variables.cpp @@ -12,8 +12,8 @@ #include <boost/algorithm/string/predicate.hpp> #include <boost/function.hpp> #include <boost/bind.hpp> -#include "instanceStore.impl.h" #include "execContext.h" +#include <factory.impl.h> VariableImplDyn::VariableImplDyn(ScriptNodePtr e) { @@ -54,13 +54,13 @@ class VariableParent : public VariableImplDyn { return row->getCurrentValue(ec, name); } } - catch (RowSet::ParentOutOfRange) { + catch (const RowSet::ParentOutOfRange &) { if (!defaultValue) { throw; } return (*defaultValue)(ec); } - catch (RowSet::FieldDoesNotExist) { + catch (const RowSet::FieldDoesNotExist &) { if (!defaultValue) { throw; } @@ -72,7 +72,7 @@ class VariableParent : public VariableImplDyn { const bool attr; const Glib::ustring name; }; -DECLARE_COMPONENT_LOADER("parent", VariableParent, VariableLoader); +NAMEDFACTORY("parent", VariableParent, VariableFactory); Variable::Variable(VariableType def) : @@ -93,7 +93,7 @@ Variable::Variable(ScriptNodePtr s, const Glib::ustring & n, const VariableType { } -Variable::Variable(VariableImpl * v) : +Variable::Variable(std::shared_ptr<VariableImpl> v) : var(v) { } @@ -101,7 +101,7 @@ Variable::Variable(VariableImpl * v) : Variable & Variable::operator=(const VariableType & vt) { - var = new VariableFixed(vt); + var = std::make_shared<VariableFixed>(vt); return *this; } @@ -116,5 +116,5 @@ Variable::fromScriptNode(ScriptNodePtr p) return p->variable(); } -INSTANTIATESTORE(std::string, VariableLoader); +INSTANTIATEFACTORY(VariableImpl, std::shared_ptr<const ScriptNode>); diff --git a/project2/common/variables.h b/project2/common/variables.h index cee9037..9073bd8 100644 --- a/project2/common/variables.h +++ b/project2/common/variables.h @@ -1,31 +1,26 @@ #ifndef VARIABLES_H #define VARIABLES_H -#include <boost/intrusive_ptr.hpp> #include <boost/optional.hpp> #include <stdint.h> -#include "intrusivePtrBase.h" -#include "genLoader.h" +#include <factory.h> #include "scripts.h" #include "variableType.h" #include <boost/shared_ptr.hpp> +#include <visibility.h> class ExecContext; -SimpleMessageException(UnknownVariableSource); - /// Base class for Project2 variable accessors -class VariableImpl : public IntrusivePtrBase { +class DLL_PUBLIC VariableImpl { public: virtual VariableType value(ExecContext *) const = 0; - - protected: virtual ~VariableImpl() = default; }; -class Variable { +class DLL_PUBLIC Variable { public: - typedef boost::intrusive_ptr<VariableImpl> VariableImplPtr; + typedef std::shared_ptr<VariableImpl> VariableImplPtr; Variable(ScriptNodePtr, const boost::optional<Glib::ustring> & = boost::optional<Glib::ustring>()); Variable(ScriptNodePtr, const Glib::ustring & n); @@ -39,13 +34,13 @@ class Variable { Variable & operator=(const VariableType &); private: - Variable(VariableImpl *); + Variable(std::shared_ptr<VariableImpl>); friend class VariableParse; VariableImplPtr var; }; /// Base class for variables whose content is dynamic -class VariableImplDyn : public VariableImpl { +class DLL_PUBLIC VariableImplDyn : public VariableImpl { public: VariableImplDyn(ScriptNodePtr e); virtual VariableType value(ExecContext *) const = 0; @@ -55,7 +50,7 @@ class VariableImplDyn : public VariableImpl { }; /// Base class to create variables -typedef GenLoader<VariableImpl, std::string, ScriptNodePtr> VariableLoader; +typedef AdHoc::Factory<VariableImpl, std::shared_ptr<const ScriptNode>> VariableFactory; #endif diff --git a/project2/common/variables/config.cpp b/project2/common/variables/config.cpp index e134d07..ebb184d 100644 --- a/project2/common/variables/config.cpp +++ b/project2/common/variables/config.cpp @@ -32,7 +32,7 @@ class VariableConfig : public VariableImplDyn { const Glib::ustring name; }; -class VariableConfigLoader : public VariableLoader::For<VariableConfig> { +class VariableConfigFactory : public VariableFactory::For<VariableConfig> { public: class AppSettings : public Options::Option { public: @@ -68,25 +68,25 @@ class VariableConfigLoader : public VariableLoader::For<VariableConfig> { return "Load settings into the client application"; } }; - VariableConfigLoader() : - opts(new Options("Variables - ModConfig options")) + VariableConfigFactory() : + opts(std::make_shared<Options>("Variables - ModConfig options")) { - (*opts)(new AppSettings()); - OptionsSets::Add(typeid(AppSettings).name(), opts); + (*opts)(std::make_shared<AppSettings>()); + AdHoc::PluginManager::getDefault()->add<Options>(opts, typeid(AppSettings).name(), __FILE__, __LINE__); } - ~VariableConfigLoader() + ~VariableConfigFactory() { - OptionsSets::Remove(typeid(AppSettings).name()); + AdHoc::PluginManager::getDefault()->remove<Options>(typeid(AppSettings).name()); } - const Options * options() const { + std::shared_ptr<const Options> options() const { return opts; } private: - Options * opts; + std::shared_ptr<Options> opts; }; -DECLARE_CUSTOM_COMPONENT_LOADER("config", VariableConfigLoader, VariableConfigLoader, VariableLoader); +NAMEDPLUGIN("config", VariableConfigFactory, VariableFactory); diff --git a/project2/common/variables/literal.cpp b/project2/common/variables/literal.cpp index 529be6e..06e01cf 100644 --- a/project2/common/variables/literal.cpp +++ b/project2/common/variables/literal.cpp @@ -13,7 +13,7 @@ static void append(VariableLiteral::Vals * vals, const Y & y) { - vals->push_back(new X(y)); + vals->push_back(std::make_shared<X>(y)); } VariableLiteral::VariableLiteral(ScriptNodePtr s) { @@ -72,8 +72,7 @@ VariableLiteral::VarPart::value(ExecContext * ec) const return (*this)(ec); } -DECLARE_COMPONENT_LOADER("literal", VariableLiteral, VariableLoader); -DECLARE_CUSTOM_COMPONENT_LOADER("", VariableLiteralDef, VariableLoader::For<VariableLiteral>, VariableLoader); - +NAMEDFACTORY("literal", VariableLiteral, VariableFactory); +NAMEDFACTORY("", VariableLiteral, VariableFactory); diff --git a/project2/common/variables/literal.h b/project2/common/variables/literal.h index 8c120b6..a70ee7b 100644 --- a/project2/common/variables/literal.h +++ b/project2/common/variables/literal.h @@ -3,17 +3,18 @@ #include "../variables.h" #include <list> +#include <visibility.h> -class VariableLiteral : public VariableImpl { +class DLL_PUBLIC VariableLiteral : public VariableImpl { public: VariableLiteral(const Glib::ustring & src, const VT_typeID format = DefaultType); VariableLiteral(ScriptNodePtr); virtual VariableType value(ExecContext * ec) const; class Part; - typedef boost::intrusive_ptr<Part> PartCPtr; + typedef std::shared_ptr<Part> PartCPtr; typedef std::list<PartCPtr> Vals; - class Part : public IntrusivePtrBase { + class Part { public: virtual void appendTo(ExecContext *, Glib::ustring & str) const = 0; virtual VariableType value(ExecContext *) const = 0; diff --git a/project2/common/variables/localparam.cpp b/project2/common/variables/localparam.cpp index cf2f165..b7506d4 100644 --- a/project2/common/variables/localparam.cpp +++ b/project2/common/variables/localparam.cpp @@ -18,7 +18,7 @@ class VariableLocalParam : public VariableImplDyn { try { return ec->getScopedParameter(name); } - catch (ParamNotFound) { + catch (class ParamNotFound &) { if (!defaultValue) { throw; } @@ -28,5 +28,5 @@ class VariableLocalParam : public VariableImplDyn { private: const Glib::ustring name; }; -DECLARE_COMPONENT_LOADER("local", VariableLocalParam, VariableLoader); +NAMEDFACTORY("local", VariableLocalParam, VariableFactory); diff --git a/project2/common/variables/lookup.cpp b/project2/common/variables/lookup.cpp index c90ce46..7aa1328 100644 --- a/project2/common/variables/lookup.cpp +++ b/project2/common/variables/lookup.cpp @@ -34,7 +34,7 @@ class VariableLookup : public VariableImplDyn, public RowProcessor { RowProcessor(e), name(e->value("name", NULL).as<Glib::ustring>()) { - e->script->loader.addLoadTarget(e, Storer::into<ElementLoader>(&rowSets)); + e->script.lock()->loader.addLoadTarget(e, Storer::into<RowSetFactory>(&rowSets)); } VariableType value(ExecContext * ec) const { @@ -46,7 +46,7 @@ class VariableLookup : public VariableImplDyn, public RowProcessor { for (const Parameters::value_type & p : parameters) { k.push_back(p.second(ec)); } - return safeMapLookup<NotFound>(map, k); + return AdHoc::safeMapLookup<NotFound>(map, k); } private: void fillCache(ExecContext * ec) const @@ -70,4 +70,4 @@ class VariableLookup : public VariableImplDyn, public RowProcessor { RowSets rowSets; const Glib::ustring name; }; -DECLARE_COMPONENT_LOADER("lookup", VariableLookup, VariableLoader); +NAMEDFACTORY("lookup", VariableLookup, VariableFactory); diff --git a/project2/common/variables/param.cpp b/project2/common/variables/param.cpp index a1ef9b7..8be4dea 100644 --- a/project2/common/variables/param.cpp +++ b/project2/common/variables/param.cpp @@ -17,7 +17,7 @@ class VariableParam : public VariableImplDyn { try { return ec->getParameter(name); } - catch (ParamNotFound) { + catch (const ParamNotFound &) { if (!defaultValue) { throw; } @@ -27,5 +27,5 @@ class VariableParam : public VariableImplDyn { private: const VariableType name; }; -DECLARE_COMPONENT_LOADER("param", VariableParam, VariableLoader); +NAMEDFACTORY("param", VariableParam, VariableFactory); diff --git a/project2/common/variables/session.cpp b/project2/common/variables/session.cpp index ed2077d..dbc1ec7 100644 --- a/project2/common/variables/session.cpp +++ b/project2/common/variables/session.cpp @@ -17,7 +17,7 @@ class VariableSession : public VariableImplDyn { try { return ec->getSession()->GetValue(name); } - catch (Session::VariableNotFound) { + catch (const Session::VariableNotFound &) { if (!defaultValue) { throw; } @@ -27,5 +27,5 @@ class VariableSession : public VariableImplDyn { private: const Glib::ustring name; }; -DECLARE_COMPONENT_LOADER("session", VariableSession, VariableLoader); +NAMEDFACTORY("session", VariableSession, VariableFactory); diff --git a/project2/common/view.cpp b/project2/common/view.cpp index 30a6491..96d2434 100644 --- a/project2/common/view.cpp +++ b/project2/common/view.cpp @@ -1,5 +1,6 @@ #include <pch.hpp> #include "view.h" +#include <factory.impl.h> View::View(ScriptNodePtr p) : SourceObject(p) @@ -10,3 +11,5 @@ View::~View() { } +INSTANTIATEFACTORY(View, std::shared_ptr<const ScriptNode>); + diff --git a/project2/common/view.h b/project2/common/view.h index 52a4130..4ad3c2e 100644 --- a/project2/common/view.h +++ b/project2/common/view.h @@ -3,19 +3,21 @@ #include "sourceObject.h" #include "scriptStorage.h" +#include <visibility.h> class MultiRowSetPresenter; class ExecContext; SimpleMessageException(EmptyRequiredRows); /// Base class for Project2 components that output data -class View : public virtual SourceObject { +class DLL_PUBLIC View : public virtual SourceObject { public: View(ScriptNodePtr); virtual ~View(); virtual void execute(const MultiRowSetPresenter *, ExecContext *) const = 0; }; +typedef AdHoc::Factory<View, std::shared_ptr<const ScriptNode>> ViewFactory; #endif diff --git a/project2/common/viewHost.cpp b/project2/common/viewHost.cpp index ce99506..7a8a7fe 100644 --- a/project2/common/viewHost.cpp +++ b/project2/common/viewHost.cpp @@ -8,7 +8,7 @@ ViewHost::ViewHost(ScriptNodePtr s) : CommonObjects(s), CheckHost(s) { - s->script->loader.addLoadTarget(s, Storer::into<ElementLoader>(&views)); + s->script.lock()->loader.addLoadTarget(s, Storer::into<ViewFactory>(&views)); } ViewHost::~ViewHost() @@ -36,7 +36,7 @@ void ViewHost::doTransforms(ExecContext * ec) const { MultiRowSetPresenterPtr presenter = getPresenter(ec); - TransformSourcePtr ts = boost::dynamic_pointer_cast<TransformSource>(presenter); + TransformSourcePtr ts = std::dynamic_pointer_cast<TransformSource>(presenter); if (ts) { ts->doTransforms(ec); } diff --git a/project2/common/viewHost.h b/project2/common/viewHost.h index 5ede3e4..d4d4c69 100644 --- a/project2/common/viewHost.h +++ b/project2/common/viewHost.h @@ -5,10 +5,10 @@ #include "presenter.h" #include "checkHost.h" #include <set> -#include <boost/filesystem/path.hpp> +#include <visibility.h> #include "commonObjects.h" -class ViewHost : virtual public CheckHost, virtual public CommonObjects { +class DLL_PUBLIC ViewHost : virtual public CheckHost, virtual public CommonObjects { public: ViewHost(ScriptNodePtr script); ~ViewHost(); @@ -23,7 +23,7 @@ class ViewHost : virtual public CheckHost, virtual public CommonObjects { typedef ANONORDEREDSTORAGEOF(View) Views; Views views; }; -typedef boost::intrusive_ptr<ViewHost> ViewHostPtr; +typedef std::shared_ptr<ViewHost> ViewHostPtr; #endif diff --git a/project2/compression/Jamfile.jam b/project2/compression/Jamfile.jam index b1715cb..bafb3ab 100644 --- a/project2/compression/Jamfile.jam +++ b/project2/compression/Jamfile.jam @@ -8,7 +8,6 @@ lib libz : : <name>z ; lib p2compression : [ glob *.cpp ] : - <include>../../libmisc <library>glibmm <library>libz <library>../common//p2common diff --git a/project2/compression/decompressStream.cpp b/project2/compression/decompressStream.cpp index c1d52ab..3af4a45 100644 --- a/project2/compression/decompressStream.cpp +++ b/project2/compression/decompressStream.cpp @@ -1,10 +1,8 @@ #include "stream.h" -#include "componentLoader.h" #include "decompressor.h" #include "scripts.h" #include "variables.h" #include "scriptStorage.h" -#include "instanceStore.impl.h" class DecompressStream : public Stream { public: @@ -12,12 +10,12 @@ class DecompressStream : public Stream { Stream(p), method(p, "method") { - p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&stream)); + p->script.lock()->loader.addLoadTarget(p, Storer::into<StreamFactory>(&stream)); } void runStream(const Sink & sink, ExecContext * ec) const { - DecompressorPtr decomp = DecompressorLoader::getFor(method(ec))->create(); + DecompressorPtr decomp = DecompressorFactory::createNew(method(ec)); stream->runStream([&](const char * data, size_t len) -> size_t { decomp->decompress(data, len, sink); return len; @@ -28,6 +26,5 @@ class DecompressStream : public Stream { const Variable method; }; -DECLARE_LOADER("decompstream", DecompressStream); -INSTANTIATESTORE(std::string, DecompressorLoader); +NAMEDFACTORY("decompstream", DecompressStream, StreamFactory); diff --git a/project2/compression/decompressor.cpp b/project2/compression/decompressor.cpp new file mode 100644 index 0000000..b727aa8 --- /dev/null +++ b/project2/compression/decompressor.cpp @@ -0,0 +1,7 @@ +#include "decompressor.h" +#include <factory.impl.h> + +Decompressor::~Decompressor() = default; + +INSTANTIATEVOIDFACTORY(Decompressor); + diff --git a/project2/compression/decompressor.h b/project2/compression/decompressor.h index c57ff61..4d9f386 100644 --- a/project2/compression/decompressor.h +++ b/project2/compression/decompressor.h @@ -2,16 +2,15 @@ #define DECOMPRESSOR #include "stream.h" -#include "intrusivePtrBase.h" +#include <factory.h> -class Decompressor : public IntrusivePtrBase { +class DLL_PUBLIC Decompressor { public: - virtual ~Decompressor() - { - } + virtual ~Decompressor(); + virtual void decompress(const char * dataIn, size_t lengthIn, const Stream::Sink &) = 0; }; -typedef boost::intrusive_ptr<Decompressor> DecompressorPtr; -typedef GenLoader<Decompressor, std::string> DecompressorLoader; +typedef std::shared_ptr<Decompressor> DecompressorPtr; +typedef AdHoc::Factory<Decompressor> DecompressorFactory; #endif diff --git a/project2/compression/gzip.cpp b/project2/compression/gzip.cpp index 2bf0a8d..de80401 100644 --- a/project2/compression/gzip.cpp +++ b/project2/compression/gzip.cpp @@ -19,9 +19,7 @@ class GZip : public Decompressor { ~GZip() { inflateEnd(&strm); - if (status != Z_STREAM_END) { - throw std::runtime_error("decompression of stream failed"); - } + BOOST_ASSERT_MSG(status == Z_STREAM_END, "decompression of stream failed"); } void decompress(const char * data, size_t len, const Stream::Sink & sink) { @@ -36,6 +34,7 @@ class GZip : public Decompressor { switch (status) { case Z_NEED_DICT: status = Z_DATA_ERROR; + [[ fallthrough ]]; case Z_DATA_ERROR: case Z_MEM_ERROR: throw std::runtime_error("inflate failed"); @@ -49,5 +48,5 @@ class GZip : public Decompressor { z_stream strm; int status; }; -DECLARE_GENERIC_LOADER("gz", DecompressorLoader, GZip); +NAMEDFACTORY("gz", GZip, DecompressorFactory); diff --git a/project2/compression/nocomp.cpp b/project2/compression/nocomp.cpp index 6861171..78f4d4c 100644 --- a/project2/compression/nocomp.cpp +++ b/project2/compression/nocomp.cpp @@ -9,6 +9,5 @@ class NoComp : public Decompressor { sink(data, len); } }; -DECLARE_GENERIC_LOADER("nocomp", DecompressorLoader, NoComp); - +NAMEDFACTORY("nocomp", NoComp, DecompressorFactory); diff --git a/project2/console/Jamfile.jam b/project2/console/Jamfile.jam index 24d8504..ba37b7d 100644 --- a/project2/console/Jamfile.jam +++ b/project2/console/Jamfile.jam @@ -3,7 +3,6 @@ alias glibmm : : : : <linkflags>"`pkg-config --libs glibmm-2.4`" ; cpp-pch pch : pch.hpp : - <include>../../libmisc <library>glibmm <library>..//p2parts ; @@ -16,6 +15,5 @@ exe p2console : <library>../common//p2common <library>../basics//p2basics <library>../cli//p2cli - <include>../../libmisc ; diff --git a/project2/console/consoleAppEngine.cpp b/project2/console/consoleAppEngine.cpp index 487c1f1..a02b34b 100644 --- a/project2/console/consoleAppEngine.cpp +++ b/project2/console/consoleAppEngine.cpp @@ -75,7 +75,7 @@ void ConsoleApplicationEngine::process(ScriptReaderPtr s) { try { - boost::intrusive_ptr<ScriptRunner> sr = new ScriptRunner(s, presenter); + auto sr = std::make_shared<ScriptRunner>(s, presenter); sr->process(this); } catch (const std::exception & e) { @@ -99,21 +99,21 @@ ConsoleApplicationEngine::getSession() const VariableType ConsoleApplicationEngine::getParameter(const VariableType & key) const { - return safeMapLookup<ParamNotFound>(parameters, key); + return AdHoc::safeMapLookup<ParamNotFound>(parameters, key); } void ConsoleApplicationEngine::process() { for (const auto & todo : todolist) { - Plugable::onAllComponents(boost::bind(&ComponentLoader::onBefore, _1)); + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onBefore, _1)); Logger()->messagebf(LOG_DEBUG, "%s: Beginning script '%s/%s'", __FUNCTION__, todo.get<0>(), todo.get<1>()); Logger()->messagef(LOG_DEBUG, "%s: Processing file", __FUNCTION__); process(ScriptReader::resolveScript(todo.get<0>(), todo.get<1>(), false)); Logger()->messagef(LOG_DEBUG, "%s: Complete", __FUNCTION__); - Plugable::onAllComponents(boost::bind(&ComponentLoader::onIteration, _1)); + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onIteration, _1)); } } diff --git a/project2/console/p2consoleMain.cpp b/project2/console/p2consoleMain.cpp index 31ffe70..3fddc11 100644 --- a/project2/console/p2consoleMain.cpp +++ b/project2/console/p2consoleMain.cpp @@ -6,14 +6,16 @@ int main(int argc, char ** argv) { - OptionsSources::Add("", new CommandLineArguments(argc, argv, &ConsoleApplicationEngine::appendScript)); - Plugable::onAllComponents(boost::bind(&ComponentLoader::onBegin, _1)); - OptionsSource::loadSources([] { return ConsoleApplicationEngine::reqPlatform;} ); + AdHoc::PluginManager::getDefault()->create<OptionsSource, + CommandLineArguments>("", __FILE__, __LINE__, argc, argv, &ConsoleApplicationEngine::appendScript); + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onBegin, _1)); ConsoleApplicationEngine app; + OptionsSource::loadSources([] { return ConsoleApplicationEngine::reqPlatform;} ); + app.process(); - Plugable::onAllComponents(boost::bind(&ComponentLoader::onPeriodic, _1)); - Plugable::onAllComponents(boost::bind(&ComponentLoader::onIdle, _1)); + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onPeriodic, _1)); + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onIdle, _1)); } diff --git a/project2/console/pch.hpp b/project2/console/pch.hpp index e79f446..829f4a0 100644 --- a/project2/console/pch.hpp +++ b/project2/console/pch.hpp @@ -2,14 +2,8 @@ #ifndef CONSOLE_PCH #define CONSOLE_PCH -#include "consoleAppEngine.h" -#include "consolePresenter.h" -#include "exceptions.h" -#include "iterate.h" -#include "logger.h" -#include "scriptLoader.h" +#include <boost/variant/variant_fwd.hpp> #include <boost/bind.hpp> -#include "options.h" #include <iostream> #include <string> diff --git a/project2/daemon/Jamfile.jam b/project2/daemon/Jamfile.jam index 1a159c3..3dd1259 100644 --- a/project2/daemon/Jamfile.jam +++ b/project2/daemon/Jamfile.jam @@ -2,7 +2,8 @@ alias glibmm : : : : <cflags>"`pkg-config --cflags glibmm-2.4`" <linkflags>"`pkg-config --libs glibmm-2.4`" ; -lib boost_filesystem : : <name>boost_filesystem ; +lib stdc++fs ; +lib pthread ; exe p2daemon : [ glob *.cpp ] : @@ -11,7 +12,7 @@ exe p2daemon : <library>..//p2daemonparts <library>../common//p2common <library>../cli//p2cli - <include>../../libmisc - <library>boost_filesystem + <library>stdc++fs + <library>pthread ; diff --git a/project2/daemon/lib/Jamfile.jam b/project2/daemon/lib/Jamfile.jam index c46ff32..6aa3b0f 100644 --- a/project2/daemon/lib/Jamfile.jam +++ b/project2/daemon/lib/Jamfile.jam @@ -5,7 +5,6 @@ alias glibmm : : : : lib p2daemonlib : [ glob *.cpp ] : - <include>../../../libmisc <library>glibmm <library>../../common//p2common : : diff --git a/project2/daemon/lib/daemon.cpp b/project2/daemon/lib/daemon.cpp index 2f1760f..f4af1c8 100644 --- a/project2/daemon/lib/daemon.cpp +++ b/project2/daemon/lib/daemon.cpp @@ -1,5 +1,5 @@ #include "daemon.h" -#include "instanceStore.impl.h" +#include <factory.impl.h> Daemon::Daemon() { @@ -9,5 +9,15 @@ Daemon::~Daemon() { } -INSTANTIATESTORE(std::string, DaemonLoader); +void +Daemon::setup() const +{ +} + +void +Daemon::teardown() const +{ +} + +INSTANTIATEFACTORY(Daemon, int &, char **); diff --git a/project2/daemon/lib/daemon.h b/project2/daemon/lib/daemon.h index acb4abf..1b33957 100644 --- a/project2/daemon/lib/daemon.h +++ b/project2/daemon/lib/daemon.h @@ -2,20 +2,22 @@ #define DAEMON_H #include <glibmm/ustring.h> -#include <genLoader.h> -#include <intrusivePtrBase.h> +#include <factory.h> +#include <visibility.h> -class Daemon : public IntrusivePtrBase { +class DLL_PUBLIC Daemon { public: Daemon(); virtual ~Daemon(); + virtual void setup() const; virtual void run() const = 0; + virtual void teardown() const; virtual void shutdown() const = 0; }; -typedef boost::intrusive_ptr<Daemon> DaemonPtr; -typedef GenLoader<Daemon, std::string, int &, char **> DaemonLoader; +typedef std::shared_ptr<Daemon> DaemonPtr; +typedef AdHoc::Factory<Daemon, int &, char **> DaemonFactory; #endif diff --git a/project2/daemon/p2daemonAppEngine.cpp b/project2/daemon/p2daemonAppEngine.cpp index b48b75b..17db02b 100644 --- a/project2/daemon/p2daemonAppEngine.cpp +++ b/project2/daemon/p2daemonAppEngine.cpp @@ -16,7 +16,7 @@ int DaemonAppEngine::periodicTimeout; DaemonAppEngine::SignalMap DaemonAppEngine::signalMap; boost::optional<uid_t> DaemonAppEngine::setUser; boost::optional<gid_t> DaemonAppEngine::setGroup; -boost::optional<boost::filesystem::path> DaemonAppEngine::pidPath; +boost::optional<std::filesystem::path> DaemonAppEngine::pidPath; bool DaemonAppEngine::daemonize; SimpleMessageException(NoSuchUser); @@ -30,7 +30,7 @@ DECLARE_OPTIONS(DaemonAppEngine, "Project2 Daemon options") ("daemon.periodicTimeout", Options::value(&periodicTimeout, 60), "Delay between occurrences of component periodic calls (default 60s)") ("daemon.setuser", Options::functions([](const VariableType & un) { - auto passwd = getpwnam(un); + auto passwd = getpwnam(un.as<std::string>().c_str()); if (!passwd) { throw NoSuchUser(un); } @@ -38,7 +38,7 @@ DECLARE_OPTIONS(DaemonAppEngine, "Project2 Daemon options") }, []{ setUser = boost::optional<uid_t>(); }), "Switch to this user on start up") ("daemon.setgroup", Options::functions([](const VariableType & gn) { - auto group = getgrnam(gn); + auto group = getgrnam(gn.as<std::string>().c_str()); if (!group) { throw NoSuchGroup(gn); } @@ -47,15 +47,15 @@ DECLARE_OPTIONS(DaemonAppEngine, "Project2 Daemon options") "Switch to this group on start up") ("daemon.pidfile", Options::functions([](const VariableType & p) { pidPath = p.as<std::string>(); }, []{ pidPath.reset(); }), "Write a pid file to this path") -("daemon.daemonize", new OptionFlagSet(&daemonize), +("daemon.daemonize", std::make_shared<OptionFlagSet>(&daemonize), "Detach and run as daemon") END_OPTIONS(DaemonAppEngine); DaemonAppEngine::DaemonAppEngine(int argc, char ** argv) : main_loop(Glib::MainLoop::create()), - daemonFactory(boost::bind(&DaemonLoader::create, DaemonLoader::getFor(daemonType), argc, argv)) + daemonFactory(boost::bind(&::DaemonFactory::create, + boost::bind(::DaemonFactory::get, boost::cref(daemonType)), argc, argv)) { - Glib::signal_timeout().connect_seconds(sigc::mem_fun(this, &DaemonAppEngine::periodicCallback), periodicTimeout); } DaemonAppEngine::~DaemonAppEngine() @@ -96,11 +96,14 @@ DaemonAppEngine::process() IgnoreSignal(SIGUSR2); AddSignalHandler(SIGQUIT, boost::bind(&DaemonAppEngine::shutdown, this)); AddSignalHandler(SIGTERM, boost::bind(&DaemonAppEngine::shutdown, this)); - + Logger()->messagebf(LOG_DEBUG, "%s: Starting events.", __PRETTY_FUNCTION__); + Glib::signal_timeout().connect_seconds(sigc::mem_fun(this, &DaemonAppEngine::periodicCallback), periodicTimeout); evThread = new std::thread(&Glib::MainLoop::run, main_loop.operator->()); Logger()->messagebf(LOG_INFO, "%s: Starting daemon.", __PRETTY_FUNCTION__); + daemon->setup(); daemon->run(); + daemon->teardown(); Logger()->messagebf(LOG_INFO, "%s: Daemon exitted.", __PRETTY_FUNCTION__); } @@ -120,7 +123,7 @@ bool DaemonAppEngine::periodicCallback() { Logger()->messagebf(LOG_DEBUG, "%s: firing component periodics.", __PRETTY_FUNCTION__); - Plugable::onAllComponents(boost::bind(&ComponentLoader::onPeriodic, _1)); + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onPeriodic, _1)); return true; } @@ -171,6 +174,6 @@ class DummyDaemon : public Daemon { private: mutable bool stop; }; -DECLARE_GENERIC_LOADER("dummydaemon", DaemonLoader, DummyDaemon); +NAMEDFACTORY("dummydaemon", DummyDaemon, DaemonFactory); #endif diff --git a/project2/daemon/p2daemonAppEngine.h b/project2/daemon/p2daemonAppEngine.h index 19bd000..807f13c 100644 --- a/project2/daemon/p2daemonAppEngine.h +++ b/project2/daemon/p2daemonAppEngine.h @@ -3,13 +3,13 @@ #include <options.h> #include <boost/optional.hpp> -#include <boost/filesystem/path.hpp> +#include <filesystem> #include "lib/daemon.h" #include <thread> #include <glibmm/main.h> #include <appInstance.h> -class DaemonAppEngine : AppInstance { +class DLL_PUBLIC DaemonAppEngine : AppInstance { public: DaemonAppEngine(int, char **); ~DaemonAppEngine(); @@ -23,7 +23,7 @@ class DaemonAppEngine : AppInstance { static int periodicTimeout; static boost::optional<uid_t> setUser; static boost::optional<gid_t> setGroup; - static boost::optional<boost::filesystem::path> pidPath; + static boost::optional<std::filesystem::path> pidPath; static bool daemonize; protected: @@ -32,7 +32,7 @@ class DaemonAppEngine : AppInstance { static void IgnoreSignal(int signum); static void DefaultSignalHandler(int signum); - static void AddSignalHandler(int signum, const SignalFunc & handler); + static void AddSignalHandler(int signum, const SignalFunc & handler); static SignalMap signalMap; static void signalHandler(int); diff --git a/project2/daemon/p2daemonMain.cpp b/project2/daemon/p2daemonMain.cpp index 8feada2..b9f96f3 100644 --- a/project2/daemon/p2daemonMain.cpp +++ b/project2/daemon/p2daemonMain.cpp @@ -44,19 +44,18 @@ daemonize() int main(int argc, char ** argv) { - Plugable::onAllComponents(boost::bind(&ComponentLoader::onBegin, _1)); - OptionsSources::Add("_2", new CommandLineArguments(argc, argv, - [](const char * a) { throw UnsupportedArguments(a); })); + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onBegin, _1)); + AdHoc::PluginManager::getDefault()->create<OptionsSource, + CommandLineArguments>("_2", __FILE__, __LINE__, argc, argv, [](const char * a) { throw UnsupportedArguments(a); }); + + DaemonAppEngine dae(argc, argv); OptionsSource::loadSources([] { return DaemonAppEngine::reqPlatform;} ); - //Plugable::onAllComponents(boost::bind(&ComponentLoader::onBefore, _1)); - + if (DaemonAppEngine::daemonize) { daemonize(); } - DaemonAppEngine dae(argc, argv); dae.process(); - //Plugable::onAllComponents(boost::bind(&ComponentLoader::onIteration, _1)); - Plugable::onAllComponents(boost::bind(&ComponentLoader::onIdle, _1)); + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onIdle, _1)); } diff --git a/project2/daemon/pidfile.cpp b/project2/daemon/pidfile.cpp index e2487c7..f42d7be 100644 --- a/project2/daemon/pidfile.cpp +++ b/project2/daemon/pidfile.cpp @@ -2,34 +2,34 @@ #include "p2daemonAppEngine.h" #include <unistd.h> #include <boost/lexical_cast.hpp> -#include <boost/filesystem/operations.hpp> -#include <boost/filesystem/fstream.hpp> +#include <filesystem> +#include <fstream> SimpleMessageException(ChownFailed); -PidFile::PidFile(const boost::filesystem::path & path) : +PidFile::PidFile(const std::filesystem::path & path) : Path(path) { auto pidDir = Path.parent_path(); - if (!boost::filesystem::exists(pidDir)) { - boost::filesystem::create_directories(pidDir); + if (!std::filesystem::exists(pidDir)) { + std::filesystem::create_directories(pidDir); if (DaemonAppEngine::setGroup || DaemonAppEngine::setUser) { if (chown(pidDir.string().c_str(), DaemonAppEngine::setUser ? *DaemonAppEngine::setUser : -1, DaemonAppEngine::setGroup ? *DaemonAppEngine::setGroup : -1)) { - boost::filesystem::remove(pidDir); + std::filesystem::remove(pidDir); throw ChownFailed(strerror(errno)); } } } - boost::filesystem::ofstream pf(Path); + std::ofstream pf(Path); pf << getpid(); if (DaemonAppEngine::setGroup || DaemonAppEngine::setUser) { if (chown(Path.string().c_str(), DaemonAppEngine::setUser ? *DaemonAppEngine::setUser : -1, DaemonAppEngine::setGroup ? *DaemonAppEngine::setGroup : -1)) { - boost::filesystem::remove(Path); + std::filesystem::remove(Path); throw ChownFailed(strerror(errno)); } } @@ -37,6 +37,6 @@ PidFile::PidFile(const boost::filesystem::path & path) : PidFile::~PidFile() { - boost::filesystem::remove(Path); + std::filesystem::remove(Path); } diff --git a/project2/daemon/pidfile.h b/project2/daemon/pidfile.h index 108b0e7..4f57e8a 100644 --- a/project2/daemon/pidfile.h +++ b/project2/daemon/pidfile.h @@ -1,15 +1,15 @@ #ifndef PIDFILE_H #define PIDFILE_H -#include <boost/filesystem/path.hpp> +#include <filesystem> class PidFile { public: - PidFile(const boost::filesystem::path & path); + PidFile(const std::filesystem::path & path); ~PidFile(); private: - const boost::filesystem::path Path; + const std::filesystem::path Path; }; #endif diff --git a/project2/daemon/tempPrivs.cpp b/project2/daemon/tempPrivs.cpp index 9c5edbd..45af498 100644 --- a/project2/daemon/tempPrivs.cpp +++ b/project2/daemon/tempPrivs.cpp @@ -20,14 +20,10 @@ TempPrivs::TempPrivs() : TempPrivs::~TempPrivs() { if (DaemonAppEngine::setUser) { - if (seteuid(originalUid)) { - throw std::runtime_error("Failed restore uid"); - } + BOOST_ASSERT_MSG(!seteuid(originalUid), "Failed restore uid"); } if (DaemonAppEngine::setGroup) { - if (setegid(originalGid)) { - throw std::runtime_error("Failed restore gid"); - } + BOOST_ASSERT_MSG(!setegid(originalGid), "Failed restore gid"); } } diff --git a/project2/files/Jamfile.jam b/project2/files/Jamfile.jam index 23fd351..7816ce8 100644 --- a/project2/files/Jamfile.jam +++ b/project2/files/Jamfile.jam @@ -4,8 +4,7 @@ alias glibmm : : : : <cflags>"`pkg-config --cflags glibmm-2.4`" <linkflags>"`pkg-config --libs glibmm-2.4`" ; -lib boost_system : : <name>boost_system ; -lib boost_filesystem : : <name>boost_filesystem ; +lib stdc++fs ; lib boost_iostreams : : <name>boost_iostreams ; lib gcrypt : : <name>gcrypt ; @@ -17,14 +16,12 @@ lib p2files : [ glob-tree *.cpp *.ll : unittests bin ] : <include>. - <include>../libmisc <library>glibmm - <library>boost_filesystem - <library>boost_system + <library>stdc++fs <library>boost_iostreams <library>gcrypt <library>../common//p2common - <library>../lib//p2lib + <library>..//adhocutil : : <include>. ; diff --git a/project2/files/configuration.ll b/project2/files/configuration.ll index aa04456..65ed4da 100644 --- a/project2/files/configuration.ll +++ b/project2/files/configuration.ll @@ -10,6 +10,7 @@ %{ #include "configFlexLexer.h" #pragma GCC diagnostic ignored "-Wsign-compare" +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" %} element [a-zA-Z][a-zA-Z0-9_-]* diff --git a/project2/files/fileLog.cpp b/project2/files/fileLog.cpp index 078e00b..8a56f6d 100644 --- a/project2/files/fileLog.cpp +++ b/project2/files/fileLog.cpp @@ -1,5 +1,5 @@ -#include "logger.h" -#include "options.h" +#include <loggerFactory.impl.h> +#include <options.h> /// Logger that writes to a file class FileLogDriver : public LogDriverBase { @@ -47,5 +47,5 @@ int FileLogDriver::level; std::string FileLogDriver::path; std::string FileLogDriver::openmode; -DECLARE_LOGGER_LOADER("file", FileLogDriver); +DECLARE_LOGGER("file", FileLogDriver); diff --git a/project2/files/fileStream.cpp b/project2/files/fileStream.cpp index 707b37e..6361438 100644 --- a/project2/files/fileStream.cpp +++ b/project2/files/fileStream.cpp @@ -1,13 +1,12 @@ #include <pch.hpp> #include "logger.h" -#include <scopeObject.h> +#include <scopeExit.h> #include "stream.h" #include "rowProcessor.h" #include "scriptLoader.h" #include "exceptions.h" #include <boost/algorithm/string/predicate.hpp> - class FileStream : public Stream { public: FileStream(ScriptNodePtr p) : @@ -22,13 +21,13 @@ class FileStream : public Stream { throw NotSupported(__PRETTY_FUNCTION__); } - void runStream(const Sink & sink, ExecContext * ec) const + void runStream(const Sink & sink, ExecContext * ec) const override { - FILE * file = fopen(path(ec), "r"); + FILE * file = fopen(path(ec).as<std::string>().c_str(), "r"); if (!file) { throw syscall_error(errno); } - ScopeObject so([&] { fclose(file); }); + AdHoc::ScopeExit so([&] { fclose(file); }); while (!feof(file)) { char buf[BUFSIZ]; size_t len = fread(buf, 1, BUFSIZ, file); @@ -46,4 +45,5 @@ class FileStream : public Stream { const Variable contentType; const Variable path; }; -DECLARE_LOADER("filestream", FileStream); +NAMEDFACTORY("filestream", FileStream, StreamFactory); + diff --git a/project2/files/fsFilterMaxDepth.cpp b/project2/files/fsFilterMaxDepth.cpp index 089737a..d55b0d1 100644 --- a/project2/files/fsFilterMaxDepth.cpp +++ b/project2/files/fsFilterMaxDepth.cpp @@ -19,4 +19,5 @@ class FsRowSpecMaxDepth : public FsRows::SpecBase { Variable maxDepth; }; -DECLARE_COMPONENT_LOADER("maxdepth", FsRowSpecMaxDepth, FsRows::SpecBaseLoader); +NAMEDFACTORY("maxdepth", FsRowSpecMaxDepth, FsRows::SpecBaseFactory); +NAMEDFACTORY("maxdepth", FsRowSpecMaxDepth, FsRows::SpecBaseStringFactory); diff --git a/project2/files/fsFilterName.cpp b/project2/files/fsFilterName.cpp index 92279c2..d1005a8 100644 --- a/project2/files/fsFilterName.cpp +++ b/project2/files/fsFilterName.cpp @@ -17,7 +17,7 @@ class FsRowSpecName : public FsRows::SpecBase { // from http://www.codeproject.com/KB/string/wildcmp.aspx Glib::ustring patt = pattern(ec); Glib::ustring::const_iterator wild = patt.begin(); - Glib::ustring leaf(curPath(fs).leaf().string()); + Glib::ustring leaf(curPath(fs).filename()); Glib::ustring::const_iterator string = leaf.begin(); while ((string != leaf.end()) && (*wild != '*')) { @@ -54,4 +54,5 @@ class FsRowSpecName : public FsRows::SpecBase { const Variable pattern; }; -DECLARE_COMPONENT_LOADER("name", FsRowSpecName, FsRows::SpecBaseLoader); +NAMEDFACTORY("name", FsRowSpecName, FsRows::SpecBaseFactory); +NAMEDFACTORY("name", FsRowSpecName, FsRows::SpecBaseStringFactory); diff --git a/project2/files/fsFilterType.cpp b/project2/files/fsFilterType.cpp index ba9ad72..2aecfee 100644 --- a/project2/files/fsFilterType.cpp +++ b/project2/files/fsFilterType.cpp @@ -40,4 +40,6 @@ class FsRowSpecType : public FsRows::SpecBase { const Variable typelist; }; -DECLARE_COMPONENT_LOADER("type", FsRowSpecType, FsRows::SpecBaseLoader); +NAMEDFACTORY("type", FsRowSpecType, FsRows::SpecBaseFactory); +NAMEDFACTORY("type", FsRowSpecType, FsRows::SpecBaseStringFactory); + diff --git a/project2/files/fsRows.cpp b/project2/files/fsRows.cpp index d22b6ea..127f1b1 100644 --- a/project2/files/fsRows.cpp +++ b/project2/files/fsRows.cpp @@ -4,7 +4,7 @@ #include "scriptLoader.h" #include "rowProcessor.h" #include "exceptions.h" -#include <boost/filesystem/operations.hpp> +#include <filesystem> #include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/split.hpp> #include <boost/bind.hpp> @@ -14,11 +14,11 @@ #include <grp.h> #include <stdio.h> #include <boost/date_time/posix_time/posix_time.hpp> -#include "instanceStore.impl.h" +#include <factory.impl.h> -typedef boost::filesystem::directory_iterator DirEnt; +typedef std::filesystem::directory_iterator DirEnt; -DECLARE_LOADER("fsrows", FsRows); +NAMEDFACTORY("fsrows", FsRows, RowSetFactory); const Glib::ustring field_absPath("absPath"); const Glib::ustring field_relPath("relPath"); @@ -32,25 +32,26 @@ const Glib::ustring field_type("type"); static Columns defCols() { Columns rtn; - rtn.insert(new Column(0, "absPath")); + rtn.insert(std::make_shared<Column>(0, "absPath")); return rtn; } const Columns FsRows::SearchState::col(defCols()); bool FsRows::SpecBase::recurse(const SearchState *, ExecContext *) const { return true; } bool FsRows::SpecBase::matches(const SearchState *, ExecContext *) const { return true; } -const boost::filesystem::path & FsRows::SpecBase::curPath(const SearchState * fs) const { return fs->curPath; } +const std::filesystem::path & FsRows::SpecBase::curPath(const SearchState * fs) const { return fs->curPath; } unsigned int FsRows::SpecBase::depth(const SearchState * fs) const { return fs->depth; } const struct stat & FsRows::SpecBase::curStat(const SearchState * fs) const { return fs->curStat; } FsRows::FsRows(ScriptNodePtr p) : + SourceObject(p), RowSet(p), root(p, "root"), spec(p, "spec", ""), ignoreErrors(p, "ignoreerrors", true) { - p->script->loader.addLoadTarget(p, Storer::into<SpecBaseLoader>(&specs)); + p->script.lock()->loader.addLoadTarget(p, Storer::into<SpecBaseFactory>(&specs)); } FsRows::~FsRows() @@ -81,7 +82,7 @@ FsRows::execute(const Glib::ustring &, const RowProcessorCallback & rp, ExecCont for (SpecSpec::const_iterator sf = s.begin(); sf != s.end(); ) { const Glib::ustring & name = (*sf++); if (name[0] == '-') { - ss.specs.insert(InstanceMap<SpecBaseLoader, std::string>::Get<NotSupported>(name.substr(1))->createWith(*sf++)); + ss.specs.insert(SpecBaseStringFactory::createNew(name.raw().substr(1), *sf++)); } else { throw NotSupported(name); @@ -112,7 +113,7 @@ FsRows::execute(SearchState & ss, const Path & dir, const RowProcessorCallback & } } } - catch (const boost::filesystem::filesystem_error & e) { + catch (const std::filesystem::filesystem_error & e) { if (!ignoreErrors(ec)) { throw; } @@ -237,5 +238,6 @@ FsRows::SearchState::fileType() const throw NotSupported(__PRETTY_FUNCTION__); } -INSTANTIATESTORE(std::string, FsRows::SpecBaseLoader); +INSTANTIATEFACTORY(FsRows::SpecBase, std::shared_ptr<const ScriptNode>); +INSTANTIATEFACTORY(FsRows::SpecBase, const Glib::ustring &); diff --git a/project2/files/fsRows.h b/project2/files/fsRows.h index 2e44750..b8fdac8 100644 --- a/project2/files/fsRows.h +++ b/project2/files/fsRows.h @@ -1,49 +1,35 @@ #ifndef FSROWS_H #define FSROWS_H -#include <boost/intrusive_ptr.hpp> -#include <boost/filesystem/path.hpp> +#include <filesystem> #include <sys/stat.h> #include "variables.h" #include "rowSet.h" #include "scriptStorage.h" #include "scriptLoader.h" +#include <factory.h> class CommonObjects; /// Project2 component to create a row set based on files and directories on the local filesystem -class FsRows : public RowSet { +class DLL_PUBLIC FsRows : public RowSet { public: class SearchState; - class SpecBase : public virtual IntrusivePtrBase { + class SpecBase : public virtual Something { public: virtual bool recurse(const SearchState * fs, ExecContext *) const; virtual bool matches(const SearchState * fs, ExecContext *) const; protected: - const boost::filesystem::path & curPath(const SearchState * fs) const; + const std::filesystem::path & curPath(const SearchState * fs) const; unsigned int depth(const SearchState * fs) const; const struct stat & curStat(const SearchState * fs) const; }; - typedef boost::intrusive_ptr<SpecBase> SpecBasePtr; - template <class X> - class SpecBaseLoaderX : public GenLoader<SpecBase, std::string, ScriptNodePtr> { - public: - virtual SpecBase * createWith(const Glib::ustring &) const = 0; - template <class T, class BaseLoader = SpecBaseLoaderX<X>> - class For : public BaseLoader { - public: - inline SpecBase * create(const ScriptNodePtr & v) const { - return new T(v); - } - inline SpecBase * createWith(const Glib::ustring & v) const { - return new T(v); - } - }; - }; - typedef SpecBaseLoaderX<void> SpecBaseLoader; + typedef std::shared_ptr<SpecBase> SpecBasePtr; + typedef AdHoc::Factory<SpecBase, std::shared_ptr<const ScriptNode>> SpecBaseFactory; + typedef AdHoc::Factory<SpecBase, const Glib::ustring &> SpecBaseStringFactory; typedef ANONSTORAGEOF(SpecBase) SpecBases; typedef std::list<Glib::ustring> SpecSpec; - typedef boost::filesystem::path Path; + typedef std::filesystem::path Path; FsRows(ScriptNodePtr p); ~FsRows(); @@ -55,7 +41,7 @@ class FsRows : public RowSet { void execute(const Glib::ustring &, const RowProcessorCallback &, ExecContext *) const; class SearchState : public RowState { public: - SearchState(const boost::filesystem::path & r); + SearchState(const std::filesystem::path & r); virtual RowAttribute resolveAttr(const Glib::ustring & attrName) const; virtual void foreachAttr(const AttrAction & action) const; @@ -72,8 +58,8 @@ class FsRows : public RowSet { static const Columns col; SpecBases specs; - const boost::filesystem::path fsRoot; - boost::filesystem::path curPath; + const std::filesystem::path fsRoot; + std::filesystem::path curPath; Glib::ustring curPathStr; unsigned int depth; struct stat curStat; diff --git a/project2/files/functions/pwd.cpp b/project2/files/functions/pwd.cpp index 644c934..ade7702 100644 --- a/project2/files/functions/pwd.cpp +++ b/project2/files/functions/pwd.cpp @@ -2,7 +2,7 @@ #include <variables.h> #include <scriptLoader.h> #include <scripts.h> -#include <boost/filesystem/operations.hpp> +#include <filesystem> /// Variable implementation to access session contents class Pwd : public VariableImplDyn { @@ -13,9 +13,9 @@ class Pwd : public VariableImplDyn { } VariableType value(ExecContext *) const { - return boost::filesystem::current_path().string(); + return std::filesystem::current_path().string(); } }; -DECLARE_COMPONENT_LOADER("pwd", Pwd, VariableLoader); +NAMEDFACTORY("pwd", Pwd, VariableFactory); diff --git a/project2/files/optionsSource.cpp b/project2/files/optionsSource.cpp index 8e98df0..7d81e50 100644 --- a/project2/files/optionsSource.cpp +++ b/project2/files/optionsSource.cpp @@ -1,21 +1,22 @@ #include <pch.hpp> -#include <boost/filesystem/convenience.hpp> +#include <filesystem> #include "optionsSource.h" #define yyFlexLexer configBaseFlexLexer #include <FlexLexer.h> #include "configFlexLexer.h" #include <boost/shared_ptr.hpp> #include <fstream> +#include <chronoHelpers.h> -FileOptions::FileOptions(const boost::filesystem::path & f) : - file(boost::filesystem::absolute(f)) +FileOptions::FileOptions(const std::filesystem::path & f) : + file(std::filesystem::absolute(f)) { } void FileOptions::loadInto(const ConfigConsumer & consume, const Options::CurrentPlatform & platform) const { - if (boost::filesystem::exists(file)) { + if (std::filesystem::exists(file)) { std::ifstream in(file.string()); if (!in.good()) { throw std::runtime_error("Couldn't open configuration file " + file.string()); @@ -29,28 +30,37 @@ boost::posix_time::ptime FileOptions::modifiedTime() const { return boost::posix_time::from_time_t( - boost::filesystem::exists(file) ? - std::max( - boost::filesystem::last_write_time(file), - boost::filesystem::last_write_time(file.parent_path())) : - boost::filesystem::last_write_time(file.parent_path())); + to_time_t( + std::filesystem::exists(file) ? + std::max( + std::filesystem::last_write_time(file), + std::filesystem::last_write_time(file.parent_path())) : + std::filesystem::last_write_time(file.parent_path()))); } FileOptions::ExtraFileOptions FileOptions::extraFileOptions; +class DefaultFileOptions : public FileOptions { + public: + DefaultFileOptions() : + FileOptions(".p2config") + { + } +}; + // Z... process last :) -DECLARE_OPTIONSSOURCE("Z_configfile", new FileOptions(".p2config")) +DECLARE_OPTIONSSOURCE("Z_configfile", DefaultFileOptions) DECLARE_OPTIONS(FileOptions, "File Options options") ("file.options.read", Options::functions( [](const VariableType & vt) { - auto fo = new FileOptions(vt.as<std::string>()); - extraFileOptions[vt] = boost::shared_ptr<FileOptions>(fo); - OptionsSources::Add(vt, fo); + auto fo = std::make_shared<FileOptions>(vt.as<std::string>()); + extraFileOptions[vt] = fo; + AdHoc::PluginManager::getDefault()->add<OptionsSource>(fo, vt, __FILE__, __LINE__); }, []() { for (const auto & fo : extraFileOptions) { - OptionsSources::Remove(fo.first); + AdHoc::PluginManager::getDefault()->remove<OptionsSource>(fo.first); } extraFileOptions.clear(); }), diff --git a/project2/files/optionsSource.h b/project2/files/optionsSource.h index a6d1cd1..121b3f3 100644 --- a/project2/files/optionsSource.h +++ b/project2/files/optionsSource.h @@ -3,21 +3,22 @@ #include "../common/optionsSource.h" #include "../common/options.h" -#include <boost/filesystem/path.hpp> +#include <filesystem> +#include <visibility.h> class FileOptions; -typedef boost::shared_ptr<FileOptions> FileOptionsPtr; +typedef std::shared_ptr<FileOptions> FileOptionsPtr; -class FileOptions : public OptionsSource { +class DLL_PUBLIC FileOptions : public OptionsSource { public: - FileOptions(const boost::filesystem::path & file); + FileOptions(const std::filesystem::path & file); - void loadInto(const ConfigConsumer & consume, const Options::CurrentPlatform & platform) const; + void loadInto(const ConfigConsumer & consume, const Options::CurrentPlatform & platform) const override; boost::posix_time::ptime modifiedTime() const override; INITOPTIONS; private: - const boost::filesystem::path file; + const std::filesystem::path file; typedef std::map<std::string, FileOptionsPtr> ExtraFileOptions; static ExtraFileOptions extraFileOptions; diff --git a/project2/files/pch.hpp b/project2/files/pch.hpp index 4b9183d..daaaf3b 100644 --- a/project2/files/pch.hpp +++ b/project2/files/pch.hpp @@ -2,29 +2,10 @@ #ifndef FILES_PCH #define FILES_PCH -#include <boost/algorithm/string/predicate.hpp> -#include <boost/algorithm/string/split.hpp> -#include <boost/algorithm/string/trim.hpp> #include <boost/bind.hpp> -#include <boost/date_time/posix_time/posix_time.hpp> -#include <boost/filesystem/operations.hpp> -#include <boost/filesystem/path.hpp> +#include <filesystem> #include <boost/intrusive_ptr.hpp> -#include <boost/lexical_cast.hpp> -#include "definedColumns.h" -#include "exceptions.h" -#include "fsRows.h" -#include <glibmm/fileutils.h> -#include <glibmm/iochannel.h> -#include "logger.h" -#include "optionsSource.h" -#include "rowProcessor.h" -#include "rowSet.h" -#include "scopeObject.h" -#include "scriptLoader.h" -#include "scripts.h" -#include "scriptStorage.h" -#include "variables.h" +#include <boost/variant/variant_fwd.hpp> #endif #endif diff --git a/project2/files/presenterCache.cpp b/project2/files/presenterCache.cpp index 897c85b..c176d17 100644 --- a/project2/files/presenterCache.cpp +++ b/project2/files/presenterCache.cpp @@ -4,12 +4,11 @@ #include "options.h" #include <safeMapFind.h> #include <fcntl.h> -#include <attr/xattr.h> +#include <sys/xattr.h> #include <sys/stat.h> #include <boost/iostreams/device/file_descriptor.hpp> #include <boost/iostreams/stream.hpp> -#include <boost/filesystem/path.hpp> -#include <boost/filesystem/operations.hpp> +#include <filesystem> #include <boost/bind.hpp> #include <boost/tuple/tuple_comparison.hpp> #include <glibmm/convert.h> @@ -37,7 +36,7 @@ class FilePresenterCache : public PresenterCache { typedef std::vector<std::string> Path; typedef std::map<std::string, VariableType> Parameters; typedef boost::tuple<Path, Parameters> Key; - class CacheFile : public IntrusivePtrBase { + class CacheFile { public: CacheFile(int f) : fd(f) { } @@ -47,7 +46,7 @@ class FilePresenterCache : public PresenterCache { operator int() const { return fd; } const int fd; }; - typedef boost::intrusive_ptr<CacheFile> CacheFilePtr; + typedef std::shared_ptr<CacheFile> CacheFilePtr; typedef std::map<Key, CacheFilePtr> OpenCaches; class WriteCacheFile : public boost::iostreams::sink { @@ -87,7 +86,7 @@ class FilePresenterCache : public PresenterCache { FilePresenterCache(ScriptNodePtr s) : PresenterCache(s), - idProvider(VariableLoader::createNew(Provider, s)) { + idProvider(VariableFactory::createNew(Provider, s)) { } ~FilePresenterCache() { @@ -96,7 +95,7 @@ class FilePresenterCache : public PresenterCache { { Key key = getCacheKey(ec); try { - CacheFilePtr f = defaultMapFind(openCaches, key); + CacheFilePtr f = AdHoc::defaultMapLookup(openCaches, key); if (!f) { f = openCacheFile(key, ec); } @@ -194,16 +193,16 @@ class FilePresenterCache : public PresenterCache { } CacheFilePtr openCacheFile(const Key & key, ExecContext * ec) const { - CacheFilePtr c = new CacheFile(safesys<OpenCacheFile>(-1, open(getCacheFile(ec).string().c_str(), O_RDONLY))); + CacheFilePtr c = std::make_shared<CacheFile>(safesys<OpenCacheFile>(-1, open(getCacheFile(ec).string().c_str(), O_RDONLY))); openCaches[key] = c; return c; } - boost::filesystem::path getCacheFile(ExecContext * ec) const + std::filesystem::path getCacheFile(ExecContext * ec) const { - boost::filesystem::path cache; + std::filesystem::path cache; cache = Store; - cache /= idProvider->value(ec); - boost::filesystem::create_directories(cache); + cache /= idProvider->value(ec).as<std::string>(); + std::filesystem::create_directories(cache); cache /= FileName; return cache; } @@ -213,7 +212,7 @@ class FilePresenterCache : public PresenterCache { cache->insert(Parameters::value_type(n, v)); } - static void appendPath(boost::filesystem::path * cache, const std::string & n, const VariableType & v) + static void appendPath(std::filesystem::path * cache, const std::string & n, const VariableType & v) { *cache /= n; *cache /= v.operator const std::string &(); @@ -224,14 +223,14 @@ class FilePresenterCache : public PresenterCache { Variable::VariableImplPtr idProvider; // Config - static boost::filesystem::path Store; + static std::filesystem::path Store; static std::string FileName; static std::string Provider; static time_t CacheLife; - friend class FilePresenterCacheLoader; + friend class FilePresenterCacheFactory; }; FilePresenterCache::OpenCaches FilePresenterCache::openCaches; -boost::filesystem::path FilePresenterCache::Store; +std::filesystem::path FilePresenterCache::Store; std::string FilePresenterCache::FileName; std::string FilePresenterCache::Provider; time_t FilePresenterCache::CacheLife; @@ -247,9 +246,9 @@ DECLARE_OPTIONS(FilePresenterCache, "File Presenter Cache options") "The name of the component used to provide a unique request ID") END_OPTIONS(FilePresenterCache) -class FilePresenterCacheLoader : public ElementLoader::For<FilePresenterCache> { +class FilePresenterCacheFactory : public LifeCycle { public: - FilePresenterCacheLoader() + FilePresenterCacheFactory() { gcry_check_version(GCRYPT_VERSION); } @@ -257,7 +256,7 @@ class FilePresenterCacheLoader : public ElementLoader::For<FilePresenterCache> { void onIdle() override { try { - if (boost::filesystem::is_directory(FilePresenterCache::Store)) { + if (std::filesystem::is_directory(FilePresenterCache::Store)) { emptyDir(FilePresenterCache::Store); } } @@ -272,11 +271,11 @@ class FilePresenterCacheLoader : public ElementLoader::For<FilePresenterCache> { FilePresenterCache::openCaches.clear(); } - bool emptyDir(const boost::filesystem::path & dir) + bool emptyDir(const std::filesystem::path & dir) { bool files = false; - boost::filesystem::directory_iterator end; - for (boost::filesystem::directory_iterator itr(dir); itr != end; ++itr) { + std::filesystem::directory_iterator end; + for (std::filesystem::directory_iterator itr(dir); itr != end; ++itr) { struct stat st; stat(itr->path().string().c_str(), &st); if (S_ISDIR(st.st_mode)) { @@ -284,7 +283,7 @@ class FilePresenterCacheLoader : public ElementLoader::For<FilePresenterCache> { files = true; } else { - boost::filesystem::remove(*itr); + std::filesystem::remove(*itr); } } else { @@ -292,11 +291,12 @@ class FilePresenterCacheLoader : public ElementLoader::For<FilePresenterCache> { files = true; } else { - boost::filesystem::remove(*itr); + std::filesystem::remove(*itr); } } } return files; } }; -DECLARE_CUSTOM_LOADER("filecache", FilePresenterCacheLoader); +NAMEDFACTORY("filecache", FilePresenterCache, PresenterCacheFactory); + diff --git a/project2/files/unittests/Jamfile.jam b/project2/files/unittests/Jamfile.jam index 236938d..ec821d6 100644 --- a/project2/files/unittests/Jamfile.jam +++ b/project2/files/unittests/Jamfile.jam @@ -1,7 +1,6 @@ import testing ; -lib boost_system ; -lib boost_filesystem ; +lib stdc++fs ; path-constant me : . ; @@ -11,7 +10,7 @@ run <library>..//p2files <library>../../ut//p2ut <library>../../common//p2common - <library>boost_filesystem + <library>stdc++fs <define>ROOT=\"$(me)\" <dependency>test.config : testConfig ; diff --git a/project2/files/unittests/testConfig.cpp b/project2/files/unittests/testConfig.cpp index 45fafac..995b07e 100644 --- a/project2/files/unittests/testConfig.cpp +++ b/project2/files/unittests/testConfig.cpp @@ -22,7 +22,7 @@ class TestConfigConsumer : public ConfigConsumer { const Glib::ustring & operator()(const Glib::ustring & name, const Glib::ustring & platform) const { - return safeMapLookup<NotFound>(options, {name, platform}); + return AdHoc::safeMapLookup<NotFound>(options, {name, platform}); } const Options::Option * get(const Glib::ustring &) const override { return NULL; } mutable OptionsMap options; @@ -31,7 +31,7 @@ class TestConfigConsumer : public ConfigConsumer { BOOST_AUTO_TEST_CASE( readMissingFile ) { TestConfigConsumer options; - OptionsSourcePtr file = OptionsSourcePtr(new FileOptions(RootDir / "nothere.config")); + OptionsSourcePtr file = OptionsSourcePtr(new FileOptions(rootDir / "nothere.config")); file->loadInto(options, []() { return Glib::ustring(); }); BOOST_REQUIRE(options.options.empty()); } @@ -39,8 +39,8 @@ BOOST_AUTO_TEST_CASE( readMissingFile ) BOOST_AUTO_TEST_CASE( readConfigFile ) { TestConfigConsumer options; - BOOST_REQUIRE(boost::filesystem::exists(RootDir / "test.config")); - OptionsSourcePtr file = OptionsSourcePtr(new FileOptions(RootDir / "test.config")); + BOOST_REQUIRE(std::filesystem::exists(rootDir / "test.config")); + OptionsSourcePtr file = OptionsSourcePtr(new FileOptions(rootDir / "test.config")); file->loadInto(options, []() { return Glib::ustring(); }); // Count BOOST_REQUIRE_EQUAL(12, options.options.size()); diff --git a/project2/files/writeStream.cpp b/project2/files/writeStream.cpp index 954ec8b..641cde5 100644 --- a/project2/files/writeStream.cpp +++ b/project2/files/writeStream.cpp @@ -2,6 +2,7 @@ #include "task.h" #include "stream.h" #include "variables.h" +#include <scriptStorage.h> #include <fstream> SimpleMessageException(OpenTargetFile); @@ -13,7 +14,7 @@ class WriteStream : public Task { Task(s), path(s, "path") { - s->script->loader.addLoadTarget(s, Storer::into<ElementLoader>(&stream)); + s->script.lock()->loader.addLoadTarget(s, Storer::into<StreamFactory>(&stream)); } void execute(ExecContext * ec) const @@ -32,5 +33,5 @@ class WriteStream : public Task { StreamPtr stream; }; -DECLARE_LOADER("writestream", WriteStream); +NAMEDFACTORY("writestream", WriteStream, TaskFactory); diff --git a/project2/ice/Jamfile.jam b/project2/ice/Jamfile.jam index 22e74b6..c7fe77c 100644 --- a/project2/ice/Jamfile.jam +++ b/project2/ice/Jamfile.jam @@ -4,36 +4,35 @@ alias glibmm : : : : ; lib dl ; -lib Slice ; -lib Ice ; -lib IceUtil ; +lib mcpp ; +lib Ice : : <name>Ice++11 ; +lib IceBox : : <name>IceBox++11 ; lib pthread ; -lib boost_filesystem ; -lib slicer : : <name>slicer : : <include>/usr/include/slicer ; +lib stdc++fs ; +lib slicer : : : : <include>/usr/include/slicer ; +lib slicer-compiler : : : : <include>/usr/include/slicer ; build-project unittests ; cpp-pch pch : pch.hpp : - <include>../../libmisc - <library>../lib//p2lib + <library>..//adhocutil <library>../common//p2common - <library>glibmm - <library>slicer + <library>glibmm + <library>slicer + <library>slice//Slice ; lib p2iceclient : pch iceDataSource.cpp iceClient.cpp buildClient.cpp slice2Task.cpp slice2Rows.cpp iceRows.cpp : - <include>../../libmisc <library>glibmm <library>../common//p2common - <library>../lib//p2lib + <library>..//adhocutil <library>p2ice <library>dl <library>Ice - <library>Slice - <library>IceUtil - <library>boost_filesystem + <library>slice//Slice + <library>stdc++fs <library>pthread : : <library>p2ice @@ -44,37 +43,55 @@ lib p2iceclient : lib p2icedaemon : pch iceDaemon.cpp iceModule.cpp buildDaemon.cpp slice2Daemon.cpp iceViewSerializer.cpp : - <include>../../libmisc <library>glibmm <library>../common//p2common - <library>../lib//p2lib + <library>..//adhocutil <library>../basics//p2basics <library>../daemon/lib//p2daemonlib <library>p2ice <library>dl <library>Ice - <library>Slice - <library>IceUtil - <library>boost_filesystem + <library>slice//Slice + <library>stdc++fs + <library>pthread : : <library>../daemon/lib//p2daemonlib <library>p2ice <include>. ; +lib p2icebox++11 : + pch [ glob icebox*.cpp ] + : + <include>../../libmisc + <library>glibmm + <library>../daemon/lib//p2daemonlib + <library>..//p2parts + <library>dl + <library>pthread + <library>Ice + <library>IceBox + : : + <library>../daemon/lib//p2daemonlib + <library>Ice + <library>IceBox + <include>. + ; + lib p2ice : pch iceConvert.cpp iceCompile.cpp sliceCompile.cpp buildComms.cpp slice2Common.cpp iceBase.cpp : - <include>../../libmisc <library>glibmm <library>../common//p2common - <library>../lib//p2lib + <library>..//adhocutil <library>dl + <library>mcpp <library>Ice - <library>Slice + <library>slice//Slice <library>slicer - <library>IceUtil - <library>boost_filesystem + <library>slicer-compiler + <library>stdc++fs + <library>pthread : : <linkflags>-rdynamic <library>slicer diff --git a/project2/ice/buildClient.cpp b/project2/ice/buildClient.cpp index 97655c7..f454373 100644 --- a/project2/ice/buildClient.cpp +++ b/project2/ice/buildClient.cpp @@ -3,7 +3,7 @@ #include "slice2Task.h" #include "slice2Rows.h" -BuildClient::BuildClient(const boost::filesystem::path & slice, const IceCompile::Deps & dep) : +BuildClient::BuildClient(const std::filesystem::path & slice, const IceCompile::Deps & dep) : SliceCompile(slice, dep) { } @@ -26,7 +26,7 @@ BuildClient::Body(FILE * out, Slice::UnitPtr u) const return taskBuilder.Components() + rowsBuilder.Components(); } -boost::filesystem::path +std::filesystem::path BuildClient::OutputName(const std::string & type) const { return slice.filename().replace_extension(".client" + type); diff --git a/project2/ice/buildClient.h b/project2/ice/buildClient.h index e16872e..a6f6ef1 100644 --- a/project2/ice/buildClient.h +++ b/project2/ice/buildClient.h @@ -6,12 +6,12 @@ class BuildClient : public SliceCompile { public: - BuildClient(const boost::filesystem::path & slice, const IceCompile::Deps & dep); + BuildClient(const std::filesystem::path & slice, const IceCompile::Deps & dep); virtual void Headers(FILE *) const; virtual unsigned int Body(FILE *, Slice::UnitPtr) const; - boost::filesystem::path OutputName(const std::string & type) const; + std::filesystem::path OutputName(const std::string & type) const; }; #endif diff --git a/project2/ice/buildComms.cpp b/project2/ice/buildComms.cpp index 3ee548c..0ccef74 100644 --- a/project2/ice/buildComms.cpp +++ b/project2/ice/buildComms.cpp @@ -1,13 +1,13 @@ #include <pch.hpp> #include "buildComms.h" #include <logger.h> -#include <misc.h> -#include <boost/filesystem/operations.hpp> +#include <buffer.h> +#include <filesystem> #include <slicer/parser.h> -namespace fs = boost::filesystem; +namespace fs = std::filesystem; -BuildComms::BuildComms(const boost::filesystem::path & slice, bool ip, bool sp) : +BuildComms::BuildComms(const std::filesystem::path & slice, bool ip, bool sp) : IceCompile(slice), iceParts(ip), slicerParts(sp) @@ -15,7 +15,7 @@ BuildComms::BuildComms(const boost::filesystem::path & slice, bool ip, bool sp) } unsigned int -BuildComms::Count(const boost::filesystem::path & in) const +BuildComms::Count(const std::filesystem::path & in) const { unsigned int components = 0; @@ -24,43 +24,47 @@ BuildComms::Count(const boost::filesystem::path & in) const } if (slicerParts) { - components += Slicer::Slicer::Apply(in, NULL); + Slicer::Slicer s; + s.slicePath = in; + components += s.Execute(); } return components; } unsigned int -BuildComms::Build(const boost::filesystem::path & in, const boost::filesystem::path & out) const +BuildComms::Build(const std::filesystem::path & in, const std::filesystem::path & out) const { - const auto slicecmd = stringbf("%s --output-dir %s %s", slice2cpp, out.parent_path(), in); + const auto slicecmd = stringbf("%s --output-dir %s --dll-export JAM_DLL_PUBLIC %s", slice2cpp, out.parent_path(), in); Logger()->messagebf(LOG_DEBUG, "%s: slice command: %s", __PRETTY_FUNCTION__, slicecmd); if (system(slicecmd.c_str())) { throw std::runtime_error("slice2cpp failed"); } unsigned int components = 0; - if (!iceParts) { - // We always need to the header, but we can truncate the cpp if we don't need the ice bits - boost::filesystem::resize_file(out, 0); - } - else { + if (iceParts) { components += 1; } if (slicerParts) { - components += Slicer::Slicer::Apply(in, out); + Slicer::Slicer s; + s.slicePath = in; + s.cpp = fopen(out.c_str(), iceParts ? "a" : "w"); + if (!s.cpp) { + throw std::runtime_error("slicer fopen failed"); + } + components += s.Execute(); } return components; } -boost::filesystem::path +std::filesystem::path BuildComms::InputPath() const { return slice; } -boost::filesystem::path +std::filesystem::path BuildComms::OutputName(const std::string & type) const { return slice.filename().replace_extension(type); diff --git a/project2/ice/buildComms.h b/project2/ice/buildComms.h index efce380..4f541b5 100644 --- a/project2/ice/buildComms.h +++ b/project2/ice/buildComms.h @@ -6,12 +6,12 @@ class BuildComms : public IceCompile { public: - BuildComms(const boost::filesystem::path & slice, bool iceParts, bool slicerParts); + BuildComms(const std::filesystem::path & slice, bool iceParts, bool slicerParts); - unsigned int Build(const boost::filesystem::path & in, const boost::filesystem::path & out) const; - unsigned int Count(const boost::filesystem::path & in) const; - boost::filesystem::path InputPath() const; - boost::filesystem::path OutputName(const std::string & type) const; + unsigned int Build(const std::filesystem::path & in, const std::filesystem::path & out) const; + unsigned int Count(const std::filesystem::path & in) const; + std::filesystem::path InputPath() const; + std::filesystem::path OutputName(const std::string & type) const; const bool iceParts; const bool slicerParts; diff --git a/project2/ice/buildDaemon.cpp b/project2/ice/buildDaemon.cpp index 5bb4cfd..6f7138b 100644 --- a/project2/ice/buildDaemon.cpp +++ b/project2/ice/buildDaemon.cpp @@ -2,7 +2,7 @@ #include "buildDaemon.h" #include "slice2Daemon.h" -BuildDaemon::BuildDaemon(const boost::filesystem::path & slice, const IceCompile::Deps & dep) : +BuildDaemon::BuildDaemon(const std::filesystem::path & slice, const IceCompile::Deps & dep) : SliceCompile(slice, dep) { } @@ -22,7 +22,7 @@ BuildDaemon::Body(FILE * out, Slice::UnitPtr u) const return daemonBuilder.Components(); } -boost::filesystem::path +std::filesystem::path BuildDaemon::OutputName(const std::string & type) const { return slice.filename().replace_extension(".daemon" + type); diff --git a/project2/ice/buildDaemon.h b/project2/ice/buildDaemon.h index b2dd8ca..47ba77a 100644 --- a/project2/ice/buildDaemon.h +++ b/project2/ice/buildDaemon.h @@ -6,12 +6,12 @@ class BuildDaemon : public SliceCompile { public: - BuildDaemon(const boost::filesystem::path & slice, const IceCompile::Deps & dep); + BuildDaemon(const std::filesystem::path & slice, const IceCompile::Deps & dep); virtual void Headers(FILE *) const; virtual unsigned int Body(FILE *, Slice::UnitPtr) const; - boost::filesystem::path OutputName(const std::string & type) const; + std::filesystem::path OutputName(const std::string & type) const; }; #endif diff --git a/project2/ice/iceBase.cpp b/project2/ice/iceBase.cpp index 7a3382c..0cdc9cc 100644 --- a/project2/ice/iceBase.cpp +++ b/project2/ice/iceBase.cpp @@ -5,7 +5,7 @@ void IceBase::SetSlice(Libs & libs, const GetComponentCompiler & gcc, const VariableType & vslice, bool iceParts, bool slicerParts) { auto slice = vslice.as<std::string>(); - IceCompile::Ptr bc(new BuildComms(slice, iceParts, slicerParts)); + auto bc = std::make_shared<BuildComms>(slice, iceParts, slicerParts); bc->Update(IceCompile::UpdateBuild); IceCompile::Ptr bcl(gcc(slice, { bc })); libs.push_back(LibCompile(bcl, new std::thread(&IceCompile::Update, bcl.get(), diff --git a/project2/ice/iceBase.h b/project2/ice/iceBase.h index 0a59416..5547342 100644 --- a/project2/ice/iceBase.h +++ b/project2/ice/iceBase.h @@ -5,8 +5,9 @@ #include <thread> #include "iceCompile.h" #include <variableType.h> +#include <visibility.h> -class IceBase { +class DLL_PUBLIC IceBase { public: typedef boost::tuple<IceCompile::Ptr, std::thread *> LibCompile; typedef boost::variant<LibCompile, IceCompile::LibHandles> LibPromise; diff --git a/project2/ice/iceClient.h b/project2/ice/iceClient.h index 1d198f1..70bcbbd 100644 --- a/project2/ice/iceClient.h +++ b/project2/ice/iceClient.h @@ -4,8 +4,9 @@ #include <variables.h> #include <commonObjects.h> #include "iceDataSource.h" +#include <visibility.h> -class IceClientBase { +class DLL_PUBLIC IceClientBase { public: IceClientBase(ScriptNodePtr p); @@ -16,7 +17,7 @@ class IceClientBase { }; template <typename Interface> -class IceClient : public IceClientBase { +class DLL_PUBLIC IceClient : public IceClientBase { public: IceClient(ScriptNodePtr p) : IceClientBase(p) { } @@ -30,7 +31,7 @@ class IceClient : public IceClientBase { } protected: - Interface service; + std::shared_ptr<Interface> service; }; #endif diff --git a/project2/ice/iceCompile.cpp b/project2/ice/iceCompile.cpp index a518cde..eee0463 100644 --- a/project2/ice/iceCompile.cpp +++ b/project2/ice/iceCompile.cpp @@ -1,11 +1,11 @@ #include <pch.hpp> #include "iceCompile.h" -#include <boost/filesystem/operations.hpp> +#include <filesystem> #include <logger.h> -#include <misc.h> +#include <buffer.h> #include <dlfcn.h> -namespace fs = boost::filesystem; +namespace fs = std::filesystem; std::string IceCompile::slice2cpp; std::string IceCompile::slicer; @@ -20,11 +20,11 @@ fs::path IceCompile::slicerheaderdir; DECLARE_OPTIONS(IceCompile, "ICE Compile Options") ("ice.compile.cxx", Options::value(&cxx, "g++"), "The C++ compiler to use") -("ice.compile.cxxopts", Options::value(&cxxopts, "-Wall -Werror -std=c++11 -O3 -march=native -fPIC"), +("ice.compile.cxxopts", Options::value(&cxxopts, "-Wall -Werror -std=c++17 -DICE_CPP11_MAPPING -O3 -march=native -fPIC"), "The extra arguments to pass to the C++ compiler") ("ice.compile.linker", Options::value(&linker, "g++"), "The linker to use") -("ice.compile.linkeropts", Options::value(&linkeropts, ""), +("ice.compile.linkeropts", Options::value(&linkeropts, "-Wl,--strip-all,--gc-sections"), "The extra arguments to pass to linker") ("ice.compile.slice2cpp", Options::value(&slice2cpp, "slice2cpp"), "The ICE Slice to CPP processor to use") @@ -38,13 +38,13 @@ DECLARE_OPTIONS(IceCompile, "ICE Compile Options") "The root folder where Slicer header files are found") END_OPTIONS(IceCompile); -IceCompile::IceCompile(const boost::filesystem::path & s) : +IceCompile::IceCompile(const std::filesystem::path & s) : slice(s), components(0) { } -IceCompile::IceCompile(const boost::filesystem::path & s, const Deps & d) : +IceCompile::IceCompile(const std::filesystem::path & s, const Deps & d) : slice(s), components(0), deps(d) @@ -102,11 +102,9 @@ IceCompile::Compile(const fs::path & in, const fs::path & out) if (components == 0) return; const auto compile = stringbf( - "%s %s -o %s -x c++ -c -I %s -I %s -I ../libmisc/ -I %s -I %s -I %s -I %s -I %s `pkg-config --cflags glibmm-2.4` %s", + "%s %s -o %s -x c++ -c -fvisibility=hidden -I %s -I %s -I /usr/include/adhocutil -I %s -I %s -I %s `pkg-config --cflags glibmm-2.4` %s", cxx, cxxopts, out, tmpdir, slicerheaderdir, - headerdir.parent_path() / "libmisc", - headerdir / "lib", headerdir / "common", headerdir / "ice", headerdir / "daemon" / "lib", diff --git a/project2/ice/iceCompile.h b/project2/ice/iceCompile.h index 3c89f69..d771231 100644 --- a/project2/ice/iceCompile.h +++ b/project2/ice/iceCompile.h @@ -4,15 +4,15 @@ #include "options.h" #include <string> #include <set> -#include <boost/filesystem/path.hpp> +#include <filesystem> #include <boost/optional.hpp> class IceCompile { public: INITOPTIONS; - typedef boost::shared_ptr<IceCompile> Ptr; - typedef boost::shared_ptr<const IceCompile> CPtr; + typedef std::shared_ptr<IceCompile> Ptr; + typedef std::shared_ptr<const IceCompile> CPtr; typedef std::vector<Ptr> Deps; static std::string slice2cpp; @@ -21,12 +21,12 @@ class IceCompile { static std::string linker; static std::string cxxopts; static std::string linkeropts; - static boost::filesystem::path tmpdir; - static boost::filesystem::path headerdir; - static boost::filesystem::path slicerheaderdir; + static std::filesystem::path tmpdir; + static std::filesystem::path headerdir; + static std::filesystem::path slicerheaderdir; - IceCompile(const boost::filesystem::path & slice); - IceCompile(const boost::filesystem::path & slice, const Deps & deps); + IceCompile(const std::filesystem::path & slice); + IceCompile(const std::filesystem::path & slice, const Deps & deps); enum Steps { UpdateBuild = 0x1, @@ -36,29 +36,29 @@ class IceCompile { /// Conditionally execute Build, Compile, Link as required void Update(int steps = UpdateBuild | UpdateCompile | UpdateLink); /// Source file path (e.g. /some/path/slice.ice) - virtual boost::filesystem::path InputPath() const = 0; + virtual std::filesystem::path InputPath() const = 0; /// File name (no extension) in temporary directory (e.g. clientSlice) - virtual boost::filesystem::path OutputName(const std::string & type) const = 0; + virtual std::filesystem::path OutputName(const std::string & type) const = 0; typedef boost::shared_ptr<void> LibHandle; typedef std::set<LibHandle> LibHandles; LibHandles Open() const; protected: - virtual unsigned int Build(const boost::filesystem::path & in, const boost::filesystem::path & out) const = 0; - virtual unsigned int Count(const boost::filesystem::path & in) const = 0; - void BuildInteral(const boost::filesystem::path & in, const boost::filesystem::path & out); - void Compile(const boost::filesystem::path & in, const boost::filesystem::path & out); - void Link(const boost::filesystem::path & in, const boost::filesystem::path & out); + virtual unsigned int Build(const std::filesystem::path & in, const std::filesystem::path & out) const = 0; + virtual unsigned int Count(const std::filesystem::path & in) const = 0; + void BuildInteral(const std::filesystem::path & in, const std::filesystem::path & out); + void Compile(const std::filesystem::path & in, const std::filesystem::path & out); + void Link(const std::filesystem::path & in, const std::filesystem::path & out); - typedef void (IceCompile::*UpdateFunc)(const boost::filesystem::path & in, const boost::filesystem::path & out); - typedef void (IceCompile::*CountFunc)(const boost::filesystem::path & in); - void update(const boost::filesystem::path & in, const boost::filesystem::path & out, UpdateFunc func, CountFunc count = NULL); + typedef void (IceCompile::*UpdateFunc)(const std::filesystem::path & in, const std::filesystem::path & out); + typedef void (IceCompile::*CountFunc)(const std::filesystem::path & in); + void update(const std::filesystem::path & in, const std::filesystem::path & out, UpdateFunc func, CountFunc count = NULL); - const boost::filesystem::path slice; + const std::filesystem::path slice; private: - void countComponents(const boost::filesystem::path & in); + void countComponents(const std::filesystem::path & in); unsigned int components; LibHandle OpenLib() const; const Deps deps; diff --git a/project2/ice/iceConvert.h b/project2/ice/iceConvert.h index 93e531c..c22d655 100644 --- a/project2/ice/iceConvert.h +++ b/project2/ice/iceConvert.h @@ -3,27 +3,28 @@ #include <variableType.h> #include <IceUtil/Exception.h> -#include <IceUtil/Optional.h> +#include <Ice/Optional.h> +#include <visibility.h> template <typename IceType> -class IceConvert { +class DLL_PUBLIC IceConvert { public: static IceType FromVariable(const VariableType &); static VariableType ToVariable(const IceType &); }; template <typename IceOptionalType> -class IceConvert<IceUtil::Optional<IceOptionalType>> { +class DLL_PUBLIC IceConvert<Ice::optional<IceOptionalType>> { public: - static IceUtil::Optional<IceOptionalType> FromVariable(const VariableType & v) + static Ice::optional<IceOptionalType> FromVariable(const VariableType & v) { if (!boost::get<Null>(&v)) { return IceConvert<IceOptionalType>::FromVariable(v); } - return IceUtil::Optional<IceOptionalType>(); + return Ice::optional<IceOptionalType>(); } - static VariableType ToVariable(const IceUtil::Optional<IceOptionalType> & v) + static VariableType ToVariable(const Ice::optional<IceOptionalType> & v) { if (v) { return IceConvert<IceOptionalType>::ToVariable(*v); diff --git a/project2/ice/iceDaemon.cpp b/project2/ice/iceDaemon.cpp index 860cd86..4d0e091 100644 --- a/project2/ice/iceDaemon.cpp +++ b/project2/ice/iceDaemon.cpp @@ -7,7 +7,7 @@ #include <scriptLoader.h> #include <options.h> #include <sys/stat.h> -#include <boost/filesystem.hpp> +#include <filesystem> #include <boost/lexical_cast.hpp> #include <commonObjects.h> #include <logger.h> @@ -15,7 +15,6 @@ #include <views/flatView.h> #include <taskHost.h> #include <execContext.h> -#include <misc.h> #include <exceptions.h> #include "appInstance.h" @@ -25,14 +24,14 @@ std::string IceDaemon::viewRoot; std::string IceDaemon::taskRoot; IceBase::Libs IceDaemon::libs; -class IceDaemonLoader : public DaemonLoader::For<IceDaemon> { +class IceDaemonFactory : public DaemonFactory::For<IceDaemon>, public LifeCycle { public: void onConfigLoad() override { IceBase::FinaliseLoad(IceDaemon::libs); } }; -DECLARE_CUSTOM_COMPONENT_LOADER("ice", IceDaemon, IceDaemonLoader, DaemonLoader); +NAMEDPLUGIN("ice", IceDaemonFactory, DaemonFactory); DECLARE_OPTIONS(IceDaemon, "ICE Daemon Options") ("ice.daemon.viewRoot", Options::value(&viewRoot, "views"), "The folder in which to find view scripts") @@ -67,19 +66,24 @@ IceDaemon::shutdown() const } void -IceDaemon::run() const +IceDaemon::setup() const { Logger()->messagebf(LOG_DEBUG, " %s creating adapter %s [%s]...", __PRETTY_FUNCTION__, adapterName, adapterEndpoint); Ice::ObjectAdapterPtr adapter = ic->createObjectAdapterWithEndpoints(adapterName, adapterEndpoint); Logger()->messagebf(LOG_DEBUG, " %s installing servants...", __PRETTY_FUNCTION__); - InstanceSet<IceDaemonAdapterHandlerLoader>::OnAll([this, adapter](IceDaemonAdapterHandlerLoader * loader) { - loader->create(this)->add(adapter, ic); - }); + for(auto p : AdHoc::PluginManager::getDefault()->getAll<IceDaemonAdapterHandlerFactory>()) { + p->implementation()->create(shared_from_this())->add(adapter, ic); + } Logger()->messagebf(LOG_DEBUG, " %s starting...", __PRETTY_FUNCTION__); adapter->activate(); - +} + + +void +IceDaemon::run() const +{ Logger()->messagebf(LOG_INFO, " %s running...", __PRETTY_FUNCTION__); ic->waitForShutdown(); @@ -92,7 +96,7 @@ class IceDaemonViewHost : public virtual CommonObjects, public virtual CheckHost CommonObjects(s), CheckHost(s) { - s->script->loader.addLoadTarget(s, Storer::into<ElementLoader>(&view)); + s->script.lock()->loader.addLoadTarget(s, Storer::into<FlatViewFactory>(&view)); } void executeView(RowSetPresenterPtr presenter, ExecContext * ec) const { @@ -107,7 +111,7 @@ class IceDaemonViewHost : public virtual CommonObjects, public virtual CheckHost } } private: - typedef boost::intrusive_ptr<FlatView> ViewPtr; + typedef std::shared_ptr<FlatView> ViewPtr; ViewPtr view; }; @@ -120,7 +124,7 @@ class IceCallContext : public ExecContext { VariableType getParameter(const VariableType & key) const { - return safeMapLookup<ParamNotFound>(params, key); + return AdHoc::safeMapLookup<ParamNotFound>(params, key); } SessionPtr getSession() const @@ -137,9 +141,9 @@ void IceDaemon::executeView(const std::string & name, Slicer::ModelPartPtr p, const ParamMap & pm) const { ScriptNodePtr s = ScriptReader::resolveScript(IceDaemon::viewRoot, name, false)->root(); - boost::intrusive_ptr<IceDaemonViewHost> v = new IceDaemonViewHost(s); + auto v = std::make_shared<IceDaemonViewHost>(s); IceCallContext icc(pm); - v->executeView(new IceViewSerializer(p), &icc); + v->executeView(std::make_shared<IceViewSerializer>(p), &icc); } class IceDaemonTaskHost : public TaskHost { @@ -164,7 +168,7 @@ void IceDaemon::executeTask(const std::string & name, const ParamMap & pm) const { ScriptNodePtr s = ScriptReader::resolveScript(IceDaemon::taskRoot, name, false)->root(); - boost::intrusive_ptr<IceDaemonTaskHost> t = new IceDaemonTaskHost(s); + auto t = std::make_shared<IceDaemonTaskHost>(s); IceCallContext icc(pm); t->executeTask(&icc); } @@ -172,7 +176,7 @@ IceDaemon::executeTask(const std::string & name, const ParamMap & pm) const IceCompile::Ptr IceDaemon::GetComponentCompiler(const std::string & slice, const IceCompile::Deps & deps) { - return IceCompile::Ptr(new BuildDaemon(slice, deps)); + return std::make_shared<BuildDaemon>(slice, deps); } void diff --git a/project2/ice/iceDaemon.h b/project2/ice/iceDaemon.h index 3164699..70939a5 100644 --- a/project2/ice/iceDaemon.h +++ b/project2/ice/iceDaemon.h @@ -4,14 +4,16 @@ #include <daemon.h> #include "iceModule.h" #include "iceBase.h" +#include <visibility.h> -class IceDaemon : public Daemon, IceBase { +class DLL_PUBLIC IceDaemon : public Daemon, IceBase, public std::enable_shared_from_this<IceDaemon> { public: IceDaemon(int & argc, char ** argv); virtual ~IceDaemon(); - void run() const; - void shutdown() const; + void setup() const override; + void run() const override; + void shutdown() const override; void executeTask(const std::string & name, const ParamMap & params) const; void executeView(const std::string & name, Slicer::ModelPartPtr p, const ParamMap & params) const; diff --git a/project2/ice/iceDataSource.cpp b/project2/ice/iceDataSource.cpp index aa033fc..9a13f4c 100644 --- a/project2/ice/iceDataSource.cpp +++ b/project2/ice/iceDataSource.cpp @@ -21,7 +21,7 @@ int dummy = 0; IceDataSource::IceDataSource(ScriptNodePtr p) : DataSource(p), endpoint(p, "endpoint"), - ic(Ice::initialize(dummy, NULL)) + ic(Ice::initialize()) { Logger()->messagebf(LOG_DEBUG, "%s: endpoint: %s", __PRETTY_FUNCTION__, endpoint(NULL)); } @@ -34,7 +34,7 @@ IceDataSource::~IceDataSource() IceCompile::Ptr IceDataSource::GetComponentCompiler(const std::string & slice, const IceCompile::Deps & deps) { - return IceCompile::Ptr(new BuildClient(slice, deps)); + return std::make_shared<BuildClient>(slice, deps); } void @@ -44,12 +44,12 @@ IceDataSource::ClearSlice() libs.clear(); } -class IceDataSourceLoader : public ElementLoader::For<IceDataSource> { +class IceDataSourceFactory : public DataSourceFactory::For<IceDataSource>, public LifeCycle { public: void onConfigLoad() override { IceBase::FinaliseLoad(IceDataSource::libs); } }; -DECLARE_CUSTOM_LOADER("icedatasource", IceDataSourceLoader); +NAMEDPLUGIN("icedatasource", IceDataSourceFactory, DataSourceFactory); diff --git a/project2/ice/iceDataSource.h b/project2/ice/iceDataSource.h index 715f27b..83cc7c0 100644 --- a/project2/ice/iceDataSource.h +++ b/project2/ice/iceDataSource.h @@ -6,8 +6,9 @@ #include <variables.h> #include <Ice/Communicator.h> #include "iceBase.h" +#include <visibility.h> -class IceDataSource : public DataSource, IceBase { +class DLL_PUBLIC IceDataSource : public DataSource, IceBase { public: INITOPTIONS; @@ -15,15 +16,15 @@ class IceDataSource : public DataSource, IceBase { ~IceDataSource(); template <typename Interface> - Interface GetProxy(const std::string object, ExecContext * ec) const + std::shared_ptr<Interface> GetProxy(const std::string object, ExecContext * ec) const { auto existingProxy = proxies.find(object); if (existingProxy == proxies.end()) { - auto prx = Interface::checkedCast(ic->stringToProxy(object + ":" + endpoint(ec).as<std::string>())); + auto prx = Ice::checkedCast<Interface>(ic->stringToProxy(object + ":" + endpoint(ec).as<std::string>())); existingProxy = proxies.insert({ object, prx }).first; return prx; } - return Interface::checkedCast(existingProxy->second); + return Ice::checkedCast<Interface>(existingProxy->second); } const Ice::CommunicatorPtr GetCommunicator() const { return ic; } @@ -35,7 +36,7 @@ class IceDataSource : public DataSource, IceBase { const Variable endpoint; const Ice::CommunicatorPtr ic; - typedef std::map<std::string, Ice::ObjectPrx> Proxies; + typedef std::map<std::string, Ice::ObjectPrxPtr> Proxies; mutable Proxies proxies; }; diff --git a/project2/ice/iceModule.cpp b/project2/ice/iceModule.cpp index 7e39858..795103c 100644 --- a/project2/ice/iceModule.cpp +++ b/project2/ice/iceModule.cpp @@ -1,9 +1,13 @@ #include <pch.hpp> +#pragma GCC visibility push(default) #include "iceModule.h" #include "iceDaemon.h" -#include "instanceStore.impl.h" +#include <factory.impl.h> -IceDaemonModule::IceDaemonModule(const std::string & n, const IceDaemon * id) : +INSTANTIATEFACTORY(IceDaemonModule, std::shared_ptr<const IceDaemon>); +#pragma GCC visibility pop + +IceDaemonModule::IceDaemonModule(const std::string & n, const std::shared_ptr<const IceDaemon> & id) : name(n), iceDaemon(id) { @@ -20,16 +24,14 @@ IceDaemonModule::executeTask(const std::string & name, const ParamMap & params) } void -IceDaemonModule::add(Ice::ObjectAdapterPtr adapter, Ice::CommunicatorPtr ic) +IceDaemonModule::add(Ice::ObjectAdapterPtr adapter, Ice::CommunicatorPtr) { - adapter->add(this, ic->stringToIdentity(name)); + adapter->add(ICE_SHARED_FROM_THIS, Ice::stringToIdentity(name)); } void -IceDaemonModule::remove(Ice::ObjectAdapterPtr adapter, Ice::CommunicatorPtr ic) +IceDaemonModule::remove(Ice::ObjectAdapterPtr adapter, Ice::CommunicatorPtr) { - adapter->remove(ic->stringToIdentity(name)); + adapter->remove(Ice::stringToIdentity(name)); } -INSTANTIATESTORE(std::string, IceDaemonAdapterHandlerLoader); - diff --git a/project2/ice/iceModule.h b/project2/ice/iceModule.h index fcdd3e4..7e35afb 100644 --- a/project2/ice/iceModule.h +++ b/project2/ice/iceModule.h @@ -9,27 +9,29 @@ #include <boost/function.hpp> #include <slicer/modelParts.h> #include "iceConvert.h" +#include <factory.h> +#include <visibility.h> typedef std::map<std::string, VariableType> ParamMap; class IceDaemon; -class IceDaemonModule : virtual public ::Ice::Object { +class DLL_PUBLIC IceDaemonModule : virtual public ::Ice::Object, public std::enable_shared_from_this<IceDaemonModule> { public: void add(Ice::ObjectAdapterPtr, Ice::CommunicatorPtr); void remove(Ice::ObjectAdapterPtr, Ice::CommunicatorPtr); protected: - IceDaemonModule(const std::string &, const IceDaemon *); + IceDaemonModule(const std::string &, const std::shared_ptr<const IceDaemon> &); void executeTask(const std::string & name, const ParamMap & params) const; void executeView(const std::string & name, Slicer::ModelPartPtr p, const ParamMap & params) const; private: const std::string name; - const IceDaemon * const iceDaemon; + const std::shared_ptr<const IceDaemon> iceDaemon; }; -typedef GenLoader<IceDaemonModule, std::string, const IceDaemon *> IceDaemonAdapterHandlerLoader; +typedef AdHoc::Factory<IceDaemonModule, std::shared_ptr<const IceDaemon>> IceDaemonAdapterHandlerFactory; #endif diff --git a/project2/ice/iceRows.cpp b/project2/ice/iceRows.cpp index 6e2015d..7d38259 100644 --- a/project2/ice/iceRows.cpp +++ b/project2/ice/iceRows.cpp @@ -36,7 +36,7 @@ class IceRowState : public RowState { void AddColumn(unsigned int & c, const std::string & name) { - columns.insert(new Column(c++, name)); + columns.insert(std::make_shared<Column>(c++, name)); } const Columns & getColumns() const { return columns; } @@ -51,7 +51,7 @@ class IceRowState : public RowState { void AssignFieldValue(FieldValues::iterator & field, ModelPartPtr domp) { if (domp) { - domp->GetValue(new Assign(*field)); + domp->GetValue(Assign(*field)); } field++; } @@ -67,31 +67,33 @@ RowProcSerializer::RowProcSerializer(ExecContext * e, const RowProcessorCallback } void -RowProcSerializer::Serialize(ModelPartPtr mp) +RowProcSerializer::Serialize(ModelPartForRootPtr mp) { if (mp) { - switch (mp->GetType()) { - case mpt_Null: - return; - case mpt_Simple: - case mpt_Dictionary: - throw std::runtime_error("Not a sequence of things"); - case mpt_Complex: - { - IceRowState irs(ec, mp); - irs.IterateOver(mp, rpc); - break; - } - case mpt_Sequence: - { - IceRowState * irs = NULL; - mp->OnEachChild(boost::bind(&RowProcSerializer::SerializeRow, this, boost::ref(irs), _2)); - if (irs) { - delete irs; + mp->OnEachChild([this](const std::string &, ModelPartPtr mp, const HookCommon *) { + switch (mp->GetType()) { + case mpt_Null: + return; + case mpt_Simple: + case mpt_Dictionary: + throw std::runtime_error("Not a sequence of things"); + case mpt_Complex: + { + IceRowState irs(ec, mp); + irs.IterateOver(mp, rpc); + break; } - break; - } - } + case mpt_Sequence: + { + IceRowState * irs = NULL; + mp->OnEachChild(boost::bind(&RowProcSerializer::SerializeRow, this, boost::ref(irs), _2)); + if (irs) { + delete irs; + } + break; + } + } + }); } } diff --git a/project2/ice/iceRows.h b/project2/ice/iceRows.h index dc729ff..77507f2 100644 --- a/project2/ice/iceRows.h +++ b/project2/ice/iceRows.h @@ -6,14 +6,15 @@ #include "iceClient.h" #include <slicer/modelParts.h> #include <slicer/serializer.h> +#include <visibility.h> class IceRowState; -class RowProcSerializer : public Slicer::Serializer { +class DLL_PUBLIC RowProcSerializer : public Slicer::Serializer { public: RowProcSerializer(ExecContext *, const RowProcessorCallback &); - void Serialize(Slicer::ModelPartPtr) override; + void Serialize(Slicer::ModelPartForRootPtr) override; private: void SerializeRow(IceRowState * &, Slicer::ModelPartPtr); @@ -23,14 +24,16 @@ class RowProcSerializer : public Slicer::Serializer { }; template <typename Interface> -class IceRows : public RowSet, public IceClient<Interface> { +class DLL_PUBLIC IceRows : public RowSet, public IceClient<Interface> { public: IceRows(ScriptNodePtr p) : + SourceObject(p), RowSet(p), IceClient<Interface>(p) { } - void loadComplete(const CommonObjects * co) { + void loadComplete(const CommonObjects * co) override + { IceClient<Interface>::loadComplete(co); } }; diff --git a/project2/ice/iceTask.h b/project2/ice/iceTask.h index 2d71818..18e3b50 100644 --- a/project2/ice/iceTask.h +++ b/project2/ice/iceTask.h @@ -6,7 +6,7 @@ #include "iceClient.h" template <typename Interface> -class IceTask : public Task, public IceClient<Interface> { +class DLL_PUBLIC IceTask : public Task, public IceClient<Interface> { public: IceTask(ScriptNodePtr p) : SourceObject(p), @@ -15,7 +15,10 @@ class IceTask : public Task, public IceClient<Interface> { { } - void loadComplete(const CommonObjects * co) { IceClient<Interface>::loadComplete(co); } + void loadComplete(const CommonObjects * co) override + { + IceClient<Interface>::loadComplete(co); + } }; #endif diff --git a/project2/ice/iceViewSerializer.cpp b/project2/ice/iceViewSerializer.cpp index 7651fc1..4c68d3c 100644 --- a/project2/ice/iceViewSerializer.cpp +++ b/project2/ice/iceViewSerializer.cpp @@ -36,7 +36,7 @@ IceViewSerializer::addNamedValue(const Glib::ustring & name, const VariableType if (rowmpp) { ModelPartPtr field = rowmpp->GetChild(name); if (field) { - field->SetValue(new Assign(vt)); + field->SetValue(Assign(vt)); } else { Logger()->messagebf(LOG_INFO, "%s: Field not found", __PRETTY_FUNCTION__); diff --git a/project2/ice/iceViewSerializer.h b/project2/ice/iceViewSerializer.h index ff4188d..135a059 100644 --- a/project2/ice/iceViewSerializer.h +++ b/project2/ice/iceViewSerializer.h @@ -4,7 +4,7 @@ #include <slicer/modelParts.h> #include <presenter.h> -class IceViewSerializer : public RowSetPresenter { +class DLL_PUBLIC IceViewSerializer : public RowSetPresenter { public: IceViewSerializer(Slicer::ModelPartPtr mpp); diff --git a/project2/ice/iceboxDaemon.cpp b/project2/ice/iceboxDaemon.cpp new file mode 100644 index 0000000..502857e --- /dev/null +++ b/project2/ice/iceboxDaemon.cpp @@ -0,0 +1,78 @@ +#include <pch.hpp> +#include <IceBox/IceBox.h> +#include <Ice/Communicator.h> +#include <Ice/Logger.h> +#include <optionsSource.h> +#include <lifeCycle.h> +#include <daemon.h> +#include <thread> +#include <appInstance.h> +#include "iceboxOptionsSource.h" +#include "iceboxLogger.h" + +class IceBoxDaemon : public IceBox::Service, public AppInstance { + public: + IceBoxDaemon() + { + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onBegin, _1)); + } + + ~IceBoxDaemon() + { + LifeCycle::onAllComponents(boost::bind(&LifeCycle::onIdle, _1)); + } + + void start(const std::string &, const Ice::CommunicatorPtr & ic, const Ice::StringSeq &) + { + AdHoc::PluginManager::getDefault()->create<OptionsSource, IceBoxOptionsSource>("service", __FILE__, __LINE__, ic); + OptionsSource::loadSources([] { return reqPlatform;} ); + int argc = 0; + char ** argv = nullptr; + ic->getLogger()->print("Creating daemon: " + daemonType); + daemon = DaemonFactory::createNew(daemonType.raw(), argc, argv); + daemon->setup(); + daemonThread = new std::thread(&Daemon::run, daemon); + } + + void stop() + { + daemon->shutdown(); + daemonThread->join(); + delete daemonThread; + daemonThread = nullptr; + daemon->teardown(); + daemon.reset(); + } + + INITOPTIONS; + static Glib::ustring daemonType; + static Glib::ustring reqPlatform; + static int periodicTimeout; + + private: + DaemonPtr daemon; + std::thread * daemonThread; +}; + +Glib::ustring IceBoxDaemon::daemonType; +Glib::ustring IceBoxDaemon::reqPlatform; +int IceBoxDaemon::periodicTimeout; + +DECLARE_OPTIONS(IceBoxDaemon, "Project2 IceBox options") +("daemon.type", Options::value(&daemonType), "The core daemon module to run") +("daemon.platform", Options::value(&reqPlatform), "Platform") +("daemon.periodicTimeout", Options::value(&periodicTimeout, 60), + "Delay between occurrences of component periodic calls (default 60s)") +END_OPTIONS(IceBoxDaemon); + +extern "C" { + DLL_PUBLIC + IceBox::Service * + createProject2Daemon(Ice::CommunicatorPtr ic) + { + AdHoc::PluginManager::getDefault()->create<OptionsSource, IceBoxOptionsSource>("admin", __FILE__, __LINE__, ic); + AdHoc::PluginManager::getDefault()->create<LogDriverFactory, IceBoxLoggerFactory>("icebox", __FILE__, __LINE__, ic->getLogger()); + return new IceBoxDaemon(); + } +} + diff --git a/project2/ice/iceboxLogger.cpp b/project2/ice/iceboxLogger.cpp new file mode 100644 index 0000000..ba0749a --- /dev/null +++ b/project2/ice/iceboxLogger.cpp @@ -0,0 +1,58 @@ +#include <loggerFactory.impl.h> +#include "iceboxLogger.h" + +IceBoxLogDriver::IceBoxLogDriver(Ice::LoggerPtr l) : + logger(l) +{ +} + +void +IceBoxLogDriver::message(int priority, const char * msg) const +{ + if (priority <= level) { + if (priority >= LOG_DEBUG) { + logger->trace(debugCategory, msg); + } + else if (priority >= LOG_NOTICE) { + logger->print(msg); + } + else if (priority >= LOG_WARNING) { + logger->warning(msg); + } + else { + logger->error(msg); + } + } +} + +IceBoxLoggerFactory::IceBoxLoggerFactory(Ice::LoggerPtr l) : + logger(l) +{ +} + +std::shared_ptr<LogDriverBase> +IceBoxLoggerFactory::create() const +{ + if (!instance) { + instance = std::make_shared<IceBoxLogDriver>(logger); + } + return instance; +} + +DECLARE_OPTIONS(IceBoxLogDriver, "IceBox log options") +("icebox.log.level", Options::value(&level, LOG_WARNING), + "Log to IceBox with level <arg> (default LOG_WARNING)")("s") +("icebox.log.debugcategory", Options::value(&debugCategory, "Project2"), + "Category to use when writing to trace (default Project2)") +END_OPTIONS(IceBoxLogDriver); + +int IceBoxLogDriver::level; +std::string IceBoxLogDriver::debugCategory; + +template<> +std::shared_ptr<LogDriverBase> +LogDriverFactoryImpl<IceBoxLogDriver>::create() const +{ + return nullptr; +} + diff --git a/project2/ice/iceboxLogger.h b/project2/ice/iceboxLogger.h new file mode 100644 index 0000000..7369adc --- /dev/null +++ b/project2/ice/iceboxLogger.h @@ -0,0 +1,37 @@ +#ifndef ICEBOXLOGDRIVER_H +#define ICEBOXLOGDRIVER_H + +#include <Ice/Logger.h> +#include <loggerFactory.h> +#include <options.h> + +class DLL_PUBLIC IceBoxLogDriver : public LogDriverBase { + public: + IceBoxLogDriver(Ice::LoggerPtr l); + + void message(int priority, const char * msg) const override; + + INITOPTIONS; + static int level; + private: + Ice::LoggerPtr logger; + static std::string debugCategory; +}; + +class DLL_PUBLIC IceBoxLoggerFactory : public LogDriverFactoryImpl<IceBoxLogDriver> +{ + public: + IceBoxLoggerFactory(Ice::LoggerPtr l); + + std::shared_ptr<LogDriverBase> create() const override; + + private: + const Ice::LoggerPtr logger; +}; + +// Specialised as IceBoxLogDriver can't be defualt constructed. +template<> +std::shared_ptr<LogDriverBase> LogDriverFactoryImpl<IceBoxLogDriver>::create() const; + +#endif + diff --git a/project2/ice/iceboxOptionsSource.cpp b/project2/ice/iceboxOptionsSource.cpp new file mode 100644 index 0000000..90eca8e --- /dev/null +++ b/project2/ice/iceboxOptionsSource.cpp @@ -0,0 +1,25 @@ +#include "iceboxOptionsSource.h" + +IceBoxOptionsSource::IceBoxOptionsSource(Ice::CommunicatorPtr i) : + ic(i), + startTime(boost::posix_time::microsec_clock::universal_time()) +{ +} + +boost::posix_time::ptime +IceBoxOptionsSource::modifiedTime() const +{ + return startTime; +} + +void +IceBoxOptionsSource::loadInto(const ConfigConsumer & consume, const Options::CurrentPlatform & currentPlatform) const +{ + if (!ic) return; + auto props = ic->getProperties(); + if (!props) return; + for (auto & prop : props->getPropertiesForPrefix("project2")) { + consume(prop.first.substr(9), "", prop.second, currentPlatform); + } +} + diff --git a/project2/ice/iceboxOptionsSource.h b/project2/ice/iceboxOptionsSource.h new file mode 100644 index 0000000..3127fa4 --- /dev/null +++ b/project2/ice/iceboxOptionsSource.h @@ -0,0 +1,20 @@ +#ifndef PROJECT2_ICEBOX_OPTIONSSOURCE_H +#define PROJECT2_ICEBOX_OPTIONSSOURCE_H + +#include <optionsSource.h> +#include <Ice/Communicator.h> + +class IceBoxOptionsSource : public OptionsSource { + public: + IceBoxOptionsSource(Ice::CommunicatorPtr); + + void loadInto(const ConfigConsumer &, const Options::CurrentPlatform & platform) const; + boost::posix_time::ptime modifiedTime() const; + + private: + Ice::CommunicatorPtr ic; + boost::posix_time::ptime startTime; +}; + +#endif + diff --git a/project2/ice/pch.hpp b/project2/ice/pch.hpp index 3ed09f0..5c1187c 100644 --- a/project2/ice/pch.hpp +++ b/project2/ice/pch.hpp @@ -3,17 +3,13 @@ #define CGI_PCH #include <Ice/Ice.h> -#include <boost/filesystem.hpp> -#include <boost/function.hpp> +#include <filesystem> +#include <boost/function/function_fwd.hpp> #include <boost/optional.hpp> -#include <commonObjects.h> -#include <exceptions.h> -#include <logger.h> #include <map> -#include <options.h> #include <Slice/Parser.h> #include <string> -#include <variables.h> +#include <boost/variant/variant_fwd.hpp> #include <slicer/modelParts.h> #include <slicer/serializer.h> diff --git a/project2/ice/slice/Jamroot.jam b/project2/ice/slice/Jamroot.jam new file mode 100644 index 0000000..46b4e3c --- /dev/null +++ b/project2/ice/slice/Jamroot.jam @@ -0,0 +1,22 @@ +project ice : + : requirements + ; + +path-constant ice : ../../../ice ; + +lib Slice : + $(ice)/cpp/src/Slice/Parser.cpp + $(ice)/cpp/src/Slice/Grammar.cpp + $(ice)/cpp/src/Slice/Preprocessor.cpp + $(ice)/cpp/src/Slice/CPlusPlusUtil.cpp + $(ice)/cpp/src/Slice/SliceUtil.cpp + $(ice)/cpp/src/Slice/FileTracker.cpp + $(ice)/cpp/src/Slice/Scanner.cpp + : + <cxxflags>-fPIC + <include>$(ice)/cpp/src + <link>static + : : + <include>$(ice)/cpp/src + ; + diff --git a/project2/ice/slice2Common.cpp b/project2/ice/slice2Common.cpp index 9dfcf9f..c20b855 100644 --- a/project2/ice/slice2Common.cpp +++ b/project2/ice/slice2Common.cpp @@ -19,7 +19,7 @@ Slice2Common::FunctionBegin(Slice::OperationPtr o) // Create typed variables for call for (const auto & p : o->parameters()) { if (p->optional()) { - fprintf(code, "\t\t\t\t\t\tconst auto _%s = IceConvert< ::IceUtil::Optional< %s > >::FromVariable(%s(ec));\n", + fprintf(code, "\t\t\t\t\t\tconst auto _%s = IceConvert< ::Ice::optional< %s > >::FromVariable(%s(ec));\n", p->name().c_str(), Slice::typeToString(p->type()).c_str(), p->name().c_str()); @@ -59,10 +59,10 @@ Slice2Common::ParameterVariables(Slice::OperationPtr o) } void -Slice2Common::Declaration(Slice::OperationPtr o) +Slice2Common::Declaration(Slice::OperationPtr o, const std::string & base) { - fprintf(code, "\t\t\tDECLARE_LOADER(\"%s-%s-%s\", %s);\n\n", - module.c_str(), interface.c_str(), o->name().c_str(), o->name().c_str()); + fprintf(code, "\t\t\tNAMEDFACTORY(\"%s-%s-%s\", %s, %s);\n\n", + module.c_str(), interface.c_str(), o->name().c_str(), o->name().c_str(), base.c_str()); } void diff --git a/project2/ice/slice2Common.h b/project2/ice/slice2Common.h index 170f0e7..ec1b35c 100644 --- a/project2/ice/slice2Common.h +++ b/project2/ice/slice2Common.h @@ -2,14 +2,15 @@ #define SLICE2COMMON_H #include <Slice/Parser.h> +#include <visibility.h> -class Slice2Common : public Slice::ParserVisitor { +class DLL_PUBLIC Slice2Common : public Slice::ParserVisitor { public: Slice2Common(FILE * c); void FunctionBegin(Slice::OperationPtr o); void ParameterVariables(Slice::OperationPtr o); - void Declaration(Slice::OperationPtr o); + void Declaration(Slice::OperationPtr o, const std::string &); void CallOperation(Slice::OperationPtr o); unsigned int Components() const; diff --git a/project2/ice/slice2Daemon.cpp b/project2/ice/slice2Daemon.cpp index 177e406..78596fc 100644 --- a/project2/ice/slice2Daemon.cpp +++ b/project2/ice/slice2Daemon.cpp @@ -26,7 +26,7 @@ Slice2Daemon::visitClassDefStart(const Slice::ClassDefPtr & c) fprintf(code, "\tclass %sImpl : public IceDaemonModule, public %s {\n", c->name().c_str(), c->name().c_str()); fprintf(code, "\t\tpublic:\n"); - fprintf(code, "\t\t\t%sImpl(const IceDaemon * id) :\n", c->name().c_str()); + fprintf(code, "\t\t\t%sImpl(const std::shared_ptr<const IceDaemon> & id) :\n", c->name().c_str()); fprintf(code, "\t\t\t\tIceDaemonModule(\"%s%s\", id)\n", module.c_str(), c->name().c_str()); fprintf(code, "\t\t\t{\n\t\t\t}\n\n"); return true; @@ -44,13 +44,14 @@ Slice2Daemon::visitOperation(const Slice::OperationPtr & o) fprintf(code, "\t\t\tvoid %s(", o->name().c_str()); } for (const auto & p : o->parameters()) { - fprintf(code, "%s %s, ", inputTypeToString(p->type(), p->optional(), p->getMetaData(), 0).c_str(), p->name().c_str()); + fprintf(code, "const %s %s, ", typeToString(p->type(), p->optional(), p->scope(), + p->getMetaData(), Slice::TypeContextCpp11).c_str(), p->name().c_str()); } - fprintf(code, "const ::Ice::Current &) {\n"); + fprintf(code, "const ::Ice::Current &) override {\n"); visitParameterMap(o); if (o->returnType()) { fprintf(code, "\t\t\t\t%s rtn;\n", returnTypeToString(o->returnType(), o->returnIsOptional()).c_str()); - fprintf(code, "\t\t\t\tSlicer::ModelPartPtr mpp = Slicer::ModelPartFor(rtn);\n"); + fprintf(code, "\t\t\t\tSlicer::ModelPartPtr mpp = Slicer::ModelPart::CreateFor(rtn);\n"); fprintf(code, "\t\t\t\texecuteView(\"%s/%s/%s\", mpp, params);\n", module.c_str(), interface.c_str(), o->name().c_str()); fprintf(code, "\t\t\t\treturn rtn;\n"); } @@ -65,7 +66,7 @@ Slice2Daemon::visitClassDefEnd(const Slice::ClassDefPtr & c) { if (code) { fprintf(code, "\t}; // class %sImpl\n\n", c->name().c_str()); - fprintf(code, "\tDECLARE_GENERIC_LOADER(\"%s-%s\", IceDaemonAdapterHandlerLoader, %sImpl);\n\n", + fprintf(code, "\tNAMEDFACTORY(\"%s-%s\", %sImpl, IceDaemonAdapterHandlerFactory);\n\n", module.c_str(), c->name().c_str(), c->name().c_str()); } components += 1; diff --git a/project2/ice/slice2Rows.cpp b/project2/ice/slice2Rows.cpp index 8c67222..18757ab 100644 --- a/project2/ice/slice2Rows.cpp +++ b/project2/ice/slice2Rows.cpp @@ -44,6 +44,7 @@ Slice2Rows::visitOperation(const Slice::OperationPtr & o) fprintf(code, "\t\t\t\tpublic:\n"); // Constructor fprintf(code, "\t\t\t\t\t%s(ScriptNodePtr p) :\n", o->name().c_str()); + fprintf(code, "\t\t\t\t\t\tSourceObject(p),\n"); fprintf(code, "\t\t\t\t\t\tIceRows< ::%s::%sPrx >(p)", module.c_str(), interface.c_str()); for (const auto & p : o->parameters()) { fprintf(code, ",\n\t\t\t\t\t\t%s(p, \"%s\")", p->name().c_str(), p->name().c_str()); @@ -54,16 +55,16 @@ Slice2Rows::visitOperation(const Slice::OperationPtr & o) fprintf(code, "\t\t\t\t\tvoid execute(const Glib::ustring &, const RowProcessorCallback & rp, ExecContext * ec) const\n"); fprintf(code, "\t\t\t\t\t{\n"); FunctionBegin(o); - fprintf(code, "\t\t\t\t\t\tSlicer::SerializerPtr toRpc = new RowProcSerializer(ec, rp);\n"); + fprintf(code, "\t\t\t\t\t\tSlicer::SerializerPtr toRpc = std::make_shared<RowProcSerializer>(ec, rp);\n"); fprintf(code, "\t\t\t\t\t\tauto result = "); CallOperation(o); fprintf(code, ";\n"); - fprintf(code, "\t\t\t\t\t\tSlicer::ModelPartPtr mp = Slicer::ModelPartFor(result);\n"); + fprintf(code, "\t\t\t\t\t\tSlicer::ModelPartForRootPtr mp = Slicer::ModelPart::CreateRootFor(result);\n"); fprintf(code, "\t\t\t\t\t\ttoRpc->Serialize(mp);\n"); fprintf(code, "\t\t\t\t\t}\n\n"); ParameterVariables(o); fprintf(code, "\t\t\t};\n"); - Declaration(o); + Declaration(o, "RowSetFactory"); } } diff --git a/project2/ice/slice2Rows.h b/project2/ice/slice2Rows.h index c85e4b8..7417523 100644 --- a/project2/ice/slice2Rows.h +++ b/project2/ice/slice2Rows.h @@ -3,7 +3,7 @@ #include "slice2Common.h" -class Slice2Rows : public Slice2Common { +class DLL_PUBLIC Slice2Rows : public Slice2Common { public: Slice2Rows(FILE * c); diff --git a/project2/ice/slice2Task.cpp b/project2/ice/slice2Task.cpp index 84a4f29..f6dc58f 100644 --- a/project2/ice/slice2Task.cpp +++ b/project2/ice/slice2Task.cpp @@ -61,7 +61,7 @@ Slice2Task::visitOperation(const Slice::OperationPtr & o) fprintf(code, "\t\t\t\t\t}\n\n"); ParameterVariables(o); fprintf(code, "\t\t\t};\n"); - Declaration(o); + Declaration(o, "TaskFactory"); } } diff --git a/project2/ice/sliceCompile.cpp b/project2/ice/sliceCompile.cpp index b879965..83b5e65 100644 --- a/project2/ice/sliceCompile.cpp +++ b/project2/ice/sliceCompile.cpp @@ -1,29 +1,32 @@ #include <pch.hpp> #include "sliceCompile.h" -#include <scopeObject.h> +#include <scopeExit.h> #include <mutex> std::mutex slicePreprocessor; -SliceCompile::SliceCompile(const boost::filesystem::path & slice, const IceCompile::Deps & dep) : +SliceCompile::SliceCompile(const std::filesystem::path & slice, const IceCompile::Deps & dep) : IceCompile(slice, dep) { } unsigned int -SliceCompile::build(const boost::filesystem::path & in, FILE * out) const +SliceCompile::build(const std::filesystem::path & in, FILE * out) const { std::vector<std::string> cppArgs; std::lock_guard<std::mutex> lock(slicePreprocessor); Slice::PreprocessorPtr icecpp = Slice::Preprocessor::create("slice2project2", in.string(), cppArgs); FILE * cppHandle = icecpp->preprocess(false); - if (cppHandle == NULL) { + if (!cppHandle) { throw std::runtime_error("preprocess failed"); } Slice::UnitPtr u = Slice::Unit::createUnit(false, false, false, false); - ScopeObject uDestroy(boost::bind(&Slice::Unit::destroy, u.get())); + if (!u) { + throw std::runtime_error("create unit failed"); + } + AdHoc::ScopeExit uDestroy(boost::bind(&Slice::Unit::destroy, u.get())); int parseStatus = u->parse(in.string(), cppHandle, false); @@ -44,7 +47,7 @@ SliceCompile::build(const boost::filesystem::path & in, FILE * out) const } unsigned int -SliceCompile::Build(const boost::filesystem::path & in, const boost::filesystem::path & outpath) const +SliceCompile::Build(const std::filesystem::path & in, const std::filesystem::path & outpath) const { FILE * out = fopen(outpath.string().c_str(), "w"); if (!out) { @@ -61,7 +64,7 @@ SliceCompile::Build(const boost::filesystem::path & in, const boost::filesystem: } unsigned int -SliceCompile::Count(const boost::filesystem::path & in) const +SliceCompile::Count(const std::filesystem::path & in) const { return build(in, NULL); } @@ -71,7 +74,7 @@ SliceCompile::Headers(FILE *) const { } -boost::filesystem::path +std::filesystem::path SliceCompile::InputPath() const { return slice; diff --git a/project2/ice/sliceCompile.h b/project2/ice/sliceCompile.h index d8e8e32..39d7948 100644 --- a/project2/ice/sliceCompile.h +++ b/project2/ice/sliceCompile.h @@ -5,20 +5,21 @@ #include <string> #include <Slice/Parser.h> #include <Slice/Preprocessor.h> +#include <visibility.h> -class SliceCompile : public IceCompile { +class DLL_PUBLIC SliceCompile : public IceCompile { public: - SliceCompile(const boost::filesystem::path & slice, const IceCompile::Deps & dep); + SliceCompile(const std::filesystem::path & slice, const IceCompile::Deps & dep); - unsigned int Count(const boost::filesystem::path & in) const; - unsigned int Build(const boost::filesystem::path & in, const boost::filesystem::path & out) const; + unsigned int Count(const std::filesystem::path & in) const; + unsigned int Build(const std::filesystem::path & in, const std::filesystem::path & out) const; virtual void Headers(FILE *) const; virtual unsigned int Body(FILE *, Slice::UnitPtr) const = 0; - boost::filesystem::path InputPath() const; + std::filesystem::path InputPath() const; private: - unsigned int build(const boost::filesystem::path & in, FILE *) const; + unsigned int build(const std::filesystem::path & in, FILE *) const; }; #endif diff --git a/project2/ice/unittests/Jamfile.jam b/project2/ice/unittests/Jamfile.jam index 8e83b1c..dfbff73 100644 --- a/project2/ice/unittests/Jamfile.jam +++ b/project2/ice/unittests/Jamfile.jam @@ -5,11 +5,11 @@ lib unittestc : : <slicer>yes <library>..//slicer - <variant>component + <library>..//Ice + <library>..//pthread <include>.. - <include>../../common - <include>../../lib - <include>../../../libmisc + <library>../../common//p2common + <include>/usr/include/adhocutil <library>..//glibmm : : <include>. @@ -20,7 +20,9 @@ lib unittest : : <slicer>no <library>..//slicer - <variant>component + <library>..//Ice + <library>..//pthread + <include>/usr/include/adhocutil : : <include>. <library>..//pthread @@ -31,7 +33,9 @@ lib unittestr : : <slicer>yes <library>..//slicer - <variant>component + <library>..//Ice + <library>..//pthread + <include>/usr/include/adhocutil : : <include>. <library>..//pthread @@ -39,9 +43,9 @@ lib unittestr : path-constant me : . ; -unit-test testClientCompile : +run [ glob testClientCompile.cpp ] - : + : : unittest unittestr : <define>ROOT=\"$(me)\" <dependency>unittest.ice <dependency>unittest @@ -50,32 +54,35 @@ unit-test testClientCompile : <library>../../ut//p2ut <library>../../basics//p2basics <library>..//Ice - <library>..//IceUtil - <library>..//boost_filesystem + <library>..//stdc++fs <dependency>testClient.xml + : + testClientCompile : ; -unit-test testClient : +run [ glob testClient.cpp ] - : + : : : <define>ROOT=\"$(me)\" <dependency>unittest.ice <library>unittestr <library>unittestc <implicit-dependency>unittestr + <implicit-dependency>unittestc <library>..//p2iceclient <library>../../ut//p2ut <library>../../xml//p2xml <library>../../basics//p2basics <library>..//Ice - <library>..//IceUtil - <library>..//boost_filesystem + <library>..//stdc++fs <dependency>testClient.xml + : + testClient : ; -unit-test testDaemonCompile : +run [ glob testDaemonCompile.cpp ] - : + : : unittest unittestr : <define>ROOT=\"$(me)\" <dependency>unittest.ice <dependency>unittest @@ -84,25 +91,26 @@ unit-test testDaemonCompile : <library>../../ut//p2ut <library>../../basics//p2basics <library>..//Ice - <library>..//IceUtil - <library>..//boost_filesystem + <library>..//stdc++fs + : + testDaemonCompile : ; -unit-test testDaemon : +run [ glob testDaemon.cpp ] - : + : : : <define>ROOT=\"$(me)\" <dependency>unittest.ice <library>unittestr <library>unittestc <implicit-dependency>unittestr + <implicit-dependency>unittestc <library>..//p2icedaemon <library>../../ut//p2ut <library>../../xml//p2xml <library>../../basics//p2basics <library>..//Ice - <library>..//IceUtil - <library>..//boost_filesystem + <library>..//stdc++fs <dependency>data/unittest-data.xml <dependency>lib/testrows.xml <dependency>tasks/UnitTest/SimpleInterface/SomeTask.xml @@ -111,5 +119,15 @@ unit-test testDaemon : <dependency>views/UnitTest/SimpleInterface/SomeRowsParams.xml <dependency>views/UnitTestComplex/ComplexInterface/ComplexRow.xml <dependency>tasks/UnitTestComplex/ComplexInterface/ComplexParam.xml + : + testDaemon : ; +run + testIceBoxDaemon.cpp + : : : + <library>..//p2icebox++11 + <library>../../ut//p2ut + : + testIceBoxDaemon + ; diff --git a/project2/ice/unittests/conversions.cpp b/project2/ice/unittests/conversions.cpp index e6be3f8..92620f1 100644 --- a/project2/ice/unittests/conversions.cpp +++ b/project2/ice/unittests/conversions.cpp @@ -3,6 +3,7 @@ #include <logger.h> namespace Slicer { + DLL_PUBLIC boost::posix_time::ptime dateTimeToPTime(const UnitTestComplex::DatePtr & dt) { @@ -12,21 +13,23 @@ namespace Slicer { boost::posix_time::time_duration(dt->hours, dt->minutes, dt->seconds)); } + DLL_PUBLIC UnitTestComplex::DatePtr ptimeToDateTime(const boost::posix_time::ptime & pt) { Logger()->messagebf(LOG_DEBUG, "%s", __PRETTY_FUNCTION__); - return new UnitTestComplex::Date { + return std::make_shared<UnitTestComplex::Date>( pt.date().year(), pt.date().month(), pt.date().day(), - pt.time_of_day().hours(), - pt.time_of_day().minutes(), - pt.time_of_day().seconds() }; + (Ice::Int)pt.time_of_day().hours(), + (Ice::Int)pt.time_of_day().minutes(), + (Ice::Int)pt.time_of_day().seconds()); } } template<> +DLL_PUBLIC ::UnitTestComplex::DatePtr IceConvert< ::UnitTestComplex::DatePtr >::FromVariable(const VariableType & vt) { @@ -35,6 +38,7 @@ IceConvert< ::UnitTestComplex::DatePtr >::FromVariable(const VariableType & vt) } template<> +DLL_PUBLIC VariableType IceConvert< ::UnitTestComplex::DatePtr >::ToVariable(const ::UnitTestComplex::DatePtr & d) { diff --git a/project2/ice/unittests/testClient.cpp b/project2/ice/unittests/testClient.cpp index 55663a0..814a4d4 100644 --- a/project2/ice/unittests/testClient.cpp +++ b/project2/ice/unittests/testClient.cpp @@ -1,6 +1,6 @@ #define BOOST_TEST_MODULE Client #include <boost/test/unit_test.hpp> -#include <boost/filesystem/operations.hpp> +#include <filesystem> #include "iceClient.h" #include <Ice/ObjectAdapter.h> #include <Ice/Service.h> @@ -10,16 +10,15 @@ #include <scripts.h> #include <xmlScriptParser.h> #include <testScriptHost.h> -#include <scopeObject.h> +#include <scopeExit.h> #include <unittest.h> #include <unittestComplex.h> #include <testAppInstance.h> #define XSTR(s) STR(s) #define STR(s) #s -const auto bindir = boost::filesystem::canonical("/proc/self/exe").parent_path(); -const auto componentdir = bindir.parent_path() / "component"; -const boost::filesystem::path iceroot(XSTR(ROOT)); +const auto bindir = std::filesystem::canonical("/proc/self/exe").parent_path(); +const std::filesystem::path iceroot(XSTR(ROOT)); const auto headers = iceroot.parent_path().parent_path(); BOOST_TEST_DONT_PRINT_LOG_VALUE( ::UnitTestComplex::Date ); @@ -33,25 +32,25 @@ class Dummy : public UnitTest::SimpleInterface { UnitTest::SimplePtr SingleRow(const Ice::Current&) { - return new UnitTest::Simple { 3, "single" }; + return std::make_shared<UnitTest::Simple>( 3, "single" ); } UnitTest::Simples SomeRows(const Ice::Current&) { UnitTest::Simples rtn { - new UnitTest::Simple { 1, "test a" }, - new UnitTest::Simple { 2, "test b" } + std::make_shared<UnitTest::Simple>( 1, "test a" ), + std::make_shared<UnitTest::Simple>( 2, "test b" ) }; execCount += 1; return rtn; } - UnitTest::Simples SomeRowsParams(Ice::Int pi, const std::string & ps, const Ice::Current&) + UnitTest::Simples SomeRowsParams(Ice::Int pi, const std::string ps, const Ice::Current&) { UnitTest::Simples rtn { - new UnitTest::Simple { 0, "before" }, - new UnitTest::Simple { pi, ps }, - new UnitTest::Simple { 2, "after" } + std::make_shared<UnitTest::Simple>( 0, "before" ), + std::make_shared<UnitTest::Simple>( pi, ps ), + std::make_shared<UnitTest::Simple>( 2, "after" ) }; execCount += 1; return rtn; @@ -62,7 +61,7 @@ class Dummy : public UnitTest::SimpleInterface { execCount += 1; } - void SomeTaskParams(Ice::Int a, const std::string & b, const Ice::Current&) + void SomeTaskParams(Ice::Int a, const std::string b, const Ice::Current&) { BOOST_REQUIRE_EQUAL(a, 1); BOOST_REQUIRE_EQUAL(b, "first"); @@ -81,10 +80,10 @@ class DummyComplex : public UnitTestComplex::ComplexInterface { UnitTestComplex::ComplexPtr ComplexRow(const Ice::Current&) { - return new UnitTestComplex::Complex { 3, "single", new UnitTestComplex::Date { 1980, 7, 9, 1, 2, 3 } }; + return std::make_shared<UnitTestComplex::Complex>( 3, "single", std::make_shared<UnitTestComplex::Date>(1980, 7, 9, 1, 2, 3) ); } - void ComplexParam(Ice::Int a, const std::string & b, const UnitTestComplex::DatePtr & d, const Ice::Current&) + void ComplexParam(Ice::Int a, const std::string b, const UnitTestComplex::DatePtr d, const Ice::Current&) { BOOST_REQUIRE_EQUAL(a, 1); BOOST_REQUIRE_EQUAL(b, "first"); @@ -106,30 +105,29 @@ void commonTests(ExecContext * ec) { BOOST_TEST_CHECKPOINT("Verify loaded"); - BOOST_REQUIRE(ElementLoader::getFor("UnitTest-SimpleInterface-SomeTask")); - BOOST_REQUIRE(ElementLoader::getFor("UnitTest-SimpleInterface-SomeTaskParams")); - BOOST_REQUIRE(ElementLoader::getFor("UnitTest-SimpleInterface-SingleRow")); - BOOST_REQUIRE(ElementLoader::getFor("UnitTest-SimpleInterface-SomeRows")); - BOOST_REQUIRE(ElementLoader::getFor("UnitTest-SimpleInterface-SomeRowsParams")); - BOOST_REQUIRE(ElementLoader::getFor("UnitTestComplex-ComplexInterface-ComplexParam")); - BOOST_REQUIRE(ElementLoader::getFor("UnitTestComplex-ComplexInterface-ComplexRow")); + BOOST_REQUIRE(TaskFactory::get("UnitTest-SimpleInterface-SomeTask")); + BOOST_REQUIRE(TaskFactory::get("UnitTest-SimpleInterface-SomeTaskParams")); + BOOST_REQUIRE(RowSetFactory::get("UnitTest-SimpleInterface-SingleRow")); + BOOST_REQUIRE(RowSetFactory::get("UnitTest-SimpleInterface-SomeRows")); + BOOST_REQUIRE(RowSetFactory::get("UnitTest-SimpleInterface-SomeRowsParams")); + BOOST_REQUIRE(TaskFactory::get("UnitTestComplex-ComplexInterface-ComplexParam")); + BOOST_REQUIRE(RowSetFactory::get("UnitTestComplex-ComplexInterface-ComplexRow")); BOOST_TEST_CHECKPOINT("Load test script"); - ScriptReaderPtr r = new XmlScriptParser(iceroot / "testClient.xml"); + ScriptReaderPtr r = std::make_shared<XmlScriptParser>(iceroot / "testClient.xml"); BOOST_TEST_CHECKPOINT("Initialize ICE service"); - int paramCount = 0; - Ice::CommunicatorPtr ic = Ice::initialize(paramCount, NULL); + Ice::CommunicatorPtr ic = Ice::initialize(); auto adapter = ic->createObjectAdapterWithEndpoints("Adp", "tcp -p 12000"); - IceUtil::Handle<Dummy> dummy = new Dummy(); - IceUtil::Handle<DummyComplex> dummyComplex = new DummyComplex(); - adapter->add(dummy, ic->stringToIdentity("testObject")); - adapter->add(dummyComplex, ic->stringToIdentity("testObjectComplex")); + auto dummy = std::make_shared<Dummy>(); + auto dummyComplex = std::make_shared<DummyComplex>(); + adapter->add(dummy, Ice::stringToIdentity("testObject")); + adapter->add(dummyComplex, Ice::stringToIdentity("testObjectComplex")); adapter->activate(); - ScopeObject _([&ic]{ ic->destroy(); }); + AdHoc::ScopeExit _([&ic]{ ic->destroy(); }); BOOST_TEST_CHECKPOINT("Execute test script"); - boost::intrusive_ptr<TestScriptHost> sr = new TestScriptHost(r); + auto sr = std::make_shared<TestScriptHost>(r); BOOST_REQUIRE_EQUAL(dummy->execCount, 0); BOOST_REQUIRE_EQUAL(dummyComplex->execCount, 0); sr->process(ec); @@ -143,33 +141,33 @@ void unloadTests() { BOOST_TEST_CHECKPOINT("Verify unloaded"); - BOOST_REQUIRE_THROW(ElementLoader::getFor("UnitTest-SimpleInterface-SomeTask"), NotSupported); - BOOST_REQUIRE_THROW(ElementLoader::getFor("UnitTest-SimpleInterface-SomeTaskParams"), NotSupported); - BOOST_REQUIRE_THROW(ElementLoader::getFor("UnitTest-SimpleInterface-SingleRow"), NotSupported); - BOOST_REQUIRE_THROW(ElementLoader::getFor("UnitTest-SimpleInterface-SomeRows"), NotSupported); - BOOST_REQUIRE_THROW(ElementLoader::getFor("UnitTest-SimpleInterface-SomeRowsParams"), NotSupported); - BOOST_REQUIRE_THROW(ElementLoader::getFor("UnitTestComplex-ComplexInterface-ComplexParam"), NotSupported); - BOOST_REQUIRE_THROW(ElementLoader::getFor("UnitTestComplex-ComplexInterface-ComplexRow"), NotSupported); + BOOST_REQUIRE_THROW(TaskFactory::get("UnitTest-SimpleInterface-SomeTask"), AdHoc::NoSuchPluginException); + BOOST_REQUIRE_THROW(TaskFactory::get("UnitTest-SimpleInterface-SomeTaskParams"), AdHoc::NoSuchPluginException); + BOOST_REQUIRE_THROW(RowSetFactory::get("UnitTest-SimpleInterface-SingleRow"), AdHoc::NoSuchPluginException); + BOOST_REQUIRE_THROW(RowSetFactory::get("UnitTest-SimpleInterface-SomeRows"), AdHoc::NoSuchPluginException); + BOOST_REQUIRE_THROW(RowSetFactory::get("UnitTest-SimpleInterface-SomeRowsParams"), AdHoc::NoSuchPluginException); + BOOST_REQUIRE_THROW(TaskFactory::get("UnitTestComplex-ComplexInterface-ComplexParam"), AdHoc::NoSuchPluginException); + BOOST_REQUIRE_THROW(RowSetFactory::get("UnitTestComplex-ComplexInterface-ComplexRow"), AdHoc::NoSuchPluginException); } -void test_client_run(ExecContext *, const boost::filesystem::path & tmpdir); +void test_client_run(ExecContext *, const std::filesystem::path & tmpdir); BOOST_FIXTURE_TEST_SUITE( Core, TestAppInstance ); BOOST_AUTO_TEST_CASE( test_client ) { - const boost::filesystem::path tmpdir = "/tmp/ut/project2.slice-client"; + const std::filesystem::path tmpdir = "/tmp/ut/project2.slice-client"; BOOST_TEST_CHECKPOINT("Clean up"); - boost::filesystem::remove_all(tmpdir); + std::filesystem::remove_all(tmpdir); test_client_run(this, tmpdir); test_client_run(this, tmpdir); - boost::filesystem::remove_all(tmpdir); + std::filesystem::remove_all(tmpdir); } BOOST_AUTO_TEST_SUITE_END(); -void test_client_run(ExecContext * ec, const boost::filesystem::path & tmpdir) +void test_client_run(ExecContext * ec, const std::filesystem::path & tmpdir) { BOOST_TEST_CHECKPOINT("Configure, compile, link, load"); TestOptionsSource::LoadTestOptions({ @@ -180,16 +178,16 @@ void test_client_run(ExecContext * ec, const boost::filesystem::path & tmpdir) { "ice.client.slicerclient", (iceroot / "unittestTypes.ice").string() }, { "ice.client.slicerclient", (iceroot / "unittest.ice").string() } }); - BOOST_REQUIRE(!boost::filesystem::exists(tmpdir / "unittest.so")); - BOOST_REQUIRE(boost::filesystem::exists(tmpdir / "unittest.client.so")); - BOOST_REQUIRE(!boost::filesystem::exists(tmpdir / "unittestTypes.so")); - BOOST_REQUIRE(!boost::filesystem::exists(tmpdir / "unittestTypes.client.so")); - BOOST_REQUIRE(!boost::filesystem::exists(tmpdir / "unittestComplex.so")); - BOOST_REQUIRE(boost::filesystem::exists(tmpdir / "unittestComplex.client.so")); + BOOST_REQUIRE(!std::filesystem::exists(tmpdir / "unittest.so")); + BOOST_REQUIRE(std::filesystem::exists(tmpdir / "unittest.client.so")); + BOOST_REQUIRE(!std::filesystem::exists(tmpdir / "unittestTypes.so")); + BOOST_REQUIRE(!std::filesystem::exists(tmpdir / "unittestTypes.client.so")); + BOOST_REQUIRE(!std::filesystem::exists(tmpdir / "unittestComplex.so")); + BOOST_REQUIRE(std::filesystem::exists(tmpdir / "unittestComplex.client.so")); commonTests(ec); TestOptionsSource::LoadTestOptions({ }); unloadTests(); - boost::filesystem::remove_all(tmpdir); + std::filesystem::remove_all(tmpdir); } diff --git a/project2/ice/unittests/testClientCompile.cpp b/project2/ice/unittests/testClientCompile.cpp index ef4b0ea..72df095 100644 --- a/project2/ice/unittests/testClientCompile.cpp +++ b/project2/ice/unittests/testClientCompile.cpp @@ -1,20 +1,18 @@ #define BOOST_TEST_MODULE ClientCompile #include <boost/test/unit_test.hpp> -#include <boost/filesystem/operations.hpp> +#include <filesystem> #include "iceClient.h" #include <testOptionsSource.h> #include <task.h> #include <exceptions.h> #include <scripts.h> #include <testScriptHost.h> -#include <scopeObject.h> #include <testAppInstance.h> #define XSTR(s) STR(s) #define STR(s) #s -const auto bindir = boost::filesystem::canonical("/proc/self/exe").parent_path(); -const auto componentdir = bindir.parent_path() / "component"; -const boost::filesystem::path iceroot(XSTR(ROOT)); +const auto bindir = std::filesystem::canonical("/proc/self/exe").parent_path(); +const std::filesystem::path iceroot(XSTR(ROOT)); const auto headers = iceroot.parent_path().parent_path(); static @@ -22,11 +20,11 @@ void commonTests() { BOOST_TEST_CHECKPOINT("Verify loaded"); - BOOST_REQUIRE(ElementLoader::getFor("UnitTest-SimpleInterface-SomeTask")); - BOOST_REQUIRE(ElementLoader::getFor("UnitTest-SimpleInterface-SomeTaskParams")); - BOOST_REQUIRE(ElementLoader::getFor("UnitTest-SimpleInterface-SingleRow")); - BOOST_REQUIRE(ElementLoader::getFor("UnitTest-SimpleInterface-SomeRows")); - BOOST_REQUIRE(ElementLoader::getFor("UnitTest-SimpleInterface-SomeRowsParams")); + BOOST_REQUIRE(TaskFactory::get("UnitTest-SimpleInterface-SomeTask")); + BOOST_REQUIRE(TaskFactory::get("UnitTest-SimpleInterface-SomeTaskParams")); + BOOST_REQUIRE(RowSetFactory::get("UnitTest-SimpleInterface-SingleRow")); + BOOST_REQUIRE(RowSetFactory::get("UnitTest-SimpleInterface-SomeRows")); + BOOST_REQUIRE(RowSetFactory::get("UnitTest-SimpleInterface-SomeRowsParams")); } static @@ -34,11 +32,11 @@ void unloadTests() { BOOST_TEST_CHECKPOINT("Verify unloaded"); - BOOST_REQUIRE_THROW(ElementLoader::getFor("UnitTest-SimpleInterface-SomeTask"), NotSupported); - BOOST_REQUIRE_THROW(ElementLoader::getFor("UnitTest-SimpleInterface-SomeTaskParams"), NotSupported); - BOOST_REQUIRE_THROW(ElementLoader::getFor("UnitTest-SimpleInterface-SingleRow"), NotSupported); - BOOST_REQUIRE_THROW(ElementLoader::getFor("UnitTest-SimpleInterface-SomeRows"), NotSupported); - BOOST_REQUIRE_THROW(ElementLoader::getFor("UnitTest-SimpleInterface-SomeRowsParams"), NotSupported); + BOOST_REQUIRE_THROW(TaskFactory::get("UnitTest-SimpleInterface-SomeTask"), AdHoc::NoSuchPluginException); + BOOST_REQUIRE_THROW(TaskFactory::get("UnitTest-SimpleInterface-SomeTaskParams"), AdHoc::NoSuchPluginException); + BOOST_REQUIRE_THROW(RowSetFactory::get("UnitTest-SimpleInterface-SingleRow"), AdHoc::NoSuchPluginException); + BOOST_REQUIRE_THROW(RowSetFactory::get("UnitTest-SimpleInterface-SomeRows"), AdHoc::NoSuchPluginException); + BOOST_REQUIRE_THROW(RowSetFactory::get("UnitTest-SimpleInterface-SomeRowsParams"), AdHoc::NoSuchPluginException); } BOOST_FIXTURE_TEST_SUITE( Core, TestAppInstance ); @@ -47,9 +45,9 @@ BOOST_AUTO_TEST_CASE( compile_client_full ) { TestOptionsSource::LoadTestOptions({ }); - const boost::filesystem::path tmpdir = "/tmp/ut/project2.slice-clientCompile/full"; + const std::filesystem::path tmpdir = "/tmp/ut/project2.slice-clientCompile/full"; BOOST_TEST_CHECKPOINT("Clean up"); - boost::filesystem::remove_all(tmpdir); + std::filesystem::remove_all(tmpdir); BOOST_TEST_CHECKPOINT("Configure, compile, link, load"); TestOptionsSource::LoadTestOptions({ @@ -59,68 +57,68 @@ BOOST_AUTO_TEST_CASE( compile_client_full ) { "ice.client.slice", (iceroot / "unittestTypes.ice").string() }, { "ice.client.slice", (iceroot / "unittest.ice").string() } }); - BOOST_REQUIRE(boost::filesystem::exists(tmpdir / "unittest.so")); - BOOST_REQUIRE(boost::filesystem::exists(tmpdir / "unittest.client.so")); - BOOST_REQUIRE(boost::filesystem::exists(tmpdir / "unittestTypes.so")); - BOOST_REQUIRE(!boost::filesystem::exists(tmpdir / "unittestTypes.client.so")); + BOOST_REQUIRE(std::filesystem::exists(tmpdir / "unittest.so")); + BOOST_REQUIRE(std::filesystem::exists(tmpdir / "unittest.client.so")); + BOOST_REQUIRE(std::filesystem::exists(tmpdir / "unittestTypes.so")); + BOOST_REQUIRE(!std::filesystem::exists(tmpdir / "unittestTypes.client.so")); commonTests(); TestOptionsSource::LoadTestOptions({ }); unloadTests(); - boost::filesystem::remove_all(tmpdir); + std::filesystem::remove_all(tmpdir); } BOOST_AUTO_TEST_CASE( compile_client_clientOnly ) { - const boost::filesystem::path tmpdir = "/tmp/ut/project2.slice-clientCompile/clientOnly"; + const std::filesystem::path tmpdir = "/tmp/ut/project2.slice-clientCompile/clientOnly"; BOOST_TEST_CHECKPOINT("Clean up"); - boost::filesystem::remove_all(tmpdir); + std::filesystem::remove_all(tmpdir); BOOST_TEST_CHECKPOINT("Configure, compile, link, load"); TestOptionsSource::LoadTestOptions({ - { "library", (componentdir / "libunittest.so").string() }, + { "library", args[1] }, { "common.datasourceRoot", iceroot.string() }, { "ice.compile.tmpdir", tmpdir.string() }, { "ice.compile.headers", headers.string() }, { "ice.client.sliceclient", (iceroot / "unittestTypes.ice").string() }, { "ice.client.sliceclient", (iceroot / "unittest.ice").string() } }); - BOOST_REQUIRE(!boost::filesystem::exists(tmpdir / "unittest.so")); - BOOST_REQUIRE(boost::filesystem::exists(tmpdir / "unittest.client.so")); - BOOST_REQUIRE(boost::filesystem::exists(tmpdir / "unittestTypes.so")); - BOOST_REQUIRE(!boost::filesystem::exists(tmpdir / "unittestTypes.client.so")); + BOOST_REQUIRE(!std::filesystem::exists(tmpdir / "unittest.so")); + BOOST_REQUIRE(std::filesystem::exists(tmpdir / "unittest.client.so")); + BOOST_REQUIRE(std::filesystem::exists(tmpdir / "unittestTypes.so")); + BOOST_REQUIRE(!std::filesystem::exists(tmpdir / "unittestTypes.client.so")); commonTests(); TestOptionsSource::LoadTestOptions({ }); unloadTests(); - boost::filesystem::remove_all(tmpdir); + std::filesystem::remove_all(tmpdir); } BOOST_AUTO_TEST_CASE( compile_client_slicer ) { TestOptionsSource::LoadTestOptions({ }); - const boost::filesystem::path tmpdir = "/tmp/ut/project2.slice-clientCompile/slicer"; + const std::filesystem::path tmpdir = "/tmp/ut/project2.slice-clientCompile/slicer"; BOOST_TEST_CHECKPOINT("Clean up"); - boost::filesystem::remove_all(tmpdir); + std::filesystem::remove_all(tmpdir); BOOST_TEST_CHECKPOINT("Configure, compile, link, load"); TestOptionsSource::LoadTestOptions({ - { "library", (componentdir / "slicer-yes" / "libunittestr.so").string() }, + { "library", args[2] }, { "common.datasourceRoot", iceroot.string() }, { "ice.compile.tmpdir", tmpdir.string() }, { "ice.compile.headers", headers.string() }, { "ice.client.slicerclient", (iceroot / "unittestTypes.ice").string() }, { "ice.client.slicerclient", (iceroot / "unittest.ice").string() } }); - BOOST_REQUIRE(!boost::filesystem::exists(tmpdir / "unittest.so")); - BOOST_REQUIRE(boost::filesystem::exists(tmpdir / "unittest.client.so")); - BOOST_REQUIRE(!boost::filesystem::exists(tmpdir / "unittestTypes.so")); - BOOST_REQUIRE(!boost::filesystem::exists(tmpdir / "unittestTypes.client.so")); + BOOST_REQUIRE(!std::filesystem::exists(tmpdir / "unittest.so")); + BOOST_REQUIRE(std::filesystem::exists(tmpdir / "unittest.client.so")); + BOOST_REQUIRE(!std::filesystem::exists(tmpdir / "unittestTypes.so")); + BOOST_REQUIRE(!std::filesystem::exists(tmpdir / "unittestTypes.client.so")); commonTests(); TestOptionsSource::LoadTestOptions({ }); unloadTests(); - boost::filesystem::remove_all(tmpdir); + std::filesystem::remove_all(tmpdir); } BOOST_AUTO_TEST_SUITE_END(); diff --git a/project2/ice/unittests/testDaemon.cpp b/project2/ice/unittests/testDaemon.cpp index 0740966..0ce5fa2 100644 --- a/project2/ice/unittests/testDaemon.cpp +++ b/project2/ice/unittests/testDaemon.cpp @@ -1,6 +1,6 @@ #define BOOST_TEST_MODULE Daemon #include <boost/test/unit_test.hpp> -#include <boost/filesystem/operations.hpp> +#include <filesystem> #include <testOptionsSource.h> #include <unittest.h> #include <unittestComplex.h> @@ -12,9 +12,8 @@ #define XSTR(s) STR(s) #define STR(s) #s -const auto bindir = boost::filesystem::canonical("/proc/self/exe").parent_path(); -const auto componentdir = bindir.parent_path() / "component"; -const boost::filesystem::path iceroot(XSTR(ROOT)); +const auto bindir = std::filesystem::canonical("/proc/self/exe").parent_path(); +const std::filesystem::path iceroot(XSTR(ROOT)); const auto headers = iceroot.parent_path().parent_path(); class DummyTask : public Task { @@ -28,7 +27,7 @@ class DummyTask : public Task { static unsigned int execCount; }; -DECLARE_LOADER("DummyTask", DummyTask); +NAMEDFACTORY("DummyTask", DummyTask, TaskFactory); unsigned int DummyTask::execCount = 0; class DummyParamTask : public Task { @@ -54,7 +53,7 @@ class DummyParamTask : public Task { static VariableType execA; static VariableType execB; }; -DECLARE_LOADER("DummyParamTask", DummyParamTask); +NAMEDFACTORY("DummyParamTask", DummyParamTask, TaskFactory); unsigned int DummyParamTask::execCount = 0; VariableType DummyParamTask::execA; VariableType DummyParamTask::execB; @@ -86,7 +85,7 @@ class DummyComplexParamTask : public Task { static VariableType execB; static VariableType execD; }; -DECLARE_LOADER("DummyComplexParamTask", DummyComplexParamTask); +NAMEDFACTORY("DummyComplexParamTask", DummyComplexParamTask, TaskFactory); unsigned int DummyComplexParamTask::execCount = 0; VariableType DummyComplexParamTask::execA; VariableType DummyComplexParamTask::execB; @@ -97,20 +96,21 @@ void commonTests() { BOOST_TEST_CHECKPOINT("Verify loaded"); - BOOST_REQUIRE(IceDaemonAdapterHandlerLoader::getFor("UnitTest-SimpleInterface")); - BOOST_REQUIRE(IceDaemonAdapterHandlerLoader::getFor("UnitTestComplex-ComplexInterface")); + BOOST_REQUIRE(IceDaemonAdapterHandlerFactory::get("UnitTest-SimpleInterface")); + BOOST_REQUIRE(IceDaemonAdapterHandlerFactory::get("UnitTestComplex-ComplexInterface")); int dummy = 0; BOOST_TEST_CHECKPOINT("Run daemon"); - DaemonPtr id = new IceDaemon(dummy, NULL); + auto id = std::make_shared<IceDaemon>(dummy, nullptr); + id->setup(); std::thread run(&Daemon::run, id.get()); BOOST_TEST_CHECKPOINT("Create and verify proxies"); - Ice::CommunicatorPtr ic = Ice::initialize(dummy, NULL); - UnitTest::SimpleInterfacePrx si = UnitTest::SimpleInterfacePrx::checkedCast(ic->stringToProxy("UnitTestSimpleInterface:tcp -p 12024")); + Ice::CommunicatorPtr ic = Ice::initialize(); + auto si = Ice::checkedCast<UnitTest::SimpleInterfacePrx>(ic->stringToProxy("UnitTestSimpleInterface:tcp -p 12024")); BOOST_REQUIRE(si); si->ice_ping(); - UnitTestComplex::ComplexInterfacePrx sic = UnitTestComplex::ComplexInterfacePrx::checkedCast(ic->stringToProxy("UnitTestComplexComplexInterface:tcp -p 12024")); + auto sic = Ice::checkedCast<UnitTestComplex::ComplexInterfacePrx>(ic->stringToProxy("UnitTestComplexComplexInterface:tcp -p 12024")); BOOST_REQUIRE(sic); sic->ice_ping(); @@ -177,7 +177,7 @@ commonTests() BOOST_TEST_CHECKPOINT("Call with complex param"); BOOST_REQUIRE_EQUAL(0, DummyComplexParamTask::execCount); - sic->ComplexParam(4, "complex", new UnitTestComplex::Date { 1980, 7, 9, 1, 2, 3}); + sic->ComplexParam(4, "complex", std::make_shared<UnitTestComplex::Date>( 1980, 7, 9, 1, 2, 3 )); BOOST_REQUIRE_EQUAL(1, DummyComplexParamTask::execCount); BOOST_REQUIRE_EQUAL(4, DummyComplexParamTask::execA.as<int>()); BOOST_REQUIRE_EQUAL("complex", DummyComplexParamTask::execB.as<std::string>()); @@ -186,6 +186,7 @@ commonTests() id->shutdown(); run.join(); + id->teardown(); ic->destroy(); } @@ -194,16 +195,16 @@ void unloadTests() { BOOST_TEST_CHECKPOINT("Verify unloaded"); - BOOST_REQUIRE_THROW(IceDaemonAdapterHandlerLoader::createNew("UnitTest-SimpleInterface", NULL), NotSupported); + BOOST_REQUIRE_THROW(IceDaemonAdapterHandlerFactory::createNew("UnitTest-SimpleInterface", NULL), AdHoc::NoSuchPluginException); } BOOST_FIXTURE_TEST_SUITE( Core, TestAppInstance ); BOOST_AUTO_TEST_CASE( test_daemon ) { - const boost::filesystem::path tmpdir = "/tmp/ut/project2.slice-daemon"; + const std::filesystem::path tmpdir = "/tmp/ut/project2.slice-daemon"; BOOST_TEST_CHECKPOINT("Clean up"); - boost::filesystem::remove_all(tmpdir); + std::filesystem::remove_all(tmpdir); BOOST_TEST_CHECKPOINT("Configure, compile, link, load"); TestOptionsSource::LoadTestOptions({ }); @@ -218,17 +219,17 @@ BOOST_AUTO_TEST_CASE( test_daemon ) { "ice.daemon.slicerdaemon", (iceroot / "unittestTypes.ice").string() }, { "ice.daemon.slicerdaemon", (iceroot / "unittest.ice").string() } }); - BOOST_REQUIRE(!boost::filesystem::exists(tmpdir / "unittest.so")); - BOOST_REQUIRE(boost::filesystem::exists(tmpdir / "unittest.daemon.so")); - BOOST_REQUIRE(!boost::filesystem::exists(tmpdir / "unittestTypes.so")); - BOOST_REQUIRE(!boost::filesystem::exists(tmpdir / "unittestTypes.daemon.so")); - BOOST_REQUIRE(!boost::filesystem::exists(tmpdir / "unittestComplex.so")); - BOOST_REQUIRE(boost::filesystem::exists(tmpdir / "unittestComplex.daemon.so")); + BOOST_REQUIRE(!std::filesystem::exists(tmpdir / "unittest.so")); + BOOST_REQUIRE(std::filesystem::exists(tmpdir / "unittest.daemon.so")); + BOOST_REQUIRE(!std::filesystem::exists(tmpdir / "unittestTypes.so")); + BOOST_REQUIRE(!std::filesystem::exists(tmpdir / "unittestTypes.daemon.so")); + BOOST_REQUIRE(!std::filesystem::exists(tmpdir / "unittestComplex.so")); + BOOST_REQUIRE(std::filesystem::exists(tmpdir / "unittestComplex.daemon.so")); commonTests(); TestOptionsSource::LoadTestOptions({ }); unloadTests(); - boost::filesystem::remove_all(tmpdir); + std::filesystem::remove_all(tmpdir); } BOOST_AUTO_TEST_SUITE_END(); diff --git a/project2/ice/unittests/testDaemonCompile.cpp b/project2/ice/unittests/testDaemonCompile.cpp index d93dbf0..6125e6c 100644 --- a/project2/ice/unittests/testDaemonCompile.cpp +++ b/project2/ice/unittests/testDaemonCompile.cpp @@ -1,6 +1,6 @@ #define BOOST_TEST_MODULE DaemonCompile #include <boost/test/unit_test.hpp> -#include <boost/filesystem/operations.hpp> +#include <filesystem> #include <testOptionsSource.h> #include <exceptions.h> #include <iceDaemon.h> @@ -8,9 +8,8 @@ #define XSTR(s) STR(s) #define STR(s) #s -const auto bindir = boost::filesystem::canonical("/proc/self/exe").parent_path(); -const auto componentdir = bindir.parent_path() / "component"; -const boost::filesystem::path iceroot(XSTR(ROOT)); +const auto bindir = std::filesystem::canonical("/proc/self/exe").parent_path(); +const std::filesystem::path iceroot(XSTR(ROOT)); const auto headers = iceroot.parent_path().parent_path(); static @@ -18,7 +17,7 @@ void commonTests() { BOOST_TEST_CHECKPOINT("Verify loaded"); - BOOST_REQUIRE(IceDaemonAdapterHandlerLoader::getFor("UnitTest-SimpleInterface")); + BOOST_REQUIRE(IceDaemonAdapterHandlerFactory::get("UnitTest-SimpleInterface")); } static @@ -26,16 +25,16 @@ void unloadTests() { BOOST_TEST_CHECKPOINT("Verify unloaded"); - BOOST_REQUIRE_THROW(IceDaemonAdapterHandlerLoader::createNew("UnitTest-SimpleInterface", NULL), NotSupported); + BOOST_REQUIRE_THROW(IceDaemonAdapterHandlerFactory::createNew("UnitTest-SimpleInterface", NULL), AdHoc::NoSuchPluginException); } BOOST_FIXTURE_TEST_SUITE( Core, TestAppInstance ); BOOST_AUTO_TEST_CASE( compile_daemon_full ) { - const boost::filesystem::path tmpdir = "/tmp/ut/project2.slice-daemonCompile/full"; + const std::filesystem::path tmpdir = "/tmp/ut/project2.slice-daemonCompile/full"; BOOST_TEST_CHECKPOINT("Clean up"); - boost::filesystem::remove_all(tmpdir); + std::filesystem::remove_all(tmpdir); BOOST_TEST_CHECKPOINT("Configure, compile, link, load"); TestOptionsSource::LoadTestOptions({ @@ -44,65 +43,65 @@ BOOST_AUTO_TEST_CASE( compile_daemon_full ) { "ice.daemon.slice", (iceroot / "unittestTypes.ice").string() }, { "ice.daemon.slice", (iceroot / "unittest.ice").string() } }); - BOOST_REQUIRE(boost::filesystem::exists(tmpdir / "unittest.so")); - BOOST_REQUIRE(boost::filesystem::exists(tmpdir / "unittest.daemon.so")); - BOOST_REQUIRE(boost::filesystem::exists(tmpdir / "unittestTypes.so")); - BOOST_REQUIRE(!boost::filesystem::exists(tmpdir / "unittestTypes.daemon.so")); + BOOST_REQUIRE(std::filesystem::exists(tmpdir / "unittest.so")); + BOOST_REQUIRE(std::filesystem::exists(tmpdir / "unittest.daemon.so")); + BOOST_REQUIRE(std::filesystem::exists(tmpdir / "unittestTypes.so")); + BOOST_REQUIRE(!std::filesystem::exists(tmpdir / "unittestTypes.daemon.so")); commonTests(); TestOptionsSource::LoadTestOptions({ }); unloadTests(); - boost::filesystem::remove_all(tmpdir); + std::filesystem::remove_all(tmpdir); } BOOST_AUTO_TEST_CASE( compile_daemon_daemonOnly ) { - const boost::filesystem::path tmpdir = "/tmp/ut/project2.slice-daemonCompile/daemonOnly"; + const std::filesystem::path tmpdir = "/tmp/ut/project2.slice-daemonCompile/daemonOnly"; BOOST_TEST_CHECKPOINT("Clean up"); - boost::filesystem::remove_all(tmpdir); + std::filesystem::remove_all(tmpdir); BOOST_TEST_CHECKPOINT("Configure, compile, link, load"); TestOptionsSource::LoadTestOptions({ - { "library", (componentdir / "libunittest.so").string() }, + { "library", args[1] }, { "ice.compile.tmpdir", tmpdir.string() }, { "ice.compile.headers", headers.string() }, { "ice.daemon.slicedaemon", (iceroot / "unittestTypes.ice").string() }, { "ice.daemon.slicedaemon", (iceroot / "unittest.ice").string() } }); - BOOST_REQUIRE(!boost::filesystem::exists(tmpdir / "unittest.so")); - BOOST_REQUIRE(boost::filesystem::exists(tmpdir / "unittest.daemon.so")); - BOOST_REQUIRE(boost::filesystem::exists(tmpdir / "unittestTypes.so")); - BOOST_REQUIRE(!boost::filesystem::exists(tmpdir / "unittestTypes.daemon.so")); + BOOST_REQUIRE(!std::filesystem::exists(tmpdir / "unittest.so")); + BOOST_REQUIRE(std::filesystem::exists(tmpdir / "unittest.daemon.so")); + BOOST_REQUIRE(std::filesystem::exists(tmpdir / "unittestTypes.so")); + BOOST_REQUIRE(!std::filesystem::exists(tmpdir / "unittestTypes.daemon.so")); commonTests(); TestOptionsSource::LoadTestOptions({ }); unloadTests(); - boost::filesystem::remove_all(tmpdir); + std::filesystem::remove_all(tmpdir); } BOOST_AUTO_TEST_CASE( compile_daemon_slicer ) { - const boost::filesystem::path tmpdir = "/tmp/ut/project2.slice-daemonCompile/slicer"; + const std::filesystem::path tmpdir = "/tmp/ut/project2.slice-daemonCompile/slicer"; BOOST_TEST_CHECKPOINT("Clean up"); - boost::filesystem::remove_all(tmpdir); + std::filesystem::remove_all(tmpdir); BOOST_TEST_CHECKPOINT("Configure, compile, link, load"); TestOptionsSource::LoadTestOptions({ - { "library", (componentdir / "slicer-yes" / "libunittestr.so").string() }, + { "library", args[2] }, { "ice.compile.tmpdir", tmpdir.string() }, { "ice.compile.headers", headers.string() }, { "ice.daemon.slicerdaemon", (iceroot / "unittestTypes.ice").string() }, { "ice.daemon.slicerdaemon", (iceroot / "unittest.ice").string() } }); - BOOST_REQUIRE(!boost::filesystem::exists(tmpdir / "unittest.so")); - BOOST_REQUIRE(boost::filesystem::exists(tmpdir / "unittest.daemon.so")); - BOOST_REQUIRE(!boost::filesystem::exists(tmpdir / "unittestTypes.so")); - BOOST_REQUIRE(!boost::filesystem::exists(tmpdir / "unittestTypes.daemon.so")); + BOOST_REQUIRE(!std::filesystem::exists(tmpdir / "unittest.so")); + BOOST_REQUIRE(std::filesystem::exists(tmpdir / "unittest.daemon.so")); + BOOST_REQUIRE(!std::filesystem::exists(tmpdir / "unittestTypes.so")); + BOOST_REQUIRE(!std::filesystem::exists(tmpdir / "unittestTypes.daemon.so")); commonTests(); TestOptionsSource::LoadTestOptions({ }); unloadTests(); - boost::filesystem::remove_all(tmpdir); + std::filesystem::remove_all(tmpdir); } BOOST_AUTO_TEST_SUITE_END(); diff --git a/project2/ice/unittests/testIceBoxDaemon.cpp b/project2/ice/unittests/testIceBoxDaemon.cpp new file mode 100644 index 0000000..6ee8487 --- /dev/null +++ b/project2/ice/unittests/testIceBoxDaemon.cpp @@ -0,0 +1,55 @@ +#define BOOST_TEST_MODULE IceBoxDaemon +#include <boost/test/unit_test.hpp> +#include <IceBox/IceBox.h> +#include <Ice/Initialize.h> +#include <Ice/Communicator.h> +#include <daemon.h> + +extern "C" { + IceBox::Service * createProject2Daemon(Ice::CommunicatorPtr); +} + +BOOST_AUTO_TEST_CASE( test_icebox_daemon ) +{ + Ice::CommunicatorPtr adminComm = Ice::initialize(); + BOOST_REQUIRE(adminComm); + adminComm->getProperties()->setProperty("project2.daemon.type", "TestDaemon"); + + IceBox::Service * service = createProject2Daemon(adminComm); + BOOST_REQUIRE(service); + + Ice::CommunicatorPtr serviceComm = Ice::initialize(); + BOOST_REQUIRE(serviceComm); + + service->start("test_icebox_daemon", serviceComm, { }); + + service->stop(); + + delete service; + + serviceComm->destroy(); + adminComm->destroy(); +} + +class TestDaemon : public Daemon { + public: + TestDaemon(int &, char **) : + stop(false) + { + } + + void run() const + { + while (!stop) sleep(1); + } + + void shutdown() const + { + stop = true; + } + + private: + mutable bool stop; +}; +NAMEDFACTORY("TestDaemon", TestDaemon, DaemonFactory); + diff --git a/project2/json/Jamfile.jam b/project2/json/Jamfile.jam index 0f87d50..3a47ff2 100644 --- a/project2/json/Jamfile.jam +++ b/project2/json/Jamfile.jam @@ -2,12 +2,11 @@ alias glibmm : : : : <cflags>"`pkg-config --cflags glibmm-2.4`" <linkflags>"`pkg-config --libs glibmm-2.4`" ; -lib boost_filesystem : : <name>boost_filesystem ; +lib stdc++fs ; lib boost_date_time : : <name>boost_date_time ; lib jsonpp ; cpp-pch pch : pch.hpp : - <include>../../libmisc <library>glibmm <library>../common//p2common ; @@ -15,13 +14,12 @@ lib p2json : pch [ glob *.cpp ] : <include>. - <include>../libmisc <library>glibmm <library>jsonpp <library>../common//p2common - <library>../lib//p2lib + <library>..//adhocutil <library>../url//p2url - <library>boost_filesystem + <library>stdc++fs <library>boost_date_time : : <include>. diff --git a/project2/json/conversion.h b/project2/json/conversion.h index 0e9d56d..3bc2412 100644 --- a/project2/json/conversion.h +++ b/project2/json/conversion.h @@ -19,7 +19,7 @@ class Project2ToJson : public boost::static_visitor<json::Value> { } }; -class JsonToProject2 : public boost::static_visitor<VariableType> { +class JsonToProject2 { public: VariableType operator()(const json::Object &) const; VariableType operator()(const json::Array &) const; diff --git a/project2/json/couchSession.cpp b/project2/json/couchSession.cpp deleted file mode 100644 index 51d466c..0000000 --- a/project2/json/couchSession.cpp +++ /dev/null @@ -1,188 +0,0 @@ -#include <pch.hpp> -#include "curlHelper.h" -#include "safeMapFind.h" -#include "exceptions.h" -#include "logger.h" -#include "buffer.h" -#include "curlsup.h" -#include <scriptLoader.h> -#include <sessionContainer.h> -#include <boost/bind.hpp> -#include <boost/lexical_cast.hpp> -#include <boost/uuid/uuid_io.hpp> -#include <boost/uuid/uuid_generators.hpp> -#include "jsonpp.h" -#include "safeMapFind.h" -#include "conversion.h" -#include "options.h" - -class CouchDBFailure : public std::exception { }; - -class CouchSessionContainer : public SessionContainer { - public: - CouchSessionContainer() { - } - virtual SessionPtr getSession(const boost::uuids::uuid & uuid) const { - try { - json::Object obj = getSessionFromServer(uuid); - if (boost::get<json::Number>(*safeMapLookup<Session::VariableNotFound>(obj, ExpiryKey)) > time(NULL)) { - SessionPtr s = new Session(uuid); - for (const json::Object::value_type & v : obj) { - s->SetValue(v.first, boost::apply_visitor(JsonToProject2(), *v.second)); - } - return s; - } - } - catch (...) { - } - return NULL; - } - - virtual void SaveSession(SessionPtr s) const { - CurlPtr c = new Curl(); - c->setopt(CURLOPT_UPLOAD, 1L); - c->setopt(CURLOPT_FAILONERROR, 1); - json::Object obj; - s->ForeachValue(boost::bind(&CouchSessionContainer::addToObject, &obj, _1, _2)); - obj[ExpiryKey] = json::ValuePtr(new json::Value((json::Number)s->ExpiryTime())); - Glib::ustring out = json::serializeObject(obj, "utf-8"); - c->setopt(CURLOPT_INFILESIZE_LARGE, (curl_off_t)out.size()); - unsigned int off = 0; - for (const std::string & b : baseUrls) { - c->setopt(CURLOPT_URL, (b + boost::lexical_cast<std::string>(s->ID())).c_str()); - try { - c->performSend(boost::bind(send, &out, &off, _1, _2)); - return; - } - catch (...) { - } - } - throw CouchDBFailure(); - } - - json::Object getSessionFromServer(const boost::uuids::uuid & uuid) const { - CurlPtr c = new Curl(); - c->setopt(CURLOPT_FAILONERROR, 1); - Glib::ustring msg; - for (const std::string & b : baseUrls) { - try { - c->setopt(CURLOPT_URL, (b + boost::lexical_cast<std::string>(uuid)).c_str()); - c->performRead(boost::bind(append, &msg, _1, _2)); - json::Object o = json::parseObject(msg); - return o; - } - catch (...) { - } - } - throw CouchDBFailure(); - } - - private: - static void addToObject(json::Object * obj, const Glib::ustring & name, const VariableType & value) { - (*obj)[name] = json::ValuePtr(new json::Value(boost::apply_visitor(Project2ToJson(), value))); - } - - static size_t send(Glib::ustring * buf, unsigned int * off, char * str, size_t l) { - size_t len = std::min(buf->size() - *off, l); - memcpy(str, buf->c_str() + *off, len); - return len; - } - - static size_t append(Glib::ustring * buf, const char * str, size_t l) { - buf->append(str, l); - return l; - } - - void setopt_s(CurlHandle::Ptr c, CURLoption o, const char * v) { - c->setopt(o, v); - } - - void setopt_l(CurlHandle::Ptr c, CURLoption o, int64_t v) { - c->setopt(o, (long)v); - } - - static std::vector<std::string> baseUrls; - static const Glib::ustring ExpiryKey; - friend class CustomCouchSessionLoader; -}; -std::vector<std::string> CouchSessionContainer::baseUrls; -const Glib::ustring CouchSessionContainer::ExpiryKey("project2:expires"); - -class CustomCouchSessionLoader : public SessionContainerLoader::For<CouchSessionContainer> { - public: - void onPeriodic() override { - try { - deleteSessions(); - compactDB(); - } - catch (...) { - Logger()->messagebf(LOG_WARNING, "Failed to purge expired sessions and compact DB"); - } - } - - INITOPTIONS; - private: - static size_t discard(size_t l) { - return l; - } - - void compactDB() { - CurlPtr c = new Curl(); - c->setopt(CURLOPT_POST, 1); - c->appendHeader("Content-Type: application/json"); - for (const std::string & b : CouchSessionContainer::baseUrls) { - c->setopt(CURLOPT_URL, (b + "_compact").c_str()); - c->performRead(boost::bind(discard, _2)); - } - } - void deleteSessions() { - // Create the server side search map - json::Object map; - Buffer mapBuf; - mapBuf.appendf("function(doc) { var exp = doc['%s']; if (exp < %u) { emit(exp, doc._rev); } }", - CouchSessionContainer::ExpiryKey.c_str(), (unsigned int)time(NULL)); - map["map"] = json::ValuePtr(new json::Value(mapBuf.str())); - Glib::ustring mapStr(json::serializeObject(map, "utf-8")); - // Create the CURL handle - CurlPtr c = new Curl(); - c->setopt(CURLOPT_FAILONERROR, 1); - c->appendHeader("Content-Type: application/json"); - c->setopt(CURLOPT_POST, 1); - c->setopt(CURLOPT_POSTFIELDS, mapStr.c_str()); - c->setopt(CURLOPT_POSTFIELDSIZE, mapStr.bytes()); - for (const std::string & b : CouchSessionContainer::baseUrls) { - Glib::ustring msg; - try { - c->setopt(CURLOPT_URL, (b + "_temp_view").c_str()); - c->performRead(boost::bind(CouchSessionContainer::append, &msg, _1, _2)); - json::Object o = json::parseObject(msg); - for (const json::Array::value_type & v : boost::get<json::Array>(*safeMapLookup<ParamNotFound>(o, "rows"))) { - json::Object rec = boost::get<json::Object>(*v); - boost::uuids::uuid u = boost::uuids::string_generator()(boost::get<json::String>(*safeMapLookup<ParamNotFound>(rec, "id")).raw()); - Glib::ustring & rev = boost::get<json::String>(*safeMapLookup<ParamNotFound>(rec, "value")); - deleteSession(u, rev); - } - return; - } - catch (...) { - } - } - } - - void deleteSession(const boost::uuids::uuid & sid, const Glib::ustring & rev) const { - CurlPtr c = new Curl(); - c->setopt(CURLOPT_CUSTOMREQUEST, "DELETE"); - for (const std::string & b : CouchSessionContainer::baseUrls) { - c->setopt(CURLOPT_URL, (b + boost::lexical_cast<std::string>(sid) + "?rev=" + rev).c_str()); - c->performRead(boost::bind(discard, _2)); - return; - } - } -}; -DECLARE_CUSTOM_COMPONENT_LOADER("couchsession", CouchSessionContainer, CustomCouchSessionLoader, SessionContainerLoader); - -DECLARE_OPTIONS(CustomCouchSessionLoader, "Session CouchDB options") -("session.couchdb.baseUrl", Options::functions([](const VariableType & v) { CouchSessionContainer::baseUrls.push_back(v); }, boost::bind(&std::vector<std::string>::clear, &CouchSessionContainer::baseUrls)), - "Base URL to store sessions in") -END_OPTIONS(CustomCouchSessionLoader); - diff --git a/project2/json/pch.hpp b/project2/json/pch.hpp index 1309317..3aa19d4 100644 --- a/project2/json/pch.hpp +++ b/project2/json/pch.hpp @@ -2,10 +2,8 @@ #ifndef JSON_PCH #define JSON_PCH -#include <boost/variant.hpp> +#include <boost/variant/variant_fwd.hpp> #include <glibmm/ustring.h> -#include <variables.h> -#include <presenter.h> #include <map> #include <stack> diff --git a/project2/json/presenter-p.cpp b/project2/json/presenter-p.cpp index 92ba8c1..29db13c 100644 --- a/project2/json/presenter-p.cpp +++ b/project2/json/presenter-p.cpp @@ -20,4 +20,5 @@ class Json_P_Presenter : public JsonPresenter { Variable Callback; }; -DECLARE_GENERIC_LOADER("json-p", PresenterLoader, Json_P_Presenter) +NAMEDFACTORY("json-p", Json_P_Presenter, PresenterFactory) + diff --git a/project2/json/presenter.cpp b/project2/json/presenter.cpp index 8db182c..4a5713a 100644 --- a/project2/json/presenter.cpp +++ b/project2/json/presenter.cpp @@ -47,21 +47,20 @@ JsonPresenter::addNamedValue(const Glib::ustring & name, const VariableType & va void JsonPresenter::addValueToObject(const Glib::ustring & name, const VariableType & value) const { - (*curRowSet.top())[name.collate_key()] = json::ValuePtr(new json::Value(boost::apply_visitor(Project2ToJson(), value))); + (*curRowSet.top())[name.collate_key()] = boost::apply_visitor(Project2ToJson(), value); } void JsonPresenter::addValueToArray(const Glib::ustring &, const VariableType & value) const { - curRowArray.top()->push_back(json::ValuePtr(new json::Value(boost::apply_visitor(Project2ToJson(), value)))); + curRowArray.top()->push_back(boost::apply_visitor(Project2ToJson(), value)); } void JsonPresenter::addNewRow(const Glib::ustring &) const { - json::Value * v = new json::Value(json::Object()); - curRowSet.push(boost::get<json::Object>(v)); - curRowArray.top()->push_back(json::ValuePtr(v)); + auto v = &curRowArray.top()->emplace_back(); + curRowSet.push(std::get_if<json::Object>(v)); vaStack.push(&JsonPresenter::addValueToObject); } @@ -75,9 +74,8 @@ JsonPresenter::finishRow() const void JsonPresenter::addNewRowSet(const Glib::ustring & name) const { - json::Value * v = new json::Value(json::Object()); - (*curRowSet.top())[name.collate_key()] = json::ValuePtr(v); - curRowSet.push(boost::get<json::Object>(v)); + auto v = &((*curRowSet.top())[name.collate_key()] = json::Object()); + curRowSet.push(std::get_if<json::Object>(v)); } void @@ -95,9 +93,8 @@ JsonPresenter::finishRowSet() const void JsonPresenter::addNewArray(const Glib::ustring & name, bool) const { - json::Value * v = new json::Value(json::Array()); - curRowArray.push(boost::get<json::Array>(v)); - (*curRowSet.top())[name.collate_key()] = json::ValuePtr(v); + auto v = &((*curRowSet.top())[name.collate_key()] = json::Array()); + curRowArray.push(std::get_if<json::Array>(v)); vaStack.push(&JsonPresenter::addValueToArray); } @@ -134,11 +131,12 @@ void JsonPresenter::writeTo(std::ostream & o, const std::string & encoding, ExecContext * ec) const { if (returnObject(ec).isNull()) { - serializeObject(object, o, encoding); + serializeValue(object, o, encoding); } else { - serializeValue(*object[returnObject(ec).as<Glib::ustring>().collate_key()], o, encoding); + serializeValue(object[returnObject(ec).as<Glib::ustring>().collate_key()], o, encoding); } } -DECLARE_GENERIC_LOADER("json", PresenterLoader, JsonPresenter) +NAMEDFACTORY("json", JsonPresenter, PresenterFactory); + diff --git a/project2/json/presenter.h b/project2/json/presenter.h index 981953c..b18f05f 100644 --- a/project2/json/presenter.h +++ b/project2/json/presenter.h @@ -7,7 +7,7 @@ #include "transform.h" #include <stack> -class JsonPresenter : public MultiRowSetPresenter, public ContentPresenter, public SourceOf<json::Object>, public WritableContent, public SourceOf<WritableContent> { +class DLL_PUBLIC JsonPresenter : public MultiRowSetPresenter, public ContentPresenter, public SourceOf<json::Object>, public WritableContent, public SourceOf<WritableContent> { public: JsonPresenter(ScriptNodePtr s, ObjectSource, ExecContext *); JsonPresenter(ScriptNodePtr s, ObjectSource, const Glib::ustring &); diff --git a/project2/lib/Jamfile.jam b/project2/lib/Jamfile.jam deleted file mode 100644 index 0f5d331..0000000 --- a/project2/lib/Jamfile.jam +++ /dev/null @@ -1,10 +0,0 @@ -lib p2lib : - [ glob-tree *.cpp ] - ../../libmisc/buffer.cpp - ../../libmisc/misc.cpp - : - <include>../../libmisc - : : - <include>../../libmisc - <include>. - ; diff --git a/project2/lib/safeMapFind.h b/project2/lib/safeMapFind.h deleted file mode 100644 index a5786bc..0000000 --- a/project2/lib/safeMapFind.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef SAFEMAPFIND_H -#define SAFEMAPFIND_H - -template <class Ex, class Map> -typename Map::const_iterator -safeMapFind(const Map & map, const typename Map::key_type & key) -{ - typename Map::const_iterator i = map.find(key); - if (i == map.end()) { - throw Ex(key); - } - return i; -} - -template <class Map> -typename Map::mapped_type -defaultMapFind(const Map & map, const typename Map::key_type & key, const typename Map::mapped_type & def = typename Map::mapped_type()) -{ - typename Map::const_iterator i = map.find(key); - if (i == map.end()) { - return def; - } - return i->second; -} - -template <class Ex, class Map> -const typename Map::mapped_type & -safeMapLookup(const Map & map, const typename Map::key_type & key) -{ - typename Map::const_iterator i = map.find(key); - if (i == map.end()) { - throw Ex(key); - } - return i->second; -} - -template <class Cont> -bool -containerContains(const Cont & c, const typename Cont::value_type & v) -{ - return (std::find(c.begin(), c.end(), v) != c.end()); -} - -#endif - diff --git a/project2/lib/scopeObject.cpp b/project2/lib/scopeObject.cpp deleted file mode 100644 index e2e42da..0000000 --- a/project2/lib/scopeObject.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "scopeObject.h" - -ScopeObject::ScopeObject(const Event & onexitpre, const Event & onsuccess, const Event & onfailure, const Event & onexitpost) : - onExitPre(onexitpre), - onSuccess(onsuccess), - onFailure(onfailure), - onExitPost(onexitpost) -{ -} - -ScopeObject::~ScopeObject() -{ - if (onExitPre) onExitPre(); - if (std::uncaught_exception()) { - if (onFailure) onFailure(); - } - else { - if (onSuccess) onSuccess(); - } - if (onExitPost) onExitPost(); -} - diff --git a/project2/lib/scopeObject.h b/project2/lib/scopeObject.h deleted file mode 100644 index 6fc323d..0000000 --- a/project2/lib/scopeObject.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef SCOPE_OBJECT_H -#define SCOPE_OBJECT_H - -#include <boost/function.hpp> - -class ScopeObject { - public: - typedef boost::function<void()> Event; - ScopeObject(const Event &, const Event & = Event(), const Event & = Event(), const Event & = Event()); - ~ScopeObject(); - - private: - const Event onExitPre; - const Event onSuccess; - const Event onFailure; - const Event onExitPost; -}; - -#endif - diff --git a/project2/mail/Jamfile.jam b/project2/mail/Jamfile.jam index 91e507d..b0acf35 100644 --- a/project2/mail/Jamfile.jam +++ b/project2/mail/Jamfile.jam @@ -7,7 +7,6 @@ lib esmtp : : <name>esmtp ; lib p2mail : sendmailTask.cpp : - <include>../../libmisc <library>glibmm <library>esmtp <library>../common//p2common diff --git a/project2/mail/sendmailTask.cpp b/project2/mail/sendmailTask.cpp index 054f844..1d211fe 100644 --- a/project2/mail/sendmailTask.cpp +++ b/project2/mail/sendmailTask.cpp @@ -19,7 +19,7 @@ DECLARE_OPTIONS(SendMailTask, "Send Email Task options") "The default encoding to use in email content") END_OPTIONS(SendMailTask); -DECLARE_LOADER("sendmail", SendMailTask); +NAMEDFACTORY("sendmail", SendMailTask, TaskFactory); uint8_t SendMailTask::MailPart::mimeIdx; @@ -107,8 +107,8 @@ class Header : public SendMailTask::MailPart { return (const char *)*buf; } private: - void writeText(char ** buf, int * len, const char * text) const { - *len = asprintf(buf, "%s: %s\r\n", header.c_str(), text); + void writeText(char ** buf, int * len, const std::string & text) const { + *len = asprintf(buf, "%s: %s\r\n", header.c_str(), text.c_str()); } const std::string header; const VariableType value; @@ -136,10 +136,10 @@ class TransformWritableContentToEmail : public TransformImpl<WritableContent, Se } void transform(const WritableContent * wc, SendMailTask::Parts * parts, ExecContext * ec) const { - parts->parts.insert(new BoundaryBegin(wc->getContentType(ec), encoding, wc->getContentClass(ec))); + parts->parts.insert(std::make_shared<BoundaryBegin>(wc->getContentType(ec), encoding, wc->getContentClass(ec))); std::stringstream str; wc->writeTo(str, encoding, ec); - parts->parts.insert(new MimeContent(str.str(), wc->getContentClass(ec))); + parts->parts.insert(std::make_shared<MimeContent>(str.str(), wc->getContentClass(ec))); SendMailTask::MailPart::mimeIdx += 1; } void configure(ScriptNodePtr s, ExecContext * ec) @@ -153,7 +153,7 @@ DECLARE_TRANSFORM(TransformWritableContentToEmail); class EmailViewHost : public ViewHost { public: - EmailViewHost(boost::intrusive_ptr<SendMailTask::Parts> & ps, ScriptNodePtr node) : + EmailViewHost(std::shared_ptr<SendMailTask::Parts> & ps, ScriptNodePtr node) : CommonObjects(node), CheckHost(node), ViewHost(node), @@ -163,9 +163,9 @@ class EmailViewHost : public ViewHost { MultiRowSetPresenterPtr getPresenter(ExecContext * ec) const { if (!presenter) { Logger()->message(LOG_DEBUG, "Building default email transform chain"); - XmlPresenterPtr xpp = new XmlPresenter(n, Default, ec); - HtmlDocument * hd = new HtmlDocument(n, Default); - TextDocument * td = new TextDocument(n, Default); + XmlPresenterPtr xpp = std::make_shared<XmlPresenter>(n, Default, ec); + auto hd = std::make_shared<HtmlDocument>(n, Default); + auto td = std::make_shared<TextDocument>(n, Default); xpp->addTarget(hd, ec, n); hd->addTarget(parts, ec, NULL); hd->addTarget(td, ec, n); @@ -175,7 +175,7 @@ class EmailViewHost : public ViewHost { return presenter; } private: - boost::intrusive_ptr<SendMailTask::Parts> & parts; + std::shared_ptr<SendMailTask::Parts> & parts; ScriptNodePtr n; mutable MultiRowSetPresenterPtr presenter; }; @@ -183,17 +183,17 @@ class EmailViewHost : public ViewHost { void SendMailTask::execute(ExecContext * ec) const { - boost::intrusive_ptr<Parts> parts = new Parts(); + auto parts = std::make_shared<Parts>(); MailPart::mimeIdx = 0; - parts->parts.insert(new Header("To", to(ec))); - parts->parts.insert(new Header("From", from(ec))); - parts->parts.insert(new Header("Subject", subject(ec))); - parts->parts.insert(new Header("Content-Type", "multipart/alternative; boundary=\"<<divider>>\"")); - parts->parts.insert(new Header("MIME-Version", "1.0")); - parts->parts.insert(new Header("Content-Transfer-Encoding", "binary")); - parts->parts.insert(new BoundaryEnd()); - - ViewHostPtr vsp = new EmailViewHost(parts, ScriptReader::resolveScript("emails", present(ec), false)->root()); + parts->parts.insert(std::make_shared<Header>("To", to(ec))); + parts->parts.insert(std::make_shared<Header>("From", from(ec))); + parts->parts.insert(std::make_shared<Header>("Subject", subject(ec))); + parts->parts.insert(std::make_shared<Header>("Content-Type", "multipart/alternative; boundary=\"<<divider>>\"")); + parts->parts.insert(std::make_shared<Header>("MIME-Version", "1.0")); + parts->parts.insert(std::make_shared<Header>("Content-Transfer-Encoding", "binary")); + parts->parts.insert(std::make_shared<BoundaryEnd>()); + + ViewHostPtr vsp = std::make_shared<EmailViewHost>(parts, ScriptReader::resolveScript("emails", present(ec), false)->root()); vsp->executeViews(ec); vsp->doTransforms(ec); parts->part = parts->parts.begin(); @@ -201,9 +201,11 @@ SendMailTask::execute(ExecContext * ec) const // Write email smtp_session_t session = smtp_create_session(); smtp_message_t message = smtp_add_message(session); - smtp_set_server(session, server(ec)); + std::string svr(server(ec)); + std::string t(to(ec)); + smtp_set_server(session, svr.c_str()); smtp_set_header(message, "To", NULL, NULL); - smtp_add_recipient(message, to(ec)); + smtp_add_recipient(message, t.c_str()); smtp_set_messagecb(message, writeMail, parts.get()); if (!smtp_start_session(session)) { char buf[BUFSIZ]; diff --git a/project2/mail/sendmailTask.h b/project2/mail/sendmailTask.h index 035fe2b..f557130 100644 --- a/project2/mail/sendmailTask.h +++ b/project2/mail/sendmailTask.h @@ -1,7 +1,6 @@ #ifndef SENDMAILTASK_H #define SENDMAILTASK_H -#include <boost/intrusive_ptr.hpp> #include <map> #include "task.h" #include "transform.h" @@ -10,9 +9,9 @@ #include <options.h> /// Project2 component to send an email -class SendMailTask : public Task { +class DLL_PUBLIC SendMailTask : public Task { public: - class MailPart : public IntrusivePtrBase { + class MailPart { public: MailPart(uint8_t, uint8_t, uint8_t); ~MailPart(); @@ -20,7 +19,7 @@ class SendMailTask : public Task { const uint8_t sec, ind, prt; static uint8_t mimeIdx; }; - typedef boost::intrusive_ptr<MailPart> MailPartPtr; + typedef std::shared_ptr<MailPart> MailPartPtr; class SortMailParts { public: bool operator()(const MailPartPtr &, const MailPartPtr &) const; @@ -49,7 +48,6 @@ class SendMailTask : public Task { PresenterPtr createDefaultPresenter(ScriptNodePtr n) const; // Configurables - friend class CustomSendMailTaskLoader; friend class TransformWritableContentToEmail; static std::string defaultMailServer; static std::string defaultMailEncoding; diff --git a/project2/processes/Jamfile.jam b/project2/processes/Jamfile.jam index 99f6ffd..97e2ee2 100644 --- a/project2/processes/Jamfile.jam +++ b/project2/processes/Jamfile.jam @@ -5,9 +5,8 @@ alias glibmm : : : : lib p2processes : [ glob *.cpp ] : - <include>../../libmisc <library>glibmm <library>../common//p2common - <library>../lib//p2lib + <library>..//adhocutil ; diff --git a/project2/processes/processStream.cpp b/project2/processes/processStream.cpp index 3067533..79945d2 100644 --- a/project2/processes/processStream.cpp +++ b/project2/processes/processStream.cpp @@ -1,11 +1,10 @@ #include "iHaveParameters.h" #include "scriptLoader.h" -#include "scopeObject.h" +#include <processPipes.h> #include "scripts.h" #include "stream.h" #include <exception> #include <sys/wait.h> -#include <misc.h> SimpleMessageException(SubProcessFailedToStart); SimpleMessageException(SubProcessFailed); @@ -28,15 +27,9 @@ class ProcessStream : public Stream, IHaveParameters { for (const Parameters::value_type & p : parameters) { callProc.push_back(p.second(ec)); } - int fds[2]; - popenrw(callProc, fds); - - ScopeObject doClose([&] { - close(fds[0]); - close(fds[1]); - }); + AdHoc::System::ProcessPipes fds(callProc, false, true, false); char buf[BUFSIZ]; - while (ssize_t r = read(fds[1], buf, BUFSIZ) != 0) { + while (ssize_t r = read(fds.fdOut(), buf, BUFSIZ) != 0) { if (r < 0) { throw syscall_error(errno); } @@ -48,7 +41,7 @@ class ProcessStream : public Stream, IHaveParameters { // ignore any error if the application is still running, // but if there is already an exception being thrown, we don't // want to throw another. - if (status != 0 && !std::uncaught_exception()) { + if (status != 0 && !std::uncaught_exceptions()) { throw SubProcessFailed(strerror(status)); } } @@ -56,4 +49,5 @@ class ProcessStream : public Stream, IHaveParameters { const Variable path; }; -DECLARE_LOADER("processstream", ProcessStream); +NAMEDFACTORY("processstream", ProcessStream, StreamFactory); + diff --git a/project2/regex/Jamfile.jam b/project2/regex/Jamfile.jam index 1849b45..4f4eb01 100644 --- a/project2/regex/Jamfile.jam +++ b/project2/regex/Jamfile.jam @@ -5,7 +5,6 @@ alias glibmm : : : : lib p2regex : [ glob *.cpp ] : - <include>../../libmisc <library>glibmm <library>../common//p2common ; diff --git a/project2/regex/regexRows.cpp b/project2/regex/regexRows.cpp index 6d72ccc..0ae4af4 100644 --- a/project2/regex/regexRows.cpp +++ b/project2/regex/regexRows.cpp @@ -4,9 +4,10 @@ #include <stdio.h> #include <glibmm/regex.h> -DECLARE_LOADER("regexrows", RegexRows); +NAMEDFACTORY("regexrows", RegexRows, RowSetFactory); RegexRows::RegexRows(ScriptNodePtr p) : + SourceObject(p), DefinedColumns(p, "columns", boost::bind(&Column::make, _1, _2)), RowSet(p), sourceText(p, "sourceText"), diff --git a/project2/regex/regexRows.h b/project2/regex/regexRows.h index 1a4ddb1..373d853 100644 --- a/project2/regex/regexRows.h +++ b/project2/regex/regexRows.h @@ -5,7 +5,7 @@ #include "variables.h" /// Base class for Project2 components that create a row set based on the contents of a byte stream -class RegexRows : public DefinedColumns, public RowSet { +class DLL_PUBLIC RegexRows : public DefinedColumns, public RowSet { public: RegexRows(ScriptNodePtr p); ~RegexRows(); diff --git a/project2/regex/regexTest.cpp b/project2/regex/regexTest.cpp index 59dca68..ab1bb47 100644 --- a/project2/regex/regexTest.cpp +++ b/project2/regex/regexTest.cpp @@ -3,7 +3,7 @@ #include "commonObjects.h" #include <glibmm/regex.h> -DECLARE_LOADER("regextest", RegexTest); +NAMEDFACTORY("regextest", RegexTest, TestFactory); RegexTest::RegexTest(ScriptNodePtr p) : SourceObject(p), diff --git a/project2/regex/regexTest.h b/project2/regex/regexTest.h index 00038a1..38d2cf7 100644 --- a/project2/regex/regexTest.h +++ b/project2/regex/regexTest.h @@ -5,7 +5,7 @@ #include "variables.h" /// Project2 component to test the value of a variable against a regular expression -class RegexTest : public Test { +class DLL_PUBLIC RegexTest : public Test { public: RegexTest(ScriptNodePtr p); virtual ~RegexTest(); diff --git a/project2/sql/Jamfile.jam b/project2/sql/Jamfile.jam index 8a3661b..dfe578f 100644 --- a/project2/sql/Jamfile.jam +++ b/project2/sql/Jamfile.jam @@ -1,84 +1,31 @@ -import lex ; - alias glibmm : : : : <cflags>"`pkg-config --cflags glibmm-2.4`" <linkflags>"`pkg-config --libs glibmm-2.4`" ; -lib boost_filesystem ; -lib fl ; +lib stdc++fs ; +lib dbppcore : : : : <include>/usr/include/dbpp ; build-project unittests ; -explicit library p2sqlmodMySQL ; -lib p2sqlmodMySQL : - sql-modMySQL.cpp : - <library>../../libmysqlpp//mysqlpp - <library>glibmm - <include>../../libmisc - <library>../common//p2common - <library>p2sql - : : - <library>../../libmysqlpp//mysqlpp - ; - -explicit library p2sqlmodSQLite ; -lib p2sqlmodSQLite : - sql-modSQLite.cpp : - <library>../../libsqlitepp//sqlitepp - <library>glibmm - <include>../../libmisc - <library>../common//p2common - <library>p2sql - <library>boost_filesystem - : : - <library>../../libsqlitepp//sqlitepp - ; - -explicit library p2sqlmodODBC ; -lib p2sqlmodODBC : - sql-modODBC.cpp : - <library>../../libodbcpp//odbcpp - <library>glibmm - <include>../../libmisc - <library>../common//p2common - <library>p2sql - : : - <library>../../libodbcpp//odbcpp - ; - -explicit library p2sqlmodPQ ; -lib p2sqlmodPQ : - sql-modPQ.cpp : - <library>../../libpqpp//pqpp - <library>glibmm - <include>../../libmisc - <library>../common//p2common - <library>p2sql - : : - <library>../../libpqpp//pqpp - ; - cpp-pch pch : pch.hpp : - <include>../../libmisc - <include>../../libdbpp + <library>dbppcore <library>glibmm <library>../common//p2common ; lib p2sql : pch - sql.ll - [ glob *.cpp : sql-mod*.cpp ] - ../../libdbpp//dbpp + [ glob *.cpp ] : <include>. + <library>dbppcore <library>glibmm - <library>boost_filesystem + <library>stdc++fs <library>../common//p2common - <library>../lib//p2lib - <include>../../libmisc - <library>fl + <library>../basics//p2basics + <library>..//adhocutil : : <include>. + <library>dbppcore ; diff --git a/project2/sql/connectionLoader.cpp b/project2/sql/connectionLoader.cpp deleted file mode 100644 index 671fafc..0000000 --- a/project2/sql/connectionLoader.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "connectionLoader.h" -#include "instanceStore.impl.h" - -INSTANTIATESTORE(std::string, ConnectionLoader); - diff --git a/project2/sql/connectionLoader.h b/project2/sql/connectionLoader.h deleted file mode 100644 index 3a8714c..0000000 --- a/project2/sql/connectionLoader.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef CONNECTIONLOADER_H -#define CONNECTIONLOADER_H - -#include "genLoader.h" -#include <connection.h> - -typedef GenLoader<DB::Connection, std::string, std::string> ConnectionLoader; - -#endif - diff --git a/project2/sql/mockDatabase.cpp b/project2/sql/mockDatabase.cpp deleted file mode 100644 index b73001a..0000000 --- a/project2/sql/mockDatabase.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include "mockDatabase.h" -#include "mockDatasource.h" -#include <misc.h> -#include <logger.h> -#include <fstream> -#include <modifycommand.h> -#include <FlexLexer.h> -#include "sqlFlexLexer.h" - -MockDatabase::MockDatabase(const std::string & name) : - mockName(name) -{ -} - -MockDatabase::~MockDatabase() -{ -} - -void -MockDatabase::PlaySchemaScripts(const std::vector<boost::filesystem::path> & ss) const -{ - DB::Connection * conn = openConnection(); - try { - CreateStatusTable(conn); - for (auto s : ss) { - conn->beginTx(); - PlaySchemaScript(conn, s); - conn->commitTx(); - } - DropStatusTable(conn); - delete conn; - Logger()->messagebf(LOG_DEBUG, "%s initialized", mockName); - MockConnectionLoader::mocks[mockName] = this; - } - catch (...) { - if (conn->inTx()) { - conn->rollbackTx(); - } - delete conn; - DropDatabase(); - throw; - } -} - -void -MockDatabase::PlaySchemaScript(DB::Connection * conn, const boost::filesystem::path & s) const -{ - UpdateStatusTable(conn, s); - Logger()->messagebf(LOG_DEBUG, "%s << %s", mockName, s); - std::ifstream f; - f.open(s.string()); - if (!f.good()) { - throw std::runtime_error("Failed to open mock script: " + s.string()); - } - auto lexer = boost::shared_ptr<FlexLexer>(new sqlFlexLexer(s.parent_path(), f, conn)); - while(lexer->yylex() != 0) ; - f.close(); -} - -void -MockDatabase::CreateStatusTable(DB::Connection * conn) const -{ - conn->execute( - "CREATE TABLE _p2_teststatus( \ - pid int, \ - script varchar(256), \ - scriptdir varchar(256))"); - auto ins = conn->newModifyCommand( - "INSERT INTO _p2_teststatus(pid) VALUES(?)"); - ins->bindParamI(0, getpid()); - ins->execute(); - delete ins; -} - -void -MockDatabase::DropStatusTable(DB::Connection * conn) const -{ - conn->execute("DROP TABLE _p2_teststatus"); -} - -void -MockDatabase::UpdateStatusTable(DB::Connection * conn, const boost::filesystem::path & script) const -{ - auto upd = conn->newModifyCommand( - "UPDATE _p2_teststatus SET script = ?, scriptdir = ?"); - upd->bindParamS(0, script.string()); - upd->bindParamS(1, script.parent_path().string()); - upd->execute(); - delete upd; -} - -MockServerDatabase::MockServerDatabase(const std::string & masterdb, const std::string & name, const std::string & type) : - MockDatabase(name), - master(InstanceMap<ConnectionLoader, std::string>::Get<std::invalid_argument>(type)->create(masterdb)), - testDbName(stringbf("test_%d_%d", getpid(), ++MockConnectionLoader::mocked)) -{ -} - -MockServerDatabase::~MockServerDatabase() -{ - delete master; -} - -void -MockServerDatabase::CreateNewDatabase() const -{ - DropDatabase(); - Logger()->messagebf(LOG_INFO, "Creating new database %s", testDbName); - master->execute("CREATE DATABASE " + testDbName); -} - -void -MockServerDatabase::DropDatabase() const -{ - Logger()->messagebf(LOG_INFO, "Droping database %s", testDbName); - master->execute("DROP DATABASE IF EXISTS " + testDbName); - MockConnectionLoader::mocks.erase(mockName); -} - diff --git a/project2/sql/mockDatabase.h b/project2/sql/mockDatabase.h deleted file mode 100644 index 9c00420..0000000 --- a/project2/sql/mockDatabase.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef MOCKDATABASE_H -#define MOCKDATABASE_H - -#include <string> -#include <vector> -#include <boost/filesystem/path.hpp> -#include <connection.h> - -class MockDatabase { - public: - MockDatabase(const std::string & mockName); - virtual ~MockDatabase(); - - virtual DB::Connection * openConnection() const = 0; - - protected: - virtual void CreateNewDatabase() const = 0; - virtual void PlaySchemaScripts(const std::vector<boost::filesystem::path> & ss) const; - virtual void PlaySchemaScript(DB::Connection *, const boost::filesystem::path & s) const; - virtual void DropDatabase() const = 0; - virtual void UpdateStatusTable(DB::Connection *, const boost::filesystem::path &) const; - - const std::string mockName; - - private: - void CreateStatusTable(DB::Connection *) const; - void DropStatusTable(DB::Connection *) const; -}; - -class MockServerDatabase : public MockDatabase { - public: - MockServerDatabase(const std::string & masterdb, const std::string & name, const std::string & type); - virtual ~MockServerDatabase(); - - protected: - virtual void CreateNewDatabase() const override; - virtual void DropDatabase() const override; - - DB::Connection * master; - const std::string testDbName; -}; - -#endif - diff --git a/project2/sql/mockDatasource.cpp b/project2/sql/mockDatasource.cpp index df5d325..8246f9b 100644 --- a/project2/sql/mockDatasource.cpp +++ b/project2/sql/mockDatasource.cpp @@ -1,15 +1,12 @@ #include "mockDatasource.h" #include <connection.h> -#include <safeMapFind.h> +#include <mockDatabase.h> -DECLARE_CUSTOM_COMPONENT_LOADER("mock", T, MockConnectionLoader, ConnectionLoader); +NAMEDPLUGIN("mock", MockConnectionFactory, DB::ConnectionFactory); -std::map<std::string, const MockDatabase *> MockConnectionLoader::mocks; -unsigned int MockConnectionLoader::mocked = 0; - -DB::Connection * -MockConnectionLoader::create(const std::string & n) const +DB::ConnectionPtr +MockConnectionFactory::create(const std::string & n) const { - return safeMapFind<std::runtime_error>(mocks, n)->second->openConnection(); + return DB::MockDatabase::openConnectionTo(n); } diff --git a/project2/sql/mockDatasource.h b/project2/sql/mockDatasource.h index ee1e976..b97af9b 100644 --- a/project2/sql/mockDatasource.h +++ b/project2/sql/mockDatasource.h @@ -1,15 +1,11 @@ #ifndef MOCKDATASOURCE_H #define MOCKDATASOURCE_H -#include <rdbmsDataSource.h> -#include "mockDatabase.h" +#include <connection.h> -class MockConnectionLoader : public ConnectionLoader { +class MockConnectionFactory : public DB::ConnectionFactory { public: - DB::Connection * create(const std::string &) const; - - static unsigned int mocked; - static std::map<std::string, const MockDatabase *> mocks; + DB::ConnectionPtr create(const std::string &) const; }; #endif diff --git a/project2/sql/pch.hpp b/project2/sql/pch.hpp index 2d8e99b..857eb5b 100644 --- a/project2/sql/pch.hpp +++ b/project2/sql/pch.hpp @@ -2,32 +2,11 @@ #ifndef SQL_PCH #define SQL_PCH -#include "cache.h" -#include "column.h" -#include "columns.h" -#include "command.h" -#include "commonObjects.h" -#include "connectionLoader.h" -#include "exceptions.h" -#include "iHaveParameters.h" -#include "logger.h" -#include "modifycommand.h" -#include "rdbmsDataSource.h" -#include "rowProcessor.h" -#include "rowSet.h" -#include "selectcommand.h" -#include "sqlHandleAsVariableType.h" -#include "sqlVariableBinder.h" -#include "sqlWriter.h" -#include "variables.h" -#include "scriptLoader.h" -#include "scripts.h" -#include <boost/bind.hpp> -#include "options.h" -#include <buffer.h> -#include <column.h> -#include <errno.h> #include <stdexcept> +#include <string> +#include <glibmm/ustring.h> +#include <boost/variant/variant_fwd.hpp> +#include <connection.h> #endif #endif diff --git a/project2/sql/rdbmsDataSource.cpp b/project2/sql/rdbmsDataSource.cpp index b0989b9..15ae638 100644 --- a/project2/sql/rdbmsDataSource.cpp +++ b/project2/sql/rdbmsDataSource.cpp @@ -1,16 +1,14 @@ #include <pch.hpp> #include "rdbmsDataSource.h" -#include "connectionLoader.h" #include <sys/utsname.h> #include "logger.h" #include "scripts.h" #include <errno.h> -SimpleMessageException(UnknownConnectionProvider); #define LOCK(l) std::lock_guard<std::mutex> _lock##l(l) -/// Specialized ElementLoader for instances of RdbmsDataSource; handles persistent DB connections -class RdbmsDataSourceLoader : public ElementLoader::For<RdbmsDataSource> { +/// Life cycle component for handling closure of persistent DB connections +class RdbmsDataSourceFactory : public LifeCycle { public: void onIdle() override { @@ -34,7 +32,7 @@ class RdbmsDataSourceLoader : public ElementLoader::For<RdbmsDataSource> { RdbmsDataSource::changedDSNs.clear(); } }; -DECLARE_CUSTOM_LOADER("rdbmsdatasource", RdbmsDataSourceLoader); +NAMEDFACTORY("rdbmsdatasource", RdbmsDataSource, DataSourceFactory); RdbmsDataSource::DBHosts RdbmsDataSource::dbhosts; RdbmsDataSource::FailedHosts RdbmsDataSource::failedhosts; @@ -202,7 +200,7 @@ RdbmsDataSource::connectTo(const ConnectionInfo & dsn) } } -RdbmsDataSource::RdbmsConnection::RdbmsConnection(const DB::Connection * con, time_t kat) : +RdbmsDataSource::RdbmsConnection::RdbmsConnection(DB::ConnectionPtr const con, time_t kat) : connection(con), txOpen(false), lastUsedTime(0), @@ -214,7 +212,6 @@ RdbmsDataSource::RdbmsConnection::RdbmsConnection(const DB::Connection * con, ti RdbmsDataSource::RdbmsConnection::~RdbmsConnection() { connection->finish(); - delete connection; } void @@ -246,14 +243,14 @@ RdbmsDataSource::RdbmsConnection::isExpired() const RdbmsDataSource::ConnectionInfo::ConnectionInfo(ScriptNodePtr node) : dsn(node->value("dsn", NULL).as<std::string>()), - typeId(InstanceMap<ConnectionLoader, std::string>::Get<UnknownConnectionProvider>(node->value("provider", NULL))) + typeId(node->value("provider", NULL).as<std::string>()) { } -DB::Connection * +DB::ConnectionPtr RdbmsDataSource::ConnectionInfo::connect() const { - return typeId->create(dsn); + return DB::ConnectionFactory::createNew(typeId, dsn); } bool @@ -290,21 +287,21 @@ RdbmsDataSource::ConnectionRef::operator=(const RdbmsDataSource::ConnectionRef & return *this; } -const DB::Connection * +DB::Connection * RdbmsDataSource::ConnectionRef::operator->() const { - return conn->connection; + return conn->connection.get(); } -const DB::Connection & +DB::Connection & RdbmsDataSource::ConnectionRef::operator*() const { return *conn->connection; } -const DB::Connection * +DB::Connection * RdbmsDataSource::ConnectionRef::get() const { - return conn->connection; + return conn->connection.get(); } diff --git a/project2/sql/rdbmsDataSource.h b/project2/sql/rdbmsDataSource.h index e347961..b1cb74c 100644 --- a/project2/sql/rdbmsDataSource.h +++ b/project2/sql/rdbmsDataSource.h @@ -10,23 +10,22 @@ #include <connection.h> #include <error.h> #include "scriptLoader.h" -#include "connectionLoader.h" /// Project2 component to provide access to transactional RDBMS data sources -class RdbmsDataSource : public DataSource { +class DLL_PUBLIC RdbmsDataSource : public DataSource { public: class ConnectionRef; class RdbmsConnection { public: - RdbmsConnection(const DB::Connection * connection, time_t kat); + RdbmsConnection(DB::ConnectionPtr const connection, time_t kat); ~RdbmsConnection(); void touch() const; bool isExpired() const; - const DB::Connection * const connection; + DB::ConnectionPtr const connection; bool txOpen; - boost::optional<std::thread::id> threadId; + std::optional<std::thread::id> threadId; private: friend class ConnectionRef; @@ -46,9 +45,9 @@ class RdbmsDataSource : public DataSource { ~ConnectionRef(); ConnectionRef & operator=(const ConnectionRef &); - const DB::Connection * operator->() const; - const DB::Connection & operator*() const; - const DB::Connection * get() const; + DB::Connection * operator->() const; + DB::Connection & operator*() const; + DB::Connection * get() const; private: ConnectionPtr conn; }; @@ -57,12 +56,12 @@ class RdbmsDataSource : public DataSource { public: ConnectionInfo(ScriptNodePtr); - DB::Connection * connect() const; + DB::ConnectionPtr connect() const; bool operator<(const ConnectionInfo & o) const; const std::string dsn; - const boost::shared_ptr<ConnectionLoader> typeId; + const std::string typeId; }; typedef std::map<std::string, ConnectionInfo> ReadonlyDSNs; // Map hostname to DSN string @@ -95,7 +94,7 @@ class RdbmsDataSource : public DataSource { typedef std::set<ChangedDSN> ChangedDSNs; static ChangedDSNs changedDSNs; - friend class RdbmsDataSourceLoader; + friend class RdbmsDataSourceFactory; }; #endif diff --git a/project2/sql/sql-modMySQL.cpp b/project2/sql/sql-modMySQL.cpp deleted file mode 100644 index 0466cbc..0000000 --- a/project2/sql/sql-modMySQL.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "connectionLoader.h" -#include "../libmysqlpp/connection.h" -#include "sql-modMySQL.h" -#include <misc.h> -#include <scripts.h> -#include <logger.h> -#include <fstream> - -typedef MySQL::Connection MySQLConnection; -DECLARE_GENERIC_LOADER("mysql", ConnectionLoader, MySQLConnection) - -MockMySQLDatabase::MockMySQLDatabase(const std::string & name, const std::vector<boost::filesystem::path> & ss) : - MockServerDatabase("options=p2testmysql", name, "mysql") -{ - CreateNewDatabase(); - PlaySchemaScripts(ss); -} - -DB::Connection * -MockMySQLDatabase::openConnection() const -{ - return InstanceMap<ConnectionLoader, std::string>::Get<std::invalid_argument>("mysql")->create( - stringbf("options=p2testmysql;database=%s", testDbName)); -} - -MockMySQLDatabase::~MockMySQLDatabase() -{ - DropDatabase(); -} - diff --git a/project2/sql/sql-modMySQL.h b/project2/sql/sql-modMySQL.h deleted file mode 100644 index b303e71..0000000 --- a/project2/sql/sql-modMySQL.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef MOCKMYSQLDATASOURCE_H -#define MOCKMYSQLDATASOURCE_H - -#include "mockDatabase.h" -#include <boost/filesystem/path.hpp> - -class MockMySQLDatabase : public MockServerDatabase { - public: - MockMySQLDatabase(const std::string & name, const std::vector<boost::filesystem::path> & ss); - ~MockMySQLDatabase(); - - private: - DB::Connection * openConnection() const override; -}; - -#endif - diff --git a/project2/sql/sql-modODBC.cpp b/project2/sql/sql-modODBC.cpp deleted file mode 100644 index 29d2441..0000000 --- a/project2/sql/sql-modODBC.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "connectionLoader.h" -#include "../libodbcpp/connection.h" -#include "sql-modODBC.h" -#include <misc.h> -#include <scripts.h> -#include <logger.h> - -typedef ODBC::Connection ODBCConnection; -DECLARE_GENERIC_LOADER("odbc", ConnectionLoader, ODBCConnection) - -MockODBCDatabase::MockODBCDatabase(const std::string & masterdb, const std::string & name, const std::vector<boost::filesystem::path> & ss) : - MockServerDatabase(masterdb, name, "odbc") -{ - CreateNewDatabase(); - PlaySchemaScripts(ss); -} - -DB::Connection * -MockODBCDatabase::openConnection() const -{ - return InstanceMap<ConnectionLoader, std::string>::Get<std::invalid_argument>("odbc")->create( - stringbf("Driver=postgresql;Database=%s;uid=postgres;servername=/run/postgresql", testDbName)); -} - -MockODBCDatabase::~MockODBCDatabase() -{ - DropDatabase(); -} - -void MockODBCDatabase::DropDatabase() const -{ - Logger()->messagebf(LOG_INFO, "Killing any active connections to database %s", testDbName); - master->execute("SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '" + testDbName + "'"); - MockServerDatabase::DropDatabase(); -} - diff --git a/project2/sql/sql-modODBC.h b/project2/sql/sql-modODBC.h deleted file mode 100644 index e7d7bdb..0000000 --- a/project2/sql/sql-modODBC.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef MOCKODBCDATASOURCE_H -#define MOCKODBCDATASOURCE_H - -#include "mockDatabase.h" -#include <boost/filesystem/path.hpp> - -class MockODBCDatabase : public MockServerDatabase { - public: - MockODBCDatabase(const std::string & master, const std::string & name, const std::vector<boost::filesystem::path> & ss); - ~MockODBCDatabase(); - - protected: - void DropDatabase() const override; - - private: - DB::Connection * openConnection() const override; -}; - -#endif - - diff --git a/project2/sql/sql-modPQ.cpp b/project2/sql/sql-modPQ.cpp deleted file mode 100644 index ec2fcf3..0000000 --- a/project2/sql/sql-modPQ.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "connectionLoader.h" -#include "../libpqpp/connection.h" -#include "sql-modPQ.h" -#include <misc.h> -#include <scripts.h> -#include <logger.h> - -typedef PQ::Connection PQConnection; -DECLARE_GENERIC_LOADER("postgresql", ConnectionLoader, PQConnection) - -MockPqDatabase::MockPqDatabase(const std::string & masterdb, const std::string & name, const std::vector<boost::filesystem::path> & ss) : - MockServerDatabase(masterdb, name, "postgresql") -{ - CreateNewDatabase(); - PlaySchemaScripts(ss); -} - -DB::Connection * -MockPqDatabase::openConnection() const -{ - return InstanceMap<ConnectionLoader, std::string>::Get<std::invalid_argument>("postgresql")->create( - stringbf("user=postgres dbname=%s", testDbName)); -} - -MockPqDatabase::~MockPqDatabase() -{ - DropDatabase(); -} - -void MockPqDatabase::DropDatabase() const -{ - Logger()->messagebf(LOG_INFO, "Killing any active connections to database %s", testDbName); - master->execute("SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '" + testDbName + "'"); - MockServerDatabase::DropDatabase(); -} - diff --git a/project2/sql/sql-modPQ.h b/project2/sql/sql-modPQ.h deleted file mode 100644 index 43ef1ee..0000000 --- a/project2/sql/sql-modPQ.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef MOCKPQDATASOURCE_H -#define MOCKPQDATASOURCE_H - -#include "mockDatabase.h" -#include <boost/filesystem/path.hpp> - -class MockPqDatabase : public MockServerDatabase { - public: - MockPqDatabase(const std::string & master, const std::string & name, const std::vector<boost::filesystem::path> & ss); - ~MockPqDatabase(); - - protected: - void DropDatabase() const override; - - private: - DB::Connection * openConnection() const override; -}; - -#endif - diff --git a/project2/sql/sql-modSQLite.cpp b/project2/sql/sql-modSQLite.cpp deleted file mode 100644 index ef8e133..0000000 --- a/project2/sql/sql-modSQLite.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "connectionLoader.h" -#include "../libsqlitepp/connection.h" -#include "sql-modSQLite.h" -#include <misc.h> -#include <scripts.h> -#include <logger.h> -#include <boost/filesystem/operations.hpp> -#include "mockDatasource.h" - -typedef SQLite::Connection SQLiteConnection; -DECLARE_GENERIC_LOADER("sqlite", ConnectionLoader, SQLiteConnection) - -MockSQLiteDatabase::MockSQLiteDatabase(const std::string & name, const std::vector<boost::filesystem::path> & ss) : - MockDatabase(name), - testDbPath(boost::filesystem::path("/tmp") / "sqliteut" / stringbf("%d", getpid()) / stringbf("%d", ++MockConnectionLoader::mocked)) -{ - CreateNewDatabase(); - PlaySchemaScripts(ss); -} - -DB::Connection * -MockSQLiteDatabase::openConnection() const -{ - return InstanceMap<ConnectionLoader, std::string>::Get<std::invalid_argument>("sqlite")->create(testDbPath.string()); -} - -MockSQLiteDatabase::~MockSQLiteDatabase() -{ - DropDatabase(); -} - -void MockSQLiteDatabase::DropDatabase() const -{ - Logger()->messagebf(LOG_INFO, "Deleting database %s", testDbPath); - boost::filesystem::remove(testDbPath); -} - -void MockSQLiteDatabase::CreateNewDatabase() const -{ - Logger()->messagebf(LOG_INFO, "Creating new database at %s", testDbPath); - boost::filesystem::create_directories(testDbPath.parent_path()); - delete openConnection(); -} - - diff --git a/project2/sql/sql-modSQLite.h b/project2/sql/sql-modSQLite.h deleted file mode 100644 index 36bca22..0000000 --- a/project2/sql/sql-modSQLite.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef MOCKSQLITEDATASOURCE_H -#define MOCKSQLITEDATASOURCE_H - -#include "mockDatabase.h" -#include <boost/filesystem/path.hpp> - -class MockSQLiteDatabase : public MockDatabase { - public: - MockSQLiteDatabase(const std::string & name, const std::vector<boost::filesystem::path> & ss); - ~MockSQLiteDatabase(); - - protected: - void DropDatabase() const override; - void CreateNewDatabase() const override; - - DB::Connection * openConnection() const override; - - private: - const boost::filesystem::path testDbPath; -}; - -#endif - - diff --git a/project2/sql/sql.ll b/project2/sql/sql.ll deleted file mode 100644 index ab40642..0000000 --- a/project2/sql/sql.ll +++ /dev/null @@ -1,123 +0,0 @@ -%option batch -%option c++ -%option noyywrap -%option 8bit -%option stack -%option yylineno -%option yyclass="sqlFlexLexer" -%option prefix="sqlBase" - -%{ -#include <stdexcept> -#include "sqlFlexLexer.h" -#pragma GCC diagnostic ignored "-Wsign-compare" -%} - -space [ \t\n\r\f] -non_newline [^\r\n] -mcomment_start "/*" -mcomment_stop "*/" -comment ("--"{non_newline}*) -other . -term ; -any ({other}|{space}) -quote ' -quote_apos '' -dolq_start [A-Za-z\200-\377_] -dolq_cont [A-Za-z\200-\377_0-9] -dollarquote \$({dolq_start}{dolq_cont}*)?\$ - -p2mockscriptdir "$P2MOCKSCRIPTDIR" - -%x COMMENT -%x STATEMENT -%x QUOTE -%x DOLLARQUOTE - -%% -{mcomment_start} { - comment += YYText(); - yy_push_state(COMMENT); -} - -<COMMENT>{mcomment_stop} { - comment += YYText(); - Comment(comment); - comment.clear(); - yy_pop_state(); -} - -<COMMENT>{any} { - comment += YYText(); -} - -<COMMENT><<EOF>> { - throw std::runtime_error("Unterminated comment"); -} - -{comment} { - Comment(YYText()); -} - -{other} { - statement += YYText(); - yy_push_state(STATEMENT); -} - -<STATEMENT>{quote} { - statement += YYText(); - yy_push_state(QUOTE); -} - -<STATEMENT>{dollarquote} { - statement += YYText(); - yy_push_state(DOLLARQUOTE); -} - -<QUOTE>{quote} { - statement += YYText(); - yy_pop_state(); -} - -<QUOTE>{p2mockscriptdir} { - statement += MockScriptDir(); -} - -<QUOTE>{quote_apos} { - statement += YYText(); -} - -<DOLLARQUOTE>{any} { - statement += YYText(); -} - -<DOLLARQUOTE>{dollarquote} { - statement += YYText(); - yy_pop_state(); -} - -<DOLLARQUOTE><<EOF>> { - throw std::runtime_error("Unterminated dollar quoted string"); -} - -<QUOTE>{any} { - statement += YYText(); -} - -<QUOTE><<EOF>> { - throw std::runtime_error("Unterminated quoted string"); -} - -<STATEMENT>{term} { - Statement(statement); - statement.clear(); - yy_pop_state(); -} - -<STATEMENT>{any} { - statement += YYText(); -} - -<*>[ \t\r\n\f] { -} - diff --git a/project2/sql/sqlBase.cpp b/project2/sql/sqlBase.cpp new file mode 100644 index 0000000..dd1e90d --- /dev/null +++ b/project2/sql/sqlBase.cpp @@ -0,0 +1,24 @@ +#include "sqlBase.h" +#include <commonObjects.h> +#include "rdbmsDataSource.h" + +SqlBase::SqlBase(ScriptNodePtr p) : + SourceObject(p), + dataSource(p, "datasource"), + db(NULL) +{ +} + +SqlBase::SqlBase(const std::string & datasource) : + SourceObject(ScriptNodePtr()), + dataSource(datasource), + db(NULL) +{ +} + +void +SqlBase::loadComplete(const CommonObjects * co) +{ + db = co->dataSource<RdbmsDataSource>(dataSource(NULL)); +} + diff --git a/project2/sql/sqlBase.h b/project2/sql/sqlBase.h new file mode 100644 index 0000000..7e906c3 --- /dev/null +++ b/project2/sql/sqlBase.h @@ -0,0 +1,23 @@ +#ifndef SQLBASE_H +#define SQLBASE_H + +#include <sourceObject.h> +#include <variables.h> + +class RdbmsDataSource; + +class DLL_PUBLIC SqlBase : public virtual SourceObject { + public: + SqlBase(ScriptNodePtr); + SqlBase(const std::string &); + + virtual void loadComplete(const CommonObjects *) override; + + const Variable dataSource; + + protected: + const RdbmsDataSource * db; +}; + +#endif + diff --git a/project2/sql/sqlBulkLoad.cpp b/project2/sql/sqlBulkLoad.cpp index 813323c..fc7e7e1 100644 --- a/project2/sql/sqlBulkLoad.cpp +++ b/project2/sql/sqlBulkLoad.cpp @@ -2,43 +2,38 @@ #include "task.h" #include <commonObjects.h> #include "rdbmsDataSource.h" -#include "scopeObject.h" +#include <scopeExit.h> #include "stream.h" +#include "sqlBase.h" -class SqlBulkLoad : public Task { +class SqlBulkLoad : public Task, SqlBase { public: SqlBulkLoad(ScriptNodePtr p) : SourceObject(p), Task(p), - dataSource(p, "datasource"), + SqlBase(p), targetTable(p, "targettable"), - extras(p, "extras"), - db(NULL) + extras(p, "extras") { - p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&stream)); - } - - void loadComplete(const CommonObjects * co) - { - db = co->dataSource<RdbmsDataSource>(dataSource(NULL)); + p->script.lock()->loader.addLoadTarget(p, Storer::into<StreamFactory>(&stream)); } void execute(ExecContext * ec) const { auto wdb = db->getWritable(); - wdb->beginBulkUpload(targetTable(ec), extras(ec)); - ScopeObject tidy([]{}, + const std::string tt(targetTable(ec)); + const std::string x(extras(ec)); + wdb->beginBulkUpload(tt.c_str(), x.c_str()); + AdHoc::ScopeExit tidy([]{}, [&]{ wdb->endBulkUpload(NULL); }, [&]{ wdb->endBulkUpload("Stack unwind in progress"); }); stream->runStream(boost::bind(&DB::Connection::bulkUploadData, wdb.get(), _1, _2), ec); } - const Variable dataSource; const Variable targetTable; const Variable extras; StreamPtr stream; - protected: - const RdbmsDataSource * db; }; -DECLARE_LOADER("sqlbulkload", SqlBulkLoad); +NAMEDFACTORY("sqlbulkload", SqlBulkLoad, TaskFactory); + diff --git a/project2/sql/sqlCache.cpp b/project2/sql/sqlCache.cpp index 142bf6f..79e2e83 100644 --- a/project2/sql/sqlCache.cpp +++ b/project2/sql/sqlCache.cpp @@ -16,12 +16,10 @@ #include <boost/algorithm/string/predicate.hpp> #include <boost/date_time/posix_time/posix_time.hpp> -typedef boost::shared_ptr<DB::SelectCommand> SelectPtr; -typedef boost::shared_ptr<DB::ModifyCommand> ModifyPtr; - class SqlCache : public RowSetCache { public: SqlCache(ScriptNodePtr p) : + SourceObject(p), RowSetCache(p), db(NULL) { @@ -32,7 +30,7 @@ class SqlCache : public RowSetCache { db = co->dataSource<RdbmsDataSource>(DataSource); } - static void appendKeyCols(Buffer * sql, unsigned int * off, const Glib::ustring & col) + static void appendKeyCols(AdHoc::Buffer * sql, unsigned int * off, const Glib::ustring & col) { if ((*off)++) { sql->append(", "); @@ -40,7 +38,7 @@ class SqlCache : public RowSetCache { sql->append(col.c_str()); } - static void appendKeyBinds(Buffer * sql, unsigned int * off) + static void appendKeyBinds(AdHoc::Buffer * sql, unsigned int * off) { if ((*off)++) { sql->append(", "); @@ -48,19 +46,20 @@ class SqlCache : public RowSetCache { sql->append("?"); } - static void appendKeyAnds(Buffer * sql, const Glib::ustring & col) + static void appendKeyAnds(AdHoc::Buffer * sql, const Glib::ustring & col) { sql->appendf(" AND h.%s = ?", col.c_str()); } static void bindKeyValues(DB::Command * cmd, unsigned int * offset, const VariableType & v) { - boost::apply_visitor<const SqlVariableBinder, const VariableType>(SqlVariableBinder(cmd, (*offset)++), v); + boost::apply_visitor(SqlVariableBinder(cmd, (*offset)++), v); } class SqlCacheRowSet : public RowSet { public: - SqlCacheRowSet(SelectPtr r) : + SqlCacheRowSet(DB::SelectCommandPtr r) : + SourceObject(ScriptNodePtr()), RowSet(NULL), s(r) { } @@ -98,7 +97,7 @@ class SqlCache : public RowSetCache { const DB::Column & col = (*s)[c]; if (!boost::algorithm::starts_with(col.name, "p2attr_") && !boost::algorithm::starts_with(col.name, "p2_")) { - ss.columns.insert(new Column(colNo++, col.name)); + ss.columns.insert(std::make_shared<Column>(colNo++, col.name)); colCols.push_back(c); } } @@ -120,14 +119,14 @@ class SqlCache : public RowSetCache { } while (s->fetch()); } private: - SelectPtr s; + DB::SelectCommandPtr s; mutable std::vector<unsigned int> colCols; mutable int64_t cacheId; }; RowSetCPtr getCachedRowSet(ExecContext * ec, const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) const { - Buffer sql; + AdHoc::Buffer sql; sql.appendf("SELECT r.* \ FROM %s p, %s_%s_%s h LEFT OUTER JOIN %s_%s_%s_rows r \ ON h.p2_cacheid = r.p2_cacheid \ @@ -139,12 +138,12 @@ class SqlCache : public RowSetCache { applyKeys(ec, boost::bind(appendKeyAnds, &sql, _1), ps); sql.appendf(" ORDER BY r.p2_cacheid DESC, r.p2_row"); auto con = db->getReadonly(); - SelectPtr gh(con->newSelectCommand(sql)); + auto gh = con->select(sql); unsigned int offset = 0; gh->bindParamT(offset++, boost::posix_time::microsec_clock::universal_time() - boost::posix_time::seconds(CacheLife)); applyKeys(ec, boost::bind(bindKeyValues, gh.get(), &offset, _2), ps); if (gh->fetch()) { - return new SqlCacheRowSet(gh); + return std::make_shared<SqlCacheRowSet>(gh); } return NULL; } @@ -166,7 +165,7 @@ class SqlCache : public RowSetCache { cols[name] = value; } void finishRow() const { - Buffer sql; + AdHoc::Buffer sql; sql.appendf("INSERT INTO %s_%s_%s_rows(p2_row", HeaderTable.c_str(), n.c_str(), f.c_str()); for (const Values::value_type & a : attrs) { sql.appendf(", p2attr_%s", a.first.c_str()); @@ -183,14 +182,14 @@ class SqlCache : public RowSetCache { } sql.appendf(")"); auto con = db->getWritable(); - ModifyPtr m(con->newModifyCommand(sql)); + auto m = con->modify(sql); unsigned int offset = 0; m->bindParamI(offset++, row++); for (const Values::value_type & a : attrs) { - boost::apply_visitor<const SqlVariableBinder, const VariableType>(SqlVariableBinder(m.get(), offset++), a.second); + boost::apply_visitor(SqlVariableBinder(m.get(), offset++), a.second); } for (const Values::value_type & v : cols) { - boost::apply_visitor<const SqlVariableBinder, const VariableType>(SqlVariableBinder(m.get(), offset++), v.second); + boost::apply_visitor(SqlVariableBinder(m.get(), offset++), v.second); } m->execute(); cols.clear(); @@ -206,19 +205,19 @@ class SqlCache : public RowSetCache { RowSetPresenterPtr openFor(ExecContext * ec, const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) { - Buffer sp; + AdHoc::Buffer sp; sp.appendf("SAVEPOINT sp%p", this); auto con = db->getWritable(); - ModifyPtr s = ModifyPtr(con->newModifyCommand(sp)); + auto s = con->modify(sp); s->execute(); // Header - Buffer del; + AdHoc::Buffer del; del.appendf("INSERT INTO %s(p2_time) VALUES(?)", HeaderTable.c_str()); - ModifyPtr h = ModifyPtr(con->newModifyCommand(del)); + auto h = con->modify(del); h->bindParamT(0, boost::posix_time::microsec_clock::universal_time()); h->execute(); // Record set header - Buffer sql; + AdHoc::Buffer sql; sql.appendf("INSERT INTO %s_%s_%s(", HeaderTable.c_str(), n.c_str(), f.c_str()); unsigned int offset = 0; applyKeys(ec, boost::bind(appendKeyCols, &sql, &offset, _1), ps); @@ -226,34 +225,34 @@ class SqlCache : public RowSetCache { offset = 0; applyKeys(ec, boost::bind(appendKeyBinds, &sql, &offset), ps); sql.appendf(")"); - ModifyPtr m(con->newModifyCommand(sql)); + auto m = con->modify(sql); offset = 0; applyKeys(ec, boost::bind(bindKeyValues, m.get(), &offset, _2), ps); m->execute(); - return new SqlCachePresenter(n, f, db); + return std::make_shared<SqlCachePresenter>(n, f, db); } void save(ExecContext *, const Glib::ustring & , const Glib::ustring & , const IHaveParameters * ) { - Buffer sp; + AdHoc::Buffer sp; sp.appendf("RELEASE SAVEPOINT sp%p", this); auto con = db->getWritable(); - ModifyPtr s = ModifyPtr(con->newModifyCommand(sp)); + auto s = con->modify(sp); s->execute(); } void discard(ExecContext *, const Glib::ustring & , const Glib::ustring & , const IHaveParameters * ) { - Buffer sp; + AdHoc::Buffer sp; sp.appendf("ROLLBACK TO SAVEPOINT sp%p", this); auto con = db->getWritable(); - ModifyPtr s = ModifyPtr(con->newModifyCommand(sp)); + auto s = con->modify(sp); s->execute(); } INITOPTIONS; private: - friend class CustomSqlCacheLoader; + friend class CustomSqlCacheFactory; const RdbmsDataSource * db; static std::string DataSource; static std::string HeaderTable; @@ -264,16 +263,16 @@ std::string SqlCache::DataSource; std::string SqlCache::HeaderTable; time_t SqlCache::CacheLife; -class CustomSqlCacheLoader : public ElementLoader::For<SqlCache> { +class CustomSqlCacheFactory : public RowSetCacheFactory::For<SqlCache>, public LifeCycle { public: void onIdle() override { try { if (!SqlCache::DataSource.empty()) { - boost::intrusive_ptr<CommonObjects> co = new CommonObjects(); + std::shared_ptr<CommonObjects> co = std::make_shared<CommonObjects>(); RdbmsDataSource * db = co->dataSource<RdbmsDataSource>(SqlCache::DataSource); auto con = db->getWritable(); - ModifyPtr m(con->newModifyCommand(stringbf("DELETE FROM %s WHERE p2_time < ?", SqlCache::HeaderTable))); + auto m = con->modify(stringbf("DELETE FROM %s WHERE p2_time < ?", SqlCache::HeaderTable)); m->bindParamT(0, boost::posix_time::microsec_clock::universal_time() - boost::posix_time::seconds(SqlCache::CacheLife)); m->execute(); db->commit(); @@ -284,7 +283,7 @@ class CustomSqlCacheLoader : public ElementLoader::For<SqlCache> { } } }; -DECLARE_CUSTOM_LOADER("sqlcache", CustomSqlCacheLoader); +NAMEDPLUGIN("sqlcache", CustomSqlCacheFactory, RowSetCacheFactory); DECLARE_OPTIONS(SqlCache, "SQL Cache options") ("cache.sql.dataSource", Options::value(&DataSource), diff --git a/project2/sql/sqlFlexLexer.cpp b/project2/sql/sqlFlexLexer.cpp deleted file mode 100644 index eaacd50..0000000 --- a/project2/sql/sqlFlexLexer.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#define yyFlexLexer sqlBaseFlexLexer -#include <FlexLexer.h> -#include "sqlFlexLexer.h" -#include <logger.h> - -sqlFlexLexer::sqlFlexLexer(const boost::filesystem::path & s, std::istream & f, DB::Connection * c) : - yyFlexLexer(&f, NULL), - conn(c), - script(s) -{ -} - -void -sqlFlexLexer::LexerError(const char * msg) -{ - throw std::runtime_error(msg); -} - -void -sqlFlexLexer::Comment(const std::string & text) -{ - Logger()->messagebf(LOG_DEBUG, "Got comment: %s", text); -} - -void -sqlFlexLexer::Statement(const std::string & text) -{ - Logger()->messagebf(LOG_DEBUG, "Got statement: %s", text); - conn->execute(text); -} - -std::string -sqlFlexLexer::MockScriptDir() const -{ - return script.string(); -} - diff --git a/project2/sql/sqlFlexLexer.h b/project2/sql/sqlFlexLexer.h deleted file mode 100644 index 55019e5..0000000 --- a/project2/sql/sqlFlexLexer.h +++ /dev/null @@ -1,24 +0,0 @@ -#include <istream> -#include <string> -#include <connection.h> -#include <boost/filesystem/path.hpp> - -class sqlFlexLexer : public yyFlexLexer { - public: - sqlFlexLexer(const boost::filesystem::path &, std::istream &, DB::Connection *); - int yylex(); - - void Comment(const std::string &); - void Statement(const std::string &); - std::string MockScriptDir() const; - - protected: - void LexerError(const char *) override; - - private: - DB::Connection * conn; - const boost::filesystem::path script; - std::string comment; - std::string statement; -}; - diff --git a/project2/sql/sqlHandleAsVariableType.cpp b/project2/sql/sqlHandleAsVariableType.cpp index ac1ea3b..a692a40 100644 --- a/project2/sql/sqlHandleAsVariableType.cpp +++ b/project2/sql/sqlHandleAsVariableType.cpp @@ -5,8 +5,8 @@ void HandleAsVariableType::null() { variable = Null(); } -void HandleAsVariableType::string(const char * c, size_t l) { - variable = Glib::ustring(c, c + l); +void HandleAsVariableType::string(const std::string_view s) { + variable = Glib::ustring(s.begin(), s.end()); } void HandleAsVariableType::integer(int64_t i) { variable = i; diff --git a/project2/sql/sqlHandleAsVariableType.h b/project2/sql/sqlHandleAsVariableType.h index d843c4e..5bf38c3 100644 --- a/project2/sql/sqlHandleAsVariableType.h +++ b/project2/sql/sqlHandleAsVariableType.h @@ -4,10 +4,10 @@ #include "column.h" #include "variables.h" -class HandleAsVariableType : public DB::HandleField { +class DLL_PUBLIC HandleAsVariableType : public DB::HandleField { public: void null(); - void string(const char * c, size_t l); + void string(const std::string_view l); void integer(int64_t i); void boolean(bool i); void floatingpoint(double d); diff --git a/project2/sql/sqlMergeTask.cpp b/project2/sql/sqlMergeTask.cpp index 91bf3e0..f78862f 100644 --- a/project2/sql/sqlMergeTask.cpp +++ b/project2/sql/sqlMergeTask.cpp @@ -6,19 +6,21 @@ #include "exceptions.h" #include "sqlVariableBinder.h" #include "scriptLoader.h" -#include "scopeObject.h" +#include <scopeExit.h> #include "execContext.h" -#include <misc.h> +#include <buffer.h> #include <stdio.h> #include <stdexcept> #include <boost/algorithm/string/join.hpp> #include <boost/bind.hpp> bool SqlMergeTask::defaultUseTempTable = true; -static void attach(boost::intrusive_ptr<IHaveSubTasks> i, DB::ModifyCommand * insert); +static void attach(std::shared_ptr<IHaveSubTasks> i, DB::ModifyCommandPtr insert); + +#define foreach(_type, _con, _it) for (_type _it = ((_con).begin()); _it != ((_con).end()); _it++) class SqlMergeInsert; -typedef boost::intrusive_ptr<SqlMergeInsert> SqlMergeInsertPtr; +typedef std::shared_ptr<SqlMergeInsert> SqlMergeInsertPtr; /// Project2 component insert custom constructed records during an SQL Merge task class SqlMergeInsert : IHaveParameters, public Task { public: @@ -31,22 +33,22 @@ class SqlMergeInsert : IHaveParameters, public Task { void execute(ExecContext * ec) const { unsigned int col = 0; for (const Parameters::value_type & v : parameters) { - boost::apply_visitor<const SqlVariableBinder, const VariableType>(SqlVariableBinder(insert, col++), v.second(ec)); + boost::apply_visitor(SqlVariableBinder(insert.get(), col++), v.second(ec)); } insert->execute(); } private: - friend void attach(SqlMergeInsertPtr i, DB::ModifyCommand * insert); - DB::ModifyCommand * insert; + friend void attach(SqlMergeInsertPtr i, DB::ModifyCommandPtr insert); + DB::ModifyCommandPtr insert; }; -DECLARE_LOADER("sqlmerge", SqlMergeTask); -DECLARE_LOADER("sqlmergeinsert", SqlMergeInsert); +NAMEDFACTORY("sqlmerge", SqlMergeTask, TaskFactory); +NAMEDFACTORY("sqlmergeinsert", SqlMergeInsert, TaskFactory); // Conversion logic SqlMergeTask::SqlMergeTask(const std::string & datasource, const std::string & target) : SourceObject(__PRETTY_FUNCTION__), - Task(NULL), + Task(__PRETTY_FUNCTION__), insteadOfDelete(NULL), updateWhere(NULL), patchOrder(NULL), @@ -85,7 +87,7 @@ SqlMergeTask::SqlMergeTask(ScriptNodePtr p) : dtable(p->value("targettable", NULL).as<std::string>()), dtablet(stringf("tmp_%s_%d", dtable.c_str(), getpid())) { - p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&sources)); + p->script.lock()->loader.addLoadTarget(p, Storer::into<TaskFactory>(&sources)); if (!sources.empty() && useView(NULL)) { throw NotSupported("useview not supported with iterate fillers"); @@ -113,7 +115,6 @@ SqlMergeTask::SqlMergeTask(ScriptNodePtr p) : SqlMergeTask::~SqlMergeTask() { - delete insCmd; delete sqlCommand; } @@ -145,7 +146,7 @@ SqlMergeTask::execute(ExecContext * ec) const { auto savepoint(stringf("sqlmerge_savepoint_%p", this)); destdb->savepoint(savepoint); - ScopeObject SPHandler(NULL, + AdHoc::ScopeExit SPHandler(NULL, boost::bind(&DB::Connection::releaseSavepoint, destdb.get(), savepoint), boost::bind(&DB::Connection::rollbackToSavepoint, destdb.get(), savepoint)); createTempTable(); @@ -161,14 +162,23 @@ SqlMergeTask::execute(ExecContext * ec) const for (const TargetColumnPtr & c : cols) { colNames.insert(c->column); } - TablePatch tp(*destdb, dtablet, dtable, colNames); - tp.doDelete = doDelete(NULL); - tp.doUpdate = doUpdate(NULL); - tp.doInsert = doInsert(NULL); + DB::TablePatch tp; + tp.src = dtablet; + tp.dest = dtable; + tp.cols = colNames; + tp.doDeletes = doDelete(ec); + tp.doUpdates = doUpdate(ec); + tp.doInserts = doInsert(ec); for (const Keys::value_type & k : keys) { - tp.addKey(k); + tp.pk.insert(k); } - tp.patch(ec, insteadOfDelete, updateWhere, patchOrder); + DynamicSql::SqlWriterWrapper iod(ec, insteadOfDelete.get()); + tp.insteadOfDelete = insteadOfDelete ? &iod : nullptr; + DynamicSql::SqlWriterWrapper uw(ec, updateWhere.get()); + tp.where = updateWhere ? &uw : nullptr; + DynamicSql::SqlWriterWrapper po(ec, patchOrder.get()); + tp.order = patchOrder ? &po : nullptr; + destdb->patchTable(&tp); dropTempTable(); } @@ -176,28 +186,25 @@ void SqlMergeTask::createTempTable() const { if (useView(NULL)) { - DB::ModifyCommand * cv = destdb->newModifyCommand(stringf( - "CREATE VIEW %s AS %s", - dtablet.c_str(), - sqlCommand->getSqlFor("").c_str())); - cv->execute(); - delete cv; + AdHoc::Buffer b; + b.appendf( "CREATE VIEW %s AS ", dtablet.c_str()); + sqlCommand->setFilter(Glib::ustring()); + sqlCommand->writeSql(b); + destdb->modify(b)->execute(); } else { - DB::ModifyCommand * ctt = destdb->newModifyCommand(stringf( + auto ctt = destdb->modify(stringf( "CREATE TEMPORARY TABLE %s AS SELECT * FROM %s WHERE 0=1", dtablet.c_str(), dtable.c_str())); ctt->execute(); - delete ctt; for (Columns::value_type c : cols) { if (!c->maptable.empty()) { - DB::ModifyCommand * at = destdb->newModifyCommand(stringf( + auto at = destdb->modify(stringf( "ALTER TABLE %s ADD COLUMN %s VARCHAR(1000)", dtablet.c_str(), c->mapcolumn.c_str())); at->execute(); - delete at; } } } @@ -207,15 +214,14 @@ void SqlMergeTask::dropTempTable() const { if (tempTableCreated) { - DB::ModifyCommand * d; + DB::ModifyCommandPtr d; if (useView(NULL)) { - d = destdb->newModifyCommand("DROP VIEW " + dtablet); + d = destdb->modify("DROP VIEW " + dtablet); } else { - d = destdb->newModifyCommand("DROP TABLE " + dtablet); + d = destdb->modify("DROP TABLE " + dtablet); } d->execute(); - delete d; } } void @@ -223,28 +229,26 @@ SqlMergeTask::createTempKey() const { if (useView(NULL)) return; /* Primary key */ - Buffer idx; + AdHoc::Buffer idx; idx.appendf("ALTER TABLE %s ADD CONSTRAINT pk_%s PRIMARY KEY(%s)", dtablet.c_str(), dtablet.c_str(), boost::algorithm::join(keys, ", ").c_str()); - DB::ModifyCommand * at = destdb->newModifyCommand(idx); + DB::ModifyCommandPtr at = destdb->modify(idx); at->execute(); - delete at; /* Indexes */ int n = 0; for (const Keys::value_type & i : indexes) { - DB::ModifyCommand * ci = destdb->newModifyCommand(stringf( + DB::ModifyCommandPtr ci = destdb->modify(stringf( "CREATE INDEX idx_%s_%d ON %s(%s)", dtablet.c_str(), n, dtablet.c_str(), i.c_str())); ci->execute(); - delete ci; n += 1; } } -DB::ModifyCommand * +DB::ModifyCommandPtr SqlMergeTask::insertCommand() const { - Buffer ins; + AdHoc::Buffer ins; ins.appendf("INSERT INTO %s(", dtablet.c_str()); foreach(Columns::const_iterator, cols, c) { if (c != cols.begin()) { @@ -262,14 +266,14 @@ SqlMergeTask::insertCommand() const } } ins.append(")"); - return destdb->newModifyCommand(ins); + return destdb->modify(ins); } -class Populate : public NoOutputExecute { +class Populate : public Task { public: - Populate(DB::ModifyCommand * c) : + Populate(DB::ModifyCommandPtr c) : SourceObject(__FUNCTION__), - NoOutputExecute(__FUNCTION__), + Task(__FUNCTION__), cmd(c) { } @@ -282,14 +286,14 @@ class Populate : public NoOutputExecute { private: void bind(unsigned int & idx, const VariableType & value) const { - boost::apply_visitor<const SqlVariableBinder, const VariableType>(SqlVariableBinder(cmd, idx++), value); + boost::apply_visitor(SqlVariableBinder(cmd.get(), idx++), value); } - DB::ModifyCommand * cmd; + DB::ModifyCommandPtr cmd; }; -typedef boost::intrusive_ptr<Populate> PopulatePtr; +typedef std::shared_ptr<Populate> PopulatePtr; void -attach(SqlMergeInsertPtr i, DB::ModifyCommand * insert) +attach(SqlMergeInsertPtr i, DB::ModifyCommandPtr insert) { if (i) { i->insert = insert; @@ -297,18 +301,18 @@ attach(SqlMergeInsertPtr i, DB::ModifyCommand * insert) } static void -attach(boost::intrusive_ptr<IHaveSubTasks> i, DB::ModifyCommand * insert) +attach(std::shared_ptr<IHaveSubTasks> i, DB::ModifyCommandPtr insert) { if (!i) { return; } if (i->normal.empty()) { - i->normal.push_back(new Populate(insert)); + i->normal.push_back(std::make_shared<Populate>(insert)); } else { for (const IHaveSubTasks::Tasks::value_type & n : i->normal) { - attach(boost::dynamic_pointer_cast<IHaveSubTasks>(n), insert); - attach(boost::dynamic_pointer_cast<SqlMergeInsert>(n), insert); + attach(std::dynamic_pointer_cast<IHaveSubTasks>(n), insert); + attach(std::dynamic_pointer_cast<SqlMergeInsert>(n), insert); } } } @@ -323,7 +327,7 @@ SqlMergeTask::copyToTempTable(ExecContext * ec) const i->execute(ec); } if (sqlCommand) { - Buffer ins; + AdHoc::Buffer ins; ins.appendf("INSERT INTO %s(", dtablet.c_str()); foreach(Columns::const_iterator, cols, c) { if (c != cols.begin()) { @@ -338,16 +342,18 @@ SqlMergeTask::copyToTempTable(ExecContext * ec) const } ins.append((*c)->column); } - ins.appendf(" FROM (%s) tmp_src", sqlCommand->getSqlFor("").c_str()); - DB::ModifyCommand * cttt = destdb->newModifyCommand(ins); + ins.appendf(" FROM ("); + sqlCommand->setFilter(Glib::ustring()); + sqlCommand->writeSql(ins); + ins.appendf(") tmp_src"); + auto cttt = destdb->modify(ins); unsigned int off = 0; - sqlCommand->bindParams(ec, cttt, off); + sqlCommand->bindParams(ec, cttt.get(), off); cttt->execute(); - delete cttt; } for (Columns::value_type c : cols) { if (!c->maptable.empty()) { - DB::ModifyCommand * utt = destdb->newModifyCommand( + auto utt = destdb->modify( stringf( "UPDATE %s d SET %s = (SELECT m.%s FROM %s m WHERE m.%s = d.%s) WHERE %s IS NULL", dtablet.c_str(), @@ -358,7 +364,6 @@ SqlMergeTask::copyToTempTable(ExecContext * ec) const c->mapcolumn.c_str(), c->column.c_str())); utt->execute(); - delete utt; } } } diff --git a/project2/sql/sqlMergeTask.h b/project2/sql/sqlMergeTask.h index eec98cd..f2a825a 100644 --- a/project2/sql/sqlMergeTask.h +++ b/project2/sql/sqlMergeTask.h @@ -7,9 +7,9 @@ #include <buffer.h> #include "tablepatch.h" #include "task.h" -#include "iterate.h" +#include <tasks/iterate.h> #include "variables.h" -#include "sqlWriter.h" +#include "sqlWriters.h" #include "rdbmsDataSource.h" #include <string> #include <set> @@ -17,13 +17,13 @@ #include <list> /// Project2 component merge arbitrary data into an RDBMS table -class SqlMergeTask : public Task { +class DLL_PUBLIC SqlMergeTask : public Task { public: typedef std::string Table; typedef std::string Column; class TargetColumn; - typedef boost::intrusive_ptr<TargetColumn> TargetColumnPtr; - class TargetColumn : public virtual IntrusivePtrBase { + typedef std::shared_ptr<TargetColumn> TargetColumnPtr; + class TargetColumn { public: class Sort { public: @@ -69,8 +69,8 @@ class SqlMergeTask : public Task { typedef ANONSTORAGEOF(IHaveSubTasks) Sources; DynamicSql::SqlCommand * sqlCommand; protected: - DB::ModifyCommand * insertCommand() const; - DB::ModifyCommand * insCmd; + DB::ModifyCommandPtr insertCommand() const; + DB::ModifyCommandPtr insCmd; public: Sources sources; diff --git a/project2/sql/sqlRows.cpp b/project2/sql/sqlRows.cpp index f8a16e1..3a65c9b 100644 --- a/project2/sql/sqlRows.cpp +++ b/project2/sql/sqlRows.cpp @@ -10,13 +10,13 @@ #include "commonObjects.h" #include <boost/date_time/gregorian/gregorian_types.hpp> -DECLARE_LOADER("sqlrows", SqlRows); +NAMEDFACTORY("sqlrows", SqlRows, RowSetFactory); SqlRows::SqlRows(ScriptNodePtr p) : + SourceObject(p), RowSet(p), - dataSource(p, "datasource"), - sqlCommand(p->child("sql")), - db(NULL) + SqlBase(p), + sqlCommand(p->child("sql")) { } @@ -24,19 +24,13 @@ SqlRows::~SqlRows() { } -void -SqlRows::loadComplete(const CommonObjects * co) -{ - db = co->dataSource<RdbmsDataSource>(dataSource(NULL)); -} - -SqlRows::SqlState::SqlState(SelectPtr s) : +SqlRows::SqlState::SqlState(DB::SelectCommandPtr s) : query(s) { query->execute(); fields.resize(query->columnCount()); for (unsigned int c = 0; c < query->columnCount(); c++) { - columns.insert(new Column(c, (*query)[c].name)); + columns.insert(std::make_shared<Column>(c, (*query)[c].name)); } } @@ -49,10 +43,9 @@ SqlRows::SqlState::getColumns() const void SqlRows::execute(const Glib::ustring & filter, const RowProcessorCallback & rp, ExecContext * ec) const { - unsigned int offset = 0; auto con = db->getReadonly(); - auto select = SelectPtr(con->newSelectCommand(sqlCommand.getSqlFor(filter))); - sqlCommand.bindParams(ec, select.get(), offset); + DynamicSql::SqlWriterWrapper sww(ec, &sqlCommand); + auto select = sww.getCommandFor<DB::SelectCommand>(con.get(), filter); SqlState ss(select); while (ss.query->fetch()) { HandleAsVariableType h; diff --git a/project2/sql/sqlRows.h b/project2/sql/sqlRows.h index 46f3972..25f63f8 100644 --- a/project2/sql/sqlRows.h +++ b/project2/sql/sqlRows.h @@ -6,33 +6,29 @@ #include "selectcommand.h" #include "iHaveParameters.h" #include "rowSet.h" -#include "sqlWriter.h" +#include "sqlWriters.h" +#include "sqlBase.h" class RdbmsDataSource; /// Project2 component to create a row set based on an SQL SELECT statement issued against an RDBMS data source -class SqlRows : public RowSet { +class DLL_PUBLIC SqlRows : public RowSet, SqlBase { public: SqlRows(ScriptNodePtr p); ~SqlRows(); void execute(const Glib::ustring &, const RowProcessorCallback &, ExecContext *) const; - virtual void loadComplete(const CommonObjects *); - - const Variable dataSource; private: const DynamicSql::SqlCommand sqlCommand; - typedef boost::shared_ptr<DB::SelectCommand> SelectPtr; class SqlState : public RowState { public: - SqlState(SelectPtr query); + SqlState(DB::SelectCommandPtr query); const Columns & getColumns() const; - SelectPtr query; + DB::SelectCommandPtr query; Columns columns; friend class SqlRows; }; - const RdbmsDataSource * db; }; #endif diff --git a/project2/sql/sqlTask.cpp b/project2/sql/sqlTask.cpp index a98748f..d62d150 100644 --- a/project2/sql/sqlTask.cpp +++ b/project2/sql/sqlTask.cpp @@ -6,19 +6,18 @@ #include "commonObjects.h" #include "sqlVariableBinder.h" -DECLARE_LOADER("sqltask", SqlTask); +NAMEDFACTORY("sqltask", SqlTask, TaskFactory); StaticMessageException(RunOnNotSpecified, "runon attribute must be specified"); SqlTask::SqlTask(ScriptNodePtr p) : SourceObject(p), Task(p), - dataSource(p, "datasource"), + SqlBase(p), filter(p, "filter", ""), - sqlCommand(p->child("sql")), - db(NULL) + sqlCommand(p->child("sql")) { - p->script->loader.addLoadTargetSub(p, "changes", false, Storer::into<ElementLoader>(&changesNOEs)); - p->script->loader.addLoadTargetSub(p, "nochanges", false, Storer::into<ElementLoader>(&noChangesNOEs)); + p->script.lock()->loader.addLoadTargetSub(p, "changes", false, Storer::into<TaskFactory>(&changesTasks)); + p->script.lock()->loader.addLoadTargetSub(p, "nochanges", false, Storer::into<TaskFactory>(&noChangesTasks)); } SqlTask::~SqlTask() @@ -26,26 +25,18 @@ SqlTask::~SqlTask() } void -SqlTask::loadComplete(const CommonObjects * co) -{ - db = co->dataSource<RdbmsDataSource>(dataSource(NULL)); -} - -void SqlTask::execute(ExecContext * ec) const { auto con = db->getWritable(); - boost::shared_ptr<DB::ModifyCommand> modify = boost::shared_ptr<DB::ModifyCommand>( - con->newModifyCommand(sqlCommand.getSqlFor(filter(NULL)))); - unsigned int offset = 0; - sqlCommand.bindParams(ec, modify.get(), offset); + DynamicSql::SqlWriterWrapper sww(ec, &sqlCommand); + auto modify = sww.getCommandFor<DB::ModifyCommand>(con.get(), filter(ec)); if (modify->execute() == 0) { - for (const SubNOEs::value_type & sq : noChangesNOEs) { + for (const auto & sq : noChangesTasks) { sq->execute(ec); } } else { - for (const SubNOEs::value_type & sq : changesNOEs) { + for (const auto & sq : changesTasks) { sq->execute(ec); } } diff --git a/project2/sql/sqlTask.h b/project2/sql/sqlTask.h index 94901a9..cb22173 100644 --- a/project2/sql/sqlTask.h +++ b/project2/sql/sqlTask.h @@ -4,30 +4,28 @@ #include <boost/intrusive_ptr.hpp> #include <map> #include "task.h" +#include "sqlBase.h" #include "variables.h" -#include "sqlWriter.h" +#include "sqlWriters.h" +#include <scriptStorage.h> namespace DB { class ModifyCommand; } -class RdbmsDataSource; /// Project2 component to execute a modifying SQL statement against an RDBMS data source -class SqlTask : public Task { +class DLL_PUBLIC SqlTask : public Task, SqlBase { public: SqlTask(ScriptNodePtr p); virtual ~SqlTask(); - virtual void loadComplete(const CommonObjects *); virtual void execute(ExecContext * ec) const; - const Variable dataSource; const Variable filter; - typedef ANONORDEREDSTORAGEOF(NoOutputExecute) SubNOEs; - SubNOEs changesNOEs; - SubNOEs noChangesNOEs; + typedef ANONORDEREDSTORAGEOF(Task) SubTasks; + SubTasks changesTasks; + SubTasks noChangesTasks; protected: const DynamicSql::SqlCommand sqlCommand; - const RdbmsDataSource * db; }; #endif diff --git a/project2/sql/sqlTest.cpp b/project2/sql/sqlTest.cpp index fedc2a0..1eac20e 100644 --- a/project2/sql/sqlTest.cpp +++ b/project2/sql/sqlTest.cpp @@ -8,19 +8,18 @@ #include "sqlVariableBinder.h" #include <boost/date_time/posix_time/posix_time.hpp> -DECLARE_LOADER("sqltest", SqlTest); +NAMEDFACTORY("sqltest", SqlTest, TestFactory); class CantCompareNulls : public std::exception { }; SqlTest::SqlTest(ScriptNodePtr p) : SourceObject(p), Test(p), - dataSource(p, "datasource"), + SqlBase(p), filter(p, "filter", ""), testOp(p, "testOp", "=="), testValue(p, "testValue"), - sqlCommand(p->child("sql")), - db(NULL) + sqlCommand(p->child("sql")) { } @@ -28,12 +27,6 @@ SqlTest::~SqlTest() { } -void -SqlTest::loadComplete(const CommonObjects * co) -{ - db = co->dataSource<RdbmsDataSource>(dataSource(NULL)); -} - class HandleDoCompare : public DB::HandleField { public: HandleDoCompare(const VariableType & tV, const std::string & tO) : @@ -44,8 +37,8 @@ class HandleDoCompare : public DB::HandleField { void null() { throw CantCompareNulls(); } - void string(const char *c , size_t l) { - doTest(Glib::ustring(c, c + l)); + void string(const std::string_view s) { + doTest(Glib::ustring(s.begin(), s.end())); } void integer(int64_t val) { doTest(val); @@ -96,10 +89,8 @@ bool SqlTest::passes(ExecContext * ec) const { auto con = db->getReadonly(); - boost::shared_ptr<DB::SelectCommand> query = boost::shared_ptr<DB::SelectCommand>( - con->newSelectCommand(sqlCommand.getSqlFor(filter(NULL)))); - unsigned int offset = 0; - sqlCommand.bindParams(ec, query.get(), offset); + DynamicSql::SqlWriterWrapper sww(ec, &sqlCommand); + auto query = sww.getCommandFor<DB::SelectCommand>(con.get(), filter(ec)); HandleDoCompare h(testValue(ec), testOp(ec)); while (query->fetch()) { (*query)[0].apply(h); diff --git a/project2/sql/sqlTest.h b/project2/sql/sqlTest.h index af843d1..04a5570 100644 --- a/project2/sql/sqlTest.h +++ b/project2/sql/sqlTest.h @@ -2,28 +2,25 @@ #define SQLTEST_H #include "test.h" -#include "sqlWriter.h" +#include "sqlWriters.h" +#include "sqlBase.h" namespace DB { class SelectCommand; } -class RdbmsDataSource; /// Project2 component to test the value of a variable against an RDBMS data source -class SqlTest : public Test { +class DLL_PUBLIC SqlTest : public Test, SqlBase { public: SqlTest(ScriptNodePtr p); virtual ~SqlTest(); - virtual void loadComplete(const CommonObjects *); bool passes(ExecContext *) const; - const Variable dataSource; const Variable filter; const Variable testOp; const Variable testValue; private: - DynamicSql::SqlCommand sqlCommand; - const RdbmsDataSource * db; + const DynamicSql::SqlCommand sqlCommand; }; #endif diff --git a/project2/sql/sqlVariableBinder.h b/project2/sql/sqlVariableBinder.h index 9f351e4..2ab202f 100644 --- a/project2/sql/sqlVariableBinder.h +++ b/project2/sql/sqlVariableBinder.h @@ -6,7 +6,7 @@ namespace DB { class Command; } -class SqlVariableBinder : public boost::static_visitor<> { +class DLL_PUBLIC SqlVariableBinder : public boost::static_visitor<> { public: SqlVariableBinder(DB::Command * c, unsigned int i); void operator()(const Null & i) const; diff --git a/project2/sql/sqlWriter.cpp b/project2/sql/sqlWriter.cpp deleted file mode 100644 index f654636..0000000 --- a/project2/sql/sqlWriter.cpp +++ /dev/null @@ -1,134 +0,0 @@ -#include <pch.hpp> -#include "sqlWriter.h" -#include "scripts.h" -#include <boost/bind.hpp> -#include "sqlVariableBinder.h" - -DynamicSql::SqlWriter::SqlWriter() -{ -} - -DynamicSql::SqlWriter::~SqlWriter() -{ -} - -template <typename Type, typename Cons> -static -void -appendNew(DynamicSql::Writers * w, const Cons & cons) -{ - w->push_back(new Type(cons)); -} - -static -void -appendNewFromNode(DynamicSql::Writers * w, DynamicSql::SqlCommand::Filters * fs, ScriptNodePtr p) -{ - if (fs && p->get_name() == "filter") { - DynamicSql::SqlFilterPtr f = new DynamicSql::SqlFilter(p); - w->push_back(f); - fs->insert(DynamicSql::SqlCommand::Filters::value_type(f->name, f)); - } - else if (p->get_name() == "param") { - w->push_back(new DynamicSql::SqlParameter(p)); - } -} - -DynamicSql::SqlCommand::SqlCommand(ScriptNodePtr s) -{ - if (s) { - s->composeWithCallbacks( - boost::bind(&appendNew<SqlText, Glib::ustring>, &writers, _1), - boost::bind(&appendNewFromNode, &writers, &filters, _1)); - } -} - -Glib::ustring -DynamicSql::SqlCommand::getSqlFor(const Glib::ustring & f) const -{ - for (const SqlCommand::Filters::value_type & filter : filters) { - filter.second->active = (filter.second->name == f); - } - Buffer sql; - writeSql(sql); - return Glib::ustring(sql.str()); -} - -void -DynamicSql::SqlCommand::writeSql(Buffer & sql) const -{ - for (const SqlWriterPtr & w : writers) { - w->writeSql(sql); - } -} - -void -DynamicSql::SqlCommand::bindParams(ExecContext * ec, DB::Command * cmd, unsigned int & offset) const -{ - for (const SqlWriterPtr & w : writers) { - w->bindParams(ec, cmd, offset); - } -} - -DynamicSql::SqlFilter::SqlFilter(ScriptNodePtr p) : - name(p->value("name", NULL).as<Glib::ustring>()), - active(false) -{ - p->composeWithCallbacks( - boost::bind(&appendNew<SqlText, Glib::ustring>, &writers, _1), - boost::bind(&appendNewFromNode, &writers, (DynamicSql::SqlCommand::Filters *)NULL, _1)); -} - -void -DynamicSql::SqlFilter::writeSql(Buffer & sql) const -{ - if (active) { - for (const SqlWriterPtr & w : writers) { - w->writeSql(sql); - } - } -} - -void -DynamicSql::SqlFilter::bindParams(ExecContext * ec, DB::Command * cmd, unsigned int & offset) const -{ - if (active) { - for (const SqlWriterPtr & w : writers) { - w->bindParams(ec, cmd, offset); - } - } -} - -DynamicSql::SqlParameter::SqlParameter(ScriptNodePtr n) : - Variable(n, boost::optional<Glib::ustring>("local")) -{ -} - -void -DynamicSql::SqlParameter::writeSql(Buffer & sql) const -{ - sql.append("?"); -} - -void -DynamicSql::SqlParameter::bindParams(ExecContext * ec, DB::Command * cmd, unsigned int & offset) const -{ - boost::apply_visitor<const SqlVariableBinder, const VariableType>(SqlVariableBinder(cmd, offset++), (*this)(ec)); -} - -DynamicSql::SqlText::SqlText(const Glib::ustring & n) : - text(n) -{ -} - -void -DynamicSql::SqlText::writeSql(Buffer & sql) const -{ - sql.append(text); -} - -void -DynamicSql::SqlText::bindParams(ExecContext *, DB::Command *, unsigned int &) const -{ -} - diff --git a/project2/sql/sqlWriter.h b/project2/sql/sqlWriter.h deleted file mode 100644 index 33a57fb..0000000 --- a/project2/sql/sqlWriter.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef SQLWRITER_H -#define SQLWRITER_H - -#include <intrusivePtrBase.h> -#include <command.h> -#include <glibmm/ustring.h> -#include <buffer.h> -#include <list> -#include <map> -#include "variables.h" - -namespace DynamicSql { - class SqlWriter; - typedef boost::intrusive_ptr<SqlWriter> SqlWriterPtr; - typedef std::list<SqlWriterPtr> Writers; - - class SqlWriter : public IntrusivePtrBase { - public: - SqlWriter(); - virtual ~SqlWriter(); - virtual void writeSql(Buffer & sql) const = 0; - virtual void bindParams(ExecContext *, DB::Command *, unsigned int & offset) const = 0; - }; - - class SqlText : public SqlWriter { - public: - SqlText(const Glib::ustring &); - virtual void writeSql(Buffer & sql) const; - virtual void bindParams(ExecContext *, DB::Command *, unsigned int & offset) const; - - const Glib::ustring text; - }; - - class SqlParameter : public SqlWriter, Variable { - public: - SqlParameter(ScriptNodePtr); - virtual void writeSql(Buffer & sql) const; - virtual void bindParams(ExecContext *, DB::Command *, unsigned int & offset) const; - }; - - class SqlFilter : public SqlWriter { - public: - SqlFilter(ScriptNodePtr); - virtual void writeSql(Buffer & sql) const; - virtual void bindParams(ExecContext *, DB::Command *, unsigned int & offset) const; - - const Glib::ustring name; - bool active; - private: - Writers writers; - }; - - typedef boost::intrusive_ptr<SqlFilter> SqlFilterPtr; - - class SqlCommand : public SqlWriter { - public: - SqlCommand(ScriptNodePtr); - virtual void writeSql(Buffer & sql) const; - virtual void bindParams(ExecContext *, DB::Command *, unsigned int & offset) const; - typedef std::multimap<Glib::ustring, SqlFilterPtr> Filters; - Glib::ustring getSqlFor(const Glib::ustring & f) const; - private: - Filters filters; - Writers writers; - }; -} - -#endif - diff --git a/project2/sql/sqlWriters.cpp b/project2/sql/sqlWriters.cpp new file mode 100644 index 0000000..88e0fc6 --- /dev/null +++ b/project2/sql/sqlWriters.cpp @@ -0,0 +1,188 @@ +#include <pch.hpp> +#include <selectcommand.h> +#include <modifycommand.h> +#include "sqlWriters.h" +#include "scripts.h" +#include <boost/bind.hpp> +#include "sqlVariableBinder.h" + +void +DynamicSql::SqlWriter::setFilter(const Glib::ustring &) const +{ +} + +template <typename Type, typename Cons> +static +void +appendNew(DynamicSql::Writers * w, const Cons & cons) +{ + w->push_back(std::make_shared<Type>(cons)); +} + +static +void +appendNewFromNode(DynamicSql::Writers * w, ScriptNodePtr p) +{ + if (p->get_name() == "filter") { + w->push_back(std::make_shared<DynamicSql::SqlFilter>(p)); + } + else if (p->get_name() == "param") { + w->push_back(std::make_shared<DynamicSql::SqlParameter>(p)); + } +} + +static +void +compose(ScriptNodePtr s, DynamicSql::Writers * writers) +{ + s->composeWithCallbacks( + boost::bind(&appendNew<DynamicSql::SqlText, Glib::ustring>, writers, _1), + boost::bind(&appendNewFromNode, writers, _1)); +} + +DynamicSql::SqlCommand::SqlCommand(ScriptNodePtr s) +{ + if (s) { + compose(s, &writers); + } +} + +void +DynamicSql::SqlCommand::setFilter(const Glib::ustring & f) const +{ + for (auto & w : writers) { + w->setFilter(f); + } +} + +void +DynamicSql::SqlFilter::setFilter(const Glib::ustring & f) const +{ + active = (name == f); + for (auto & w : writers) { + w->setFilter(f); + } +} + +void +DynamicSql::SqlCommand::writeSql(AdHoc::Buffer & sql) const +{ + for (const SqlWriterPtr & w : writers) { + w->writeSql(sql); + } +} + +void +DynamicSql::SqlCommand::bindParams(ExecContext * ec, DB::Command * cmd, unsigned int & offset) const +{ + for (const SqlWriterPtr & w : writers) { + w->bindParams(ec, cmd, offset); + } +} + +DynamicSql::SqlFilter::SqlFilter(ScriptNodePtr p) : + name(p->value("name", NULL).as<Glib::ustring>()), + active(false) +{ + compose(p, &writers); +} + +void +DynamicSql::SqlFilter::writeSql(AdHoc::Buffer & sql) const +{ + if (active) { + for (const SqlWriterPtr & w : writers) { + w->writeSql(sql); + } + } +} + +void +DynamicSql::SqlFilter::bindParams(ExecContext * ec, DB::Command * cmd, unsigned int & offset) const +{ + if (active) { + for (const SqlWriterPtr & w : writers) { + w->bindParams(ec, cmd, offset); + } + } +} + +DynamicSql::SqlParameter::SqlParameter(ScriptNodePtr n) : + Variable(n, boost::optional<Glib::ustring>("local")) +{ +} + +void +DynamicSql::SqlParameter::writeSql(AdHoc::Buffer & sql) const +{ + sql.append("?"); +} + +void +DynamicSql::SqlParameter::bindParams(ExecContext * ec, DB::Command * cmd, unsigned int & offset) const +{ + boost::apply_visitor<const SqlVariableBinder, const VariableType>(SqlVariableBinder(cmd, offset++), (*this)(ec)); +} + +DynamicSql::SqlText::SqlText(const Glib::ustring & n) : + text(n) +{ +} + +void +DynamicSql::SqlText::writeSql(AdHoc::Buffer & sql) const +{ + sql.append(text); +} + +void +DynamicSql::SqlText::bindParams(ExecContext *, DB::Command *, unsigned int &) const +{ +} + +namespace DynamicSql { + template <> + std::shared_ptr<DB::SelectCommand> + SqlWriterWrapper::getCommandFor<DB::SelectCommand>(DB::Connection * db, const Glib::ustring & f) const + { + AdHoc::Buffer sql; + w->setFilter(f); + w->writeSql(sql); + auto cmd = db->select(sql); + unsigned int offset = 0; + w->bindParams(ec, cmd.get(), offset); + return cmd; + } + + template <> + std::shared_ptr<DB::ModifyCommand> + SqlWriterWrapper::getCommandFor<DB::ModifyCommand>(DB::Connection * db, const Glib::ustring & f) const + { + AdHoc::Buffer sql; + w->setFilter(f); + w->writeSql(sql); + auto cmd = db->modify(sql); + unsigned int offset = 0; + w->bindParams(ec, cmd.get(), offset); + return cmd; + } + + SqlWriterWrapper::SqlWriterWrapper(ExecContext * e, const DynamicSql::SqlWriter * sw) : + ec(e), + w(sw) + { + } + + void + SqlWriterWrapper::writeSql(AdHoc::Buffer & sql) + { + w->writeSql(sql); + } + + void + SqlWriterWrapper::bindParams(DB::Command * cmd, unsigned int & offset) + { + w->bindParams(ec, cmd, offset); + } +} + diff --git a/project2/sql/sqlWriters.h b/project2/sql/sqlWriters.h new file mode 100644 index 0000000..0ef7115 --- /dev/null +++ b/project2/sql/sqlWriters.h @@ -0,0 +1,86 @@ +#ifndef SQLWRITER_H +#define SQLWRITER_H + +#include <boost/enable_shared_from_this.hpp> +#include <boost/shared_ptr.hpp> +#include <command.h> +#include <connection.h> +#include <sqlWriter.h> +#include <glibmm/ustring.h> +#include <buffer.h> +#include <list> +#include <map> +#include "variables.h" + +namespace DynamicSql { + class SqlWriter; + typedef std::shared_ptr<SqlWriter> SqlWriterPtr; + typedef std::list<SqlWriterPtr> Writers; + + class DLL_PUBLIC SqlWriter { + public: + virtual ~SqlWriter() = default; + virtual void writeSql(AdHoc::Buffer & sql) const = 0; + virtual void bindParams(ExecContext *, DB::Command *, unsigned int & offset) const = 0; + virtual void setFilter(const Glib::ustring &) const; + }; + + class DLL_PUBLIC SqlText : public SqlWriter { + public: + SqlText(const Glib::ustring &); + virtual void writeSql(AdHoc::Buffer & sql) const override; + virtual void bindParams(ExecContext *, DB::Command *, unsigned int & offset) const override; + + const Glib::ustring text; + }; + + class DLL_PUBLIC SqlParameter : public SqlWriter, Variable { + public: + SqlParameter(ScriptNodePtr); + virtual void writeSql(AdHoc::Buffer & sql) const override; + virtual void bindParams(ExecContext *, DB::Command *, unsigned int & offset) const override; + }; + + class DLL_PUBLIC SqlFilter : public SqlWriter { + public: + SqlFilter(ScriptNodePtr); + virtual void writeSql(AdHoc::Buffer & sql) const override; + virtual void bindParams(ExecContext *, DB::Command *, unsigned int & offset) const override; + void setFilter(const Glib::ustring &) const override; + + const Glib::ustring name; + mutable bool active; + + private: + Writers writers; + }; + + class DLL_PUBLIC SqlCommand : public SqlWriter { + public: + SqlCommand(ScriptNodePtr); + + virtual void writeSql(AdHoc::Buffer & sql) const override; + virtual void bindParams(ExecContext *, DB::Command *, unsigned int & offset) const override; + void setFilter(const Glib::ustring &) const override; + + private: + Writers writers; + }; + + class DLL_PUBLIC SqlWriterWrapper : public DB::SqlWriter { + public: + SqlWriterWrapper(ExecContext *, const DynamicSql::SqlWriter *); + + virtual void writeSql(AdHoc::Buffer & sql) override; + virtual void bindParams(DB::Command *, unsigned int & offset) override; + + template <typename CommandType> std::shared_ptr<CommandType> getCommandFor(DB::Connection *, const Glib::ustring & f) const; + + private: + ExecContext * ec; + const DynamicSql::SqlWriter * w; + }; +} + +#endif + diff --git a/project2/sql/tablepatch.cpp b/project2/sql/tablepatch.cpp deleted file mode 100644 index f49c4ee..0000000 --- a/project2/sql/tablepatch.cpp +++ /dev/null @@ -1,506 +0,0 @@ -#include <pch.hpp> -#include "tablepatch.h" -#include <stdio.h> -#include <misc.h> -#include <selectcommand.h> -#include <column.h> -#include <buffer.h> -#include <boost/algorithm/string/join.hpp> - -using namespace DB; - -TablePatch::TablePatch(const Connection & wdb, const TablePatch::Table & s, const TablePatch::Table & d, - const TablePatch::Columns & c) : - doDelete(true), - doUpdate(true), - doInsert(true), - src(s), - dest(d), - cols(c), - db(wdb) -{ - if (!src.length()) { - throw PatchCheckFailure(); - } - if (!dest.length()) { - throw PatchCheckFailure(); - } - if (!db.inTx()) { - throw PatchCheckFailure(); - } -} - -void -TablePatch::addKey(const TablePatch::Column & c) -{ - pk.insert(c); -} - -void -TablePatch::patch(ExecContext * ec, DynamicSql::SqlWriterPtr insteadOfDelete, DynamicSql::SqlWriterPtr where, DynamicSql::SqlWriterPtr order) -{ - if (pk.empty()) { - throw PatchCheckFailure(); - } - if (doDelete) { - doDeletes(ec, insteadOfDelete, where, order); - } - if (doUpdate) { - doUpdates(ec, where, order); - } - if (doInsert) { - doInserts(ec, order); - } -} - -void -TablePatch::doDeletes(ExecContext * ec, DynamicSql::SqlWriterPtr insteadOfDelete, DynamicSql::SqlWriterPtr where, DynamicSql::SqlWriterPtr order) -{ - Buffer toDelSql; - switch (db.bulkDeleteStyle()) { - case BulkDeleteUsingSubSelect: - { - // ----------------------------------------------------------------- - // Build SQL to delete keys ---------------------------------------- - // ----------------------------------------------------------------- - if (insteadOfDelete) { - toDelSql.appendf("UPDATE %s ", - dest.c_str()); - insteadOfDelete->writeSql(toDelSql); - toDelSql.append(" WHERE ("); - } - else { - toDelSql.appendf("DELETE FROM %s WHERE (", - dest.c_str()); - } - foreach (PKI, pk, pki) { - if (pki != pk.begin()) { - toDelSql.append(", "); - } - toDelSql.appendf("%s.%s", - dest.c_str(), - pki->c_str()); - } - // ----------------------------------------------------------------- - // Build SQL to select keys to delete ------------------------------ - // ----------------------------------------------------------------- - toDelSql.append(") IN (SELECT "); - foreach (PKI, pk, pki) { - if (pki != pk.begin()) { - toDelSql.append(", "); - } - toDelSql.appendf("a.%s", - pki->c_str()); - } - toDelSql.appendf(" FROM %s a LEFT OUTER JOIN %s b ON ", - dest.c_str(), src.c_str()); - foreach (PKI, pk, pki) { - if (pki != pk.begin()) { - toDelSql.append(" AND "); - } - toDelSql.appendf(" a.%s = b.%s", - pki->c_str(), pki->c_str()); - } - foreach (PKI, pk, pki) { - if (pki == pk.begin()) { - toDelSql.append(" WHERE "); - } - else { - toDelSql.append(" AND "); - } - toDelSql.appendf(" b.%s IS NULL", - pki->c_str()); - } - if (where) { - toDelSql.append(" AND "); - where->writeSql(toDelSql); - } - if (order) { - toDelSql.append(" ORDER BY "); - order->writeSql(toDelSql); - } - toDelSql.append(")"); - break; - } - case BulkDeleteUsingUsingAlias: - case BulkDeleteUsingUsing: - { - if (insteadOfDelete) { - toDelSql.appendf("UPDATE %s a ", - dest.c_str()); - } - else { - toDelSql.appendf("DELETE FROM %s USING %s a ", - (db.bulkDeleteStyle() == BulkDeleteUsingUsingAlias ? "a" : dest.c_str()), - dest.c_str()); - } - toDelSql.appendf(" LEFT OUTER JOIN %s b ", - src.c_str()); - foreach (PKI, pk, pki) { - if (pki != pk.begin()) { - toDelSql.append(" AND "); - } - else { - toDelSql.append(" ON "); - } - toDelSql.appendf(" a.%s = b.%s ", - pki->c_str(), pki->c_str()); - } - if (insteadOfDelete) { - insteadOfDelete->writeSql(toDelSql); - } - foreach (PKI, pk, pki) { - if (pki != pk.begin()) { - toDelSql.append(" AND "); - } - else { - toDelSql.append(" WHERE "); - } - toDelSql.appendf(" b.%s IS NULL", - pki->c_str()); - } - if (where) { - toDelSql.append(" AND "); - where->writeSql(toDelSql); - } - if (order) { - toDelSql.append(" ORDER BY "); - order->writeSql(toDelSql); - } - break; - } - } - ModifyCommand * del = db.newModifyCommand(toDelSql); - unsigned int offset = 0; - if (where) { - where->bindParams(ec, del, offset); - } - if (order) { - order->bindParams(ec, del, offset); - } - del->execute(); - delete del; -} - -void -TablePatch::doUpdates(ExecContext * ec, DynamicSql::SqlWriterPtr where, DynamicSql::SqlWriterPtr order) -{ - if (cols.size() == pk.size()) { - // Can't "change" anything... it's all part of the key - return; - } - switch (db.bulkUpdateStyle()) { - case BulkUpdateByIteration: - { - // ----------------------------------------------------------------- - // Build SQL for list of updates to perform ------------------------ - // ----------------------------------------------------------------- - Buffer toUpdSel; - toUpdSel.append("SELECT "); - foreach (Columns::const_iterator, cols, col) { - if (pk.find(*col) == pk.end()) { - toUpdSel.appendf("b.%s, ", - col->c_str()); - } - } - foreach (Columns::const_iterator, cols, col) { - if (pk.find(*col) != pk.end()) { - toUpdSel.appendf("b.%s, ", - col->c_str()); - } - } - toUpdSel.appendf("0 FROM %s a, %s b", - dest.c_str(), src.c_str()); - foreach (PKI, pk, pki) { - if (pki == pk.begin()) { - toUpdSel.append(" WHERE "); - } - else { - toUpdSel.append(" AND "); - } - toUpdSel.appendf(" a.%s = b.%s", - pki->c_str(), pki->c_str()); - } - if (where) { - toUpdSel.append(" AND "); - where->writeSql(toUpdSel); - } - toUpdSel.append(" AND ("); - bool first = true; - foreach (Columns::const_iterator, cols, col) { - if (pk.find(*col) == pk.end()) { - if (!first) { - toUpdSel.append(" OR "); - } - first = false; - toUpdSel.appendf( - " (((CASE WHEN (a.%s IS NULL AND b.%s IS NULL) THEN 1 ELSE 0 END) \ - + (CASE WHEN(a.%s = b.%s) THEN 1 ELSE 0 END)) = 0)", - col->c_str(), col->c_str(), col->c_str(), col->c_str()); - } - } - toUpdSel.append(")"); - if (order) { - toUpdSel.append(" ORDER BY "); - order->writeSql(toUpdSel); - } - // ----------------------------------------------------------------- - // Build SQL to perform updates ------------------------------------ - // ----------------------------------------------------------------- - Buffer updSql; - updSql.appendf("UPDATE %s SET ", - dest.c_str()); - first = true; - foreach (Columns::const_iterator, cols, col) { - if (pk.find(*col) == pk.end()) { - if (!first) { - updSql.append(", "); - } - first = false; - updSql.appendf(" %s = ?", - col->c_str()); - } - } - foreach (PKI, pk, pki) { - if (pki == pk.begin()) { - updSql.append(" WHERE "); - } - else { - updSql.append(" AND "); - } - updSql.appendf(" %s = ?", - pki->c_str()); - } - // ----------------------------------------------------------------- - // Iterator over update list make changes -------------------------- - // ----------------------------------------------------------------- - SelectCommand * toUpd = db.newSelectCommand(toUpdSel); - unsigned int offset = 0; - if (where) { - where->bindParams(ec, toUpd, offset); - } - if (order) { - order->bindParams(ec, toUpd, offset); - } - ModifyCommand * upd = db.newModifyCommand(updSql); - int cs = cols.size(); - toUpd->execute(); - for (int c = 0; c < cs; c += 1) { - (*toUpd)[c].rebind(upd, c); - } - while (toUpd->fetch()) { - upd->execute(false); - } - delete toUpd; - delete upd; - } - break; - case BulkUpdateUsingFromSrc: - { - // ----------------------------------------------------------------- - // Build SQL for list of updates to perform ------------------------ - // ----------------------------------------------------------------- - Buffer updSql; - updSql.appendf("UPDATE %s a SET ", - dest.c_str()); - bool first = true; - foreach (Columns::const_iterator, cols, col) { - if (pk.find(*col) == pk.end()) { - if (!first) { - updSql.append(", "); - } - first = false; - updSql.appendf(" %s = b.%s ", - col->c_str(), col->c_str()); - } - } - updSql.appendf(" FROM %s b ", - src.c_str()); - foreach (PKI, pk, pki) { - if (pki == pk.begin()) { - updSql.append(" WHERE "); - } - else { - updSql.append(" AND "); - } - updSql.appendf(" a.%s = b.%s ", - pki->c_str(), pki->c_str()); - } - updSql.append(" AND ("); - first = true; - foreach (Columns::const_iterator, cols, col) { - if (pk.find(*col) == pk.end()) { - if (!first) { - updSql.append(" OR "); - } - first = false; - updSql.appendf( - " (((CASE WHEN (a.%s IS NULL AND b.%s IS NULL) THEN 1 ELSE 0 END) \ - + (CASE WHEN(a.%s = b.%s) THEN 1 ELSE 0 END)) = 0)", - col->c_str(), col->c_str(), - col->c_str(), col->c_str()); - } - } - updSql.append(")"); - if (where) { - updSql.append(" AND "); - where->writeSql(updSql); - } - if (order) { - updSql.append(" ORDER BY "); - order->writeSql(updSql); - } - // ----------------------------------------------------------------- - // Execute the bulk update command --------------------------------- - // ----------------------------------------------------------------- - ModifyCommand * upd = db.newModifyCommand(updSql); - unsigned int offset = 0; - if (where) { - where->bindParams(ec, upd, offset); - } - if (order) { - order->bindParams(ec, upd, offset); - } - upd->execute(true); - delete upd; - break; - } - case BulkUpdateUsingJoin: - { - // ----------------------------------------------------------------- - // Build SQL for list of updates to perform ------------------------ - // ----------------------------------------------------------------- - Buffer updSql; - updSql.appendf("UPDATE %s a, %s b SET ", - dest.c_str(), src.c_str()); - bool first = true; - foreach (Columns::const_iterator, cols, col) { - if (pk.find(*col) == pk.end()) { - if (!first) { - updSql.append(", "); - } - first = false; - updSql.appendf(" a.%s = b.%s ", - col->c_str(), col->c_str()); - } - } - foreach (PKI, pk, pki) { - if (pki == pk.begin()) { - updSql.append(" WHERE "); - } - else { - updSql.append(" AND "); - } - updSql.appendf(" a.%s = b.%s ", - pki->c_str(), pki->c_str()); - } - updSql.append(" AND ("); - first = true; - foreach (Columns::const_iterator, cols, col) { - if (pk.find(*col) == pk.end()) { - if (!first) { - updSql.append(" OR "); - } - first = false; - updSql.appendf( - " (((CASE WHEN (a.%s IS NULL AND b.%s IS NULL) THEN 1 ELSE 0 END) \ - + (CASE WHEN(a.%s = b.%s) THEN 1 ELSE 0 END)) = 0)", - col->c_str(), col->c_str(), - col->c_str(), col->c_str()); - } - } - updSql.append(")"); - if (where) { - updSql.append(" AND "); - where->writeSql(updSql); - } - if (order) { - updSql.append(" ORDER BY "); - order->writeSql(updSql); - } - // ----------------------------------------------------------------- - // Execute the bulk update command --------------------------------- - // ----------------------------------------------------------------- - ModifyCommand * upd = db.newModifyCommand(updSql); - unsigned int offset = 0; - if (where) { - where->bindParams(ec, upd, offset); - } - if (order) { - order->bindParams(ec, upd, offset); - } - upd->execute(true); - delete upd; - break; - } - } -} - -void -TablePatch::doInserts(ExecContext * ec, DynamicSql::SqlWriterPtr order) -{ - // ----------------------------------------------------------------- - // Build SQL for copying new records ------------------------------- - // ----------------------------------------------------------------- - Buffer toInsSql; - toInsSql.appendf("INSERT INTO %s", - dest.c_str()); - foreach (Columns::const_iterator, cols, col) { - if (col == cols.begin()) { - toInsSql.append("("); - } - else { - toInsSql.append(", "); - } - toInsSql.appendf("%s", - col->c_str()); - } - toInsSql.append(") SELECT "); - foreach (Columns::const_iterator, cols, col) { - if (col != cols.begin()) { - toInsSql.append(", "); - } - toInsSql.appendf("b.%s", - col->c_str()); - } - toInsSql.appendf(" FROM %s b LEFT OUTER JOIN %s a", - src.c_str(), dest.c_str()); - foreach (PKI, pk, pki) { - if (pki == pk.begin()) { - toInsSql.append(" ON "); - } - else { - toInsSql.append(" AND "); - } - toInsSql.appendf(" a.%s = b.%s", - pki->c_str(), pki->c_str()); - } - foreach (PKI, pk, pki) { - if (pki == pk.begin()) { - toInsSql.append(" WHERE "); - } - else { - toInsSql.append(" AND "); - } - toInsSql.appendf(" a.%s IS NULL", - pki->c_str()); - } - if (order) { - toInsSql.appendf(" ORDER BY "); - order->writeSql(toInsSql); - } - ModifyCommand * ins = db.newModifyCommand(toInsSql); - unsigned int offset = 0; - if (order) { - order->bindParams(ec, ins, offset); - } - ins->execute(); - delete ins; -} - -const char * -TablePatch::PatchCheckFailure::what() const throw() -{ - return "Santiy checks failed: check table names and keys"; -} - diff --git a/project2/sql/tablepatch.h b/project2/sql/tablepatch.h deleted file mode 100644 index df574bf..0000000 --- a/project2/sql/tablepatch.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef TABLEPATCH_H -#define TABLEPATCH_H - -#include <string> -#include <set> -#include <map> -#include <connection.h> -#include <modifycommand.h> -#include <selectcommand.h> -#include <buffer.h> -#include "sqlWriter.h" - -class TablePatch { - public: - typedef std::string Table; - typedef std::string Column; - typedef std::set<Column> Columns; - typedef Columns PrimaryKey; - typedef PrimaryKey::const_iterator PKI; - - class PatchCheckFailure : public std::exception { - public: - const char * what() const throw(); - }; - - TablePatch(const DB::Connection & db, const Table & src, const Table & dest, const Columns & cols); - - void addKey(const Column & col); - void patch(ExecContext *, DynamicSql::SqlWriterPtr insteadOfDelete, DynamicSql::SqlWriterPtr where, DynamicSql::SqlWriterPtr order); - - bool doDelete; - bool doUpdate; - bool doInsert; - - private: - void doDeletes(ExecContext *, DynamicSql::SqlWriterPtr insteadOfDelete, DynamicSql::SqlWriterPtr where, DynamicSql::SqlWriterPtr order); - void doUpdates(ExecContext *, DynamicSql::SqlWriterPtr where, DynamicSql::SqlWriterPtr order); - void doInserts(ExecContext *, DynamicSql::SqlWriterPtr order); - - Table src; - Table dest; - PrimaryKey pk; - Columns cols; - const DB::Connection &db; -}; - -#endif - diff --git a/project2/sql/unittests/Jamfile.jam b/project2/sql/unittests/Jamfile.jam deleted file mode 100644 index 8fb6918..0000000 --- a/project2/sql/unittests/Jamfile.jam +++ /dev/null @@ -1,62 +0,0 @@ -import testing ; - -lib boost_system ; -lib boost_filesystem ; -lib IceUtil ; -lib Ice ; - -path-constant me : . ; - -lib sqlTestCore : - testCore.cpp - : - <library>../../ut//p2ut - <library>../../common//p2common - <library>boost_filesystem - <define>ROOT=\"$(me)\" - : : - <library>../../common//p2common - <library>../../basics//p2basics - <library>../../ut//p2ut - <library>../../lib//p2lib - <library>../../xml//p2xml - <library>..//p2sql - <library>boost_system - <library>boost_filesystem - <library>../../ut//boost_utf - <define>ROOT=\"$(me)\" - <define>BOOST_TEST_DYN_LINK - ; - -run - testpq.cpp - : : : - <library>sqlTestCore - <library>..//p2sqlmodPQ - <dependency>pqschema.sql - : testpq ; - -run - testsqlite.cpp - : : : - <library>sqlTestCore - <library>..//p2sqlmodSQLite - <dependency>sqliteschema.sql - : testsqlite ; - -run - testmysql.cpp - : : : - <library>sqlTestCore - <library>..//p2sqlmodMySQL - <dependency>mysqlschema.sql - : testmysql ; - -run - testodbc.cpp - : : : - <library>sqlTestCore - <library>..//p2sqlmodODBC - <dependency>odbcschema.sql - : testodbc ; - diff --git a/project2/sql/unittests/bulk.sample b/project2/sql/unittests/bulk.sample deleted file mode 100644 index ae81633..0000000 --- a/project2/sql/unittests/bulk.sample +++ /dev/null @@ -1,800 +0,0 @@ -1 /usr/portage/ -2 /usr/portage/games-rpg -3 /usr/portage/games-rpg/penumbra-collection -4 /usr/portage/games-rpg/penumbra-collection/ChangeLog -5 /usr/portage/games-rpg/penumbra-collection/Manifest -6 /usr/portage/games-rpg/penumbra-collection/metadata.xml -7 /usr/portage/games-rpg/penumbra-collection/penumbra-collection-1.1.ebuild -8 /usr/portage/games-rpg/arx-fatalis-data -9 /usr/portage/games-rpg/arx-fatalis-data/ChangeLog -10 /usr/portage/games-rpg/arx-fatalis-data/Manifest -11 /usr/portage/games-rpg/arx-fatalis-data/metadata.xml -12 /usr/portage/games-rpg/arx-fatalis-data/arx-fatalis-data-1.21-r2.ebuild -13 /usr/portage/games-rpg/arx-fatalis-data/arx-fatalis-data-1.21-r1.ebuild -14 /usr/portage/games-rpg/nwmouse -15 /usr/portage/games-rpg/nwmouse/ChangeLog -16 /usr/portage/games-rpg/nwmouse/Manifest -17 /usr/portage/games-rpg/nwmouse/metadata.xml -18 /usr/portage/games-rpg/nwmouse/nwmouse-20090906.183839.ebuild -19 /usr/portage/games-rpg/bass -20 /usr/portage/games-rpg/bass/ChangeLog -21 /usr/portage/games-rpg/bass/Manifest -22 /usr/portage/games-rpg/bass/metadata.xml -23 /usr/portage/games-rpg/bass/bass-1.2-r1.ebuild -24 /usr/portage/games-rpg/bass/files -25 /usr/portage/games-rpg/bass/files/scummvmGetLang.sh -26 /usr/portage/games-rpg/a-bird-story -27 /usr/portage/games-rpg/a-bird-story/ChangeLog -28 /usr/portage/games-rpg/a-bird-story/Manifest -29 /usr/portage/games-rpg/a-bird-story/metadata.xml -30 /usr/portage/games-rpg/a-bird-story/a-bird-story-20141106.ebuild -31 /usr/portage/games-rpg/nwn-shadowlordsdreamcatcherdemon -32 /usr/portage/games-rpg/nwn-shadowlordsdreamcatcherdemon/ChangeLog -33 /usr/portage/games-rpg/nwn-shadowlordsdreamcatcherdemon/Manifest -34 /usr/portage/games-rpg/nwn-shadowlordsdreamcatcherdemon/metadata.xml -35 /usr/portage/games-rpg/nwn-shadowlordsdreamcatcherdemon/nwn-shadowlordsdreamcatcherdemon-1.ebuild -36 /usr/portage/games-rpg/eschalon-book-1-demo -37 /usr/portage/games-rpg/eschalon-book-1-demo/ChangeLog -38 /usr/portage/games-rpg/eschalon-book-1-demo/eschalon-book-1-demo-106.ebuild -39 /usr/portage/games-rpg/eschalon-book-1-demo/Manifest -40 /usr/portage/games-rpg/eschalon-book-1-demo/metadata.xml -41 /usr/portage/games-rpg/openglad -42 /usr/portage/games-rpg/openglad/ChangeLog -43 /usr/portage/games-rpg/openglad/Manifest -44 /usr/portage/games-rpg/openglad/metadata.xml -45 /usr/portage/games-rpg/openglad/files -46 /usr/portage/games-rpg/openglad/files/openglad-0.98-gcc43.patch -47 /usr/portage/games-rpg/openglad/files/0.98-gladpack.c.patch -48 /usr/portage/games-rpg/openglad/files/openglad-0.98-ovfl.patch -49 /usr/portage/games-rpg/openglad/openglad-0.98.ebuild -50 /usr/portage/games-rpg/dungeon-defenders -51 /usr/portage/games-rpg/dungeon-defenders/ChangeLog -52 /usr/portage/games-rpg/dungeon-defenders/dungeon-defenders-20130305.ebuild -53 /usr/portage/games-rpg/dungeon-defenders/Manifest -54 /usr/portage/games-rpg/dungeon-defenders/metadata.xml -55 /usr/portage/games-rpg/xu4 -56 /usr/portage/games-rpg/xu4/ChangeLog -57 /usr/portage/games-rpg/xu4/Manifest -58 /usr/portage/games-rpg/xu4/xu4-0.9.ebuild -59 /usr/portage/games-rpg/xu4/metadata.xml -60 /usr/portage/games-rpg/xu4/files -61 /usr/portage/games-rpg/xu4/files/xu4-0.9-ldflags.patch -62 /usr/portage/games-rpg/xu4/files/xu4-0.9-zip.patch -63 /usr/portage/games-rpg/xu4/files/xu4-0.9-warnings.patch -64 /usr/portage/games-rpg/xu4/files/0.9-savegame.patch -65 /usr/portage/games-rpg/eternal-lands-data -66 /usr/portage/games-rpg/eternal-lands-data/ChangeLog -67 /usr/portage/games-rpg/eternal-lands-data/eternal-lands-data-1.9.3.ebuild -68 /usr/portage/games-rpg/eternal-lands-data/Manifest -69 /usr/portage/games-rpg/eternal-lands-data/metadata.xml -70 /usr/portage/games-rpg/eternal-lands-data/eternal-lands-data-1.9.3-r1.ebuild -71 /usr/portage/games-rpg/eternal-lands-data/eternal-lands-data-1.9.2-r1.ebuild -72 /usr/portage/games-rpg/nwn-data -73 /usr/portage/games-rpg/nwn-data/ChangeLog -74 /usr/portage/games-rpg/nwn-data/Manifest -75 /usr/portage/games-rpg/nwn-data/metadata.xml -76 /usr/portage/games-rpg/nwn-data/nwn-data-1.29-r5.ebuild -77 /usr/portage/games-rpg/eternal-lands -78 /usr/portage/games-rpg/eternal-lands/ChangeLog -79 /usr/portage/games-rpg/eternal-lands/Manifest -80 /usr/portage/games-rpg/eternal-lands/eternal-lands-1.9.3-r2.ebuild -81 /usr/portage/games-rpg/eternal-lands/eternal-lands-1.9.2-r1.ebuild -82 /usr/portage/games-rpg/eternal-lands/metadata.xml -83 /usr/portage/games-rpg/eternal-lands/eternal-lands-1.9.2.ebuild -84 /usr/portage/games-rpg/eternal-lands/eternal-lands-1.9.3-r1.ebuild -85 /usr/portage/games-rpg/eternal-lands/eternal-lands-1.9.3.ebuild -86 /usr/portage/games-rpg/eternal-lands/files -87 /usr/portage/games-rpg/eternal-lands/files/eternal-lands-1.9.1-libpng.patch -88 /usr/portage/games-rpg/eternal-lands/files/eternal-lands-1.9.3-minizip.patch -89 /usr/portage/games-rpg/eternal-lands/files/eternal-lands-1.9.2-glext.patch -90 /usr/portage/games-rpg/eternal-lands/files/eternal-lands-1.9.3-build.patch -91 /usr/portage/games-rpg/eternal-lands/files/eternal-lands-1.9.3-glbuild.patch -92 /usr/portage/games-rpg/eternal-lands/files/eternal-lands-1.9.0-glext.patch -93 /usr/portage/games-rpg/freedink-data -94 /usr/portage/games-rpg/freedink-data/ChangeLog -95 /usr/portage/games-rpg/freedink-data/Manifest -96 /usr/portage/games-rpg/freedink-data/metadata.xml -97 /usr/portage/games-rpg/freedink-data/freedink-data-1.08.20140901.ebuild -98 /usr/portage/games-rpg/nwmovies -99 /usr/portage/games-rpg/nwmovies/ChangeLog -100 /usr/portage/games-rpg/nwmovies/nwmovies-20090223.080954.ebuild -101 /usr/portage/games-rpg/nwmovies/Manifest -102 /usr/portage/games-rpg/nwmovies/metadata.xml -103 /usr/portage/games-rpg/arx-libertatis -104 /usr/portage/games-rpg/arx-libertatis/ChangeLog -105 /usr/portage/games-rpg/arx-libertatis/arx-libertatis-1.1.2.ebuild -106 /usr/portage/games-rpg/arx-libertatis/Manifest -107 /usr/portage/games-rpg/arx-libertatis/metadata.xml -108 /usr/portage/games-rpg/arx-libertatis/arx-libertatis-1.1.1.ebuild -109 /usr/portage/games-rpg/arx-libertatis/arx-libertatis-1.0.3.ebuild -110 /usr/portage/games-rpg/arx-libertatis/files -111 /usr/portage/games-rpg/arx-libertatis/files/arx-data-copy -112 /usr/portage/games-rpg/arx-libertatis/files/arx-libertatis-1.0.3-gentoo.patch -113 /usr/portage/games-rpg/arx-libertatis/files/arx-libertatis-1.0.3-cmake2.8.patch -114 /usr/portage/games-rpg/lure -115 /usr/portage/games-rpg/lure/ChangeLog -116 /usr/portage/games-rpg/lure/Manifest -117 /usr/portage/games-rpg/lure/metadata.xml -118 /usr/portage/games-rpg/lure/lure-1.1.ebuild -119 /usr/portage/games-rpg/to-the-moon -120 /usr/portage/games-rpg/to-the-moon/ChangeLog -121 /usr/portage/games-rpg/to-the-moon/Manifest -122 /usr/portage/games-rpg/to-the-moon/metadata.xml -123 /usr/portage/games-rpg/to-the-moon/to-the-moon-0.ebuild -124 /usr/portage/games-rpg/drascula -125 /usr/portage/games-rpg/drascula/ChangeLog -126 /usr/portage/games-rpg/drascula/Manifest -127 /usr/portage/games-rpg/drascula/metadata.xml -128 /usr/portage/games-rpg/drascula/drascula-1.0-r2.ebuild -129 /usr/portage/games-rpg/coe2 -130 /usr/portage/games-rpg/coe2/ChangeLog -131 /usr/portage/games-rpg/coe2/Manifest -132 /usr/portage/games-rpg/coe2/metadata.xml -133 /usr/portage/games-rpg/coe2/coe2-2007-r1.ebuild -134 /usr/portage/games-rpg/queen -135 /usr/portage/games-rpg/queen/ChangeLog -136 /usr/portage/games-rpg/queen/Manifest -137 /usr/portage/games-rpg/queen/metadata.xml -138 /usr/portage/games-rpg/queen/queen-1.ebuild -139 /usr/portage/games-rpg/tmw -140 /usr/portage/games-rpg/tmw/ChangeLog -141 /usr/portage/games-rpg/tmw/Manifest -142 /usr/portage/games-rpg/tmw/tmw-20130201.ebuild -143 /usr/portage/games-rpg/tmw/metadata.xml -144 /usr/portage/games-rpg/tmw/files -145 /usr/portage/games-rpg/tmw/files/tmw-branding-20130201-gentoo.patch -146 /usr/portage/games-rpg/freedroid -147 /usr/portage/games-rpg/freedroid/ChangeLog -148 /usr/portage/games-rpg/freedroid/Manifest -149 /usr/portage/games-rpg/freedroid/freedroid-1.0.2.ebuild -150 /usr/portage/games-rpg/freedroid/metadata.xml -151 /usr/portage/games-rpg/nwn-penultimarerolled -152 /usr/portage/games-rpg/nwn-penultimarerolled/ChangeLog -153 /usr/portage/games-rpg/nwn-penultimarerolled/Manifest -154 /usr/portage/games-rpg/nwn-penultimarerolled/nwn-penultimarerolled-1.ebuild -155 /usr/portage/games-rpg/nwn-penultimarerolled/metadata.xml -156 /usr/portage/games-rpg/vendetta-online-bin -157 /usr/portage/games-rpg/vendetta-online-bin/ChangeLog -158 /usr/portage/games-rpg/vendetta-online-bin/Manifest -159 /usr/portage/games-rpg/vendetta-online-bin/metadata.xml -160 /usr/portage/games-rpg/vendetta-online-bin/files -161 /usr/portage/games-rpg/vendetta-online-bin/files/vendetta -162 /usr/portage/games-rpg/vendetta-online-bin/vendetta-online-bin-1.8.296.ebuild -163 /usr/portage/games-rpg/metadata.xml -164 /usr/portage/games-rpg/adonthell -165 /usr/portage/games-rpg/adonthell/ChangeLog -166 /usr/portage/games-rpg/adonthell/Manifest -167 /usr/portage/games-rpg/adonthell/metadata.xml -168 /usr/portage/games-rpg/adonthell/files -169 /usr/portage/games-rpg/adonthell/files/adonthell-0.3.5-gcc46.patch -170 /usr/portage/games-rpg/adonthell/files/adonthell-0.3.5-glibc-2.10.patch -171 /usr/portage/games-rpg/adonthell/files/adonthell-0.3.5-format.patch -172 /usr/portage/games-rpg/adonthell/files/adonthell-0.3.5-configure.in.patch -173 /usr/portage/games-rpg/adonthell/adonthell-0.3.5-r1.ebuild -174 /usr/portage/games-rpg/soltys -175 /usr/portage/games-rpg/soltys/ChangeLog -176 /usr/portage/games-rpg/soltys/Manifest -177 /usr/portage/games-rpg/soltys/metadata.xml -178 /usr/portage/games-rpg/soltys/soltys-1.0-r1.ebuild -179 /usr/portage/games-rpg/sumwars -180 /usr/portage/games-rpg/sumwars/ChangeLog -181 /usr/portage/games-rpg/sumwars/Manifest -182 /usr/portage/games-rpg/sumwars/metadata.xml -183 /usr/portage/games-rpg/sumwars/sumwars-0.5.8.ebuild -184 /usr/portage/games-rpg/bastion -185 /usr/portage/games-rpg/bastion/ChangeLog -186 /usr/portage/games-rpg/bastion/Manifest -187 /usr/portage/games-rpg/bastion/bastion-20120620-r1.ebuild -188 /usr/portage/games-rpg/bastion/metadata.xml -189 /usr/portage/games-rpg/manaplus -190 /usr/portage/games-rpg/manaplus/ChangeLog -191 /usr/portage/games-rpg/manaplus/manaplus-1.3.9.29.ebuild -192 /usr/portage/games-rpg/manaplus/Manifest -193 /usr/portage/games-rpg/manaplus/metadata.xml -194 /usr/portage/games-rpg/manaplus/manaplus-1.5.5.9.ebuild -195 /usr/portage/games-rpg/mana -196 /usr/portage/games-rpg/mana/ChangeLog -197 /usr/portage/games-rpg/mana/mana-0.6.1.ebuild -198 /usr/portage/games-rpg/mana/Manifest -199 /usr/portage/games-rpg/mana/metadata.xml -200 /usr/portage/games-rpg/mana/files -201 /usr/portage/games-rpg/mana/files/mana-0.6.1-Import-cstdint-for-int64_t.patch -202 /usr/portage/games-rpg/mana/files/mana-0.6.1-Trick-gcc-into-importing-C99-stdint.h-when-C-11-is-n.patch -203 /usr/portage/games-rpg/mana/files/mana-0.6.1-gentoo.patch -204 /usr/portage/games-rpg/mana/files/mana-0.6.1-Fix-missing-virtual-destructors-and-guichan-use.patch -205 /usr/portage/games-rpg/kqlives -206 /usr/portage/games-rpg/kqlives/ChangeLog -207 /usr/portage/games-rpg/kqlives/Manifest -208 /usr/portage/games-rpg/kqlives/metadata.xml -209 /usr/portage/games-rpg/kqlives/kqlives-0.99.ebuild -210 /usr/portage/games-rpg/kqlives/files -211 /usr/portage/games-rpg/kqlives/files/kqlives.xpm -212 /usr/portage/games-rpg/eternal-lands-bloodsucker -213 /usr/portage/games-rpg/eternal-lands-bloodsucker/ChangeLog -214 /usr/portage/games-rpg/eternal-lands-bloodsucker/eternal-lands-bloodsucker-3.0.ebuild -215 /usr/portage/games-rpg/eternal-lands-bloodsucker/Manifest -216 /usr/portage/games-rpg/eternal-lands-bloodsucker/eternal-lands-bloodsucker-3.0_p20110618.ebuild -217 /usr/portage/games-rpg/eternal-lands-bloodsucker/metadata.xml -218 /usr/portage/games-rpg/zsdx -219 /usr/portage/games-rpg/zsdx/ChangeLog -220 /usr/portage/games-rpg/zsdx/Manifest -221 /usr/portage/games-rpg/zsdx/zsdx-1.9.0.ebuild -222 /usr/portage/games-rpg/zsdx/metadata.xml -223 /usr/portage/games-rpg/arx-fatalis-demo -224 /usr/portage/games-rpg/arx-fatalis-demo/ChangeLog -225 /usr/portage/games-rpg/arx-fatalis-demo/Manifest -226 /usr/portage/games-rpg/arx-fatalis-demo/metadata.xml -227 /usr/portage/games-rpg/arx-fatalis-demo/arx-fatalis-demo-0.ebuild -228 /usr/portage/games-rpg/avadon -229 /usr/portage/games-rpg/avadon/ChangeLog -230 /usr/portage/games-rpg/avadon/Manifest -231 /usr/portage/games-rpg/avadon/avadon-1.0.4.ebuild -232 /usr/portage/games-rpg/avadon/metadata.xml -233 /usr/portage/games-rpg/wastesedge -234 /usr/portage/games-rpg/wastesedge/ChangeLog -235 /usr/portage/games-rpg/wastesedge/Manifest -236 /usr/portage/games-rpg/wastesedge/metadata.xml -237 /usr/portage/games-rpg/wastesedge/wastesedge-0.3.5.ebuild -238 /usr/portage/games-rpg/daimonin-client -239 /usr/portage/games-rpg/daimonin-client/ChangeLog -240 /usr/portage/games-rpg/daimonin-client/Manifest -241 /usr/portage/games-rpg/daimonin-client/metadata.xml -242 /usr/portage/games-rpg/daimonin-client/daimonin-client-0.10.5.ebuild -243 /usr/portage/games-rpg/daimonin-client/files -244 /usr/portage/games-rpg/daimonin-client/files/daimonin-client-0.10.5-nozlib.patch -245 /usr/portage/games-rpg/daimonin-client/files/daimonin-client-0.10.5-datadir.patch -246 /usr/portage/games-rpg/nwn-cep -247 /usr/portage/games-rpg/nwn-cep/ChangeLog -248 /usr/portage/games-rpg/nwn-cep/Manifest -249 /usr/portage/games-rpg/nwn-cep/nwn-cep-2.0.ebuild -250 /usr/portage/games-rpg/nwn-cep/metadata.xml -251 /usr/portage/games-rpg/nwn-cep/nwn-cep-1.68-r1.ebuild -252 /usr/portage/games-rpg/dear-esther -253 /usr/portage/games-rpg/dear-esther/ChangeLog -254 /usr/portage/games-rpg/dear-esther/Manifest -255 /usr/portage/games-rpg/dear-esther/metadata.xml -256 /usr/portage/games-rpg/dear-esther/dear-esther-20130608.ebuild -257 /usr/portage/games-rpg/wasteland2 -258 /usr/portage/games-rpg/wasteland2/ChangeLog -259 /usr/portage/games-rpg/wasteland2/Manifest -260 /usr/portage/games-rpg/wasteland2/metadata.xml -261 /usr/portage/games-rpg/wasteland2/wasteland2-1.3.0.7.ebuild -262 /usr/portage/games-rpg/sacred-gold -263 /usr/portage/games-rpg/sacred-gold/ChangeLog -264 /usr/portage/games-rpg/sacred-gold/Manifest -265 /usr/portage/games-rpg/sacred-gold/metadata.xml -266 /usr/portage/games-rpg/sacred-gold/sacred-gold-1.0.ebuild -267 /usr/portage/games-rpg/sacred-gold/sacred-gold-1.0.01.ebuild -268 /usr/portage/games-rpg/freedink -269 /usr/portage/games-rpg/freedink/ChangeLog -270 /usr/portage/games-rpg/freedink/Manifest -271 /usr/portage/games-rpg/freedink/metadata.xml -272 /usr/portage/games-rpg/freedink/freedink-108.4.ebuild -273 /usr/portage/games-rpg/pcgen -274 /usr/portage/games-rpg/pcgen/ChangeLog -275 /usr/portage/games-rpg/pcgen/Manifest -276 /usr/portage/games-rpg/pcgen/pcgen-6.04.01.ebuild -277 /usr/portage/games-rpg/pcgen/metadata.xml -278 /usr/portage/games-rpg/nwn-penultima -279 /usr/portage/games-rpg/nwn-penultima/ChangeLog -280 /usr/portage/games-rpg/nwn-penultima/Manifest -281 /usr/portage/games-rpg/nwn-penultima/metadata.xml -282 /usr/portage/games-rpg/nwn-penultima/nwn-penultima-1.ebuild -283 /usr/portage/games-rpg/nwn-penultima/nwn-penultima-1-r1.ebuild -284 /usr/portage/games-rpg/egoboo -285 /usr/portage/games-rpg/egoboo/ChangeLog -286 /usr/portage/games-rpg/egoboo/Manifest -287 /usr/portage/games-rpg/egoboo/egoboo-2.8.1.ebuild -288 /usr/portage/games-rpg/egoboo/metadata.xml -289 /usr/portage/games-rpg/egoboo/files -290 /usr/portage/games-rpg/egoboo/files/egoboo-2.8.1-gentoo.patch -291 /usr/portage/games-rpg/freedroidrpg -292 /usr/portage/games-rpg/freedroidrpg/ChangeLog -293 /usr/portage/games-rpg/freedroidrpg/Manifest -294 /usr/portage/games-rpg/freedroidrpg/freedroidrpg-0.15.1.ebuild -295 /usr/portage/games-rpg/freedroidrpg/metadata.xml -296 /usr/portage/games-rpg/gwiz -297 /usr/portage/games-rpg/gwiz/ChangeLog -298 /usr/portage/games-rpg/gwiz/Manifest -299 /usr/portage/games-rpg/gwiz/metadata.xml -300 /usr/portage/games-rpg/gwiz/gwiz-0.8.ebuild -301 /usr/portage/games-rpg/gwiz/files -302 /usr/portage/games-rpg/gwiz/files/gwiz-0.8-buffer.patch -303 /usr/portage/games-rpg/dragonhunt -304 /usr/portage/games-rpg/dragonhunt/ChangeLog -305 /usr/portage/games-rpg/dragonhunt/Manifest -306 /usr/portage/games-rpg/dragonhunt/dragonhunt-3.56-r1.ebuild -307 /usr/portage/games-rpg/dragonhunt/metadata.xml -308 /usr/portage/games-rpg/draci-historie -309 /usr/portage/games-rpg/draci-historie/ChangeLog -310 /usr/portage/games-rpg/draci-historie/draci-historie-2012.ebuild -311 /usr/portage/games-rpg/draci-historie/Manifest -312 /usr/portage/games-rpg/draci-historie/metadata.xml -313 /usr/portage/games-rpg/dreamweb -314 /usr/portage/games-rpg/dreamweb/ChangeLog -315 /usr/portage/games-rpg/dreamweb/Manifest -316 /usr/portage/games-rpg/dreamweb/dreamweb-1.1.ebuild -317 /usr/portage/games-rpg/dreamweb/metadata.xml -318 /usr/portage/games-rpg/valyriatear -319 /usr/portage/games-rpg/valyriatear/ChangeLog -320 /usr/portage/games-rpg/valyriatear/Manifest -321 /usr/portage/games-rpg/valyriatear/metadata.xml -322 /usr/portage/games-rpg/valyriatear/valyriatear-1.0.0.ebuild -323 /usr/portage/games-rpg/nwn -324 /usr/portage/games-rpg/nwn/ChangeLog -325 /usr/portage/games-rpg/nwn/Manifest -326 /usr/portage/games-rpg/nwn/nwn-1.69-r1.ebuild -327 /usr/portage/games-rpg/nwn/metadata.xml -328 /usr/portage/games-rpg/nwn/nwn-1.68-r5.ebuild -329 /usr/portage/games-rpg/nwn/files -330 /usr/portage/games-rpg/nwn/files/fixinstall -331 /usr/portage/games-rpg/nwn/nwn-1.68-r6.ebuild -332 /usr/portage/games-rpg/twclone -333 /usr/portage/games-rpg/twclone/ChangeLog -334 /usr/portage/games-rpg/twclone/Manifest -335 /usr/portage/games-rpg/twclone/metadata.xml -336 /usr/portage/games-rpg/twclone/twclone-0.14.ebuild -337 /usr/portage/games-rpg/zsxd -338 /usr/portage/games-rpg/zsxd/ChangeLog -339 /usr/portage/games-rpg/zsxd/Manifest -340 /usr/portage/games-rpg/zsxd/metadata.xml -341 /usr/portage/games-rpg/zsxd/zsxd-1.9.0.ebuild -342 /usr/portage/games-rpg/grimrock -343 /usr/portage/games-rpg/grimrock/ChangeLog -344 /usr/portage/games-rpg/grimrock/Manifest -345 /usr/portage/games-rpg/grimrock/metadata.xml -346 /usr/portage/games-rpg/grimrock/grimrock-20130515.ebuild -347 /usr/portage/games-arcade -348 /usr/portage/games-arcade/ascii-invaders -349 /usr/portage/games-arcade/ascii-invaders/ChangeLog -350 /usr/portage/games-arcade/ascii-invaders/Manifest -351 /usr/portage/games-arcade/ascii-invaders/metadata.xml -352 /usr/portage/games-arcade/ascii-invaders/ascii-invaders-0.1b.ebuild -353 /usr/portage/games-arcade/notpacman -354 /usr/portage/games-arcade/notpacman/ChangeLog -355 /usr/portage/games-arcade/notpacman/Manifest -356 /usr/portage/games-arcade/notpacman/metadata.xml -357 /usr/portage/games-arcade/notpacman/notpacman-1.0.4.ebuild -358 /usr/portage/games-arcade/gnake -359 /usr/portage/games-arcade/gnake/ChangeLog -360 /usr/portage/games-arcade/gnake/Manifest -361 /usr/portage/games-arcade/gnake/metadata.xml -362 /usr/portage/games-arcade/gnake/gnake-0.94b.ebuild -363 /usr/portage/games-arcade/xbubble -364 /usr/portage/games-arcade/xbubble/ChangeLog -365 /usr/portage/games-arcade/xbubble/Manifest -366 /usr/portage/games-arcade/xbubble/metadata.xml -367 /usr/portage/games-arcade/xbubble/xbubble-0.5.8.ebuild -368 /usr/portage/games-arcade/xbubble/files -369 /usr/portage/games-arcade/xbubble/files/xbubble-0.5.8-libpng14.patch -370 /usr/portage/games-arcade/xbubble/files/xbubble-0.5.8-png15.patch -371 /usr/portage/games-arcade/xbubble/files/xbubble-0.5.8-locale.patch -372 /usr/portage/games-arcade/xbubble/files/xbubble-0.5.8-xpaths.patch -373 /usr/portage/games-arcade/stardork -374 /usr/portage/games-arcade/stardork/ChangeLog -375 /usr/portage/games-arcade/stardork/Manifest -376 /usr/portage/games-arcade/stardork/stardork-0.7.ebuild -377 /usr/portage/games-arcade/stardork/metadata.xml -378 /usr/portage/games-arcade/blobby -379 /usr/portage/games-arcade/blobby/ChangeLog -380 /usr/portage/games-arcade/blobby/Manifest -381 /usr/portage/games-arcade/blobby/blobby-0.9c.ebuild -382 /usr/portage/games-arcade/blobby/metadata.xml -383 /usr/portage/games-arcade/blobby/files -384 /usr/portage/games-arcade/blobby/files/blobby-0.9c-gcc47.patch -385 /usr/portage/games-arcade/jumpnbump -386 /usr/portage/games-arcade/jumpnbump/ChangeLog -387 /usr/portage/games-arcade/jumpnbump/Manifest -388 /usr/portage/games-arcade/jumpnbump/jumpnbump-1.50-r1.ebuild -389 /usr/portage/games-arcade/jumpnbump/metadata.xml -390 /usr/portage/games-arcade/xtux -391 /usr/portage/games-arcade/xtux/ChangeLog -392 /usr/portage/games-arcade/xtux/xtux-20030306.ebuild -393 /usr/portage/games-arcade/xtux/Manifest -394 /usr/portage/games-arcade/xtux/metadata.xml -395 /usr/portage/games-arcade/xtux/files -396 /usr/portage/games-arcade/xtux/files/xtux-20030306-particles.patch -397 /usr/portage/games-arcade/xtux/files/xtux-20030306-ldflags.patch -398 /usr/portage/games-arcade/rockdodger -399 /usr/portage/games-arcade/rockdodger/ChangeLog -400 /usr/portage/games-arcade/rockdodger/Manifest -401 /usr/portage/games-arcade/rockdodger/rockdodger-0.6.0a-r1.ebuild -402 /usr/portage/games-arcade/rockdodger/metadata.xml -403 /usr/portage/games-arcade/rockdodger/files -404 /usr/portage/games-arcade/rockdodger/files/rockdodger-0.6.0a-gcc41.patch -405 /usr/portage/games-arcade/rockdodger/files/rockdodger-0.6.0a-underlink.patch -406 /usr/portage/games-arcade/rockdodger/files/0.6.0a-sec.patch -407 /usr/portage/games-arcade/supertux -408 /usr/portage/games-arcade/supertux/ChangeLog -409 /usr/portage/games-arcade/supertux/Manifest -410 /usr/portage/games-arcade/supertux/metadata.xml -411 /usr/portage/games-arcade/supertux/supertux-0.1.3.ebuild -412 /usr/portage/games-arcade/supertux/files -413 /usr/portage/games-arcade/supertux/files/supertux-0.1.3-desktop.patch -414 /usr/portage/games-arcade/supertux/files/supertux-0.1.3-ndebug.patch -415 /usr/portage/games-arcade/supertux/files/supertux-0.1.3-gcc41.patch -416 /usr/portage/games-arcade/dynamitejack -417 /usr/portage/games-arcade/dynamitejack/ChangeLog -418 /usr/portage/games-arcade/dynamitejack/Manifest -419 /usr/portage/games-arcade/dynamitejack/metadata.xml -420 /usr/portage/games-arcade/dynamitejack/dynamitejack-1.0.23-r1.ebuild -421 /usr/portage/games-arcade/smc -422 /usr/portage/games-arcade/smc/ChangeLog -423 /usr/portage/games-arcade/smc/Manifest -424 /usr/portage/games-arcade/smc/smc-1.9.ebuild -425 /usr/portage/games-arcade/smc/metadata.xml -426 /usr/portage/games-arcade/smc/files -427 /usr/portage/games-arcade/smc/files/smc-1.9-underlink.patch -428 /usr/portage/games-arcade/smc/files/smc-1.9-boost150.patch -429 /usr/portage/games-arcade/marbleblast-demo -430 /usr/portage/games-arcade/marbleblast-demo/ChangeLog -431 /usr/portage/games-arcade/marbleblast-demo/Manifest -432 /usr/portage/games-arcade/marbleblast-demo/metadata.xml -433 /usr/portage/games-arcade/marbleblast-demo/marbleblast-demo-1.3.ebuild -434 /usr/portage/games-arcade/epiar -435 /usr/portage/games-arcade/epiar/ChangeLog -436 /usr/portage/games-arcade/epiar/Manifest -437 /usr/portage/games-arcade/epiar/metadata.xml -438 /usr/portage/games-arcade/epiar/files -439 /usr/portage/games-arcade/epiar/files/epiar-0.5-paths.patch -440 /usr/portage/games-arcade/epiar/files/epiar-0.5-gcc41.patch -441 /usr/portage/games-arcade/epiar/files/epiar-0.5-Makefile.linux.patch -442 /usr/portage/games-arcade/epiar/files/epiar-0.5-underlink.patch -443 /usr/portage/games-arcade/epiar/files/0.5-gentoo-paths.patch -444 /usr/portage/games-arcade/epiar/epiar-0.5-r1.ebuild -445 /usr/portage/games-arcade/circuslinux -446 /usr/portage/games-arcade/circuslinux/ChangeLog -447 /usr/portage/games-arcade/circuslinux/Manifest -448 /usr/portage/games-arcade/circuslinux/metadata.xml -449 /usr/portage/games-arcade/circuslinux/circuslinux-1.0.3.ebuild -450 /usr/portage/games-arcade/sdl-sopwith -451 /usr/portage/games-arcade/sdl-sopwith/ChangeLog -452 /usr/portage/games-arcade/sdl-sopwith/Manifest -453 /usr/portage/games-arcade/sdl-sopwith/sdl-sopwith-1.7.5-r1.ebuild -454 /usr/portage/games-arcade/sdl-sopwith/metadata.xml -455 /usr/portage/games-arcade/sdl-sopwith/files -456 /usr/portage/games-arcade/sdl-sopwith/files/sdl-sopwith-1.7.5-nogtk.patch -457 /usr/portage/games-arcade/sdl-sopwith/files/sdl-sopwith-1.7.5-video-fix.patch -458 /usr/portage/games-arcade/moleinvasion -459 /usr/portage/games-arcade/moleinvasion/ChangeLog -460 /usr/portage/games-arcade/moleinvasion/Manifest -461 /usr/portage/games-arcade/moleinvasion/metadata.xml -462 /usr/portage/games-arcade/moleinvasion/moleinvasion-0.4-r1.ebuild -463 /usr/portage/games-arcade/moleinvasion/files -464 /usr/portage/games-arcade/moleinvasion/files/moleinvasion-0.4-opengl.patch -465 /usr/portage/games-arcade/moleinvasion/files/moleinvasion-0.4-underlink.patch -466 /usr/portage/games-arcade/aquaria -467 /usr/portage/games-arcade/aquaria/ChangeLog -468 /usr/portage/games-arcade/aquaria/Manifest -469 /usr/portage/games-arcade/aquaria/aquaria-1.1.3-r1.ebuild -470 /usr/portage/games-arcade/aquaria/metadata.xml -471 /usr/portage/games-arcade/pycadia -472 /usr/portage/games-arcade/pycadia/ChangeLog -473 /usr/portage/games-arcade/pycadia/Manifest -474 /usr/portage/games-arcade/pycadia/metadata.xml -475 /usr/portage/games-arcade/pycadia/pycadia-0.5.1.ebuild -476 /usr/portage/games-arcade/sable -477 /usr/portage/games-arcade/sable/ChangeLog -478 /usr/portage/games-arcade/sable/Manifest -479 /usr/portage/games-arcade/sable/sable-1.0.ebuild -480 /usr/portage/games-arcade/sable/metadata.xml -481 /usr/portage/games-arcade/sable/files -482 /usr/portage/games-arcade/sable/files/sable-1.0-gentoo.patch -483 /usr/portage/games-arcade/cdogs-sdl -484 /usr/portage/games-arcade/cdogs-sdl/ChangeLog -485 /usr/portage/games-arcade/cdogs-sdl/Manifest -486 /usr/portage/games-arcade/cdogs-sdl/cdogs-sdl-0.4-r1.ebuild -487 /usr/portage/games-arcade/cdogs-sdl/metadata.xml -488 /usr/portage/games-arcade/cdogs-sdl/files -489 /usr/portage/games-arcade/cdogs-sdl/files/cdogs-sdl-0.4-64bit.patch -490 /usr/portage/games-arcade/digger -491 /usr/portage/games-arcade/digger/ChangeLog -492 /usr/portage/games-arcade/digger/Manifest -493 /usr/portage/games-arcade/digger/digger-20140423.ebuild -494 /usr/portage/games-arcade/digger/metadata.xml -495 /usr/portage/games-arcade/digger/files -496 /usr/portage/games-arcade/digger/files/digger-20140423-ldflags.patch -497 /usr/portage/games-arcade/afternoonstalker -498 /usr/portage/games-arcade/afternoonstalker/ChangeLog -499 /usr/portage/games-arcade/afternoonstalker/Manifest -500 /usr/portage/games-arcade/afternoonstalker/metadata.xml -501 /usr/portage/games-arcade/afternoonstalker/afternoonstalker-1.1.5.ebuild -502 /usr/portage/games-arcade/pacmanarena -503 /usr/portage/games-arcade/pacmanarena/ChangeLog -504 /usr/portage/games-arcade/pacmanarena/Manifest -505 /usr/portage/games-arcade/pacmanarena/metadata.xml -506 /usr/portage/games-arcade/pacmanarena/pacmanarena-0.15.ebuild -507 /usr/portage/games-arcade/pacmanarena/files -508 /usr/portage/games-arcade/pacmanarena/files/pacmanarena-0.15-underlink.patch -509 /usr/portage/games-arcade/holotz-castle -510 /usr/portage/games-arcade/holotz-castle/ChangeLog -511 /usr/portage/games-arcade/holotz-castle/Manifest -512 /usr/portage/games-arcade/holotz-castle/holotz-castle-1.3.14.ebuild -513 /usr/portage/games-arcade/holotz-castle/metadata.xml -514 /usr/portage/games-arcade/holotz-castle/files -515 /usr/portage/games-arcade/holotz-castle/files/holotz-castle-1.3.14-gcc44.patch -516 /usr/portage/games-arcade/holotz-castle/files/holotz-castle-1.3.14-build.patch -517 /usr/portage/games-arcade/holotz-castle/files/holotz-castle-1.3.14-underlink.patch -518 /usr/portage/games-arcade/bloboats -519 /usr/portage/games-arcade/bloboats/ChangeLog -520 /usr/portage/games-arcade/bloboats/Manifest -521 /usr/portage/games-arcade/bloboats/bloboats-1.0.2.ebuild -522 /usr/portage/games-arcade/bloboats/metadata.xml -523 /usr/portage/games-arcade/bloboats/files -524 /usr/portage/games-arcade/bloboats/files/bloboats-1.0.2-warnings.patch -525 /usr/portage/games-arcade/berusky -526 /usr/portage/games-arcade/berusky/ChangeLog -527 /usr/portage/games-arcade/berusky/Manifest -528 /usr/portage/games-arcade/berusky/berusky-1.7.1.ebuild -529 /usr/portage/games-arcade/berusky/metadata.xml -530 /usr/portage/games-arcade/berusky/files -531 /usr/portage/games-arcade/berusky/files/berusky-1.7.1-gentoo.patch -532 /usr/portage/games-arcade/conveysdl -533 /usr/portage/games-arcade/conveysdl/ChangeLog -534 /usr/portage/games-arcade/conveysdl/Manifest -535 /usr/portage/games-arcade/conveysdl/metadata.xml -536 /usr/portage/games-arcade/conveysdl/conveysdl-1.3.ebuild -537 /usr/portage/games-arcade/conveysdl/files -538 /usr/portage/games-arcade/conveysdl/files/conveysdl-1.3-arrays.patch -539 /usr/portage/games-arcade/conveysdl/files/conveysdl-1.3-speed.patch -540 /usr/portage/games-arcade/openbubbles -541 /usr/portage/games-arcade/openbubbles/ChangeLog -542 /usr/portage/games-arcade/openbubbles/Manifest -543 /usr/portage/games-arcade/openbubbles/metadata.xml -544 /usr/portage/games-arcade/openbubbles/openbubbles-1.2.ebuild -545 /usr/portage/games-arcade/openbubbles/files -546 /usr/portage/games-arcade/openbubbles/files/openbubbles-1.2-glibc2.10.patch -547 /usr/portage/games-arcade/vor -548 /usr/portage/games-arcade/vor/ChangeLog -549 /usr/portage/games-arcade/vor/Manifest -550 /usr/portage/games-arcade/vor/metadata.xml -551 /usr/portage/games-arcade/vor/vor-0.5.5.ebuild -552 /usr/portage/games-arcade/vor/files -553 /usr/portage/games-arcade/vor/files/vor-0.5.5-underlink.patch -554 /usr/portage/games-arcade/wop -555 /usr/portage/games-arcade/wop/ChangeLog -556 /usr/portage/games-arcade/wop/Manifest -557 /usr/portage/games-arcade/wop/wop-0.4.3-r1.ebuild -558 /usr/portage/games-arcade/wop/metadata.xml -559 /usr/portage/games-arcade/wop/files -560 /usr/portage/games-arcade/wop/files/wop-0.4.3-gcc43.patch -561 /usr/portage/games-arcade/wop/files/wop-0.4.3-Makefile.patch -562 /usr/portage/games-arcade/supertransball2 -563 /usr/portage/games-arcade/supertransball2/ChangeLog -564 /usr/portage/games-arcade/supertransball2/supertransball2-1.5.ebuild -565 /usr/portage/games-arcade/supertransball2/Manifest -566 /usr/portage/games-arcade/supertransball2/metadata.xml -567 /usr/portage/games-arcade/supertransball2/files -568 /usr/portage/games-arcade/supertransball2/files/supertransball2-1.5-ldflags.patch -569 /usr/portage/games-arcade/grande-KXL -570 /usr/portage/games-arcade/grande-KXL/ChangeLog -571 /usr/portage/games-arcade/grande-KXL/Manifest -572 /usr/portage/games-arcade/grande-KXL/metadata.xml -573 /usr/portage/games-arcade/grande-KXL/grande-KXL-0.6.ebuild -574 /usr/portage/games-arcade/grande-KXL/files -575 /usr/portage/games-arcade/grande-KXL/files/grande-KXL-0.6-configure.in.patch -576 /usr/portage/games-arcade/grande-KXL/files/grande-KXL-0.6-cflags.patch -577 /usr/portage/games-arcade/cavezofphear -578 /usr/portage/games-arcade/cavezofphear/ChangeLog -579 /usr/portage/games-arcade/cavezofphear/Manifest -580 /usr/portage/games-arcade/cavezofphear/metadata.xml -581 /usr/portage/games-arcade/cavezofphear/cavezofphear-0.5.1.ebuild -582 /usr/portage/games-arcade/cavezofphear/files -583 /usr/portage/games-arcade/cavezofphear/files/cavezofphear-0.5.1-gentoo.patch -584 /usr/portage/games-arcade/defendguin -585 /usr/portage/games-arcade/defendguin/ChangeLog -586 /usr/portage/games-arcade/defendguin/Manifest -587 /usr/portage/games-arcade/defendguin/metadata.xml -588 /usr/portage/games-arcade/defendguin/defendguin-0.0.12.ebuild -589 /usr/portage/games-arcade/missile -590 /usr/portage/games-arcade/missile/ChangeLog -591 /usr/portage/games-arcade/missile/Manifest -592 /usr/portage/games-arcade/missile/metadata.xml -593 /usr/portage/games-arcade/missile/missile-1.0.1.ebuild -594 /usr/portage/games-arcade/missile/files -595 /usr/portage/games-arcade/missile/files/missile-1.0.1-ldflags.patch -596 /usr/portage/games-arcade/retrobattle -597 /usr/portage/games-arcade/retrobattle/ChangeLog -598 /usr/portage/games-arcade/retrobattle/Manifest -599 /usr/portage/games-arcade/retrobattle/retrobattle-1.0.0.ebuild -600 /usr/portage/games-arcade/retrobattle/metadata.xml -601 /usr/portage/games-arcade/retrobattle/files -602 /usr/portage/games-arcade/retrobattle/files/retrobattle-1.0.0-sound.patch -603 /usr/portage/games-arcade/retrobattle/files/retrobattle-1.0.0-build.patch -604 /usr/portage/games-arcade/asteroid -605 /usr/portage/games-arcade/asteroid/ChangeLog -606 /usr/portage/games-arcade/asteroid/Manifest -607 /usr/portage/games-arcade/asteroid/metadata.xml -608 /usr/portage/games-arcade/asteroid/asteroid-1.1.ebuild -609 /usr/portage/games-arcade/asteroid/files -610 /usr/portage/games-arcade/asteroid/files/asteroid-1.1-include.patch -611 /usr/portage/games-arcade/sdb -612 /usr/portage/games-arcade/sdb/ChangeLog -613 /usr/portage/games-arcade/sdb/Manifest -614 /usr/portage/games-arcade/sdb/metadata.xml -615 /usr/portage/games-arcade/sdb/files -616 /usr/portage/games-arcade/sdb/files/sdb-1.0.2-endian.patch -617 /usr/portage/games-arcade/sdb/files/sdb-1.0.2-gcc43.patch -618 /usr/portage/games-arcade/sdb/files/sdb-1.0.2-ldflags.patch -619 /usr/portage/games-arcade/sdb/sdb-1.0.2.ebuild -620 /usr/portage/games-arcade/lbreakout -621 /usr/portage/games-arcade/lbreakout/ChangeLog -622 /usr/portage/games-arcade/lbreakout/Manifest -623 /usr/portage/games-arcade/lbreakout/metadata.xml -624 /usr/portage/games-arcade/lbreakout/lbreakout-010315.ebuild -625 /usr/portage/games-arcade/xscavenger -626 /usr/portage/games-arcade/xscavenger/ChangeLog -627 /usr/portage/games-arcade/xscavenger/Manifest -628 /usr/portage/games-arcade/xscavenger/metadata.xml -629 /usr/portage/games-arcade/xscavenger/files -630 /usr/portage/games-arcade/xscavenger/files/1.4.4-gentoo.patch -631 /usr/portage/games-arcade/xscavenger/xscavenger-1.4.4.ebuild -632 /usr/portage/games-arcade/bomns -633 /usr/portage/games-arcade/bomns/ChangeLog -634 /usr/portage/games-arcade/bomns/Manifest -635 /usr/portage/games-arcade/bomns/metadata.xml -636 /usr/portage/games-arcade/bomns/bomns-0.99.2.ebuild -637 /usr/portage/games-arcade/bomns/files -638 /usr/portage/games-arcade/bomns/files/bomns-0.99.2-fpe.patch -639 /usr/portage/games-arcade/openmortal -640 /usr/portage/games-arcade/openmortal/ChangeLog -641 /usr/portage/games-arcade/openmortal/Manifest -642 /usr/portage/games-arcade/openmortal/metadata.xml -643 /usr/portage/games-arcade/openmortal/openmortal-0.7-r1.ebuild -644 /usr/portage/games-arcade/openmortal/files -645 /usr/portage/games-arcade/openmortal/files/openmortal-0.7-freetype.patch -646 /usr/portage/games-arcade/openmortal/files/openmortal-0.7-gcc41.patch -647 /usr/portage/games-arcade/syobon -648 /usr/portage/games-arcade/syobon/ChangeLog -649 /usr/portage/games-arcade/syobon/Manifest -650 /usr/portage/games-arcade/syobon/metadata.xml -651 /usr/portage/games-arcade/syobon/syobon-1.0.1.ebuild -652 /usr/portage/games-arcade/aop -653 /usr/portage/games-arcade/aop/ChangeLog -654 /usr/portage/games-arcade/aop/Manifest -655 /usr/portage/games-arcade/aop/aop-0.6.ebuild -656 /usr/portage/games-arcade/aop/metadata.xml -657 /usr/portage/games-arcade/aop/files -658 /usr/portage/games-arcade/aop/files/aop-0.6-as-needed.patch -659 /usr/portage/games-arcade/commandergenius -660 /usr/portage/games-arcade/commandergenius/ChangeLog -661 /usr/portage/games-arcade/commandergenius/Manifest -662 /usr/portage/games-arcade/commandergenius/metadata.xml -663 /usr/portage/games-arcade/commandergenius/commandergenius-1.8.0.0.ebuild -664 /usr/portage/games-arcade/commandergenius/files -665 /usr/portage/games-arcade/commandergenius/files/commandergenius-1.8.0.0-install.patch -666 /usr/portage/games-arcade/commandergenius/files/commandergenius-wrapper -667 /usr/portage/games-arcade/thinktanks-demo -668 /usr/portage/games-arcade/thinktanks-demo/ChangeLog -669 /usr/portage/games-arcade/thinktanks-demo/Manifest -670 /usr/portage/games-arcade/thinktanks-demo/thinktanks-demo-1.1-r2.ebuild -671 /usr/portage/games-arcade/thinktanks-demo/metadata.xml -672 /usr/portage/games-arcade/gunocide2ex -673 /usr/portage/games-arcade/gunocide2ex/ChangeLog -674 /usr/portage/games-arcade/gunocide2ex/Manifest -675 /usr/portage/games-arcade/gunocide2ex/metadata.xml -676 /usr/portage/games-arcade/gunocide2ex/gunocide2ex-1.0.ebuild -677 /usr/portage/games-arcade/gunocide2ex/files -678 /usr/portage/games-arcade/gunocide2ex/files/gunocide2ex-1.0-build.patch -679 /usr/portage/games-arcade/gunocide2ex/files/gunocide2ex-1.0-glibc2.10.patch -680 /usr/portage/games-arcade/excido -681 /usr/portage/games-arcade/excido/ChangeLog -682 /usr/portage/games-arcade/excido/Manifest -683 /usr/portage/games-arcade/excido/metadata.xml -684 /usr/portage/games-arcade/excido/excido-0.1.5c-r2.ebuild -685 /usr/portage/games-arcade/excido/files -686 /usr/portage/games-arcade/excido/files/excido-0.1.5c-build.patch -687 /usr/portage/games-arcade/excido/files/excido-0.1.5c-freealut.patch -688 /usr/portage/games-arcade/apricots -689 /usr/portage/games-arcade/apricots/ChangeLog -690 /usr/portage/games-arcade/apricots/apricots-0.2.6-r1.ebuild -691 /usr/portage/games-arcade/apricots/Manifest -692 /usr/portage/games-arcade/apricots/metadata.xml -693 /usr/portage/games-arcade/apricots/files -694 /usr/portage/games-arcade/apricots/files/apricots-0.2.6-freealut.patch -695 /usr/portage/games-arcade/apricots/files/apricots-0.2.6-ldflags.patch -696 /usr/portage/games-arcade/primateplunge -697 /usr/portage/games-arcade/primateplunge/ChangeLog -698 /usr/portage/games-arcade/primateplunge/Manifest -699 /usr/portage/games-arcade/primateplunge/primateplunge-1.1-r1.ebuild -700 /usr/portage/games-arcade/primateplunge/metadata.xml -701 /usr/portage/games-arcade/primateplunge/files -702 /usr/portage/games-arcade/primateplunge/files/primateplunge-1.1-AC_SUBST.patch -703 /usr/portage/games-arcade/xsfcave -704 /usr/portage/games-arcade/xsfcave/ChangeLog -705 /usr/portage/games-arcade/xsfcave/Manifest -706 /usr/portage/games-arcade/xsfcave/metadata.xml -707 /usr/portage/games-arcade/xsfcave/xsfcave-0.5.ebuild -708 /usr/portage/games-arcade/triplexinvaders -709 /usr/portage/games-arcade/triplexinvaders/ChangeLog -710 /usr/portage/games-arcade/triplexinvaders/Manifest -711 /usr/portage/games-arcade/triplexinvaders/metadata.xml -712 /usr/portage/games-arcade/triplexinvaders/triplexinvaders-1.08.ebuild -713 /usr/portage/games-arcade/triplexinvaders/files -714 /usr/portage/games-arcade/triplexinvaders/files/triplexinvaders-1.08-gentoo.patch -715 /usr/portage/games-arcade/pachi -716 /usr/portage/games-arcade/pachi/ChangeLog -717 /usr/portage/games-arcade/pachi/Manifest -718 /usr/portage/games-arcade/pachi/metadata.xml -719 /usr/portage/games-arcade/pachi/pachi-1.0.ebuild -720 /usr/portage/games-arcade/pachi/files -721 /usr/portage/games-arcade/pachi/files/1.0-autotools.patch -722 /usr/portage/games-arcade/marbleblastgold-demo -723 /usr/portage/games-arcade/marbleblastgold-demo/ChangeLog -724 /usr/portage/games-arcade/marbleblastgold-demo/Manifest -725 /usr/portage/games-arcade/marbleblastgold-demo/metadata.xml -726 /usr/portage/games-arcade/marbleblastgold-demo/marbleblastgold-demo-1.4.1.ebuild -727 /usr/portage/games-arcade/blockrage -728 /usr/portage/games-arcade/blockrage/ChangeLog -729 /usr/portage/games-arcade/blockrage/Manifest -730 /usr/portage/games-arcade/blockrage/metadata.xml -731 /usr/portage/games-arcade/blockrage/blockrage-0.2.3.ebuild -732 /usr/portage/games-arcade/blockrage/files -733 /usr/portage/games-arcade/blockrage/files/blockrage-0.2.3-config.patch -734 /usr/portage/games-arcade/solarwolf -735 /usr/portage/games-arcade/solarwolf/solarwolf-1.5.ebuild -736 /usr/portage/games-arcade/solarwolf/ChangeLog -737 /usr/portage/games-arcade/solarwolf/Manifest -738 /usr/portage/games-arcade/solarwolf/metadata.xml -739 /usr/portage/games-arcade/xboing -740 /usr/portage/games-arcade/xboing/ChangeLog -741 /usr/portage/games-arcade/xboing/Manifest -742 /usr/portage/games-arcade/xboing/metadata.xml -743 /usr/portage/games-arcade/xboing/xboing-2.4-r2.ebuild -744 /usr/portage/games-arcade/xboing/files -745 /usr/portage/games-arcade/xboing/files/xboing-2.4-buffer.patch -746 /usr/portage/games-arcade/xboing/files/xboing-2.4-sleep.patch -747 /usr/portage/games-arcade/komi -748 /usr/portage/games-arcade/komi/ChangeLog -749 /usr/portage/games-arcade/komi/Manifest -750 /usr/portage/games-arcade/komi/metadata.xml -751 /usr/portage/games-arcade/komi/komi-1.04.ebuild -752 /usr/portage/games-arcade/komi/files -753 /usr/portage/games-arcade/komi/files/1.04-DESTDIR.patch -754 /usr/portage/games-arcade/komi/files/komi-1.04-install.patch -755 /usr/portage/games-arcade/metadata.xml -756 /usr/portage/games-arcade/briquolo -757 /usr/portage/games-arcade/briquolo/ChangeLog -758 /usr/portage/games-arcade/briquolo/Manifest -759 /usr/portage/games-arcade/briquolo/briquolo-0.5.7.ebuild -760 /usr/portage/games-arcade/briquolo/metadata.xml -761 /usr/portage/games-arcade/briquolo/files -762 /usr/portage/games-arcade/briquolo/files/briquolo-0.5.7-gcc43.patch -763 /usr/portage/games-arcade/briquolo/files/briquolo-0.5.7-libpng14.patch -764 /usr/portage/games-arcade/spout -765 /usr/portage/games-arcade/spout/ChangeLog -766 /usr/portage/games-arcade/spout/Manifest -767 /usr/portage/games-arcade/spout/metadata.xml -768 /usr/portage/games-arcade/spout/spout-1.3.ebuild -769 /usr/portage/games-arcade/mrrescue -770 /usr/portage/games-arcade/mrrescue/ChangeLog -771 /usr/portage/games-arcade/mrrescue/Manifest -772 /usr/portage/games-arcade/mrrescue/metadata.xml -773 /usr/portage/games-arcade/mrrescue/mrrescue-1.02b.ebuild -774 /usr/portage/games-arcade/insaneodyssey -775 /usr/portage/games-arcade/insaneodyssey/ChangeLog -776 /usr/portage/games-arcade/insaneodyssey/Manifest -777 /usr/portage/games-arcade/insaneodyssey/metadata.xml -778 /usr/portage/games-arcade/insaneodyssey/insaneodyssey-000311.ebuild -779 /usr/portage/games-arcade/insaneodyssey/files -780 /usr/portage/games-arcade/insaneodyssey/files/insaneodyssey-000311-datafiles.patch -781 /usr/portage/games-arcade/trailblazer -782 /usr/portage/games-arcade/trailblazer/ChangeLog -783 /usr/portage/games-arcade/trailblazer/Manifest -784 /usr/portage/games-arcade/trailblazer/metadata.xml -785 /usr/portage/games-arcade/trailblazer/trailblazer-0.9.ebuild -786 /usr/portage/games-arcade/trailblazer/files -787 /usr/portage/games-arcade/trailblazer/files/trailblazer-0.9-underlink.patch -788 /usr/portage/games-arcade/trailblazer/files/trailblazer-0.9-ldflags.patch -789 /usr/portage/games-arcade/monkey-bubble -790 /usr/portage/games-arcade/monkey-bubble/ChangeLog -791 /usr/portage/games-arcade/monkey-bubble/monkey-bubble-0.4.0.ebuild -792 /usr/portage/games-arcade/monkey-bubble/Manifest -793 /usr/portage/games-arcade/monkey-bubble/metadata.xml -794 /usr/portage/games-arcade/monkey-bubble/files -795 /usr/portage/games-arcade/monkey-bubble/files/monkey-bubble-0.4.0-glib-single-include.patch -796 /usr/portage/games-arcade/monkey-bubble/files/monkey-bubble-0.4.0-gnome-doc.patch -797 /usr/portage/games-arcade/monkey-bubble/files/monkey-bubble-0.4.0-asneeded.patch -798 /usr/portage/games-arcade/monkey-bubble/files/monkey-bubble-0.4.0-noesound.patch -799 /usr/portage/games-arcade/whichwayisup -800 /usr/portage/games-arcade/whichwayisup/ChangeLog diff --git a/project2/sql/unittests/mysqlschema.sql b/project2/sql/unittests/mysqlschema.sql deleted file mode 100644 index 58724c8..0000000 --- a/project2/sql/unittests/mysqlschema.sql +++ /dev/null @@ -1,14 +0,0 @@ -CREATE TABLE test( - id int, - fl numeric(5,2), - string varchar(30), - boolean bool, - dt timestamp, - ts time); - -INSERT INTO test VALUES(4, 123.45, 'some text', true, '2015-04-27 23:06:03', '38:13:12'); - -CREATE TABLE bulktest( - intcol int, - stringcol varchar(3000)); - diff --git a/project2/sql/unittests/odbcschema.sql b/project2/sql/unittests/odbcschema.sql deleted file mode 100644 index 96848eb..0000000 --- a/project2/sql/unittests/odbcschema.sql +++ /dev/null @@ -1,8 +0,0 @@ -CREATE TABLE test( - id int, - fl numeric(5,2), - string text, - boolean bool, - dt timestamp without time zone, - ts interval); -INSERT INTO test VALUES(4, 123.45, 'some text', true, '2015-04-27 23:06:03', '1 day 14:13:12'); diff --git a/project2/sql/unittests/pqschema.sql b/project2/sql/unittests/pqschema.sql deleted file mode 100644 index 2c7e94a..0000000 --- a/project2/sql/unittests/pqschema.sql +++ /dev/null @@ -1,37 +0,0 @@ --- --- pg_dump style comment --- Table: test; owner: comment: ; --- - -/* - This is - a - multiline comment */ - -CREATE TABLE test( - id int, - fl numeric(5,2), - string text, - boolean bool, - dt timestamp without time zone, - ts interval); - -INSERT INTO test VALUES(4, 123.45, 'some text with a ; in it and a '' too', true, '2015-04-27 23:06:03', '1 day 14:13:12'); - -CREATE TABLE test2( - path text not null); - -INSERT INTO test2 VALUES('$P2MOCKSCRIPTDIR/pqschema.sql'); - -CREATE FUNCTION event_tsvector() RETURNS int -LANGUAGE sql STABLE -AS $tag$ - SELECT max(id) - FROM test - WHERE string != 'complex '' string;'; -$tag$; - -CREATE TABLE bulktest( - id int, - string text); - diff --git a/project2/sql/unittests/sqliteschema.sql b/project2/sql/unittests/sqliteschema.sql deleted file mode 100644 index 393d21a..0000000 --- a/project2/sql/unittests/sqliteschema.sql +++ /dev/null @@ -1,6 +0,0 @@ -CREATE TABLE test( - id int, - fl numeric(5,2), - string text); -INSERT INTO test VALUES(4, 123.45, 'some text'); - diff --git a/project2/sql/unittests/testCore.cpp b/project2/sql/unittests/testCore.cpp deleted file mode 100644 index 440d676..0000000 --- a/project2/sql/unittests/testCore.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "testCore.h" -#include <testOptionsSource.h> -#include <definedDirs.h> - -TestCore::TestCore() : - testInt(43), - testDouble(3.14), - testString("Some C String"), - testBool(false), - testDateTime(boost::posix_time::from_time_t(1430530593)), - testInterval(boost::posix_time::time_duration(1, 2, 3)) -{ - TestOptionsSource::LoadTestOptions({ - { "common.datasourceRoot", (RootDir / "datasources").string() }, - }); -} - diff --git a/project2/sql/unittests/testCore.h b/project2/sql/unittests/testCore.h deleted file mode 100644 index 0a667d6..0000000 --- a/project2/sql/unittests/testCore.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef PROJECT2_SQL_UNITTEST_CORE -#define PROJECT2_SQL_UNITTEST_CORE - -#include <commonObjects.h> -#include <variableType.h> -#include <appInstance.h> - -class TestCore : public CommonObjects, AppInstance { - public: - TestCore(); - - int testInt; - double testDouble; - std::string testString; - bool testBool; - boost::posix_time::ptime testDateTime; - boost::posix_time::time_duration testInterval; -}; - -#endif - diff --git a/project2/sql/unittests/testmysql.cpp b/project2/sql/unittests/testmysql.cpp deleted file mode 100644 index 546199c..0000000 --- a/project2/sql/unittests/testmysql.cpp +++ /dev/null @@ -1,171 +0,0 @@ -#define BOOST_TEST_MODULE TestMySQL -#include <boost/test/unit_test.hpp> - -#include <mockDatasource.h> -#include <definedDirs.h> -#include <modifycommand.h> -#include <selectcommand.h> -#include <column.h> -#include <sql-modMySQL.h> -#include "testCore.h" -#include <sqlHandleAsVariableType.h> -#include <fstream> - -class StandardMockDatabase : public MockMySQLDatabase { - public: - StandardMockDatabase() : MockMySQLDatabase("mysqlmock", { - RootDir / "mysqlschema.sql" }) - { - } -}; - -BOOST_GLOBAL_FIXTURE( StandardMockDatabase ); - -BOOST_FIXTURE_TEST_SUITE( Core, TestCore ); - -BOOST_AUTO_TEST_CASE( transactions ) -{ - RdbmsDataSource * ds = CommonObjects::dataSource<RdbmsDataSource>("mysqlmock"); - auto ro = ds->getReadonly(); - - BOOST_REQUIRE_EQUAL(false, ro->inTx()); - ro->beginTx(); - BOOST_REQUIRE_EQUAL(true, ro->inTx()); - ro->rollbackTx(); - BOOST_REQUIRE_EQUAL(false, ro->inTx()); - - ro->beginTx(); - BOOST_REQUIRE_EQUAL(true, ro->inTx()); - ro->commitTx(); - BOOST_REQUIRE_EQUAL(false, ro->inTx()); - - ds->close(); -} - -BOOST_AUTO_TEST_CASE( bindAndSend ) -{ - RdbmsDataSource * ds = CommonObjects::dataSource<RdbmsDataSource>("mysqlmock"); - auto rw = ds->getWritable(); - - auto mod = rw->newModifyCommand("INSERT INTO test VALUES(?, ?, ?, ?, ?, ?)"); - mod->bindParamI(0, testInt); - mod->bindParamF(1, testDouble); - mod->bindParamS(2, testString); - mod->bindParamB(3, testBool); - mod->bindParamT(4, testDateTime); - mod->bindParamT(5, testInterval); - mod->execute(); - delete mod; - ds->commit(); - ds->close(); -} - -template<typename T> -void -assertColumnValueHelper(DB::SelectCommand & sel, const T & t) -{ - while (sel.fetch()) { - HandleAsVariableType h; - sel[0].apply(h); - BOOST_REQUIRE_EQUAL(t, h.variable.as<T>()); - } -} - -template<typename T> -void -assertColumnValueHelper(DB::SelectCommand & sel, unsigned int col, const T & t) -{ - HandleAsVariableType h; - sel[col].apply(h); - BOOST_REQUIRE_EQUAL(t, h.variable.as<T>()); -} - -BOOST_AUTO_TEST_CASE( bindAndSelect ) -{ - RdbmsDataSource * ds = CommonObjects::dataSource<RdbmsDataSource>("mysqlmock"); - auto ro = ds->getReadonly(); - - auto select = ro->newSelectCommand("SELECT * FROM test WHERE id = ?"); - select->bindParamI(0, testInt); - select->execute(); - int rows = 0; - while (select->fetch()) { - assertColumnValueHelper(*select, 0, testInt); - assertColumnValueHelper(*select, 1, testDouble); - assertColumnValueHelper(*select, 2, testString); - assertColumnValueHelper(*select, 3, testBool); - assertColumnValueHelper(*select, 4, testDateTime); - assertColumnValueHelper(*select, 5, testInterval); - rows += 1; - } - delete select; - BOOST_REQUIRE_EQUAL(1, rows); - ds->close(); -} - -BOOST_AUTO_TEST_CASE( bindAndSelectOther ) -{ - RdbmsDataSource * ds = CommonObjects::dataSource<RdbmsDataSource>("mysqlmock"); - auto ro = ds->getReadonly(); - - auto select = ro->newSelectCommand("SELECT * FROM test WHERE id != ?"); - select->bindParamI(0, testInt); - select->execute(); - int rows = 0; - while (select->fetch()) { - assertColumnValueHelper(*select, 0, 4); - assertColumnValueHelper(*select, 1, 123.45); - assertColumnValueHelper(*select, 2, std::string("some text")); - assertColumnValueHelper(*select, 3, true); - assertColumnValueHelper(*select, 4, boost::posix_time::ptime_from_tm({ 3, 6, 23, 27, 3, 115, 0, 0, 0, 0, 0})); - assertColumnValueHelper(*select, 5, boost::posix_time::time_duration(38, 13, 12)); - rows += 1; - } - delete select; - BOOST_REQUIRE_EQUAL(1, rows); - ds->close(); -} - -BOOST_AUTO_TEST_CASE( bulkload ) -{ - RdbmsDataSource * ds = CommonObjects::dataSource<RdbmsDataSource>("mysqlmock"); - auto ro = ds->getReadonly(); - - auto count = ro->newSelectCommand("SELECT COUNT(*) FROM bulktest"); - // Test empty - ro->beginBulkUpload("bulktest", ""); - ro->endBulkUpload(NULL); - assertColumnValueHelper(*count, 0); - // Test sample file - ro->beginBulkUpload("bulktest", ""); - std::ifstream in((RootDir / "bulk.sample").string()); - if (!in.good()) throw std::runtime_error("Couldn't open bulk.sample"); - char buf[BUFSIZ]; - for (std::streamsize r; (r = in.readsome(buf, sizeof(buf))) > 0; ) { - ro->bulkUploadData(buf, r); - } - ro->endBulkUpload(NULL); - assertColumnValueHelper(*count, 800); - - delete count; - ds->close(); -} - -BOOST_AUTO_TEST_CASE( bigIterate ) -{ - RdbmsDataSource * ds = CommonObjects::dataSource<RdbmsDataSource>("mysqlmock"); - auto ro = ds->getReadonly(); - - auto count = ro->newSelectCommand("SELECT * FROM bulktest"); - unsigned int rows = 0; - while (count->fetch()) { - rows += 1; - } - BOOST_REQUIRE_EQUAL(800, rows); - - delete count; - ds->close(); -} - -BOOST_AUTO_TEST_SUITE_END(); - diff --git a/project2/sql/unittests/testodbc.cpp b/project2/sql/unittests/testodbc.cpp deleted file mode 100644 index 60db6ce..0000000 --- a/project2/sql/unittests/testodbc.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#define BOOST_TEST_MODULE TestODBC -#include <boost/test/unit_test.hpp> - -#include <mockDatasource.h> -#include <definedDirs.h> -#include <modifycommand.h> -#include <selectcommand.h> -#include <column.h> -#include <sql-modODBC.h> -#include "testCore.h" -#include <sqlHandleAsVariableType.h> -#include <definedDirs.h> - -class StandardMockDatabase : public MockODBCDatabase { - public: - StandardMockDatabase() : MockODBCDatabase("Driver=postgresql;Database=postgres;uid=postgres;servername=/run/postgresql", "odbcmock", { - RootDir / "odbcschema.sql" }) - { - } -}; - -BOOST_GLOBAL_FIXTURE( StandardMockDatabase ); - -BOOST_FIXTURE_TEST_SUITE( Core, TestCore ); - -BOOST_AUTO_TEST_CASE( transactions ) -{ - RdbmsDataSource * ds = CommonObjects::dataSource<RdbmsDataSource>("odbcmock"); - auto ro = ds->getReadonly(); - - BOOST_REQUIRE_EQUAL(false, ro->inTx()); - ro->beginTx(); - BOOST_REQUIRE_EQUAL(true, ro->inTx()); - ro->rollbackTx(); - BOOST_REQUIRE_EQUAL(false, ro->inTx()); - - ro->beginTx(); - BOOST_REQUIRE_EQUAL(true, ro->inTx()); - ro->commitTx(); - BOOST_REQUIRE_EQUAL(false, ro->inTx()); - - ds->close(); -} - -BOOST_AUTO_TEST_CASE( bindAndSend ) -{ - RdbmsDataSource * ds = CommonObjects::dataSource<RdbmsDataSource>("odbcmock"); - auto rw = ds->getWritable(); - - auto mod = rw->newModifyCommand("INSERT INTO test VALUES(?, ?, ?, ?, ?)"); - mod->bindParamI(0, testInt); - mod->bindParamF(1, testDouble); - mod->bindParamS(2, testString); - mod->bindParamB(3, testBool); - mod->bindParamT(4, testDateTime); - mod->execute(); - delete mod; - ds->commit(); - ds->close(); -} - -template<typename T> -void -assertColumnValueHelper(DB::SelectCommand & sel, unsigned int col, const T & t) -{ - HandleAsVariableType h; - sel[col].apply(h); - BOOST_REQUIRE_EQUAL(t, h.variable.as<T>()); -} - -BOOST_AUTO_TEST_CASE( bindAndSelect ) -{ - RdbmsDataSource * ds = CommonObjects::dataSource<RdbmsDataSource>("odbcmock"); - auto ro = ds->getReadonly(); - - auto select = ro->newSelectCommand("SELECT * FROM test WHERE id = ?"); - select->bindParamI(0, testInt); - select->execute(); - int rows = 0; - while (select->fetch()) { - assertColumnValueHelper(*select, 0, testInt); - assertColumnValueHelper(*select, 1, testDouble); - assertColumnValueHelper(*select, 2, testString); - assertColumnValueHelper(*select, 3, testBool); - assertColumnValueHelper(*select, 4, testDateTime); - rows += 1; - } - delete select; - BOOST_REQUIRE_EQUAL(1, rows); - ds->close(); -} - -BOOST_AUTO_TEST_CASE( bindAndSelectOther ) -{ - RdbmsDataSource * ds = CommonObjects::dataSource<RdbmsDataSource>("odbcmock"); - auto ro = ds->getReadonly(); - - auto select = ro->newSelectCommand("SELECT * FROM test WHERE id != ?"); - select->bindParamI(0, testInt); - select->execute(); - int rows = 0; - while (select->fetch()) { - assertColumnValueHelper(*select, 0, 4); - assertColumnValueHelper(*select, 1, 123.45); - assertColumnValueHelper(*select, 2, std::string("some text")); - assertColumnValueHelper(*select, 3, true); - assertColumnValueHelper(*select, 4, boost::posix_time::ptime_from_tm({ 3, 6, 23, 27, 3, 115, 0, 0, 0, 0, 0})); - rows += 1; - } - delete select; - BOOST_REQUIRE_EQUAL(1, rows); - ds->close(); -} - -BOOST_AUTO_TEST_SUITE_END(); - diff --git a/project2/sql/unittests/testpq.cpp b/project2/sql/unittests/testpq.cpp deleted file mode 100644 index da38a34..0000000 --- a/project2/sql/unittests/testpq.cpp +++ /dev/null @@ -1,187 +0,0 @@ -#define BOOST_TEST_MODULE TestPQ -#include <boost/test/unit_test.hpp> - -#include <mockDatasource.h> -#include <definedDirs.h> -#include <modifycommand.h> -#include <selectcommand.h> -#include <column.h> -#include <sql-modPQ.h> -#include "testCore.h" -#include <sqlHandleAsVariableType.h> -#include <fstream> - -class StandardMockDatabase : public MockPqDatabase { - public: - StandardMockDatabase() : MockPqDatabase("user=postgres dbname=postgres", "pqmock", { - RootDir / "pqschema.sql" }) - { - } -}; - -BOOST_GLOBAL_FIXTURE( StandardMockDatabase ); - -BOOST_FIXTURE_TEST_SUITE( Core, TestCore ); - -BOOST_AUTO_TEST_CASE( transactions ) -{ - RdbmsDataSource * ds = CommonObjects::dataSource<RdbmsDataSource>("pqmock"); - auto ro = ds->getReadonly(); - - BOOST_REQUIRE_EQUAL(false, ro->inTx()); - ro->beginTx(); - BOOST_REQUIRE_EQUAL(true, ro->inTx()); - ro->rollbackTx(); - BOOST_REQUIRE_EQUAL(false, ro->inTx()); - - ro->beginTx(); - BOOST_REQUIRE_EQUAL(true, ro->inTx()); - ro->commitTx(); - BOOST_REQUIRE_EQUAL(false, ro->inTx()); - - ds->close(); -} - -BOOST_AUTO_TEST_CASE( bindAndSend ) -{ - RdbmsDataSource * ds = CommonObjects::dataSource<RdbmsDataSource>("pqmock"); - auto rw = ds->getWritable(); - - auto mod = rw->newModifyCommand("INSERT INTO test VALUES(?, ?, ?, ?, ?, ?)"); - mod->bindParamI(0, testInt); - mod->bindParamF(1, testDouble); - mod->bindParamS(2, testString); - mod->bindParamB(3, testBool); - mod->bindParamT(4, testDateTime); - mod->bindParamT(5, testInterval); - mod->execute(); - delete mod; - ds->commit(); - ds->close(); -} - -template<typename T> -void -assertColumnValueHelper(DB::SelectCommand & sel, const T & t) -{ - while (sel.fetch()) { - HandleAsVariableType h; - sel[0].apply(h); - BOOST_REQUIRE_EQUAL(t, h.variable.as<T>()); - } -} - -template<typename T> -void -assertColumnValueHelper(DB::SelectCommand & sel, unsigned int col, const T & t) -{ - HandleAsVariableType h; - sel[col].apply(h); - BOOST_REQUIRE_EQUAL(t, h.variable.as<T>()); -} - -BOOST_AUTO_TEST_CASE( bindAndSelect ) -{ - RdbmsDataSource * ds = CommonObjects::dataSource<RdbmsDataSource>("pqmock"); - auto ro = ds->getReadonly(); - - auto select = ro->newSelectCommand("SELECT * FROM test WHERE id = ?"); - select->bindParamI(0, testInt); - select->execute(); - int rows = 0; - while (select->fetch()) { - assertColumnValueHelper(*select, 0, testInt); - assertColumnValueHelper(*select, 1, testDouble); - assertColumnValueHelper(*select, 2, testString); - assertColumnValueHelper(*select, 3, testBool); - assertColumnValueHelper(*select, 4, testDateTime); - assertColumnValueHelper(*select, 5, testInterval); - rows += 1; - } - delete select; - BOOST_REQUIRE_EQUAL(1, rows); - ds->close(); -} - -BOOST_AUTO_TEST_CASE( bindAndSelectOther ) -{ - RdbmsDataSource * ds = CommonObjects::dataSource<RdbmsDataSource>("pqmock"); - auto ro = ds->getReadonly(); - - auto select = ro->newSelectCommand("SELECT * FROM test WHERE id != ?"); - select->bindParamI(0, testInt); - select->execute(); - int rows = 0; - while (select->fetch()) { - assertColumnValueHelper(*select, 0, 4); - assertColumnValueHelper(*select, 1, 123.45); - assertColumnValueHelper(*select, 2, std::string("some text with a ; in it and a ' too")); - assertColumnValueHelper(*select, 3, true); - assertColumnValueHelper(*select, 4, boost::posix_time::ptime_from_tm({ 3, 6, 23, 27, 3, 115, 0, 0, 0, 0, 0})); - assertColumnValueHelper(*select, 5, boost::posix_time::time_duration(38, 13, 12)); - rows += 1; - } - delete select; - BOOST_REQUIRE_EQUAL(1, rows); - ds->close(); -} - -BOOST_AUTO_TEST_CASE( testP2MockScriptDir ) -{ - RdbmsDataSource * ds = CommonObjects::dataSource<RdbmsDataSource>("pqmock"); - auto ro = ds->getReadonly(); - - auto select = ro->newSelectCommand("SELECT path FROM test2"); - select->execute(); - while (select->fetch()) { - HandleAsVariableType h; - (*select)[0].apply(h); - BOOST_REQUIRE(boost::filesystem::exists(h.variable.as<std::string>())); - } - delete select; - ds->close(); -} - -BOOST_AUTO_TEST_CASE( bulkload ) -{ - RdbmsDataSource * ds = CommonObjects::dataSource<RdbmsDataSource>("pqmock"); - auto ro = ds->getReadonly(); - - auto count = ro->newSelectCommand("SELECT COUNT(*) FROM bulktest"); - // Test empty - ro->beginBulkUpload("bulktest", ""); - ro->endBulkUpload(NULL); - assertColumnValueHelper(*count, 0); - // Test sample file - ro->beginBulkUpload("bulktest", ""); - std::ifstream in((RootDir / "bulk.sample").string()); - if (!in.good()) throw std::runtime_error("Couldn't open bulk.sample"); - char buf[BUFSIZ]; - for (std::streamsize r; (r = in.readsome(buf, sizeof(buf))) > 0; ) { - ro->bulkUploadData(buf, r); - } - ro->endBulkUpload(NULL); - assertColumnValueHelper(*count, 800); - - delete count; - ds->close(); -} - -BOOST_AUTO_TEST_CASE( bigIterate ) -{ - RdbmsDataSource * ds = CommonObjects::dataSource<RdbmsDataSource>("pqmock"); - auto ro = ds->getReadonly(); - - auto count = ro->newSelectCommand("SELECT * FROM bulktest"); - unsigned int rows = 0; - while (count->fetch()) { - rows += 1; - } - BOOST_REQUIRE_EQUAL(800, rows); - - delete count; - ds->close(); -} - -BOOST_AUTO_TEST_SUITE_END(); - diff --git a/project2/sql/unittests/testsqlite.cpp b/project2/sql/unittests/testsqlite.cpp deleted file mode 100644 index 89a1f77..0000000 --- a/project2/sql/unittests/testsqlite.cpp +++ /dev/null @@ -1,89 +0,0 @@ -#define BOOST_TEST_MODULE TestSQLite -#include <boost/test/unit_test.hpp> - -#include <mockDatasource.h> -#include <definedDirs.h> -#include <modifycommand.h> -#include <selectcommand.h> -#include <column.h> -#include <sql-modSQLite.h> -#include "testCore.h" -#include <sqlHandleAsVariableType.h> - -class StandardMockDatabase : public MockSQLiteDatabase { - public: - StandardMockDatabase() : MockSQLiteDatabase("sqlitemock", { - RootDir / "sqliteschema.sql" }) - { - } -}; - -BOOST_GLOBAL_FIXTURE( StandardMockDatabase ); - -BOOST_FIXTURE_TEST_SUITE( Core, TestCore ); - -BOOST_AUTO_TEST_CASE( transactions ) -{ - RdbmsDataSource * ds = CommonObjects::dataSource<RdbmsDataSource>("sqlitemock"); - auto ro = ds->getReadonly(); - - BOOST_REQUIRE_EQUAL(false, ro->inTx()); - ro->beginTx(); - BOOST_REQUIRE_EQUAL(true, ro->inTx()); - ro->rollbackTx(); - BOOST_REQUIRE_EQUAL(false, ro->inTx()); - - ro->beginTx(); - BOOST_REQUIRE_EQUAL(true, ro->inTx()); - ro->commitTx(); - BOOST_REQUIRE_EQUAL(false, ro->inTx()); - - ds->close(); -} - -BOOST_AUTO_TEST_CASE( bindAndSend ) -{ - RdbmsDataSource * ds = CommonObjects::dataSource<RdbmsDataSource>("sqlitemock"); - auto rw = ds->getWritable(); - - auto mod = rw->newModifyCommand("INSERT INTO test VALUES(?, ?, ?)"); - mod->bindParamI(0, testInt); - mod->bindParamF(1, testDouble); - mod->bindParamS(2, testString); - mod->execute(); - delete mod; - ds->commit(); - ds->close(); -} - -template<typename T> -void -assertColumnValueHelper(DB::SelectCommand & sel, unsigned int col, const T & t) -{ - HandleAsVariableType h; - sel[col].apply(h); - BOOST_REQUIRE_EQUAL(t, h.variable.as<T>()); -} - -BOOST_AUTO_TEST_CASE( bindAndSelect ) -{ - RdbmsDataSource * ds = CommonObjects::dataSource<RdbmsDataSource>("sqlitemock"); - auto ro = ds->getReadonly(); - - auto select = ro->newSelectCommand("SELECT * FROM test WHERE id = ?"); - select->bindParamI(0, testInt); - select->execute(); - int rows = 0; - while (select->fetch()) { - assertColumnValueHelper(*select, 0, testInt); - assertColumnValueHelper(*select, 1, testDouble); - assertColumnValueHelper(*select, 2, testString); - rows += 1; - } - delete select; - BOOST_REQUIRE_EQUAL(1, rows); - ds->close(); -} - -BOOST_AUTO_TEST_SUITE_END(); - diff --git a/project2/streams/Jamfile.jam b/project2/streams/Jamfile.jam index 530fac1..1941f55 100644 --- a/project2/streams/Jamfile.jam +++ b/project2/streams/Jamfile.jam @@ -6,9 +6,8 @@ alias glibmm : : : : lib p2streams : [ glob *.cpp ] : - <include>../../libmisc <library>glibmm <library>../common//p2common - <library>../lib//p2lib + <library>..//adhocutil ; diff --git a/project2/streams/streamNvpRows.cpp b/project2/streams/streamNvpRows.cpp index 8bc5b87..a4c4b7b 100644 --- a/project2/streams/streamNvpRows.cpp +++ b/project2/streams/streamNvpRows.cpp @@ -1,6 +1,5 @@ #include <pch.hpp> #include "variables.h" -#include "scopeObject.h" #include "stream.h" #include "definedColumns.h" #include "rowProcessor.h" @@ -51,7 +50,7 @@ class StreamNvpRows : public RowSet { ~ParseState() { - if (!std::uncaught_exception()) { + if (!std::uncaught_exceptions()) { newRecord(tok.length()); } } @@ -108,7 +107,7 @@ class StreamNvpRows : public RowSet { } bool newField(size_t start) { - columns.insert(new Column(columns.size(), + columns.insert(std::make_shared<Column>(columns.size(), boost::algorithm::trim_copy_if(tok.substr(0, start), g_unichar_isspace))); fields.push_back(Null()); inValue = true; @@ -149,6 +148,7 @@ class StreamNvpRows : public RowSet { }; StreamNvpRows(ScriptNodePtr p) : + SourceObject(p), RowSet(p), fieldSep(p->value("fieldSep", ",", NULL).as<Glib::ustring>()), quoteChar(p->value("quoteChar", "\"", NULL).as<Glib::ustring>()), @@ -158,7 +158,7 @@ class StreamNvpRows : public RowSet { assign(p->value("assign", "=", NULL).as<Glib::ustring>()), encoding(p->value("encoding", "utf-8", NULL).as<std::string>()) { - p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&stream)); + p->script.lock()->loader.addLoadTarget(p, Storer::into<StreamFactory>(&stream)); } void execute(const Glib::ustring &, const RowProcessorCallback & rp, ExecContext * ec) const @@ -179,5 +179,5 @@ class StreamNvpRows : public RowSet { const Glib::ustring assign; const std::string encoding; }; -DECLARE_LOADER("streamnvprows", StreamNvpRows); +NAMEDFACTORY("streamnvprows", StreamNvpRows, RowSetFactory); diff --git a/project2/streams/streamPresenter.cpp b/project2/streams/streamPresenter.cpp index 229799c..7b2129b 100644 --- a/project2/streams/streamPresenter.cpp +++ b/project2/streams/streamPresenter.cpp @@ -8,7 +8,7 @@ class StreamPresenter : public Presenter, public SourceOf<WritableContent> { StreamPresenter(ScriptNodePtr e, ObjectSource os, ExecContext * ) : Presenter(os) { - e->script->loader.addLoadTarget(e, Storer::into<ElementLoader>(&stream)); + e->script.lock()->loader.addLoadTarget(e, Storer::into<StreamFactory>(&stream)); } void addNewArray(const Glib::ustring&, bool) const @@ -44,4 +44,5 @@ class StreamPresenter : public Presenter, public SourceOf<WritableContent> { StreamPtr stream; }; -DECLARE_GENERIC_LOADER("stream", PresenterLoader, StreamPresenter) +NAMEDFACTORY("stream", StreamPresenter, PresenterFactory); + diff --git a/project2/streams/streamRows.cpp b/project2/streams/streamRows.cpp index 1b9063f..1bea9ad 100644 --- a/project2/streams/streamRows.cpp +++ b/project2/streams/streamRows.cpp @@ -1,6 +1,5 @@ #include <pch.hpp> #include "variables.h" -#include "scopeObject.h" #include "stream.h" #include "definedColumns.h" #include "rowProcessor.h" @@ -28,7 +27,7 @@ class StreamRows : public DefinedColumns, public RowSet { ~ParseState() { - if (!std::uncaught_exception()) { + if (!std::uncaught_exceptions()) { sr->end(*this); } } @@ -46,6 +45,7 @@ class StreamRows : public DefinedColumns, public RowSet { }; StreamRows(ScriptNodePtr p) : + SourceObject(p), DefinedColumns(p, "columns", boost::bind(&Column::make, _1, _2)), RowSet(p), fieldSep(p->value("fieldSep", ",", NULL).as<Glib::ustring>()[0]), @@ -56,7 +56,7 @@ class StreamRows : public DefinedColumns, public RowSet { encoding(p->value("encoding", "utf-8", NULL).as<std::string>()), skipheader(p->value("skipheader", 0, NULL).as<int64_t>()) { - p->script->loader.addLoadTarget(p, Storer::into<ElementLoader>(&stream)); + p->script.lock()->loader.addLoadTarget(p, Storer::into<StreamFactory>(&stream)); } void execute(const Glib::ustring &, const RowProcessorCallback & rp, ExecContext * ec) const @@ -144,5 +144,5 @@ class StreamRows : public DefinedColumns, public RowSet { const std::string encoding; const size_t skipheader; }; -DECLARE_LOADER("streamrows", StreamRows); +NAMEDFACTORY("streamrows", StreamRows, RowSetFactory); diff --git a/project2/streams/textReader.h b/project2/streams/textReader.h index b101272..98386c1 100644 --- a/project2/streams/textReader.h +++ b/project2/streams/textReader.h @@ -3,8 +3,9 @@ #include <boost/function.hpp> #include <glib.h> +#include <visibility.h> -class TextReader { +class DLL_PUBLIC TextReader { public: typedef boost::function<void(gunichar)> CharSink; diff --git a/project2/streams/viewStream.cpp b/project2/streams/viewStream.cpp index 29917f6..37b3f00 100644 --- a/project2/streams/viewStream.cpp +++ b/project2/streams/viewStream.cpp @@ -1,10 +1,11 @@ #include "scriptLoader.h" #include "stream.h" -#include <scopeObject.h> +#include <scopeExit.h> #include "ostreamWrapper.h" #include "viewHost.h" #include <boost/iostreams/stream.hpp> #include <boost/iostreams/concepts.hpp> +#include <scripts.h> class SinkStream : public boost::iostreams::sink { public: @@ -27,17 +28,17 @@ class ViewStream : public Stream, public ViewHost { Stream(p), ViewHost(p) { - p->script->loader.addLoadTarget(p, Storer::into<PresenterLoader>(&presenter, Scripted, (ExecContext*)NULL)); + p->script.lock()->loader.addLoadTarget(p, Storer::into<PresenterFactory>(&presenter, Scripted, (ExecContext*)NULL)); } void runStream(const Stream::Sink & s, ExecContext * ec) const { - TransformSourcePtr t = boost::dynamic_pointer_cast<TransformSource>(getPresenter(ec)); + TransformSourcePtr t = std::dynamic_pointer_cast<TransformSource>(getPresenter(ec)); if (t) { boost::iostreams::stream<SinkStream> strm(s); - ostreamWrapper * o = new ostreamWrapper(strm); + auto o = std::make_shared<ostreamWrapper>(strm); executeViews(ec); t->addTarget(o, ec, NULL); - ScopeObject remove([&t] { t->clearTargets(); }); + AdHoc::ScopeExit remove([&t] { t->clearTargets(); }); doTransforms(ec); } } @@ -49,4 +50,5 @@ class ViewStream : public Stream, public ViewHost { MultiRowSetPresenterPtr presenter; }; -DECLARE_LOADER("viewstream", ViewStream); +NAMEDFACTORY("viewstream", ViewStream, StreamFactory); + diff --git a/project2/url/Jamfile.jam b/project2/url/Jamfile.jam index b35eb03..aa55a78 100644 --- a/project2/url/Jamfile.jam +++ b/project2/url/Jamfile.jam @@ -6,11 +6,9 @@ lib curl : : <name>curl ; lib p2url : [ glob *.cpp ] - ../../libmisc/curlsup.cpp : <library>../common//p2common - <library>../lib//p2lib - <include>../../libmisc + <library>..//adhocutil <library>glibmm <library>curl : : diff --git a/project2/url/curlHelper.cpp b/project2/url/curlHelper.cpp index 2988be9..3add479 100644 --- a/project2/url/curlHelper.cpp +++ b/project2/url/curlHelper.cpp @@ -26,80 +26,43 @@ CurlHelper::~CurlHelper() { } -size_t -Curl::curlReadHelperHandle(const char * ptr, size_t size, size_t nmemb, void *stream) -{ - return (*static_cast<const Curl::ReadHandler *>(stream))(ptr, size * nmemb); -} - -size_t -Curl::curlSendHelperHandle(char * ptr, size_t size, size_t nmemb, void *stream) -{ - return (*static_cast<const Curl::SendHandler *>(stream))(ptr, size * nmemb); -} - -CurlPtr +AdHoc::Net::CurlHandlePtr CurlHelper::newCurl(ExecContext * ec) const { - CurlPtr c = new Curl(); - c->setopt(CURLOPT_FOLLOWLOCATION, 1); - c->setopt(CURLOPT_ENCODING, "deflate, gzip"); - c->setopt(CURLOPT_URL, getUrl(ec).c_str()); - c->setopt(CURLOPT_FAILONERROR, 1); - return c; -} - -CurlPtr -VariableCurlHelper::newCurl(ExecContext * ec) const -{ - CurlPtr c = CurlHelper::newCurl(ec); - setopt_s(c, CURLOPT_USERAGENT, userAgent(ec)); - setopt_s(c, CURLOPT_PROXY, proxy(ec)); - setopt_s(c, CURLOPT_REFERER, referer(ec)); - setopt_s(c, CURLOPT_COOKIEFILE, cookieJar(ec)); - setopt_s(c, CURLOPT_COOKIEJAR, cookieJar(ec)); - setopt_l(c, CURLOPT_TIMEOUT_MS, timeout(ec)); + AdHoc::Net::CurlHandlePtr c = std::make_shared<AdHoc::Net::CurlHandle>(getUrl(ec)); + setCurlOpts(c.get(), ec); return c; } void -Curl::performRead(const ReadHandler & h) -{ - setReadHandler(h); - CurlHandle::perform(); -} - -void -Curl::setReadHandler(const ReadHandler & h) -{ - setopt(CURLOPT_WRITEDATA, &h); - setopt(CURLOPT_WRITEFUNCTION, &curlReadHelperHandle); -} - -void -Curl::performSend(const SendHandler & h) +CurlHelper::setCurlOpts(AdHoc::Net::CurlHandle * c, ExecContext *) const { - setSendHandler(h); - CurlHandle::perform(); -} - -void -Curl::setSendHandler(const SendHandler & h) -{ - setopt(CURLOPT_READDATA, &h); - setopt(CURLOPT_READFUNCTION, &curlSendHelperHandle); + c->setopt(CURLOPT_FOLLOWLOCATION, 1); + c->setopt(CURLOPT_ENCODING, "deflate, gzip"); + c->setopt(CURLOPT_FAILONERROR, 1); } void -VariableCurlHelper::setopt_s(CurlPtr c, CURLoption o, const char * v) +VariableCurlHelper::setCurlOpts(AdHoc::Net::CurlHandle * c, ExecContext * ec) const { - c->setopt(o, v); + CurlHelper::setCurlOpts(c, ec); + setCurlOptCached(c, CURLOPT_USERAGENT, userAgent, ec); + setCurlOptCached(c, CURLOPT_PROXY, proxy, ec); + setCurlOptCached(c, CURLOPT_REFERER, referer, ec); + setCurlOptCached(c, CURLOPT_COOKIEFILE, cookieJar, ec); + setCurlOptCached(c, CURLOPT_COOKIEJAR, cookieJar, ec); + c->setopt<long>(CURLOPT_TIMEOUT_MS, timeout(ec)); } void -VariableCurlHelper::setopt_l(CurlPtr c, CURLoption o, int64_t v) +VariableCurlHelper::setCurlOptCached(AdHoc::Net::CurlHandle * c, CURLoption opt, const Variable & v, ExecContext * ec) const { - c->setopt(o, (long)v); + if (v(ec).isNull()) { + c->setopt(opt, nullptr); + } + else { + c->setopt(opt, valueCache.insert(ValueCache::value_type(opt, v(ec))).first->second.c_str()); + } } std::string diff --git a/project2/url/curlHelper.h b/project2/url/curlHelper.h index 76ac48f..66e7643 100644 --- a/project2/url/curlHelper.h +++ b/project2/url/curlHelper.h @@ -2,40 +2,24 @@ #define CURLHELPER_H #include "variables.h" -#include <curlsup.h> - -class Curl : public CurlHandle { - public: - virtual ~Curl() { } - - typedef boost::function2<size_t, const char *, size_t> ReadHandler; - typedef boost::function2<size_t, char *, size_t> SendHandler; - - void performRead(const ReadHandler &); - void setReadHandler(const ReadHandler &); - void performSend(const SendHandler &); - void setSendHandler(const SendHandler &); - - private: - static size_t curlReadHelperHandle(const char * ptr, size_t size, size_t nmemb, void *stream); - static size_t curlSendHelperHandle(char * ptr, size_t size, size_t nmemb, void *stream); -}; -typedef boost::intrusive_ptr<Curl> CurlPtr; +#include <curlHandle.h> +#include <visibility.h> /// Project2 helper component to provide common access to remote resources via libcurl -class CurlHelper { +class DLL_PUBLIC CurlHelper { public: CurlHelper(); virtual ~CurlHelper(); - virtual CurlPtr newCurl(ExecContext *) const; + AdHoc::Net::CurlHandlePtr newCurl(ExecContext *) const; + virtual void setCurlOpts(AdHoc::Net::CurlHandle *, ExecContext *) const; protected: virtual std::string getUrl(ExecContext *) const = 0; }; /// Project2 helper component to configure CurlHelper from variables -class VariableCurlHelper : public CurlHelper { +class DLL_PUBLIC VariableCurlHelper : public CurlHelper { public: VariableCurlHelper(ScriptNodePtr p); ~VariableCurlHelper(); @@ -43,13 +27,11 @@ class VariableCurlHelper : public CurlHelper { const Variable url; protected: - virtual CurlPtr newCurl(ExecContext *) const; - virtual std::string getUrl(ExecContext *) const; + virtual void setCurlOpts(AdHoc::Net::CurlHandle *, ExecContext *) const override; + void setCurlOptCached(AdHoc::Net::CurlHandle *, CURLoption, const Variable &, ExecContext * ec) const; + virtual std::string getUrl(ExecContext *) const override; private: - static void setopt_s(CurlPtr, CURLoption, const char *); - static void setopt_l(CurlPtr, CURLoption, int64_t); - const Variable userAgent; const Variable cookieJar; const Variable proxy; @@ -58,6 +40,8 @@ class VariableCurlHelper : public CurlHelper { const Variable userName; const Variable password; const Variable timeout; + typedef std::map<CURLoption, std::string> ValueCache; + mutable ValueCache valueCache; }; #endif diff --git a/project2/url/downloadToFile.cpp b/project2/url/downloadToFile.cpp index 2f6726e..0c91f91 100644 --- a/project2/url/downloadToFile.cpp +++ b/project2/url/downloadToFile.cpp @@ -1,9 +1,8 @@ #include "curlHelper.h" #include "task.h" -#include <scopeObject.h> +#include <scopeExit.h> #include "scriptLoader.h" #include "exceptions.h" -#include "../libmisc/curlsup.h" /// Project2 component to create a row set from the contents of a file accessible via libcurl class Download : public Task, VariableCurlHelper { @@ -15,16 +14,18 @@ class Download : public Task, VariableCurlHelper { destination(p, "destination") { } - + void execute(ExecContext * ec) const { - CurlPtr c = newCurl(ec); - FILE * file = fopen(destination(ec), "w"); + FILE * file = fopen(destination(ec).as<std::string>().c_str(), "w"); if (!file) { throw syscall_error(errno); } - ScopeObject tidy([=]{ fclose(file); }); - c->performRead([=](const char * data, size_t len) -> size_t { return fwrite(data, 1, len, file); }); + AdHoc::ScopeExit tidy([=]{ fclose(file); }); + auto c = newCurl(ec); + c->setopt(CURLOPT_READDATA, file); + c->setopt(CURLOPT_READFUNCTION, &fwrite); + c->perform(); } private: @@ -32,5 +33,5 @@ class Download : public Task, VariableCurlHelper { const Variable destination; }; -DECLARE_LOADER("download", Download); +NAMEDFACTORY("download", Download, TaskFactory); diff --git a/project2/url/urlStream.cpp b/project2/url/urlStream.cpp index d9fa336..1c681c7 100644 --- a/project2/url/urlStream.cpp +++ b/project2/url/urlStream.cpp @@ -2,7 +2,6 @@ #include "stream.h" #include "scriptLoader.h" #include "scripts.h" -#include "../libmisc/curlsup.h" /// Project2 component to create a row set from the contents of a file accessible via libcurl class UrlStream : public Stream, VariableCurlHelper { @@ -15,10 +14,19 @@ class UrlStream : public Stream, VariableCurlHelper { void runStream(const Sink & sink, ExecContext * ec) const { - CurlPtr c = newCurl(ec); - c->performRead(sink); + auto c = newCurl(ec); + c->setopt(CURLOPT_READDATA, &sink); + c->setopt(CURLOPT_READFUNCTION, &readToSink); + c->perform(); + } + + static size_t readToSink(const void *ptr, size_t size, size_t nmemb, void * sink) + { + auto s = static_cast<const Sink *>(sink); + auto d = static_cast<const char *>(ptr); + return (*s)(d, size * nmemb); } }; -DECLARE_LOADER("urlstream", UrlStream); +NAMEDFACTORY("urlstream", UrlStream, StreamFactory); diff --git a/project2/ut/Jamfile.jam b/project2/ut/Jamfile.jam index 335294f..982f9ea 100644 --- a/project2/ut/Jamfile.jam +++ b/project2/ut/Jamfile.jam @@ -1,5 +1,5 @@ lib boost_utf : : <name>boost_unit_test_framework ; -lib boost_fs : : <name>boost_filesystem ; +lib boost_fs : : <name>stdc++fs ; lib p2ut : [ glob *.cpp ] diff --git a/project2/ut/butf_logger.cpp b/project2/ut/butf_logger.cpp index c5f45b4..42afd41 100644 --- a/project2/ut/butf_logger.cpp +++ b/project2/ut/butf_logger.cpp @@ -1,6 +1,6 @@ #include <boost/test/unit_test_log.hpp> -#include "logger.h" -#include "options.h" +#include <loggerFactory.impl.h> +#include <options.h> /// Logger that writes Boost Unit Test Framework messages class BoostUTFLogDriver : public LogDriverBase { @@ -17,5 +17,5 @@ class BoostUTFLogDriver : public LogDriverBase { int BoostUTFLogDriver::level = LOG_DEBUG; -DECLARE_LOGGER_LOADER("boostutf", BoostUTFLogDriver); +DECLARE_LOGGER("boostutf", BoostUTFLogDriver); diff --git a/project2/ut/definedDirs.h b/project2/ut/definedDirs.h deleted file mode 100644 index cbed012..0000000 --- a/project2/ut/definedDirs.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef P2_UT_DEFINEDDIRS -#define P2_UT_DEFINEDDIRS - -#include <boost/filesystem/path.hpp> -#include <boost/filesystem/convenience.hpp> - -#ifndef ROOT -#error "ROOT needs to be defined at compilation time" -#endif - -#define XSTR(s) STR(s) -#define STR(s) #s -const auto BinDir = boost::filesystem::canonical("/proc/self/exe").parent_path(); -const boost::filesystem::path RootDir(XSTR(ROOT)); - -#endif - diff --git a/project2/ut/testAppInstance.cpp b/project2/ut/testAppInstance.cpp index 21e9c38..8e3f852 100644 --- a/project2/ut/testAppInstance.cpp +++ b/project2/ut/testAppInstance.cpp @@ -1,4 +1,12 @@ #include "testAppInstance.h" +#include <boost/test/unit_test_suite.hpp> + +TestAppInstance::TestAppInstance() : + args(boost::unit_test::framework::master_test_suite().argv, + boost::unit_test::framework::master_test_suite().argv + + boost::unit_test::framework::master_test_suite().argc) +{ +} VariableType TestAppInstance::getParameter(const VariableType &) const diff --git a/project2/ut/testAppInstance.h b/project2/ut/testAppInstance.h index aa52227..81eecd6 100644 --- a/project2/ut/testAppInstance.h +++ b/project2/ut/testAppInstance.h @@ -3,11 +3,16 @@ #include <appInstance.h> #include <execContext.h> +#include <visibility.h> -class TestAppInstance : public AppInstance, public ExecContext { +class DLL_PUBLIC TestAppInstance : public AppInstance, public ExecContext { public: + TestAppInstance(); + VariableType getParameter(const VariableType & key) const override; SessionPtr getSession() const override; + + const std::vector<std::string> args; }; #endif diff --git a/project2/ut/testOptionsSource.h b/project2/ut/testOptionsSource.h index 3d0e046..c293a4b 100644 --- a/project2/ut/testOptionsSource.h +++ b/project2/ut/testOptionsSource.h @@ -2,8 +2,9 @@ #define P2_TEST_OPTIONSSOURCE_H #include <optionsSource.h> +#include <visibility.h> -class TestOptionsSource : public OptionsSource { +class DLL_PUBLIC TestOptionsSource : public OptionsSource { public: typedef std::list<std::pair<std::string, std::string>> Opts; diff --git a/project2/ut/testPresenter.cpp b/project2/ut/testPresenter.cpp index 2b9c952..eb9ed59 100644 --- a/project2/ut/testPresenter.cpp +++ b/project2/ut/testPresenter.cpp @@ -1,6 +1,6 @@ #include "testPresenter.h" -#include "misc.h" -#include <boost/filesystem/operations.hpp> +#include <buffer.h> +#include <filesystem> #include <boost/test/test_tools.hpp> #include <fstream> #include <boost/format.hpp> @@ -115,10 +115,10 @@ namespace std { } bool - operator==(const PresenterData & left, const boost::filesystem::path & rightPath) + operator==(const PresenterData & left, const std::filesystem::path & rightPath) { PresenterData right; - BOOST_REQUIRE(boost::filesystem::exists(rightPath)); + BOOST_REQUIRE(std::filesystem::exists(rightPath)); fstream strm(rightPath.string()); strm >> right; return (left == right); diff --git a/project2/ut/testPresenter.h b/project2/ut/testPresenter.h index 74e5e0d..027b7d0 100644 --- a/project2/ut/testPresenter.h +++ b/project2/ut/testPresenter.h @@ -3,12 +3,13 @@ #include <string> #include <vector> -#include <boost/filesystem/path.hpp> +#include <filesystem> #include <presenter.h> +#include <visibility.h> typedef std::vector<std::string> PresenterData; -class TestPresenter : public Presenter { +class DLL_PUBLIC TestPresenter : public Presenter { public: TestPresenter(); @@ -32,9 +33,9 @@ class TestPresenter : public Presenter { }; namespace std { - bool operator==(const PresenterData &, const boost::filesystem::path &); - std::ostream & operator<<(std::ostream & s, const PresenterData & v); - std::istream & operator>>(std::istream & s, PresenterData & v); + DLL_PUBLIC bool operator==(const PresenterData &, const std::filesystem::path &); + DLL_PUBLIC std::ostream & operator<<(std::ostream & s, const PresenterData & v); + DLL_PUBLIC std::istream & operator>>(std::istream & s, PresenterData & v); } #endif diff --git a/project2/ut/testScriptHost.cpp b/project2/ut/testScriptHost.cpp index c3090ff..2df7fbe 100644 --- a/project2/ut/testScriptHost.cpp +++ b/project2/ut/testScriptHost.cpp @@ -11,7 +11,7 @@ TestScriptHost::TestScriptHost(ScriptReaderPtr script) : ViewHost(script->root()) { Logger()->message(LOG_DEBUG, __PRETTY_FUNCTION__); - script->loader.addLoadTarget(script->root(), Storer::into<PresenterLoader>(&presenter, Scripted, (ExecContext*)NULL)); + script->loader.addLoadTarget(script->root(), Storer::into<PresenterFactory>(&presenter, Scripted, (ExecContext*)NULL)); } TestScriptHost::~TestScriptHost() @@ -22,7 +22,7 @@ TestScriptHost::~TestScriptHost() MultiRowSetPresenterPtr TestScriptHost::getPresenter(ExecContext *) const { if (!presenter) { - presenter = new TestPresenter(); + presenter = std::make_shared<TestPresenter>(); } return presenter; } @@ -37,7 +37,7 @@ void TestScriptHost::process(ExecContext * ec) const PresenterData & TestScriptHost::GetPresenterData() const { - auto tp = boost::dynamic_pointer_cast<TestPresenter>(presenter); + auto tp = std::dynamic_pointer_cast<TestPresenter>(presenter); if (!tp) { throw std::runtime_error("Not using the TestPresenter"); } diff --git a/project2/ut/testScriptHost.h b/project2/ut/testScriptHost.h index c838f9c..816d54c 100644 --- a/project2/ut/testScriptHost.h +++ b/project2/ut/testScriptHost.h @@ -4,8 +4,9 @@ #include <taskHost.h> #include <viewHost.h> #include "testPresenter.h" +#include <visibility.h> -class TestScriptHost : public TaskHost, public ViewHost { +class DLL_PUBLIC TestScriptHost : public TaskHost, public ViewHost { public: TestScriptHost(ScriptReaderPtr script); ~TestScriptHost(); diff --git a/project2/ut/testScriptNode.cpp b/project2/ut/testScriptNode.cpp index fb54c12..8c24f71 100644 --- a/project2/ut/testScriptNode.cpp +++ b/project2/ut/testScriptNode.cpp @@ -59,20 +59,19 @@ bool TestScriptNode::applyValue(const Glib::ustring & name, VariableType & targe return false; } -VariableImpl * TestScriptNode::variable(const boost::optional<Glib::ustring> & defaultSource) const +std::shared_ptr<VariableImpl> TestScriptNode::variable(const boost::optional<Glib::ustring> & defaultSource) const { Logger()->messagebf(LOG_DEBUG, "%s: defaultSource = %s", __PRETTY_FUNCTION__, defaultSource ? *defaultSource : "NULL"); - (void)defaultSource; return NULL; } -VariableImpl * TestScriptNode::variable(const Glib::ustring & name) const +std::shared_ptr<VariableImpl> TestScriptNode::variable(const Glib::ustring & name) const { Logger()->messagebf(LOG_DEBUG, "%s: %s", __PRETTY_FUNCTION__, name); auto i = vars.find(name.collate_key()); if (i != vars.end()) { - return new VariableLiteral(i->second); + return std::make_shared<VariableLiteral>(i->second); } throw ValueNotFound(name); } diff --git a/project2/ut/testScriptNode.h b/project2/ut/testScriptNode.h index d85f6db..1425c14 100644 --- a/project2/ut/testScriptNode.h +++ b/project2/ut/testScriptNode.h @@ -2,8 +2,9 @@ #define TESTSCRIPTNODE_H #include <scripts.h> +#include <visibility.h> -class TestScriptNode : public ScriptNode { +class DLL_PUBLIC TestScriptNode : public ScriptNode { public: typedef std::map<std::string, VariableType> Vars; @@ -16,8 +17,8 @@ class TestScriptNode : public ScriptNode { ScriptNodes childrenIn(const Glib::ustring & sub) const; bool valueExists(const Glib::ustring & name) const; bool applyValue(const Glib::ustring & name, VariableType & target, ExecContext *) const; - VariableImpl * variable(const boost::optional<Glib::ustring> & defaultSource = boost::optional<Glib::ustring>()) const; - VariableImpl * variable(const Glib::ustring & name) const; + std::shared_ptr<VariableImpl> variable(const boost::optional<Glib::ustring> & defaultSource = boost::optional<Glib::ustring>()) const; + std::shared_ptr<VariableImpl> variable(const Glib::ustring & name) const; void composeWithCallbacks(const LiteralCallback &, const NodeCallback &) const; private: diff --git a/project2/xml/Jamfile.jam b/project2/xml/Jamfile.jam index 4a69457..021f6df 100644 --- a/project2/xml/Jamfile.jam +++ b/project2/xml/Jamfile.jam @@ -1,15 +1,12 @@ -alias libxmlpp : : : : - <cflags>"`pkg-config --cflags libxml++-2.6`" - <linkflags>"`pkg-config --libs libxml++-2.6`" ; alias libxslt : : : : <cflags>"`pkg-config --cflags libexslt`" <linkflags>"`pkg-config --libs libexslt`" ; -lib boost_filesystem : : <name>boost_filesystem ; +lib stdc++fs ; lib boost_date_time : : <name>boost_date_time ; +lib Ice : : <name>Ice++11 ; cpp-pch pch : pch.hpp : - <include>../../libmisc - <library>libxmlpp + <library>../..//libxmlpp <library>../common//p2common ; lib p2xml : @@ -17,13 +14,13 @@ lib p2xml : [ glob-tree *.cpp : unittests ] : <include>. - <include>../libmisc - <library>libxmlpp + <library>../..//libxmlpp <library>../common//p2common <library>../url//p2url - <library>../lib//p2lib + <library>..//adhocutil + <library>Ice <library>libxslt - <library>boost_filesystem + <library>stdc++fs <library>boost_date_time : : <include>. diff --git a/project2/xml/mutators/copy.cpp b/project2/xml/mutators/copy.cpp index f58bef7..a40eaf6 100644 --- a/project2/xml/mutators/copy.cpp +++ b/project2/xml/mutators/copy.cpp @@ -17,7 +17,7 @@ class Copy : public XmlDocMutator { for (xmlpp::Node * t : e->find(to(NULL))) { t->import_node(e); if (delAfter(NULL)) { - e->get_parent()->remove_child(e); + e->get_parent()->remove_node(e); } } } @@ -27,5 +27,5 @@ class Copy : public XmlDocMutator { Variable delAfter; }; -DECLARE_GENERIC_LOADER("copy", XmlDocMutatorLoader, Copy); +NAMEDFACTORY("copy", Copy, XmlDocMutatorFactory); diff --git a/project2/xml/mutators/copyToAttr.cpp b/project2/xml/mutators/copyToAttr.cpp index a58ac93..a82920b 100644 --- a/project2/xml/mutators/copyToAttr.cpp +++ b/project2/xml/mutators/copyToAttr.cpp @@ -17,9 +17,9 @@ class CopyToAttr : public XmlDocMutator { if (xmlpp::Element * ee = dynamic_cast<xmlpp::Element *>(e)) { for (xmlpp::Node * t : e->find(to(NULL))) { if (xmlpp::Element * te = dynamic_cast<xmlpp::Element *>(t)) { - te->set_attribute(e->get_name(), ee->get_child_text()->get_content()); + te->set_attribute(e->get_name(), ee->get_first_child_text()->get_content()); if (delAfter(NULL)) { - e->get_parent()->remove_child(e); + e->get_parent()->remove_node(e); } } } @@ -31,6 +31,5 @@ class CopyToAttr : public XmlDocMutator { Variable delAfter; }; -DECLARE_GENERIC_LOADER("copytoattr", XmlDocMutatorLoader, CopyToAttr); - +NAMEDFACTORY("copytoattr", CopyToAttr, XmlDocMutatorFactory); diff --git a/project2/xml/mutators/create.cpp b/project2/xml/mutators/create.cpp index 88d8808..6bb7940 100644 --- a/project2/xml/mutators/create.cpp +++ b/project2/xml/mutators/create.cpp @@ -12,12 +12,14 @@ class Create : public XmlDocMutator { } void mutateElement(xmlpp::Element * root) const { - for (xmlpp::Node * e : root->find(xpath(NULL))) { - e->add_child(name(NULL)); + for (xmlpp::Node * n : root->find(xpath(NULL))) { + if (auto e = dynamic_cast<xmlpp::Element *>(n)) + e->add_child_element(name(NULL)); } } Variable xpath; Variable name; }; -DECLARE_GENERIC_LOADER("create", XmlDocMutatorLoader, Create); +NAMEDFACTORY("create", Create, XmlDocMutatorFactory); + diff --git a/project2/xml/mutators/delete.cpp b/project2/xml/mutators/delete.cpp index 6e4d597..d14b0ee 100644 --- a/project2/xml/mutators/delete.cpp +++ b/project2/xml/mutators/delete.cpp @@ -11,13 +11,12 @@ class Delete : public XmlDocMutator { } void mutateElement(xmlpp::Element * root) const { - for (xmlpp::Node * e : root->find(xpath(NULL))) { - e->get_parent()->remove_child(e); + for (xmlpp::Node * n : root->find(xpath(NULL))) { + n->get_parent()->remove_node(n); } } Variable xpath; }; -DECLARE_GENERIC_LOADER("delete", XmlDocMutatorLoader, Delete); - +NAMEDFACTORY("delete", Delete, XmlDocMutatorFactory); diff --git a/project2/xml/mutators/rename.cpp b/project2/xml/mutators/rename.cpp index ec347d8..ed1a5ca 100644 --- a/project2/xml/mutators/rename.cpp +++ b/project2/xml/mutators/rename.cpp @@ -20,7 +20,5 @@ class Rename : public XmlDocMutator { Variable newname; }; -DECLARE_GENERIC_LOADER("rename", XmlDocMutatorLoader, Rename); - - +NAMEDFACTORY("rename", Rename, XmlDocMutatorFactory); diff --git a/project2/xml/pch.hpp b/project2/xml/pch.hpp index 1eb8309..210a49c 100644 --- a/project2/xml/pch.hpp +++ b/project2/xml/pch.hpp @@ -2,16 +2,8 @@ #ifndef XML_PCH #define XML_PCH -#include "cache.h" -#include "exceptions.h" -#include "iHaveParameters.h" -#include "logger.h" -#include "presenter.h" -#include "rowProcessor.h" -#include "safeMapFind.h" -#include "variables.h" -#include <boost/filesystem/path.hpp> -#include "options.h" +#include <filesystem> +#include <boost/variant/variant_fwd.hpp> #include <libxml++/document.h> #include <libxml++/nodes/element.h> #include <libxml++/nodes/textnode.h> diff --git a/project2/xml/rawView.cpp b/project2/xml/rawView.cpp index 4f013f9..7219e8a 100644 --- a/project2/xml/rawView.cpp +++ b/project2/xml/rawView.cpp @@ -1,6 +1,5 @@ #include <pch.hpp> #include "exceptions.h" -#include "xml.h" #include "presenter.h" #include "scriptLoader.h" #include "xmlDocumentCache.h" @@ -36,14 +35,14 @@ class RawViewBase : public View { p->setNamespace(n->get_namespace_prefix(), n->get_namespace_uri()); } p->pushSub(n->get_name(), n->get_namespace_prefix()); - xmlpp::Element::AttributeList al = n->get_attributes(); + auto al = n->get_attributes(); for (const xmlpp::Attribute * a : al) { if (!a->get_namespace_uri().empty()) { p->setNamespace(a->get_namespace_prefix(), a->get_namespace_uri()); } p->addAttribute(a->get_name(), a->get_namespace_prefix(), a->get_value()); } - const xmlpp::Node::NodeList ch = n->get_children(); + auto ch = n->get_children(); for (const xmlpp::Node * c : ch) { if (const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(c)) { copyNode(p, e); @@ -61,7 +60,7 @@ class RawView : public RawViewBase { RawView(ScriptNodePtr p) : SourceObject(p), RawViewBase(p), - copyRoot(boost::dynamic_pointer_cast<const XmlScriptNode>(p)->xmlElement()) + copyRoot(std::dynamic_pointer_cast<const XmlScriptNode>(p)->xmlElement()) { } protected: @@ -69,28 +68,27 @@ class RawView : public RawViewBase { private: const xmlpp::Element * copyRoot; }; -DECLARE_LOADER("rawview", RawView); +NAMEDFACTORY("rawview", RawView, ViewFactory); -class XmlResourceView : public RawViewBase, XmlDocumentCache, VariableCurlHelper { +class XmlResourceView : public RawViewBase, XmlDocumentCache { public: XmlResourceView(ScriptNodePtr p) : SourceObject(p), RawViewBase(p), - VariableCurlHelper(p), + XmlDocumentCache(p), encoding(p, "encoding", Null()) { } protected: const xmlpp::Element * getCopyRoot(ExecContext * ec) const { - return getDocument(url(ec), encoding(ec), ec)->get_root_node(); + return getDocument(url(ec), encoding(ec), false, false, ec)->get_root_node(); } bool asHtml(ExecContext *) const { return false; } bool withWarnings(ExecContext *) const { return true; } - CurlPtr newCurl(ExecContext * ec) const { return VariableCurlHelper::newCurl(ec); } private: Variable encoding; }; -DECLARE_LOADER("xmlresourceview", XmlResourceView); +NAMEDFACTORY("xmlresourceview", XmlResourceView, ViewFactory); diff --git a/project2/xml/sessionXml.cpp b/project2/xml/sessionXml.cpp index 866d5b2..bd60bf6 100644 --- a/project2/xml/sessionXml.cpp +++ b/project2/xml/sessionXml.cpp @@ -5,24 +5,24 @@ #include <libxml++/nodes/element.h> #include <libxml++/parsers/domparser.h> #include <boost/bind.hpp> -#include <boost/filesystem/convenience.hpp> +#include <filesystem> #include <boost/lexical_cast.hpp> #include "options.h" #include "logger.h" -class CustomSessionContainerLoaderXml : public SessionContainerLoader::For<SessionContainerXml> { +class CustomSessionContainerFactoryXml : public SessionContainerFactory::For<SessionContainerXml>, public LifeCycle { public: void onPeriodic() override { try { - if (boost::filesystem::is_directory(SessionContainerXml::xmlDir)) { - boost::filesystem::directory_iterator end; - for (boost::filesystem::directory_iterator p(SessionContainerXml::xmlDir); p != end; ++p) { + if (std::filesystem::is_directory(SessionContainerXml::xmlDir)) { + std::filesystem::directory_iterator end; + for (std::filesystem::directory_iterator p(SessionContainerXml::xmlDir); p != end; ++p) { xmlpp::DomParser session(p->path().string()); xmlpp::Element * sess = session.get_document()->get_root_node(); time_t expires = boost::lexical_cast<time_t>(sess->get_attribute_value("expires")); if (expires < time(NULL)) { - boost::filesystem::remove(*p); + std::filesystem::remove(*p); } } } @@ -37,8 +37,8 @@ DECLARE_OPTIONS(SessionContainerXml, "Session XML options") "Path of the folder in which to store XML files for session information") END_OPTIONS(SessionContainerXml) -boost::filesystem::path SessionContainerXml::xmlDir; -DECLARE_CUSTOM_COMPONENT_LOADER("xml", SessionContainerXml, CustomSessionContainerLoaderXml, SessionContainerLoader); +std::filesystem::path SessionContainerXml::xmlDir; +NAMEDPLUGIN("xml", CustomSessionContainerFactoryXml, SessionContainerFactory); SessionContainerXml::SessionContainerXml() { @@ -52,7 +52,7 @@ static void appendToXmlNode(xmlpp::Element * sess, const Glib::ustring & name, const VariableType & value) { - xmlpp::Element * v = sess->add_child(name); + xmlpp::Element * v = sess->add_child_element(name); v->add_child_text(value); } @@ -63,8 +63,8 @@ SessionContainerXml::SaveSession(SessionPtr currentSession) const xmlpp::Element * sess = d.create_root_node("session"); sess->set_attribute("expires", boost::lexical_cast<Glib::ustring>(currentSession->ExpiryTime())); currentSession->ForeachValue(boost::bind(appendToXmlNode, sess, _1, _2)); - boost::filesystem::create_directories(SessionContainerXml::xmlDir); - boost::filesystem::path p = xmlDir / boost::lexical_cast<std::string>(currentSession->ID()); + std::filesystem::create_directories(SessionContainerXml::xmlDir); + std::filesystem::path p = xmlDir / boost::lexical_cast<std::string>(currentSession->ID()); d.write_to_file(p.string()); } @@ -72,19 +72,19 @@ SessionPtr SessionContainerXml::getSession(const boost::uuids::uuid & sid) const { try { - boost::filesystem::path p = xmlDir / boost::lexical_cast<std::string>(sid); + std::filesystem::path p = xmlDir / boost::lexical_cast<std::string>(sid); xmlpp::DomParser session(p.string()); xmlpp::Element * sess = session.get_document()->get_root_node(); time_t expires = boost::lexical_cast<time_t>(sess->get_attribute_value("expires")); if (expires < time(NULL)) { - boost::filesystem::remove(p); + std::filesystem::remove(p); return NULL; } - SessionPtr s = new Session(sid); + SessionPtr s = std::make_shared<Session>(sid); for (const xmlpp::Node * n : sess->get_children()) { if (const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(n)) { - if (e->get_child_text()) { - s->SetValue(e->get_name(), e->get_child_text()->get_content()); + if (e->get_first_child_text()) { + s->SetValue(e->get_name(), e->get_first_child_text()->get_content()); } else { s->SetValue(e->get_name(), Null()); diff --git a/project2/xml/sessionXml.h b/project2/xml/sessionXml.h index 4288d9e..4a03e37 100644 --- a/project2/xml/sessionXml.h +++ b/project2/xml/sessionXml.h @@ -3,9 +3,9 @@ #include "sessionContainer.h" #include "options.h" -#include <boost/filesystem/path.hpp> +#include <filesystem> -class SessionContainerXml : public SessionContainer { +class DLL_PUBLIC SessionContainerXml : public SessionContainer { public: SessionContainerXml(); ~SessionContainerXml(); @@ -17,8 +17,8 @@ class SessionContainerXml : public SessionContainer { private: // Configurables - static boost::filesystem::path xmlDir; - friend class CustomSessionContainerLoaderXml; + static std::filesystem::path xmlDir; + friend class CustomSessionContainerFactoryXml; }; #endif diff --git a/project2/xml/transformHtml.cpp b/project2/xml/transformHtml.cpp index 6d1e925..c8ab246 100644 --- a/project2/xml/transformHtml.cpp +++ b/project2/xml/transformHtml.cpp @@ -82,21 +82,20 @@ class TransformXmlToHtml : public TransformImpl<xmlpp::Document, HtmlDocument> { } }; -class XmlTransformLoader : public TransformLoader::For<TransformXmlToHtml> { - public: - XmlTransformLoader() - { - xmlInitParser(); - exsltRegisterAll(); - } +static void initLibXml() __attribute__((constructor(102))); +void initLibXml() +{ + xmlInitParser(); + exsltRegisterAll(); +} - ~XmlTransformLoader() - { - xsltCleanupGlobals(); - xmlCleanupParser(); - } -}; +static void cleanupLibXml() __attribute__((destructor(102))); +void cleanupLibXml() +{ + xsltCleanupGlobals(); + xmlCleanupParser(); +} -DECLARE_CUSTOM_COMPONENT_LOADER("TransformXmlToHtml", TransformXmlToHtml, XmlTransformLoader, TransformLoader) -DECLARE_TRANSFORMTARGET("htmldocument", HtmlDocument) +NAMEDFACTORY("TransformXmlToHtml", TransformXmlToHtml, TransformFactory); +NAMEDFACTORY("htmldocument", HtmlDocument, TransformTargetFactory); diff --git a/project2/xml/transformHtml.h b/project2/xml/transformHtml.h index b8fa82e..0cb3b93 100644 --- a/project2/xml/transformHtml.h +++ b/project2/xml/transformHtml.h @@ -3,8 +3,9 @@ #include "transform.h" #include <libxml/HTMLtree.h> +#include <visibility.h> -class HtmlDocument : public SourceOf<HtmlDocument>, public WritableContent, public SourceOf<WritableContent> { +class DLL_PUBLIC HtmlDocument : public SourceOf<HtmlDocument>, public WritableContent, public SourceOf<WritableContent> { public: HtmlDocument(ScriptNodePtr, ObjectSource); ~HtmlDocument(); diff --git a/project2/xml/transformText.cpp b/project2/xml/transformText.cpp index edf8a8b..525b910 100644 --- a/project2/xml/transformText.cpp +++ b/project2/xml/transformText.cpp @@ -5,7 +5,7 @@ #include <libxml++/document.h> #include "transformHtml.h" #include <sys/wait.h> -#include <misc.h> +#include <processPipes.h> #include <glibmm/convert.h> TextDocument::TextDocument(ScriptNodePtr s, ObjectSource os) : @@ -46,7 +46,6 @@ class TransformHtmlToText : public TransformImpl<HtmlDocument, TextDocument> { { xmlDoc * doc = const_cast<xmlDoc *>(cdoc->doc); str->doc.clear(); - int fds[2]; std::vector<std::string> callLynx; callLynx.push_back("/usr/bin/lynx"); callLynx.push_back("-dump"); @@ -57,20 +56,18 @@ class TransformHtmlToText : public TransformImpl<HtmlDocument, TextDocument> { callLynx.push_back("-nonumbers"); callLynx.push_back("-nolist"); } - popenrw(callLynx, fds); - FILE * lynxIn = fdopen(fds[0], "w"); + AdHoc::System::ProcessPipes fds(callLynx, true, true, false); + FILE * lynxIn = fdopen(fds.fdIn(), "w"); // Fixed encoding as we want the result to go back into a ustring htmlNodeDumpFileFormat(lynxIn, doc, xmlDocGetRootElement(doc), "utf-8", 0); fclose(lynxIn); - close(fds[0]); char buf[1024]; int r; - while ((r = read(fds[1], buf, sizeof(buf))) > 0) { + while ((r = read(fds.fdOut(), buf, sizeof(buf))) > 0) { str->doc.append(std::string(buf, r)); } - close(fds[1]); int status; - wait(&status); + waitpid(fds.pid(), &status, 0); if (status != 0) { throw std::runtime_error("Lynx failed"); } @@ -99,6 +96,6 @@ END_OPTIONS(TransformHtmlToText) int TransformHtmlToText::defaultWidth; bool TransformHtmlToText::defaultLinks; -DECLARE_COMPONENT_LOADER("TransformHtmlToText", TransformHtmlToText, TransformLoader); -DECLARE_TRANSFORMTARGET("textdocument", TextDocument) +NAMEDFACTORY("TransformHtmlToText", TransformHtmlToText, TransformFactory); +NAMEDFACTORY("textdocument", TextDocument, TransformTargetFactory) diff --git a/project2/xml/transformText.h b/project2/xml/transformText.h index 57e19f9..bba45f0 100644 --- a/project2/xml/transformText.h +++ b/project2/xml/transformText.h @@ -4,8 +4,9 @@ #include "transform.h" #include <glibmm/ustring.h> #include <variables.h> +#include <visibility.h> -class TextDocument : public SourceOf<TextDocument>, public WritableContent, public SourceOf<WritableContent> { +class DLL_PUBLIC TextDocument : public SourceOf<TextDocument>, public WritableContent, public SourceOf<WritableContent> { public: TextDocument(ScriptNodePtr, ObjectSource); Glib::ustring doc; diff --git a/project2/xml/unittests/Jamfile.jam b/project2/xml/unittests/Jamfile.jam index f520c04..b2e0652 100644 --- a/project2/xml/unittests/Jamfile.jam +++ b/project2/xml/unittests/Jamfile.jam @@ -1,7 +1,6 @@ import testing ; -lib boost_system ; -lib boost_filesystem ; +lib stdc++fs ; path-constant me : . ; @@ -13,6 +12,6 @@ run <define>ROOT=\"$(me)\" <library>..//p2xml <library>../../ut//p2ut - <library>boost_filesystem + <library>stdc++fs : testxml ; diff --git a/project2/xml/unittests/testxml.cpp b/project2/xml/unittests/testxml.cpp index 143f501..fe2911d 100644 --- a/project2/xml/unittests/testxml.cpp +++ b/project2/xml/unittests/testxml.cpp @@ -16,21 +16,21 @@ systembf(const char * fmt, const T & ... params) return system(stringbf(fmt, params...).c_str()); } -const boost::filesystem::path tmpdir = "/tmp/ut/project2.xml"; +const std::filesystem::path tmpdir = "/tmp/ut/project2.xml"; BOOST_AUTO_TEST_CASE( before ) { - boost::filesystem::remove_all(tmpdir); - boost::filesystem::create_directories(tmpdir); + std::filesystem::remove_all(tmpdir); + std::filesystem::create_directories(tmpdir); } BOOST_AUTO_TEST_CASE( rawview ) { TestOptionsSource::LoadTestOptions({ }); - ScriptReaderPtr s = new XmlScriptParser(RootDir / "rawview.xml"); - boost::intrusive_ptr<TestScriptHost> h = new TestScriptHost(s); + ScriptReaderPtr s = std::make_shared<XmlScriptParser>(rootDir / "rawview.xml"); + std::shared_ptr<TestScriptHost> h = std::make_shared<TestScriptHost>(s); h->executeViews(NULL); - auto p = boost::dynamic_pointer_cast<XmlPresenter>(h->getPresenter(NULL)); + auto p = std::dynamic_pointer_cast<XmlPresenter>(h->getPresenter(NULL)); BOOST_REQUIRE(p); const auto out = tmpdir / "rawview.xml"; std::fstream strm(out.string(), std::ios::out); @@ -38,12 +38,12 @@ BOOST_AUTO_TEST_CASE( rawview ) p->writeTo(strm, "utf-8", NULL); BOOST_REQUIRE_EQUAL(0, systembf("diff -w --unified %s %s", out, - RootDir / "expected" / "rawview.xml")); - boost::filesystem::remove_all(tmpdir); + rootDir / "expected" / "rawview.xml")); + std::filesystem::remove_all(tmpdir); } BOOST_AUTO_TEST_CASE( after ) { - boost::filesystem::remove_all(tmpdir); + std::filesystem::remove_all(tmpdir); } diff --git a/project2/xml/xmlCache.cpp b/project2/xml/xmlCache.cpp index 52e693a..b33824a 100644 --- a/project2/xml/xmlCache.cpp +++ b/project2/xml/xmlCache.cpp @@ -7,42 +7,42 @@ #include "xmlPresenter.h" #include <sys/stat.h> #include "options.h" -#include <boost/filesystem/path.hpp> -#include <boost/filesystem/convenience.hpp> +#include <filesystem> #include <libxml++/document.h> class XmlCache : public RowSetCache { public: XmlCache(ScriptNodePtr p) : + SourceObject(p), RowSetCache(p) { } RowSetCPtr getCachedRowSet(ExecContext * ec, const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) const { - boost::filesystem::path cache = getCacheFile(ec, n, f, ps); + std::filesystem::path cache = getCacheFile(ec, n, f, ps); struct stat st; if (stat(cache.string().c_str(), &st) == 0) { if (st.st_mtime < time(NULL) - CacheLife) { - boost::filesystem::remove(cache); + std::filesystem::remove(cache); return NULL; } - return new XmlRawRows(cache.string()); + return std::make_shared<XmlRawRows>(cache.string()); } return NULL; } RowSetPresenterPtr openFor(ExecContext *, const Glib::ustring & n, const Glib::ustring &, const IHaveParameters *) { - writeTo = new XmlPresenter(n, Scripts::scriptNamespace, Scripts::scriptNamespacePrefix); + writeTo = std::make_shared<XmlPresenter>(n, Scripts::scriptNamespace, Scripts::scriptNamespacePrefix); return writeTo; } void save(ExecContext * ec, const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) { - boost::filesystem::path target = getCacheFile(ec, n, f, ps); + std::filesystem::path target = getCacheFile(ec, n, f, ps); try { - boost::filesystem::create_directories(target.parent_path()); + std::filesystem::create_directories(target.parent_path()); const xmlpp::Document * d = *writeTo; const_cast<xmlpp::Document *>(d)->write_to_file(target.string()); writeTo.reset(); @@ -58,15 +58,15 @@ class XmlCache : public RowSetCache { INITOPTIONS; private: - boost::filesystem::path getCacheFile(ExecContext * ec, const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) const + std::filesystem::path getCacheFile(ExecContext * ec, const Glib::ustring & n, const Glib::ustring & f, const IHaveParameters * ps) const { - boost::filesystem::path cache = Store / n.raw() / f.raw(); + std::filesystem::path cache = Store / n.raw() / f.raw(); applyKeys(ec, boost::bind(&appendPath, &cache, _1, _2), ps); cache /= FileName; return cache; } - static void appendPath(boost::filesystem::path * cache, const std::string & n, const VariableType & v) + static void appendPath(std::filesystem::path * cache, const std::string & n, const VariableType & v) { *cache /= n; *cache /= v.operator const std::string &(); @@ -74,22 +74,22 @@ class XmlCache : public RowSetCache { XmlPresenterPtr writeTo; - friend class CustomXmlCacheLoader; - static boost::filesystem::path Store; + friend class CustomXmlCacheFactory; + static std::filesystem::path Store; static std::string FileName; static time_t CacheLife; }; -boost::filesystem::path XmlCache::Store; +std::filesystem::path XmlCache::Store; std::string XmlCache::FileName; time_t XmlCache::CacheLife; -class CustomXmlCacheLoader : public ElementLoader::For<XmlCache> { +class CustomXmlCacheFactory : public AdHoc::Factory<RowSetCache, std::shared_ptr<const ScriptNode>>::For<XmlCache>, public LifeCycle { public: void onIdle() override { try { - if (boost::filesystem::is_directory(XmlCache::Store)) { + if (std::filesystem::is_directory(XmlCache::Store)) { emptyDir(XmlCache::Store); } } @@ -98,11 +98,11 @@ class CustomXmlCacheLoader : public ElementLoader::For<XmlCache> { } } - bool emptyDir(const boost::filesystem::path & dir) + bool emptyDir(const std::filesystem::path & dir) { bool files = false; - boost::filesystem::directory_iterator end; - for (boost::filesystem::directory_iterator itr(dir); itr != end; ++itr) { + std::filesystem::directory_iterator end; + for (std::filesystem::directory_iterator itr(dir); itr != end; ++itr) { struct stat st; stat(itr->path().string().c_str(), &st); if (S_ISDIR(st.st_mode)) { @@ -110,7 +110,7 @@ class CustomXmlCacheLoader : public ElementLoader::For<XmlCache> { files = true; } else { - boost::filesystem::remove(*itr); + std::filesystem::remove(*itr); } } else { @@ -118,14 +118,14 @@ class CustomXmlCacheLoader : public ElementLoader::For<XmlCache> { files = true; } else { - boost::filesystem::remove(*itr); + std::filesystem::remove(*itr); } } } return files; } }; -DECLARE_CUSTOM_LOADER("xmlcache", CustomXmlCacheLoader); +NAMEDPLUGIN("xmlcache", CustomXmlCacheFactory, RowSetCacheFactory); DECLARE_OPTIONS(XmlCache, "XML Cache options") ("cache.xml.store", Options::value(&XmlCache::Store, "/tmp/project2.cache"), diff --git a/project2/xml/xmlDocumentCache.cpp b/project2/xml/xmlDocumentCache.cpp index b0d850d..f981a24 100644 --- a/project2/xml/xmlDocumentCache.cpp +++ b/project2/xml/xmlDocumentCache.cpp @@ -5,13 +5,14 @@ #include <logger.h> #include <libxml/HTMLparser.h> #include <boost/bind.hpp> +#include <net.h> #include "exceptions.h" #include "curlHelper.h" #include "safeMapFind.h" XmlDocumentCache::Documents XmlDocumentCache::documents; XmlDocumentCache::Queued XmlDocumentCache::queued; -CurlBulkFetcher XmlDocumentCache::cbf; +AdHoc::Net::CurlMultiHandle XmlDocumentCache::cbf; SimpleMessageException(XmlParseError); SimpleMessageException(DownloadFailed); @@ -20,92 +21,94 @@ template <class Exception> static XmlDocumentCache::DocumentPtr helperThrow(const std::string & msg) { throw Exception(msg); } -static XmlDocumentCache::DocumentPtr helperReturnDocument(XmlDocumentCache::DocumentPtr dp) { - return dp; +static XmlDocumentCache::DocumentPtr helperReturnDom(XmlDocumentCache::DomParserPtr dp) { + return dp->get_document(); +} +static XmlDocumentCache::DocumentPtr helperReturnDocument(boost::shared_ptr<xmlpp::Document> dp) { + return dp.get(); } -class XmlDocumentCachePopulator : public CurlCompleteCallback { - public: - XmlDocumentCachePopulator(CurlPtr ch, const Glib::ustring & u, bool h, bool w, const char * e) : - CurlCompleteCallback(ch), - handler(boost::bind(&XmlDocumentCachePopulator::append, this, _1, _2)), - url(u), - html(h), - warnings(w), - encoding(e ? strdup(e) : NULL) - { - ch->setReadHandler(handler); - } - ~XmlDocumentCachePopulator() - { - free(encoding); - } - void call(CurlBulkFetcher *) - { - int flags = 0; - flags |= warnings ? 0 : XML_PARSE_NOWARNING | XML_PARSE_NOERROR; - xmlDocPtr doc = html ? - htmlReadMemory(buf.c_str(), buf.length(), url.c_str(), encoding, flags) : - xmlReadMemory(buf.c_str(), buf.length(), url.c_str(), encoding, flags); - if (!doc) { - Logger()->messagebf(LOG_DEBUG, "Download of '%s' succeeded, but parsing failed with error '%s'", url, xmlGetLastError()->message); - XmlDocumentCache::documents.insert(XmlDocumentCache::Documents::value_type(url, - boost::bind(helperThrow<XmlParseError>, std::string(xmlGetLastError()->message)))); - return; - } - - // Dirty hack alert - // xmlpp doesn't play nicely with HTML documents... - // sooo ummm, lie and hope it doesn't break something else - doc->type = XML_DOCUMENT_NODE; - // end hack - - XmlDocumentCache::documents.insert(XmlDocumentCache::Documents::value_type(url, - boost::bind(helperReturnDocument, XmlDocumentCache::DocumentPtr(new xmlpp::Document(doc))))); - Logger()->messagebf(LOG_DEBUG, "Download of '%s' completed, stored", url); - } - void error(CurlBulkFetcher *, const char * error) - { - Logger()->messagebf(LOG_DEBUG, "Download of '%s' failed with error '%s'", url, error); - XmlDocumentCache::documents.insert(XmlDocumentCache::Documents::value_type(url, - boost::bind(helperThrow<DownloadFailed>, std::string(error)))); - } - size_t append(const char * c, size_t b) - { - buf.append(c, b); - return b; - } - - Curl::ReadHandler handler; - std::string buf; - const Glib::ustring url; - const bool html; - const bool warnings; - char * encoding; -}; +XmlDocumentCache::XmlDocumentCache(ScriptNodePtr n) : + VariableCurlHelper(n) +{ +} XmlDocumentCache::DocumentPtr -XmlDocumentCache::getDocument(const Glib::ustring & url, const char * encoding, ExecContext * ec) const +XmlDocumentCache::getDocument(const Glib::ustring & url, boost::optional<std::string> encoding, bool html, bool warnings, ExecContext * ec) const { Documents::const_iterator i = documents.find(url); if (i == documents.end()) { - queue(url, encoding, ec); - cbf.perform(); + queue(url, encoding, html, warnings, ec); + cbf.performAll(); queued.clear(); } - return safeMapLookup<DownloadFailed>(documents, url)(); + return AdHoc::safeMapLookup<DownloadFailed>(documents, url)(); +} + +int +xmlReadFunc(void * context, char * buffer, int len) +{ + try { + std::istream * strm = static_cast<std::istream *>(context); + strm->read(buffer, len); + return strm->gcount(); + } + catch (const AdHoc::Net::CurlException & error) { + return -1; + } +} + +int +xmlCloseFunc(void *) +{ + return 0; } void -XmlDocumentCache::queue(const Glib::ustring & url, const char * encoding, ExecContext * ec) const +XmlDocumentCache::queue(const Glib::ustring & url, boost::optional<std::string> encoding, bool html, bool warnings, ExecContext * ec) const { if (queued.find(url) == queued.end()) { - cbf.curls.insert(new XmlDocumentCachePopulator(newCurl(ec), url, asHtml(ec), withWarnings(ec), encoding)); + auto curl = cbf.addCurl(url, [url, encoding, html, warnings](std::istream & strm) { + if (html) { + int flags = warnings ? 0 : XML_PARSE_NOWARNING | XML_PARSE_NOERROR; + htmlDocPtr doc = htmlReadIO(xmlReadFunc, xmlCloseFunc, &strm, url.c_str(), + encoding ? encoding->c_str() : nullptr, flags); + if (!doc) { + Logger()->messagebf(LOG_DEBUG, "Download of '%s' failed with error '%s'", url, xmlGetLastError()->message); + XmlDocumentCache::documents.insert(XmlDocumentCache::Documents::value_type(url, + boost::bind(helperThrow<XmlParseError>, std::string(xmlGetLastError()->message)))); + return; + } + + // Dirty hack alert + // xmlpp doesn't play nicely with HTML documents... + // sooo ummm, lie and hope it doesn't break something else + doc->type = XML_DOCUMENT_NODE; + // end hack + + XmlDocumentCache::documents.insert(XmlDocumentCache::Documents::value_type(url, + boost::bind(helperReturnDocument, boost::shared_ptr<xmlpp::Document>(new xmlpp::Document(doc))))); + } + else { + try { + DomParserPtr doc = DomParserPtr(new xmlpp::DomParser()); + doc->parse_stream(strm); + XmlDocumentCache::documents.insert(XmlDocumentCache::Documents::value_type(url, + boost::bind(helperReturnDom, doc))); + } + catch (const AdHoc::Net::CurlException & error) { + Logger()->messagebf(LOG_DEBUG, "Download of '%s' failed with error '%s'", url, error.message); + XmlDocumentCache::documents.insert(XmlDocumentCache::Documents::value_type(url, + boost::bind(helperThrow<DownloadFailed>, error.message))); + } + } + }); + setCurlOpts(curl.get(), ec); queued.insert(url); } } -class XmlDocumentCacheClearer : public ComponentLoader { +class XmlDocumentCacheClearer : public LifeCycle { public: typedef bool KeyType; @@ -116,5 +119,5 @@ class XmlDocumentCacheClearer : public ComponentLoader { Logger()->messagef(LOG_DEBUG, "%s: Cleared XML document cache", __PRETTY_FUNCTION__); } }; -DECLARE_COMPONENT("XmlDocumentCacheClearer", XmlDocumentCacheClearer); +NAMEDPLUGIN("XmlDocumentCacheClearer", XmlDocumentCacheClearer, LifeCycle); diff --git a/project2/xml/xmlDocumentCache.h b/project2/xml/xmlDocumentCache.h index a7b7454..97fdb6d 100644 --- a/project2/xml/xmlDocumentCache.h +++ b/project2/xml/xmlDocumentCache.h @@ -2,34 +2,40 @@ #define XMLDOCUMENTROWSCACHE_H #include <boost/shared_ptr.hpp> +#include <boost/optional.hpp> #include <map> #include <set> #include <curlHelper.h> #include <glibmm/ustring.h> #include <libxml++/document.h> +#include <libxml++/parsers/domparser.h> +#include <curlMultiHandle.h> +#include <curlHelper.h> -class XmlDocumentCache { +class DLL_PUBLIC XmlDocumentCache : protected VariableCurlHelper { public: typedef std::set<Glib::ustring> Queued; - typedef boost::shared_ptr<xmlpp::Document> DocumentPtr; + typedef xmlpp::Document * DocumentPtr; + typedef boost::shared_ptr<xmlpp::DomParser> DomParserPtr; typedef boost::function0<DocumentPtr> ReturnDocument; typedef std::map<const Glib::ustring, ReturnDocument> Documents; protected: + XmlDocumentCache(ScriptNodePtr); + static Queued queued; static Documents documents; - void queue(const Glib::ustring & url, const char * encoding, ExecContext *) const; - - virtual CurlPtr newCurl(ExecContext *) const = 0; + void queue(const Glib::ustring & url, boost::optional<std::string> encoding, bool html, bool warnings, ExecContext *) const; + virtual bool asHtml(ExecContext * ec) const = 0; virtual bool withWarnings(ExecContext * ec) const = 0; protected: - DocumentPtr getDocument(const Glib::ustring & url, const char * encoding, ExecContext * ec) const; + DocumentPtr getDocument(const Glib::ustring & url, boost::optional<std::string> encoding, bool html, bool warnings, ExecContext * ec) const; private: - static CurlBulkFetcher cbf; + static AdHoc::Net::CurlMultiHandle cbf; friend class XmlDocumentCachePopulator; friend class XmlDocumentCacheClearer; diff --git a/project2/xml/xmlDocumentPrefetch.cpp b/project2/xml/xmlDocumentPrefetch.cpp index 4af0055..769709f 100644 --- a/project2/xml/xmlDocumentPrefetch.cpp +++ b/project2/xml/xmlDocumentPrefetch.cpp @@ -2,13 +2,14 @@ #include "xmlDocumentPrefetch.h" #include "scriptLoader.h" -DECLARE_LOADER("xmldocumentprefetch", XmlDocumentPrefetch); +NAMEDFACTORY("xmldocumentprefetch", XmlDocumentPrefetch, ViewFactory); +NAMEDFACTORY("xmldocumentprefetch", XmlDocumentPrefetch, TaskFactory); XmlDocumentPrefetch::XmlDocumentPrefetch(ScriptNodePtr p) : SourceObject(p), View(p), Task(p), - VariableCurlHelper(p), + XmlDocumentCache(p), html(p, "html", false), warnings(p, "warnings", true), encoding(p, "encoding", Null()) @@ -28,13 +29,7 @@ XmlDocumentPrefetch::execute(const MultiRowSetPresenter*, ExecContext * ec) cons void XmlDocumentPrefetch::execute(ExecContext * ec) const { - queue(url(ec), encoding(ec), ec); -} - -CurlPtr -XmlDocumentPrefetch::newCurl(ExecContext * ec) const -{ - return VariableCurlHelper::newCurl(ec); + queue(url(ec), encoding(ec), asHtml(ec), warnings(ec), ec); } bool diff --git a/project2/xml/xmlDocumentPrefetch.h b/project2/xml/xmlDocumentPrefetch.h index fd9285d..7dd428f 100644 --- a/project2/xml/xmlDocumentPrefetch.h +++ b/project2/xml/xmlDocumentPrefetch.h @@ -8,7 +8,7 @@ #include <libxml++/nodes/element.h> /// Project2 component to queue up CURL objects to be downloaded -class XmlDocumentPrefetch : public View, public Task, XmlDocumentCache, VariableCurlHelper { +class DLL_PUBLIC XmlDocumentPrefetch : public View, public Task, XmlDocumentCache { public: XmlDocumentPrefetch(ScriptNodePtr p); ~XmlDocumentPrefetch(); @@ -20,7 +20,6 @@ class XmlDocumentPrefetch : public View, public Task, XmlDocumentCache, Variable const Variable warnings; const Variable encoding; - CurlPtr newCurl(ExecContext *) const; bool asHtml(ExecContext * ec) const; bool withWarnings(ExecContext * ec) const; }; diff --git a/project2/xml/xmlPresenter.cpp b/project2/xml/xmlPresenter.cpp index a43f9f8..249d2a8 100644 --- a/project2/xml/xmlPresenter.cpp +++ b/project2/xml/xmlPresenter.cpp @@ -7,7 +7,7 @@ #include <libxml++/document.h> #include <boost/date_time/posix_time/time_formatters.hpp> #include <boost/date_time/gregorian/formatters.hpp> -#include "instanceStore.impl.h" +#include <factory.impl.h> DECLARE_OPTIONS(XmlPresenter, "XML Presenter options") ("presenter.xml.typeid.null", Options::value(&typeidNull, false), @@ -43,7 +43,7 @@ bool XmlPresenter::dateAttr; bool XmlPresenter::timeAttr; boost::optional<std::string> XmlPresenter::customFormat; -DECLARE_GENERIC_LOADER("xml", PresenterLoader, XmlPresenter) +NAMEDFACTORY("xml", XmlPresenter, PresenterFactory) XmlPresenter::XmlPresenter(const Glib::ustring & responseRootNodeName, const Glib::ustring & responseStyle, const Glib::ustring & ct) : Presenter(Default), @@ -67,7 +67,7 @@ XmlPresenter::XmlPresenter(ScriptNodePtr e, ObjectSource os, ExecContext * ec) : style(e, "style", Null()) { if (os == Scripted) { - e->script->loader.addLoadTarget(e, Storer::into<XmlDocMutatorLoader>(&mutators)); + e->script.lock()->loader.addLoadTarget(e, Storer::into<XmlDocMutatorFactory>(&mutators)); } } @@ -85,7 +85,7 @@ XmlPresenter::init(ExecContext * ec) // XSLT Style char * buf; if (!style(ec).isNull() && asprintf(&buf, "type=\"text/xsl\" href=\"%s\"", - style(ec).as<const char *>()) > 0) { + style(ec).as<std::string>().c_str()) > 0) { xmlAddPrevSibling(nodeStack.back()->cobj(), xmlNewDocPI(responseDoc->cobj(), BAD_CAST "xml-stylesheet", BAD_CAST buf)); free(buf); @@ -127,7 +127,7 @@ XmlPresenter::setNamespace(const Glib::ustring & prefix, const Glib::ustring & n void XmlPresenter::pushSub(const Glib::ustring & name, const Glib::ustring & ns) const { - nodeStack.push_back(nodeStack.back()->add_child(name, ns)); + nodeStack.push_back(nodeStack.back()->add_child_element(name, ns)); } void @@ -198,10 +198,8 @@ class XmlNodeWriter : public boost::static_visitor<bool> { } if (!dateFormat.isNull()) { std::stringstream ss; - boost::date_time::time_facet<boost::posix_time::ptime, char> * ft = new boost::date_time::time_facet<boost::posix_time::ptime, char>(); - ss.imbue(std::locale(ss.getloc(), ft)); - ft->format(dateFormat); - ss << boost::get<boost::posix_time::ptime>(i); + boost::posix_time::time_facet ft(dateFormat.as<std::string>().c_str()); + ft.put(ss, ss, ' ', i); node->set_attribute("custom", ss.str()); } return true; @@ -236,7 +234,7 @@ void XmlPresenter::addNewArray(const Glib::ustring & name, bool objects) const { if (!objects) { - nodeStack.push_back(nodeStack.back()->add_child(name)); + nodeStack.push_back(nodeStack.back()->add_child_element(name)); } } @@ -275,5 +273,5 @@ XmlDocMutator::XmlDocMutator(ScriptNodePtr) { } -INSTANTIATESTORE(std::string, XmlDocMutatorLoader); +INSTANTIATEFACTORY(XmlDocMutator, std::shared_ptr<const ScriptNode>); diff --git a/project2/xml/xmlPresenter.h b/project2/xml/xmlPresenter.h index 6e3dac2..3ad1c2d 100644 --- a/project2/xml/xmlPresenter.h +++ b/project2/xml/xmlPresenter.h @@ -6,21 +6,22 @@ #include "options.h" #include "variables.h" #include <libxml/tree.h> +#include <visibility.h> namespace xmlpp { class Document; class Element; } -class XmlDocMutator : public IntrusivePtrBase { +class DLL_PUBLIC XmlDocMutator : public virtual Something { public: XmlDocMutator(ScriptNodePtr); virtual void mutateElement(xmlpp::Element *) const = 0; }; -typedef boost::intrusive_ptr<XmlDocMutator> XmlDocMutatorPtr; -typedef GenLoader<XmlDocMutator, std::string, ScriptNodePtr> XmlDocMutatorLoader; +typedef std::shared_ptr<XmlDocMutator> XmlDocMutatorPtr; +typedef AdHoc::Factory<XmlDocMutator, std::shared_ptr<const ScriptNode>> XmlDocMutatorFactory; -class XmlPresenter : public Presenter, public ContentPresenter, public SourceOf<xmlpp::Document>, public SourceOf<xmlDoc>, public SourceOf<boost::shared_ptr<xmlpp::Document> >, public WritableContent, public SourceOf<WritableContent> { +class DLL_PUBLIC XmlPresenter : public Presenter, public ContentPresenter, public SourceOf<xmlpp::Document>, public SourceOf<xmlDoc>, public SourceOf<boost::shared_ptr<xmlpp::Document> >, public WritableContent, public SourceOf<WritableContent> { public: typedef boost::shared_ptr<xmlpp::Document> XmlDocumentPtr; XmlPresenter(const Glib::ustring & responseRootNodeName, const Glib::ustring & responseStyle, const Glib::ustring & contentType); @@ -74,7 +75,7 @@ class XmlPresenter : public Presenter, public ContentPresenter, public SourceOf< static boost::optional<std::string> customFormat; }; -typedef boost::intrusive_ptr<XmlPresenter> XmlPresenterPtr; +typedef std::shared_ptr<XmlPresenter> XmlPresenterPtr; #endif diff --git a/project2/xml/xmlRawRows.cpp b/project2/xml/xmlRawRows.cpp index eb6e003..680757b 100644 --- a/project2/xml/xmlRawRows.cpp +++ b/project2/xml/xmlRawRows.cpp @@ -3,7 +3,7 @@ #include <libxml++/parsers/domparser.h> #include <libxml++/nodes/textnode.h> -DECLARE_LOADER("xmlrawrows", XmlRawRows); +NAMEDFACTORY("xmlrawrows", XmlRawRows, RowSetFactory); class XmlRowState : public RowState { public: @@ -42,11 +42,13 @@ class XmlRowState : public RowState { XmlRawRowsBase::XmlRawRowsBase(ScriptNodePtr p) : + SourceObject(p), RowSet(p) { } XmlRawRowsBase::XmlRawRowsBase() : + SourceObject(ScriptNodePtr()), RowSet(NULL) { } @@ -60,7 +62,7 @@ void XmlRawRowsBase::execute(const xmlpp::Document * doc, const RowProcessorCall unsigned int col = 0; for (const xmlpp::Node * in : rs.e->get_children()) { if (const xmlpp::Element * ie = dynamic_cast<const xmlpp::Element *>(in)) { - rs.cols.insert(new Column(col++, ie->get_name())); + rs.cols.insert(std::make_shared<Column>(col++, ie->get_name())); } } rs.fields.resize(col); @@ -68,7 +70,7 @@ void XmlRawRowsBase::execute(const xmlpp::Document * doc, const RowProcessorCall unsigned int col = 0; for (const xmlpp::Node * in : rs.e->get_children()) { if (const xmlpp::Element * ie = dynamic_cast<const xmlpp::Element *>(in)) { - const xmlpp::TextNode * t = ie->get_child_text(); + const xmlpp::TextNode * t = ie->get_first_child_text(); if (t) { rs.fields[col] = VariableType::make(t->get_content(), VariableType::getTypeFromName(ie->get_attribute_value("type", Scripts::scriptNamespacePrefix))); @@ -82,12 +84,14 @@ void XmlRawRowsBase::execute(const xmlpp::Document * doc, const RowProcessorCall } XmlRawRows::XmlRawRows(ScriptNodePtr p) : + SourceObject(p), XmlRawRowsBase(p), path(p, "path") { } XmlRawRows::XmlRawRows(const Glib::ustring & p) : + SourceObject(ScriptNodePtr()), path(p) { } @@ -99,6 +103,7 @@ void XmlRawRows::execute(const Glib::ustring&, const RowProcessorCallback & rp, } XmlMemRawRows::XmlMemRawRows(boost::shared_ptr<const xmlpp::Document> d) : + SourceObject(ScriptNodePtr()), doc(d) { } diff --git a/project2/xml/xmlRawRows.h b/project2/xml/xmlRawRows.h index ac5a30f..483863d 100644 --- a/project2/xml/xmlRawRows.h +++ b/project2/xml/xmlRawRows.h @@ -4,7 +4,7 @@ namespace xmlpp { class Document; } -class XmlRawRowsBase : public RowSet { +class DLL_PUBLIC XmlRawRowsBase : public RowSet { public: XmlRawRowsBase(ScriptNodePtr p); XmlRawRowsBase(); @@ -13,7 +13,7 @@ class XmlRawRowsBase : public RowSet { void execute(const xmlpp::Document *, const RowProcessorCallback &, ExecContext *) const; }; -class XmlRawRows : public XmlRawRowsBase { +class DLL_PUBLIC XmlRawRows : public XmlRawRowsBase { public: XmlRawRows(ScriptNodePtr p); XmlRawRows(const Glib::ustring & p); @@ -24,7 +24,7 @@ class XmlRawRows : public XmlRawRowsBase { const Variable path; }; -class XmlMemRawRows : public XmlRawRowsBase { +class DLL_PUBLIC XmlMemRawRows : public XmlRawRowsBase { public: XmlMemRawRows(boost::shared_ptr<const xmlpp::Document> d); diff --git a/project2/xml/xmlRows.cpp b/project2/xml/xmlRows.cpp index e0ffb5b..56dfe9a 100644 --- a/project2/xml/xmlRows.cpp +++ b/project2/xml/xmlRows.cpp @@ -1,7 +1,6 @@ #include <pch.hpp> #include "xmlRows.h" #include "rowProcessor.h" -#include "xml.h" #include "exceptions.h" #include <libxml++/nodes/textnode.h> #include <libxml/xmlreader.h> @@ -11,9 +10,10 @@ #include <boost/algorithm/string/join.hpp> #include <boost/algorithm/string/predicate.hpp> -DECLARE_LOADER("xmlrows", XmlRows); +NAMEDFACTORY("xmlrows", XmlRows, RowSetFactory); XmlRows::XmlRows(ScriptNodePtr p) : + SourceObject(p), RowSet(p), recordRoot(p, "recordroot"), recordTrigger(p, "recordtrigger"), @@ -40,7 +40,7 @@ XmlRows::XmlRows(ScriptNodePtr p) : } fields[p] = col; - fieldNames.insert(new Column(col++, node->get_name())); + fieldNames.insert(std::make_shared<Column>(col++, node->get_name())); } } @@ -61,7 +61,7 @@ store(const XmlRows::Path & position, RowState::FieldValues & values, const XmlR void XmlRows::execute(const Glib::ustring &, const RowProcessorCallback & rp, ExecContext * ec) const { - xmlTextReaderPtr reader = xmlReaderForFile(filename(ec), NULL, 0); + xmlTextReaderPtr reader = xmlReaderForFile(filename(ec).as<std::string>().c_str(), NULL, 0); if (reader == NULL) { throw std::runtime_error("Failed to open file"); } diff --git a/project2/xml/xmlRows.h b/project2/xml/xmlRows.h index bfc6514..4f0d9f1 100644 --- a/project2/xml/xmlRows.h +++ b/project2/xml/xmlRows.h @@ -7,7 +7,7 @@ #include "rowSet.h" /// Project2 component to create a row set based on the contents of an XML file -class XmlRows : public RowSet { +class DLL_PUBLIC XmlRows : public RowSet { public: typedef std::vector<std::string> Path; typedef std::map<Path, unsigned int> Interests; diff --git a/project2/xml/xmlScriptParser.cpp b/project2/xml/xmlScriptParser.cpp index 1c4c798..354bb55 100644 --- a/project2/xml/xmlScriptParser.cpp +++ b/project2/xml/xmlScriptParser.cpp @@ -3,29 +3,31 @@ #include "scripts.h" #include "commonObjects.h" #include "variables/literal.h" -#include <boost/filesystem/convenience.hpp> +#include <filesystem> +#include <chronoHelpers.h> static const std::string XIncludeNS("http://www.w3.org/2001/XInclude"); static const std::string XIncludeInclude("include"); -XmlScriptParser::XmlScriptParser(const boost::filesystem::path & file) +XmlScriptParser::XmlScriptParser(const std::filesystem::path & file) { try { - parse_file(file.string()); + parse_file(file); } catch (const xmlpp::internal_error &) { throw NotReadable(file.string()); } doIncludes(get_document()->get_root_node(), file); - files.insert(Files::value_type(file, boost::filesystem::last_write_time(file))); + files.insert(Files::value_type(file, to_time_t( + std::filesystem::last_write_time(file)))); } void -XmlScriptParser::doIncludes(xmlpp::Element * e, const boost::filesystem::path & f) +XmlScriptParser::doIncludes(xmlpp::Element * e, const std::filesystem::path & f) { if (e->get_namespace_uri().raw() == XIncludeNS && e->get_name().raw() == XIncludeInclude) { - boost::filesystem::path inc = f.parent_path(); - for (boost::filesystem::path c : boost::filesystem::path(e->get_attribute_value("href").raw())) { + std::filesystem::path inc = f.parent_path(); + for (std::filesystem::path c : std::filesystem::path(e->get_attribute_value("href").raw())) { if (c.string() == "..") { inc = inc.parent_path(); } @@ -37,7 +39,8 @@ XmlScriptParser::doIncludes(xmlpp::Element * e, const boost::filesystem::path & xmlpp::DomParser(inc.string()).get_document()->get_root_node()))) { doIncludes(c, inc); } - files.insert(Files::value_type(inc, boost::filesystem::last_write_time(inc))); + files.insert(Files::value_type(inc, to_time_t( + std::filesystem::last_write_time(inc)))); } else { for (xmlpp::Node * n : e->get_children()) { @@ -53,7 +56,7 @@ ScriptNodePtr XmlScriptParser::root() const { if (!_root) { - _root = new XmlScriptNode(get_document()->get_root_node(), this); + _root = std::make_shared<XmlScriptNode>(get_document()->get_root_node(), shared_from_this()); } return _root; } @@ -77,12 +80,12 @@ XmlScriptParser::isCurrent() const { for (const Files::value_type & f : files) { try { - if (boost::filesystem::last_write_time(f.first) != f.second) { + if (to_time_t(std::filesystem::last_write_time(f.first)) != f.second) { _root.reset(); return false; } } - catch (const boost::filesystem::filesystem_error &) { + catch (const std::filesystem::filesystem_error &) { _root.reset(); return false; } @@ -90,12 +93,12 @@ XmlScriptParser::isCurrent() const return true; } -class XmlScriptReaderLoader : public ScriptReaderLoader { +class XmlScriptReaderFactory : public ScriptReaderFactory { public: - ScriptReaderPtr resolveScript(const std::string & group, const std::string & name) const { - boost::filesystem::path script(boost::filesystem::path(group) / (name + ".xml")); - if (boost::filesystem::is_regular_file(script)) { - return new XmlScriptParser(script); + std::shared_ptr<ScriptReader> create(const std::string & group, const std::string & name) const { + std::filesystem::path script(std::filesystem::path(group) / (name + ".xml")); + if (std::filesystem::is_regular_file(script)) { + return std::make_shared<XmlScriptParser>(script); } return NULL; } @@ -136,10 +139,10 @@ ScriptNode::ScriptNodes XmlScriptNode::children() const { if (!childrenCache) { - childrenCache = boost::shared_ptr<ScriptNodes>(new ScriptNodes()); + childrenCache = std::make_shared<ScriptNodes>(); for (const xmlpp::Node * n : element->get_children()) { if (const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(n)) { - childrenCache->push_back(new XmlScriptNode(e, script)); + childrenCache->push_back(std::make_shared<XmlScriptNode>(e, script.lock())); } } } @@ -149,10 +152,10 @@ XmlScriptNode::children() const ScriptNodePtr XmlScriptNode::child(const Glib::ustring & n, bool required) const { - const xmlpp::Element::NodeList cs = element->get_children(n); + auto cs = element->get_children(n); if (cs.size() == 1) { if (const xmlpp::Element * c = dynamic_cast<const xmlpp::Element *>(cs.front())) { - return new XmlScriptNode(c, script); + return std::make_shared<XmlScriptNode>(c, script.lock()); } } if (required) { @@ -169,7 +172,7 @@ XmlScriptNode::childrenIn(const Glib::ustring & c) const if (const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(n)) { for (const xmlpp::Node * n1 : e->get_children()) { if (const xmlpp::Element * e1 = dynamic_cast<const xmlpp::Element *>(n1)) { - sns.push_back(new XmlScriptNode(e1, script)); + sns.push_back(std::make_shared<XmlScriptNode>(e1, script.lock())); } } } @@ -177,37 +180,37 @@ XmlScriptNode::childrenIn(const Glib::ustring & c) const return sns; } -VariableImpl * +std::shared_ptr<VariableImpl> XmlScriptNode::variable(const Glib::ustring & n) const { if (const xmlpp::Attribute * a = element->get_attribute(n)) { - return new VariableLiteral(a->get_value()); + return std::make_shared<VariableLiteral>(a->get_value()); } - const xmlpp::Element::NodeList cs = element->get_children(n); + auto cs = element->get_children(n); if (cs.size() == 1) { if (const xmlpp::Element * c = dynamic_cast<const xmlpp::Element *>(cs.front())) { if (const xmlpp::Attribute * source = c->get_attribute("source")) { - return InstanceMap<VariableLoader, std::string>::Get<UnknownVariableSource>(source->get_value())->create(new XmlScriptNode(c, script)); + return VariableFactory::createNew(source->get_value().raw(), std::make_shared<XmlScriptNode>(c, script.lock())); } else { - return new VariableLiteral(new XmlScriptNode(c, script)); + return std::make_shared<VariableLiteral>(std::make_shared<XmlScriptNode>(c, script.lock())); } } } throw ValueNotFound(n); } -VariableImpl * +std::shared_ptr<VariableImpl> XmlScriptNode::variable(const boost::optional<Glib::ustring> & defaultSource) const { if (const xmlpp::Attribute * source = element->get_attribute("source")) { - return InstanceMap<VariableLoader, std::string>::Get<UnknownVariableSource>(source->get_value())->create(new XmlScriptNode(element, script)); + return VariableFactory::createNew(source->get_value().raw(), std::make_shared<XmlScriptNode>(element, script.lock())); } else if (defaultSource) { - return InstanceMap<VariableLoader, std::string>::Get<UnknownVariableSource>(defaultSource.get())->create(new XmlScriptNode(element, script)); + return VariableFactory::createNew(defaultSource.get().raw(), std::make_shared<XmlScriptNode>(element, script.lock())); } else { - return new VariableLiteral(new XmlScriptNode(element, script)); + return std::make_shared<VariableLiteral>(std::make_shared<XmlScriptNode>(element, script.lock())); } } @@ -218,15 +221,15 @@ XmlScriptNode::applyValue(const Glib::ustring & n, VariableType & val, ExecConte val = a->get_value(); return true; } - const xmlpp::Element::NodeList cs = element->get_children(n); + auto cs = element->get_children(n); if (cs.size() == 1) { if (const xmlpp::Element * c = dynamic_cast<const xmlpp::Element *>(cs.front())) { - boost::intrusive_ptr<VariableImpl> v; + std::shared_ptr<VariableImpl> v; if (const xmlpp::Attribute * source = c->get_attribute("source")) { - v = InstanceMap<VariableLoader, std::string>::Get<UnknownVariableSource>(source->get_value())->create(new XmlScriptNode(c, script)); + v = VariableFactory::createNew(source->get_value().raw(), std::make_shared<XmlScriptNode>(c, script.lock())); } else { - v = new VariableLiteral(new XmlScriptNode(c, script)); + v = std::make_shared<VariableLiteral>(std::make_shared<XmlScriptNode>(c, script.lock())); } val = v->value(ec); return false; @@ -243,9 +246,10 @@ XmlScriptNode::composeWithCallbacks(const LiteralCallback & lcb, const NodeCallb lcb(t->get_content()); } else if (const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(n)) { - ncb(new XmlScriptNode(e, script)); + ncb(std::make_shared<XmlScriptNode>(e, script.lock())); } } } -DECLARE_CUSTOM_COMPONENT_LOADER("xmlScriptReader", XmlScriptReaderLoader, XmlScriptReaderLoader, ScriptReaderLoader); +NAMEDPLUGIN("xmlScriptReader", XmlScriptReaderFactory, ScriptReaderFactory); + diff --git a/project2/xml/xmlScriptParser.h b/project2/xml/xmlScriptParser.h index f596c8d..e53e165 100644 --- a/project2/xml/xmlScriptParser.h +++ b/project2/xml/xmlScriptParser.h @@ -5,11 +5,11 @@ #include "exceptions.h" #include "scriptLoader.h" #include "scripts.h" -#include <intrusivePtrBase.h> -#include <boost/filesystem/path.hpp> +#include <filesystem> #include <libxml++/document.h> #include <libxml++/nodes/element.h> #include <libxml++/parsers/domparser.h> +#include <visibility.h> class XmlScriptNode : public ScriptNode { public: @@ -22,31 +22,31 @@ class XmlScriptNode : public ScriptNode { ScriptNodes children() const; ScriptNodes childrenIn(const Glib::ustring&) const; bool valueExists(const Glib::ustring&) const; - VariableImpl * variable(const boost::optional<Glib::ustring> & defaultSource) const; - VariableImpl * variable(const Glib::ustring&) const; + std::shared_ptr<VariableImpl> variable(const boost::optional<Glib::ustring> & defaultSource) const; + std::shared_ptr<VariableImpl> variable(const Glib::ustring&) const; bool applyValue(const Glib::ustring & name, VariableType & target, ExecContext *) const; void composeWithCallbacks(const ScriptNode::LiteralCallback&, const ScriptNode::NodeCallback&) const; private: const xmlpp::Element * element; - mutable boost::shared_ptr<ScriptNodes> childrenCache; + mutable std::shared_ptr<ScriptNodes> childrenCache; }; -class XmlScriptParser : public xmlpp::DomParser, public ScriptReader { +class DLL_PUBLIC XmlScriptParser : public xmlpp::DomParser, public ScriptReader, public std::enable_shared_from_this<XmlScriptParser> { public: SimpleMessageException(ParseError); SimpleMessageExceptionBase(NotReadable, ParseError); SimpleMessageExceptionBase(IncludesError, ParseError); - XmlScriptParser(const boost::filesystem::path & file); + XmlScriptParser(const std::filesystem::path & file); ScriptNodePtr root() const; void load(const CommonObjects *, bool childrenOnly) const; bool isCurrent() const; time_t modifiedTime() const; private: mutable ScriptNodePtr _root; - void doIncludes(xmlpp::Element * e, const boost::filesystem::path & f); - typedef std::map<boost::filesystem::path, std::time_t> Files; + void doIncludes(xmlpp::Element * e, const std::filesystem::path & f); + typedef std::map<std::filesystem::path, std::time_t> Files; Files files; }; diff --git a/project2/xml/xpathRows.cpp b/project2/xml/xpathRows.cpp index e97270f..c00519d 100644 --- a/project2/xml/xpathRows.cpp +++ b/project2/xml/xpathRows.cpp @@ -3,28 +3,27 @@ #include "safeMapFind.h" #include "rowProcessor.h" #include "logger.h" -#include "xml.h" #include "exceptions.h" #include "scriptLoader.h" #include <boost/lexical_cast.hpp> #include <libxml/xpath.h> #include <libxml/xpathInternals.h> -#include "../libmisc/curlsup.h" -DECLARE_LOADER("xpathrows", XPathRows); +NAMEDFACTORY("xpathrows", XPathRows, RowSetFactory); SimpleMessageException(XpathInitError); SimpleMessageException(XpathEvalError); XPathRows::XPathRows(ScriptNodePtr p) : + SourceObject(p), RowSet(p), - VariableCurlHelper(p), + XmlDocumentCache(p), html(p, "html", false), warnings(p, "warnings", true), encoding(p, "encoding", Null()) { for (ScriptNodePtr node : p->childrenIn("filterviews")) { - FilterViewPtr fv = new FilterView(node); + FilterViewPtr fv = std::make_shared<FilterView>(node); fvs[fv->name] = fv; } for (ScriptNodePtr node : p->childrenIn("namespaces")) { @@ -48,20 +47,14 @@ XPathRows::withWarnings(ExecContext * ec) const return warnings(ec); } -CurlPtr -XPathRows::newCurl(ExecContext * ec) const -{ - return VariableCurlHelper::newCurl(ec); -} - void XPathRows::execute(const Glib::ustring & filter, const RowProcessorCallback & rp, ExecContext * ec) const { - FilterViewPtr fv = safeMapLookup<FilterNotFound>(fvs, filter); + FilterViewPtr fv = AdHoc::safeMapLookup<FilterNotFound>(fvs, filter); typedef boost::shared_ptr<xmlXPathObject> xmlXPathObjectSPtr; typedef boost::shared_ptr<xmlXPathContext> xmlXPathContextSPtr; - xmlDocPtr doc = getDocument(url(ec), encoding(ec), ec)->cobj(); + xmlDocPtr doc = getDocument(url(ec), encoding(ec), html(ec), warnings(ec), ec)->cobj(); xmlXPathContextSPtr xpathCtx = xmlXPathContextSPtr(xmlXPathNewContext(doc), xmlXPathFreeContext); if (!xpathCtx) { throw XpathInitError(xmlGetLastError()->message); @@ -69,11 +62,12 @@ XPathRows::execute(const Glib::ustring & filter, const RowProcessorCallback & rp for (const Namespaces::value_type & ns : namespaces) { xmlXPathRegisterNs(xpathCtx.get(), BAD_CAST ns.first.c_str(), BAD_CAST ns.second.c_str()); } - xmlXPathObjectSPtr xpathObj = xmlXPathObjectSPtr(xmlXPathEvalExpression(fv->root(ec), xpathCtx.get()), xmlXPathFreeObject); + Glib::ustring rootv(fv->root(ec).as<Glib::ustring>()); + xmlXPathObjectSPtr xpathObj = xmlXPathObjectSPtr(xmlXPathEvalExpression(BAD_CAST rootv.c_str(), xpathCtx.get()), xmlXPathFreeObject); if (!xpathObj || !xpathObj->nodesetval) { throw XpathEvalError(xmlGetLastError()->message); } - Logger()->messagef(LOG_INFO, "%d nodes matched %s", xpathObj->nodesetval->nodeNr, (const char *)(fv->root(ec))); + Logger()->messagef(LOG_INFO, "%d nodes matched %s", xpathObj->nodesetval->nodeNr, rootv.c_str()); XPathState xs(fv); for (int row = 0; row < xpathObj->nodesetval->nodeNr; row += 1) { xmlNodePtr rowRoot = xpathObj->nodesetval->nodeTab[row]; @@ -84,7 +78,7 @@ XPathRows::execute(const Glib::ustring & filter, const RowProcessorCallback & rp if (path.isNull()) { continue; } - xmlXPathObjectSPtr xpathObjI = xmlXPathObjectSPtr(xmlXPathEvalExpression(path, xpathCtx.get()), xmlXPathFreeObject); + xmlXPathObjectSPtr xpathObjI = xmlXPathObjectSPtr(xmlXPathEvalExpression(BAD_CAST path.as<std::string>().c_str(), xpathCtx.get()), xmlXPathFreeObject); if (!xpathObjI) { throw XpathEvalError(xmlGetLastError()->message); } @@ -128,10 +122,10 @@ XPathRows::FilterViewColumn::FilterViewColumn(unsigned int idx, ScriptNodePtr p) { } -XPathRows::FilterViewColumn * +std::shared_ptr<Column> XPathRows::FilterViewColumn::make(unsigned int idx, ScriptNodePtr p) { - return new FilterViewColumn(idx, p); + return std::make_shared<FilterViewColumn>(idx, p); } XPathRows::XPathState::XPathState(FilterViewCPtr f) : diff --git a/project2/xml/xpathRows.h b/project2/xml/xpathRows.h index 03929ab..9066261 100644 --- a/project2/xml/xpathRows.h +++ b/project2/xml/xpathRows.h @@ -3,7 +3,6 @@ #include <libxml++/nodes/element.h> #include <libxml/tree.h> -#include <boost/intrusive_ptr.hpp> #include <map> #include "rowSet.h" #include "variables.h" @@ -12,7 +11,7 @@ #include "definedColumns.h" /// Project2 component to create a row set based on the contents of an XML resource and specific XPaths with its hierarchy -class XPathRows : public RowSet, XmlDocumentCache, VariableCurlHelper { +class DLL_PUBLIC XPathRows : public RowSet, XmlDocumentCache { public: XPathRows(ScriptNodePtr p); ~XPathRows(); @@ -23,10 +22,10 @@ class XPathRows : public RowSet, XmlDocumentCache, VariableCurlHelper { class FilterViewColumn : public Column { public: FilterViewColumn(unsigned int, ScriptNodePtr); - static FilterViewColumn * make(unsigned int, ScriptNodePtr); + static std::shared_ptr<Column> make(unsigned int, ScriptNodePtr); const Variable path; }; - class FilterView : public DefinedColumns, public virtual IntrusivePtrBase { + class FilterView : public DefinedColumns { public: typedef std::map<const Glib::ustring, Variable> XPaths; @@ -35,12 +34,11 @@ class XPathRows : public RowSet, XmlDocumentCache, VariableCurlHelper { const Glib::ustring name; const Variable root; }; - typedef boost::intrusive_ptr<FilterView> FilterViewPtr; - typedef boost::intrusive_ptr<const FilterView> FilterViewCPtr; + typedef std::shared_ptr<FilterView> FilterViewPtr; + typedef std::shared_ptr<const FilterView> FilterViewCPtr; typedef std::map<const Glib::ustring, FilterViewPtr> FilterViews; FilterViews fvs; - virtual CurlPtr newCurl(ExecContext *) const; virtual bool asHtml(ExecContext *) const; virtual bool withWarnings(ExecContext *) const; @@ -7,7 +7,9 @@ import toolset ; type.register SLICE : ice ; -feature slicer : no yes : propagated ; +feature slicer : no yes pure ; +feature allow-ice : no yes ; +feature ice-visibility : public hidden ; class slice-scanner : common-scanner { @@ -22,22 +24,35 @@ scanner.register slice-scanner : include ; type.set-scanner SLICE : slice-scanner ; generators.register-standard slice.slice2cpp : SLICE : CPP H : <slicer>no ; -generators.register-standard slice.slicer : SLICE : CPP H : <slicer>yes ; +generators.register-standard slice.slicer : SLICE : CPP CPP(slicer-%) H : <slicer>yes ; +generators.register-standard slice.slicer.pure : SLICE : CPP(slicer-%) : <slicer>pure ; toolset.flags slice.slice2cpp INCLUDES <include> ; +toolset.flags slice.slice2cpp DLLEXPORT <ice-visibility>public : --dll-export JAM_DLL_PUBLIC ; +toolset.flags slice.slice2cpp ALLOWICE <allow-ice>yes : --ice ; toolset.flags slice.slicer INCLUDES <include> ; +toolset.flags slice.slicer DLLEXPORT <ice-visibility>public : --dll-export JAM_DLL_PUBLIC ; +toolset.flags slice.slicer ALLOWICE <allow-ice>yes : --ice ; +toolset.flags slice.slicer.pure INCLUDES <include> ; +toolset.flags slice.slicer.pure ALLOWICE <allow-ice>yes : --ice ; actions slice.slice2cpp { - slice2cpp -I"$(INCLUDES)" --checksum --output-dir $(1[1]:D) $(2) + slice2cpp -I"$(INCLUDES)" --checksum --output-dir $(1[1]:D) $(2) $(DLLEXPORT) $(ALLOWICE[1]) } actions slice.slicer { - slice2cpp -I"$(INCLUDES)" --checksum --output-dir $(1[1]:D) $(2) - slicer -I"$(INCLUDES)" $(2) $(1[1]) + slice2cpp -I"$(INCLUDES)" --checksum --output-dir $(1[1]:D) $(2) $(DLLEXPORT) $(ALLOWICE[1]) + slicer -I"$(INCLUDES)" $(2) $(1[2]) $(ALLOWICE[1]) +} + +actions slice.slicer.pure +{ + slicer -I"$(INCLUDES)" $(2) $(1[1]) $(ALLOWICE[1]) } IMPORT $(__name__) : slice.slice2cpp : : slice.slice2cpp ; IMPORT $(__name__) : slice.slicer : : slice.slicer ; +IMPORT $(__name__) : slice.slicer.pure : : slice.slicer.pure ; |
