From 436979094a007dda8ef52572dcb181439dcc26db Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Wed, 16 Mar 2011 03:43:11 +0100 Subject: [PATCH 1/8] Bugfix: fallback implementation for integer div and remainder this fallback allows to use our custom floordiv for all integral types. This solves compilation problems on 32bit, when gavl_time_t is defined to long long int --- src/lib/util.hpp | 11 ++++++++++- tests/lib/util-floordiv-test.cpp | 23 +++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/lib/util.hpp b/src/lib/util.hpp index ce3755c52..b80468cce 100644 --- a/src/lib/util.hpp +++ b/src/lib/util.hpp @@ -59,7 +59,16 @@ namespace util { /** helper to treat int or long division uniformly */ template - struct IDiv; + struct IDiv + { + I quot; + I rem; + + IDiv (I num, I den) + : quot(num/den) + , rem(num - quot*den) + { } + }; template<> struct IDiv diff --git a/tests/lib/util-floordiv-test.cpp b/tests/lib/util-floordiv-test.cpp index 015faaf64..dad2a40b7 100644 --- a/tests/lib/util-floordiv-test.cpp +++ b/tests/lib/util-floordiv-test.cpp @@ -90,6 +90,7 @@ namespace test { /********************************************************************** * @test Evaluate a custom built integer floor function. + * Also known as Knuth's floor division. * This function is crucial for Lumiera's rule of quantisation * of time values into frame intervals. This rule requires time * points to be rounded towards the next lower frame border always, @@ -111,6 +112,12 @@ namespace test { { verifyBehaviour (); + verifyIntegerTypes(); + verifyIntegerTypes(); + verifyIntegerTypes(); + verifyIntegerTypes(); + verifyIntegerTypes(); + if (!isnil (arg)) runPerformanceTest(); } @@ -147,6 +154,22 @@ namespace test { } + template + void + verifyIntegerTypes () + { + I n,d,expectedRes; + + for (int i=-12; i <= 12; ++i) + { + n = i; + d = 4; + expectedRes = floordiv (i,4); + CHECK (floordiv(n,d) == expectedRes); + } + } + + /** @test timing measurements to compare implementation details. * This test uses a sequence of random integers, where the values From 1b50665a2b102d4f8204d6194a1eec65c3d78269 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 18 Mar 2011 05:43:30 +0100 Subject: [PATCH 2/8] Build/testsuite adjustments - increase CPU time limit to about 2 min - tests also depend on the startup configuration --- SConstruct | 6 ++++-- tests/SConscript | 1 + tests/test.conf | 5 +++-- tests/test.sh | 1 + 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/SConstruct b/SConstruct index 6419b5cb7..9665854f4 100644 --- a/SConstruct +++ b/SConstruct @@ -347,10 +347,12 @@ def defineBuildTargets(env, artifacts): artifacts['corelib'] = core artifacts['support'] = lLib - artifacts['lumiera'] = ( env.Program('lumiera', ['src/lumiera/main.cpp'], LIBS=core, install=True) - + env.ConfigData(env.path.srcConf+'setup.ini', targetDir='$ORIGIN') + artifacts['config'] = ( env.ConfigData(env.path.srcConf+'setup.ini', targetDir='$ORIGIN') + env.ConfigData(env.path.srcConf+'dummy_lumiera.ini') ) + artifacts['lumiera'] = ( env.Program('lumiera', ['src/lumiera/main.cpp'], LIBS=core, install=True) + + artifacts['config'] + ) # building Lumiera Plugins artifacts['plugins'] = [] # currently none diff --git a/tests/SConscript b/tests/SConscript index 6920e912c..8a09b547a 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -59,6 +59,7 @@ artifacts['testsuite'] = ts = ( [ testExecutable(env, dir) for dir in ['lib','co + [ testCollection(env, dir) for dir in moduledirs if not dir in specials] + createPlugins(env, 'plugin') + env.File(glob('*.tests')) # depending on the test definition files for test.sh + + artifacts['config'] ) diff --git a/tests/test.conf b/tests/test.conf index c3abbce1c..d7109e910 100755 --- a/tests/test.conf +++ b/tests/test.conf @@ -1,4 +1,5 @@ LOGSUPPRESS='^\(\*\*[0-9]*\*\* \)\?[0-9]\{10,\}[:!] \(TRACE\|INFO\|NOTICE\|WARNING\|ERR\|TODO\|PLANNED\|FIXME\|DEPRECATED\|UNIMPLEMENTED\|RESOURCE_ANNOUNCE\|RESOURCE_ENTER\|RESOURCE_STATE\|RESOURCE_LEAVE\):' -LIMIT_VG_CPU=55 -LIMIT_VG_TIME=60 +LIMIT_CPU=120 +LIMIT_VG_CPU=115 +LIMIT_VG_TIME=120 diff --git a/tests/test.sh b/tests/test.sh index 6b4944d55..214b7641c 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -134,6 +134,7 @@ fi #valgrind false positives in 'vgsuppression'. Care must be taken that this file is simple and does #valgrind not generate true positives. #valgrind +echo "NOTE: CPU time limit: $LIMIT_CPU sec" ulimit -S -t ${LIMIT_CPU:-5} -v ${LIMIT_VSZ:-524288} valgrind="" LIMIT_TIME_REAL="$LIMIT_TIME" From 1b5de947b196e720f9e1f793678970d144e5fe37 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Fri, 25 Mar 2011 19:38:59 +0100 Subject: [PATCH 3/8] fix some further 32/64bit problems - use the C99 qualifier for size_t ('z') in printf - use Long Long number literals in GUI timeline ruler --- src/gui/widgets/timeline/timeline-ruler.cpp | 12 ++-- src/lib/time.cpp | 6 +- src/lib/time.h | 2 +- src/lib/time/digxel.hpp | 3 +- src/lib/time/timevalue.hpp | 9 +++ src/lib/util.hpp | 9 +++ src/proc/asset/meta/time-grid.cpp | 2 +- tests/43session.tests | 2 +- .../proc/asset/meta/time-grid-basics-test.cpp | 6 +- tests/lib/time/quantiser-basics-test.cpp | 68 ++++++++++--------- tests/lib/time/time-formats-test.cpp | 6 +- tests/lib/time/time-quantisation-test.cpp | 4 +- tests/lib/time/time-value-test.cpp | 18 ++--- 13 files changed, 87 insertions(+), 60 deletions(-) diff --git a/src/gui/widgets/timeline/timeline-ruler.cpp b/src/gui/widgets/timeline/timeline-ruler.cpp index 3d2d73cf3..6c79d6af7 100644 --- a/src/gui/widgets/timeline/timeline-ruler.cpp +++ b/src/gui/widgets/timeline/timeline-ruler.cpp @@ -511,12 +511,12 @@ TimelineRuler::calculate_major_spacing() const 15l * GAVL_TIME_SCALE, 30l * GAVL_TIME_SCALE, 60l * GAVL_TIME_SCALE, - 2l * 60l * GAVL_TIME_SCALE, - 5l * 60l * GAVL_TIME_SCALE, - 10l * 60l * GAVL_TIME_SCALE, - 15l * 60l * GAVL_TIME_SCALE, - 30l * 60l * GAVL_TIME_SCALE, - 60l * 60l * GAVL_TIME_SCALE + 2ll * 60ll * GAVL_TIME_SCALE, + 5ll * 60ll * GAVL_TIME_SCALE, + 10ll * 60ll * GAVL_TIME_SCALE, + 15ll * 60ll * GAVL_TIME_SCALE, + 30ll * 60ll * GAVL_TIME_SCALE, + 60ll * 60ll * GAVL_TIME_SCALE }; for(i = 0; i < sizeof(major_spacings) / sizeof(gavl_time_t); i++) diff --git a/src/lib/time.cpp b/src/lib/time.cpp index a7efb8009..7cbe53004 100644 --- a/src/lib/time.cpp +++ b/src/lib/time.cpp @@ -96,7 +96,7 @@ lumiera_frame_duration (FrameRate const& fps) namespace { // implementation helper - inline long + inline long long calculate_quantisation (gavl_time_t time, gavl_time_t origin, gavl_time_t grid) { time -= origin; @@ -105,9 +105,11 @@ namespace { // implementation helper } -long +int64_t lumiera_quantise_frames (gavl_time_t time, gavl_time_t origin, gavl_time_t grid) { + ENSURE (sizeof(int64_t) <= sizeof(long long)); + return calculate_quantisation (time, origin, grid); } diff --git a/src/lib/time.h b/src/lib/time.h index 521b5658d..fb1a7992a 100644 --- a/src/lib/time.h +++ b/src/lib/time.h @@ -103,7 +103,7 @@ lumiera_tmpbuf_print_time (gavl_time_t time); * @return number of the grid interval containing the given time. * @warning the resulting value is limited to (Time::Min, Time::MAX) */ -long +int64_t lumiera_quantise_frames (gavl_time_t time, gavl_time_t origin, gavl_time_t grid); /** diff --git a/src/lib/time/digxel.hpp b/src/lib/time/digxel.hpp index 53aac3456..d49e81af4 100644 --- a/src/lib/time/digxel.hpp +++ b/src/lib/time/digxel.hpp @@ -72,6 +72,7 @@ #include #include #include +#include #include using std::string; @@ -126,7 +127,7 @@ namespace time { { size_t space = std::snprintf (printbuffer_, bufsiz, formatSpec_, val); REQUIRE (space < bufsiz, "Digxel value exceeded available buffer size. " - "For showing %s, %lu+1 chars instead of just %lu+1 would be required." + "For showing %s, %zu+1 chars instead of just %zu+1 would be required." , cStr(lexical_cast(val)), space, len); ///////////TICKET #197 } ENSURE (!empty()); diff --git a/src/lib/time/timevalue.hpp b/src/lib/time/timevalue.hpp index f0d7fc9c8..7e3d370ad 100644 --- a/src/lib/time/timevalue.hpp +++ b/src/lib/time/timevalue.hpp @@ -256,6 +256,9 @@ namespace time { /// direct assignment prohibited Time& operator= (Time const); + /// suppress possible direct conversions + Time(int); + public: static const Time MAX ; static const Time MIN ; @@ -269,6 +272,7 @@ namespace time { : TimeValue(calcResult) { } + explicit Time (FSecs const& fractionalSeconds); Time ( long millis @@ -314,6 +318,11 @@ namespace time { : Offset(Offset(timeSpec).abs()) { } + explicit + Duration (FSecs const& timeSpan_in_secs) + : Offset(Offset(Time(timeSpan_in_secs)).abs()) + { } + Duration (TimeSpan const& interval); Duration (ulong count, FrameRate const& fps); diff --git a/src/lib/util.hpp b/src/lib/util.hpp index b80468cce..3fc2cb97b 100644 --- a/src/lib/util.hpp +++ b/src/lib/util.hpp @@ -88,6 +88,15 @@ namespace util { { } }; + template<> + struct IDiv + : lldiv_t + { + IDiv (long long num, long long den) + : lldiv_t(lldiv (num,den)) + { } + }; + /** floor function for integer arithmetics. * Unlike the built-in integer division, this function diff --git a/src/proc/asset/meta/time-grid.cpp b/src/proc/asset/meta/time-grid.cpp index ad3599a80..767daa41c 100644 --- a/src/proc/asset/meta/time-grid.cpp +++ b/src/proc/asset/meta/time-grid.cpp @@ -154,7 +154,7 @@ namespace meta { PGrid TimeGrid::build (Symbol gridID, FrameRate frames_per_second) { - return build (gridID,frames_per_second, Time(0)); + return build (gridID,frames_per_second, Time(0,0)); } diff --git a/tests/43session.tests b/tests/43session.tests index 85242cd65..dd86bcc31 100644 --- a/tests/43session.tests +++ b/tests/43session.tests @@ -100,7 +100,7 @@ out: TestSubMO1\(ID= [0-9]{3}\) out: TestSubMO2\(ID= [0-9]{3}\) out: TestSubMO21\(ID= [0-9]{3}\) out: specialAPI() -out: pID\(\w{8,16}\) +out: pID\(\w{6,16}\) END diff --git a/tests/components/proc/asset/meta/time-grid-basics-test.cpp b/tests/components/proc/asset/meta/time-grid-basics-test.cpp index ae6f70d53..c40ac7cbb 100644 --- a/tests/components/proc/asset/meta/time-grid-basics-test.cpp +++ b/tests/components/proc/asset/meta/time-grid-basics-test.cpp @@ -85,7 +85,7 @@ namespace test { GridBuilder spec = asset::Meta::create (myGrID); CHECK ( spec.fps_ == 1); - CHECK ( spec.origin_ == Time(0)); + CHECK ( spec.origin_ == TimeValue(0)); CHECK (!spec.predecessor_); spec.fps_ = testFps; @@ -118,8 +118,8 @@ namespace test { CHECK (!util::isnil (simplePALGrid->ident.name)); // note: name-ID filled in automatically cout << "simple PAL Grid: " << simplePALGrid->ident << endl; - CHECK (Time(2) == simplePALGrid->timeOf(50)); - CHECK (Time(2) == simplePALGrid->timeOf(FSecs(2))); + CHECK (Time(0,2) == simplePALGrid->timeOf(50)); + CHECK (Time(0,2) == simplePALGrid->timeOf(FSecs(2))); } }; diff --git a/tests/lib/time/quantiser-basics-test.cpp b/tests/lib/time/quantiser-basics-test.cpp index e790d5f8b..b503e3d29 100644 --- a/tests/lib/time/quantiser-basics-test.cpp +++ b/tests/lib/time/quantiser-basics-test.cpp @@ -42,7 +42,13 @@ namespace test{ const uint MAX_FRAMES = 25*500; const uint DIRT_GRAIN = 50; - const FSecs F25(1,25); // duration of one PAL frame + const FSecs F25(1,25); // duration of one PAL frame + + inline Time + secs (int seconds) + { + return Time(FSecs(seconds)); + } } @@ -84,7 +90,7 @@ namespace test{ uint frames = (rand() % MAX_FRAMES); FSecs dirt = (F25 / (rand() % DIRT_GRAIN)); - Time rawTime = dirt + frames*F25; + Time rawTime (dirt + frames*F25); CHECK (Time( frames *F25) <= rawTime); CHECK (Time((frames+1)*F25) > rawTime); @@ -152,51 +158,51 @@ namespace test{ { // origin at lower end of the time range FixedFrameQuantiser case1 (1, Time::MIN); - CHECK (Time(0) == case1.gridAlign(Time::MIN )); - CHECK (Time(0) == case1.gridAlign(Time::MIN +TimeValue(1) )); - CHECK (Time(1) == case1.gridAlign(Time::MIN +Time(1) )); - CHECK (Time::MAX -Time(1) > case1.gridAlign( Time(-1) )); - CHECK (Time::MAX -Time(1) <= case1.gridAlign( Time (0) )); - CHECK (Time::MAX > case1.gridAlign( Time (0) )); - CHECK (Time::MAX == case1.gridAlign( Time(+1) )); - CHECK (Time::MAX == case1.gridAlign( Time(+2) )); + CHECK (secs(0) == case1.gridAlign(Time::MIN )); + CHECK (secs(0) == case1.gridAlign(Time::MIN +TimeValue(1) )); + CHECK (secs(1) == case1.gridAlign(Time::MIN +secs(1) )); + CHECK (Time::MAX -secs(1) > case1.gridAlign( secs(-1) )); + CHECK (Time::MAX -secs(1) <= case1.gridAlign( secs (0) )); + CHECK (Time::MAX > case1.gridAlign( secs (0) )); + CHECK (Time::MAX == case1.gridAlign( secs(+1) )); + CHECK (Time::MAX == case1.gridAlign( secs(+2) )); // origin at upper end of the time range FixedFrameQuantiser case2 (1, Time::MAX); - CHECK (Time( 0) == case2.gridAlign(Time::MAX )); - CHECK (Time(-1) == case2.gridAlign(Time::MAX -TimeValue(1) )); // note: next lower frame - CHECK (Time(-1) == case2.gridAlign(Time::MAX -Time(1) )); // i.e. the same as a whole frame down - CHECK (Time::MIN +Time(1) < case2.gridAlign( Time(+2) )); - CHECK (Time::MIN +Time(1) >= case2.gridAlign( Time(+1) )); - CHECK (Time::MIN < case2.gridAlign( Time(+1) )); - CHECK (Time::MIN == case2.gridAlign( Time( 0) )); // note: because of downward truncating, - CHECK (Time::MIN == case2.gridAlign( Time(-1) )); // resulting values will already exceed - CHECK (Time::MIN == case2.gridAlign( Time(-2) )); // allowed range and thus will be clipped + CHECK (secs( 0) == case2.gridAlign(Time::MAX )); + CHECK (secs(-1) == case2.gridAlign(Time::MAX -TimeValue(1) )); // note: next lower frame + CHECK (secs(-1) == case2.gridAlign(Time::MAX -secs(1) )); // i.e. the same as a whole frame down + CHECK (Time::MIN +secs(1) < case2.gridAlign( secs(+2) )); + CHECK (Time::MIN +secs(1) >= case2.gridAlign( secs(+1) )); + CHECK (Time::MIN < case2.gridAlign( secs(+1) )); + CHECK (Time::MIN == case2.gridAlign( secs( 0) )); // note: because of downward truncating, + CHECK (Time::MIN == case2.gridAlign( secs(-1) )); // resulting values will already exceed + CHECK (Time::MIN == case2.gridAlign( secs(-2) )); // allowed range and thus will be clipped // maximum frame size is half the time range Duration hugeFrame(Offset(Time::MAX)); FixedFrameQuantiser case3 (hugeFrame); CHECK (Time::MIN == case3.gridAlign(Time::MIN )); CHECK (Time::MIN == case3.gridAlign(Time::MIN +TimeValue(1) )); - CHECK (Time::MIN == case3.gridAlign( Time(-1) )); - CHECK (Time(0) == case3.gridAlign( Time( 0) )); - CHECK (Time(0) == case3.gridAlign( Time(+1) )); - CHECK (Time(0) == case3.gridAlign(Time::MAX -TimeValue(1) )); + CHECK (Time::MIN == case3.gridAlign( secs(-1) )); + CHECK (TimeValue(0) == case3.gridAlign( secs( 0) )); + CHECK (TimeValue(0) == case3.gridAlign( secs(+1) )); + CHECK (TimeValue(0) == case3.gridAlign(Time::MAX -TimeValue(1) )); CHECK (Time::MAX == case3.gridAlign(Time::MAX )); // now displacing this grid by +1sec.... - FixedFrameQuantiser case4 (hugeFrame, Time(1)); + FixedFrameQuantiser case4 (hugeFrame, secs(1)); CHECK (Time::MIN == case4.gridAlign(Time::MIN )); CHECK (Time::MIN == case4.gridAlign(Time::MIN +TimeValue(1) )); // clipped... - CHECK (Time::MIN == case4.gridAlign(Time::MIN +Time(1) )); // but now exact (unclipped) - CHECK (Time::MIN == case4.gridAlign( Time(-1) )); - CHECK (Time::MIN == case4.gridAlign( Time( 0) )); - CHECK (Time(0) == case4.gridAlign( Time(+1) )); //.....now exactly the frame number zero - CHECK (Time(0) == case4.gridAlign(Time::MAX -TimeValue(1) )); - CHECK (Time(0) == case4.gridAlign(Time::MAX )); //.......still truncated down to frame #0 + CHECK (Time::MIN == case4.gridAlign(Time::MIN +secs(1) )); // but now exact (unclipped) + CHECK (Time::MIN == case4.gridAlign( secs(-1) )); + CHECK (Time::MIN == case4.gridAlign( secs( 0) )); + CHECK (TimeValue(0) == case4.gridAlign( secs(+1) )); //.....now exactly the frame number zero + CHECK (TimeValue(0) == case4.gridAlign(Time::MAX -TimeValue(1) )); + CHECK (TimeValue(0) == case4.gridAlign(Time::MAX )); //.......still truncated down to frame #0 // larger frames aren't possible - Duration not_really_larger(Time(10000) + hugeFrame); + Duration not_really_larger(secs(10000) + hugeFrame); CHECK (hugeFrame == not_really_larger); // frame sizes below the time micro grid get trapped diff --git a/tests/lib/time/time-formats-test.cpp b/tests/lib/time/time-formats-test.cpp index daf7f6ca1..eab218d58 100644 --- a/tests/lib/time/time-formats-test.cpp +++ b/tests/lib/time/time-formats-test.cpp @@ -148,7 +148,7 @@ namespace test{ // Extended SMPTE: extension of the axis beyond origin towards negative values smpte.hours -= 6; CHECK ("- 0:21:59:24"== string(smpte)); // representation is symmetrical to origin - CHECK (tx - Time(6*60*60) == smpte.getTime()); // Continuous time axis + CHECK (tx - Time(0,0,0,6) == smpte.getTime()); // Continuous time axis CHECK (-1 == smpte.sgn); // Note: for these negative (extended) SMPTE... CHECK (smpte.mins > 0); // ...the representation is really flipped around zero @@ -161,13 +161,13 @@ namespace test{ ++smpte; // but the orientation of the increment on the *whole* TC values is unaltered CHECK ("- 0:21:59:24"== string(smpte)); // so this actually *advanced* time by one frame CHECK (tx == smpte.getTime()); - CHECK (tx < Time(0)); + CHECK (tx < TimeValue(0)); smpte.mins -= 2*60; // now lets flip the representation again... CHECK (" 1:38:00:01"== string(smpte)); CHECK (+1 == smpte.sgn); CHECK (smpte.getTime() > 0); - CHECK (tx + Time(2*60*60) == smpte.getTime()); + CHECK (tx + Time(0,0,0,2) == smpte.getTime()); smpte.secs -= 2*60*60; // and again... CHECK (tx == smpte.getTime()); CHECK ("- 0:21:59:24"== string(smpte)); diff --git a/tests/lib/time/time-quantisation-test.cpp b/tests/lib/time/time-quantisation-test.cpp index 237ce7f8e..a22988f1b 100644 --- a/tests/lib/time/time-quantisation-test.cpp +++ b/tests/lib/time/time-quantisation-test.cpp @@ -75,8 +75,8 @@ namespace test{ virtual void run (Arg arg) { - Time ref (random_or_get(arg)); - CHECK (Time(0) < ref); + Time ref (0,random_or_get(arg),0,0); + CHECK (TimeValue(0) < ref); checkSimpleUsage (ref); check_theFullStory (ref); diff --git a/tests/lib/time/time-value-test.cpp b/tests/lib/time/time-value-test.cpp index 9a1383e8b..e73354ea8 100644 --- a/tests/lib/time/time-value-test.cpp +++ b/tests/lib/time/time-value-test.cpp @@ -167,8 +167,8 @@ namespace test{ CHECK (o1 == o2); CHECK (o1 == org); - // integer interpreted as second - Time t1(1); + // time in seconds + Time t1(FSecs(1)); CHECK (t1 == TimeValue(GAVL_TIME_SCALE)); // create from fractional seconds @@ -190,7 +190,7 @@ namespace test{ CHECK (th+th == t1); CHECK (t1-th == th); CHECK (((t1-th)*=2) == t1); - CHECK (th-th == Time(0)); + CHECK (th-th == TimeValue(0)); // that was indeed a temporary and didn't affect the originals CHECK (t1 == TimeValue(GAVL_TIME_SCALE)); @@ -252,14 +252,14 @@ namespace test{ CHECK (distance == backwards.abs()); Duration len1(Time(23,4,5,6)); - CHECK (len1 == Time(FSecs(23,1000)) + Time(4 + 5*60 + 6*3600)); + CHECK (len1 == Time(FSecs(23,1000)) + Time(0, 4 + 5*60 + 6*3600)); - Duration len2(Time(-10)); // negative specs... - CHECK (len2 == Time(10));// - CHECK (len2 > zero); // will be taken absolute + Duration len2(Time(FSecs(-10))); // negative specs... + CHECK (len2 == Time(FSecs(10)));// + CHECK (len2 > zero); // will be taken absolute Duration unit(50, FrameRate::PAL); - CHECK (Time(2) == unit); // duration of 50 frames at 25fps is... (guess what) + CHECK (Time(0,2,0,0) == unit); // duration of 50 frames at 25fps is... (guess what) CHECK (FrameRate::PAL.duration() == Time(FSecs(1,25))); CHECK (FrameRate::NTSC.duration() == Time(FSecs(1001,30000))); @@ -296,7 +296,7 @@ namespace test{ CHECK (theLength == Offset(org,five).abs()); Time endpoint = interval.end(); - TimeSpan successor (endpoint, Duration(Time(2))); + TimeSpan successor (endpoint, Duration(Time(0,2,0,0))); CHECK (Offset(interval,endpoint) == Offset(org,five).abs()); CHECK (Offset(endpoint,successor.end()) == Duration(successor)); From 2bc69d0d002974dbb39d46c4ffc5565e4b24c5b4 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 24 Jul 2011 17:25:30 +0200 Subject: [PATCH 4/8] SCons: fix error in linking executables a long standing error, uncovered recently due to more stringent checks of the linker on newer platforms, not picking up direct dependencies of an executable transitively from the linked-to dynamic libs (which is fine). The error was to *overwrite* the LIBS construction variable in the definition of the executable to link, instead of just adding our dynamic links to the sources to be linked. --- SConstruct | 2 +- src/tool/SConscript | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SConstruct b/SConstruct index 9665854f4..26f9e0498 100644 --- a/SConstruct +++ b/SConstruct @@ -350,7 +350,7 @@ def defineBuildTargets(env, artifacts): artifacts['config'] = ( env.ConfigData(env.path.srcConf+'setup.ini', targetDir='$ORIGIN') + env.ConfigData(env.path.srcConf+'dummy_lumiera.ini') ) - artifacts['lumiera'] = ( env.Program('lumiera', ['src/lumiera/main.cpp'], LIBS=core, install=True) + artifacts['lumiera'] = ( env.Program('lumiera', ['src/lumiera/main.cpp'] + core, install=True) + artifacts['config'] ) diff --git a/src/tool/SConscript b/src/tool/SConscript index 1cd45d0d6..583b7032f 100644 --- a/src/tool/SConscript +++ b/src/tool/SConscript @@ -12,12 +12,12 @@ envSvg.mergeConf(['librsvg-2.0']) envSvg.Append(LIBS=support_lib) -luidgen = env.Program('luidgen', 'luidgen.c', LIBS=support_lib, install=True) ## for generating Lumiera-UIDs +luidgen = env.Program('luidgen', ['luidgen.c'] + support_lib, install=True) ## for generating Lumiera-UIDs rsvg = envSvg.Program('rsvg-convert','rsvg-convert.c') ## for rendering SVG icons (uses librsvg) # build additional test and administrative tools.... artifacts['tools'] = [ env.Program('hello-world','hello.c', install=True) #### hello world (checks C build) - + env.Program('try', 'try.cpp', LIBS=support_lib) #### to try out some feature... + + env.Program('try', ['try.cpp'] + support_lib) #### to try out some feature... + luidgen + rsvg ] From 65b5ea9df0f9cdaa11f3503e0dad71d14a321cdf Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 2 Nov 2013 23:54:45 +0100 Subject: [PATCH 5/8] SCons: ability to define additional libraries in a flexible way --- admin/scons/LumieraEnvironment.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/admin/scons/LumieraEnvironment.py b/admin/scons/LumieraEnvironment.py index 8d2d8db43..85d5c5a7b 100644 --- a/admin/scons/LumieraEnvironment.py +++ b/admin/scons/LumieraEnvironment.py @@ -270,6 +270,8 @@ class LumieraExeBuilder(WrappedStandardExeBuilder): """ custEnv = lumiEnv.Clone() custEnv.Append( LINKFLAGS = "-Wl,-rpath=\\$$ORIGIN/modules,--enable-new-dtags" ) + if 'addLibs' in kw: + custEnv.Append(LIBS = kw['addLibs']) return custEnv def getBuildDestination(self, lumiEnv): return lumiEnv.path.buildExe @@ -286,6 +288,8 @@ class LumieraModuleBuilder(WrappedStandardExeBuilder): """ custEnv = lumiEnv.Clone() custEnv.Append(LINKFLAGS = "-Wl,-soname="+self.defineSoname(target,**kw)) + if 'addLibs' in kw: + custEnv.Append(LIBS = kw['addLibs']) return custEnv def getBuildDestination(self, lumiEnv): return lumiEnv.path.buildLib From 9d2220553fd6189b600bf2cb69394558d5ad286a Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 3 Nov 2013 00:05:20 +0100 Subject: [PATCH 6/8] Build: improve declared library dependencies - dependency on X-Lib explicit - always link explicitly agrainst lib rt - enforce strict dependencies on dynamic modules (--no-undefined) These changes were included in 0.pre.02-1 and applied to master --- admin/scons/Platform.py | 11 +++++------ admin/scons/Setup.py | 1 + doc/technical/build/Dependencies.txt | 2 +- src/SConscript | 10 +++++----- tests/SConscript | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/admin/scons/Platform.py b/admin/scons/Platform.py index 2a5931417..1ce12662c 100644 --- a/admin/scons/Platform.py +++ b/admin/scons/Platform.py @@ -56,6 +56,10 @@ def configure(env): conf.env.Append(CPPFLAGS = ' -DHAVE_PTHREAD') conf.env.Append(CCFLAGS = ' -pthread') + if not conf.CheckLib(symbol='clock_gettime', library='rt'): + problems.append('We expect the POSIX realtime extensions to be available through librt. ' + + 'Unable to use clock_gettime()') + if conf.CheckCHeader('execinfo.h'): conf.env.Append(CPPFLAGS = ' -DHAVE_EXECINFO_H') @@ -89,12 +93,6 @@ def configure(env): problems.append('We need the boost regular expression lib (incl. binary lib for linking).') - if conf.CheckLib(symbol='clock_gettime'): - print 'Using function clock_gettime() as defined in the C-lib...' - else: - if not conf.CheckLib(symbol='clock_gettime', library='rt'): - problems.append('No library known to provide the clock_gettime() function.') - if not conf.CheckPkgConfig('gavl', 1.0): problems.append('Did not find Gmerlin Audio Video Lib [http://gmerlin.sourceforge.net/gavl.html].') else: @@ -129,6 +127,7 @@ def configure(env): problems.append('Xlib.h and Xutil.h required. Please install libx11-dev.') if not conf.CheckPkgConfig('xv') : problems.append('Need libXv...') + if not conf.CheckPkgConfig('x11') : problems.append('Need X-lib...') # for the xvdisplayer widget if not conf.CheckPkgConfig('xext'): problems.append('Need libXext.') diff --git a/admin/scons/Setup.py b/admin/scons/Setup.py index ee09a3889..4fae9d85b 100644 --- a/admin/scons/Setup.py +++ b/admin/scons/Setup.py @@ -77,6 +77,7 @@ def defineBuildEnvironment(): , CXXFLAGS='-Wno-enum-compare' , CFLAGS='-std=gnu99' ) + env.Append(LINKFLAGS='-Wl,--no-undefined') # require every dependency is given on link, in the right order handleVerboseMessages(env) handleNoBugSwitches(env) diff --git a/doc/technical/build/Dependencies.txt b/doc/technical/build/Dependencies.txt index 1b7b0262c..967ac6bbd 100644 --- a/doc/technical/build/Dependencies.txt +++ b/doc/technical/build/Dependencies.txt @@ -90,7 +90,7 @@ Libraries - libgtkmm-2.4-dev - libcairomm-1.0-dev - libglibmm-2.4-dev, requiring glib2.0 and gthread-2.0 - - libxv-dev + - libxv-dev and X-lib footnote:[for the XV viewer widget `gui/output/xvdisplayer.cpp`] - librsvg-2.0 and librsvg2-dev for rendering Icons - libgdl-1-dev -- old version of the Gnome Docking Library footnote:[GDL isn't directly related to GNOME any more. We contributed to the improvement of this library in the past. These improvements went upstream diff --git a/src/SConscript b/src/SConscript index e6da9dbb9..8db741cfe 100644 --- a/src/SConscript +++ b/src/SConscript @@ -11,10 +11,10 @@ Import('env icons config') # define the source file/dirs comprising each artifact to be built. -lLib = env.SharedLibrary('lumierasupport', srcSubtree('lib'), install=True) -lApp = env.SharedLibrary('lumieracommon', srcSubtree('common'), install=True) -lBack = env.SharedLibrary('lumierabackend', srcSubtree('backend'), install=True) -lProc = env.SharedLibrary('lumieraproc', srcSubtree('proc'), install=True) +lLib = env.SharedLibrary('lumierasupport', srcSubtree('lib'), install=True) +lApp = env.SharedLibrary('lumieracommon', srcSubtree('common'), addLibs=lLib, install=True) +lBack = env.SharedLibrary('lumierabackend', srcSubtree('backend'),addLibs=lLib+lApp, install=True) +lProc = env.SharedLibrary('lumieraproc', srcSubtree('proc'), addLibs=lLib+lApp+lBack, install=True) core = lProc+lBack+lApp+lLib # in reverse dependency order support_lib = lLib @@ -37,7 +37,7 @@ plugins = [] # currently none # the Lumiera GTK GUI envGtk = env.Clone() -envGtk.mergeConf(['gtkmm-2.4','gthread-2.0','cairomm-1.0','gdl','xv','xext','sm']) +envGtk.mergeConf(['gtkmm-2.4','gthread-2.0','cairomm-1.0','gdl','xv','x11','xext','sm']) envGtk.Append(LIBS=core) guimodule = envGtk.LumieraPlugin('gtk_gui', srcSubtree('gui'), install=True) diff --git a/tests/SConscript b/tests/SConscript index 80388a067..f8c0aa337 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -51,7 +51,7 @@ def testCases(env,dir): testlib = [] testClasses = list(scanSubtree(dir,['*.cpp'])) if testClasses: - testlib = sharedTestLibs[dir] = env.SharedLibrary('test-'+dir, testClasses) + testlib = sharedTestLibs[dir] = env.SharedLibrary('test-'+dir, testClasses, addLibs=core_lib) ### TICKET #938 : should be: addLibs=linkContext(dir)) # pick up standalone plain-C tests standaloneTests = list(scanSubtree(dir,['test-*.c'])) @@ -74,7 +74,7 @@ testrunner = env.Program("test-suite", ["testrunner.cpp"]+testLibs+core_lib) testsuite = ( testcases + testrunner - + createPlugins(env, 'plugin') + + createPlugins(env, 'plugin', addLibs=core_lib) + env.File(glob('*.tests')) # depend explicitly on the test definition files for test.sh + config ) From f77f396afc048d187d6558ae3d81c08768349081 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 9 Nov 2013 02:30:16 +0100 Subject: [PATCH 7/8] bugfix: format-string for long and ulong values our front-end for boost::format, the class lib::_Fmt was lacking an reliable specialisation for long and ulong. This is due to the notorious problem of these types being of platform dependant size. As a fix, we're speclialising explicitly for int16_t, int32_t and int64_t and avoid the common names 'short', 'int' and 'long' alltogether. And especially for non-64bit-platform (NONPORTABLE) we add an explicit specialisation for long --- src/lib/format-string.cpp | 12 ++++++++---- src/lib/format-string.hpp | 12 ++++++++---- tests/40core.tests | 2 +- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/lib/format-string.cpp b/src/lib/format-string.cpp index 82a9d7ea0..bea186abb 100644 --- a/src/lib/format-string.cpp +++ b/src/lib/format-string.cpp @@ -186,10 +186,10 @@ namespace util { template void _Fmt::format (const char, Implementation&); template void _Fmt::format (const uchar, Implementation&); - template void _Fmt::format (const int, Implementation&); - template void _Fmt::format (const uint, Implementation&); - template void _Fmt::format (const short, Implementation&); - template void _Fmt::format (const ushort, Implementation&); + template void _Fmt::format (const int16_t, Implementation&); + template void _Fmt::format (const uint16_t,Implementation&); + template void _Fmt::format (const int32_t, Implementation&); + template void _Fmt::format (const uint32_t,Implementation&); template void _Fmt::format (const int64_t, Implementation&); template void _Fmt::format (const uint64_t,Implementation&); template void _Fmt::format (const float, Implementation&); @@ -197,6 +197,10 @@ namespace util { template void _Fmt::format (const string, Implementation&); template void _Fmt::format (const void *, Implementation&); template void _Fmt::format (const char *, Implementation&); +#ifndef __x86_64__ + template void _Fmt::format (const long, Implementation&); + template void _Fmt::format (const ulong, Implementation&); +#endif diff --git a/src/lib/format-string.hpp b/src/lib/format-string.hpp index 1f4c4033e..fa884b174 100644 --- a/src/lib/format-string.hpp +++ b/src/lib/format-string.hpp @@ -247,14 +247,18 @@ namespace util { template<> struct _allow_call { enum{ value = true }; }; template<> struct _allow_call { enum{ value = true }; }; template<> struct _allow_call { enum{ value = true }; }; - template<> struct _allow_call { enum{ value = true }; }; - template<> struct _allow_call { enum{ value = true }; }; - template<> struct _allow_call { enum{ value = true }; }; - template<> struct _allow_call { enum{ value = true }; }; + template<> struct _allow_call { enum{ value = true }; }; + template<> struct _allow_call{ enum{ value = true }; }; + template<> struct _allow_call { enum{ value = true }; }; + template<> struct _allow_call{ enum{ value = true }; }; template<> struct _allow_call { enum{ value = true }; }; template<> struct _allow_call{ enum{ value = true }; }; template<> struct _allow_call { enum{ value = true }; }; template<> struct _allow_call { enum{ value = true }; }; +#ifndef __x86_64__ + template<> struct _allow_call { enum{ value = true }; }; + template<> struct _allow_call { enum{ value = true }; }; +#endif template struct _shall_format_directly diff --git a/tests/40core.tests b/tests/40core.tests index 73487887a..063202d21 100644 --- a/tests/40core.tests +++ b/tests/40core.tests @@ -310,7 +310,7 @@ END TEST "formatting by string template" FormatString_test < Date: Sun, 10 Nov 2013 04:17:53 +0100 Subject: [PATCH 8/8] bugfix: 32/64bit problems found while packaging This changeset combines several small fixes done while preparing the current debian package. They were included into the package and applied to master --- src/lib/time/digxel.hpp | 2 +- tests/library/time/quantiser-basics-test.cpp | 2 +- tests/library/time/time-formats-test.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/time/digxel.hpp b/src/lib/time/digxel.hpp index 964985c3e..8237d95dc 100644 --- a/src/lib/time/digxel.hpp +++ b/src/lib/time/digxel.hpp @@ -317,7 +317,7 @@ namespace time { typedef Digxel< int, digxel::SexaFormatter> SexaDigit; ///< for displaying time components (sexagesimal) typedef Digxel HexaDigit; ///< for displaying a hex byte typedef Digxel< int, digxel::HourFormatter> HourDigit; ///< for displaying hours in H:M.S - typedef Digxel CountVal; ///< for displaying a counter ///////////TICKET #882 : outch! + typedef Digxel CountVal; ///< for displaying a counter ///////////TICKET #882 : should better use a typedef for frame counts /** special Digxel to show a sign. diff --git a/tests/library/time/quantiser-basics-test.cpp b/tests/library/time/quantiser-basics-test.cpp index dbcfa695a..edc4ced6a 100644 --- a/tests/library/time/quantiser-basics-test.cpp +++ b/tests/library/time/quantiser-basics-test.cpp @@ -90,7 +90,7 @@ namespace test{ uint frames = (rand() % MAX_FRAMES); FSecs dirt = (F25 / (2 + rand() % DIRT_GRAIN)); - Time rawTime (dirt + frames*F25); + Time rawTime = Time(frames*F25) + Duration(dirt); ////////////////TICKET #939 : should better use 64bit base type for FSecs ?? CHECK (Time( frames *F25) <= rawTime); CHECK (Time((frames+1)*F25) > rawTime); diff --git a/tests/library/time/time-formats-test.cpp b/tests/library/time/time-formats-test.cpp index fef32a278..1b9d23116 100644 --- a/tests/library/time/time-formats-test.cpp +++ b/tests/library/time/time-formats-test.cpp @@ -52,12 +52,12 @@ namespace test{ using format::Smpte; namespace{ - const int MAX_FRAME = 265*24*60*60*25; + const int64_t MAX_FRAME = 265*24*60*60*25; string generateRandomFrameNr() { - uint frameNr(0); + int64_t frameNr(0); /////////TICKET #882 : better use a typedef for frame counts while (!frameNr) frameNr = rand() % (2*MAX_FRAME) - MAX_FRAME;