diff --git a/Makefile.am b/Makefile.am index a709c1230..c8703c6fa 100644 --- a/Makefile.am +++ b/Makefile.am @@ -41,9 +41,6 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/ \ # Only use subdirs if really needed, prefer the include scheme below #SUBDIRS += -# administrative tools -include $(top_srcdir)/admin/Makefile.am - # core include $(top_srcdir)/src/lib/Makefile.am include $(top_srcdir)/src/proc/Makefile.am diff --git a/SConstruct b/SConstruct index e38511152..8a2316996 100644 --- a/SConstruct +++ b/SConstruct @@ -28,6 +28,7 @@ CUSTOPTIONSFILE = 'custom-options' SRCDIR = 'src' BINDIR = 'bin' LIBDIR = '.libs' +PLUGDIR = '.libs' TESTDIR = 'tests' ICONDIR = 'icons' VERSION = '0.1+pre.01' @@ -74,6 +75,7 @@ def setupBasicEnvironment(): , SRCDIR=SRCDIR , BINDIR=BINDIR , LIBDIR=LIBDIR + , PLUGDIR=PLUGDIR , ICONDIR=ICONDIR , CPPPATH=["#"+SRCDIR] # used to find includes, "#" means always absolute to build-root , CPPDEFINES=['-DLUMIERA_VERSION='+VERSION ] # note: it's a list to append further defines @@ -322,28 +324,30 @@ def defineBuildTargets(env, artifacts): # + env.PrecompiledHeader('$SRCDIR/pre_a.hpp') # ) - objapp = srcSubtree(env,'$SRCDIR/common') - objback = srcSubtree(env,'$SRCDIR/backend') - objproc = srcSubtree(env,'$SRCDIR/proc') - objlib = srcSubtree(env,'$SRCDIR/lib') - core = ( env.SharedLibrary('$LIBDIR/lumieracommon', objapp) - + env.SharedLibrary('$LIBDIR/lumierabackend', objback) - + env.SharedLibrary('$LIBDIR/lumieraproc', objproc) - + env.SharedLibrary('$LIBDIR/lumiera', objlib) - ) + + lApp = env.SharedLibrary('$LIBDIR/lumieracommon', srcSubtree(env,'$SRCDIR/common')) + lBack = env.SharedLibrary('$LIBDIR/lumierabackend', srcSubtree(env,'$SRCDIR/backend')) + lProc = env.SharedLibrary('$LIBDIR/lumieraproc', srcSubtree(env,'$SRCDIR/proc')) + lLib = env.SharedLibrary('$LIBDIR/lumiera', srcSubtree(env,'$SRCDIR/lib')) + + core = lLib+lApp+lBack+lProc artifacts['lumiera'] = env.Program('$BINDIR/lumiera', ['$SRCDIR/lumiera/main.cpp'], LIBS=core) - artifacts['corelib'] = core - + artifacts['corelib'] = lLib+lApp + artifacts['support'] = lLib + # building Lumiera Plugins + envPlu = env.Clone() + envPlu.Append(CPPDEFINES='LUMIERA_PLUGIN') artifacts['plugins'] = [] # currently none # the Lumiera GTK GUI - envgtk = env.Clone().mergeConf(['gtkmm-2.4','cairomm-1.0','gdl-1.0','librsvg-2.0','xv','xext','sm']) - envgtk.Append(CPPDEFINES='LUMIERA_PLUGIN', LIBS=core) - objgui = srcSubtree(envgtk,'$SRCDIR/gui') + envGtk = env.Clone() + envGtk.mergeConf(['gtkmm-2.4','cairomm-1.0','gdl-1.0','librsvg-2.0','xv','xext','sm']) + envGtk.Append(CPPDEFINES='LUMIERA_PLUGIN', LIBS=core) + objgui = srcSubtree(envGtk,'$SRCDIR/gui') # render and install Icons vector_icon_dir = env.subst('$ICONDIR/svg') @@ -352,17 +356,16 @@ def defineBuildTargets(env, artifacts): + [env.IconCopy(f) for f in scanSubtree(prerendered_icon_dir, ['*.png'])] ) - guimodule = envgtk.LoadableModule('$LIBDIR/gtk_gui', objgui, SHLIBPREFIX='', SHLIBSUFFIX='.lum') + guimodule = envGtk.LoadableModule('$LIBDIR/gtk_gui', objgui, SHLIBPREFIX='', SHLIBSUFFIX='.lum') artifacts['lumigui'] = ( guimodule - + envgtk.Program('$BINDIR/lumigui', objgui ) + + envGtk.Program('$BINDIR/lumigui', objgui ) + env.Install('$BINDIR', env.Glob('$SRCDIR/gui/*.rc')) + artifacts['icons'] ) # call subdir SConscript(s) for independent components - SConscript(dirs=[SRCDIR+'/tool'], exports='env artifacts core') - SConscript(dirs=['admin'], exports='env envgtk artifacts core') - SConscript(dirs=[TESTDIR], exports='env artifacts core') + SConscript(dirs=[SRCDIR+'/tool'], exports='env envGtk artifacts core') + SConscript(dirs=[TESTDIR], exports='env envPlu artifacts core') diff --git a/admin/Makefile.am b/admin/Makefile.am deleted file mode 100644 index a8d2da160..000000000 --- a/admin/Makefile.am +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (C) Lumiera.org -# 2008, Christian Thaeter -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -admin_srcdir = $(top_srcdir)/admin - -noinst_PROGRAMS += vgsuppression -vgsuppression_SOURCES = $(admin_srcdir)/vgsuppression.c -vgsuppression_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -vgsuppression_LDADD = liblumiera.la $(NOBUGMT_LUMIERA_LIBS) -ldl liblumieracommon.la liblumieraproc.la -lboost_regex-mt -lboost_program_options-mt -ldl - -noinst_PROGRAMS += rsvg-convert -rsvg_convert_SOURCES = $(admin_srcdir)/rsvg-convert.c -rsvg_convert_CPPFLAGS = $(AM_CPPFLAGS) $(LUMIERA_GUI_CFLAGS) -std=gnu99 -Wall -Werror -rsvg_convert_LDADD = -lcairo -lglib-2.0 -lgthread-2.0 -lrsvg-2 diff --git a/admin/SConscript b/admin/SConscript deleted file mode 100644 index 2737bab7e..000000000 --- a/admin/SConscript +++ /dev/null @@ -1,17 +0,0 @@ -# -*- python -*- -## -## SConscript - SCons buildscript for helper tools (called by SConstruct) -## - -Import('env','envgtk','artifacts','core') - -vgsuppr = env.Program('#$BINDIR/vgsuppression',['vgsuppression.c']+core) -rsvg = envgtk.Program('#$BINDIR/rsvg-convert','rsvg-convert.c') - -artifacts['tools'] += [ vgsuppr ## for suppressing false valgrind alarms - + rsvg ## for rendering SVG icons (uses librsvg) - ] - -# Rendering the SVG Icons depends on rsvg-convert -env.Depends(artifacts['icons'], rsvg) - diff --git a/admin/scons/Buildhelper.py b/admin/scons/Buildhelper.py index a8a76a600..159dc4721 100644 --- a/admin/scons/Buildhelper.py +++ b/admin/scons/Buildhelper.py @@ -91,6 +91,38 @@ def globRootdirs(roots): +def findSrcTrees(location, patterns=SRCPATTERNS): + """ find possible source tree roots, starting with the given location. + When delving down from the initial location(s), a source tree is defined + as a directory containing source files and possibly further sub directories. + After having initially expanded the given location with #globRootdirs, each + directory is examined depth first, until encountering a directory containing + source files, which then yields a result. Especially, this can be used to traverse + an organisational directory structure and find out all possible source trees of + to be built into packages, plugins, individual tool executables etc. + @return: the relative path names of all source root dirs found (generator function). + """ + for dir in globRootdirs(location): + if isSrcDir(dir,patterns): + yield dir + else: + for result in findSrcTrees(str(dir)+'/*'): + yield result + + +def isSrcDir(path, patterns=SRCPATTERNS): + """ helper: investigate the given (relative) path + @param patterns: list of wildcards defining what counts as "source file" + @return: True if it's a directory containing any source file + """ + if not os.path.isdir(path): + return False + else: + for p in patterns: + if glob.glob(path+'/'+p): + return True + + def filterNodes(nlist, removeName=None): """ filter out scons build nodes using the given criteria. @@ -115,6 +147,19 @@ def getDirname(dir): +def createPlugins(env, dir): + """ investigate the given source directory to identify all contained source trees. + @return: a list of build nodes defining a plugin for each of these source trees. + """ + return [env.LoadableModule( '#$PLUGDIR/%s' % getDirname(tree) + , srcSubtree(env, tree) + , SHLIBPREFIX='', SHLIBSUFFIX='.lum' + ) + for tree in findSrcTrees(dir) + ] + + + def checkCommandOption(env, optID, val=None, cmdName=None): """ evaluate and verify an option, which may point at a command. besides specifying a path, the option may read True, yes or 1, diff --git a/src/backend/file.c b/src/backend/file.c index 95b4474c4..b8b8ae937 100644 --- a/src/backend/file.c +++ b/src/backend/file.c @@ -130,7 +130,7 @@ LumieraMMapings lumiera_file_mmapings (LumieraFile self) { if (!self->descriptor->mmapings) - LUMIERA_ERROR_SET (file, FILE_NOCHUNKSIZE); + LUMIERA_ERROR_SET (file, FILE_NOCHUNKSIZE, lumiera_filedescriptor_name (self->descriptor)); return self->descriptor->mmapings; } diff --git a/src/backend/filedescriptor.c b/src/backend/filedescriptor.c index 442e9b6b0..8f68e3e42 100644 --- a/src/backend/filedescriptor.c +++ b/src/backend/filedescriptor.c @@ -141,7 +141,7 @@ lumiera_filedescriptor_acquire (const char* name, int flags, LList filenode) INFO (filedescriptor, "try creating dir: %s", dir); if (mkdir (dir, 0777) == -1 && errno != EEXIST) { - LUMIERA_ERROR_SET (filedescriptor, ERRNO); + LUMIERA_ERROR_SET (filedescriptor, ERRNO, name); goto error; } *slash = '/'; @@ -152,14 +152,14 @@ lumiera_filedescriptor_acquire (const char* name, int flags, LList filenode) fd = creat (name, 0666); if (fd == -1) { - LUMIERA_ERROR_SET (filedescriptor, ERRNO); + LUMIERA_ERROR_SET (filedescriptor, ERRNO, name); goto error; } close (fd); if (stat (name, &fdesc.stat) != 0) { /* finally, no luck */ - LUMIERA_ERROR_SET (filedescriptor, ERRNO); + LUMIERA_ERROR_SET (filedescriptor, ERRNO, name); goto error; } } diff --git a/src/backend/filehandle.c b/src/backend/filehandle.c index c0d136ec2..2197a0805 100644 --- a/src/backend/filehandle.c +++ b/src/backend/filehandle.c @@ -84,7 +84,7 @@ lumiera_filehandle_handle (LumieraFilehandle self) fd = open (lumiera_filedescriptor_name (self->descriptor), lumiera_filedescriptor_flags (self->descriptor) & LUMIERA_FILE_MASK); if (fd == -1) { - LUMIERA_ERROR_SET (filehandle, ERRNO); + LUMIERA_ERROR_SET (filehandle, ERRNO, lumiera_filedescriptor_name (self->descriptor)); } else { @@ -92,13 +92,13 @@ lumiera_filehandle_handle (LumieraFilehandle self) if (fstat (fd, &st) == -1) { close (fd); - LUMIERA_ERROR_SET (filehandle, ERRNO); + LUMIERA_ERROR_SET (filehandle, ERRNO, lumiera_filedescriptor_name (self->descriptor)); } else if (!lumiera_filedescriptor_samestat (self->descriptor, &st)) { close (fd); /* Woops this is not the file we expected to use */ - LUMIERA_ERROR_SET (filehandle, FILE_CHANGED); + LUMIERA_ERROR_SET (filehandle, FILE_CHANGED, lumiera_filedescriptor_name (self->descriptor)); } } self->fd = fd; diff --git a/src/backend/filehandlecache.c b/src/backend/filehandlecache.c index 03abe08ae..23dd5fb74 100644 --- a/src/backend/filehandlecache.c +++ b/src/backend/filehandlecache.c @@ -85,7 +85,7 @@ lumiera_filehandlecache_handle_acquire (LumieraFilehandlecache self, LumieraFile NOTICE (filehandlecache, "overallocating filehandle"); ret = lumiera_filehandle_new (desc); if (!ret) - LUMIERA_ERROR_SET (filehandlecache, FILEHANDLECACHE_NOHANDLE); + LUMIERA_ERROR_SET (filehandlecache, FILEHANDLECACHE_NOHANDLE, lumiera_filedescriptor_name (desc)); else --self->available; } diff --git a/src/backend/mmap.c b/src/backend/mmap.c index d202a80f7..f39bafc12 100644 --- a/src/backend/mmap.c +++ b/src/backend/mmap.c @@ -140,7 +140,7 @@ lumiera_mmap_init (LumieraMMap self, LumieraFile file, off_t start, size_t size) /* extend file (writable) */ if (ftruncate (fd, begin+length) == -1) { - LUMIERA_ERROR_SET (mmap, ERRNO); + LUMIERA_ERROR_SET (mmap, ERRNO, lumiera_filedescriptor_name (file->descriptor)); goto etruncate; }; descriptor->stat.st_size = begin+length; @@ -173,7 +173,7 @@ lumiera_mmap_init (LumieraMMap self, LumieraFile file, off_t start, size_t size) break; case GIVE_UP: - LUMIERA_ERROR_SET (mmap, MMAP_SPACE); + LUMIERA_ERROR_SET (mmap, MMAP_SPACE, lumiera_filedescriptor_name (file->descriptor)); goto espace; } diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 337bf1595..bf63ed6eb 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -32,6 +32,7 @@ liblumieracommon_la_SOURCES = \ $(liblumieracommon_la_srcdir)/config_lookup.c \ $(liblumieracommon_la_srcdir)/config_interface.c \ $(liblumieracommon_la_srcdir)/configrules.cpp \ + $(liblumieracommon_la_srcdir)/external/libgavl.cpp \ $(liblumieracommon_la_srcdir)/query/fake-configrules.cpp \ $(liblumieracommon_la_srcdir)/interface.c \ $(liblumieracommon_la_srcdir)/interfaceregistry.c \ @@ -42,8 +43,7 @@ liblumieracommon_la_SOURCES = \ $(liblumieracommon_la_srcdir)/appstate.cpp \ $(liblumieracommon_la_srcdir)/option.cpp \ $(liblumieracommon_la_srcdir)/subsys.cpp \ - $(liblumieracommon_la_srcdir)/interfaceproxy.cpp \ - $(liblumieracommon_la_srcdir)/nobugcfg.cpp + $(liblumieracommon_la_srcdir)/interfaceproxy.cpp noinst_HEADERS += \ @@ -57,6 +57,7 @@ noinst_HEADERS += \ $(liblumieracommon_la_srcdir)/config_lookup.h \ $(liblumieracommon_la_srcdir)/config_interface.h \ $(liblumieracommon_la_srcdir)/configrules.hpp \ + $(liblumieracommon_la_srcdir)/external/libgavl.hpp \ $(liblumieracommon_la_srcdir)/query/fake-configrules.hpp \ $(liblumieracommon_la_srcdir)/subsys.hpp \ $(liblumieracommon_la_srcdir)/appstate.hpp \ diff --git a/src/common/appstate.cpp b/src/common/appstate.cpp index 6d5d009f0..4bea6168b 100644 --- a/src/common/appstate.cpp +++ b/src/common/appstate.cpp @@ -24,7 +24,6 @@ #include "lib/error.hpp" #include "include/lifecycle.h" #include "common/appstate.hpp" -#include "lib/lifecycleregistry.hpp" #include "common/subsystem-runner.hpp" extern "C" { @@ -51,7 +50,16 @@ namespace lumiera { { if (const char * errorstate = lumiera_error ()) ERROR (NOBUG_ON, "*** Unexpected error: %s\n Triggering emergency exit.", errorstate); - } } + } + + void + createAppStateInstance(){ + AppState::instance(); + } + + LifecycleHook schedule_ (ON_BASIC_INIT, &createAppStateInstance); + + } @@ -67,13 +75,10 @@ namespace lumiera { * client codes POV it just behaves like intended). */ AppState::AppState() - : lifecycleHooks_(new LifecycleRegistry) - , subsystems_(0) + : subsystems_(0) , emergency_(false) , core_up_ (false) - { - lifecycleHooks_->execute (ON_BASIC_INIT); // note in most cases a NOP - } + { } @@ -88,14 +93,6 @@ namespace lumiera { - void - AppState::lifecycle (Symbol event_label) - { - instance().lifecycleHooks_->execute(event_label); - } - - - @@ -124,7 +121,7 @@ namespace lumiera { _THROW_IF core_up_= true; - AppState::lifecycle (ON_GLOBAL_INIT); + LifecycleHook::trigger (ON_GLOBAL_INIT); _THROW_IF @@ -173,12 +170,12 @@ namespace lumiera { if (emergency_) { ERROR (operate, "Triggering emergency exit..."); - lifecycle (ON_EMERGENCY); + LifecycleHook::trigger (ON_EMERGENCY); return CLEAN_EMERGENCY_EXIT; } else { - lifecycle (ON_GLOBAL_SHUTDOWN); + LifecycleHook::trigger (ON_GLOBAL_SHUTDOWN); return NORMAL_EXIT; } } @@ -219,12 +216,12 @@ namespace lumiera { if (emergency_) { - lifecycle (ON_EMERGENCY); + LifecycleHook::trigger (ON_EMERGENCY); return FAILED_EMERGENCY_EXIT; } else { - lifecycle (ON_GLOBAL_SHUTDOWN); + LifecycleHook::trigger (ON_GLOBAL_SHUTDOWN); return CLEAN_EXIT_AFTER_ERROR; } } @@ -256,70 +253,4 @@ namespace lumiera { - - // ==== implementation LifecycleHook class ======= - - typedef LifecycleRegistry::Hook Callback; - - - LifecycleHook::LifecycleHook (Symbol eventLabel, Callback callbackFun) - { - add (eventLabel,callbackFun); - } - - void - LifecycleHook::add (Symbol eventLabel, Callback callbackFun) - { - bool isNew = AppState::instance().lifecycleHooks_->enroll (eventLabel,callbackFun); - - if (isNew && !strcmp(ON_BASIC_INIT, eventLabel)) - callbackFun(); // when this code executes, - // then per definition we are already post "basic init" - // (which happens in the AppState ctor); thus fire it immediately - } - - - void - LifecycleHook::trigger (Symbol eventLabel) - { - AppState::lifecycle (eventLabel); - } - - - - Symbol ON_BASIC_INIT ("ON_BASIC_INIT"); - Symbol ON_GLOBAL_INIT ("ON_GLOBAL_INIT"); - Symbol ON_GLOBAL_SHUTDOWN ("ON_GLOBAL_SHUTDOWN"); - - Symbol ON_EMERGENCY ("ON_EMERGENCY"); - - } // namespace lumiera - - -extern "C" { /* ==== implementation C interface for lifecycle hooks ======= */ - - - extern const char * lumiera_ON_BASIC_INIT = lumiera::ON_BASIC_INIT; - extern const char * lumiera_ON_GLOBAL_INIT = lumiera::ON_GLOBAL_INIT; - extern const char * lumiera_ON_GLOBAL_SHUTDOWN = lumiera::ON_GLOBAL_SHUTDOWN; - - extern const char * lumiera_ON_EMERGENCY = lumiera::ON_EMERGENCY; - - - - void - lumiera_LifecycleHook_add (const char* eventLabel, void callbackFun(void)) - { - lumiera::LifecycleHook (eventLabel, callbackFun); - } - - - void - lumiera_Lifecycle_trigger (const char* eventLabel) - { - lumiera::AppState::lifecycle (eventLabel); - } - -} - diff --git a/src/common/appstate.hpp b/src/common/appstate.hpp index aa9f0aa8d..e31d75328 100644 --- a/src/common/appstate.hpp +++ b/src/common/appstate.hpp @@ -52,7 +52,6 @@ namespace lumiera { using boost::scoped_ptr; using boost::noncopyable; - class LifecycleRegistry; class SubsystemRunner; @@ -78,11 +77,6 @@ namespace lumiera { static AppState& instance(); - /** fire off all lifecycle callbacks - * registered under the given label */ - static void lifecycle (Symbol eventLabel); - - /** evaluate the result of option parsing and maybe additional configuration * such as to be able to determine the further behaviour of the application. * Set the internal state within this object accordingly. */ @@ -123,17 +117,13 @@ namespace lumiera { private: - typedef scoped_ptr PLife; typedef scoped_ptr PSub; - PLife lifecycleHooks_; PSub subsystems_; bool emergency_; bool core_up_; - friend class LifecycleHook; - }; diff --git a/src/common/config.c b/src/common/config.c index 8801c4576..34d78dcdb 100644 --- a/src/common/config.c +++ b/src/common/config.c @@ -208,12 +208,12 @@ lumiera_config_get (const char* key, const char** value) *value = item->delim+1; } else - LUMIERA_ERROR_SET (configsys, CONFIG_NO_ENTRY); + LUMIERA_ERROR_SET (configsys, CONFIG_NO_ENTRY, key); } } else { - LUMIERA_ERROR_SET (configsys, CONFIG_SYNTAX_KEY); + LUMIERA_ERROR_SET (configsys, CONFIG_SYNTAX_KEY, key); } return *value; diff --git a/src/common/config_typed.c b/src/common/config_typed.c index 5a278665a..4fb55e6cc 100644 --- a/src/common/config_typed.c +++ b/src/common/config_typed.c @@ -77,12 +77,12 @@ lumiera_config_number_get (const char* key, long long* value) /* got it, scan it */ if (sscanf (raw_value, "%Li", value) != 1) { + LUMIERA_ERROR_SET (config_typed, CONFIG_SYNTAX_VALUE, lumiera_tmpbuf_snprintf (5000, "key '%s', value '%s'", key, raw_value)); raw_value = NULL; - LUMIERA_ERROR_SET (config_typed, CONFIG_SYNTAX_VALUE); } } else - LUMIERA_ERROR_SET (configsys, CONFIG_NO_ENTRY); + LUMIERA_ERROR_SET (configsys, CONFIG_NO_ENTRY, key); } } @@ -176,7 +176,7 @@ scan_string (const char* in) } else /* quotes doesnt match */ - LUMIERA_ERROR_SET (config_typed, CONFIG_SYNTAX_VALUE); + LUMIERA_ERROR_SET (config_typed, CONFIG_SYNTAX_VALUE, "unmatched quotes"); } else { @@ -208,7 +208,7 @@ lumiera_config_string_get (const char* key, const char** value) *value = scan_string (raw_value); } else - LUMIERA_ERROR_SET (configsys, CONFIG_NO_ENTRY); + LUMIERA_ERROR_SET (configsys, CONFIG_NO_ENTRY, key); } } @@ -253,7 +253,7 @@ lumiera_config_wordlist_get (const char* key, const char** value) *value = raw_value; } else - LUMIERA_ERROR_SET (configsys, CONFIG_NO_ENTRY); + LUMIERA_ERROR_SET (configsys, CONFIG_NO_ENTRY, key); TODO ("remove the ERROR_SET because config_get sets it already? also in all other getters in this file"); } @@ -322,7 +322,7 @@ lumiera_config_word_get (const char* key, const char** value) *value = scan_word (raw_value); } else - LUMIERA_ERROR_SET (configsys, CONFIG_NO_ENTRY); + LUMIERA_ERROR_SET (configsys, CONFIG_NO_ENTRY, key); } } diff --git a/src/common/configitem.c b/src/common/configitem.c index 9897158b1..82de5ae25 100644 --- a/src/common/configitem.c +++ b/src/common/configitem.c @@ -250,7 +250,7 @@ parse_directive (LumieraConfigitem self, char* itr) self->key = NULL; self->key_size = 0; - LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX); + LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX, self->line); } } else @@ -260,7 +260,7 @@ parse_directive (LumieraConfigitem self, char* itr) self->key = NULL; self->key_size = 0; - LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX); + LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX, self->line); } return self; } @@ -317,7 +317,7 @@ parse_section (LumieraConfigitem self, char* itr) self->key = NULL; self->key_size = 0; - LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX); + LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX, self->line); } } else @@ -329,7 +329,7 @@ parse_section (LumieraConfigitem self, char* itr) self->key = NULL; self->key_size = 0; - LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX); + LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX, self->line); } return self; @@ -368,7 +368,7 @@ parse_configentry (LumieraConfigitem self, char* itr) self->key = NULL; self->key_size = 0; - LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX); + LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX, self->line); } return self; diff --git a/src/lib/external/libgavl.cpp b/src/common/external/libgavl.cpp similarity index 98% rename from src/lib/external/libgavl.cpp rename to src/common/external/libgavl.cpp index a5711584d..8cb37a12f 100644 --- a/src/lib/external/libgavl.cpp +++ b/src/common/external/libgavl.cpp @@ -22,7 +22,7 @@ #include "proc/common.hpp" -#include "lib/external/libgavl.hpp" +#include "common/external/libgavl.hpp" #include "proc/control/stypemanager.hpp" extern "C" { diff --git a/src/lib/external/libgavl.hpp b/src/common/external/libgavl.hpp similarity index 100% rename from src/lib/external/libgavl.hpp rename to src/common/external/libgavl.hpp diff --git a/src/common/guifacade.cpp b/src/common/guifacade.cpp index 8b2bf0dee..60a16d0f6 100644 --- a/src/common/guifacade.cpp +++ b/src/common/guifacade.cpp @@ -27,7 +27,6 @@ #include "lib/error.hpp" #include "lib/singleton.hpp" #include "lib/functorutil.hpp" -#include "lib/thread-wrapper.hpp" #include "common/instancehandle.hpp" #include @@ -46,7 +45,6 @@ namespace gui { using util::dispatchSequenced; using lib::Sync; using lib::RecursiveLock_NoWait; - using lib::Thread; @@ -62,7 +60,7 @@ namespace gui { : theGUI_("lumieraorg_Gui", 1, 1, "lumieraorg_GuiStarterPlugin") // load GuiStarterPlugin { ASSERT (theGUI_); - Thread ("GUI-Main", bind (&GuiRunner::kickOff, this, terminationHandle)); + this->kickOff (terminationHandle); if (lumiera_error_peek()) throw lumiera::error::Fatal("failed to bring up GUI",lumiera_error()); diff --git a/src/common/plugin.c b/src/common/plugin.c index 3795f8511..e5045b8e9 100644 --- a/src/common/plugin.c +++ b/src/common/plugin.c @@ -283,13 +283,13 @@ lumiera_plugin_register (LumieraPlugin plugin) } break; default: - LUMIERA_ERROR_SET (plugin, PLUGIN_VERSION); + LUMIERA_ERROR_SET (plugin, PLUGIN_VERSION, plugin->name); } } } else { - LUMIERA_ERROR_SET (plugin, PLUGIN_REGISTER); + LUMIERA_ERROR_SET (plugin, PLUGIN_REGISTER, plugin->name); } } return !!lumiera_error_peek(); diff --git a/src/common/plugin_dynlib.c b/src/common/plugin_dynlib.c index afdb0e63c..920d1f385 100644 --- a/src/common/plugin_dynlib.c +++ b/src/common/plugin_dynlib.c @@ -18,6 +18,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "lib/safeclib.h" #include "common/plugin.h" #include @@ -42,18 +43,10 @@ lumiera_plugin_load_DYNLIB (const char* name) plugin = (LumieraInterface) dlsym (handle, LUMIERA_INTERFACE_DSTRING (lumieraorg__plugin, 0, lumieraorg_plugin)); if (!plugin) - LUMIERA_ERROR_SET (plugin, PLUGIN_WTF); + LUMIERA_ERROR_SET (plugin, PLUGIN_WTF, name); } else - LUMIERA_ERROR_SET (plugin, PLUGIN_OPEN); - -#ifdef DEBUG - if (lumiera_error_peek()) - { - const char* problem = dlerror(); - WARN_IF (problem, plugin, "Problem opening shared object %s : %s", name, problem); - } -#endif + LUMIERA_ERROR_SET (plugin, PLUGIN_OPEN, lumiera_tmpbuf_snprintf (4096, "%s: %s", name, dlerror())); return lumiera_plugin_init (self, handle, plugin); } diff --git a/src/gui/guistart.cpp b/src/gui/guistart.cpp index 455dafabb..86a8a0ab4 100644 --- a/src/gui/guistart.cpp +++ b/src/gui/guistart.cpp @@ -53,6 +53,7 @@ #include "gui/guifacade.hpp" #include "gui/notification-service.hpp" #include "common/subsys.hpp" +#include "lib/thread-wrapper.hpp" #include "lib/singleton.hpp" extern "C" { @@ -60,11 +61,14 @@ extern "C" { #include "common/interfacedescriptor.h" } +#include #include using std::string; +using lib::Thread; +using std::tr1::bind; using lumiera::Subsys; using gui::LUMIERA_INTERFACE_INAME(lumieraorg_Gui, 1); @@ -120,14 +124,19 @@ namespace gui { }; + void + runGUI (Subsys::SigTerm& reportTermination) + { + GuiLifecycle(reportTermination).run(); + } } // (End) impl details void - kickOff (Subsys::SigTerm& reportTermination) + kickOff (Subsys::SigTerm& terminationHandle) { - GuiLifecycle(reportTermination).run(); + Thread ("GUI-Main", bind (&runGUI, terminationHandle)); } } // namespace gui diff --git a/src/gui/notification-service.cpp b/src/gui/notification-service.cpp index c09e1bbd5..f713d7390 100644 --- a/src/gui/notification-service.cpp +++ b/src/gui/notification-service.cpp @@ -147,7 +147,7 @@ namespace gui { , LUMIERA_INTERFACE_INLINE (displayInfo, "\366\075\213\163\207\040\221\233\010\366\174\374\317\126\331\205", void, (const char* text), { - if (!_instance) lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE); + if (!_instance) lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, text); else _instance->displayInfo(text); } @@ -155,7 +155,7 @@ namespace gui { , LUMIERA_INTERFACE_INLINE (triggerGuiShutdown, "\267\043\244\065\107\314\370\175\063\330\264\257\302\146\326\303", void, (const char* cause), { - if (!_instance) lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE); + if (!_instance) lumiera_error_set(LUMIERA_ERROR_FACADE_LIFECYCLE, cause); else _instance->triggerGuiShutdown(cause); } diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 7f9d5fbf0..ab9567089 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -36,8 +36,9 @@ liblumiera_la_SOURCES = \ $(liblumiera_la_srcdir)/time.c \ $(liblumiera_la_srcdir)/resourcecollector.c \ $(liblumiera_la_srcdir)/allocationcluster.cpp \ - $(liblumiera_la_srcdir)/external/libgavl.cpp \ $(liblumiera_la_srcdir)/lumitime.cpp \ + $(liblumiera_la_srcdir)/lifecycle.cpp \ + $(liblumiera_la_srcdir)/nobugcfg.cpp \ $(liblumiera_la_srcdir)/util.cpp \ $(liblumiera_la_srcdir)/visitor.cpp \ $(liblumiera_la_srcdir)/query.cpp \ @@ -64,7 +65,6 @@ noinst_HEADERS += \ $(liblumiera_la_srcdir)/allocationcluster.hpp \ $(liblumiera_la_srcdir)/scopedholdertransfer.hpp \ $(liblumiera_la_srcdir)/scopedholder.hpp \ - $(liblumiera_la_srcdir)/external/libgavl.hpp \ $(liblumiera_la_srcdir)/lifecycleregistry.hpp \ $(liblumiera_la_srcdir)/factory.hpp \ $(liblumiera_la_srcdir)/frameid.hpp \ diff --git a/src/lib/error.c b/src/lib/error.c index 735f85955..caf2cf81b 100644 --- a/src/lib/error.c +++ b/src/lib/error.c @@ -33,51 +33,103 @@ predefined errors */ LUMIERA_ERROR_DEFINE (ERRNO, "errno"); +LUMIERA_ERROR_DEFINE (EERROR, "could not initialize error system"); /* Thread local storage */ static pthread_key_t lumiera_error_tls; static pthread_once_t lumiera_error_initialized = PTHREAD_ONCE_INIT; +/** + * Holding error and some context data. + */ +struct lumiera_errorcontext_struct +{ + lumiera_err err; + char* extra; +}; + +typedef struct lumiera_errorcontext_struct lumiera_errorcontext; +typedef lumiera_errorcontext* LumieraErrorcontext; + + +static void +lumiera_error_tls_delete (void* err) +{ + if (err) + free (((LumieraErrorcontext)err)->extra); +} + static void lumiera_error_tls_init (void) { - pthread_key_create (&lumiera_error_tls, NULL); + if (!!pthread_key_create (&lumiera_error_tls, lumiera_error_tls_delete)) + LUMIERA_DIE (EERROR); } -lumiera_err -lumiera_error_set (lumiera_err nerr) +LumieraErrorcontext +lumiera_error_get (void) { if (lumiera_error_initialized == PTHREAD_ONCE_INIT) pthread_once (&lumiera_error_initialized, lumiera_error_tls_init); - lumiera_err err = pthread_getspecific (lumiera_error_tls); - if (!err) - pthread_setspecific (lumiera_error_tls, nerr); + LumieraErrorcontext self = pthread_getspecific (lumiera_error_tls); + if (!self) + { + /* malloc() and not lumiera_malloc() here because nothing else might be initialized when calling this */ + self = malloc (sizeof *self); + if (!self) + LUMIERA_DIE (EERROR); - return err; + self->err = NULL; + self->extra = NULL; + pthread_setspecific (lumiera_error_tls, self); + } + + return self; +} + + +lumiera_err +lumiera_error_set (lumiera_err nerr, const char* extra) +{ + LumieraErrorcontext self = lumiera_error_get (); + + if (!self->err) + { + self->err = nerr; + free (self->extra); + if (extra) + self->extra = strdup (extra); + else + self->extra = NULL; + } + + return self->err; } lumiera_err lumiera_error (void) { - if (lumiera_error_initialized == PTHREAD_ONCE_INIT) - pthread_once (&lumiera_error_initialized, lumiera_error_tls_init); + LumieraErrorcontext self = lumiera_error_get (); + lumiera_err err = self->err; - lumiera_err err = pthread_getspecific (lumiera_error_tls); if (err) - pthread_setspecific (lumiera_error_tls, NULL); + self->err = NULL; return err; } +const char* +lumiera_error_extra (void) +{ + return lumiera_error_get ()->extra; +} + lumiera_err lumiera_error_peek (void) { - if (lumiera_error_initialized == PTHREAD_ONCE_INIT) - pthread_once (&lumiera_error_initialized, lumiera_error_tls_init); - - return pthread_getspecific (lumiera_error_tls); + return lumiera_error_get ()->err; } diff --git a/src/lib/error.h b/src/lib/error.h index 5ad8a3142..b6fb8a416 100644 --- a/src/lib/error.h +++ b/src/lib/error.h @@ -67,19 +67,30 @@ lumiera_err LUMIERA_ERROR_##err = "LUMIERA_ERROR_" #err ":" msg * @param flag NoBug flag describing the subsystem where the error was raised * @param err name of the error without the 'LUMIERA_ERROR_' prefix (example: NO_MEMORY) */ -#define LUMIERA_ERROR_SET(flag, err) \ -(({ERROR (flag, "%s", strchr(LUMIERA_ERROR_##err, ':')+1);}), \ -lumiera_error_set(LUMIERA_ERROR_##err)) +#define LUMIERA_ERROR_SET(flag, err, extra) \ + do { \ + const char* theextra = extra; \ + ERROR (flag, "%s%s%s", strchr(LUMIERA_ERROR_##err, ':')+1, theextra?": ":"", theextra?theextra:""); \ + lumiera_error_set(LUMIERA_ERROR_##err, theextra); \ + } while (0) /** * Set error state for the current thread. * If the error state of the current thread was cleared, then set it, else preserve the old state. * @param nerr name of the error with 'LUMIERA_ERROR_' prefix (example: LUMIERA_ERROR_NO_MEMORY) - * @return old state, that is NULL for success, when the state was cleared and a pointer to a pending + * @param extra a string (possibly a constructed tmpbuf) which adds some more context to the error occured this will be copied + * @return old state, that is NULL for success, when the state was cleared and a pointer to a pending * error when the error state was already set */ lumiera_err -lumiera_error_set (lumiera_err err); +lumiera_error_set (lumiera_err nerr, const char* extra); + +/** + * Query the extra context for the last error + * @return the extra string from the last error + */ +const char* +lumiera_error_extra (void); /** * Get and clear current error state. diff --git a/src/lib/exception.cpp b/src/lib/exception.cpp index 3514528bb..d59928025 100644 --- a/src/lib/exception.cpp +++ b/src/lib/exception.cpp @@ -79,7 +79,7 @@ namespace lumiera { desc_ (description), cause_ ("") { - lumiera_error_set (this->id_); + lumiera_error_set (this->id_, description.c_str ()); } @@ -91,7 +91,7 @@ namespace lumiera { desc_ (description), cause_ (extractCauseMsg(cause)) { - lumiera_error_set (this->id_); + lumiera_error_set (this->id_, description.c_str ()); } diff --git a/src/lib/lifecycle.cpp b/src/lib/lifecycle.cpp new file mode 100644 index 000000000..2a0a5f099 --- /dev/null +++ b/src/lib/lifecycle.cpp @@ -0,0 +1,101 @@ +/* + Lifecycle - registering and triggering lifecycle callbacks + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + + +#include "lib/error.hpp" +#include "include/lifecycle.h" +#include "lib/lifecycleregistry.hpp" +#include "lib/util.hpp" + +using util::cStr; + + + +namespace lumiera { + + + // ==== implementation LifecycleHook class ======= + + typedef LifecycleRegistry::Hook Callback; + + + LifecycleHook::LifecycleHook (Symbol eventLabel, Callback callbackFun) + { + add (eventLabel,callbackFun); + } + + void + LifecycleHook::add (Symbol eventLabel, Callback callbackFun) + { + bool isNew = LifecycleRegistry::instance().enroll (eventLabel,callbackFun); + + if (isNew && !strcmp(ON_BASIC_INIT, eventLabel)) + callbackFun(); // when this code executes, + // then per definition we are already post "basic init" + // (which happens in the AppState ctor); thus fire it immediately + } + + + void + LifecycleHook::trigger (Symbol eventLabel) + { + LifecycleRegistry::instance().execute (eventLabel); + } + + + + Symbol ON_BASIC_INIT ("ON_BASIC_INIT"); + Symbol ON_GLOBAL_INIT ("ON_GLOBAL_INIT"); + Symbol ON_GLOBAL_SHUTDOWN ("ON_GLOBAL_SHUTDOWN"); + + Symbol ON_EMERGENCY ("ON_EMERGENCY"); + + +} // namespace lumiera + + +extern "C" { /* ==== implementation C interface for lifecycle hooks ======= */ + + + extern const char * lumiera_ON_BASIC_INIT = lumiera::ON_BASIC_INIT; + extern const char * lumiera_ON_GLOBAL_INIT = lumiera::ON_GLOBAL_INIT; + extern const char * lumiera_ON_GLOBAL_SHUTDOWN = lumiera::ON_GLOBAL_SHUTDOWN; + + extern const char * lumiera_ON_EMERGENCY = lumiera::ON_EMERGENCY; + + + + void + lumiera_LifecycleHook_add (const char* eventLabel, void callbackFun(void)) + { + lumiera::LifecycleHook (eventLabel, callbackFun); + } + + + void + lumiera_Lifecycle_trigger (const char* eventLabel) + { + lumiera::LifecycleRegistry::instance().execute (eventLabel); + } + +} + diff --git a/src/lib/lifecycleregistry.hpp b/src/lib/lifecycleregistry.hpp index 7a9c603e2..4e1bcef7c 100644 --- a/src/lib/lifecycleregistry.hpp +++ b/src/lib/lifecycleregistry.hpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include "lib/util.hpp" @@ -49,6 +50,7 @@ namespace lumiera { + using boost::scoped_ptr; using boost::noncopyable; using std::tr1::function; using util::contains; @@ -89,11 +91,25 @@ namespace lumiera { } + /** get the (single) LifecycleRegistry instance. + * @warning don't use it after the end of main()! */ + static LifecycleRegistry& instance() // Meyer's singleton + { + static scoped_ptr theRegistry_; + if (!theRegistry_) theRegistry_.reset (new LifecycleRegistry ()); + return *theRegistry_; + } + + private: std::map table_; - LifecycleRegistry () {} - friend class AppState; + LifecycleRegistry () { + execute (ON_BASIC_INIT); // just to be sure, typically a NOP, because nothing is registered yet + } + + ~LifecycleRegistry () {} + friend void boost::checked_delete(LifecycleRegistry*); }; diff --git a/src/common/nobugcfg.cpp b/src/lib/nobugcfg.cpp similarity index 100% rename from src/common/nobugcfg.cpp rename to src/lib/nobugcfg.cpp diff --git a/src/lib/singletonfactory.hpp b/src/lib/singletonfactory.hpp index abd8a5bbf..151af7855 100644 --- a/src/lib/singletonfactory.hpp +++ b/src/lib/singletonfactory.hpp @@ -58,7 +58,7 @@ namespace lumiera { * http://www.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap04.html#tag_04_10 * @param SI the class of the Singleton instance * @param Create policy defining how to create/destroy the instance - * @oaram Life policy defining how to manage Singleton Lifecycle + * @param Life policy defining how to manage Singleton Lifecycle */ template < class SI @@ -133,12 +133,14 @@ namespace lumiera { -///// TODO: get rid of the static fields? -///// is tricky because of invoking the destructors. If we rely on instance vars, +///// Question: can we get rid of the static fields? +///// this is tricky because of invoking the destructors. If we rely on instance vars, ///// the object may already have been released when the runtime system calls the ///// destructors of static objects at shutdown. ///// It seems this would either cost us much of the flexibility or get complicated ///// to a point where we could as well implement our own Dependency Injection Manager. +///// But the whole point of my pervasive use of this singleton template is to remain +///// below this borderline of integration ("IoC yes, but avoid DI"). } // namespace lumiera #endif diff --git a/src/tool/Makefile.am b/src/tool/Makefile.am index 64f8fa182..f9445f934 100644 --- a/src/tool/Makefile.am +++ b/src/tool/Makefile.am @@ -18,10 +18,19 @@ lumitool_srcdir = $(top_srcdir)/src/tool noinst_PROGRAMS += luidgen - luidgen_CFLAGS = $(CFLAGS) -std=gnu99 -Wall -Werror luidgen_CPPFLAGS = -I$(top_srcdir)/src/ -luidgen_SOURCES = \ - $(lumitool_srcdir)/luidgen.c +luidgen_LDADD = liblumiera.la $(NOBUGMT_LUMIERA_LIBS) liblumieracommon.la liblumieraproc.la -lboost_regex-mt -lboost_program_options-mt -ldl +luidgen_SOURCES = $(lumitool_srcdir)/luidgen.c -luidgen_LDADD = liblumiera.la $(NOBUGMT_LUMIERA_LIBS) liblumieracommon.la liblumieraproc.la -lboost_regex-mt -lboost_program_options-mt -ldl + +noinst_PROGRAMS += vgsuppression +vgsuppression_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror +vgsuppression_LDADD = liblumiera.la $(NOBUGMT_LUMIERA_LIBS) -ldl liblumieracommon.la liblumieraproc.la -lboost_regex-mt -lboost_program_options-mt -ldl +vgsuppression_SOURCES = $(lumitool_srcdir)/vgsuppression.c + + +noinst_PROGRAMS += rsvg-convert +rsvg_convert_CPPFLAGS = $(AM_CPPFLAGS) $(LUMIERA_GUI_CFLAGS) -std=gnu99 -Wall -Werror +rsvg_convert_LDADD = -lcairo -lglib-2.0 -lgthread-2.0 -lrsvg-2 +rsvg_convert_SOURCES = $(lumitool_srcdir)/rsvg-convert.c diff --git a/src/tool/SConscript b/src/tool/SConscript index 2336c3553..0ca19490d 100644 --- a/src/tool/SConscript +++ b/src/tool/SConscript @@ -3,12 +3,24 @@ ## SConscript - SCons buildscript for tool subdirectory (called by SConstruct) ## -Import('env','artifacts','core') +Import('env','envGtk','artifacts','core') + +support_lib = artifacts['support'] + +vgsuppr = env.Program('#$BINDIR/vgsuppression','vgsuppression.c', LIBS=core) ## for suppressing false valgrind alarms +luidgen = env.Program('#$BINDIR/luidgen', 'luidgen.c', LIBS=support_lib) ## for rendering SVG icons (uses librsvg) + +rsvg = envGtk.Program('#$BINDIR/rsvg-convert','rsvg-convert.c') -# build the ubiquitous Hello World application (note: C source) -artifacts['tools'] = [ env.Program('#$BINDIR/hello-world','hello.c') - + env.Program('#$BINDIR/luidgen', ['luidgen.c']+core) +# build additional test and administrative tools.... +artifacts['tools'] = [ env.Program('#$BINDIR/hello-world','hello.c') #### hello world (checks C build) + env.Program('#$BINDIR/try', 'try.cpp') #### to try out some feature... + + luidgen + + vgsuppr + + rsvg ] +# Rendering the SVG Icons depends on rsvg-convert +env.Depends(artifacts['icons'], rsvg) + diff --git a/src/tool/hello.c b/src/tool/hello.c index d75f55f94..befad1f21 100644 --- a/src/tool/hello.c +++ b/src/tool/hello.c @@ -7,6 +7,8 @@ int main(int argc, char* argv[]) { - printf("hello lumiera world"); + (void)argc; + (void)argv; + printf("hello lumiera world\n"); return 0; } diff --git a/admin/rsvg-convert.c b/src/tool/rsvg-convert.c similarity index 100% rename from admin/rsvg-convert.c rename to src/tool/rsvg-convert.c diff --git a/admin/vgsuppression.c b/src/tool/vgsuppression.c similarity index 100% rename from admin/vgsuppression.c rename to src/tool/vgsuppression.c diff --git a/tests/31plugin.tests b/tests/31plugin.tests index 15f7e7a90..46844f754 100644 --- a/tests/31plugin.tests +++ b/tests/31plugin.tests @@ -10,7 +10,7 @@ export LUMIERA_PLUGIN_PATH=.libs export LUMIERA_CONFIG_PATH=./ TEST "discovering plugins" plugin_discover < - -#include "hello_interface.h" - -class example_plugin -{ -public: - static int myopen(void) - { - std::cout << "opened" << std::endl; - return 0; - } - - static int myclose(void) - { - std::cout << "closed" << std::endl; - return 0; - } -}; - -class example_plugin_de - : public example_plugin -{ -public: - static void hello(void) - { - std::cout << "Hallo Welt!" << std::endl; - } - - static void bye(const char* m) - { - std::cout << "Tschuess " << m << std::endl; - } -}; - - -class example_plugin_en - : public example_plugin -{ -public: - static void hello(void) - { - std::cout << "Hello World!" << std::endl; - } - - static void bye(const char* m) - { - std::cout << "Bye " << m << std::endl; - } -}; - - -LUMIERA_INTERFACE_IMPLEMENT(hello, 1, german, example_plugin_de::myopen, example_plugin_de::myclose, - example_plugin_de::hello, - example_plugin_de::bye - ); - -LUMIERA_INTERFACE_IMPLEMENT(hello, 1, english, example_plugin_en::myopen, example_plugin_en::myclose, - example_plugin_en::hello, - example_plugin_en::bye - ); diff --git a/tests/plugin/example_plugin.c b/tests/plugin/examplepluginc/example_plugin.c similarity index 100% rename from tests/plugin/example_plugin.c rename to tests/plugin/examplepluginc/example_plugin.c diff --git a/tests/plugin/test-cpp-plugin/example_plugin.cpp b/tests/plugin/test-cpp-plugin/example_plugin.cpp new file mode 100644 index 000000000..b99d951d3 --- /dev/null +++ b/tests/plugin/test-cpp-plugin/example_plugin.cpp @@ -0,0 +1,129 @@ +/* + example_plugin.cpp - example plugin (C++) for testing the interface/plugin system + + Copyright (C) Lumiera.org + 2008, Christian Thaeter , + Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + + +#include +#include + +#include "common/interfacedescriptor.h" +#include "common/config_interface.h" + +extern "C" { +#include "common/interface.h" +#include "common/interfacedescriptor.h" + +#include "tests/common/hello_interface.h" +} + +using boost::format; +using std::cout; +using std::endl; + + + +class example_plugin + { + public: + static LumieraInterface + myopen (LumieraInterface self, LumieraInterface interfaces) + { + static format fmt("opened %x global interfaces %x"); + cout << fmt % self % interfaces << endl; + return self; + } + + static void + myclose (LumieraInterface) + { + std::cout << "closed" << endl; + } + }; + + +class example_plugin_de + : public example_plugin + { + public: + static void + griazi () + { + std::cout << "Hallo Welt!" << endl; + } + + static void + servus (const char* m) + { + std::cout << "Tschuess " << m << endl; + } + }; + + +class example_plugin_en + : public example_plugin + { + public: + static void + hello () + { + std::cout << "Hello World!" << endl; + } + + static void + bye (const char* m) + { + std::cout << "Bye " << m << endl; + } + }; + + + + +extern "C" { /* ================== define two lumieraorg_testhello instance ======================= */ + + + + LUMIERA_EXPORT( /* ===================== PLUGIN EXPORTS ================================== */ + + LUMIERA_INTERFACE_DEFINE (lumieraorg_testhello, 0 + ,lumieraorg_hello_german_cpp + , NULL /* no descriptor given */ + , example_plugin::myopen + , example_plugin::myclose + , LUMIERA_INTERFACE_MAP (hello, "\300\244\125\265\235\312\175\263\335\044\371\047\247\263\015\322", + example_plugin_de::griazi) + , LUMIERA_INTERFACE_MAP (goodbye, "\115\365\126\102\201\104\012\257\153\232\006\210\010\346\076\070", + example_plugin_de::servus) + ), + LUMIERA_INTERFACE_DEFINE (lumieraorg_testhello, 0 + ,lumieraorg_hello_english_cpp + , NULL /* no descriptor given */ + , example_plugin::myopen + , example_plugin::myclose + , LUMIERA_INTERFACE_MAP (hello, "\303\367\107\154\077\063\237\066\034\034\050\136\170\220\260\226", + example_plugin_en::hello) + , LUMIERA_INTERFACE_MAP (goodbye, "\107\207\072\105\101\102\150\201\322\043\104\110\232\023\205\161", + example_plugin_en::bye) + ) + ); + +} // extern "C"