diff --git a/SConstruct b/SConstruct index 19063b865..58b47e4dc 100644 --- a/SConstruct +++ b/SConstruct @@ -27,6 +27,7 @@ OPTIONSCACHEFILE = 'optcache' CUSTOPTIONSFILE = 'custom-options' SRCDIR = 'src' BINDIR = 'bin' +LIBDIR = '.libs' TESTDIR = 'tests' ICONDIR = 'icons' VERSION = '0.1+pre.01' @@ -63,26 +64,37 @@ def setupBasicEnvironment(): ,toolpath = [TOOLDIR] ,tools = ["default", "BuilderGCH", "BuilderDoxygen"] ) + env.Tool("ToolDistCC") + env.Tool("ToolCCache") + handleVerboseMessages(env) - env.Append ( CCCOM=' -std=gnu99') # workaround for a bug: CCCOM currently doesn't honor CFLAGS, only CCFLAGS + env.Append ( CCCOM=' -std=gnu99') + env.Append ( SHCCCOM=' -std=gnu99') # workaround for a bug: CCCOM currently doesn't honour CFLAGS, only CCFLAGS env.Replace( VERSION=VERSION , SRCDIR=SRCDIR , BINDIR=BINDIR + , LIBDIR=LIBDIR , 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 - , CCFLAGS='-Wall ' # -fdiagnostics-show-option + , CCFLAGS='-Wall ' # -fdiagnostics-show-option + , CFLAGS='-std=gnu99' ) - RegisterIcon_Builder(env,SVGRENDERER) handleNoBugSwitches(env) env.Append(CPPDEFINES = '_GNU_SOURCE') appendCppDefine(env,'DEBUG','DEBUG', 'NDEBUG') # appendCppDefine(env,'OPENGL','USE_OPENGL') - appendVal(env,'ARCHFLAGS', 'CCFLAGS') # for both C and C++ - appendVal(env,'OPTIMIZE', 'CCFLAGS', val=' -O3') - appendVal(env,'DEBUG', 'CCFLAGS', val=' -ggdb') + appendVal(env,'ARCHFLAGS','CCFLAGS') # for both C and C++ + appendVal(env,'OPTIMIZE', 'CCFLAGS', val=' -O3') + appendVal(env,'DEBUG', 'CCFLAGS', val=' -ggdb') + + # setup search path for Lumiera plugins + appendCppDefine(env,'PKGLIBDIR','LUMIERA_PLUGIN_PATH=\\"$PKGLIBDIR\\"' + ,'LUMIERA_PLUGIN_PATH=\\"$DESTDIR/lib/lumiera\\"') + appendCppDefine(env,'PKGDATADIR','LUMIERA_CONFIG_PATH=\\"$PKGLIBDIR\\"' + ,'LUMIERA_CONFIG_PATH=\\"$DESTDIR/share/lumiera\\"') prepareOptionsHelp(opts,env) opts.Save(OPTIONSCACHEFILE, env) @@ -90,13 +102,13 @@ def setupBasicEnvironment(): def appendCppDefine(env,var,cppVar, elseVal=''): if env[var]: - env.Append(CPPDEFINES = cppVar ) + env.Append(CPPDEFINES = env.subst(cppVar) ) elif elseVal: - env.Append(CPPDEFINES = elseVal) + env.Append(CPPDEFINES = env.subst(elseVal)) def appendVal(env,var,targetVar,val=None): if env[var]: - env.Append( **{targetVar: val or env[var]}) + env.Append( **{targetVar: env.subst(val) or env[var]}) def handleNoBugSwitches(env): @@ -113,6 +125,15 @@ def handleNoBugSwitches(env): elif level == 'RELEASE': env.Replace( DEBUG = 0 ) +def handleVerboseMessages(env): + """ toggle verbose build output """ + if not env['VERBOSE']: + # SetOption('silent', True) + env['CCCOMSTR'] = env['SHCCCOMSTR'] = " Compiling $SOURCE" + env['CXXCOMSTR'] = env['SHCXXCOMSTR'] = " Compiling++ $SOURCE" + env['LINKCOMSTR'] = " Linking --> $TARGET" + env['LDMODULECOMSTR'] = " creating module [ $TARGET ]" + @@ -123,19 +144,26 @@ def defineCmdlineOptions(): """ opts = Options([OPTIONSCACHEFILE, CUSTOPTIONSFILE]) opts.AddOptions( - ('ARCHFLAGS', 'Set architecture-specific compilation flags (passed literally to gcc)','') + ('ARCHFLAGS', 'Set architecture-specific compilation flags (passed literally to gcc)','') + ,('CC', 'Set the C compiler to use.', 'gcc') + ,('CXX', 'Set the C++ compiler to use.', 'g++') + ,PathOption('CCACHE', 'Integrate with CCache', '', PathOption.PathAccept) + ,PathOption('DISTCC', 'Invoke C/C++ compiler commands through DistCC', '', PathOption.PathAccept) ,EnumOption('BUILDLEVEL', 'NoBug build level for debugging', 'ALPHA', allowed_values=('ALPHA', 'BETA', 'RELEASE')) - ,BoolOption('DEBUG', 'Build with debugging information and no optimizations', False) - ,BoolOption('OPTIMIZE', 'Build with strong optimization (-O3)', False) + ,BoolOption('DEBUG', 'Build with debugging information and no optimisations', False) + ,BoolOption('OPTIMIZE', 'Build with strong optimisation (-O3)', False) ,BoolOption('VALGRIND', 'Run Testsuite under valgrind control', True) + ,BoolOption('VERBOSE', 'Print full build commands', False) ,('TESTSUITES', 'Run only Testsuites matching the given pattern', '') # ,BoolOption('OPENGL', 'Include support for OpenGL preview rendering', False) # ,EnumOption('DIST_TARGET', 'Build target architecture', 'auto', # allowed_values=('auto', 'i386', 'i686', 'x86_64' ), ignorecase=2) ,PathOption('DESTDIR', 'Installation dir prefix', '/usr/local') + ,PathOption('PKGLIBDIR', 'Installation dir for plugins, defaults to DESTDIR/lib/lumiera', '',PathOption.PathAccept) + ,PathOption('PKGDATADIR', 'Installation dir for default config, usually DESTDIR/share/lumiera', '',PathOption.PathAccept) ,PathOption('SRCTAR', 'Create source tarball prior to compiling', '..', PathOption.PathAccept) - ,PathOption('DOCTAR', 'Create tarball with dev documentaionl', '..', PathOption.PathAccept) + ,PathOption('DOCTAR', 'Create tarball with developer documentation', '..', PathOption.PathAccept) ) return opts @@ -153,7 +181,7 @@ Special Targets: build : just compile and link testcode: additionally compile the Testsuite check : build and run the Testsuite - doc : generate documetation (Doxygen) + doc : generate documentation (Doxygen) install : install created artifacts at PREFIX src.tar : create source tarball doc.tar : create developer doc tarball @@ -215,7 +243,6 @@ def configurePlatform(env): if not conf.CheckLibWithHeader('boost_regex-mt','boost/regex.hpp','C++'): problems.append('We need the boost regular expression lib (incl. binary lib for linking).') -# if not conf.CheckLibWithHeader('gavl', ['gavlconfig.h', 'gavl/gavl.h'], 'C'): if not conf.CheckPkgConfig('gavl', 1.0): problems.append('Did not find Gmerlin Audio Video Lib [http://gmerlin.sourceforge.net/gavl.html].') @@ -232,13 +259,16 @@ def configurePlatform(env): problems.append('Unable to configure Cairo--, exiting.') if not conf.CheckPkgConfig('gdl-1.0', '0.6.1'): - problems.append('Unable to configure the GNOME DevTool Library, exiting.') + problems.append('Unable to configure the GNOME DevTool Library.') if not conf.CheckPkgConfig('librsvg-2.0', '2.18.1'): problems.append('Need rsvg Library for rendering icons.') - if not conf.CheckPkgConfig('xv'): problems.append('Need lib xv') -# if not conf.CheckPkgConfig('xext'): Exit(1) + if not conf.CheckCHeader(['X11/Xutil.h', 'X11/Xlib.h'],'<>'): + problems.append('Xlib.h and Xutil.h required. Please install libx11-dev.') + + if not conf.CheckPkgConfig('xv') : problems.append('Need libXv...') + if not conf.CheckPkgConfig('xext'): problems.append('Need libXext.') # if not conf.CheckPkgConfig('sm'): Exit(1) # # obviously not needed? @@ -287,23 +317,27 @@ def defineBuildTargets(env, artifacts): # + env.PrecompiledHeader('$SRCDIR/pre_a.hpp') # ) - objback = srcSubtree(env,'$SRCDIR/backend') - objproc = srcSubtree(env,'$SRCDIR/proc') - objlib = ( srcSubtree(env,'$SRCDIR/common') - + srcSubtree(env,'$SRCDIR/lib') - ) - objplug = srcSubtree(env,'$SRCDIR/plugin', isShared=True) - core = ( env.StaticLibrary('$BINDIR/lumiback.la', objback) - + env.StaticLibrary('$BINDIR/lumiproc.la', objproc) - + env.StaticLibrary('$BINDIR/lumiera.la', objlib) + 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) ) + artifacts['lumiera'] = env.Program('$BINDIR/lumiera', ['$SRCDIR/lumiera/main.cpp'], LIBS=core) + artifacts['corelib'] = core + + + artifacts['plugins'] = [] # currently none - artifacts['lumiera'] = env.Program('$BINDIR/lumiera', ['$SRCDIR/main.cpp']+ core ) - artifacts['plugins'] = env.SharedLibrary('$BINDIR/lumiera-plugin', objplug) # 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') # render and install Icons @@ -313,7 +347,9 @@ def defineBuildTargets(env, artifacts): + [env.IconCopy(f) for f in scanSubtree(prerendered_icon_dir, ['*.png'])] ) - artifacts['lumigui'] = ( envgtk.Program('$BINDIR/lumigui', objgui + core) + guimodule = envgtk.LoadableModule('$LIBDIR/gtk_gui', objgui, SHLIBPREFIX='', SHLIBSUFFIX='.lum') + artifacts['lumigui'] = ( guimodule + + envgtk.Program('$BINDIR/lumigui', objgui ) + env.Install('$BINDIR', env.Glob('$SRCDIR/gui/*.rc')) + artifacts['icons'] ) @@ -349,6 +385,7 @@ def defineInstallTargets(env, artifacts): """ define some artifacts to be installed into target locations. """ env.Install(dir = '$DESTDIR/bin', source=artifacts['lumiera']) + env.Install(dir = '$DESTDIR/lib', source=artifacts['corelib']) env.Install(dir = '$DESTDIR/lib', source=artifacts['plugins']) env.Install(dir = '$DESTDIR/bin', source=artifacts['tools']) diff --git a/admin/SConscript b/admin/SConscript index d0ad7b84e..2737bab7e 100644 --- a/admin/SConscript +++ b/admin/SConscript @@ -8,7 +8,7 @@ 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 supressing false valgrind alarms +artifacts['tools'] += [ vgsuppr ## for suppressing false valgrind alarms + rsvg ## for rendering SVG icons (uses librsvg) ] diff --git a/admin/gnu-indent.sh b/admin/gnu-indent.sh deleted file mode 100644 index 7d4d79b43..000000000 --- a/admin/gnu-indent.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -# -# gnu-indent -- call the "indent" tool with parameters suitable for GNU coding style -# -indent -nbad -bap -nbc -bbo -bl -bli2 -bls -ncdb -nce -cp1 -cs -di2 -ndj -nfc1 -nfca -hnl -i2 -ip5 -lp -pcs -psl -nsc -nsob $@ diff --git a/admin/render-icon.py b/admin/render-icon.py index 26bdb3653..4b0d464ca 100755 --- a/admin/render-icon.py +++ b/admin/render-icon.py @@ -1,5 +1,5 @@ #!/usr/bin/python - +# # render-icons.py - Icon rendering utility script # # Copyright (C) Lumiera.org @@ -20,9 +20,10 @@ # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. import sys +import os +import os.path as Path import getopt from xml.dom import minidom -import os import shutil #svgDir = "svg" @@ -32,14 +33,20 @@ rsvgPath = "./rsvg-convert" artworkLayerPrefix = "artwork:" def createDirectory( name ): - if os.path.exists(name) == False: + if Path.isfile(name): + print "WARNING: moving %s to %s.bak because it's in the way." % (name,name) + bak_name = name + ".bak" + if Path.isfile(bak_name): + os.remove(bak_name) + os.rename(name,bak_name) + if not Path.isdir(name): os.mkdir(name) - + def copyMergeDirectory( src, dst ): listing = os.listdir(src) for file_name in listing: - src_file_path = os.path.join(src, file_name) - dst_file_path = os.path.join(dst, file_name) + src_file_path = Path.join(src, file_name) + dst_file_path = Path.join(dst, file_name) shutil.copyfile(src_file_path, dst_file_path) def getDocumentSize( svg_element ): @@ -99,7 +106,7 @@ def renderSvgInkscape(file_path, out_dir, artwork_name, rectangle, doc_size): "-a %g:%g:%g:%g" % (x1, y1, x2, y2), "-w %g" % (rectangle[2]), "-h %g" % (rectangle[3]), "--export-png=" + os.path.join(out_dir, "%gx%g/%s.png" % (rectangle[2], rectangle[3], artwork_name))) - + def renderSvgRsvg(file_path, out_dir, artwork_name, rectangle, doc_size): # Prepare a Cairo context width = int(rectangle[2]) @@ -154,19 +161,23 @@ def parseArguments(argv): def main(argv): in_path, out_dir = parseArguments(argv) - if in_path == None or out_dir == None: - return + if not (in_path and out_dir): + print "Missing arguments in_path and out_dir." + sys.exit(1) - if os.path.exists(out_dir) == False: - print "Directory not found: " + out_dir - return + if Path.isfile(out_dir): + print "Unable to use '%s' as output directory, because it\'s a file." % out_dir + sys.exit(1) + if not Path.isdir(out_dir): + print "Output directory '%s' not found." % out_dir + sys.exit(1) # Create the icons folders - createDirectory(os.path.join(out_dir, "48x48")) - createDirectory(os.path.join(out_dir, "32x32")) - createDirectory(os.path.join(out_dir, "24x24")) - createDirectory(os.path.join(out_dir, "22x22")) - createDirectory(os.path.join(out_dir, "16x16")) + createDirectory(Path.join(out_dir, "48x48")) + createDirectory(Path.join(out_dir, "32x32")) + createDirectory(Path.join(out_dir, "24x24")) + createDirectory(Path.join(out_dir, "22x22")) + createDirectory(Path.join(out_dir, "16x16")) renderSvgIcon(in_path, out_dir) diff --git a/admin/rsvg-convert.c b/admin/rsvg-convert.c index 7ed5a9910..655a25720 100644 --- a/admin/rsvg-convert.c +++ b/admin/rsvg-convert.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -71,7 +72,7 @@ static void display_error (GError * err) { if (err) { - g_print ("%s", err->message); + g_print ("%s\n", err->message); g_error_free (err); } } @@ -87,8 +88,9 @@ rsvg_cairo_size_callback (int *width, int *height, gpointer data) static cairo_status_t rsvg_cairo_write_func (void *closure, const unsigned char *data, unsigned int length) { - fwrite (data, 1, length, (FILE *) closure); - return CAIRO_STATUS_SUCCESS; + if (fwrite (data, 1, length, (FILE *) closure) == length) + return CAIRO_STATUS_SUCCESS; + return CAIRO_STATUS_WRITE_ERROR; } int @@ -124,6 +126,9 @@ main (int argc, char **argv) {NULL} }; + /* Set the locale so that UTF-8 filenames work */ + setlocale(LC_ALL, ""); + g_thread_init(NULL); g_option_context = g_option_context_new (_("- SVG Converter")); diff --git a/admin/scons/BuilderDoxygen.py b/admin/scons/BuilderDoxygen.py index 943fce946..a397ef32e 100644 --- a/admin/scons/BuilderDoxygen.py +++ b/admin/scons/BuilderDoxygen.py @@ -33,198 +33,197 @@ from fnmatch import fnmatch def DoxyfileParse(file_contents): - """ - Parse a Doxygen source file and return a dictionary of all the values. - Values will be strings and lists of strings. - """ - data = {} - - import shlex - lex = shlex.shlex(instream = file_contents, posix = True) - lex.wordchars += "*+./-:" - lex.whitespace = lex.whitespace.replace("\n", "") - lex.escape = "" - - lineno = lex.lineno - token = lex.get_token() - key = token # the first token should be a key - last_token = "" - key_token = False - next_key = False - new_data = True - - def append_data(data, key, new_data, token): - if new_data or len(data[key]) == 0: - data[key].append(token) - else: - data[key][-1] += token - - while token: - if token in ['\n']: - if last_token not in ['\\']: - key_token = True - elif token in ['\\']: - pass - elif key_token: - key = token - key_token = False - else: - if token == "+=": - if not data.has_key(key): + """ Parse a Doxygen source file and return a dictionary of all the values. + Values will be strings and lists of strings. + """ + data = {} + + import shlex + lex = shlex.shlex(instream = file_contents, posix = True) + lex.wordchars += "*+./-:" + lex.whitespace = lex.whitespace.replace("\n", "") + lex.escape = "" + + lineno = lex.lineno + token = lex.get_token() + key = token # the first token should be a key + last_token = "" + key_token = False + next_key = False + new_data = True + + def append_data(data, key, new_data, token): + if new_data or len(data[key]) == 0: + data[key].append(token) + else: + data[key][-1] += token + + while token: + if token in ['\n']: + if last_token not in ['\\']: + key_token = True + elif token in ['\\']: + pass + elif key_token: + key = token + key_token = False + else: + if token == "+=": + if not data.has_key(key): + data[key] = list() + elif token == "=": data[key] = list() - elif token == "=": - data[key] = list() - else: - append_data( data, key, new_data, token ) - new_data = True + else: + append_data( data, key, new_data, token ) + new_data = True + + last_token = token + token = lex.get_token() + + if last_token == '\\' and token != '\n': + new_data = False + append_data( data, key, new_data, '\\' ) + + # compress lists of len 1 into single strings + for (k, v) in data.items(): + if len(v) == 0: + data.pop(k) + + # items in the following list will be kept as lists and not converted to strings + if k in ["INPUT", "FILE_PATTERNS", "EXCLUDE_PATTERNS"]: + continue + + if len(v) == 1: + data[k] = v[0] + + return data - last_token = token - token = lex.get_token() - - if last_token == '\\' and token != '\n': - new_data = False - append_data( data, key, new_data, '\\' ) - - # compress lists of len 1 into single strings - for (k, v) in data.items(): - if len(v) == 0: - data.pop(k) - - # items in the following list will be kept as lists and not converted to strings - if k in ["INPUT", "FILE_PATTERNS", "EXCLUDE_PATTERNS"]: - continue - - if len(v) == 1: - data[k] = v[0] - - return data def DoxySourceScan(node, env, path): - """ - Doxygen Doxyfile source scanner. This should scan the Doxygen file and add - any files used to generate docs to the list of source files. - """ - default_file_patterns = [ - '*.c', '*.cc', '*.cxx', '*.cpp', '*.c++', '*.java', '*.ii', '*.ixx', - '*.ipp', '*.i++', '*.inl', '*.h', '*.hh ', '*.hxx', '*.hpp', '*.h++', - '*.idl', '*.odl', '*.cs', '*.php', '*.php3', '*.inc', '*.m', '*.mm', - '*.py', - ] - - default_exclude_patterns = [ - '*~', - ] - - sources = [] - - data = DoxyfileParse(node.get_contents()) - - if data.get("RECURSIVE", "NO") == "YES": - recursive = True - else: - recursive = False - - file_patterns = data.get("FILE_PATTERNS", default_file_patterns) - exclude_patterns = data.get("EXCLUDE_PATTERNS", default_exclude_patterns) - - # - # We're running in the top-level directory, but the doxygen - # configuration file is in the same directory as node; this means - # that relative pathnames in node must be adjusted before they can - # go onto the sources list - conf_dir = os.path.dirname(str(node)) - - for node in data.get("INPUT", []): - if not os.path.isabs(node): - node = os.path.join(conf_dir, node) - if os.path.isfile(node): - sources.append(node) - elif os.path.isdir(node): - if recursive: - for root, dirs, files in os.walk(node): - for f in files: - filename = os.path.join(root, f) - - pattern_check = reduce(lambda x, y: x or bool(fnmatch(filename, y)), file_patterns, False) - exclude_check = reduce(lambda x, y: x and fnmatch(filename, y), exclude_patterns, True) - - if pattern_check and not exclude_check: - sources.append(filename) - else: - for pattern in file_patterns: - sources.extend(glob.glob("/".join([node, pattern]))) - - sources = map( lambda path: env.File(path), sources ) - return sources + """ Doxygen Doxyfile source scanner. + This should scan the Doxygen file and add any files + used to generate docs to the list of source files. + """ + default_file_patterns = [ + '*.c', '*.cc', '*.cxx', '*.cpp', '*.c++', '*.java', '*.ii', '*.ixx', + '*.ipp', '*.i++', '*.inl', '*.h', '*.hh ', '*.hxx', '*.hpp', '*.h++', + '*.idl', '*.odl', '*.cs', '*.php', '*.php3', '*.inc', '*.m', '*.mm', + '*.py', + ] + + default_exclude_patterns = [ + '*~', + ] + + sources = [] + + data = DoxyfileParse(node.get_contents()) + + if data.get("RECURSIVE", "NO") == "YES": + recursive = True + else: + recursive = False + + file_patterns = data.get("FILE_PATTERNS", default_file_patterns) + exclude_patterns = data.get("EXCLUDE_PATTERNS", default_exclude_patterns) + + # + # We're running in the top-level directory, but the doxygen configuration file + # is in the same directory as node; this means that relative pathnames in node + # must be adjusted before they can go onto the sources list + conf_dir = os.path.dirname(str(node)) + + for node in data.get("INPUT", []): + if not os.path.isabs(node): + node = os.path.join(conf_dir, node) + if os.path.isfile(node): + sources.append(node) + elif os.path.isdir(node): + if recursive: + for root, dirs, files in os.walk(node): + for f in files: + filename = os.path.join(root, f) + + pattern_check = reduce(lambda x, y: x or bool(fnmatch(filename, y)), file_patterns, False) + exclude_check = reduce(lambda x, y: x and fnmatch(filename, y), exclude_patterns, True) + + if pattern_check and not exclude_check: + sources.append(filename) + else: + for pattern in file_patterns: + sources.extend(glob.glob("/".join([node, pattern]))) + + sources = map( lambda path: env.File(path), sources ) + return sources def DoxySourceScanCheck(node, env): - """Check if we should scan this file""" - return os.path.isfile(node.path) + """ Check if we should scan this file """ + return os.path.isfile(node.path) + def DoxyEmitter(source, target, env): - """Doxygen Doxyfile emitter""" - # possible output formats and their default values and output locations - output_formats = { - "HTML": ("YES", "html"), - "LATEX": ("YES", "latex"), - "RTF": ("NO", "rtf"), - "MAN": ("NO", "man"), - "XML": ("NO", "xml"), - } - - data = DoxyfileParse(source[0].get_contents()) - - targets = [] - out_dir = data.get("OUTPUT_DIRECTORY", ".") - - # add our output locations - for (k, v) in output_formats.items(): - if data.get("GENERATE_" + k, v[0]) == "YES": - targets.append(env.Dir( os.path.join(out_dir, data.get(k + "_OUTPUT", v[1]))) ) - - # don't clobber targets - for node in targets: - env.Precious(node) - - # set up cleaning stuff - for node in targets: - env.Clean(node, node) - - return (targets, source) + """ Doxygen Doxyfile emitter """ + # possible output formats and their default values and output locations + output_formats = { + "HTML": ("YES", "html"), + "LATEX": ("YES", "latex"), + "RTF": ("NO", "rtf"), + "MAN": ("NO", "man"), + "XML": ("NO", "xml"), + } + + data = DoxyfileParse(source[0].get_contents()) + + targets = [] + out_dir = data.get("OUTPUT_DIRECTORY", ".") + + # add our output locations + for (k, v) in output_formats.items(): + if data.get("GENERATE_" + k, v[0]) == "YES": + targets.append(env.Dir( os.path.join(out_dir, data.get(k + "_OUTPUT", v[1]))) ) + + # don't clobber targets + for node in targets: + env.Precious(node) + + # set up cleaning stuff + for node in targets: + env.Clean(node, node) + + return (targets, source) def generate(env): - """ - Add builders and construction variables for the - Doxygen tool. This is currently for Doxygen 1.4.6. - """ - doxyfile_scanner = env.Scanner( - DoxySourceScan, - "DoxySourceScan", - scan_check = DoxySourceScanCheck, - ) + """ Add builders and construction variables for the + Doxygen tool. This is currently for Doxygen 1.4.6. + """ + doxyfile_scanner = env.Scanner( + DoxySourceScan, + "DoxySourceScan", + scan_check = DoxySourceScanCheck, + ) + + import SCons.Builder + doxyfile_builder = SCons.Builder.Builder( + action = "cd ${SOURCE.dir} && (${DOXYGEN} ${SOURCE.file} 2>&1 |tee ,doxylog)", + emitter = DoxyEmitter, + target_factory = env.fs.Entry, + single_source = True, + source_scanner = doxyfile_scanner, + ) + + env.Append(BUILDERS = { + 'Doxygen': doxyfile_builder, + }) + + env.AppendUnique( + DOXYGEN = 'doxygen', + ) - import SCons.Builder - doxyfile_builder = SCons.Builder.Builder( - action = "cd ${SOURCE.dir} && (${DOXYGEN} ${SOURCE.file} 2>&1 |tee ,doxylog)", - emitter = DoxyEmitter, - target_factory = env.fs.Entry, - single_source = True, - source_scanner = doxyfile_scanner, - ) - - env.Append(BUILDERS = { - 'Doxygen': doxyfile_builder, - }) - - env.AppendUnique( - DOXYGEN = 'doxygen', - ) def exists(env): - """ - Make sure doxygen exists. - """ - return env.Detect("doxygen") + """ Make sure doxygen exists. + """ + return env.Detect("doxygen") diff --git a/admin/scons/BuilderGCH.py b/admin/scons/BuilderGCH.py index c522cb9cd..ec48edcdd 100644 --- a/admin/scons/BuilderGCH.py +++ b/admin/scons/BuilderGCH.py @@ -61,7 +61,7 @@ def setup_dependency(target,source,env, key): if header_path in [x.path for x in deps]: print "Precompiled header(%s) %s \t <--- %s" % (key,header_path,source[0]) env.Depends(target, header) - + def static_pch_emitter(target,source,env): SCons.Defaults.StaticObjectEmitter( target, source, env ) @@ -73,9 +73,9 @@ def shared_pch_emitter(target,source,env): setup_dependency(target,source,env, key='GCH-sh') return (target, source) + def generate(env): - """ - Add builders and construction variables for the Gch builder. + """ Add builders and construction variables for the Gch builder. """ env.Append(BUILDERS = { 'gch': env.Builder( @@ -87,7 +87,7 @@ def generate(env): target_factory = env.fs.File, ), }) - + try: bld = env['BUILDERS']['GCH'] bldsh = env['BUILDERS']['GCH-sh'] @@ -96,11 +96,11 @@ def generate(env): bldsh = GchShBuilder env['BUILDERS']['PrecompiledHeader'] = bld env['BUILDERS']['PrecompiledHeaderShared'] = bldsh - + env['GCHCOM'] = '$CXX -o $TARGET -x c++-header -c $CXXFLAGS $_CCCOMCOM $SOURCE' env['GCHSHCOM'] = '$CXX -o $TARGET -x c++-header -c $SHCXXFLAGS $_CCCOMCOM $SOURCE' env['GCHSUFFIX'] = '.gch' - + for suffix in SCons.Util.Split('.c .C .cc .cxx .cpp .c++'): env['BUILDERS']['StaticObject'].add_emitter( suffix, static_pch_emitter ) env['BUILDERS']['SharedObject'].add_emitter( suffix, shared_pch_emitter ) diff --git a/admin/scons/Buildhelper.py b/admin/scons/Buildhelper.py index 38940424c..a8a76a600 100644 --- a/admin/scons/Buildhelper.py +++ b/admin/scons/Buildhelper.py @@ -40,7 +40,7 @@ def isCleanupOperation(env): def isHelpRequest(): """ this is a hack: SCons does all configure tests even if only - the helpmessage is requested. SCons doesn't export the + the help message is requested. SCons doesn't export the help option for retrieval by env.GetOption(), so we scan the commandline directly. """ @@ -48,8 +48,8 @@ def isHelpRequest(): -def srcSubtree(env,tree,isShared=False,builder=None, **args): - """ convienience wrapper: scans the given subtree, which is +def srcSubtree(env,tree,isShared=True,builder=None, **args): + """ convenience wrapper: scans the given subtree, which is relative to the current SConscript, find all source files and declare them as Static or SharedObjects for compilation """ @@ -68,7 +68,7 @@ SRCPATTERNS = ['*.c','*.cpp','*.cc'] def scanSubtree(roots, patterns=SRCPATTERNS): """ first expand (possible) wildcards and filter out non-dirs. - Then scan the given subtree for source filesnames + Then scan the given subtree for source filenames (python generator function) """ for root in globRootdirs(roots): @@ -112,11 +112,47 @@ def getDirname(dir): dir,_ = os.path.split(dir) _, name = os.path.split(dir) return name + + + +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, + denoting that the system default for this command should be used. + @return: True, if the key has been expanded and validated, + False, if this failed and the key was removed + """ + if not val: + if not env.get(optID): return False + else: + val = env.get(optID) + if val=='True' or val=='true' or val=='yes' or val=='1' or val == 1 : + if not cmdName: + print "WARNING: no default for %s, please specify a full path." % optID + del env[optID] + return False + else: + val = env.WhereIs(cmdName) + if not val: + print "WARNING: %s not found, please specify a full path" % cmdName + del env[optID] + return False + + if not os.path.isfile(val): + val = env.WhereIs(val) + + if val and os.path.isfile(val): + env[optID] = val + return True + else: + del env[optID] + return False + def RegisterIcon_Builder(env, renderer): - """ Registeres Custom Builders for generating and installing Icons. + """ Registers Custom Builders for generating and installing Icons. Additionally you need to build the tool (rsvg-convert.c) used to generate png from the svg source using librsvg. """ @@ -157,7 +193,7 @@ def Tarball(env,location,dirs,suffix=''): suffix: (optional) suffix to include in the tar name dirs: directories to include in the tar - This is a bit of a hack, because we want to be able to include arbitrary dirctories, + This is a bit of a hack, because we want to be able to include arbitrary directories, without creating new dependencies on those dirs. Esp. we want to tar the source tree prior to compiling. Solution is - use the Command-Builder, but pass all target specifications as custom build vars diff --git a/admin/scons/ToolDistCC.py b/admin/scons/ToolDistCC.py new file mode 100644 index 000000000..ecc45d011 --- /dev/null +++ b/admin/scons/ToolDistCC.py @@ -0,0 +1,65 @@ +# -*- python -*- +## +## ToolDistCC.py - SCons tool for distributed compilation using DistCC +## + +# Copyright (C) Lumiera.org and FreeOrion.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. +##################################################################### + +# This SCons builder was extracted from http://www.freeorion.org/ +# FreeOrion is an open-source platform-independent galactic conquest game +# +# history: 12/2008 adapted for Lumiera build system + + +import os +from Buildhelper import * + + +def generate(env): + """ Modify the environment such as to redirect any + C/C++ compiler invocations through DistCC. Additionally + pull in the environment config variables used by DistCC + """ + if not exists(env): return + + assert env['DISTCC'] + if not env['DISTCC'] in env['CC']: + env['CC'] = env.subst('$DISTCC $CC') + if not env['DISTCC'] in env['CXX']: + env['CXX'] = env.subst('$DISTCC $CXX') + print env.subst("* Build using $DISTCC") + for i in ['HOME' + ,'DISTCC_HOSTS' + ,'DISTCC_VERBOSE' + ,'DISTCC_FALLBACK' + ,'DISTCC_LOG' + ,'DISTCC_MMAP' + ,'DISTCC_SAVE_TEMPS' + ,'DISTCC_TCP_CORK' + ,'DISTCC_SSH' + ]: + if os.environ.has_key(i) and not env.has_key(i): + env['ENV'][i] = os.environ[i] + + +def exists(env): + """ Ensure DistCC exists. + """ + return checkCommandOption(env, 'DISTCC', cmdName='distcc') + diff --git a/bin/.libs b/bin/.libs new file mode 120000 index 000000000..2e321a8e9 --- /dev/null +++ b/bin/.libs @@ -0,0 +1 @@ +../.libs \ No newline at end of file diff --git a/build/DIR_INFO b/build/DIR_INFO deleted file mode 100644 index 62f540bad..000000000 --- a/build/DIR_INFO +++ /dev/null @@ -1 +0,0 @@ -build dir diff --git a/doc/devel/Doxyfile b/doc/devel/Doxyfile index 9b276233e..02d2d787c 100644 --- a/doc/devel/Doxyfile +++ b/doc/devel/Doxyfile @@ -70,10 +70,10 @@ SORT_MEMBER_DOCS = NO SORT_BRIEF_DOCS = YES SORT_GROUP_NAMES = NO SORT_BY_SCOPE_NAME = NO -GENERATE_TODOLIST = YES -GENERATE_TESTLIST = YES -GENERATE_BUGLIST = YES -GENERATE_DEPRECATEDLIST= YES +GENERATE_TODOLIST = NO +GENERATE_TESTLIST = NO +GENERATE_BUGLIST = NO +GENERATE_DEPRECATEDLIST= NO ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES @@ -94,8 +94,7 @@ WARN_LOGFILE = warnings.txt #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- -INPUT = ../../src/ \ - ../../tests/ +INPUT = ../../src/ INPUT_ENCODING = UTF-8 FILE_PATTERNS = *.c \ *.cc \ @@ -154,7 +153,7 @@ FILTER_SOURCE_FILES = NO # configuration options related to source browsing #--------------------------------------------------------------------------- SOURCE_BROWSER = YES -INLINE_SOURCES = YES +INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES REFERENCED_BY_RELATION = YES REFERENCES_RELATION = YES diff --git a/scripts/DIR_INFO b/scripts/DIR_INFO deleted file mode 100644 index 265ca57ac..000000000 --- a/scripts/DIR_INFO +++ /dev/null @@ -1 +0,0 @@ -autotools helper scripts diff --git a/src/common/DIR_INFO b/src/common/DIR_INFO new file mode 100644 index 000000000..e3b6d818a --- /dev/null +++ b/src/common/DIR_INFO @@ -0,0 +1,7 @@ +Common application services (liblumieracommon) + +contains: + * the config system + * commandline parsing + * interfaces and plugin loading + * lua interpreter (planned) diff --git a/src/proc/nobugcfg.cpp b/src/common/nobugcfg.cpp similarity index 90% rename from src/proc/nobugcfg.cpp rename to src/common/nobugcfg.cpp index 7dc68a9bb..ecbde0e79 100644 --- a/src/proc/nobugcfg.cpp +++ b/src/common/nobugcfg.cpp @@ -21,24 +21,26 @@ * *****************************************************/ -#include "proc/nobugcfg.hpp" +#include "include/nobugcfg.h" #define NOBUG_INIT_DEFS_ -#include "proc/nobugcfg.hpp" +#include "include/nobugcfg.h" #undef NOBUG_INIT_DEFS_ -namespace lumiera - { + + +namespace lumiera { + void - initialize_NoBug () + initialise_NoBug () { NOBUG_INIT; #ifdef DEBUG static uint callCount = 0; ASSERT ( 0 == callCount++ ); -#endif +#endif } } diff --git a/src/gui/gtk-lumiera.hpp b/src/gui/gtk-lumiera.hpp index 34bf96b84..f543f1fde 100644 --- a/src/gui/gtk-lumiera.hpp +++ b/src/gui/gtk-lumiera.hpp @@ -10,6 +10,9 @@ #include #include #include +#include +#include +#include "lib/util.hpp" #include @@ -50,7 +53,7 @@ static const gchar* AppTitle = "Lumiera"; /** * The main application class. */ -class GtkLumiera +class GtkLumiera : private boost::noncopyable { public: int main(int argc, char *argv[]); diff --git a/src/gui/lumiera_ui.rc b/src/gui/lumiera_ui.rc index 9d4f4d771..dcce8df48 100644 --- a/src/gui/lumiera_ui.rc +++ b/src/gui/lumiera_ui.rc @@ -152,13 +152,13 @@ style "timeline_ruler" = "default_base" gtkmm__CustomObject_TimelineRuler::playback_period_arrow_stem_size = 3 } -style "header_container" = "default_base" +style "timeline_header_container" = "default_base" { gtkmm__CustomObject_HeaderContainer::heading_margin = 4 } class "gtkmm__CustomObject_TimelineBody" style:highest "timeline_body" class "gtkmm__CustomObject_TimelineRuler" style:highest "timeline_ruler" -class "gtkmm__CustomObject_HeaderContainer" style:highest "header_container" +class "gtkmm__CustomObject_TimelineHeaderContainer" style:highest "timeline_header_container" diff --git a/src/include/nobugcfg.h b/src/include/nobugcfg.h new file mode 100644 index 000000000..cfcedd6b7 --- /dev/null +++ b/src/include/nobugcfg.h @@ -0,0 +1,117 @@ +/* + NOBUGCFG.h - NoBug definitions and initialisation for the Proc-Layer + + + 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. + +*/ + +/** @file nobugcfg.h + ** This header is for including and configuring NoBug. + ** The idea is that configuration and some commonly used flag + ** declarations are to be kept in one central location. Subsystems + ** are free to define and use additional flags for local use. Typically, + ** this header will be included via some of the basic headers like error.hpp, + ** which in turn gets included e.g. by proc/common.hpp + ** + ** This header can thus be assumed to be effectively global. It should contain + ** only declarations of global relevance, as any change causes the whole project + ** to be rebuilt. Moreover, for C++ this header assures automatic initialisation + ** of NoBug by placing a static ctor call. + ** + ** Besides the usual guarded declarations, this header contains one section + ** with the corresponding definitions. This section is to be included once + ** by some translation unit (currently this is lumiera/nobugcfg.cpp) in order to + ** generate the necessary definitions. + ** + ** @par Logging configuration + ** By default, logging is configured such as to emit a small number of informative + ** messages on the starting terminal and to report fatal errors. But besides the + ** usual fine-grained tracing messages, we define a small number of distinct + ** thematic Logging Channels providing a consistent high-level view of + ** what is going on with regards to a specific aspect of the application + ** - \c operate documents a high-level overall view of what the application \em does + ** - \c render focuses on the working of the render engine (without logging each frame) + ** - \c config shows anything of relevance regarding the configured state of App and session + ** - \c memory allows to diagnose a high-level view of memory management + ** + ** Any log level can be overridden by an environment variable, for example + ** \code NOBUG_LOG='operate:INFO' ./lumiera \endcode + ** + ** @todo logging to files? + */ + + +#ifndef NOBUGCFG_H /* ============= Part 1: DECLARATIONS ======== */ +#define NOBUGCFG_H + +#include +#include + + +#ifdef __cplusplus /* ============= C++ ================ */ + +#include "include/lifecycle.h" +#include "include/error.hpp" ///< make assertions throw instead of abort() + +namespace lumiera { + void initialise_NoBug (); + namespace { + LifecycleHook trigger_it_ (ON_BASIC_INIT, &initialise_NoBug); +} } +#endif /* =====================(End) C++ ================ */ + + + + + /* declare flags used throughout the code base */ + NOBUG_DECLARE_FLAG (all); + NOBUG_DECLARE_FLAG (lumiera_all); + NOBUG_DECLARE_FLAG (lumiera); ///< master log, informative console output + NOBUG_DECLARE_FLAG (operate); ///< logging channel reporting what the application does + NOBUG_DECLARE_FLAG (render); ///< logging channel focusing on the render engine's workings + NOBUG_DECLARE_FLAG (config); ///< logging channel covering application and session configuration + NOBUG_DECLARE_FLAG (memory); ///< logging channel covering memory management issues + NOBUG_DECLARE_FLAG (test); + + +#endif /*NOBUGCFG_H ======= (End) Part 1: DECLARATIONS ======== */ + + + + + + +#ifdef NOBUG_INIT_DEFS_ /*========== Part 2: DEFINITIONS ========= */ + + + /* flags used throughout the code base... */ + NOBUG_CPP_DEFINE_FLAG (all); + NOBUG_CPP_DEFINE_FLAG_PARENT (lumiera_all, all); + NOBUG_CPP_DEFINE_FLAG_PARENT (lumiera, lumiera_all); + NOBUG_CPP_DEFINE_FLAG_PARENT (config, lumiera); + NOBUG_CPP_DEFINE_FLAG_PARENT (operate, lumiera); + NOBUG_CPP_DEFINE_FLAG_PARENT_LIMIT (render, lumiera, LOG_WARNING); + NOBUG_CPP_DEFINE_FLAG_PARENT_LIMIT (memory, lumiera, LOG_WARNING); + NOBUG_CPP_DEFINE_FLAG_PARENT_LIMIT (test, all, LOG_ERR); + + + + +#endif /*NOBUG_INIT_DEFS_ ==== (End) Part 2: DEFINITIONS ========= */ diff --git a/src/lumiera/DIR_INFO b/src/lumiera/DIR_INFO new file mode 100644 index 000000000..fc536d0ed --- /dev/null +++ b/src/lumiera/DIR_INFO @@ -0,0 +1 @@ +The Lumiera application shell diff --git a/src/lumiera/main.cpp b/src/lumiera/main.cpp new file mode 100644 index 000000000..8dce65c54 --- /dev/null +++ b/src/lumiera/main.cpp @@ -0,0 +1,89 @@ +/* + main.cpp - start the Lumiera Application + + Copyright (C) Lumiera.org + 2007-2008, Joel Holdsworth + 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/nobugcfg.h" +#include "include/error.hpp" +#include "common/appstate.hpp" +#include "common/option.hpp" + +#include "backend/enginefacade.hpp" +#include "backend/netnodefacade.hpp" +#include "backend/scriptrunnerfacade.hpp" +#include "proc/facade.hpp" +#include "gui/guifacade.hpp" + +using util::Cmdline; +using lumiera::Subsys; +using lumiera::AppState; +using lumiera::ON_GLOBAL_INIT; + +namespace { + Subsys& engine = backend::EngineFacade::getDescriptor(); + Subsys& netNode = backend::NetNodeFacade::getDescriptor(); + Subsys& script = backend::ScriptRunnerFacade::getDescriptor(); + Subsys& builder = proc::Facade::getBuilderDescriptor(); + Subsys& session = proc::Facade::getSessionDescriptor(); + Subsys& lumigui = gui::GuiFacade::getDescriptor(); +} + + + +int +main (int argc, const char* argv[]) +{ + NOTICE (lumiera, "*** Lumiera NLE for Linux ***"); + + AppState& application = AppState::instance(); + try + { + Cmdline args (argc,argv); + lumiera::Option options (args); + application.init (options); + + session.depends (builder); + netNode.depends (session); + netNode.depends (engine); +// lumigui.depends (session); //////TODO commented out in order to be able to start up a dummy GuiStarterPlugin +// lumigui.depends (engine); + script.depends (session); + script.depends (engine); + + application.maybeStart (session); + application.maybeStart (netNode); + application.maybeStart (lumigui); + application.maybeStart (script); + + return application.maybeWait(); + } + + + catch (lumiera::Error& problem) + { + return application.abort (problem); + } + catch (...) + { + return application.abort(); + } +} diff --git a/src/main.cpp b/src/main.cpp deleted file mode 100644 index ffa3957f9..000000000 --- a/src/main.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - main.cpp - start the Lumiera Application - - 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 "proc/lumiera.hpp" - -using std::cout; - - -int main (int argc, char* argv[]) -{ - cout << "*** Lumiera NLE for Linux ***" << "\n" - << " Version: quasi niente" << "\n"; - - - // great things are happening here.... - - return 0; -} diff --git a/src/plugin/.gitignore b/src/plugin/.gitignore deleted file mode 100644 index 1e2cde283..000000000 --- a/src/plugin/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.os - diff --git a/src/plugin/helloplugin.c b/src/plugin/helloplugin.c deleted file mode 100644 index d75f55f94..000000000 --- a/src/plugin/helloplugin.c +++ /dev/null @@ -1,12 +0,0 @@ -/* - * hello.c - demonstrates how to build a standalone tool (C source) - * integrated into the SCons based build system of Lumiera - */ - -#include - -int main(int argc, char* argv[]) - { - printf("hello lumiera world"); - return 0; - } diff --git a/src/pre.hpp b/src/pre.hpp index ca948b7d6..d1495d952 100644 --- a/src/pre.hpp +++ b/src/pre.hpp @@ -45,7 +45,7 @@ #include #include -#include "proc/lumiera.hpp" +#include "proc/common.hpp" diff --git a/src/proc/lumiera.hpp b/src/proc/common.hpp similarity index 81% rename from src/proc/lumiera.hpp rename to src/proc/common.hpp index 1efdb0aef..970811102 100644 --- a/src/proc/lumiera.hpp +++ b/src/proc/common.hpp @@ -41,12 +41,16 @@ /* common types frequently used... */ -#include "proc/nobugcfg.hpp" +#include "lib/p.hpp" +#include "lib/util.hpp" +#include "lib/lumitime.hpp" +#include "include/symbol.hpp" +#include "include/error.hpp" ///< pulls in NoBug via nobugcfg.h /** - * Namespace for globals. - * A small number of definitions and facilities of application wide relevance. + * Lumiera public interface. + * Global interfaces and facilities accessible from plugins and scripts. * It's probably a good idea to pull it in explicitly and to avoid nesting * implementation namespaces within \c lumiera:: */ @@ -59,7 +63,7 @@ namespace lumiera { /** - * Namespace for support and library code. + * Implementation namespace for support and library code. */ namespace lib { @@ -68,12 +72,14 @@ namespace lib { /** * The asset subsystem of the Proc-Layer. + * @todo refactor proc namespaces */ namespace asset { } /** * Proc-Layer dispatcher, controller and administrative facilities. + * @todo refactor proc namespaces */ namespace control { } @@ -83,6 +89,7 @@ namespace control { } * Backbone of the engine, render nodes base and cooperation. * A good deal of the active engine code is outside the scope of the * Proc-Layer, e.g. code located in backend services and plugins. + * @todo refactor proc namespaces */ namespace engine { } @@ -90,6 +97,8 @@ namespace engine { } /** * Media-Objects, edit operations and high-level session. + * @todo is this interface or implementation ?? + * @todo refactor proc namespaces */ namespace mobject { diff --git a/src/proc/nobugcfg.hpp b/src/proc/nobugcfg.hpp deleted file mode 100644 index aa9411471..000000000 --- a/src/proc/nobugcfg.hpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - NOBUGCFG.hpp - NoBug definitions and initialisation for the Proc-Layer - - - 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. - -*/ - -/** @file nobugcfg.hpp - ** This header is for including and configuring NoBug. - ** The idea is that configuration and some globally used flag - ** declarations are to be kept in one central location. Normally, - ** this header will be included via some of the basic headers like - ** error.hpp, which in turn gets included by proc/lumiera.hpp - ** - ** @par Besides the usual guarded declarations, this header contains - ** one section with the corresponding definitions. This section - ** is to be included once by some translation unit (currently this is - ** nobugcfg.cpp) in order to generate the necessary definitions. - ** - ** @note this header assures automatic initialisation of NoBug - ** by placing a static ctor call. - ** - */ - - -#ifndef NOBUGCFG_H /* ============= Part 1: DECLARATIONS ======== */ -#define NOBUGCFG_H - -#include -#include - - - /* declare flags used throughout the code base... */ - NOBUG_DECLARE_FLAG(config); - NOBUG_DECLARE_FLAG(oper); - NOBUG_DECLARE_FLAG(test); - NOBUG_DECLARE_FLAG(singleton); - NOBUG_DECLARE_FLAG(assetmem); - NOBUG_DECLARE_FLAG(mobjectmem); - - -namespace lumiera { - void initialize_NoBug (); - namespace { -// LifecycleHook schedule_ (ON_BASIC_INIT, &initialize_NoBug); -} } -#endif /*NOBUGCFG_H ======= (End) Part 1: DECLARATIONS ======== */ - - - - - - -#ifdef NOBUG_INIT_DEFS_ /*========== Part 2: DEFINITIONS ========= */ - - - /* flags used throughout the code base... */ - NOBUG_CPP_DEFINE_FLAG(config); - NOBUG_CPP_DEFINE_FLAG(oper); - NOBUG_CPP_DEFINE_FLAG(test); - NOBUG_CPP_DEFINE_FLAG_LIMIT(singleton, LOG_WARNING); - NOBUG_CPP_DEFINE_FLAG_LIMIT(assetmem, LOG_WARNING); - NOBUG_CPP_DEFINE_FLAG_LIMIT(mobjectmem, LOG_WARNING); - - - - -#endif /*NOBUG_INIT_DEFS_ ==== (End) Part 2: DEFINITIONS ========= */ diff --git a/src/tool/SConscript b/src/tool/SConscript index c2bc612f6..2336c3553 100644 --- a/src/tool/SConscript +++ b/src/tool/SConscript @@ -9,6 +9,6 @@ Import('env','artifacts','core') # 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/try', 'try.cpp') #### to try out some feature... + + env.Program('#$BINDIR/try', 'try.cpp') #### to try out some feature... ] diff --git a/src/tool/luidgen.c b/src/tool/luidgen.c index 41081ca97..730395b6c 100644 --- a/src/tool/luidgen.c +++ b/src/tool/luidgen.c @@ -19,25 +19,98 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "lib/safeclib.h" #include "lib/luid.h" +#include +#include +#include #include +#include +#include /** * @file * Generate amd print a Lumiera uid as octal escaped string + * or process a file replaceing 'LUIDGEN' with a octal escaped string */ + int main (int argc, char** argv) { + NOBUG_INIT; lumiera_uid luid; - lumiera_uid_gen (&luid); - printf ("\""); - for (int i = 0; i < 16; ++i) - printf ("\\%.3hho", *(((char*)&luid)+i)); - printf ("\"\n"); + if (argc == 1) + { + lumiera_uid_gen (&luid); + printf ("\""); + for (int i = 0; i < 16; ++i) + printf ("\\%.3hho", *(((char*)&luid)+i)); + printf ("\"\n"); + } + else + { + for (int i = 1; i < argc; ++i) + { + FILE* in = fopen (argv[i], "r"); + if (!in) + { + fprintf (stderr, "Failed to open file %s for reading: %s\n", argv[i], strerror (errno)); + continue; + } + + char* outname = lumiera_tmpbuf_snprintf (SIZE_MAX, "%s.luidgen", argv[i]); + FILE* out = fopen (outname, "wx"); + if (!out) + { + fprintf (stderr, "Failed to open file %s for writing: %s\n", outname, strerror (errno)); + fclose (in); + continue; + } + + char buf[4096]; + char luidbuf[67]; + + printf ("Luidgen %s ", argv[i]); fflush (stdout); + + while (fgets (buf, 4096, in)) + { + char* pos; + while ((pos = strstr(buf, "LUIDGEN"))) + { + memmove (pos+66, pos+7, strlen (pos+7)+1); + lumiera_uid_gen (&luid); + sprintf (luidbuf, "\""LUMIERA_UID_FMT"\"", LUMIERA_UID_ELEMENTS(luid)); + memcpy (pos, luidbuf, 66); + putchar ('.'); fflush (stdout); + } + fputs (buf, out); + } + + fclose (out); + fclose (in); + + char* backup = lumiera_tmpbuf_snprintf (SIZE_MAX, "%s~", argv[i]); + unlink (backup); + + if (!!rename (argv[i], backup)) + { + fprintf (stderr, "Failed to create backupfile %s: %s\n", backup, strerror (errno)); + continue; + } + + if (!!rename (outname, argv[i])) + { + fprintf (stderr, "Renaming %s to %s failed: %s\n", outname, argv[i], strerror (errno)); + rename (backup, argv[i]); + continue; + } + + printf (" done\n"); + } + } return 0; } diff --git a/src/tool/try.cpp b/src/tool/try.cpp index cd654bf73..0854e5310 100644 --- a/src/tool/try.cpp +++ b/src/tool/try.cpp @@ -5,28 +5,33 @@ // 8/07 - how to control NOBUG?? // execute with NOBUG_LOG='ttt:TRACE' bin/try +// 1/08 - working out a static initialisation problem for Visitor (Tag creation) +// 1/08 - check 64bit longs +// 4/08 - comparison operators on shared_ptr +// 4/08 - conversions on the value_type used for boost::any +// 5/08 - how to guard a downcasting access, so it is compiled in only if the involved types are convertible +// 7/08 - combining partial specialisation and subclasses +// 10/8 - abusing the STL containers to hold noncopyable values -#include +#include "include/nobugcfg.h" + #include -#include - - using std::string; using std::cout; - - int main (int argc, char* argv[]) { NOBUG_INIT; - cout << "\ngulp\n"; - + cout << "\n.gulp.\n"; + + int * my = 0; + int oh = *my; // Congratulations... return 0; } diff --git a/tests/SConscript b/tests/SConscript index cd4fd2ae3..4f208f0ea 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -18,7 +18,7 @@ env.Append(CPPPATH='#/.') # add Rootdir to Includepath, so test/test.h is found def testExecutable(env,tree, exeName=None, obj=None): """ declare all targets needed to create a standalone - Test executalbe of the given Sub-tree. Note that + Test executable of the given Sub-tree. Note that each subdir is built in its own Environment. """ env = env.Clone() @@ -27,7 +27,7 @@ def testExecutable(env,tree, exeName=None, obj=None): if obj: obj = [path.join(tree,name) for name in obj] else: - obj = srcSubtree(env,tree) # use all sourcefiles found in subtree + obj = srcSubtree(env,tree, isShared=False) # use all sourcefiles found in subtree if not exeName: exeName = 'test-%s' % tree return env.Program('#$BINDIR/'+exeName, obj + core) @@ -46,21 +46,17 @@ def testCollection(env,dir): def treatPluginTestcase(env): """ Special case: the test-plugin executable """ - tree = 'backend' + tree = 'plugin' env = env.Clone() - env.Append(CPPPATH=tree) + 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.SharedLibrary('#$BINDIR/.libs/example_plugin', oC, SHLIBPREFIX='') - + env.SharedLibrary('#$BINDIR/.libs/example_plugin_cpp', oCPP, SHLIBPREFIX='') + testplugin = ( env.LoadableModule('#$LIBDIR/examplepluginc', oC, SHLIBPREFIX='') +# + env.SharedLibrary('#$LIBDIR/exampleplugincpp', oCPP, SHLIBPREFIX='') +# doesn't compile yet... ) -# testExe = env.Program('#$BINDIR/test-plugin', ['plugin/plugin_main.c'] + core) -# env.Depends(testExe, testplugin) -# return testExe - - # 10/2008 example_plugin moved to backend directory. - # ...we should try to find some convention here + return testplugin #-- it depends (at the moment) on a specific isolated test-plugin, # which is not integrated in the "normal procedure" for building Plugins @@ -73,7 +69,7 @@ def treatPluginTestcase(env): moduledirs = globRootdirs('*') # but have to treat some subdirs individually. -specials = ['plugin','library','backend'] +specials = ['plugin','library','backend','lumiera'] @@ -81,6 +77,7 @@ artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in moduledirs # + treatPluginTestcase(env) # + testCollection(env, 'library') # + testCollection(env, 'backend') +# + testCollection(env, 'lumiera') ) @@ -98,10 +95,16 @@ artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in moduledirs # testEnv = env.Clone() if not env['VALGRIND']: - testEnv.Append(ENV = {'VALGRINDFLAGS' : 'DISABLE'}) + testEnv.Append(ENV = { 'VALGRINDFLAGS' : 'DISABLE' + , 'LUMIERA_CONFIG_PATH' : './' }) + testsuites = env['TESTSUITES'] or os.environ.get('TESTSUITES') if testsuites: testEnv['ENV']['TESTSUITES'] = testsuites + +pluginpath = os.environ.get('LUMIERA_PLUGIN_PATH') +if testsuites: + testEnv['ENV']['LUMIERA_PLUGIN_PATH'] = pluginpath testDir = env.Dir('#$BINDIR') runTest = env.File("test.sh").abspath