struct globals {
IF_FEATURE_BC_SIGNALS(smallint ttyin;)
+ IF_FEATURE_CLEAN_UP(smallint exiting;)
smallint eof;
char sbgn;
char send;
#else
# define G_ttyin 0
#endif
+#if ENABLE_FEATURE_CLEAN_UP
+# define G_exiting G.exiting
+#else
+# define G_exiting 0
+#endif
#define IS_BC (ENABLE_BC && (!ENABLE_DC || applet_name[0] == 'b'))
#if ENABLE_BC
}
#if ENABLE_FEATURE_CLEAN_UP
-#define quit_or_return_for_exit() \
+#define QUIT_OR_RETURN_TO_MAIN \
do { \
IF_FEATURE_BC_SIGNALS(G_ttyin = 0;) /* do not loop in main loop anymore */ \
+ G_exiting = 1; \
return BC_STATUS_FAILURE; \
} while (0)
#else
-#define quit_or_return_for_exit() quit()
+#define QUIT_OR_RETURN_TO_MAIN quit()
#endif
static void quit(void) NORETURN;
// "quit" is a compile-time command. For example,
// "if (0 == 1) quit" terminates when parsing the statement,
// not when it is executed
- quit_or_return_for_exit();
+ QUIT_OR_RETURN_TO_MAIN;
}
case BC_LEX_KEY_RETURN:
if (G.prog.stack.len < val)
return bc_error_stack_has_too_few_elements();
if (G.prog.stack.len == val) {
- if (ENABLE_FEATURE_CLEAN_UP)
- return BC_STATUS_FAILURE;
- quit();
+ QUIT_OR_RETURN_TO_MAIN;
}
bc_vec_npop(&G.prog.stack, val);
case BC_INST_HALT:
{
- quit_or_return_for_exit();
+ QUIT_OR_RETURN_TO_MAIN;
break;
}
case BC_INST_QUIT:
{
if (G.prog.stack.len <= 2)
- quit_or_return_for_exit();
+ QUIT_OR_RETURN_TO_MAIN;
bc_vec_npop(&G.prog.stack, 2);
break;
}
{
BcStatus st = bc_vm_exec();
#if ENABLE_FEATURE_CLEAN_UP
+ if (G_exiting) // it was actually "halt" or "quit"
+ st = EXIT_SUCCESS;
bc_vm_free();
# if ENABLE_FEATURE_EDITING
free_line_input_t(G.line_input_state);