diff --git a/pub/CHANGELOG b/pub/CHANGELOG index e9e74e585de2fe2164cb86c487683f17af531cc8..5dddcf5d236e2969e6ccae72a021a31860289496 100644 --- a/pub/CHANGELOG +++ b/pub/CHANGELOG @@ -5,6 +5,7 @@ Release 2.3.0b of - Shell escape '!' restored - Improved behavior: - 'pn','pv' aka FK01,2 are ignored when j would exceed the allowed range + - Tests yield more explicit error messages; distinguish 'exit' from 'throw' - Improved help: - 'hr' for help on resolution convolution @@ -43,6 +44,7 @@ Release 2.2.3a of 2feb15: - New functionality: - global fits - integer expressions now evaluated in integer arithmetics + - starting a test script collection - Remove legacy methods: - rm loaders for old formats 96 and 01. - Major code refactoring: diff --git a/pub/lib/fbase.cpp b/pub/lib/fbase.cpp index 3facf934c868063659d1868d14df121744e39e91..aa24a58221ec134ce47dfe5189b48e3ac364fc12 100644 --- a/pub/lib/fbase.cpp +++ b/pub/lib/fbase.cpp @@ -168,8 +168,8 @@ double func_diehl( double a ) { int func_exit( int a ) { exit(a); return 0; } -int func_exit_if( int a ) { if(a) exit(0); return 0; } -int func_exit_unless( int a ) { if(!a) exit(0); return 0; } +int func_throw_if( int a, string s ) { if(a) throw s; return 0; } +int func_throw_unless( int a, string s ) { if(!a) throw s; return 0; } //************************************************************************************************** //* Functions of two arguments @@ -443,10 +443,6 @@ void fbase_initialize() G->register_fct_0_s ( "pop", func_pop ); G->register_fct_meta ( "exit", 1, "(x): exit(x)" ); G->register_fct_i_i ( "exit", func_exit ); - G->register_fct_meta ( "exit_if", 1, "(x): exit(0) if x" ); - G->register_fct_i_i ( "exit_if", func_exit_if ); - G->register_fct_meta ( "exit_unless", 1, "(x): exit(0) if !x" ); - G->register_fct_i_i ( "exit_unless", func_exit_unless ); G->register_fct_meta ( "ln", 1, "(x): natural logarithm of x, or 0 if x<=0" ); G->register_fct_d_d ( "ln", func_ln ); G->register_fct_e_e ( "ln", func_ln ); @@ -557,14 +553,11 @@ void fbase_initialize() G->register_fct_meta ( "lndiehl", 1, "(cauchywid/gausswid): ln of normalized convolution gauss(*)cauchy" ); G->register_fct_d_d ( "lndiehl", func_lndiehl ); - G->register_fct_meta ( "exit", 1, "(x): exit with return value nint(x)" ); - G->register_fct_i_i ( "exit", func_exit ); - G->register_fct_meta ( "exit_if", 1, "(x): exit(0) if x" ); - G->register_fct_i_i ( "exit_if", func_exit_if ); - G->register_fct_meta ( "exit_unless", 1, "(x): exit(0) if !x" ); - G->register_fct_i_i ( "exit_unless", func_exit_unless ); - // f(2 args) + G->register_fct_meta ( "throw_if", 2, "(x,s): throw s if x" ); + G->register_fct_i_is ( "throw_if", func_throw_if ); + G->register_fct_meta ( "throw_unless", 1, "(x,s): throw s if !x" ); + G->register_fct_i_is ( "throw_unless", func_throw_unless ); G->register_fct_meta ( "min2", 2, "(x,y): the smaller of the two arguments x and y" ); G->register_fct_i_ii ( "min2", func_min ); G->register_fct_d_dd ( "min2", func_min ); diff --git a/pub/lib/fregistry.hpp b/pub/lib/fregistry.hpp index 50f37d7f51e5c9afc6459323dea82d165683ceee..392ceca5cb4ba8121b53e4aba1b0d04f72008bdc 100644 --- a/pub/lib/fregistry.hpp +++ b/pub/lib/fregistry.hpp @@ -24,6 +24,7 @@ typedef string (*func_s_s) (string); typedef int (*func_i_ii) (int, int); typedef int (*func_i_id) (int, double); +typedef int (*func_i_is) (int, string); typedef int (*func_i_di) (double, int); typedef int (*func_i_dd) (double, double); typedef int (*func_i_si) (string, int); @@ -110,6 +111,9 @@ public: void register_fct_i_id( const char* _tag, func_i_id _f ) { register_fct_template( _tag, "i", "id", (funcPtr)_f ); } + void register_fct_i_is( const char* _tag, func_i_is _f ) + { register_fct_template( _tag, "i", "is", (funcPtr)_f ); } + void register_fct_i_di( const char* _tag, func_i_di _f ) { register_fct_template( _tag, "i", "di", (funcPtr)_f ); } diff --git a/pub/lib/node.cpp b/pub/lib/node.cpp index 10b450d8f886c18384a954f75fb61d6d1c034dd3..7d511c5ce8d130e0dad19850467efa33f33447b2 100644 --- a/pub/lib/node.cpp +++ b/pub/lib/node.cpp @@ -136,6 +136,8 @@ const RObj CNodeFun::tree_val( const CContext& ctx ) const val = (*(func_i_s)(f))( pa[0]->to_s() ); else if ( tf->intypes=="ii" ) val = (*(func_i_ii)(f))( pa[0]->to_i(), pa[1]->to_i() ); + else if ( tf->intypes=="is" ) + val = (*(func_i_is)(f))( pa[0]->to_i(), pa[1]->to_s() ); else if ( tf->intypes=="dd" ) val = (*(func_i_dd)(f))( pa[0]->to_r(), pa[1]->to_r() ); else if ( tf->intypes=="si" ) diff --git a/pub/lib/toplevel.cpp b/pub/lib/toplevel.cpp index 101fee201727f4bdf6f7ffef52b1148034b5c0f8..631dcf66c9a0e72667329d0d4e53e9adbf46e331 100644 --- a/pub/lib/toplevel.cpp +++ b/pub/lib/toplevel.cpp @@ -179,16 +179,20 @@ void CFrida::execute_file( const string fnam ) try{ cout << "executing " << fnam << "\n"; ifstream F( fnam ); - for( lineno=1; ; ++lineno ){ + for( lineno=0; ; ++lineno ){ string cmdline = NMacro::readln( "", &F ); if ( cmdline=="EOF" ) break; - execute_cmd( cmdline ); + try { + execute_cmd( cmdline ); + } catch( string& ex ) { + throw "'" + cmdline + "': " + ex; + } } } catch( string& ex ) { cerr << "Error in script " << fnam << ", line " << lineno << ": " << ex << endl; } catch( const char* ex ) { - cerr << "Error in script " << fnam << ", line " << lineno << ": " << ex << endl; + cerr << "BUG: char* error in script " << fnam << ", line " << lineno << ": " << ex << endl; } catch( ... ) { cerr << "BUG: catched invalid exception\n"; } diff --git a/pub/readplus/macro.cpp b/pub/readplus/macro.cpp index fae2baa85fe50e7d366fb6d29b6d6ce96471efef..96603bf5e3e8bae5cdf3043d3308f5bdcd21f7c9 100644 --- a/pub/readplus/macro.cpp +++ b/pub/readplus/macro.cpp @@ -30,7 +30,6 @@ namespace NMacro { // the following are only called indirectly through macros: void metacmd_incl( string r ); - string metacmd_echo( string r ); // auxiliary: string wordexp_cpp_unique( const string& s ); @@ -196,4 +195,4 @@ void NMacro::metacmd_incl( string r ) bool NMacro::is_separator( char c ) { return string(" \t").find_first_of( c )!=string::npos; -} \ No newline at end of file +} diff --git a/pub/test/arithmetics.f2t b/pub/test/arithmetics.f2t index c382584625900df733457bd19eb0c11fdc493e18..6e050946b12f24f838934d767c583768260ec330 100755 --- a/pub/test/arithmetics.f2t +++ b/pub/test/arithmetics.f2t @@ -1,11 +1,11 @@ #!/usr/bin/env frida -exit_unless(2+3==5) -exit_unless(0.2+.3==.5) -exit_unless(0.2+3==3.2) -exit_unless(2<3) -exit_unless(!(3<3)) -exit_unless(3<=3) -exit_unless(3.1>3) -exit_unless(!(3.>3)) -exit_unless(!(-3.<-3)) +throw_unless(2+3==5,"arithmetic_failure") +throw_unless(0.2+.3==.5,"arithmetic_failure") +throw_unless(0.2+3==3.2,"arithmetic_failure") +throw_unless(2<3,"arithmetic_failure") +throw_unless(!(3<3),"arithmetic_failure") +throw_unless(3<=3,"arithmetic_failure") +throw_unless(3.1>3,"arithmetic_failure") +throw_unless(!(3.>3),"arithmetic_failure") +throw_unless(!(-3.<-3),"arithmetic_failure") exit(1) \ No newline at end of file diff --git a/pub/test/curve_functionals.f2t b/pub/test/curve_functionals.f2t index f91c34d0e2040df069501c712785d4e4d6fd939b..900ae2c6ac68eff02bebd983d349f8b1a296a445 100755 --- a/pub/test/curve_functionals.f2t +++ b/pub/test/curve_functionals.f2t @@ -1,4 +1,4 @@ #!/usr/bin/env frida cca sin(t) -exit_unless(abs(integrate(0,pi)-2)<1e-14) +throw_unless(abs(integrate(0,pi)-2)<1e-14,"integration_failed") exit(1) \ No newline at end of file diff --git a/pub/test/divisions.f2t b/pub/test/divisions.f2t index b6154b8f6d211fb9c4a3eef323c5fd60d48a7334..6501107ab54e2a80640a73d9270fe8dfff1bc8a7 100755 --- a/pub/test/divisions.f2t +++ b/pub/test/divisions.f2t @@ -1,5 +1,5 @@ #!/usr/bin/env frida -exit_unless(abs(5/3-5.0/3.0)<1e-14) -exit_unless(5//3==1) -exit_unless(5%3==2) +throw_unless(abs(5/3-5.0/3.0)<1e-14,"fp_division_failed") +throw_unless(5//3==1,"int_division_failed") +throw_unless(5%3==2,"modulo_failed") exit(1) \ No newline at end of file diff --git a/pub/test/oi_avge.f2t b/pub/test/oi_avge.f2t index c04454e60679838a62d49f907a31445b7e49842c..a824c2b717b5ef9ea79696fc0e08e9e7376583b4 100755 --- a/pub/test/oi_avge.f2t +++ b/pub/test/oi_avge.f2t @@ -1,4 +1,5 @@ #!/usr/bin/env frida fm 11 1 h oy i -exit(avge==5) +throw_unless(avge==5,"final_result_wrong") +exit(1) \ No newline at end of file diff --git a/pub/test/oi_p.f2t b/pub/test/oi_p.f2t index 05fd140cb4a61c6589f08b13b7336e1c6e237675..128e95fd86fddbf307c3006c96af6e1824edf984 100755 --- a/pub/test/oi_p.f2t +++ b/pub/test/oi_p.f2t @@ -3,4 +3,5 @@ fm 3 3 h cc p0*t op0 j+.77 oi p0 -exit(y[,,2]==2.77) +throw_unless(y[,,2]==2.77,"final_result_wrong") +exit(1) \ No newline at end of file diff --git a/pub/test/oy1.f2t b/pub/test/oy1.f2t index 35ebc41276cea64a8e3f190d2d1f45aed2bf0462..71b55adc0e81f0d245fc71db8b60ed446f930a5f 100755 --- a/pub/test/oy1.f2t +++ b/pub/test/oy1.f2t @@ -4,4 +4,5 @@ ox! i oy! j+i oz0! j oy x+z0 -exit(y[0,2,7]==9&&y[1,2,7]==9) +throw_unless(y[0,2,7]==9&&y[1,2,7]==9,"final_result_wrong") +exit(1) \ No newline at end of file diff --git a/pub/test/oy_arg_collat.f2t b/pub/test/oy_arg_collat.f2t index 77eca152c9e3bae6a62bed6ec24c511300f48fdf..23c11be8ba3be1146283589e7bcca23b7f87a7ef 100755 --- a/pub/test/oy_arg_collat.f2t +++ b/pub/test/oy_arg_collat.f2t @@ -5,4 +5,5 @@ fm 7 1 h oy! i 0 oy y/y[1,0] df -exit(y[2,2,6]==3) +throw_unless(y[2,2,6]==3,"final_result_wrong") +exit(1) \ No newline at end of file diff --git a/pub/test/run b/pub/test/run index 3736c5f46a242e61bb71f0f18df1a612ccb75838..b5abbc4ca7243008e38a27cce665e31f2ef07261 100755 --- a/pub/test/run +++ b/pub/test/run @@ -11,4 +11,4 @@ for I in *.f2t; do let COUNTER=COUNTER+1 fi done -echo "=> $COUNTER failures" +echo "=> $COUNTER failures. See log.tmp for full dialogs." diff --git a/pub/test/ternary.f2t b/pub/test/ternary.f2t index 76d661b06a971c0ac19680ba457fce62cbc1b23a..ca9c42f529241caf61fa6ccd10fa52d8e2ed6416 100755 --- a/pub/test/ternary.f2t +++ b/pub/test/ternary.f2t @@ -1,4 +1,4 @@ #!/usr/bin/env frida -exit_unless(0?2:3==3) -exit_unless(1?4:5==4) +throw_unless(0?2:3==3,"cond_expr_failed") +throw_unless(1?4:5==4,"cond_expr_failed") exit(1)