diff options
-rw-r--r-- | doc/sciteco.1.in | 7 | ||||
-rw-r--r-- | src/core-commands.c | 9 | ||||
-rw-r--r-- | src/main.c | 14 | ||||
-rw-r--r-- | tests/testsuite.at | 22 |
4 files changed, 38 insertions, 14 deletions
diff --git a/doc/sciteco.1.in b/doc/sciteco.1.in index f57415c..c7ad1a9 100644 --- a/doc/sciteco.1.in +++ b/doc/sciteco.1.in @@ -223,7 +223,12 @@ Execute \(lqsciteco --help\(rq for more details. .SCITECO_TOPIC status . \*(ST will return a non-null exit code if an error occurred during -batch mode processing. +batch mode processing \(em usually 1 on UNIX. +Otherwise the top value on the numeric stack will determine +the process' exit code as if passed to libc's +.BR exit (3) +function. +On UNIX systems only numbers between 0 and 255 may be meaningfull. . . .SH ENVIRONMENT diff --git a/src/core-commands.c b/src/core-commands.c index 141ce0a..337e8df 100644 --- a/src/core-commands.c +++ b/src/core-commands.c @@ -1320,7 +1320,7 @@ teco_state_control_xor(teco_machine_main_t *ctx, GError **error) } /*$ ^C exit - * ^C -- Exit program immediately + * [n]^C -- Exit program immediately * * Lets the top-level macro return immediately * regardless of the current macro invocation frame. @@ -1333,6 +1333,10 @@ teco_state_control_xor(teco_machine_main_t *ctx, GError **error) * effectively just like \(lq-EX\fB$$\fP\(rq * (when executed in the top-level macro at least). * + * Any numeric parameter is returned by the process + * as its exit status. + * By default, the success code is returned. + * * The \fBquit\fP hook is still executed. */ static void @@ -1678,6 +1682,9 @@ teco_state_escape_input(teco_machine_main_t *ctx, gunichar chr, GError **error) * Returning from the top-level macro in batch mode * will exit the program or start up interactive mode depending * on whether program exit has been requested. + * If \fB$$\fP exits the program, any remaining numeric parameter + * is returned by the process as its exit status. + * By default, the success code is returned. * \(lqEX\fB$$\fP\(rq is thus a common idiom to exit * prematurely. * @@ -35,6 +35,7 @@ #endif #include "sciteco.h" +#include "expressions.h" #include "file-utils.h" #include "cmdline.h" #include "interface.h" @@ -337,6 +338,7 @@ main(int argc, char **argv) #endif { g_autoptr(GError) error = NULL; + teco_int_t ret = EXIT_SUCCESS; #ifdef DEBUG_PAUSE /* Windows debugging hack (see above) */ @@ -461,7 +463,8 @@ main(int argc, char **argv) } g_clear_error(&error); - if (!teco_ed_hook(TECO_ED_HOOK_QUIT, &error)) + if (!teco_expressions_pop_num_calc(&ret, EXIT_SUCCESS, &error) || + !teco_ed_hook(TECO_ED_HOOK_QUIT, &error)) goto cleanup; goto cleanup; } @@ -499,7 +502,8 @@ main(int argc, char **argv) g_clear_error(&error); if (teco_quit_requested) { - if (!teco_ed_hook(TECO_ED_HOOK_QUIT, &error)) + if (!teco_expressions_pop_num_calc(&ret, EXIT_SUCCESS, &error) || + !teco_ed_hook(TECO_ED_HOOK_QUIT, &error)) goto cleanup; goto cleanup; } @@ -553,8 +557,10 @@ main(int argc, char **argv) goto cleanup; cleanup: - if (error != NULL) + if (error != NULL) { teco_error_display_full(error); + ret = EXIT_FAILURE; + } #ifndef NDEBUG teco_ring_cleanup(); @@ -565,5 +571,5 @@ cleanup: #endif teco_interface_cleanup(); - return error ? EXIT_FAILURE : EXIT_SUCCESS; + return ret; } diff --git a/tests/testsuite.at b/tests/testsuite.at index 294bb5e..5cf3d4f 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -6,11 +6,11 @@ AT_COLOR_TESTS AT_ARG_OPTION([valgrind], AS_HELP_STRING([--valgrind], [Run tests under Valgrind (memcheck)])) -# NOTE: There is currently no way to influence the return -# code of SciTECO, except to provoke an error. -# Since errors cannot be yielded explicitly, we use the -# idiom "(0/0)" to enforce a "Division by zero" error -# whenever we want to fail. +# NOTE: We could use 1^C to get an unsuccessful return code. +# However, this won't print any stack trace or error message. +# Therefore, we still use the idiom "(0/0)" to enforce a "Division by zero" +# error whenever we want to fail. +# A proper error throwing construct should be used instead once it's available. # # NOTE: By convention, we double quote the SciTECO test case # snippets, ie. put them between [[ and ]]. @@ -44,7 +44,7 @@ m4_define([TE_RUBOUT_WORD], [m4_format([%c], 23)]) AT_BANNER([Language features]) AT_SETUP([Number stack]) -TE_CHECK([[2%a,%a - 3"N(0/0)']], 0, ignore, ignore) +TE_CHECK([[2%a,%a - 3"N(0/0)' $]], 0, ignore, ignore) # It's not quite clear what would be the best semantics for comma: # a) Superfluous commas as in ",," or "(1,)" should be an error. # b) Superfluous commas should be ignored which is effectively what we do now. @@ -55,6 +55,12 @@ TE_CHECK([[(1,) "~|(0/0)']], 0, ignore, ignore) TE_CHECK([[1,(2)==]], 0, ignore, ignore) AT_CLEANUP +AT_SETUP([Exit status]) +TE_CHECK([[23]], 23, ignore, ignore) +TE_CHECK([[42^C]], 42, ignore, ignore) +TE_CHECK([[13$$]], 13, ignore, ignore) +AT_CLEANUP + AT_SETUP([Radix]) TE_CHECK([[0^R]], 1, ignore, ignore) TE_CHECK([[0U.^R]], 1, ignore, ignore) @@ -103,8 +109,8 @@ AT_SETUP([Pass-through loops]) # More elegant would be a command for popping exactly one argument like <:$>. TE_CHECK([[1,2,3,-1:<"~1;'%a=> Qa-6"N(0/0)']], 0, ignore, ignore) TE_CHECK([[1,2,3,-1:<"~1;'%a= F>(0/0)> Qa-6"N(0/0)']], 0, ignore, ignore) -TE_CHECK([[3<%a:>-3"N(0/0)']], 0, ignore, ignore) -TE_CHECK([[3<%a :F>(0/0):>-3"N(0/0)']], 0, ignore, ignore) +TE_CHECK([[3<%a:>-3"N(0/0)' $]], 0, ignore, ignore) +TE_CHECK([[3<%a :F>(0/0):>-3"N(0/0)' $]], 0, ignore, ignore) AT_CLEANUP AT_SETUP([String arguments]) |