diff --git a/.gitignore b/.gitignore index 01c32fa89..141d31bb7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,7 @@ /wiki/backups/* *~ *.tar.* -.sconf_temp -.sconf_temp/* -.sconsign.dblite +.[^.]* Buildhelper.pyc optcache Makefile.in diff --git a/Makefile.am b/Makefile.am index fbaecd794..9b03ecb54 100644 --- a/Makefile.am +++ b/Makefile.am @@ -18,8 +18,9 @@ bin_PROGRAMS = lib_LTLIBRARIES = noinst_PROGRAMS = +check_PROGRAMS = noinst_LIBRARIES = -noinst_LTLIBRARIES = +check_LTLIBRARIES = noinst_HEADERS = BUILT_SOURCES = EXTRA_DIST = @@ -35,7 +36,8 @@ include $(top_srcdir)/src/lib/Makefile.am #include $(top_srcdir)/src... # tests -include $(top_srcdir)/tests/examples/Makefile.am +include $(top_srcdir)/tests/Makefile.am +include $(top_srcdir)/tests/plugin/Makefile.am #EXTRA_DIST += admin debian doc depcomp README.BUILD LICENSE \ # cinelerra-cvs-current.spec diff --git a/SConstruct b/SConstruct index cc2f5c308..9b11e379e 100644 --- a/SConstruct +++ b/SConstruct @@ -32,6 +32,7 @@ OPTIONSCACHEFILE = 'optcache' CUSTOPTIONSFILE = 'custom-options' SRCDIR = 'src' BINDIR = 'src/bin' +TESTDIR = 'tests' VERSION = '3+alpha.01' #-----------------------------------Configuration @@ -54,35 +55,52 @@ def setupBasicEnvironment(): opts = defineCmdlineOptions() env = Environment(options=opts) + + env.Append ( CCCOM=' -std=gnu99') # workaround for a bug: CCCOM currently doesn't honor CFLAGS, only CCFLAGS env.Replace( VERSION=VERSION , SRCDIR=SRCDIR , BINDIR=BINDIR - , CPPPATH=SRCDIR # used to find includes + , CPPPATH=["#"+SRCDIR] # used to find includes, "#" means always absolute to build-root + , CPPDEFINES=['-DCINELERRA_VERSION=\\"%s\\"' % VERSION ] # note: make it a list to append further defines + , CCFLAGS='-Wall' ) - appendCppDefine(env,'DEBUG','DEBUG') + handleNoBugSwitches(env) + + appendCppDefine(env,'DEBUG','DEBUG', 'NDEBUG') appendCppDefine(env,'OPENGL','USE_OPENGL') - appendVal(env,'ARCHFLAGS', 'CPPFLAGS') # for both C and C++ - appendVal(env,'OPTIMIZE', 'CPPFLAGS', val=' -O3') - - if env['BUILDLEVEL'] in ['ALPHA', 'BETA']: - env.Append(CPPFLAGS = ' -DEBUG_'+env['BUILDLEVEL']) - if env['BUILDLEVEL'] == 'RELEASE': - env.Append(CPPFLAGS = ' -DNDEBUG') + appendVal(env,'ARCHFLAGS', 'CCFLAGS') # for both C and C++ + appendVal(env,'OPTIMIZE', 'CCFLAGS', val=' -O3') + appendVal(env,'DEBUG', 'CCFLAGS', val=' -g') prepareOptionsHelp(opts,env) opts.Save(OPTIONSCACHEFILE, env) return env -def appendCppDefine(env,var,cppVar): +def appendCppDefine(env,var,cppVar, elseVal=''): if env[var]: - env.Append(CPPDEFINES = {cppVar: env[var]}) + env.Append(CPPDEFINES = cppVar ) + elif elseVal: + env.Append(CPPDEFINES = elseVal) def appendVal(env,var,targetVar,val=None): if env[var]: env.Append( **{targetVar: val or env[var]}) +def handleNoBugSwitches(env): + """ set the build level for NoBug. + Release builds imply no DEBUG + """ + level = env['BUILDLEVEL'] + if level in ['ALPHA', 'BETA']: + env.Replace( DEBUG = 1 ) + env.Append(CPPDEFINES = 'EBUG_'+level) + elif level == 'RELEASE': + env.Replace( DEBUG = 0 ) + + + def defineCmdlineOptions(): """ current options will be persisted in a options cache file. @@ -117,6 +135,8 @@ USAGE: scons [-c] [OPTS] [key=val,...] [TARGETS] Special Targets: build : just compile and link + testcode: additionally compile the Testsuite + check : build and run the Testsuite install : install created artifacts at PREFIX src.tar : create source tarball doc.tar : create developer doc tarball @@ -142,16 +162,29 @@ def configurePlatform(env): print 'Did not find math.h / libm, exiting.' Exit(1) + if not conf.CheckLibWithHeader('dl', 'dlfcn.h', 'C'): + print 'Functions for runtime dynamic loading not available, exiting.' + Exit(1) + if not conf.CheckLibWithHeader('nobugmt', 'nobug.h', 'C'): print 'Did not find NoBug [http://www.pipapo.org/pipawiki/NoBug], exiting.' Exit(1) + if not conf.CheckLibWithHeader('pthread', 'pthread.h', 'C'): + print 'Did not find the pthread lib or pthread.h, exiting.' + else: + conf.env.Append(CPPFLAGS = ' -DHAVE_PTHREAD_H') + if conf.CheckCHeader('execinfo.h'): conf.env.Append(CPPFLAGS = ' -DHAS_EXECINFO_H') if conf.CheckCHeader('valgrind/valgrind.h'): conf.env.Append(CPPFLAGS = ' -DHAS_VALGRIND_VALGIND_H') + if not conf.CheckCXXHeader('tr1/memory'): + print 'We rely on the std::tr1 proposed standard extension for shared_ptr.' + Exit(1) + if not conf.CheckCXXHeader('boost/config.hpp'): print 'We need the C++ boost-lib.' Exit(1) @@ -186,18 +219,20 @@ def defineBuildTargets(env, artifacts): setup sub-environments with special build options if necessary. We use a custom function to declare a whole tree of srcfiles. """ - cinobj = ( srcSubtree(env,'backend') - + srcSubtree(env,'proc') - + env.Object('$SRCDIR/main.cpp') + cinobj = ( srcSubtree(env,'$SRCDIR/backend') + + srcSubtree(env,'$SRCDIR/proc') + + srcSubtree(env,'$SRCDIR/common') + + srcSubtree(env,'$SRCDIR/lib') ) - plugobj = srcSubtree(env,'plugin', isShared=True) + plugobj = srcSubtree(env,'$SRCDIR/plugin', isShared=True) + corelib = env.StaticLibrary('$BINDIR/core.la', cinobj) - artifacts['cinelerra'] = env.Program('$BINDIR/cinelerra', cinobj) + artifacts['cinelerra'] = env.Program('$BINDIR/cinelerra', ['$SRCDIR/main.cpp']+ corelib ) artifacts['plugins'] = env.SharedLibrary('$BINDIR/cinelerra-plugin', plugobj) # call subdir SConscript(s) for independent components SConscript(dirs=[SRCDIR+'/tool'], exports='env artifacts') - + SConscript(dirs=[TESTDIR], exports='env artifacts corelib') def defineInstallTargets(env, artifacts): diff --git a/admin/git-mrproper.sh b/admin/git-mrproper.sh deleted file mode 100755 index 46184161a..000000000 --- a/admin/git-mrproper.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh -if test "$1" = "yes"; then - git ls-files -o | xargs rm -f -else - ( - echo "'git-mrproper.sh yes'" - echo "would delete following files:" - echo - git ls-files -o | while read file; do echo " $file"; done - ) | less -fi diff --git a/admin/scons/Buildhelper.py b/admin/scons/Buildhelper.py index 99b84c997..3f6a0e7d5 100644 --- a/admin/scons/Buildhelper.py +++ b/admin/scons/Buildhelper.py @@ -23,6 +23,7 @@ import os import sys +import glob import fnmatch import re import tarfile @@ -47,10 +48,10 @@ def isHelpRequest(): def srcSubtree(env,tree,isShared=False, **args): """ convienience wrapper: scans the given subtree, which is - to be located within $SRCDIR, find all source files and + relative to the current SConscript, find all source files and declare them as Static or SharedObjects for compilation """ - root = env.subst('$SRCDIR/%s' % tree) # expand $SRCDIR + root = env.subst(tree) # expand Construction Vars if isShared: builder = lambda f: env.SharedObject(f, **args) else: @@ -62,16 +63,28 @@ def srcSubtree(env,tree,isShared=False, **args): SRCPATTERNS = ['*.c','*.cpp','*.cc'] -def scanSrcSubtree(root): - """ scan the given subtree for source filesnames +def scanSrcSubtree(roots): + """ first expand (possible) wildcards and filter out non-dirs. + Then scan the given subtree for source filesnames (python generator function) """ - for (dir,_,files) in os.walk(root): - if dir.startswith('./'): - dir = dir[2:] - for p in SRCPATTERNS: - for f in fnmatch.filter(files, p): - yield os.path.join(dir,f) + for root in globRootdirs(roots): + for (dir,_,files) in os.walk(root): + if dir.startswith('./'): + dir = dir[2:] + for p in SRCPATTERNS: + for f in fnmatch.filter(files, p): + yield os.path.join(dir,f) + + + +def globRootdirs(roots): + """ helper: expand shell wildcards and filter the resulting list, + so that it only contains existing directories + """ + filter = lambda f: os.path.isdir(f) and os.path.exists(f) + roots = glob.glob(roots) + return (dir for dir in roots if filter(dir) ) diff --git a/configure.ac b/configure.ac index 872275791..1730b3bdc 100644 --- a/configure.ac +++ b/configure.ac @@ -29,7 +29,9 @@ AC_COPYRIGHT([ AC_PROG_CC AC_PROG_CPP AC_PROG_CXX -AC_PROG_RANLIB + +AC_LIBTOOL_DLOPEN +AC_PROG_LIBTOOL # # test for headers diff --git a/doc/devel/Doxyfile b/doc/devel/Doxyfile new file mode 100644 index 000000000..ebc2bbc4a --- /dev/null +++ b/doc/devel/Doxyfile @@ -0,0 +1,277 @@ +# Doxyfile 1.5.1 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = Cinelerra3 +PROJECT_NUMBER = 3.0+alpha +OUTPUT_DIRECTORY = +CREATE_SUBDIRS = YES +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = ../../src/ +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +BUILTIN_STL_SUPPORT = NO +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = YES +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = NO +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = ../../src/ +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.py \ + *.C \ + *.CC \ + *.C++ \ + *.II \ + *.I++ \ + *.H \ + *.HH \ + *.H++ \ + *.CS \ + *.PHP \ + *.PHP3 \ + *.M \ + *.MM \ + *.PY +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = YES +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = YES +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +REFERENCES_LINK_SOURCE = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = cinelerra:: \ + cinelerra_ \ + CINELERRA_ +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = YES +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = YES +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = YES +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = YES +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = YES +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = YES +TEMPLATE_RELATIONS = YES +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = YES +CALLER_GRAPH = YES +GRAPHICAL_HIERARCHY = NO +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = YES +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 000000000..fa4c89bdf --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,2 @@ +bin/* +plugin/*.os diff --git a/src/DIR_INFO b/src/DIR_INFO index fbe280987..b6c7308d3 100644 --- a/src/DIR_INFO +++ b/src/DIR_INFO @@ -1 +1 @@ -every components source in a own subdir here +root of sourcecode tree diff --git a/src/bin/DIR_INFO b/src/bin/DIR_INFO new file mode 100644 index 000000000..c9048f8c1 --- /dev/null +++ b/src/bin/DIR_INFO @@ -0,0 +1 @@ +cinelerra executable(s) and libraries will be built here diff --git a/src/cinelerra.h b/src/cinelerra.h index d9a813952..c2b95dd8c 100644 --- a/src/cinelerra.h +++ b/src/cinelerra.h @@ -40,13 +40,18 @@ extern "C" { +#ifndef __cplusplus +#include "nobugcfg.h" -#ifdef __cplusplus /* ============== C++-Part ================= */ +#else /* ========================== C++-Part ================= */ /* common types frequently used... */ +#include "common/util.hpp" #include "common/time.hpp" +#include "common/appconfig.hpp" // includes NoBug via "nobugcfg.h" +#include "common/error.hpp" namespace cinelerra diff --git a/src/common/appconfig.cpp b/src/common/appconfig.cpp new file mode 100644 index 000000000..769cde604 --- /dev/null +++ b/src/common/appconfig.cpp @@ -0,0 +1,94 @@ +/* + Appconfig - for global initialization and configuration + + Copyright (C) CinelerraCV + 2007, 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. + +* *****************************************************/ + + +#include "common/appconfig.hpp" +#include "common/error.hpp" +#include "common/util.hpp" + +#define NOBUG_INIT_DEFS_ +#include "nobugcfg.h" +#undef NOBUG_INIT_DEFS_ + + +using util::isnil; + +namespace cinelerra + { + + /** This internal pointer to the single instance is deliberately + * not initialized (i.e. rely on implicit initialisation to 0), + * because when static init reaches this definition, the + * Appconfig::instance() probably already has been called + * by another compilation unit. This is ugliy, but preferable + * to beeing dependant on inclusion order of headers. */ + Appconfig* Appconfig::theApp_ ; + +#ifndef CINELERRA_VERSION +#define CINELERRA_VERSION "3++devel" +#endif + + + /** perform initialization on first access. + * A call is placed in static initialization code + * included in cinelerra.h; thus it will happen + * probably very early. + */ + Appconfig::Appconfig() + : configParam_ (new Configmap) + { + ////////// + NOBUG_INIT; + ////////// + + INFO(config, "Basic application configuration triggered."); + (*configParam_)["version"] = CINELERRA_VERSION; + } + + + + + + /** access the configuation value for a given key. + * @return empty string for unknown keys, else the corresponding configuration value + */ + const string & + Appconfig::get (const string & key) throw() + { + + try + { + const string& val = (*instance().configParam_)[key]; + WARN_IF( isnil(val), config, "undefined config parameter \"%s\" requested.", key.c_str()); + return val; + + } + catch (...) + { + ERROR(config, "error while accessing configuration parameter \"%s\".", key.c_str()); + } + } + + + + +} // namespace cinelerra diff --git a/src/common/appconfig.hpp b/src/common/appconfig.hpp new file mode 100644 index 000000000..9cf20f9f9 --- /dev/null +++ b/src/common/appconfig.hpp @@ -0,0 +1,111 @@ +/* + APPCONFIG.hpp - for global initialization and configuration + + Copyright (C) CinelerraCV + 2007, 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. + +*/ + +/** @file appconfig.hpp + ** This header is special, as it causes global system initialisation + ** to happen. On inclusion, it places static initialisation code, + ** which on first run will create the Appconfig singleton instance. + ** Additionally, the inclusion, configuration and initialisation + ** of the NoBug library is handled here. Global definitions + ** for NoBug are placed into the corresponding translation unit + ** appconfig.cpp" + ** + ** @see nobugcfg.h + */ + + +#ifndef CINELERRA_APPCONFIG_H +#define CINELERRA_APPCONFIG_H + +#include +#include +#include + +#include "nobugcfg.h" + + +using std::string; +using std::auto_ptr; + + + + +namespace cinelerra + { + + + /** + * Singleton to hold inevitable global flags and constants + * and for performing early (static) global initialization tasks. + */ + class Appconfig + { + private: + + /** holds the single instance and triggers initialization */ + static Appconfig* theApp_; + + + /** perform initialization on first access. + * A call is placed in static initialization code + * included via cinelerra.h (see below), + * thus it will happen rather early. + */ + Appconfig () ; + + + public: + static Appconfig& instance() + { + if (!theApp_) theApp_ = new Appconfig (); + return *theApp_; + } + + /** access the configuation value for a given key. + * @return empty string for unknown keys, config value else + * @todo do we need such a facility? + */ + static const string & get (const string& key) throw(); + + + private: + typedef std::map Configmap; + typedef auto_ptr PConfig; + + /** @TODO the following is just placeholder code! + * Appconfig could do such things if necessary. + */ + PConfig configParam_; + + }; + + + + + namespace + { + /** "magic code" to cause early static initialization */ + Appconfig& init (Appconfig::instance ()); + } + +} // namespace cinelerra +#endif diff --git a/src/common/error.cpp b/src/common/error.cpp new file mode 100644 index 000000000..0e869fe93 --- /dev/null +++ b/src/common/error.cpp @@ -0,0 +1,53 @@ +/* + Error - Cinelerra Exception Interface + + Copyright (C) CinelerraCV + 2007, 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. + +* *****************************************************/ + + +#include "common/error.hpp" + +namespace cinelerra + { + + /** Description of the problem, including the internal char constant + * in accordance to cinelerras error identification scheme. + * If a ::rootCause() can be obtained, this will be included in the + * generated output as well. + */ + const char* + Error::what () const throw() + { + } + + + /** If this exception was caused by a chain of further exceptions, + * return the first one registered in this throw sequence. + * This works only, if every exceptions thrown as a consequence + * of another exception is propperly constructed by passing + * the original exception to the constructor + */ + std::exception + Error::rootCause() const throw() + { + } + + + +} // namespace cinelerra diff --git a/src/common/error.hpp b/src/common/error.hpp new file mode 100644 index 000000000..973fa1d8a --- /dev/null +++ b/src/common/error.hpp @@ -0,0 +1,102 @@ +/* + ERROR.hpp - Cinelerra Exception Interface + + Copyright (C) CinelerraCV + 2007, 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. + +*/ + + +#ifndef CINELERRA_ERROR_H +#define CINELERRA_ERROR_H + +#include + + +namespace cinelerra + { + + + /** + * Interface and Baseclass of all Exceptions thrown + * from within cinelerra (C++) code. Common operations + * for getting an diagnostic message and for obtaining + * the root cause, i.e. the frist exception encountered + * in a chain of exceptions. + */ + class Error : public std::exception + { + public: + virtual ~Error () throw() {}; + + /** yield a diagnostig message characterizing the problem */ + virtual const char* what () const throw(); + + /** If this exception was caused by a chain of further exceptions, + * return the first one registered in this throw sequence. + * This works only, if every exceptions thrown as a consequence + * of another exception is propperly constructed by passing + * the original exception to the constructor + */ + std::exception rootCause () const throw(); + + private: + /** a copy of the first exception encountered in this exception chain */ + std::exception cause; + + }; + + + + + /* === Exception Subcategories === */ + + namespace error + { + + class Logic : public Error + { + + }; + + class Config : public Error + { + + }; + + class State : public Error + { + + }; + + class Invalid : public Error + { + + }; + + class External : public Error + { + + }; + + + + + } // namespace error + +} // namespace cinelerra +#endif diff --git a/src/common/factory.hpp b/src/common/factory.hpp new file mode 100644 index 000000000..8664675c8 --- /dev/null +++ b/src/common/factory.hpp @@ -0,0 +1,127 @@ +/* + FACTORY.hpp - template for object/smart-pointer factories + + Copyright (C) CinelerraCV + 2007, 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. + +*/ + + +#ifndef CINELERRA_FACTORY_H +#define CINELERRA_FACTORY_H + +#include + + + +namespace cinelerra + { + + namespace factory{ class VanillaAllocator; }//////////////////////////////////TODO + + /** + * Configurable template for creating Factory classes. + * These encapsulate the creating of new objects, indeed + * delegating the memory allocation to the backend layer. + * The clients get just a smart-pointer or similar handle + * to the created object, which will manage the ownership. + * + * The provided default implementation uses just std::auto_ptr, + * but delegates the allocation to cinelerra's backend-layer. + * + */ + template + < + class T, // the product to be created + template class SMP = std::auto_ptr,// smart-pointer actually returned + class ALO = factory::VanillaAllocator // Allocator facility to be used //////////////TODO + > + class Factory : protected ALO + { + public: + /** Object creating facility. + * Intended to be over/written/ with a variant taking + * the appropriate number of parameters and using the + * (privately inherited) functions of the allocator. + * Note: non-virtual. + */ + SMP operator() (){ return SMP (new T ); }; + + private: + void operator= (const Factory&); // copy prohibited + }; + + + + /* -- some example and default instantiiations -- */ + + namespace factory + { + /** + * Example Allocator using just the normal C++ memory management. + * The intended use is for a Factory instance to iherit from this class. + * Specialized Allocators typically overload operator new and delete. + */ + class VanillaAllocator {}; + + /** + * Example Allocator using plain C memory management. + */ + class MallocAllocator + { + void* operator new (size_t siz) { return malloc (siz); }; + void operator delete (void* p) { if (p) free (p); }; + }; + + + using std::tr1::shared_ptr; + + /** a frequently used instantiation of the Factory, + * using the refcounting shared_ptr from Boost + * and for allocation just our default Allocator + */ + template + class RefcountPtr : public Factory + { + /** let the smart-Ptr use the custom operator delete, + * which may be defined in our Allocator baseclass. + */ + static void destroy (T* victim) { delete victim; }; + + public: + shared_ptr operator() () { return shared_ptr (new T, &destroy ); } + }; + + + /** another convienience instantiiation: auto_ptr-Factory, + * actually creating a subclass of the returned type + */ + template + class SubclassPtr : public Factory + { + typedef std::auto_ptr aP; + + public: + aP operator() (){ return aP (new TImpl ); }; + }; + + + + } // namespace factory + +} // namespace cinelerra +#endif diff --git a/src/common/factorytest.cpp b/src/common/factorytest.cpp new file mode 100644 index 000000000..6c11cb45b --- /dev/null +++ b/src/common/factorytest.cpp @@ -0,0 +1,48 @@ +/* + Factorytest - check basic workings of object/smart-pointer factory + + Copyright (C) CinelerraCV + 2007, 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. + +* *****************************************************/ + + +#include "common/factory.hpp" + +namespace cinelerra + { + + class Blubb + { + int uii ; + + public: + typedef factory::RefcountPtr Factory; + static Factory create; + + Blubb() : uii(42) {} ; + }; + + /** a static Factory instance + * for creating refcounting Ptrs to Blubb objects + */ + Blubb::Factory Blubb::create; + + std::tr1::shared_ptr huii = Blubb::create (); + std::tr1::shared_ptr pfuii = huii; + +} // namespace cinelerra diff --git a/src/common/util.hpp b/src/common/util.hpp new file mode 100644 index 000000000..f0a8bfc2f --- /dev/null +++ b/src/common/util.hpp @@ -0,0 +1,53 @@ +/* + TIME.hpp - unified representation of a time point, including conversion functions + + Copyright (C) CinelerraCV + 2007, 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. + +*/ + + +#ifndef UTIL_HPP_ +#define UTIL_HPP_ + +#include +#include + + +namespace util + { + using std::string; + + + /** a family of util functions providing a "no value whatsoever" test */ + inline bool isnil(const string& val) + { + return 0 == val.length(); + } + + inline bool isnil(const string* pval) + { + return !pval || 0 == pval->length(); + } + + inline bool isnil(const char* pval) + { + return !pval || 0 == std::strlen(pval); + } + +} // namespace util +#endif /*UTIL_HPP_*/ diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index b6c493a18..7419bedf9 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -20,5 +20,5 @@ noinst_LIBRARIES += libcin3.a libcin3_a_CFLAGS = $(CFLAGS) -std=gnu99 -Wall -Werror -libcin3_a_SOURCES = $(libcin3_a_srcdir)/plugin.c -noinst_HEADERS += $(libcin3_a_srcdir)/plugin.h +libcin3_a_SOURCES = $(libcin3_a_srcdir)/plugin.c $(libcin3_a_srcdir)/error.c +noinst_HEADERS += $(libcin3_a_srcdir)/plugin.h $(libcin3_a_srcdir)/error.h diff --git a/src/lib/error.c b/src/lib/error.c new file mode 100644 index 000000000..d05696c06 --- /dev/null +++ b/src/lib/error.c @@ -0,0 +1,56 @@ +/* + error.c - Cinelerra Error handling + + Copyright (C) CinelerraCV + 2007, 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. +*/ + +#include + +/* Thread local storage */ +static pthread_key_t cinelerra_error_tls; +static pthread_once_t cinelerra_error_initialized = PTHREAD_ONCE_INIT; + +static void +cinelerra_error_tls_init (void) +{ + pthread_key_create (&cinelerra_error_tls, NULL); +} + +const char* +cinelerra_error_set (const char * nerr) +{ + pthread_once (&cinelerra_error_initialized, cinelerra_error_tls_init); + + const char* err = pthread_getspecific (cinelerra_error_tls); + if (!err) + pthread_setspecific (cinelerra_error_tls, nerr); + + return err; +} + + +const char* +cinelerra_error () +{ + pthread_once (&cinelerra_error_initialized, cinelerra_error_tls_init); + + const char* err = pthread_getspecific (cinelerra_error_tls); + if (err) + pthread_setspecific (cinelerra_error_tls, NULL); + return err; +} diff --git a/src/lib/error.h b/src/lib/error.h new file mode 100644 index 000000000..abc2d151a --- /dev/null +++ b/src/lib/error.h @@ -0,0 +1,46 @@ +/* + error.h - Cinelerra Error handling + + Copyright (C) CinelerraCV + 2007, 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. +*/ +#ifndef CINELERRA_ERROR_H +#define CINELERRA_ERROR_H + +#include +#include + +#define CINELERRA_DIE do { NOBUG_ERROR(NOBUG_ON, "Fatal Error!"); abort(); } while(0) + +#define CINELERRA_ERROR_DECLARE(err) \ +extern const char* CINELERRA_ERROR_##err + +#define CINELERRA_ERROR_DEFINE(err, msg) \ +const char* CINELERRA_ERROR_##err = "CINELERRA_ERROR_" #err ":" msg + +#define CINELERRA_ERROR_SET(flag, err) \ +ERROR (flag, "%s", strchr(CINELERRA_ERROR_##err, ':')+1); \ +cinelerra_error_set(CINELERRA_ERROR_##err) + +const char* +cinelerra_error_set (const char * err); + +const char* +cinelerra_error (); + + +#endif /* CINELERRA_ERROR_H */ diff --git a/src/lib/plugin.c b/src/lib/plugin.c index ec7b3f0a6..4005bb204 100644 --- a/src/lib/plugin.c +++ b/src/lib/plugin.c @@ -28,26 +28,17 @@ #include "plugin.h" -/* - TODO cinelerra_xmalloc which aborts on allocation error - or cinelerra_die() function - -TODO move CINELERRA_DIE elsewhere (cinlib.h?) -*/ -#define CINELERRA_DIE do{NOBUG_LOG(NOBUG_ON, LOG_EMERG, "aborting due fatal error"); abort();}while(0) - /* TODO should be set by the build system to the actual plugin path */ -#define CINELERRA_PLUGIN_PATH "~/.cinelerra3/plugins:/usr/local/lib/cinelerra3/plugins" +#define CINELERRA_PLUGIN_PATH "~/.cinelerra3/plugins:/usr/local/lib/cinelerra3/plugins:.libs" NOBUG_DEFINE_FLAG (cinelerra_plugin); /* errors */ -const char* CINELERRA_PLUGIN_SUCCESS = NULL; -const char* CINELERRA_PLUGIN_EDLOPEN = "Could not open plugin"; -const char* CINELERRA_PLUGIN_EHOOK = "Hook function failed"; -const char* CINELERRA_PLUGIN_ENFOUND = "No such plugin"; -const char* CINELERRA_PLUGIN_ENIFACE = "No such interface"; -const char* CINELERRA_PLUGIN_EREVISION = "Interface revision too old"; +CINELERRA_ERROR_DEFINE(PLUGIN_DLOPEN, "Could not open plugin"); +CINELERRA_ERROR_DEFINE(PLUGIN_HOOK, "Hook function failed"); +CINELERRA_ERROR_DEFINE(PLUGIN_NFILE, "No such plugin"); +CINELERRA_ERROR_DEFINE(PLUGIN_NIFACE, "No such interface"); +CINELERRA_ERROR_DEFINE(PLUGIN_REVISION, "Interface revision too old"); /* supported (planned) plugin types and their file extensions @@ -66,9 +57,8 @@ static const struct enum cinelerra_plugin_type type; } cinelerra_plugin_extensions [] = { - {"plugin", CINELERRA_PLUGIN_DYNLIB}, {"so", CINELERRA_PLUGIN_DYNLIB}, - {"tcc", CINELERRA_PLUGIN_CSOURCE}, + {"o", CINELERRA_PLUGIN_DYNLIB}, {"c", CINELERRA_PLUGIN_CSOURCE}, /* extend here */ {NULL, CINELERRA_PLUGIN_NULL} @@ -103,16 +93,6 @@ void* cinelerra_plugin_registry = NULL; /* plugin operations are protected by one big mutex */ pthread_mutex_t cinelerra_plugin_mutex = PTHREAD_MUTEX_INITIALIZER; -/* Thread local storage, for now only the error state */ -static pthread_key_t cinelerra_plugin_tls_error; -static pthread_once_t cinelerra_plugin_initialized = PTHREAD_ONCE_INIT; - -void -cinelerra_plugin_tls_init (void) -{ - pthread_key_create (&cinelerra_plugin_tls_error, NULL); -} - /* the compare function for the registry tree */ static int cinelerra_plugin_name_cmp (const void* a, const void* b) @@ -120,21 +100,10 @@ cinelerra_plugin_name_cmp (const void* a, const void* b) return strcmp (((struct cinelerra_plugin*) a)->name, ((struct cinelerra_plugin*) b)->name); } - -const char* -cinelerra_plugin_error () +void +cinelerra_init_plugin (void) { - pthread_once (&cinelerra_plugin_initialized, cinelerra_plugin_tls_init); - - const char* err = pthread_getspecific (cinelerra_plugin_tls_error); - pthread_setspecific (cinelerra_plugin_tls_error, CINELERRA_PLUGIN_SUCCESS); - return err; -} - -static void -cinelerra_plugin_error_set (const char* err) -{ - pthread_setspecific (cinelerra_plugin_tls_error, err); + NOBUG_INIT_FLAG (cinelerra_plugin); } int @@ -169,6 +138,7 @@ cinelerra_plugin_lookup (struct cinelerra_plugin* self, const char* path) if (!access(pathname, R_OK)) { /* got it */ + TRACE (cinelerra_plugin, "found %s", pathname); self->pathname = strdup (pathname); if (!self->pathname) CINELERRA_DIE; self->type = cinelerra_plugin_extensions[i].type; @@ -185,8 +155,6 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re //REQUIRE (min_revision > sizeof(struct cinelerra_interface), "try to use an empty interface eh?"); REQUIRE (interface, "interface name must be given"); - pthread_once (&cinelerra_plugin_initialized, cinelerra_plugin_tls_init); - pthread_mutex_lock (&cinelerra_plugin_mutex); struct cinelerra_plugin plugin; @@ -211,14 +179,14 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re (*found)->name = strdup (name); if (!(*found)->name) CINELERRA_DIE; - if (!cinelerra_plugin_lookup (*found, getenv("CINELERRA_PLUGIN_PATH")) + if (!!cinelerra_plugin_lookup (*found, getenv("CINELERRA_PLUGIN_PATH")) #ifdef CINELERRA_PLUGIN_PATH /* else lookup for -DCINELERRA_PLUGIN_PATH */ - || !cinelerra_plugin_lookup (&plugin, CINELERRA_PLUGIN_PATH) + && !!cinelerra_plugin_lookup (*found, CINELERRA_PLUGIN_PATH) #endif ) { - cinelerra_plugin_error_set (CINELERRA_PLUGIN_ENFOUND); + CINELERRA_ERROR_SET (cinelerra_plugin, PLUGIN_NFILE); goto elookup; } } @@ -233,11 +201,13 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re PLANNED("if .so like then dlopen; else if .c like tcc compile"); TODO("factor dlopen and dlsym out"); - (*found)->handle = dlopen ((*found)->pathname, RTLD_NOW|RTLD_LOCAL); + TRACE(cinelerra_plugin, "trying to open %s", (*found)->pathname); + + (*found)->handle = dlopen ((*found)->pathname, RTLD_LAZY|RTLD_LOCAL); if (!(*found)->handle) { ERROR (cinelerra_plugin, "dlopen failed: %s", dlerror()); - cinelerra_plugin_error_set (CINELERRA_PLUGIN_EDLOPEN); + CINELERRA_ERROR_SET (cinelerra_plugin, PLUGIN_DLOPEN); goto edlopen; } @@ -245,20 +215,24 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re int (*init)(void) = dlsym((*found)->handle, "cinelerra_plugin_init"); if (init && init()) { - ERROR (cinelerra_plugin, "cinelerra_plugin_init failed: %s: %s", name, interface); - cinelerra_plugin_error_set (CINELERRA_PLUGIN_EHOOK); + //ERROR (cinelerra_plugin, "cinelerra_plugin_init failed: %s: %s", name, interface); + CINELERRA_ERROR_SET (cinelerra_plugin, PLUGIN_HOOK); goto einit; } } /* we have the plugin, now get the interface descriptor */ struct cinelerra_interface* ret; + dlerror(); ret = dlsym ((*found)->handle, interface); + + const char *dlerr = dlerror(); + TRACE(cinelerra_plugin, "%s", dlerr); TODO ("need some way to tell 'interface not provided by plugin', maybe cinelerra_plugin_error()?"); - if (!ret) + if (dlerr) { - ERROR (cinelerra_plugin, "plugin %s doesnt provide interface %s", name, interface); - cinelerra_plugin_error_set (CINELERRA_PLUGIN_ENIFACE); + //ERROR (cinelerra_plugin, "plugin %s doesnt provide interface %s", name, interface); + CINELERRA_ERROR_SET (cinelerra_plugin, PLUGIN_NIFACE); goto edlsym; } @@ -266,7 +240,7 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re if (ret->size < min_revision) { ERROR (cinelerra_plugin, "plugin %s provides older interface %s revision than required", name, interface); - cinelerra_plugin_error_set (CINELERRA_PLUGIN_EREVISION); + CINELERRA_ERROR_SET (cinelerra_plugin, PLUGIN_REVISION); goto erevision; } @@ -276,7 +250,7 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re if (ret->open && ret->open()) { ERROR (cinelerra_plugin, "open hook indicated an error"); - cinelerra_plugin_error_set (CINELERRA_PLUGIN_EHOOK); + CINELERRA_ERROR_SET (cinelerra_plugin, PLUGIN_HOOK); goto eopen; } @@ -299,13 +273,14 @@ cinelerra_interface_open (const char* name, const char* interface, size_t min_re free (*found); *found = &plugin; tdelete (&plugin, &cinelerra_plugin_registry, cinelerra_plugin_name_cmp); - pthread_mutex_lock (&cinelerra_plugin_mutex); + pthread_mutex_unlock (&cinelerra_plugin_mutex); return NULL; } void cinelerra_interface_close (void* ptr) { + TRACE (cinelerra_plugin, "%p", ptr); if(!ptr) return; diff --git a/src/lib/plugin.h b/src/lib/plugin.h index 74ab964b3..b787870d2 100644 --- a/src/lib/plugin.h +++ b/src/lib/plugin.h @@ -30,6 +30,8 @@ extern "C" { #include #include +#include "error.h" + NOBUG_DECLARE_FLAG (cinelerra_plugin); /* tool macros*/ @@ -61,8 +63,6 @@ CINELERRA_INTERFACE_TYPE(iname, version) name##_##version = __VA_ARGS__ \ } -#define CINELERRA_INTERFACE_FUNC(protoname, funcname) funcname, - /* internally used */ @@ -90,6 +90,14 @@ struct cinelerra_interface int (*close)(void); }; +/** + * Initialize the plugin system. + * always succeeds or aborts + */ +void +cinelerra_init_plugin (void); + + /** * Make an interface available. * To use an interface provided by a plugin it must be opened first. It is allowed to open an interface more than once. @@ -129,30 +137,11 @@ cinelerra_plugin_unload (const char* plugin); void cinelerra_plugin_expire (time_t age); -/** - * Query and reset the error state. - * report last error, reset error state. Errors are thread local. - * Error strings are guaranteed to point to a C string with a unique comparable address. - * Note that the error state gets cleared by calling this function. The application may store it temporary for further handling. - * @return pointer to one of the error C-strings, NULL when no error happened. - */ -const char* -cinelerra_plugin_error (); - -/// success, NULL -extern const char* CINELERRA_PLUGIN_SUCCESS; -/// memory allocation error -extern const char* CINELERRA_PLUGIN_EALLOC; -/// dlopen failed -extern const char* CINELERRA_PLUGIN_EDLOPEN; -/// dlopen failed -extern const char* CINELERRA_PLUGIN_EHOOK; -/// Plugin not found -extern const char* CINELERRA_PLUGIN_ENFOUND; -/// no such interface -extern const char* CINELERRA_PLUGIN_ENIFACE; -/// revision not sufficient -extern const char* CINELERRA_PLUGIN_EREVISION; +CINELERRA_ERROR_DECLARE(PLUGIN_DLOPEN); +CINELERRA_ERROR_DECLARE(PLUGIN_HOOK); +CINELERRA_ERROR_DECLARE(PLUGIN_NFILE); +CINELERRA_ERROR_DECLARE(PLUGIN_NIFACE); +CINELERRA_ERROR_DECLARE(PLUGIN_REVISION); #ifdef __cplusplus } /* extern "C" */ diff --git a/src/main.cpp b/src/main.cpp index 3d4c1ef20..ccc1dd481 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,9 +26,14 @@ #include "cinelerra.h" using std::cout; +using std::endl; +using cinelerra::Appconfig; + int main (int argc, char* argv[]) { - cout << "hello cinelerra again\n"; + cout << "*** Cinelerra NLE for Linux ***" << endl + << " Version: " << Appconfig::get("version") << endl; + assert(true); return 0; } diff --git a/src/nobugcfg.h b/src/nobugcfg.h new file mode 100644 index 000000000..c89a284af --- /dev/null +++ b/src/nobugcfg.h @@ -0,0 +1,84 @@ +/* + NOBUGCFG.h - global configuration and definitions for NoBug + + + Copyright (C) CinelerraCV + 2007, 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 globally used flag + ** declarations are to be kept in one central location. Normally, + ** this header will be included by appconfig.hpp, which in turn gets + ** included by cinelerra.h + ** @par Besides the usual guarded declarations, this header contains + ** one section with the corresponding definitions. This section + ** is to be called by appconfig.cpp only, which deals with application + ** wide configuration values contained in the Singleton class Appconfig. + ** Incidentally, the constructor of Appconfig issues the NOBUG_INIT call + ** + */ + + +#ifndef NOBUGCFG_H /* ============= Part 1: DECLARATIONS ======== */ +#define NOBUGCFG_H + +#include + + /* configuration of NoBug goes here... */ + +#include + + + /* declare flags used throughout the code base... */ + NOBUG_DECLARE_FLAG(config); + NOBUG_DECLARE_FLAG(test); + + +#endif /*NOBUGCFG_H ======= (End) Part 1: DECLARATIONS ======== */ + + + + + + +#ifdef NOBUG_INIT_DEFS_ /*========== Part 2: DEFINITIONS ========= */ + +/* ================================= common C Part ========= */ + + + + + + +#ifdef __cplusplus /* ============== C++-Part ============== */ + + + /* flags used throughout the code base... */ + NOBUG_CPP_DEFINE_FLAG(config); + NOBUG_CPP_DEFINE_FLAG(test); + + + +#endif /* ===================== (End) C++-Part ============= */ + + + +#endif /*NOBUG_INIT_DEFS_ ==== (End) Part 2: DEFINITIONS ========= */ diff --git a/src/proc/mobject/session/relativeplacement.hpp b/src/proc/mobject/session/relativeplacement.hpp index ca3041928..1836d689d 100644 --- a/src/proc/mobject/session/relativeplacement.hpp +++ b/src/proc/mobject/session/relativeplacement.hpp @@ -44,8 +44,8 @@ namespace mobject * the possible kinds of RelativePlacements */ enum RelType - { SAMETIME /** place subject at the same time as the anchor */ - , ATTACH /** attach subject to anchor (e.g. an effect to a clip) */ + { SAMETIME /**< place subject at the same time as the anchor */ + , ATTACH /**< attach subject to anchor (e.g. an effect to a clip) */ }; protected: diff --git a/src/tool/SConscript b/src/tool/SConscript index f3a3abf76..fe3a35dcc 100644 --- a/src/tool/SConscript +++ b/src/tool/SConscript @@ -5,6 +5,13 @@ Import('env','artifacts') -# build the ubiquitous Hello World application (note: C source) -artifacts['tools'] = env.Program('#$BINDIR/hello-world','hello.c') +# at the moment (8/07), Ichthyo tries to find out how to configure NoBug +# does it help, if we set the NOBUG_LOG to the environment used for building?? +env = env.Clone() +env['ENV']['NOBUG_LOG'] = 'ttt:WARNING' + +# build the ubiquitous Hello World application (note: C source) +artifacts['tools'] = [ env.Program('#$BINDIR/hello-world','hello.c') + + env.Program('#$BINDIR/try', 'try.cpp') #### to try out some feature: + ] diff --git a/src/tool/try.cpp b/src/tool/try.cpp new file mode 100644 index 000000000..b948ada31 --- /dev/null +++ b/src/tool/try.cpp @@ -0,0 +1,35 @@ +/* try.cpp - for trying out some language features.... + * scons will create the binary bin/try + * + */ + +// 8/07 - how to control NOBUG?? + + +#include + +#define NOBUG_LOG_LIMIT LOG_ERR + +#include + +NOBUG_DECLARE_FLAG(ttt); + +NOBUG_DEFINE_FLAG(ttt); + +int main (int argc, char* argv[]) + { + + NOBUG_INIT; + + NOBUG_INIT_FLAG_LIMIT(ttt, LOG_WARNING); + + TRACE(ttt,"trace"); + INFO(ttt,"info"); + NOTICE(ttt,"notice"); + WARN(ttt,"warning"); + ERROR(ttt,"error"); + + TRACE(NOBUG_ON,"allways on?"); + + return 0; + } diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 000000000..cbfcd6fe3 --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1,4 @@ +,* +mainsuite +errortest +plugin-example diff --git a/tests/00test.tests b/tests/00test.tests new file mode 100644 index 000000000..0b894982b --- /dev/null +++ b/tests/00test.tests @@ -0,0 +1,13 @@ +TESTING "test system selftest" cat + +TEST "test cat'ing stdin to stdout" < +# 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 @@ -15,12 +16,12 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -examples_srcdir = $(top_srcdir)/tests/examples -noinst_PROGRAMS += plugin_example +tests_srcdir = $(top_srcdir)/tests -plugin_example_CFLAGS = $(CFLAGS) -std=gnu99 -Wall -Werror -plugin_example_CPPFLAGS = $(CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src/lib/ -plugin_example_LDADD = -lnobugmt -lpthread -ldl $(builddir)/libcin3.a +check_PROGRAMS += test-error -plugin_example_SOURCES = $(examples_srcdir)/plugin_main.c -noinst_HEADERS += $(examples_srcdir)/hello_interface.h +test_error_SOURCES = $(tests_srcdir)/error/errortest.c +test_error_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src/ +test_error_LDADD = $(builddir)/libcin3.a -lnobugmt -lpthread -ldl + +TESTS = $(tests_srcdir)/test.sh diff --git a/tests/SConscript b/tests/SConscript new file mode 100644 index 000000000..95ecdc0a7 --- /dev/null +++ b/tests/SConscript @@ -0,0 +1,76 @@ +# -*- python -*- +## +## SConscript - SCons buildscript for the Testsuite (called by SConstruct) +## + +from Buildhelper import srcSubtree +from Buildhelper import globRootdirs + +Import('env','artifacts','corelib') + + +def SingleTestExecutableSubdir(env,tree): + """ declare all targets needed to create a standalone + Test executalbe of the given Sub-tree. Note that + each subdir is built in its own Environment. + """ + env = env.Clone() + env.Append(CPPPATH=tree) # add Subdir to Includepath + tree = env.subst(tree) # expand Construction Vars + exeName = 'test-%s' % tree + objects = srcSubtree(env,tree) + return env.Program(exeName, objects + corelib) + + +def treatPluginTestcase(env): + """ Special case: the test-plugin executable + """ + env = env.Clone() + env.Append(CPPPATH='plugin') + testplugin = env.SharedLibrary('hello_1', 'plugin/example_plugin.c', SHLIBPREFIX='') + testExe = env.Program('test-plugin', ['plugin/plugin_main.c'] + corelib) + env.Depends(testExe, testplugin) + return testExe + #-- it depentds (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('*') + +# +# have to treat the plugin-example specially. +isnt_plugin = lambda dir : dir!='plugin' +moduledirs = filter(isnt_plugin, moduledirs) +pluginExe = treatPluginTestcase(env) +print 'moduledirs: %s' %moduledirs + +artifacts['testsuite'] = ts = [ SingleTestExecutableSubdir(env, dir) for dir in moduledirs] + pluginExe + + + + + + +# +# actually run the Testsuite +# +# - the product of running the Testsuite is the ",testlog" +# - it depends on all artifacts defined as "ts" above +# +runTs = env.Command(',testlog', ts, "./test.sh", chdir=1) + +env.Clean (runTs, [ ',*']) # declare tempfiles of test.sh as cleanable + + +# +# define Phony targets +# - 'scons testcode' triggers building of the Testsuite +# - 'scons check' triggers building and running +# +env.Alias('testcode', ts ) +env.Alias('check', runTs ) + diff --git a/tests/bugs/bugmain.c b/tests/bugs/bugmain.c new file mode 100644 index 000000000..4331f4516 --- /dev/null +++ b/tests/bugs/bugmain.c @@ -0,0 +1,28 @@ +/* + errortest.c - executable for running bug regression tests + + Copyright (C) CinelerraCV + 2007, 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. +*/ + +#include + +int main(int argc, char* argv[]) + { + printf("hello sunshine, noBugs whatsoever\n"); + return 0; + } diff --git a/tests/components/DIR_INFO b/tests/components/DIR_INFO new file mode 100644 index 000000000..55fe55def --- /dev/null +++ b/tests/components/DIR_INFO @@ -0,0 +1 @@ +Testsuite sourcecode tree diff --git a/tests/components/common/factorytest.cpp b/tests/components/common/factorytest.cpp new file mode 100644 index 000000000..37bc66587 --- /dev/null +++ b/tests/components/common/factorytest.cpp @@ -0,0 +1,54 @@ +/* + Factory(Test) - unittest for the object creating factory + + Copyright (C) CinelerraCV + 2007, 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. + +* *****************************************************/ + + +#include "helper/run.hpp" + + +namespace cinelerra + { + namespace test + { + + /** + * Target object to be created by the Test-Factory + */ + class TargetObj + { + public: + }; + + class Factory_test : public Test + { + virtual void run(Arg arg) + { + } + }; + + /** Register this test class to be invoked in some test groups (suites) */ + Launch run_Factory_test("Factory_test","unit common"); + + + + } // namespace test + +} // namespace cinelerra diff --git a/tests/components/common/helloworldtest.cpp b/tests/components/common/helloworldtest.cpp new file mode 100644 index 000000000..d22ad619d --- /dev/null +++ b/tests/components/common/helloworldtest.cpp @@ -0,0 +1,55 @@ +/* + HelloWorld(Test) - how to use this test framework... + + Copyright (C) CinelerraCV + 2007, 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. + +* *****************************************************/ + + +#include +#include "helper/run.hpp" + + +namespace cinelerra + { + namespace test + { + + + class HelloWorld_test : public Test + { + virtual void run(Arg arg) + { + greeting(); + } + + void greeting() + { + std::cout << "This is how the world ends...\n"; + } + }; + + + + /** Register this test class to be invoked in some test groups (suites) */ + Launch run_HelloWorld_test("HelloWorld_test","unit common"); + + + } // namespace test + +} // namespace cinelerra diff --git a/tests/components/helper/run.hpp b/tests/components/helper/run.hpp new file mode 100644 index 000000000..518ff37d2 --- /dev/null +++ b/tests/components/helper/run.hpp @@ -0,0 +1,92 @@ +/* + RUN.hpp - helper class for grouping, registering and invoking testcases + + Copyright (C) CinelerraCV + 2007, 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. + +*/ + + +#ifndef TESTHELPER_RUN_H +#define TESTHELPER_RUN_H + +#include +#include + +#include "helper/suite.hpp" + + +namespace test + { + + using std::string; + using std::auto_ptr; + + typedef std::vector * Arg; + + + + /** + * Abstract Base Class for all testcases. + * Typically, such testcases are created by a Launcher. + */ + class Test + { + public: + virtual ~Test() {} + virtual void run(Arg arg) = 0; + }; + + + + /** interface: generic testcase creating functor. */ + class Launcher + { + public: + virtual ~Launcher() {} + virtual auto_ptr operator() () = 0; + }; + + + /** + * Helper class for running a collection of tests. + * Launch objects are functors, which create on + * invocation an instance of the Test class + * they were created with. Creating such a + * Test Launcher internally registers this + * testcase with the Testsuite-Class, + * optionally under several groups + * (=categories, suite selections). + * @note a subclass of Launcher + */ + template + class Launch : public Launcher + { + public: + Launch (string testID, string groups) { Suite::enroll (this,testID,groups); }; + virtual auto_ptr operator() () { return auto_ptr (new TEST ); }; + }; + +} // namespace test + +// make them global for convienience +using ::test::Arg; +using ::test::Test; +using ::test::Launch; + +#endif diff --git a/tests/components/helper/suite.cpp b/tests/components/helper/suite.cpp new file mode 100644 index 000000000..6d8250cac --- /dev/null +++ b/tests/components/helper/suite.cpp @@ -0,0 +1,182 @@ +/* + Suite - helper class for running collections of tests + + Copyright (C) CinelerraCV + 2007, 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. + +* *****************************************************/ + + +#include +#include +#include +#include +#include +#include + +#include "helper/suite.hpp" +#include "helper/run.hpp" +#include "common/error.hpp" +#include "common/util.hpp" + +#include "nobugcfg.h" + + +namespace test + { + using std::map; + using std::vector; + using std::auto_ptr; + using std::tr1::shared_ptr; + + using util::isnil; + + typedef map TestMap; + typedef shared_ptr PTestMap; + typedef map GroupMap; + + + + /** helper to collect and manage the test cases. + * Every testcase class should create a Launch instance + * which causes a call to Suite::enroll(), so we can add a + * pointer to this Launcher into a map indexed by the + * provided testIDs and groupIDs. + * This enables us to build a Suite instance for any + * requested group and then instantiiate and invoke + * individual testcases accordingly. + */ + class Registry + { + auto_ptr groups; + public: + Registry() : groups(new GroupMap ) {}; + PTestMap& getGroup (string grpID) { return (*groups)[grpID]; }; + void add2group (Launcher* test, string testID, string groupID); + }; + + void + Registry::add2group (Launcher* test, string testID, string groupID) + { + REQUIRE( test ); + REQUIRE( !isnil(testID) ); + REQUIRE( !isnil(groupID) ); + + PTestMap& group = getGroup(groupID); + if (!group) + group.reset( new TestMap ); + (*group)[testID] = test; + } + + Registry testcases; + + + + + /** register the given test-launcher, so it can be later accessed + * either as a member of one of the specified groups, or direcly + * by its testID. Any test is automatically added to the groupID + * #ALLGROUP + * @param groups List of group-IDs selected by whitespace + */ + void + Suite::enroll (Launcher* test, string testID, string groups) + { + REQUIRE( test ); + REQUIRE( !isnil(testID) ); + + std::istringstream ss(groups); + string group; + while (ss >> group ) + testcases.add2group(test, testID, group); + + // Magic: allways add any testcas to groupID="ALL" + testcases.add2group(test,testID, ALLGROUP); + } + + /** "magic" groupID containing all registered testcases */ + const string Suite::ALLGROUP = "ALL"; + + + + /** create a suite comprised of all the testcases + * previously @link #enroll() registered @endlink with this + * this group. + * @see #run() running tests in a Suite + */ + Suite::Suite(string groupID) + : groupID_(groupID) + { + REQUIRE( !isnil(groupID) ); + TRACE(test, "Test-Suite( groupID=%s )\n", groupID.c_str () ); + + if (!testcases.getGroup(groupID)) + throw cinelerra::error::Invalid (); + //throw "empty testsuite"; /////////// TODO Errorhandling! + } + + + /** run all testcases contained in this Suite. + * The first argument in the commandline, if present, will select + * one single testcase with a matching ID. + */ + void + Suite::run (int argc, char* argv[]) + { + + PTestMap tests = testcases.getGroup(groupID_); + if (!tests) + throw cinelerra::error::Invalid (); + + if (argc >= 2) + { + if (Launcher* test = (*tests)[argv[1]]) + { + // first cmdline argument denotes a valid + // testcase registered in this group: + // go ahead and invoke just this test. + if (argc > 2) + { // pass additional cmdline as vector + vector arglist(argc-2); + for ( int i=2; irun(&arglist); + } + else + (*test)()->run(0); // without additional argumens + + return; + } + } + + // no test-ID was specified. + // instantiiate all tests cases and execute them. + for ( TestMap::iterator i=tests->begin(); i!=tests->end(); ++i ) + if (i->second) + { + std::cout << " ----------"<< i->first<< "----------\n"; + Launcher& test = *(i->second); + test()->run(0); // without cmdline arguments + } + + } + + + +} // namespace test diff --git a/tests/components/helper/suite.hpp b/tests/components/helper/suite.hpp new file mode 100644 index 000000000..8060aaab3 --- /dev/null +++ b/tests/components/helper/suite.hpp @@ -0,0 +1,60 @@ +/* + SUITE.hpp - helper class for running collections of tests + + Copyright (C) CinelerraCV + 2007, 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. + +*/ + + +#ifndef TESTHELPER_SUITE_H +#define TESTHELPER_SUITE_H + +#include + + + +namespace test + { + using std::string; + + // Forward decls needed for run.hpp + class Test; + class Launcher; + + + + /** + * Helper class for running a collection of tests. + * + */ + class Suite + { + string groupID_; + + public: + Suite (string groupID); + void run (int argc, char* argv[]); + static void enroll (Launcher *test, string testID, string groups); + + static const string ALLGROUP; + }; + + + +} // namespace test +#endif diff --git a/tests/components/mainsuite.cpp b/tests/components/mainsuite.cpp new file mode 100644 index 000000000..9ed0831fe --- /dev/null +++ b/tests/components/mainsuite.cpp @@ -0,0 +1,36 @@ +/* + mainsuite.cpp - "the" cinelerra3 self test suite + + Copyright (C) CinelerraCV + 2007, 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 "helper/suite.hpp" + + +/** run all tests or any single test specified in the first + * cmd line argument. + * Note: to ease debugging, we don't catch any exceptions. + */ +int main (int argc, char* argv[]) + { + test::Suite suite (test::Suite::ALLGROUP); + suite.run(argc,argv); + return 0; + } diff --git a/tests/error/DIR_INFO b/tests/error/DIR_INFO new file mode 100644 index 000000000..f5c354ef8 --- /dev/null +++ b/tests/error/DIR_INFO @@ -0,0 +1,3 @@ +example (test) code for errorhandling +The test application to be built from this directory shows how +to use the various error handling features. diff --git a/tests/error/errortest.c b/tests/error/errortest.c new file mode 100644 index 000000000..96d49b851 --- /dev/null +++ b/tests/error/errortest.c @@ -0,0 +1,67 @@ +/* + errortest.c - test error handling + + Copyright (C) CinelerraCV + 2007, 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. +*/ + +#include +#include + +#include "lib/error.h" + + +CINELERRA_ERROR_DEFINE(TEST, "test error"); + +int +main (int argc, char** argv) +{ + if (argc == 1) + return 0; + + if (!strcmp(argv[1], "set")) + { + cinelerra_error_set (CINELERRA_ERROR_TEST); + } + + if (!strcmp(argv[1], "get_no")) + { + const char* err; + err = cinelerra_error (); + printf ("%p\n", err); + } + + if (!strcmp(argv[1], "get")) + { + cinelerra_error_set (CINELERRA_ERROR_TEST); + const char* err; + err = cinelerra_error (); + printf ("%s\n", err); + } + + if (!strcmp(argv[1], "get2")) + { + cinelerra_error_set (CINELERRA_ERROR_TEST); + const char* err; + err = cinelerra_error (); + printf ("%s\n", err); + err = cinelerra_error (); + printf ("%p\n", err); + } + + return 0; +} diff --git a/tests/examples/example_plugin.c b/tests/examples/example_plugin.c deleted file mode 100644 index 1a294b8bf..000000000 --- a/tests/examples/example_plugin.c +++ /dev/null @@ -1,44 +0,0 @@ -#include - -#include "hello_interface.h" - -int myopen(void) -{ - printf("opened\n"); -} - -int myclose(void); -{ - printf("closed\n"); -} - -int hallo(void) -{ - printf("Hallo Welt!\n"); -} - -int tschuess(const char* m) -{ - printf("Tschues %s\n", m); -} - -int hello(void); -{ - printf("Hello world!\n"); -} - -int bye(const char* m) -{ - printf("bye %s\n", m); - -} - -CINELERRA_INTERFACE_IMPLEMENT(hello, 1, german, myopen, myclose, - CINELERRA_INTERFACE_FUNC(hello, hallo), - CINELERRA_INTERFACE_FUNC(goodbye, tschuess) - ); - -CINELERRA_INTERFACE_IMPLEMENT(hello, 1, english, myopen, myclose, - CINELERRA_INTERFACE_FUNC(hello, hello), - CINELERRA_INTERFACE_FUNC(goodbye, bye) - ); diff --git a/tests/examples/plugin_main.c b/tests/examples/plugin_main.c deleted file mode 100644 index 427f88655..000000000 --- a/tests/examples/plugin_main.c +++ /dev/null @@ -1,55 +0,0 @@ - - -#include "plugin.h" -#include "hello_interface.h" - - -int -main(int argc, char** argv) -{ - /* - we have a plugin 'hello_1' which provides us 2 hello interfaces, one for english and one for german output, - open both try them, close them. - */ - - TODO("macros, doing casting and typing"); - - CINELERRA_INTERFACE_TYPE(hello, 1)* hello_de = (CINELERRA_INTERFACE_TYPE(hello, 1)*) - cinelerra_interface_open ("hello_1", "german_1", sizeof(CINELERRA_INTERFACE_TYPE(hello, 1))); - TODO("new error handling, when finished if (!hello_de) CINELERRA_DIE"); - - hello_de->hello(); - - - // struct hello_interface_1* hello_en = - // cinelerra_interface_open ("hello_1", "english_1", sizeof(struct hello_interface_1)); - // TODO if (!hello_en) CINELERRA_DIE; - - //hello_en->hello(); - - //cinelerra_interface_close (hello_en); - cinelerra_interface_close (hello_de); - -#if 0 - /* - same again for a plugin written in C++ - */ - hello_de = - cinelerra_interface_open ("hellocpp_1", "german_1", sizeof(struct hello_interface_1)); - if (!hello_de) CINELERRA_DIE; - - hello_de->say_hello(); - - - hello_en = - cinelerra_interface_open ("hellocpp_1", "english_1", sizeof(struct hello_interface_1)); - if (!hello_en) CINELERRA_DIE; - - hello_en->say_hello(); - - cinelerra_interface_close (hello_en); - cinelerra_interface_close (hello_de); -#endif - - return 0; -} diff --git a/tests/examples/DIR_INFO b/tests/plugin/DIR_INFO similarity index 73% rename from tests/examples/DIR_INFO rename to tests/plugin/DIR_INFO index 2c5e28d26..19ed2b9e2 100644 --- a/tests/examples/DIR_INFO +++ b/tests/plugin/DIR_INFO @@ -1,3 +1,3 @@ -working example code +working example code for cinelerra's plugin system This directory contains example code which shows how to use specific features. All examples will be build and run as part of the testsuite diff --git a/tests/plugin/Makefile.am b/tests/plugin/Makefile.am new file mode 100644 index 000000000..7beeacc75 --- /dev/null +++ b/tests/plugin/Makefile.am @@ -0,0 +1,37 @@ +# Copyright (C) CinelerraCV +# 2007, 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. + +examples_srcdir = $(top_srcdir)/tests/plugin +noinst_PROGRAMS += test-plugin + +test_plugin_CFLAGS = $(AM_CFLAGS) -std=gnu99 -Wall -Werror +test_plugin_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src +test_plugin_LDADD = $(builddir)/libcin3.a -lnobugmt -lpthread -ldl +test_plugin_SOURCES = $(examples_srcdir)/plugin_main.c + +noinst_HEADERS += $(examples_srcdir)/hello_interface.h + +check_LTLIBRARIES += example_plugin.la example_plugin_cpp.la +example_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src +example_plugin_la_SOURCES = $(examples_srcdir)/example_plugin.c +# the -rpath option is required, prolly a automake bug? +example_plugin_la_LDFLAGS = -avoid-version -module -rpath $(shell pwd) + +example_plugin_cpp_la_CPPFLAGS = $(AM_CPPFLAGS) -Wall -Werror -I$(top_srcdir)/src +example_plugin_cpp_la_SOURCES = $(examples_srcdir)/example_plugin.cpp +# the -rpath option is required, prolly a automake bug? +example_plugin_cpp_la_LDFLAGS = -avoid-version -module -rpath $(shell pwd) diff --git a/tests/plugin/example_plugin.c b/tests/plugin/example_plugin.c new file mode 100644 index 000000000..ebb71ae8a --- /dev/null +++ b/tests/plugin/example_plugin.c @@ -0,0 +1,45 @@ +#include + +#include "hello_interface.h" + +int myopen(void) +{ + printf("opened\n"); + return 0; +} + +int myclose(void) +{ + printf("closed\n"); + return 0; +} + +void hallo(void) +{ + printf("Hallo Welt!\n"); +} + +void tschuess(const char* m) +{ + printf("Tschuess %s\n", m); +} + +void hello(void) +{ + printf("Hello World!\n"); +} + +void bye(const char* m) +{ + printf("Bye %s\n", m); +} + +CINELERRA_INTERFACE_IMPLEMENT(hello, 1, german, myopen, myclose, + hallo, + tschuess + ); + +CINELERRA_INTERFACE_IMPLEMENT(hello, 1, english, myopen, myclose, + hello, + bye + ); diff --git a/tests/plugin/example_plugin.cpp b/tests/plugin/example_plugin.cpp new file mode 100644 index 000000000..b608887d8 --- /dev/null +++ b/tests/plugin/example_plugin.cpp @@ -0,0 +1,61 @@ +#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; + } +}; + + +CINELERRA_INTERFACE_IMPLEMENT(hello, 1, german, example_plugin_de::myopen, example_plugin_de::myclose, + example_plugin_de::hello, + example_plugin_de::bye + ); + +CINELERRA_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/examples/hello_interface.h b/tests/plugin/hello_interface.h similarity index 89% rename from tests/examples/hello_interface.h rename to tests/plugin/hello_interface.h index 183a22c54..ccec270ed 100644 --- a/tests/examples/hello_interface.h +++ b/tests/plugin/hello_interface.h @@ -1,4 +1,4 @@ -#include "plugin.h" +#include "lib/plugin.h" CINELERRA_INTERFACE(hello, 1, CINELERRA_INTERFACE_PROTO(void, hello, (void)) diff --git a/tests/plugin/plugin_main.c b/tests/plugin/plugin_main.c new file mode 100644 index 000000000..e691438b3 --- /dev/null +++ b/tests/plugin/plugin_main.c @@ -0,0 +1,69 @@ +#include + +#include "lib/plugin.h" +#include "hello_interface.h" + + +int +main(int argc, char** argv) +{ + NOBUG_INIT; + + if (argc < 2) + return -1; + + cinelerra_init_plugin (); + /* + we have a plugin 'hello_1' which provides us 2 hello interfaces, one for english and one for german output, + open both try them, close them. + */ + + TODO("macros, doing casting and typing"); + + if( !strcmp(argv[1],"C")) + { + CINELERRA_INTERFACE_TYPE(hello, 1)* hello_de = + (CINELERRA_INTERFACE_TYPE(hello, 1)*) cinelerra_interface_open ("example_plugin", "german_1", sizeof(CINELERRA_INTERFACE_TYPE(hello, 1))); + + if (!hello_de) CINELERRA_DIE; + + hello_de->hello(); + hello_de->goodbye(argv[1]); + + CINELERRA_INTERFACE_TYPE(hello, 1)* hello_en = + (CINELERRA_INTERFACE_TYPE(hello, 1)*) cinelerra_interface_open ("example_plugin", "english_1", sizeof(CINELERRA_INTERFACE_TYPE(hello, 1))); + + if (!hello_en) CINELERRA_DIE; + + hello_en->hello(); + hello_en->goodbye(argv[1]); + + cinelerra_interface_close (hello_en); + cinelerra_interface_close (hello_de); + } + + if( !strcmp(argv[1],"C++")) + { + /* same again for a plugin written in C++ */ + CINELERRA_INTERFACE_TYPE(hello, 1)* hello_de = + (CINELERRA_INTERFACE_TYPE(hello, 1)*) cinelerra_interface_open ("example_plugin_cpp", "german_1", sizeof(CINELERRA_INTERFACE_TYPE(hello, 1))); + + if (!hello_de) CINELERRA_DIE; + + hello_de->hello(); + hello_de->goodbye(argv[1]); + + CINELERRA_INTERFACE_TYPE(hello, 1)* hello_en = + (CINELERRA_INTERFACE_TYPE(hello, 1)*) cinelerra_interface_open ("example_plugin_cpp", "english_1", sizeof(CINELERRA_INTERFACE_TYPE(hello, 1))); + + if (!hello_en) CINELERRA_DIE; + + hello_en->hello(); + hello_en->goodbye(argv[1]); + + cinelerra_interface_close (hello_en); + cinelerra_interface_close (hello_de); + } + + return 0; +} diff --git a/tests/test.sh b/tests/test.sh new file mode 100755 index 000000000..ed8d6a35b --- /dev/null +++ b/tests/test.sh @@ -0,0 +1,214 @@ +#!/bin/bash +# Copyright (C) CinelerraCV +# 2007, 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. + +# TESTMODE=FULL yet unimplemented +# run all tests, PLANNED which fail count as error +# +# TESTMODE=FAST +# run only tests which recently failed +# +# TESTMODE=FIRSTFAIL +# stop testing on the first failure + +export LC_ALL=C + +arg0="$0" +srcdir=$(dirname "$arg0") + +ulimit -S -t 1 -v 524288 +valgrind="" +if [ "$VALGRINDFLAGS" = 'DISABLE' ]; then + echo "valgrind explicit disabled" +else + if [ "$(which valgrind)" ]; then + valgrind="$(which valgrind) --leak-check=yes --show-reachable=yes -q $VALGRINDFLAGS" + ulimit -S -t 10 + else + echo "no valgrind found, go without it" + fi +fi + +echo +echo ================ ${0##*/} ================ + +TESTCNT=0 +SKIPCNT=0 +FAILCNT=0 + +# the old testlog if existing will be used to check for previous test states +if test -f ,testlog; then + mv ,testlog ,testlog.pre +else + touch ,testlog.pre +fi + +date >,testlog + +function TEST() +{ + name="$1" + shift + rm -f ,send_stdin + rm -f ,expect_stdout + rm -f ,expect_stderr + + while read -r line; do + cmd="${line%%:*}" + arg="${line#*: }" + expect_return=0 + + case $cmd in + 'in') + echo "$arg" >>,send_stdin + ;; + 'out') + echo "$arg" >>,expect_stdout + ;; + 'err') + echo "$arg" >>,expect_stderr + ;; + 'return') + expect_return=$arg + ;; + *) + echo "UNKOWN TEST COMMAND '$cmd'" 1>&2 + exit + ;; + esac + done + echo -n "TEST $name: " + echo -en "\nTEST $name: $* " >>,testlog + + case $TESTMODE in + *FAST*) + if grep "^TEST $name: .* FAILED" ,testlog.pre >&/dev/null; then + MSGOK=" (fixed)" + MSGFAIL=" (still broken)" + elif grep "^TEST $name: .* \\(SKIPPED (ok)\\|OK\\)" ,testlog.pre >&/dev/null; then + echo ".. SKIPPED (ok)" + echo ".. SKIPPED (ok)" >>,testlog + SKIPCNT=$(($SKIPCNT + 1)) + TESTCNT=$(($TESTCNT + 1)) + return + else + MSGOK=" (new)" + MSGFAIL=" (new)" + fi + ;; + *) + MSGOK="" + MSGFAIL="" + ;; + esac + + TESTCNT=$(($TESTCNT + 1)) + + fails=0 + + + if test -f ,send_stdin; then + cat ,send_stdin | $valgrind $TESTBIN "$@" 2>,stderr >,stdout + else + $valgrind $TESTBIN "$@" 2>,stderr >,stdout + fi &>/dev/null + return=$? + + echo -n >,testtmp + + if test -f ,expect_stdout; then + if ! cmp ,expect_stdout ,stdout &>/dev/null; then + echo "unexpected data on stdout" >>,testtmp + grep -v ': \(TRACE\|INFO\|NOTICE\|WARNING\|ERR\):' <,stdout >,tmp + diff -ua ,expect_stdout ,tmp >>,testtmp + rm ,tmp + ((fails+=1)) + fi + fi + + if test -f ,expect_stderr; then + if ! cmp ,expect_stderr ,stderr &>/dev/null; then + echo "unexpected data on stderr" >>,testtmp + grep -v ': \(TRACE\|INFO\|NOTICE\|WARNING\|ERR\):' <,stderr >,tmp + diff -ua ,expect_stderr ,tmp >>,testtmp + rm ,tmp + ((fails+=1)) + fi + fi + + if test $expect_return != $return; then + echo "unexpected return value $return" >>,testtmp + ((fails+=1)) + fi + + if test $fails -eq 0; then + echo ".. OK$MSGOK" + echo ".. OK$MSGOK" >>,testlog + else + echo ".. FAILED$MSGFAIL"; + echo ".. FAILED$MSGFAIL" >>,testlog + cat ,testtmp >>,testlog + rm ,testtmp + echo "stderr was:" >>,testlog + cat ,stderr >>,testlog + echo END >>,testlog + FAILCNT=$(($FAILCNT + 1)) + case $TESTMODE in + *FIRSTFAIL*) + break 2 + ;; + esac + fi +} + +function PLANNED() +{ + echo -n "PLANNED $1: " + echo -en "\nPLANNED $* " >>,testlog + echo ".. SKIPPED (planned)" + echo ".. SKIPPED (planned)" >>,testlog + SKIPCNT=$(($SKIPCNT + 1)) + TESTCNT=$(($TESTCNT + 1)) +} + +function RUNTESTS() +{ + for i in $srcdir/*.tests; do + source $i + done + echo + if [ $FAILCNT = 0 ]; then + echo " ... PASSED $(($TESTCNT - $SKIPCNT)) TESTS, $SKIPCNT SKIPPED" + #rm ,testlog + else + echo " ... SUCCEDED $(($TESTCNT - $FAILCNT - $SKIPCNT)) TESTS" + echo " ... FAILED $FAILCNT TESTS" + echo " ... SKIPPED $SKIPCNT TESTS" + echo " see ',testlog' for details" + exit 1 + fi +} + +function TESTING() +{ + echo + echo "$1" + TESTBIN=$2 +} + +RUNTESTS diff --git a/uml/cinelerra3/128517 b/uml/cinelerra3/128517 index 8683426d4..60ea7208b 100644 --- a/uml/cinelerra3/128517 +++ b/uml/cinelerra3/128517 @@ -1,6 +1,6 @@ -format 38 +format 40 "CommonLib" // CommonLib - revision 6 + revision 9 modified_by 5 "hiv" // class settings //class diagram settings @@ -8,7 +8,7 @@ format 38 //use case diagram settings package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default //sequence diagram settings - show_full_operations_definition default write_horizontally default drawing_language default draw_all_relations default shadow default + show_full_operations_definition default write_horizontally default class_drawing_mode default drawing_language default draw_all_relations default shadow default //collaboration diagram settings show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default //object diagram settings @@ -26,6 +26,216 @@ format 38 package_name_in_tab default show_context default show_opaque_action_definition default auto_label_position default write_flow_label_horizontally default draw_all_relations default shadow default show_infonote default drawing_language default + classview 128773 "error" + //class diagram settings + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + //collaboration diagram settings + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + //object diagram settings + write_horizontally default package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default + //sequence diagram settings + show_full_operations_definition default write_horizontally default class_drawing_mode default drawing_language default draw_all_relations default shadow default + //state diagram settings + package_name_in_tab default show_context default auto_label_position default write_trans_label_horizontally default show_trans_definition default draw_all_relations default shadow default + show_activities default region_horizontally default drawing_language default + //class settings + //activity diagram settings + package_name_in_tab default show_context default show_opaque_action_definition default auto_label_position default write_flow_label_horizontally default draw_all_relations default shadow default + show_infonote default drawing_language default + + classdiagram 130181 "Hierarchy" + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + comment "Cinelerra Exception hierarchy" + size A4 + end + + class 135557 "Error" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + classrelation 139781 // + relation 137989 ---|> + a public + cpp default "${type}" + classrelation_ref 139781 // + b multiplicity "" parent class_ref 136325 // std::exception + end + + operation 131845 "what" + const cpp_virtual public explicit_return_type "const char*" + nparams 0 + cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${)}${const}${volatile} ${throw}${abstract};" + cpp_def "${comment}${inline}${type} +${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} +{ + ${body} +} + +" + + + end + + operation 131973 "rootCause" + public explicit_return_type "std::exception" + nparams 0 + cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${)}${const}${volatile} ${throw}${abstract};" + cpp_def "${comment}${inline}${type} +${class}::${name} ${(}${)}${const}${volatile} ${throw}${staticnl} +{ + ${body} +} + +" + + + comment "If this exception was caused by a chain of further exceptions, +return the first one registered in this throw sequence. +This works only, if every exceptions thrown as a consequence +of another exception is propperly constructed by passing +the original exception to the constructor" + end + + attribute 130309 "cause" + private type class_ref 136325 // std::exception + stereotype "auto_ptr" + cpp_decl " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value}; +" + java_decl "" + idl_decl "" + comment "a copy of the first exception encountered in this exception chain" + end + end + + class 135685 "Logic" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + classrelation 139397 // + relation 137605 ---|> + a public + cpp default "${type}" + classrelation_ref 139397 // + b multiplicity "" parent class_ref 135557 // Error + end + end + + class 135813 "Config" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + classrelation 139269 // + relation 137477 ---|> + a public + cpp default "${type}" + classrelation_ref 139269 // + b multiplicity "" parent class_ref 135557 // Error + end + end + + class 135941 "State" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + classrelation 139141 // + relation 137349 ---|> + a public + cpp default "${type}" + classrelation_ref 139141 // + b multiplicity "" parent class_ref 135557 // Error + end + end + + class 136069 "Invalid" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + classrelation 139525 // + relation 137733 ---|> + a public + cpp default "${type}" + classrelation_ref 139525 // + b multiplicity "" parent class_ref 135557 // Error + end + end + + class 136197 "External" + visibility package + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + classrelation 139653 // + relation 137861 ---|> + a public + cpp default "${type}" + classrelation_ref 139653 // + b multiplicity "" parent class_ref 135557 // Error + end + end + + class 136325 "std::exception" + visibility public stereotype "auxiliary" + cpp_external cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + operation 131717 "what" + const cpp_virtual public explicit_return_type "const char*" + nparams 0 + cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${)}${const}${volatile} ${throw}${abstract};" + + + comment "the base class of all exceptions thrown by the standard library" + end + end + end + classview 128645 "Service Components" //class diagram settings draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default @@ -34,7 +244,7 @@ format 38 //object diagram settings write_horizontally default package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default //sequence diagram settings - show_full_operations_definition default write_horizontally default drawing_language default draw_all_relations default shadow default + show_full_operations_definition default write_horizontally default class_drawing_mode default drawing_language default draw_all_relations default shadow default //state diagram settings package_name_in_tab default show_context default auto_label_position default write_trans_label_horizontally default show_trans_definition default draw_all_relations default shadow default show_activities default region_horizontally default drawing_language default @@ -58,6 +268,91 @@ ${inlines} investigate posix.4 realtime timers, wrap these here" end + + class 135301 "Factory" + visibility public + nformals 1 + formal name "T" type "class" explicit_default_value "" + explicit_extends "" + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + comment "a template for generating functor-like Factory objects, used to encapsulate object creation and providing access via smart-pointers only." + end + + class 135429 "Appconfig" + visibility public stereotype "singleton" + cpp_decl "${comment}${template}class ${name}${inherit} + { +${members} }; +${inlines} +" + java_decl "" + idl_decl "" + explicit_switch_type "" + + comment "Singleton to hold inevitable global flags and constants and for performing erarly (static) global initialization tasks." + attribute 130181 "theApp_" + class_attribute private type class_ref 135429 // Appconfig + init_value "=0" + cpp_decl " ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value}; +" + java_decl "" + idl_decl "" + comment "holds the single instance and triggers initialization" + end + + operation 131333 "Appconfig" + private explicit_return_type "" + nparams 0 + cpp_decl " ${comment}${inline}${name} ${(}${)}${volatile} ${throw};" + cpp_def "${comment}${inline} +${class}::${name} ${(}${)}${volatile} ${throw} +{ + ${body} +} + +" + + + comment "perform initialization on first access. +A call is placed in static initialization code +included in cinelerra.h; thus it will happen +ubiquitous very early." + end + + operation 131461 "instance" + class_operation private explicit_return_type "Appconfig*" + nparams 0 + cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${)}${const}${volatile} ${throw}${abstract};" + + + end + + operation 131589 "get" + class_operation public explicit_return_type "string" + nparams 1 + param inout name "key" explicit_type "string" + cpp_decl " ${comment}${friend}${static}${inline}${virtual}${type} ${name} ${(}${t0} & ${p0}${)}${const}${volatile} ${throw}${abstract};" + cpp_def "${comment}${inline}${type} +${class}::${name} ${(}${t0} & ${p0}${)}${const}${volatile} ${throw}${staticnl} +{ + ${body} +} + +" + + + comment "access the configuation value for a given key. +@return empty string for unknown keys, else the corresponding configuration value" + end + end end classview 128138 "Posix Threads Abstraction" @@ -68,7 +363,7 @@ investigate posix.4 realtime timers, wrap these here" //object diagram settings write_horizontally default package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default //sequence diagram settings - show_full_operations_definition default write_horizontally default drawing_language default draw_all_relations default shadow default + show_full_operations_definition default write_horizontally default class_drawing_mode default drawing_language default draw_all_relations default shadow default //state diagram settings package_name_in_tab default show_context default auto_label_position default write_trans_label_horizontally default show_trans_definition default draw_all_relations default shadow default show_activities default region_horizontally default drawing_language default @@ -148,7 +443,7 @@ ${inlines} //object diagram settings write_horizontally default package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default //sequence diagram settings - show_full_operations_definition default write_horizontally default drawing_language default draw_all_relations default shadow default + show_full_operations_definition default write_horizontally default class_drawing_mode default drawing_language default draw_all_relations default shadow default //state diagram settings package_name_in_tab default show_context default auto_label_position default write_trans_label_horizontally default show_trans_definition default draw_all_relations default shadow default show_activities default region_horizontally default drawing_language default @@ -159,7 +454,7 @@ ${inlines} class 128906 "SmartPointer" abstract visibility package stereotype "auxiliary" - cpp_decl "${comment}${template}class ${name}${inherit} { + cpp_external cpp_decl "${comment}${template}class ${name}${inherit} { ${members}}; ${inlines} " diff --git a/uml/cinelerra3/129413 b/uml/cinelerra3/129413 index e8dca4ded..fa3bd529e 100644 --- a/uml/cinelerra3/129413 +++ b/uml/cinelerra3/129413 @@ -1,6 +1,6 @@ format 40 "common" // design::codegen::common - revision 11 + revision 13 modified_by 5 "hiv" // class settings //class diagram settings @@ -39,6 +39,89 @@ Common library and helper classes" package_name_in_tab default show_context default write_horizontally default auto_label_position default draw_all_relations default shadow default draw_component_as_icon default show_component_req_prov default show_component_rea default comment "defines source files to be generated by BOUML" + artifact 135813 "error" + stereotype "source" + cpp_h "/* + ${NAME}.hpp - ${description} +@{CopyrightClaim}@{GPLHeader} +*/ + + +#ifndef ${NAMESPACE}_${NAME}_H +#define ${NAMESPACE}_${NAME}_H + +${includes} +${declarations} + + +${namespace_start} + +${definition} +${namespace_end} +#endif +" + cpp_src "/* + ${Name} - ${description} +@{CopyrightClaim}@{GPLHeader} +* *****************************************************/ + + +${includes} +${namespace_start} + + +${members} +${namespace_end}" + associated_classes + class_ref 135557 // Error + class_ref 135685 // Logic + class_ref 135813 // Config + class_ref 135941 // State + class_ref 136069 // Invalid + class_ref 136197 // External + end + comment "Cinelerra Exception Interface" + end + + artifact 135173 "appconfig" + stereotype "source" + cpp_h "/* + ${NAME}.hpp - ${description} +@{CopyrightClaim}@{GPLHeader} +*/ + + +#ifndef ${NAMESPACE}_${NAME}_H +#define ${NAMESPACE}_${NAME}_H + +${includes} +${declarations} + + +${namespace_start} + +${definition} +${namespace_end} +#endif +" + cpp_src "/* + ${Name} - ${description} +@{CopyrightClaim}@{GPLHeader} +* *****************************************************/ + + +${includes} +${namespace_start} + + +${members} +${namespace_end}" + associated_classes + class_ref 135429 // Appconfig + end + comment "for global initialization and configuration " + end + artifact 134789 "time" stereotype "source" cpp_h "/* @@ -78,4 +161,6 @@ ${namespace_end}" comment "unified representation of a time point, including conversion functions" end end + + package_ref 130821 // error end diff --git a/uml/cinelerra3/130181.diagram b/uml/cinelerra3/130181.diagram new file mode 100644 index 000000000..68704453b --- /dev/null +++ b/uml/cinelerra3/130181.diagram @@ -0,0 +1,74 @@ +format 40 + +classcanvas 128005 class_ref 135557 // Error + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 254 162 2000 + end +classcanvas 128133 class_ref 135685 // Logic + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 87 361 2000 + end +classcanvas 128261 class_ref 135813 // Config + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 175 361 2000 + end +classcanvas 128389 class_ref 135941 // State + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 267 361 2000 + end +classcanvas 128517 class_ref 136069 // Invalid + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 355 361 2000 + end +classcanvas 128645 class_ref 136197 // External + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 444 361 2000 + end +packagecanvas 130821 + package_ref 130821 // error + show_context_mode namespace xyzwh 55 258 1994 472 162 +classcanvas 130949 class_ref 136325 // std::exception + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + xyz 409 43 2000 + end +relationcanvas 128773 relation_ref 137349 // + geometry VHV + from ref 128389 z 1999 to point 287 304 + line 130565 z 1999 to point 287 304 + line 130693 z 1999 to ref 128005 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 128901 relation_ref 137477 // + geometry VHV + from ref 128261 z 1999 to point 197 304 + line 130053 z 1999 to point 287 304 + line 130181 z 1999 to ref 128005 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 129029 relation_ref 137605 // + geometry VHV + from ref 128133 z 1999 to point 107 304 + line 130309 z 1999 to point 287 304 + line 130437 z 1999 to ref 128005 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 129157 relation_ref 137733 // + geometry VHV + from ref 128517 z 1999 to point 376 304 + line 129797 z 1999 to point 287 304 + line 129925 z 1999 to ref 128005 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 129285 relation_ref 137861 // + geometry VHV + from ref 128645 z 1999 to point 469 304 + line 129541 z 1999 to point 287 304 + line 129669 z 1999 to ref 128005 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +relationcanvas 131077 relation_ref 137989 // + from ref 128005 z 1999 to point 450 181 + line 131205 z 1999 to ref 130949 + no_role_a no_role_b + no_multiplicity_a no_multiplicity_b +end diff --git a/uml/cinelerra3/130821 b/uml/cinelerra3/130821 new file mode 100644 index 000000000..2823b3193 --- /dev/null +++ b/uml/cinelerra3/130821 @@ -0,0 +1,33 @@ +format 40 +"error" // design::codegen::common::error + revision 1 + modified_by 5 "hiv" + // class settings + //class diagram settings + draw_all_relations default hide_attributes default hide_operations default show_members_full_definition default show_members_visibility default show_members_stereotype default show_parameter_dir default show_parameter_name default package_name_in_tab default class_drawing_mode default drawing_language default show_context_mode default auto_label_position default show_infonote default shadow default + //use case diagram settings + package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default + //sequence diagram settings + show_full_operations_definition default write_horizontally default class_drawing_mode default drawing_language default draw_all_relations default shadow default + //collaboration diagram settings + show_full_operations_definition default show_hierarchical_rank default write_horizontally default drawing_language default package_name_in_tab default show_context default draw_all_relations default shadow default + //object diagram settings + write_horizontally default package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default + //component diagram settings + package_name_in_tab default show_context default auto_label_position default draw_all_relations default shadow default + draw_component_as_icon default show_component_req_prov default show_component_rea default + //deployment diagram settings + package_name_in_tab default show_context default write_horizontally default auto_label_position default draw_all_relations default shadow default + draw_component_as_icon default show_component_req_prov default show_component_rea default + //state diagram settings + package_name_in_tab default show_context default auto_label_position default write_trans_label_horizontally default show_trans_definition default draw_all_relations default shadow default + show_activities default region_horizontally default drawing_language default + //activity diagram settings + package_name_in_tab default show_context default show_opaque_action_definition default auto_label_position default write_flow_label_horizontally default draw_all_relations default shadow default + show_infonote default drawing_language default + + cpp_h_dir "common" + cpp_src_dir "common" + cpp_namespace "cinelerra::error" + comment "Namespace for Exception Kinds" +end diff --git a/uml/cinelerra3/5.session b/uml/cinelerra3/5.session index 65a46ae7d..431e0a5d0 100644 --- a/uml/cinelerra3/5.session +++ b/uml/cinelerra3/5.session @@ -1,9 +1,24 @@ window_sizes 1104 756 270 824 557 120 +diagrams + active classdiagram_ref 130181 // Hierarchy + 762 514 100 4 0 0 +end show_stereotypes -selected -package_ref 129 // cinelerra3 +selected artifact_ref 135813 // error open + deploymentview_ref 128261 // gen + deploymentview_ref 128773 // gen -package_ref 129669 // proc + package_ref 129797 // gui + + package_ref 129285 // ProcessingLayer + class_ref 135685 // Logic + class_ref 135813 // Config + class_ref 135941 // State + class_ref 136069 // Invalid + class_ref 136197 // External + class_ref 136325 // std::exception + class_ref 135429 // Appconfig + classview_ref 128266 // SmartPointers end end diff --git a/wiki/.gitignore b/wiki/.gitignore deleted file mode 100644 index 1fb9ef574..000000000 --- a/wiki/.gitignore +++ /dev/null @@ -1 +0,0 @@ -tmp/* diff --git a/wiki/index.html b/wiki/index.html index 51da7bc71..7a5c333ce 100755 --- a/wiki/index.html +++ b/wiki/index.html @@ -42,7 +42,7 @@ DAMAGE. -
My TiddlyWiki is loading ...

Requires Javascript.
+
Cinelerra TiddlyWiki is loading ...

Requires Javascript.
Cinelerra3 - Distributed Developer Wiki