augmented (static) App initialsation, reorganized NoBug includes...

This commit is contained in:
Fischlurch 2007-08-17 00:36:07 +02:00
parent 358b9050e9
commit db1a35ca94
17 changed files with 296 additions and 67 deletions

View file

@ -59,14 +59,13 @@ def setupBasicEnvironment():
, SRCDIR=SRCDIR
, BINDIR=BINDIR
, CPPPATH="#"+SRCDIR # used to find includes, "#" means always absolute to build-root
, CPPDEFINES=[] # flags will be appended to this list
, CPPDEFINES=['-DCINELERRA_VERSION=\\"%s\\"' % VERSION ] # note: make it a list to append further defines
)
handleNoBugSwitches(env)
appendCppDefine(env,'DEBUG','DEBUG', 'NDEBUG')
appendCppDefine(env,'OPENGL','USE_OPENGL')
appendCppDefine(env,'VERSION','VERSION')
appendVal(env,'ARCHFLAGS', 'CPPFLAGS') # for both C and C++
appendVal(env,'OPTIMIZE', 'CPPFLAGS', val=' -O3')
appendVal(env,'DEBUG', 'CPPFLAGS', val=' -g')
@ -215,17 +214,17 @@ def defineBuildTargets(env, artifacts):
+ srcSubtree(env,'proc')
+ srcSubtree(env,'common')
# + srcSubtree(env,'lib')
+ env.Object('$SRCDIR/main.cpp')
)
applobj = cinobj + env.Object('$SRCDIR/main.cpp')
testobj = srcSubtree(env,'test/*', isShared=False)
plugobj = srcSubtree(env,'plugin', isShared=True)
artifacts['cinelerra'] = env.Program('$BINDIR/cinelerra', cinobj)
artifacts['cinelerra'] = env.Program('$BINDIR/cinelerra', applobj)
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 testobj')
SConscript(dirs=[TESTDIR], exports='env artifacts cinobj testobj')
def defineInstallTargets(env, artifacts):

View file

@ -25,7 +25,6 @@
#ifndef CINELERRA_H
#define CINELERRA_H
#include <nobug.h>
#ifdef __cplusplus
@ -41,14 +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"
#include "common/appconfig.hpp" // includes NoBug via "nobugcfg.h"
#include "common/error.hpp"
namespace cinelerra

View file

@ -22,21 +22,32 @@
#include "common/appconfig.hpp"
#include "common/error.hpp"
#include "common/util.hpp"
#define NOBUG_INIT_DEFS_
#include "nobugcfg.h"
#undef NOBUG_INIT_DEFS_
NOBUG_CPP_DEFINE_FLAG(config);
using util::isnil;
namespace cinelerra
{
/** holds the single instance and triggers initialization */
auto_ptr<Appconfig> Appconfig::theApp_ (0);
/** 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 VERSION
#define VERSION 3++devel
#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
@ -49,30 +60,26 @@ namespace cinelerra
NOBUG_INIT;
//////////
(*configParam_)["version"] = "VERSION";
INFO(config, "Basic application configuration triggered.");
(*configParam_)["version"] = CINELERRA_VERSION;
}
////////////////////////////TODO: ein richtiges utility draus machen....
bool isnil(string val)
{
return 0 == val.length();
};
////////////////////////////TODO
/** access the configuation value for a given key.
* @return empty string for unknown keys, else the corresponding configuration value
*/
string
const string &
Appconfig::get (const string & key) throw()
{
try
{
string& val = (*instance().configParam_)[key];
const string& val = (*instance().configParam_)[key];
WARN_IF( isnil(val), config, "undefined config parameter \"%s\" requested.", key.c_str());
return val;
}
catch (...)

View file

@ -20,6 +20,18 @@
*/
/** @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 <i>definitions</i>
** for NoBug are placed into the corresponding translation unit
** appconfig.cpp"
**
** @see nobugcfg.h
*/
#ifndef CINELERRA_APPCONFIG_H
#define CINELERRA_APPCONFIG_H
@ -28,16 +40,14 @@
#include <string>
#include <memory>
#include "nobugcfg.h"
using std::string;
using std::auto_ptr;
#include <nobug.h>
NOBUG_DECLARE_FLAG(config);
namespace cinelerra
{
@ -45,20 +55,20 @@ namespace cinelerra
/**
* Singleton to hold inevitable global flags and constants
* and for performing erarly (static) global initialization tasks.
* and for performing early (static) global initialization tasks.
*/
class Appconfig
{
private:
/** holds the single instance and triggers initialization */
static auto_ptr<Appconfig> theApp_;
static Appconfig* theApp_;
/** perform initialization on first access.
* A call is placed in static initialization code
* included in cinelerra.h; thus it will happen
* ubiquitous very early.
* included via cinelerra.h (see below),
* thus it will happen rather early.
*/
Appconfig () ;
@ -66,21 +76,22 @@ namespace cinelerra
public:
static Appconfig& instance()
{
if (!theApp_.get()) theApp_.reset (new Appconfig ());
if (!theApp_) theApp_ = new Appconfig ();
return *theApp_;
}
/** access the configuation value for a given key.
* @return empty string for unknown keys, else the corresponding configuration value
* @return empty string for unknown keys, config value else
* @todo do we need such a facility?
*/
static string get (const string & key) throw();
static const string & get (const string& key) throw();
private:
typedef std::map<string,string> Configmap;
typedef auto_ptr<Configmap> PConfig;
/** <b>the following is just placeholder code!</b>
/** @TODO <b>the following is just placeholder code!</b>
* Appconfig <i>could</i> do such things if necessary.
*/
PConfig configParam_;
@ -92,8 +103,8 @@ namespace cinelerra
namespace
{
/** generate "magic code" causing early static initialization */
Appconfig* init (&Appconfig::instance ());
/** "magic code" to cause early static initialization */
Appconfig& init (Appconfig::instance ());
}
} // namespace cinelerra

View file

@ -41,6 +41,8 @@ namespace cinelerra
class Error : public std::exception
{
public:
virtual ~Error () throw() {};
/** yield a diagnostig message characterizing the problem */
virtual const char* what () const throw();

53
src/common/util.hpp Normal file
View file

@ -0,0 +1,53 @@
/*
TIME.hpp - unified representation of a time point, including conversion functions
Copyright (C) CinelerraCV
2007, Christian Thaeter <ct@pipapo.org>
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 <string>
#include <cstring>
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_*/

View file

@ -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;
}

84
src/nobugcfg.h Normal file
View file

@ -0,0 +1,84 @@
/*
NOBUGCFG.h - global configuration and definitions for NoBug
Copyright (C) CinelerraCV
2007, Christian Thaeter <ct@pipapo.org>
Hermann Vosseler <Ichthyostega@web.de>
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 <b>definitions</b>. 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 <syslog.h>
/* configuration of NoBug goes here... */
#include <nobug.h>
/* 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 ========= */

View file

@ -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:

View file

@ -27,7 +27,7 @@
#include <vector>
#include <string>
#include "common/factory.hpp"
#include "test/helper/suite.hpp"
@ -36,8 +36,6 @@ namespace test
using std::string;
using std::auto_ptr;
using cinelerra::Factory;
using cinelerra::factory::SubclassPtr;
typedef std::vector<string> * Arg;

View file

@ -25,23 +25,30 @@
#include <vector>
#include <memory>
#include <tr1/memory>
#include "test/helper/suite.hpp"
#include "test/helper/run.hpp"
#include <nobug.h>
#include <iostream>
#include <sstream>
#include "test/helper/suite.hpp"
#include "test/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<string, Launcher*> TestMap;
typedef shared_ptr<TestMap> PTestMap;
typedef map<string,PTestMap> GroupMap;
/** helper to collect and manage the test cases.
@ -65,7 +72,10 @@ namespace test
void
Registry::add2group (Launcher* test, string testID, string groupID)
{
// TODO: ASSERT test!=null, testID.length > 0 ...
REQUIRE( test );
REQUIRE( !isnil(testID) );
REQUIRE( !isnil(groupID) );
PTestMap& group = getGroup(groupID);
if (!group)
group.reset( new TestMap );
@ -86,9 +96,8 @@ namespace test
void
Suite::enroll (Launcher* test, string testID, string groups)
{
// TODO learn to use NoBug for logging
std::cerr << "enroll( testID=" << testID << ")\n";
// TODO: ASSERT test!=null, testID.length() > 0...
REQUIRE( test );
REQUIRE( !isnil(testID) );
std::istringstream ss(groups);
string group;
@ -112,9 +121,12 @@ namespace test
Suite::Suite(string groupID)
: groupID_(groupID)
{
std::cerr << "Suite( groupID="<< groupID << ")\n";
REQUIRE( !isnil(groupID) );
TRACE(test, "Test-Suite( groupID=%s )\n", groupID.c_str () );
if (!testcases.getGroup(groupID))
throw "empty testsuite"; /////////// TODO Errorhandling!
throw cinelerra::error::Invalid ();
//throw "empty testsuite"; /////////// TODO Errorhandling!
}
@ -125,15 +137,10 @@ namespace test
void
Suite::run (int argc, char* argv[])
{
/////////////////////////////////////////////////////TODO:DEBUG
std::cerr << "Suite::run( (" << argc << "[" ;
for ( int i=0; i<argc; ++i )
std::cerr << argv[i] << ",";
std::cerr << "]\n";
/////////////////////////////////////////////////////TODO:DEBUG
PTestMap tests = testcases.getGroup(groupID_);
//TODO ASSERT tests!=null
if (!tests)
throw cinelerra::error::Invalid ();
if (argc >= 2)
{

View file

@ -25,7 +25,6 @@
#define TESTHELPER_SUITE_H
#include <string>
#include "common/factory.hpp"

View file

@ -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:
]

35
src/tool/try.cpp Normal file
View file

@ -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 <syslog.h>
#define NOBUG_LOG_LIMIT LOG_ERR
#include <nobug.h>
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;
}

View file

@ -3,10 +3,10 @@
## SConscript - SCons buildscript for the Testsuite (called by SConstruct)
##
Import('env','artifacts','testobj')
Import('env','artifacts','cinobj','testobj')
# build an application running the testsuite
artifacts['testsuite'] = env.Program('mainsuite',testobj + ['#$SRCDIR/test/mainsuite.cpp'])
artifacts['testsuite'] = env.Program('mainsuite', cinobj + testobj + ['#$SRCDIR/test/mainsuite.cpp'])
# TODO: we could apply much more "magic" here
# - build /every/ $TESTDIR/*.cpp into an application

View file

@ -747,11 +747,12 @@ config.macros.timeline.handler = function(place,macroName,params,wikifier,paramS
}
//}}}</pre>
</div>
<div title="BuildDependenceis" modifier="Ichthyostega" modified="200708120113" created="200708120103" tags="organization buildsys" changecount="3">
<div title="BuildDependenceis" modifier="Ichthyostega" modified="200708140618" created="200708120103" tags="organization buildsys" changecount="5">
<pre>for __Building__
* gcc (4.1), glibc6 (2.3), libstdc++6 (4.1)
* [[build system|BuildSystem]] dependencies: SCons (0.96.90), Python (2.3)
* NoBug for Logging, Tracing, Asserting (can be obtained from [[Pipapo.org|http://www.pipapo.org/pipawiki/NoBug]])
* ~NoBug needs [[valgrind|Valgrind]] (3.2), execinfo.h and libpthread (&amp;rarr; glibc)
* std::tr1 &amp;mdash; esp. for the former BOOST::shared_ptr (which is now proposed standard)
* BOOST
//usually, newer versions are OK//

View file

@ -646,7 +646,12 @@ Error: #f88</pre>
<div title="DefaultTiddlers" modifier="CehTeh" modified="200707102306" created="200707102301" changecount="2">
<pre>[[SupportLibrary]]</pre>
</div>
<div title="ErrorHandling" modifier="CehTeh" modified="200708101307" created="200707152252" tags="excludeMissing" changecount="5">
<div title="ErrorHandling" modifier="Ichthyostega" modified="200708140629" created="200708140628" changecount="2">
<pre>We distinguish the way how to cope with Errors, i.e. the ErrorHandlingPolicy, and the actual implementation
* for code with C semantics &amp;rarr; ErrorHandling-C
* for C++ code &amp;rarr; ErrorHandling-Cpp</pre>
</div>
<div title="ErrorHandling-C" modifier="Ichthyostega" modified="200708140628" created="200707152252" tags="excludeMissing" changecount="1">
<pre>! Proposal:
We need some centralized way to handle errors and doing hard aborts.
@ -700,6 +705,19 @@ thus a {{{CINELERRA_ERROR_DEFINE(NFOO, &quot;Foo not found&quot;)}}} will result
!! Allocation
The next point is allocation failures. These are possible by C/C++ standard but don't actually happen anymore in Linux (except in few rare cases). Instead of gracefully handling this errors I'll add a {{{CINELERRA_DIE(message)}}} macro to this library later. This macro will just do (NoBug) logging and then doing a hard abort. It should be a macro because we want to preserve file/line location for logging.
</pre>
</div>
<div title="ErrorHandling-Cpp" modifier="Ichthyostega" created="200708140640" changecount="1">
<pre>Basically, the C++ error handling techniques are layered on top of the [[C solution|ErrorHandling-C]].
!Proposal:
We use a common base class for all our application specific exceptions. These exceptions can be thought of as a classification of error situations, thus the hierarchical approach. The purpose of throwing such a //classified exception// is
* to do a controlled partial failure
* to trigger automatic cleanup without the need to implement the details
!!Requirements for the Exception Interface
* a means for capturing and transporting detail informations
* the possibility to link to the ''root cause'' of an exception, even after having passed several subsystem barriers.
* getting standardized error messages automatically
</pre>
</div>
<div title="FullScreenPlugin" modifier="CehTeh" modified="200706110313" created="200607241016" tags="systemConfig lewcidExtension" server.type="file" server.host="file:///home/ct/.homepage/home.html" server.page.revision="200706110313">