changeset 19478:3f29b433bd5d

do a better job of preserving warning state when running tests * error.cc (vwarning): Always set Vlast_warning and Vlast_warning_message. * __run_test_suite__.m: Restore warning state to initial value before exiting. * test.m: Restore warning state to initial value after each test block.
author John W. Eaton <jwe@octave.org>
date Tue, 30 Dec 2014 11:33:33 -0500
parents 0f79fa9b3a8c
children 0b4915fcd2eb
files libinterp/corefcn/error.cc scripts/testfun/__run_test_suite__.m scripts/testfun/test.m
diffstat 3 files changed, 365 insertions(+), 365 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/error.cc	Fri Sep 19 18:24:05 2014 +0200
+++ b/libinterp/corefcn/error.cc	Tue Dec 30 11:33:33 2014 -0500
@@ -171,13 +171,8 @@
 
   std::string msg_string = output_buf.str ();
 
-  if (! warning_state)
-    {
-      // This is the first warning in a possible series.
-
-      Vlast_warning_id = id;
-      Vlast_warning_message = msg_string;
-    }
+  Vlast_warning_id = id;
+  Vlast_warning_message = msg_string;
 
   if (! Vquiet_warning)
     {
--- a/scripts/testfun/__run_test_suite__.m	Fri Sep 19 18:24:05 2014 +0200
+++ b/scripts/testfun/__run_test_suite__.m	Tue Dec 30 11:33:33 2014 -0500
@@ -40,82 +40,83 @@
   global topsrcdir = fcnfiledir;
   global topbuilddir = testsdir;
   pso = page_screen_output ();
-  warn_state = warning ("query", "quiet");
-  warning ("on", "quiet");
+  orig_wstate = warning ();
   logfile = make_absolute_filename ("fntests.log");
-  try
+  unwind_protect
     page_screen_output (false);
+    warning ("on", "quiet");
     warning ("off", "Octave:deprecated-function");
-    fid = fopen (logfile, "wt");
-    if (fid < 0)
-      error ("could not open %s for writing", logfile);
-    endif
-    test ("", "explain", fid);
-    dp = dn = dxf = dsk = 0;
-    puts ("\nIntegrated test scripts:\n\n");
-    for i = 1:length (fcndirs)
-      [p, n, xf, sk] = run_test_script (fid, fcndirs{i});
-      dp += p;
-      dn += n;
-      dxf += xf;
-      dsk += sk;
-    endfor
-    puts ("\nFixed test scripts:\n\n");
-    for i = 1:length (fixedtestdirs)
-      [p, n, xf, sk] = run_test_dir (fid, fixedtestdirs{i});
-      dp += p;
-      dn += n;
-      dxf += xf;
-      dsk += sk;
-    endfor
-    puts ("\nSummary:\n\n");
-    nfail = dn - dp - dxf;
-    printf ("  PASS    %6d\n", dp);
-    printf ("  FAIL    %6d\n", nfail);
-    if (dxf > 0)
-      printf ("  XFAIL   %6d\n", dxf);
-    endif
-    if (dsk > 0)
-      printf ("  SKIPPED %6d\n", dsk);
-    endif
-    puts ("\n");
-    printf ("See the file %s for additional details.\n", logfile);
-    if (dxf > 0)
+    try
+      fid = fopen (logfile, "wt");
+      if (fid < 0)
+        error ("could not open %s for writing", logfile);
+      endif
+      test ("", "explain", fid);
+      dp = dn = dxf = dsk = 0;
+      puts ("\nIntegrated test scripts:\n\n");
+      for i = 1:length (fcndirs)
+        [p, n, xf, sk] = run_test_script (fid, fcndirs{i});
+        dp += p;
+        dn += n;
+        dxf += xf;
+        dsk += sk;
+      endfor
+      puts ("\nFixed test scripts:\n\n");
+      for i = 1:length (fixedtestdirs)
+        [p, n, xf, sk] = run_test_dir (fid, fixedtestdirs{i});
+        dp += p;
+        dn += n;
+        dxf += xf;
+        dsk += sk;
+      endfor
+      puts ("\nSummary:\n\n");
+      nfail = dn - dp - dxf;
+      printf ("  PASS    %6d\n", dp);
+      printf ("  FAIL    %6d\n", nfail);
+      if (dxf > 0)
+        printf ("  XFAIL   %6d\n", dxf);
+      endif
+      if (dsk > 0)
+        printf ("  SKIPPED %6d\n", dsk);
+      endif
       puts ("\n");
-      puts ("Expected failures (listed as XFAIL above) are known bugs.\n");
-      puts ("Please help improve Octave by contributing fixes for them.\n");
-    endif
-    if (dsk > 0)
-      puts ("\n");
-      puts ("Tests are most often skipped because the features they require\n");
-      puts ("have been disabled.  Features are most often disabled because\n");
-      puts ("they require dependencies that were not present when Octave\n");
-      puts ("was built.  The configure script should have printed a summary\n");
-      puts ("at the end of its run indicating which dependencies were not found.\n");
-    endif
+      printf ("See the file %s for additional details.\n", logfile);
+      if (dxf > 0)
+        puts ("\n");
+        puts ("Expected failures (listed as XFAIL above) are known bugs.\n");
+        puts ("Please help improve Octave by contributing fixes for them.\n");
+      endif
+      if (dsk > 0)
+        puts ("\n");
+        puts ("Tests are most often skipped because the features they require\n");
+        puts ("have been disabled.  Features are most often disabled because\n");
+        puts ("they require dependencies that were not present when Octave\n");
+        puts ("was built.  The configure script should have printed a summary\n");
+        puts ("at the end of its run indicating which dependencies were not found.\n");
+      endif
 
-    ## Weed out deprecated and private functions
-    weed_idx = cellfun (@isempty, regexp (files_with_tests, '\<deprecated\>|\<private\>', 'once'));
-    files_with_tests = files_with_tests(weed_idx);
-    weed_idx = cellfun (@isempty, regexp (files_with_no_tests, '\<deprecated\>|\<private\>', 'once'));
-    files_with_no_tests = files_with_no_tests(weed_idx);
+      ## Weed out deprecated and private functions
+      weed_idx = cellfun (@isempty, regexp (files_with_tests, '\<deprecated\>|\<private\>', 'once'));
+      files_with_tests = files_with_tests(weed_idx);
+      weed_idx = cellfun (@isempty, regexp (files_with_no_tests, '\<deprecated\>|\<private\>', 'once'));
+      files_with_no_tests = files_with_no_tests(weed_idx);
 
-    report_files_with_no_tests (files_with_tests, files_with_no_tests, ".m");
+      report_files_with_no_tests (files_with_tests, files_with_no_tests, ".m");
 
-    puts ("\nPlease help improve Octave by contributing tests for these files\n");
-    printf ("(see the list in the file %s).\n\n", logfile);
+      puts ("\nPlease help improve Octave by contributing tests for these files\n");
+      printf ("(see the list in the file %s).\n\n", logfile);
 
-    fprintf (fid, "\nFiles with no tests:\n\n%s",
-                  list_in_columns (files_with_no_tests, 80));
-    fclose (fid);
-
+      fprintf (fid, "\nFiles with no tests:\n\n%s",
+                    list_in_columns (files_with_no_tests, 80));
+      fclose (fid);
+    catch
+      disp (lasterr ());
+    end_try_catch
+  unwind_protect_cleanup
+    warning ("off", "all");
+    warning (orig_wstate);
     page_screen_output (pso);
-    warning (warn_state.state, "quiet");
-  catch
-    page_screen_output (pso);
-    warning (warn_state.state, "quiet");
-    disp (lasterr ());
-  end_try_catch
+  end_unwind_protect
 endfunction
 
 function print_test_file_name (nm)
--- a/scripts/testfun/test.m	Fri Sep 19 18:24:05 2014 +0200
+++ b/scripts/testfun/test.m	Tue Dec 30 11:33:33 2014 -0500
@@ -301,343 +301,347 @@
   __clearfcn = "";
   for __i = 1:numel (__blockidx)-1
 
-    ## Extract the block.
-    __block = __body(__blockidx(__i):__blockidx(__i+1)-2);
+    ## FIXME: Should other global settings be similarly saved and restored?
+    orig_wstate = warning ();
+    unwind_protect
 
-    ## Print the code block before execution if in verbose mode.
-    if (__verbose > 0)
-      fprintf (__fid, "%s%s\n", __signal_block, __block);
-      fflush (__fid);
-    endif
+      ## Extract the block.
+      __block = __body(__blockidx(__i):__blockidx(__i+1)-2);
+
+      ## Print the code block before execution if in verbose mode.
+      if (__verbose > 0)
+        fprintf (__fid, "%s%s\n", __signal_block, __block);
+        fflush (__fid);
+      endif
 
-    ## Split __block into __type and __code.
-    __idx = find (! isletter (__block));
-    if (isempty (__idx))
-      __type = __block;
-      __code = "";
-    else
-      __type = __block(1:__idx(1)-1);
-      __code = __block(__idx(1):length (__block));
-    endif
+      ## Split __block into __type and __code.
+      __idx = find (! isletter (__block));
+      if (isempty (__idx))
+        __type = __block;
+        __code = "";
+      else
+        __type = __block(1:__idx(1)-1);
+        __code = __block(__idx(1):length (__block));
+      endif
+
+      ## Assume the block will succeed.
+      __success = true;
+      __msg = [];
+      __isxtest = false;
+
+### DEMO
+
+      ## If in __grabdemo mode, then don't process any other block type.
+      ## So that the other block types don't have to worry about
+      ## this __grabdemo mode, the demo block processor grabs all block
+      ## types and skips those which aren't demo blocks.
+
+      __isdemo = strcmp (__type, "demo");
+      if (__grabdemo || __isdemo)
+        __istest = false;
 
-    ## Assume the block will succeed.
-    __success = true;
-    __msg = [];
-    __isxtest = false;
-
-    ### DEMO
-
-    ## If in __grabdemo mode, then don't process any other block type.
-    ## So that the other block types don't have to worry about
-    ## this __grabdemo mode, the demo block processor grabs all block
-    ## types and skips those which aren't demo blocks.
+        if (__grabdemo && __isdemo)
+          if (isempty (__demo_code))
+            __demo_code = __code;
+            __demo_idx = [1, length(__demo_code)+1];
+          else
+            __demo_code = [__demo_code, __code];
+            __demo_idx = [__demo_idx, length(__demo_code)+1];
+          endif
 
-    __isdemo = strcmp (__type, "demo");
-    if (__grabdemo || __isdemo)
-      __istest = false;
+        elseif (__rundemo && __isdemo)
+          try
+            ## process the code in an environment without variables
+            eval (sprintf ("function __test__ ()\n%s\nendfunction", __code));
+            __test__;
+            input ("Press <enter> to continue: ", "s");
+          catch
+            __success = false;
+            __msg = [__signal_fail "demo failed\n" lasterr()];
+          end_try_catch
+          clear __test__;
 
-      if (__grabdemo && __isdemo)
-        if (isempty (__demo_code))
-          __demo_code = __code;
-          __demo_idx = [1, length(__demo_code)+1];
+        endif
+        ## Code already processed.
+        __code = "";
+
+### SHARED
+
+      elseif (strcmp (__type, "shared"))
+        __istest = false;
+
+        ## Separate initialization code from variables.
+        __idx = find (__code == "\n");
+        if (isempty (__idx))
+          __vars = __code;
+          __code = "";
         else
-          __demo_code = [__demo_code, __code];
-          __demo_idx = [__demo_idx, length(__demo_code)+1];
+          __vars = __code (1:__idx(1)-1);
+          __code = __code (__idx(1):length (__code));
         endif
 
-      elseif (__rundemo && __isdemo)
-        try
-          ## process the code in an environment without variables
-          eval (sprintf ("function __test__ ()\n%s\nendfunction", __code));
-          __test__;
-          input ("Press <enter> to continue: ", "s");
-        catch
-          __success = false;
-          __msg = [__signal_fail "demo failed\n" lasterr()];
-        end_try_catch
-        clear __test__;
+        ## Strip comments off the variables.
+        __idx = find (__vars == "%" | __vars == "#");
+        if (! isempty (__idx))
+          __vars = __vars(1:__idx(1)-1);
+        endif
 
-      endif
-      ## Code already processed.
-      __code = "";
-
-    ### SHARED
-
-    elseif (strcmp (__type, "shared"))
-      __istest = false;
+        ## Assign default values to variables.
+        try
+          __vars = deblank (__vars);
+          if (! isempty (__vars))
+            eval ([strrep(__vars, ",", "=[];"), "=[];"]);
+            __shared = __vars;
+            __shared_r = ["[ " __vars "] = "];
+          else
+            __shared = " ";
+            __shared_r = " ";
+          endif
+        catch
+          ## Couldn't declare, so don't initialize.
+          __code = "";
+          __success = false;
+          __msg = [__signal_fail "shared variable initialization failed\n"];
+        end_try_catch
 
-      ## Separate initialization code from variables.
-      __idx = find (__code == "\n");
-      if (isempty (__idx))
-        __vars = __code;
-        __code = "";
-      else
-        __vars = __code (1:__idx(1)-1);
-        __code = __code (__idx(1):length (__code));
-      endif
+        ## Initialization code will be evaluated below.
+
+### FUNCTION
 
-      ## Strip comments off the variables.
-      __idx = find (__vars == "%" | __vars == "#");
-      if (! isempty (__idx))
-        __vars = __vars(1:__idx(1)-1);
-      endif
+      elseif (strcmp (__type, "function"))
+        __istest = false;
+        persistent __fn = 0;
+        __name_position = function_name (__block);
+        if (isempty (__name_position))
+          __success = false;
+          __msg = [__signal_fail "test failed: missing function name\n"];
+        else
+          __name = __block(__name_position(1):__name_position(2));
+          __code = __block;
+          try
+            eval (__code);  # Define the function
+            __clearfcn = sprintf ("%sclear %s;\n", __clearfcn, __name);
+          catch
+            __success = false;
+            __msg = [__signal_fail "test failed: syntax error\n" lasterr()];
+          end_try_catch
+        endif
+        __code = "";
 
-      ## Assign default values to variables.
-      try
-        __vars = deblank (__vars);
-        if (! isempty (__vars))
-          eval ([strrep(__vars, ",", "=[];"), "=[];"]);
-          __shared = __vars;
-          __shared_r = ["[ " __vars "] = "];
-        else
-          __shared = " ";
-          __shared_r = " ";
-        endif
-      catch
-        ## Couldn't declare, so don't initialize.
+### ENDFUNCTION
+
+      elseif (strcmp (__type, "endfunction"))
+        ## endfunction simply declares the end of a previous function block.
+        ## There is no processing to be done here, just skip to next block.
+        __istest = false;
         __code = "";
-        __success = false;
-        __msg = [__signal_fail "shared variable initialization failed\n"];
-      end_try_catch
+
+### ASSERT/FAIL
 
-      ## Initialization code will be evaluated below.
+      elseif (strcmp (__type, "assert") || strcmp (__type, "fail"))
+        __istest = true;
+        ## Put the keyword back on the code.
+        __code = __block;
+        ## The code will be evaluated below as a test block.
 
-    ### FUNCTION
+### ERROR/WARNING
 
-    elseif (strcmp (__type, "function"))
-      __istest = false;
-      persistent __fn = 0;
-      __name_position = function_name (__block);
-      if (isempty (__name_position))
-        __success = false;
-        __msg = [__signal_fail "test failed: missing function name\n"];
-      else
-        __name = __block(__name_position(1):__name_position(2));
-        __code = __block;
+      elseif (strcmp (__type, "error") || strcmp (__type, "warning"))
+        __istest = true;
+        __iswarning = strcmp (__type, "warning");
+        [__pattern, __id, __code] = getpattern (__code);
+        if (__id)
+          __patstr = ["id=" __id];
+        else
+          if (! strcmp (__pattern, '.'))
+            __patstr = ["<" __pattern ">"];
+          else
+            __patstr = ifelse (__iswarning, "a warning", "an error");
+          endif
+        endif
         try
-          eval (__code);  # Define the function
-          __clearfcn = sprintf ("%sclear %s;\n", __clearfcn, __name);
+          eval (sprintf ("function __test__(%s)\n%s\nendfunction",
+                         __shared, __code));
         catch
           __success = false;
           __msg = [__signal_fail "test failed: syntax error\n" lasterr()];
         end_try_catch
-      endif
-      __code = "";
-
-    ### ENDFUNCTION
-
-    elseif (strcmp (__type, "endfunction"))
-      ## endfunction simply declares the end of a previous function block.
-      ## There is no processing to be done here, just skip to next block.
-      __istest = false;
-      __code = "";
-
-    ### ASSERT/FAIL
-
-    elseif (strcmp (__type, "assert") || strcmp (__type, "fail"))
-      __istest = true;
-      ## Put the keyword back on the code.
-      __code = __block;
-      ## The code will be evaluated below as a test block.
-
-    ### ERROR/WARNING
 
-    elseif (strcmp (__type, "error") || strcmp (__type, "warning"))
-      __istest = true;
-      __iswarning = strcmp (__type, "warning");
-      [__pattern, __id, __code] = getpattern (__code);
-      if (__id)
-        __patstr = ["id=" __id];
-      else
-        if (! strcmp (__pattern, '.'))
-          __patstr = ["<" __pattern ">"];
-        else
-          __patstr = ifelse (__iswarning, "a warning", "an error");
-        endif
-      endif
-      try
-        eval (sprintf ("function __test__(%s)\n%s\nendfunction",
-                       __shared, __code));
-      catch
-        __success = false;
-        __msg = [__signal_fail "test failed: syntax error\n" lasterr()];
-      end_try_catch
+        if (__success)
+          __success = false;
+          __warnstate = warning ("query", "quiet");
+          warning ("on", "quiet");
+          ## Clear error and warning strings before starting
+          lasterr ("");
+          lastwarn ("");
+          try
+            eval (sprintf ("__test__(%s);", __shared));
+            if (! __iswarning)
+              __msg = [__signal_fail "error failed.\n" ...
+                                     "Expected " __patstr ", but got no error\n"];
+            else
+              if (! isempty (__id))
+                [~, __err] = lastwarn ();
+                __mismatch = ! strcmp (__err, __id);
+              else
+                __err = trimerr (lastwarn (), "warning");
+                __mismatch = isempty (regexp (__err, __pattern, "once"));
+              endif
+              warning (__warnstate.state, "quiet");
+              if (isempty (__err))
+                __msg = [__signal_fail "warning failed.\n" ...
+                                       "Expected " __patstr ", but got no warning\n"];
+              elseif (__mismatch)
+                __msg = [__signal_fail "warning failed.\n" ...
+                                       "Expected " __patstr ", but got <" __err ">\n"];
+              else
+                __success = true;
+              endif
+            endif
 
-      if (__success)
-        __success = false;
-        __warnstate = warning ("query", "quiet");
-        warning ("on", "quiet");
-        ## Clear error and warning strings before starting
-        lasterr ("");
-        lastwarn ("");
-        try
-          ## FIXME: lastwarn () must be called once from *WITHIN* the try block
-          ##        or subsequent warning/lastwarn statements may fail.
-          ##        Likely this is something to do with the specialness of
-          ##        the try block which is disabling normal errors.
-          lastwarn ();
-          eval (sprintf ("__test__(%s);", __shared));
-          if (! __iswarning)
-            __msg = [__signal_fail "error failed.\n" ...
-                     "Expected " __patstr ", but got no error\n"];
-          else
+          catch
             if (! isempty (__id))
-              [~, __err] = lastwarn ();
+              [~, __err] = lasterr ();
               __mismatch = ! strcmp (__err, __id);
             else
-              __err = trimerr (lastwarn (), "warning");
+              __err = trimerr (lasterr (), "error");
               __mismatch = isempty (regexp (__err, __pattern, "once"));
             endif
             warning (__warnstate.state, "quiet");
-            if (isempty (__err))
+            if (__iswarning)
               __msg = [__signal_fail "warning failed.\n" ...
-                       "Expected " __patstr ", but got no warning\n"];
+                                     "Expected warning " __patstr ...
+                                     ", but got error <" __err ">\n"];
             elseif (__mismatch)
-              __msg = [__signal_fail "warning failed.\n" ...
-                       "Expected " __patstr ", but got <" __err ">\n"];
+              __msg = [__signal_fail "error failed.\n" ...
+                                     "Expected " __patstr ", but got <" __err ">\n"];
             else
               __success = true;
             endif
-          endif
+          end_try_catch
+          clear __test__;
+        endif
+        ## Code already processed.
+        __code = "";
+
+### TESTIF
+
+      elseif (strcmp (__type, "testif"))
+        __e = regexp (__code, '.$', 'lineanchors', 'once');
+        ## Strip any comment from testif line before looking for features
+        __feat_line = strtok (__code(1:__e), '#%'); 
+        __feat = regexp (__feat_line, '\w+', 'match');
+        __feat = strrep (__feat, "HAVE_", "");
+        __have_feat = __have_feature__ (__feat);
+        if (__have_feat)
+          __istest = true;
+          __code = __code(__e + 1 : end);
+        else
+          __xskip++;
+          __istest = false;
+          __code = ""; # Skip the code.
+          __msg = [__signal_skip "skipped test\n"];
+        endif
+
+### TEST
+
+      elseif (strcmp (__type, "test"))
+        __istest = true;
+        ## Code will be evaluated below.
+
+### XTEST
 
-        catch
-          if (! isempty (__id))
-            [~, __err] = lasterr ();
-            __mismatch = ! strcmp (__err, __id);
+      elseif (strcmp (__type, "xtest"))
+        __istest = false;
+        __isxtest = true;
+        ## Code will be evaluated below.
+
+### Comment block.
+
+      elseif (strcmp (__block(1:1), "#"))
+        __istest = false;
+        __code = ""; # skip the code
+
+### Unknown block.
+
+      else
+        __istest = true;
+        __success = false;
+        __msg = [__signal_fail "unknown test type!\n"];
+        __code = ""; # skip the code
+      endif
+
+      ## evaluate code for test, shared, and assert.
+      if (! isempty(__code))
+        try
+          ## FIXME: Must check for embedded test functions, which cause
+          ## segfaults, until issues with subfunctions in functions are resolved.
+          embed_func = regexp (__code, '^\s*function ', 'once', 'lineanchors');
+          if (isempty (embed_func))
+            eval (sprintf ("function %s__test__(%s)\n%s\nendfunction",
+                           __shared_r, __shared, __code));
+            eval (sprintf ("%s__test__(%s);", __shared_r, __shared));
           else
-            __err = trimerr (lasterr (), "error");
-            __mismatch = isempty (regexp (__err, __pattern, "once"));
+            error (["Functions embedded in %!test blocks are not allowed.\n", ...
+                    "Use the %!function/%!endfunction syntax instead to define shared functions for testing.\n"]);
           endif
-          warning (__warnstate.state, "quiet");
-          if (__iswarning)
-            __msg = [__signal_fail "warning failed.\n" ...
-                     "Expected warning " __patstr ...
-                     ", but got error <" __err ">\n"];
-          elseif (__mismatch)
-            __msg = [__signal_fail "error failed.\n" ...
-                     "Expected " __patstr ", but got <" __err ">\n"];
+        catch
+          if (strcmp (__type, "xtest"))
+            __msg = [__signal_fail "known failure\n" lasterr()];
+            __xfail++;
+            __success = false;
           else
-            __success = true;
+            __msg = [__signal_fail "test failed\n" lasterr()];
+            __success = false;
+          endif
+          if (isempty (lasterr ()))
+            error ("empty error text, probably Ctrl-C --- aborting");
           endif
         end_try_catch
         clear __test__;
       endif
-      ## Code already processed.
-      __code = "";
-
-    ### TESTIF
-
-    elseif (strcmp (__type, "testif"))
-      __e = regexp (__code, '.$', 'lineanchors', 'once');
-      ## Strip any comment from testif line before looking for features
-      __feat_line = strtok (__code(1:__e), '#%'); 
-      __feat = regexp (__feat_line, '\w+', 'match');
-      __feat = strrep (__feat, "HAVE_", "");
-      __have_feat = __have_feature__ (__feat);
-      if (__have_feat)
-        __istest = true;
-        __code = __code(__e + 1 : end);
-      else
-        __xskip++;
-        __istest = false;
-        __code = ""; # Skip the code.
-        __msg = [__signal_skip "skipped test\n"];
-      endif
-
-    ### TEST
-
-    elseif (strcmp (__type, "test"))
-      __istest = true;
-      ## Code will be evaluated below.
-
-    ### XTEST
-
-    elseif (strcmp (__type, "xtest"))
-      __istest = false;
-      __isxtest = true;
-      ## Code will be evaluated below.
-
-    ### Comment block.
-
-    elseif (strcmp (__block(1:1), "#"))
-      __istest = false;
-      __code = ""; # skip the code
-
-    ### Unknown block.
-
-    else
-      __istest = true;
-      __success = false;
-      __msg = [__signal_fail "unknown test type!\n"];
-      __code = ""; # skip the code
-    endif
 
-    ## evaluate code for test, shared, and assert.
-    if (! isempty(__code))
-      try
-        ## FIXME: Must check for embedded test functions, which cause
-        ## segfaults, until issues with subfunctions in functions are resolved.
-        embed_func = regexp (__code, '^\s*function ', 'once', 'lineanchors');
-        if (isempty (embed_func))
-          eval (sprintf ("function %s__test__(%s)\n%s\nendfunction",
-                         __shared_r, __shared, __code));
-          eval (sprintf ("%s__test__(%s);", __shared_r, __shared));
-        else
-          error (["Functions embedded in %!test blocks are not allowed.\n", ...
-                  "Use the %!function/%!endfunction syntax instead to define shared functions for testing.\n"]);
+      ## All done.  Remember if we were successful and print any messages.
+      if (! isempty (__msg) && (__verbose >= 0 || __logfile))
+        ## Make sure the user knows what caused the error.
+        if (__verbose < 1)
+          fprintf (__fid, "%s%s\n", __signal_block, __block);
+          fflush (__fid);
+        endif
+        fprintf (__fid, "%s\n", __msg);
+        fflush (__fid);
+        ## Show the variable context.
+        if (! strcmp (__type, "error") && ! strcmp (__type, "testif")
+            && ! all (__shared == " "))
+          fputs (__fid, "shared variables ");
+          eval (sprintf ("fdisp(__fid,var2struct(%s));", __shared));
+          fflush (__fid);
         endif
-      catch
-        if (strcmp (__type, "xtest"))
-           __msg = [__signal_fail "known failure\n" lasterr()];
-           __xfail++;
-           __success = false;
-        else
-           __msg = [__signal_fail "test failed\n" lasterr()];
-           __success = false;
+      endif
+      if (! __success && ! __isxtest)
+        __all_success = false;
+        ## Stop after 1 error if not in batch mode or only pass/fail requested.
+        if (! __batch || nargout == 1)
+          if (nargout > 0)
+            if (nargout == 1)
+              __n = false;
+            else
+              __n = __nmax = 0;
+            endif
+          endif
+          if (__close_fid)
+            fclose (__fid);
+          endif
+          return;
         endif
-        if (isempty (lasterr ()))
-          error ("empty error text, probably Ctrl-C --- aborting");
-        endif
-      end_try_catch
-      clear __test__;
-    endif
+      endif
+      __tests += (__istest || __isxtest);
+      __successes += __success && (__istest || __isxtest);
 
-    ## All done.  Remember if we were successful and print any messages.
-    if (! isempty (__msg) && (__verbose >= 0 || __logfile))
-      ## Make sure the user knows what caused the error.
-      if (__verbose < 1)
-        fprintf (__fid, "%s%s\n", __signal_block, __block);
-        fflush (__fid);
-      endif
-      fprintf (__fid, "%s\n", __msg);
-      fflush (__fid);
-      ## Show the variable context.
-      if (! strcmp (__type, "error") && ! strcmp (__type, "testif")
-          && ! all (__shared == " "))
-        fputs (__fid, "shared variables ");
-        eval (sprintf ("fdisp(__fid,var2struct(%s));", __shared));
-        fflush (__fid);
-      endif
-    endif
-    if (! __success && ! __isxtest)
-      __all_success = false;
-      ## Stop after 1 error if not in batch mode or only pass/fail requested.
-      if (! __batch || nargout == 1)
-        if (nargout > 0)
-          if (nargout == 1)
-            __n = false;
-          else
-            __n = __nmax = 0;
-          endif
-        endif
-        if (__close_fid)
-          fclose (__fid);
-        endif
-        return;
-      endif
-    endif
-    __tests += (__istest || __isxtest);
-    __successes += __success && (__istest || __isxtest);
+    unwind_protect_cleanup
+      warning ("off", "all");
+      warning (orig_wstate);
+    end_unwind_protect
   endfor
 
   ## Clear any functions created during test run