Search code examples
assertexit-codemaple

How to make non-interactive Maple exit on assertion failure?


My t.ms file contains:

interface(prettyprint=0): kernelopts(assertlevel=1):
ASSERT(1<1):
ASSERT(2<2):

When I run:

maple -q t.ms; echo $?

I get:

Error, assertion failed
Error, assertion failed
0

When I run:

maple -e 2 -q t.ms; echo $?

I get:

Error, assertion failed
0

I want to get:

Error, assertion failed
4

That is, I want Maple to exit with a nonzero exit status upon the first failing assertion. (I don't care if the exit code is 1 or anything else as long as it's nonzero. I've got the number 4 from the documentation, related to errorbreak) How do I get that?


Solution

  • The documentation doesn't make it very clear that one must use,

    `quit`(n)
    

    with name-quotes.

    interface(prettyprint=0):
    
    handler:=proc(e::uneval)
      local failed;
      printf("entered\n"); # remove this when satisfied
      failed:=false;
      try
        if evalb(eval(e)) <> true then
          error;
        end if;;
      catch:
        failed:=true;
        printf("Error, assertion failed\n");
      finally;
        if failed then
           `quit`(5);
        end if;
      end try;
      true;
    end proc:
    
    ASSERT( handler( 1<1 )):
    ASSERT( handler( 2<2 )):
    

    Now, saving this as file uh.mpl then using Maple 18.01 for Linux I see,

    $ maple18.01 -q -A 2 ~/uh.mpl ; echo $?
    entered
    Error, assertion failed
    5
    

    And if run without the -A 2 then it doesn't run the asserted checks.

    [edited] Here below is a slight modification, to process additional arguments as part of the printing.

    handler:=proc(e::uneval)
      local failed;
      printf("entered\n"); # remove this when satisfied
      failed:=false;
      try
        if evalb(eval(e)) <> true then
          error;
        end if;;
      catch:
      failed:=true;
      printf("Error, assertion failed, %q\n", _rest);
      finally;
      if failed then
         `quit`(5);
      end if;
      end try;
      true;
    end proc: