From bd6436e43b8c5471dc83fbcf9428a44cc016b1b5 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 12 Jan 2009 11:42:03 +0100 Subject: [PATCH 01/10] SCons: implement logic to find source trees, which than can be built as plugin --- admin/scons/Buildhelper.py | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/admin/scons/Buildhelper.py b/admin/scons/Buildhelper.py index a8a76a600..cfde75994 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, From d4c9e413e0b38df37c1a4c777fe3d38b901dbae3 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 12 Jan 2009 12:46:49 +0100 Subject: [PATCH 02/10] move test plugins, fix the old C++ plugin example to make it compile again --- tests/Makefile.am | 2 +- tests/plugin/example_plugin.cpp | 61 --------- .../{ => examplepluginc}/example_plugin.c | 0 .../plugin/test-cpp-plugin/example_plugin.cpp | 129 ++++++++++++++++++ 4 files changed, 130 insertions(+), 62 deletions(-) delete mode 100644 tests/plugin/example_plugin.cpp rename tests/plugin/{ => examplepluginc}/example_plugin.c (100%) create mode 100644 tests/plugin/test-cpp-plugin/example_plugin.cpp diff --git a/tests/Makefile.am b/tests/Makefile.am index 8c9876412..e1f01fc90 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -76,7 +76,7 @@ test_config_LDADD = \ check_LTLIBRARIES += examplepluginc.la -examplepluginc_la_SOURCES = $(tests_srcdir)/plugin/example_plugin.c +examplepluginc_la_SOURCES = $(tests_srcdir)/plugin/examplepluginc/example_plugin.c examplepluginc_la_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -DLUMIERA_PLUGIN -I$(top_srcdir)/src/ examplepluginc_la_LDFLAGS = -module -avoid-version -no-undefined -rpath /dev/null diff --git a/tests/plugin/example_plugin.cpp b/tests/plugin/example_plugin.cpp deleted file mode 100644 index aba34b44a..000000000 --- a/tests/plugin/example_plugin.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include - -#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" From ac156231ac8c6d23868ddceb4fc5fe1c7c004a58 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 12 Jan 2009 12:48:14 +0100 Subject: [PATCH 03/10] SCons: use new plugin building rule for the test plugins --- SConstruct | 11 ++++++++--- admin/scons/Buildhelper.py | 2 +- tests/SConscript | 30 ++++++------------------------ 3 files changed, 15 insertions(+), 28 deletions(-) diff --git a/SConstruct b/SConstruct index e38511152..c2c9f3a4c 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 @@ -336,12 +338,15 @@ def defineBuildTargets(env, artifacts): artifacts['lumiera'] = env.Program('$BINDIR/lumiera', ['$SRCDIR/lumiera/main.cpp'], LIBS=core) artifacts['corelib'] = core - + # 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 = 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') @@ -362,7 +367,7 @@ def defineBuildTargets(env, artifacts): # 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=[TESTDIR], exports='env envPlu artifacts core') diff --git a/admin/scons/Buildhelper.py b/admin/scons/Buildhelper.py index cfde75994..159dc4721 100644 --- a/admin/scons/Buildhelper.py +++ b/admin/scons/Buildhelper.py @@ -151,7 +151,7 @@ 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) + return [env.LoadableModule( '#$PLUGDIR/%s' % getDirname(tree) , srcSubtree(env, tree) , SHLIBPREFIX='', SHLIBSUFFIX='.lum' ) diff --git a/tests/SConscript b/tests/SConscript index a6a4457cd..e914ca001 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -8,12 +8,15 @@ from os import path from Buildhelper import srcSubtree from Buildhelper import scanSubtree from Buildhelper import globRootdirs +from Buildhelper import createPlugins -Import('env','artifacts','core') +Import('env','envPlu','artifacts','core') # temp fix to add test.h -- wouldn't it be better to put this header be into src/lib ? env = env.Clone() env.Append(CPPPATH='#/.') # add Rootdir to Includepath, so test/test.h is found +envPlu = envPlu.Clone() +envPlu.Append(CPPPATH='#/.') # temp fix------------- def testExecutable(env,tree, exeName=None, obj=None): @@ -43,39 +46,18 @@ def testCollection(env,dir): return [buildIt(f) for f in scanSubtree(dir,srcpatt)] -def treatPluginTestcase(env): - """ Special case: the test-plugin executable - """ - tree = 'plugin' - env = env.Clone() - env.Append(CPPPATH=tree, CPPDEFINES='LUMIERA_PLUGIN') - prfx = path.join(tree,'example_plugin') - oC = env.SharedObject(prfx, prfx+'.c') - oCPP = env.SharedObject(prfx+'_cpp', prfx+'.cpp') - testplugin = ( env.LoadableModule('#$LIBDIR/examplepluginc', oC, SHLIBPREFIX='') -# + env.SharedLibrary('#$LIBDIR/exampleplugincpp', oCPP, SHLIBPREFIX='') -# doesn't compile yet... - ) - - return testplugin - #-- it depends (at the moment) on a specific isolated test-plugin, - # which is not integrated in the "normal procedure" for building Plugins - # (which is not yet implemented as of 8/07) - # TODO: handle this case automatically -# -# build a Test-Executable out of every subdir... -moduledirs = globRootdirs('*') # but have to treat some subdirs individually. specials = ['plugin','lib','components'] +moduledirs = globRootdirs('*') artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in ['lib','components'] ] - + treatPluginTestcase(env) + [ testCollection(env, dir) for dir in moduledirs if not dir in specials] + + createPlugins(envPlu, 'plugin') ) From 1b9580b1d480c9f14bcafcf36e02d478862bf11d Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 13 Jan 2009 11:52:04 +0100 Subject: [PATCH 04/10] SCons: define lib dependencies more fine grained (core, lib, app+lib etc) --- SConstruct | 19 +++++++++---------- src/tool/SConscript | 3 ++- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/SConstruct b/SConstruct index c2c9f3a4c..97e232ef5 100644 --- a/SConstruct +++ b/SConstruct @@ -324,19 +324,18 @@ 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() diff --git a/src/tool/SConscript b/src/tool/SConscript index 2336c3553..0b6a84291 100644 --- a/src/tool/SConscript +++ b/src/tool/SConscript @@ -5,10 +5,11 @@ Import('env','artifacts','core') +support_lib = artifacts['support'] # 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) + + env.Program('#$BINDIR/luidgen', ['luidgen.c'] + support_lib) + env.Program('#$BINDIR/try', 'try.cpp') #### to try out some feature... ] From bdffc18101417c127867fe9794daae6bff4921b3 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 13 Jan 2009 12:16:48 +0100 Subject: [PATCH 05/10] move all tools to src/tool and remove admin dir from build --- Makefile.am | 3 --- SConstruct | 17 ++++++++--------- admin/Makefile.am | 28 ---------------------------- admin/SConscript | 17 ----------------- src/tool/Makefile.am | 17 +++++++++++++---- src/tool/SConscript | 19 +++++++++++++++---- src/tool/hello.c | 4 +++- {admin => src/tool}/rsvg-convert.c | 0 {admin => src/tool}/vgsuppression.c | 0 9 files changed, 39 insertions(+), 66 deletions(-) delete mode 100644 admin/Makefile.am delete mode 100644 admin/SConscript rename {admin => src/tool}/rsvg-convert.c (100%) rename {admin => src/tool}/vgsuppression.c (100%) 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 97e232ef5..8a2316996 100644 --- a/SConstruct +++ b/SConstruct @@ -344,10 +344,10 @@ def defineBuildTargets(env, artifacts): # the Lumiera GTK 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') + 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') @@ -356,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 envPlu 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/src/tool/Makefile.am b/src/tool/Makefile.am index 64f8fa182..3d5599bdb 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 = $(admin_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 = $(admin_srcdir)/rsvg-convert.c diff --git a/src/tool/SConscript b/src/tool/SConscript index 0b6a84291..0ca19490d 100644 --- a/src/tool/SConscript +++ b/src/tool/SConscript @@ -3,13 +3,24 @@ ## SConscript - SCons buildscript for tool subdirectory (called by SConstruct) ## -Import('env','artifacts','core') +Import('env','envGtk','artifacts','core') support_lib = artifacts['support'] -# build the ubiquitous Hello World application (note: C source) -artifacts['tools'] = [ env.Program('#$BINDIR/hello-world','hello.c') - + env.Program('#$BINDIR/luidgen', ['luidgen.c'] + support_lib) +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 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 From d37bb1756652872af8deeb24fb784990db423a5f Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Tue, 13 Jan 2009 21:23:37 +0100 Subject: [PATCH 06/10] Add a context string to the error system lumiera_error_set() now takes an optional extra string which can be used to pass context relevant data along. This string gets copied into the error state so one can easily create it by the tmpbuf_snprintf() facility. Also a lot of places which define errors get fixed according to this. --- src/backend/file.c | 2 +- src/backend/filedescriptor.c | 6 +-- src/backend/filehandle.c | 6 +-- src/backend/filehandlecache.c | 2 +- src/backend/mmap.c | 4 +- src/common/config.c | 4 +- src/common/config_typed.c | 12 ++--- src/common/configitem.c | 10 ++-- src/common/plugin.c | 4 +- src/common/plugin_dynlib.c | 13 ++--- src/gui/notification-service.cpp | 4 +- src/lib/error.c | 82 ++++++++++++++++++++++++++------ src/lib/error.h | 21 ++++++-- src/lib/exception.cpp | 4 +- tests/library/test-error.c | 6 +-- 15 files changed, 118 insertions(+), 62 deletions(-) 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/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/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/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/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/tests/library/test-error.c b/tests/library/test-error.c index 0133c2b4c..0a2d418a4 100644 --- a/tests/library/test-error.c +++ b/tests/library/test-error.c @@ -35,7 +35,7 @@ main (int argc, char** argv) if (!strcmp(argv[1], "set")) { - lumiera_error_set (LUMIERA_ERROR_TEST); + lumiera_error_set (LUMIERA_ERROR_TEST, NULL); } if (!strcmp(argv[1], "get_no")) @@ -47,7 +47,7 @@ main (int argc, char** argv) if (!strcmp(argv[1], "get")) { - lumiera_error_set (LUMIERA_ERROR_TEST); + lumiera_error_set (LUMIERA_ERROR_TEST, NULL); const char* err; err = lumiera_error (); printf ("%s\n", err); @@ -55,7 +55,7 @@ main (int argc, char** argv) if (!strcmp(argv[1], "get2")) { - lumiera_error_set (LUMIERA_ERROR_TEST); + lumiera_error_set (LUMIERA_ERROR_TEST, NULL); const char* err; err = lumiera_error (); printf ("%s\n", err); From e8469d5552a4a18004f8ca1fe9d5b690df43c2f0 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Wed, 14 Jan 2009 12:15:13 +0100 Subject: [PATCH 07/10] chaninsaw surgery to resolve the most urgent dependency problems with lib --- src/common/Makefile.am | 5 +- src/common/appstate.cpp | 103 ++++------------------- src/common/appstate.hpp | 10 --- src/{lib => common}/external/libgavl.cpp | 2 +- src/{lib => common}/external/libgavl.hpp | 0 src/lib/Makefile.am | 4 +- src/lib/lifecycle.cpp | 101 ++++++++++++++++++++++ src/lib/lifecycleregistry.hpp | 20 ++++- src/{common => lib}/nobugcfg.cpp | 0 src/lib/singletonfactory.hpp | 8 +- tests/lib/lifecycletest.cpp | 14 ++- tests/lib/mainsuite.cpp | 7 +- 12 files changed, 156 insertions(+), 118 deletions(-) rename src/{lib => common}/external/libgavl.cpp (98%) rename src/{lib => common}/external/libgavl.hpp (100%) create mode 100644 src/lib/lifecycle.cpp rename src/{common => lib}/nobugcfg.cpp (100%) 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/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/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/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/tests/lib/lifecycletest.cpp b/tests/lib/lifecycletest.cpp index e93d5e7d7..b3f909965 100644 --- a/tests/lib/lifecycletest.cpp +++ b/tests/lib/lifecycletest.cpp @@ -25,15 +25,13 @@ #include "lib/test/run.hpp" #include "lib/util.hpp" -#include "common/appstate.hpp" +#include "include/lifecycle.h" -namespace lumiera - { - namespace test - { +namespace lumiera { + namespace test { uint basicInit (0); uint customCallback (0); @@ -41,13 +39,13 @@ namespace lumiera void basicInitHook () { ++basicInit; } void myCallback() { ++customCallback; } - Symbol MY_MAGIC_MEGA_EVENT = "dial M for murder"; + Symbol MY_DEADLY_EVENT = "dial M for murder"; namespace // register them to be invoked by lifecycle event id { LifecycleHook _schedule1 (ON_BASIC_INIT, &basicInitHook); - LifecycleHook _schedule2 (MY_MAGIC_MEGA_EVENT, &myCallback); + LifecycleHook _schedule2 (MY_DEADLY_EVENT, &myCallback); } @@ -64,7 +62,7 @@ namespace lumiera ASSERT (1 == basicInit, "the basic-init callback has been invoked more than once"); ASSERT (!customCallback); - AppState::lifecycle (MY_MAGIC_MEGA_EVENT); + LifecycleHook::trigger (MY_DEADLY_EVENT); ASSERT ( 1 == customCallback); } diff --git a/tests/lib/mainsuite.cpp b/tests/lib/mainsuite.cpp index a23e37b7f..a49d99317 100644 --- a/tests/lib/mainsuite.cpp +++ b/tests/lib/mainsuite.cpp @@ -23,10 +23,9 @@ #include "lib/test/suite.hpp" #include "lib/test/testoption.hpp" -#include "common/appstate.hpp" #include "include/lifecycle.h" -using lumiera::AppState; +using lumiera::LifecycleHook; using lumiera::ON_GLOBAL_INIT; using lumiera::ON_GLOBAL_SHUTDOWN; @@ -40,13 +39,13 @@ int main (int argc, const char* argv[]) util::Cmdline args (argc,argv); test::TestOption optparser (args); test::Suite suite (optparser.getTestgroup()); - AppState::lifecycle(ON_GLOBAL_INIT); + LifecycleHook::trigger (ON_GLOBAL_INIT); if (optparser.getDescribe()) suite.describe(); else suite.run (args); - AppState::lifecycle(ON_GLOBAL_SHUTDOWN); + LifecycleHook::trigger (ON_GLOBAL_SHUTDOWN); return 0; } From 9cfa0e5522a4da0e86c73cb06987e27f77f6b6bd Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Wed, 14 Jan 2009 12:28:24 +0100 Subject: [PATCH 08/10] push starting of the GUI thread down into the gui plugin --- src/common/guifacade.cpp | 4 +--- src/gui/guistart.cpp | 13 +++++++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) 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/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 From bb1d9426cd15b203ae5eeecdedf099477e41cf8c Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Wed, 14 Jan 2009 12:43:27 +0100 Subject: [PATCH 09/10] Fix Plugin test --- tests/31plugin.tests | 2 +- tests/common/test-interfaces.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 < Date: Wed, 14 Jan 2009 21:10:30 +0100 Subject: [PATCH 10/10] path fix for Autotools --- src/tool/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tool/Makefile.am b/src/tool/Makefile.am index 3d5599bdb..f9445f934 100644 --- a/src/tool/Makefile.am +++ b/src/tool/Makefile.am @@ -27,10 +27,10 @@ luidgen_SOURCES = $(lumitool_srcdir)/luidgen.c 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 = $(admin_srcdir)/vgsuppression.c +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 = $(admin_srcdir)/rsvg-convert.c +rsvg_convert_SOURCES = $(lumitool_srcdir)/rsvg-convert.c