bc": drop unused error codes and strings
[oweals/busybox.git] / miscutils / bc.c
index 18d388bd3e743d6d315f467294e49cb7f9a2dbf4..ee6cc47cea1fe229292425093dd847c5ba5babf3 100644 (file)
 //kbuild:lib-$(CONFIG_BC) += bc.o
 //kbuild:lib-$(CONFIG_DC) += bc.o
 
+//See www.gnu.org/software/bc/manual/bc.html
 //usage:#define bc_trivial_usage
-//usage:       "EXPRESSION...\n"
-//usage:       "function_definition\n"
+//usage:       "[-sqli] FILE..."
 //usage:
-//usage:#define bc_full_usage "\n\n"
-//usage:       "See www.gnu.org/software/bc/manual/bc.html\n"
+//usage:#define bc_full_usage "\n"
+//usage:     "\nArbitrary precision calculator"
+//usage:     "\n"
+//usage:     "\n       -i      Interactive"
+//usage:     "\n       -l      Load standard math library"
+//usage:     "\n       -s      Be POSIX compatible"
+//usage:     "\n       -q      Quiet"
+//usage:     "\n       -w      Warn if extensions are used"
+///////:     "\n       -v      Version"
 //usage:
 //usage:#define bc_example_usage
 //usage:       "3 + 4.129\n"
 #include "libbb.h"
 
 typedef enum BcStatus {
-
        BC_STATUS_SUCCESS,
 
-       BC_STATUS_ALLOC_ERR,
+//     BC_STATUS_ALLOC_ERR,
        BC_STATUS_INPUT_EOF,
        BC_STATUS_BIN_FILE,
-       BC_STATUS_PATH_IS_DIR,
+//     BC_STATUS_PATH_IS_DIR,
 
        BC_STATUS_LEX_BAD_CHAR,
        BC_STATUS_LEX_NO_STRING_END,
@@ -176,7 +182,6 @@ typedef enum BcStatus {
 #if ENABLE_DC
        BC_STATUS_LEX_EXTENDED_REG,
 #endif
-
        BC_STATUS_PARSE_BAD_TOKEN,
        BC_STATUS_PARSE_BAD_EXP,
        BC_STATUS_PARSE_EMPTY_EXP,
@@ -193,7 +198,7 @@ typedef enum BcStatus {
        BC_STATUS_MATH_DIVIDE_BY_ZERO,
        BC_STATUS_MATH_BAD_STRING,
 
-       BC_STATUS_EXEC_FILE_ERR,
+//     BC_STATUS_EXEC_FILE_ERR,
        BC_STATUS_EXEC_MISMATCHED_PARAMS,
        BC_STATUS_EXEC_UNDEFINED_FUNC,
        BC_STATUS_EXEC_FILE_NOT_EXECUTABLE,
@@ -202,17 +207,16 @@ typedef enum BcStatus {
        BC_STATUS_EXEC_STRING_LEN,
        BC_STATUS_EXEC_ARRAY_LEN,
        BC_STATUS_EXEC_BAD_IBASE,
-       BC_STATUS_EXEC_BAD_SCALE,
+//     BC_STATUS_EXEC_BAD_SCALE,
        BC_STATUS_EXEC_BAD_READ_EXPR,
        BC_STATUS_EXEC_REC_READ,
        BC_STATUS_EXEC_BAD_TYPE,
-       BC_STATUS_EXEC_BAD_OBASE,
+//     BC_STATUS_EXEC_BAD_OBASE,
        BC_STATUS_EXEC_SIGNAL,
        BC_STATUS_EXEC_STACK,
 
-       BC_STATUS_VEC_OUT_OF_BOUNDS,
+//     BC_STATUS_VEC_OUT_OF_BOUNDS,
        BC_STATUS_VEC_ITEM_EXISTS,
-
 #if ENABLE_BC
        BC_STATUS_POSIX_NAME_LEN,
        BC_STATUS_POSIX_COMMENT,
@@ -227,23 +231,77 @@ typedef enum BcStatus {
        BC_STATUS_POSIX_FOR3,
        BC_STATUS_POSIX_BRACE,
 #endif
-
        BC_STATUS_QUIT,
        BC_STATUS_LIMITS,
 
-       BC_STATUS_INVALID_OPTION,
-
+//     BC_STATUS_INVALID_OPTION,
 } BcStatus;
+// Keep enum above and messages below in sync!
+static const char *const bc_err_msgs[] = {
+       NULL,
+//     "memory allocation error",
+       "I/O error",
+       "file is not text:",
+//     "path is a directory:",
+
+       "bad character",
+       "string end could not be found",
+       "comment end could not be found",
+       "end of file",
+#if ENABLE_DC
+       "extended register",
+#endif
+       "bad token",
+       "bad expression",
+       "empty expression",
+       "bad print statement",
+       "bad function definition",
+       "bad assignment: left side must be scale, ibase, "
+               "obase, last, var, or array element",
+       "no auto variable found",
+       "function parameter or auto var has the same name as another",
+       "block end could not be found",
 
-#define BC_ERR_IDX_VM (0)
-#define BC_ERR_IDX_LEX (1)
-#define BC_ERR_IDX_PARSE (2)
-#define BC_ERR_IDX_MATH (3)
-#define BC_ERR_IDX_EXEC (4)
-#define BC_ERR_IDX_VEC (5)
+       "negative number",
+       "non integer number",
+       "overflow",
+       "divide by zero",
+       "bad number string",
+
+//     "could not open file:",
+       "mismatched parameters", // wrong number of them, to be exact
+       "undefined function",
+       "file is not executable:",
+       "number too long: must be [1, BC_NUM_MAX]",
+       "name too long: must be [1, BC_NAME_MAX]",
+       "string too long: must be [1, BC_STRING_MAX]",
+       "array too long; must be [1, BC_DIM_MAX]",
+       "bad ibase; must be [2, 16]",
+//     "bad scale; must be [0, BC_SCALE_MAX]",
+       "bad read() expression",
+       "read() call inside of a read() call",
+       "variable is wrong type",
+//     "bad obase; must be [2, BC_BASE_MAX]",
+       "signal caught and not handled",
+       "stack has too few elements",
+
+//     "index is out of bounds",
+       "item already exists",
 #if ENABLE_BC
-#define BC_ERR_IDX_POSIX (6)
+       "POSIX only allows one character names; the following is bad:",
+       "POSIX does not allow '#' script comments",
+       "POSIX does not allow the following keyword:",
+       "POSIX does not allow a period ('.') as a shortcut for the last result",
+       "POSIX requires parentheses around return expressions",
+       "POSIX does not allow boolean operators; the following is bad:",
+       "POSIX does not allow comparison operators outside if or loops",
+       "POSIX requires exactly one comparison operator per condition",
+       "POSIX does not allow an empty init expression in a for loop",
+       "POSIX does not allow an empty condition expression in a for loop",
+       "POSIX does not allow an empty update expression in a for loop",
+       "POSIX requires the left brace be on the same line as the function header",
 #endif
+};
 
 #define BC_VEC_INVALID_IDX ((size_t) -1)
 #define BC_VEC_START_CAP (1 << 5)
@@ -299,7 +357,7 @@ static void bc_num_copy(BcNum *d, BcNum *s);
 static void bc_num_free(void *num);
 
 static BcStatus bc_num_ulong(BcNum *n, unsigned long *result);
-static BcStatus bc_num_ulong2num(BcNum *n, unsigned long val);
+static void bc_num_ulong2num(BcNum *n, unsigned long val);
 
 static BcStatus bc_num_add(BcNum *a, BcNum *b, BcNum *c, size_t scale);
 static BcStatus bc_num_sub(BcNum *a, BcNum *b, BcNum *c, size_t scale);
@@ -599,7 +657,7 @@ typedef struct BcLex {
 
 #define bc_parse_push(p, i) (bc_vec_pushByte(&(p)->func->code, (char) (i)))
 #define bc_parse_updateFunc(p, f) \
-       ((p)->func = bc_vec_item(&(p)->prog->fns, ((p)->fidx = (f))))
+       ((p)->func = bc_vec_item(&G.prog.fns, ((p)->fidx = (f))))
 
 #define BC_PARSE_REL (1 << 0)
 #define BC_PARSE_PRINT (1 << 1)
@@ -677,7 +735,6 @@ typedef struct BcParse {
 
        BcVec ops;
 
-       struct BcProgram *prog;
        BcFunc *func;
        size_t fidx;
 
@@ -711,7 +768,6 @@ static BcStatus bc_lex_token(BcLex *l);
 // first in the expr enum. Note: This only works for binary operators.
 #define BC_PARSE_TOKEN_INST(t) ((char) ((t) -BC_LEX_NEG + BC_INST_NEG))
 
-static BcStatus bc_parse_parse(BcParse *p);
 static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next);
 
 #endif // ENABLE_BC
@@ -782,8 +838,8 @@ typedef struct BcProgram {
 
 typedef unsigned long (*BcProgramBuiltIn)(BcNum *);
 
-static void bc_program_addFunc(BcProgram *p, char *name, size_t *idx);
-static BcStatus bc_program_reset(BcProgram *p, BcStatus s);
+static void bc_program_addFunc(char *name, size_t *idx);
+static BcStatus bc_program_reset(BcStatus s);
 
 #define BC_FLAG_X (1 << 0)
 #define BC_FLAG_W (1 << 1)
@@ -796,14 +852,14 @@ static BcStatus bc_program_reset(BcProgram *p, BcStatus s);
 #define BC_MAX(a, b) ((a) > (b) ? (a) : (b))
 #define BC_MIN(a, b) ((a) < (b) ? (a) : (b))
 
-#define BC_MAX_OBASE ((unsigned long) 999)
-#define BC_MAX_DIM ((unsigned long) INT_MAX)
-#define BC_MAX_SCALE ((unsigned long) UINT_MAX)
-#define BC_MAX_STRING ((unsigned long) UINT_MAX - 1)
-#define BC_MAX_NAME BC_MAX_STRING
-#define BC_MAX_NUM BC_MAX_STRING
-#define BC_MAX_EXP ((unsigned long) LONG_MAX)
-#define BC_MAX_VARS ((unsigned long) SIZE_MAX - 1)
+#define BC_MAX_OBASE  ((unsigned) 999)
+#define BC_MAX_DIM    ((unsigned) INT_MAX)
+#define BC_MAX_SCALE  ((unsigned) UINT_MAX)
+#define BC_MAX_STRING ((unsigned) UINT_MAX - 1)
+#define BC_MAX_NAME   BC_MAX_STRING
+#define BC_MAX_NUM    BC_MAX_STRING
+#define BC_MAX_EXP    ((unsigned long) LONG_MAX)
+#define BC_MAX_VARS   ((unsigned long) SIZE_MAX - 1)
 
 struct globals {
        char sbgn;
@@ -839,124 +895,10 @@ static BcStatus bc_vm_posixError(BcStatus s, const char *file, size_t line,
 
 static void bc_vm_info(void);
 
-static const char* const bc_args_env_name = "BC_ENV_ARGS";
-
-static const char bc_err_fmt[] = "\n%s error: %s\n";
-static const char bc_warn_fmt[] = "\n%s warning: %s\n";
+static const char bc_err_fmt[] = "\nerror: %s\n";
+static const char bc_warn_fmt[] = "\nwarning: %s\n";
 static const char bc_err_line[] = ":%zu\n\n";
 
-static const char *bc_errs[] = {
-       "VM",
-       "Lex",
-       "Parse",
-       "Math",
-       "Runtime",
-       "Vector",
-#if ENABLE_BC
-       "POSIX",
-#endif
-};
-
-static const uint8_t bc_err_ids[] = {
-       BC_ERR_IDX_VM, BC_ERR_IDX_VM, BC_ERR_IDX_VM, BC_ERR_IDX_VM, BC_ERR_IDX_VM,
-       BC_ERR_IDX_LEX, BC_ERR_IDX_LEX, BC_ERR_IDX_LEX, BC_ERR_IDX_LEX,
-#if ENABLE_DC
-       BC_ERR_IDX_LEX,
-#endif
-       BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE,
-       BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE, BC_ERR_IDX_PARSE,
-       BC_ERR_IDX_MATH, BC_ERR_IDX_MATH, BC_ERR_IDX_MATH, BC_ERR_IDX_MATH,
-       BC_ERR_IDX_MATH,
-#if ENABLE_DC
-       BC_ERR_IDX_MATH,
-#endif
-       BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC,
-       BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC,
-       BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC,
-       BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC, BC_ERR_IDX_EXEC,
-       BC_ERR_IDX_EXEC,
-       BC_ERR_IDX_VEC, BC_ERR_IDX_VEC,
-#if ENABLE_BC
-       BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX,
-       BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX,
-       BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX, BC_ERR_IDX_POSIX,
-#endif
-       BC_ERR_IDX_VM, BC_ERR_IDX_VM, BC_ERR_IDX_VM,
-};
-
-static const char *bc_err_msgs[] = {
-
-       NULL,
-       "memory allocation error",
-       "I/O error",
-       "file is not text:",
-       "path is a directory:",
-
-       "bad character",
-       "string end could not be found",
-       "comment end could not be found",
-       "end of file",
-#if ENABLE_DC
-       "extended register",
-#endif
-
-       "bad token",
-       "bad expression",
-       "empty expression",
-       "bad print statement",
-       "bad function definition",
-       "bad assignment: left side must be scale, ibase, "
-               "obase, last, var, or array element",
-       "no auto variable found",
-       "function parameter or auto var has the same name as another",
-       "block end could not be found",
-
-       "negative number",
-       "non integer number",
-       "overflow",
-       "divide by zero",
-       "bad number string",
-
-       "could not open file:",
-       "mismatched parameters",
-       "undefined function",
-       "file is not executable:",
-       "number too long: must be [1, BC_NUM_MAX]",
-       "name too long: must be [1, BC_NAME_MAX]",
-       "string too long: must be [1, BC_STRING_MAX]",
-       "array too long; must be [1, BC_DIM_MAX]",
-       "bad ibase; must be [2, 16]",
-       "bad scale; must be [0, BC_SCALE_MAX]",
-       "bad read() expression",
-       "read() call inside of a read() call",
-       "variable is wrong type",
-       "bad obase; must be [2, BC_BASE_MAX]",
-       "signal caught and not handled",
-       "stack has too few elements",
-
-       "index is out of bounds",
-       "item already exists",
-
-#if ENABLE_BC
-       "POSIX only allows one character names; the following is bad:",
-       "POSIX does not allow '#' script comments",
-       "POSIX does not allow the following keyword:",
-       "POSIX does not allow a period ('.') as a shortcut for the last result",
-       "POSIX requires parentheses around return expressions",
-       "POSIX does not allow boolean operators; the following is bad:",
-       "POSIX does not allow comparison operators outside if or loops",
-       "POSIX requires exactly one comparison operator per condition",
-       "POSIX does not allow an empty init expression in a for loop",
-       "POSIX does not allow an empty condition expression in a for loop",
-       "POSIX does not allow an empty update expression in a for loop",
-       "POSIX requires the left brace be on the same line as the function header",
-#endif
-
-};
-
-static const char bc_func_main[] = "(main)";
-static const char bc_func_read[] = "(read)";
-
 #if ENABLE_BC
 static const BcLexKeyword bc_lex_kws[20] = {
        BC_LEX_KW_ENTRY("auto", 4, true),
@@ -1339,12 +1281,12 @@ static BcStatus bc_read_line(BcVec *vec, const char *prompt)
 #if ENABLE_FEATURE_BC_SIGNALS
        if (bb_got_signal) { /* ^C was pressed */
  intr:
+               bb_got_signal = 0; /* resets G_interrupt to zero */
                fputs(IS_BC
                        ? "\ninterrupt (type \"quit\" to exit)\n"
                        : "\ninterrupt (type \"q\" to exit)\n"
                        , stderr);
        }
-       bb_got_signal = 0; /* resets G_interrupt to zero */
 #endif
        if (G.ttyin && !G_posix)
                fputs(prompt, stderr);
@@ -1387,24 +1329,23 @@ static BcStatus bc_read_line(BcVec *vec, const char *prompt)
        return BC_STATUS_SUCCESS;
 }
 
-static BcStatus bc_read_file(const char *path, char **buf)
+static char* bc_read_file(const char *path)
 {
-       BcStatus s = BC_STATUS_BIN_FILE;
+       char *buf;
        size_t size = ((size_t) -1);
        size_t i;
 
-       *buf = xmalloc_open_read_close(path, &size);
+       buf = xmalloc_open_read_close(path, &size);
 
        for (i = 0; i < size; ++i) {
-               if (BC_READ_BIN_CHAR((*buf)[i]))
-                       goto read_err;
+               if (BC_READ_BIN_CHAR(buf[i])) {
+                       free(buf);
+                       buf = NULL;
+                       break;
+               }
        }
 
-       return BC_STATUS_SUCCESS;
-
-read_err:
-       free(*buf);
-       return s;
+       return buf;
 }
 
 static void bc_args(int argc, char **argv)
@@ -1460,24 +1401,23 @@ static void bc_num_ten(BcNum *n)
        n->num[1] = 1;
 }
 
-static BcStatus bc_num_subArrays(BcDig *restrict a, BcDig *restrict b,
+static void bc_num_subArrays(BcDig *restrict a, BcDig *restrict b,
                                  size_t len)
 {
        size_t i, j;
-       for (i = 0; !G_interrupt && i < len; ++i) {
-               for (a[i] -= b[i], j = 0; !G_interrupt && a[i + j] < 0;) {
+       for (i = 0; i < len; ++i) {
+               for (a[i] -= b[i], j = 0; a[i + j] < 0;) {
                        a[i + j++] += 10;
                        a[i + j] -= 1;
                }
        }
-       return G_interrupt ? BC_STATUS_EXEC_SIGNAL : BC_STATUS_SUCCESS;
 }
 
 static ssize_t bc_num_compare(BcDig *restrict a, BcDig *restrict b, size_t len)
 {
        size_t i;
        int c = 0;
-       for (i = len - 1; !G_interrupt && i < len && !(c = a[i] - b[i]); --i);
+       for (i = len - 1; i < len && !(c = a[i] - b[i]); --i);
        return BC_NUM_NEG(i + 1, c < 0);
 }
 
@@ -1523,7 +1463,7 @@ static ssize_t bc_num_cmp(BcNum *a, BcNum *b)
        cmp = bc_num_compare(max_num, min_num, b_int + min);
        if (cmp != 0) return BC_NUM_NEG(cmp, (!a_max) != neg);
 
-       for (max_num -= diff, i = diff - 1; !G_interrupt && i < diff; --i) {
+       for (max_num -= diff, i = diff - 1; i < diff; --i) {
                if (max_num[i]) return BC_NUM_NEG(1, (!a_max) != neg);
        }
 
@@ -1682,13 +1622,13 @@ static BcStatus bc_num_a(BcNum *a, BcNum *b, BcNum *restrict c, size_t sub)
                ptr = ptr_b;
        }
 
-       for (carry = 0, i = 0; !G_interrupt && i < min_rdx + min_int; ++i, ++c->len) {
+       for (carry = 0, i = 0; i < min_rdx + min_int; ++i, ++c->len) {
                in = ((int) ptr_a[i]) + ((int) ptr_b[i]) + carry;
                carry = in / 10;
                ptr_c[i] = (BcDig)(in % 10);
        }
 
-       for (; !G_interrupt && i < max + min_rdx; ++i, ++c->len) {
+       for (; i < max + min_rdx; ++i, ++c->len) {
                in = ((int) ptr[i]) + carry;
                carry = in / 10;
                ptr_c[i] = (BcDig)(in % 10);
@@ -1696,12 +1636,11 @@ static BcStatus bc_num_a(BcNum *a, BcNum *b, BcNum *restrict c, size_t sub)
 
        if (carry != 0) c->num[c->len++] = (BcDig) carry;
 
-       return G_interrupt ? BC_STATUS_EXEC_SIGNAL : BC_STATUS_SUCCESS;
+       return BC_STATUS_SUCCESS; // can't make void, see bc_num_binary()
 }
 
 static BcStatus bc_num_s(BcNum *a, BcNum *b, BcNum *restrict c, size_t sub)
 {
-       BcStatus s;
        ssize_t cmp;
        BcNum *minuend, *subtrahend;
        size_t start;
@@ -1755,11 +1694,11 @@ static BcStatus bc_num_s(BcNum *a, BcNum *b, BcNum *restrict c, size_t sub)
        else
                start = c->rdx - subtrahend->rdx;
 
-       s = bc_num_subArrays(c->num + start, subtrahend->num, subtrahend->len);
+       bc_num_subArrays(c->num + start, subtrahend->num, subtrahend->len);
 
        bc_num_clean(c);
 
-       return s;
+       return BC_STATUS_SUCCESS; // can't make void, see bc_num_binary()
 }
 
 static BcStatus bc_num_k(BcNum *restrict a, BcNum *restrict b,
@@ -1771,7 +1710,6 @@ static BcStatus bc_num_k(BcNum *restrict a, BcNum *restrict b,
        BcNum l1, h1, l2, h2, m2, m1, z0, z1, z2, temp;
        bool aone = BC_NUM_ONE(a);
 
-       if (G_interrupt) return BC_STATUS_EXEC_SIGNAL;
        if (a->len == 0 || b->len == 0) {
                bc_num_zero(c);
                return BC_STATUS_SUCCESS;
@@ -1789,9 +1727,9 @@ static BcStatus bc_num_k(BcNum *restrict a, BcNum *restrict b,
                memset(c->num, 0, sizeof(BcDig) * c->cap);
                c->len = carry = len = 0;
 
-               for (i = 0; !G_interrupt && i < b->len; ++i) {
+               for (i = 0; i < b->len; ++i) {
 
-                       for (j = 0; !G_interrupt && j < a->len; ++j) {
+                       for (j = 0; j < a->len; ++j) {
                                int in = (int) c->num[i + j];
                                in += ((int) a->num[j]) * ((int) b->num[i]) + carry;
                                carry = in / 10;
@@ -1805,7 +1743,7 @@ static BcStatus bc_num_k(BcNum *restrict a, BcNum *restrict b,
 
                c->len = len;
 
-               return G_interrupt ? BC_STATUS_EXEC_SIGNAL : BC_STATUS_SUCCESS;
+               return BC_STATUS_SUCCESS;
        }
 
        bc_num_init(&l1, max);
@@ -1955,17 +1893,17 @@ static BcStatus bc_num_d(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale)
        c->len = cp.len;
        p = b->num;
 
-       for (i = end - 1; !G_interrupt && !s && i < end; --i) {
+       for (i = end - 1; !s && i < end; --i) {
                n = cp.num + i;
                for (q = 0; (!s && n[len] != 0) || bc_num_compare(n, p, len) >= 0; ++q)
-                       s = bc_num_subArrays(n, p, len);
+                       bc_num_subArrays(n, p, len);
                c->num[i] = q;
        }
 
-       if (!s) bc_num_retireMul(c, scale, a->neg, b->neg);
+       bc_num_retireMul(c, scale, a->neg, b->neg);
        bc_num_free(&cp);
 
-       return s;
+       return BC_STATUS_SUCCESS; // can't make void, see bc_num_binary()
 }
 
 static BcStatus bc_num_r(BcNum *a, BcNum *b, BcNum *restrict c,
@@ -2055,20 +1993,15 @@ static BcStatus bc_num_p(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale)
 
        b->neg = neg;
 
-       for (powrdx = a->rdx; !G_interrupt && !(pow & 1); pow >>= 1) {
+       for (powrdx = a->rdx; !(pow & 1); pow >>= 1) {
                powrdx <<= 1;
                s = bc_num_mul(&copy, &copy, &copy, powrdx);
                if (s) goto err;
        }
 
-       if (G_interrupt) {
-               s = BC_STATUS_EXEC_SIGNAL;
-               goto err;
-       }
-
        bc_num_copy(c, &copy);
 
-       for (resrdx = powrdx, pow >>= 1; !G_interrupt && pow != 0; pow >>= 1) {
+       for (resrdx = powrdx, pow >>= 1; pow != 0; pow >>= 1) {
 
                powrdx <<= 1;
                s = bc_num_mul(&copy, &copy, &copy, powrdx);
@@ -2086,11 +2019,6 @@ static BcStatus bc_num_p(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale)
                if (s) goto err;
        }
 
-       if (G_interrupt) {
-               s = BC_STATUS_EXEC_SIGNAL;
-               goto err;
-       }
-
        if (c->rdx > scale) bc_num_truncate(c, c->rdx - scale);
 
        // We can't use bc_num_clean() here.
@@ -2223,8 +2151,7 @@ static void bc_num_parseBase(BcNum *n, const char *val, BcNum *base)
 
                s = bc_num_mul(n, base, &mult, 0);
                if (s) goto int_err;
-               s = bc_num_ulong2num(&temp, v);
-               if (s) goto int_err;
+               bc_num_ulong2num(&temp, v);
                s = bc_num_add(&mult, &temp, n, 0);
                if (s) goto int_err;
        }
@@ -2247,8 +2174,7 @@ static void bc_num_parseBase(BcNum *n, const char *val, BcNum *base)
 
                s = bc_num_mul(&result, base, &result, 0);
                if (s) goto err;
-               s = bc_num_ulong2num(&temp, v);
-               if (s) goto err;
+               bc_num_ulong2num(&temp, v);
                s = bc_num_add(&result, &temp, &result, 0);
                if (s) goto err;
                s = bc_num_mul(&mult, base, &mult, 0);
@@ -2386,8 +2312,7 @@ static BcStatus bc_num_printNum(BcNum *n, BcNum *base, size_t width,
                if (s) goto err;
                s = bc_num_ulong(&fracp, &dig);
                if (s) goto err;
-               s = bc_num_ulong2num(&intp, dig);
-               if (s) goto err;
+               bc_num_ulong2num(&intp, dig);
                s = bc_num_sub(&fracp, &intp, &fracp, 0);
                if (s) goto err;
                print(dig, width, radix, nchars, len);
@@ -2529,7 +2454,7 @@ static BcStatus bc_num_ulong(BcNum *n, unsigned long *result)
        return BC_STATUS_SUCCESS;
 }
 
-static BcStatus bc_num_ulong2num(BcNum *n, unsigned long val)
+static void bc_num_ulong2num(BcNum *n, unsigned long val)
 {
        size_t len;
        BcDig *ptr;
@@ -2537,12 +2462,10 @@ static BcStatus bc_num_ulong2num(BcNum *n, unsigned long val)
 
        bc_num_zero(n);
 
-       if (val == 0) return BC_STATUS_SUCCESS;
+       if (val == 0) return;
 
        for (len = 1, i = ULONG_MAX; i != 0; i /= 10, ++len) bc_num_expand(n, len);
        for (ptr = n->num, i = 0; val; ++i, ++n->len, val /= 10) ptr[i] = val % 10;
-
-       return BC_STATUS_SUCCESS;
 }
 
 static BcStatus bc_num_add(BcNum *a, BcNum *b, BcNum *c, size_t scale)
@@ -2643,7 +2566,7 @@ static BcStatus bc_num_sqrt(BcNum *a, BcNum *restrict b, size_t scale)
        resrdx = scale + 2;
        len = BC_NUM_INT(x0) + resrdx - 1;
 
-       while (!G_interrupt && (cmp != 0 || digs < len)) {
+       while (cmp != 0 || digs < len) {
 
                s = bc_num_div(a, x0, &f, resrdx);
                if (s) goto err;
@@ -2671,11 +2594,6 @@ static BcStatus bc_num_sqrt(BcNum *a, BcNum *restrict b, size_t scale)
                x1 = temp;
        }
 
-       if (G_interrupt) {
-               s = BC_STATUS_EXEC_SIGNAL;
-               goto err;
-       }
-
        bc_num_copy(b, x0);
        scale -= 1;
        if (b->rdx > scale) bc_num_truncate(b, b->rdx - scale);
@@ -3603,8 +3521,8 @@ static BcStatus dc_lex_token(BcLex *l)
 
 static void bc_parse_addFunc(BcParse *p, char *name, size_t *idx)
 {
-       bc_program_addFunc(p->prog, name, idx);
-       p->func = bc_vec_item(&p->prog->fns, p->fidx);
+       bc_program_addFunc(name, idx);
+       p->func = bc_vec_item(&G.prog.fns, p->fidx);
 }
 
 static void bc_parse_pushName(BcParse *p, char *name)
@@ -3633,9 +3551,9 @@ static void bc_parse_pushIndex(BcParse *p, size_t idx)
 static void bc_parse_number(BcParse *p, BcInst *prev, size_t *nexs)
 {
        char *num = xstrdup(p->l.t.v.v);
-       size_t idx = p->prog->consts.len;
+       size_t idx = G.prog.consts.len;
 
-       bc_vec_push(&p->prog->consts, &num);
+       bc_vec_push(&G.prog.consts, &num);
 
        bc_parse_push(p, BC_INST_NUM);
        bc_parse_pushIndex(p, idx);
@@ -3648,7 +3566,7 @@ static BcStatus bc_parse_text(BcParse *p, const char *text)
 {
        BcStatus s;
 
-       p->func = bc_vec_item(&p->prog->fns, p->fidx);
+       p->func = bc_vec_item(&G.prog.fns, p->fidx);
 
        if (!strcmp(text, "") && !BC_PARSE_CAN_EXEC(p)) {
                p->l.t.t = BC_LEX_INVALID;
@@ -3681,7 +3599,7 @@ static BcStatus bc_parse_reset(BcParse *p, BcStatus s)
        bc_vec_npop(&p->conds, p->conds.len);
        bc_vec_npop(&p->ops, p->ops.len);
 
-       return bc_program_reset(p->prog, s);
+       return bc_program_reset(s);
 }
 
 static void bc_parse_free(BcParse *p)
@@ -3693,7 +3611,7 @@ static void bc_parse_free(BcParse *p)
        bc_lex_free(&p->l);
 }
 
-static void bc_parse_create(BcParse *p, BcProgram *prog, size_t func,
+static void bc_parse_create(BcParse *p, size_t func,
                             BcParseParse parse, BcLexNext next)
 {
        memset(p, 0, sizeof(BcParse));
@@ -3706,7 +3624,6 @@ static void bc_parse_create(BcParse *p, BcProgram *prog, size_t func,
        bc_vec_init(&p->ops, sizeof(BcLexType), NULL);
 
        p->parse = parse;
-       p->prog = prog;
        p->auto_part = (p->nbraces = 0);
        bc_parse_updateFunc(p, func);
 }
@@ -3810,18 +3727,18 @@ static BcStatus bc_parse_call(BcParse *p, char *name, uint8_t flags)
                goto err;
        }
 
-       idx = bc_map_index(&p->prog->fn_map, &entry);
+       idx = bc_map_index(&G.prog.fn_map, &entry);
 
        if (idx == BC_VEC_INVALID_IDX) {
                name = xstrdup(entry.name);
                bc_parse_addFunc(p, name, &idx);
-               idx = bc_map_index(&p->prog->fn_map, &entry);
+               idx = bc_map_index(&G.prog.fn_map, &entry);
                free(entry.name);
        }
        else
                free(name);
 
-       entry_ptr = bc_vec_item(&p->prog->fn_map, idx);
+       entry_ptr = bc_vec_item(&G.prog.fn_map, idx);
        bc_parse_pushIndex(p, entry_ptr->idx);
 
        return bc_lex_next(&p->l);
@@ -4061,8 +3978,8 @@ static BcStatus bc_parse_string(BcParse *p, char inst)
        char *str = xstrdup(p->l.t.v.v);
 
        bc_parse_push(p, BC_INST_STR);
-       bc_parse_pushIndex(p, p->prog->strs.len);
-       bc_vec_push(&p->prog->strs, &str);
+       bc_parse_pushIndex(p, G.prog.strs.len);
+       bc_vec_push(&G.prog.strs, &str);
        bc_parse_push(p, inst);
 
        return bc_lex_next(&p->l);
@@ -5021,9 +4938,9 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next)
        return s;
 }
 
-static void bc_parse_init(BcParse *p, BcProgram *prog, size_t func)
+static void bc_parse_init(BcParse *p, size_t func)
 {
-       bc_parse_create(p, prog, func, bc_parse_parse, bc_lex_token);
+       bc_parse_create(p, func, bc_parse_parse, bc_lex_token);
 }
 
 static BcStatus bc_parse_expression(BcParse *p, uint8_t flags)
@@ -5051,7 +4968,7 @@ static BcStatus dc_parse_register(BcParse *p)
 static BcStatus dc_parse_string(BcParse *p)
 {
        char *str, *name, b[DC_PARSE_BUF_LEN + 1];
-       size_t idx, len = p->prog->strs.len;
+       size_t idx, len = G.prog.strs.len;
 
        sprintf(b, "%0*zu", DC_PARSE_BUF_LEN, len);
        name = xstrdup(b);
@@ -5059,7 +4976,7 @@ static BcStatus dc_parse_string(BcParse *p)
        str = xstrdup(p->l.t.v.v);
        bc_parse_push(p, BC_INST_STR);
        bc_parse_pushIndex(p, len);
-       bc_vec_push(&p->prog->strs, &str);
+       bc_vec_push(&G.prog.strs, &str);
        bc_parse_addFunc(p, name, &idx);
 
        return bc_lex_next(&p->l);
@@ -5213,7 +5130,7 @@ static BcStatus dc_parse_expr(BcParse *p, uint8_t flags)
        BcInst inst;
        BcLexType t;
 
-       if (flags & BC_PARSE_NOCALL) p->nbraces = p->prog->results.len;
+       if (flags & BC_PARSE_NOCALL) p->nbraces = G.prog.results.len;
 
        for (t = p->l.t.t; !s && t != BC_LEX_EOF; t = p->l.t.t) {
 
@@ -5247,18 +5164,18 @@ static BcStatus dc_parse_parse(BcParse *p)
        return s;
 }
 
-static void dc_parse_init(BcParse *p, BcProgram *prog, size_t func)
+static void dc_parse_init(BcParse *p, size_t func)
 {
-       bc_parse_create(p, prog, func, dc_parse_parse, dc_lex_token);
+       bc_parse_create(p, func, dc_parse_parse, dc_lex_token);
 }
 #endif // ENABLE_DC
 
-static void common_parse_init(BcParse *p, BcProgram *prog, size_t func)
+static void common_parse_init(BcParse *p, size_t func)
 {
        if (IS_BC) {
-               bc_parse_init(p, prog, func);
+               bc_parse_init(p, func);
        } else {
-               dc_parse_init(p, prog, func);
+               dc_parse_init(p, func);
        }
 }
 
@@ -5271,7 +5188,7 @@ static BcStatus common_parse_expr(BcParse *p, uint8_t flags)
        }
 }
 
-static void bc_program_search(BcProgram *p, char *id, BcVec **ret, bool var)
+static BcVec* bc_program_search(char *id, bool var)
 {
        BcStatus s;
        BcId e, *ptr;
@@ -5280,8 +5197,8 @@ static void bc_program_search(BcProgram *p, char *id, BcVec **ret, bool var)
        BcResultData data;
        bool new;
 
-       v = var ? &p->vars : &p->arrs;
-       map = var ? &p->var_map : &p->arr_map;
+       v = var ? &G.prog.vars : &G.prog.arrs;
+       map = var ? &G.prog.var_map : &G.prog.arr_map;
 
        e.name = id;
        e.idx = v->len;
@@ -5295,10 +5212,10 @@ static void bc_program_search(BcProgram *p, char *id, BcVec **ret, bool var)
 
        ptr = bc_vec_item(map, i);
        if (new) ptr->name = xstrdup(e.name);
-       *ret = bc_vec_item(v, ptr->idx);
+       return bc_vec_item(v, ptr->idx);
 }
 
-static BcStatus bc_program_num(BcProgram *p, BcResult *r, BcNum **num, bool hex)
+static BcStatus bc_program_num(BcResult *r, BcNum **num, bool hex)
 {
        BcStatus s = BC_STATUS_SUCCESS;
 
@@ -5316,15 +5233,15 @@ static BcStatus bc_program_num(BcProgram *p, BcResult *r, BcNum **num, bool hex)
 
                case BC_RESULT_CONSTANT:
                {
-                       char **str = bc_vec_item(&p->consts, r->d.id.idx);
+                       char **str = bc_vec_item(&G.prog.consts, r->d.id.idx);
                        size_t base_t, len = strlen(*str);
                        BcNum *base;
 
                        bc_num_init(&r->d.n, len);
 
                        hex = hex && len == 1;
-                       base = hex ? &p->hexb : &p->ib;
-                       base_t = hex ? BC_NUM_MAX_IBASE : p->ib_t;
+                       base = hex ? &G.prog.hexb : &G.prog.ib;
+                       base_t = hex ? BC_NUM_MAX_IBASE : G.prog.ib_t;
                        s = bc_num_parse(&r->d.n, *str, base, base_t);
 
                        if (s) {
@@ -5344,7 +5261,7 @@ static BcStatus bc_program_num(BcProgram *p, BcResult *r, BcNum **num, bool hex)
                {
                        BcVec *v;
 
-                       bc_program_search(p, r->d.id.name, &v, r->t == BC_RESULT_VAR);
+                       v = bc_program_search(r->d.id.name, r->t == BC_RESULT_VAR);
 
                        if (r->t == BC_RESULT_ARRAY_ELEM) {
                                v = bc_vec_top(v);
@@ -5359,13 +5276,13 @@ static BcStatus bc_program_num(BcProgram *p, BcResult *r, BcNum **num, bool hex)
 
                case BC_RESULT_LAST:
                {
-                       *num = &p->last;
+                       *num = &G.prog.last;
                        break;
                }
 
                case BC_RESULT_ONE:
                {
-                       *num = &p->one;
+                       *num = &G.prog.one;
                        break;
                }
        }
@@ -5373,31 +5290,31 @@ static BcStatus bc_program_num(BcProgram *p, BcResult *r, BcNum **num, bool hex)
        return s;
 }
 
-static BcStatus bc_program_binOpPrep(BcProgram *p, BcResult **l, BcNum **ln,
+static BcStatus bc_program_binOpPrep(BcResult **l, BcNum **ln,
                                      BcResult **r, BcNum **rn, bool assign)
 {
        BcStatus s;
        bool hex;
        BcResultType lt, rt;
 
-       if (!BC_PROG_STACK(&p->results, 2)) return BC_STATUS_EXEC_STACK;
+       if (!BC_PROG_STACK(&G.prog.results, 2)) return BC_STATUS_EXEC_STACK;
 
-       *r = bc_vec_item_rev(&p->results, 0);
-       *l = bc_vec_item_rev(&p->results, 1);
+       *r = bc_vec_item_rev(&G.prog.results, 0);
+       *l = bc_vec_item_rev(&G.prog.results, 1);
 
        lt = (*l)->t;
        rt = (*r)->t;
        hex = assign && (lt == BC_RESULT_IBASE || lt == BC_RESULT_OBASE);
 
-       s = bc_program_num(p, *l, ln, false);
+       s = bc_program_num(*l, ln, false);
        if (s) return s;
-       s = bc_program_num(p, *r, rn, hex);
+       s = bc_program_num(*r, rn, hex);
        if (s) return s;
 
        // We run this again under these conditions in case any vector has been
        // reallocated out from under the BcNums or arrays we had.
        if (lt == rt && (lt == BC_RESULT_VAR || lt == BC_RESULT_ARRAY_ELEM)) {
-               s = bc_program_num(p, *l, ln, false);
+               s = bc_program_num(*l, ln, false);
                if (s) return s;
        }
 
@@ -5408,22 +5325,22 @@ static BcStatus bc_program_binOpPrep(BcProgram *p, BcResult **l, BcNum **ln,
        return s;
 }
 
-static void bc_program_binOpRetire(BcProgram *p, BcResult *r)
+static void bc_program_binOpRetire(BcResult *r)
 {
        r->t = BC_RESULT_TEMP;
-       bc_vec_pop(&p->results);
-       bc_vec_pop(&p->results);
-       bc_vec_push(&p->results, r);
+       bc_vec_pop(&G.prog.results);
+       bc_vec_pop(&G.prog.results);
+       bc_vec_push(&G.prog.results, r);
 }
 
-static BcStatus bc_program_prep(BcProgram *p, BcResult **r, BcNum **n)
+static BcStatus bc_program_prep(BcResult **r, BcNum **n)
 {
        BcStatus s;
 
-       if (!BC_PROG_STACK(&p->results, 1)) return BC_STATUS_EXEC_STACK;
-       *r = bc_vec_top(&p->results);
+       if (!BC_PROG_STACK(&G.prog.results, 1)) return BC_STATUS_EXEC_STACK;
+       *r = bc_vec_top(&G.prog.results);
 
-       s = bc_program_num(p, *r, n, false);
+       s = bc_program_num(*r, n, false);
        if (s) return s;
 
        if (!BC_PROG_NUM((*r), (*n))) return BC_STATUS_EXEC_BAD_TYPE;
@@ -5431,26 +5348,26 @@ static BcStatus bc_program_prep(BcProgram *p, BcResult **r, BcNum **n)
        return s;
 }
 
-static void bc_program_retire(BcProgram *p, BcResult *r, BcResultType t)
+static void bc_program_retire(BcResult *r, BcResultType t)
 {
        r->t = t;
-       bc_vec_pop(&p->results);
-       bc_vec_push(&p->results, r);
+       bc_vec_pop(&G.prog.results);
+       bc_vec_push(&G.prog.results, r);
 }
 
-static BcStatus bc_program_op(BcProgram *p, char inst)
+static BcStatus bc_program_op(char inst)
 {
        BcStatus s;
        BcResult *opd1, *opd2, res;
        BcNum *n1, *n2 = NULL;
 
-       s = bc_program_binOpPrep(p, &opd1, &n1, &opd2, &n2, false);
+       s = bc_program_binOpPrep(&opd1, &n1, &opd2, &n2, false);
        if (s) return s;
        bc_num_init(&res.d.n, BC_NUM_DEF_SIZE);
 
-       s = bc_program_ops[inst - BC_INST_POWER](n1, n2, &res.d.n, p->scale);
+       s = bc_program_ops[inst - BC_INST_POWER](n1, n2, &res.d.n, G.prog.scale);
        if (s) goto err;
-       bc_program_binOpRetire(p, &res);
+       bc_program_binOpRetire(&res);
 
        return s;
 
@@ -5461,17 +5378,15 @@ err:
 
 static BcStatus bc_program_read(void)
 {
-       BcProgram *p = &G.prog;
-
        BcStatus s;
        BcParse parse;
        BcVec buf;
        BcInstPtr ip;
        size_t i;
-       BcFunc *f = bc_vec_item(&p->fns, BC_PROG_READ);
+       BcFunc *f = bc_vec_item(&G.prog.fns, BC_PROG_READ);
 
-       for (i = 0; i < p->stack.len; ++i) {
-               BcInstPtr *ip_ptr = bc_vec_item(&p->stack, i);
+       for (i = 0; i < G.prog.stack.len; ++i) {
+               BcInstPtr *ip_ptr = bc_vec_item(&G.prog.stack, i);
                if (ip_ptr->func == BC_PROG_READ) return BC_STATUS_EXEC_REC_READ;
        }
 
@@ -5481,7 +5396,7 @@ static BcStatus bc_program_read(void)
        s = bc_read_line(&buf, "read> ");
        if (s) goto io_err;
 
-       common_parse_init(&parse, p, BC_PROG_READ);
+       common_parse_init(&parse, BC_PROG_READ);
        bc_lex_file(&parse.l, bc_program_stdin_name);
 
        s = bc_parse_text(&parse, buf.v);
@@ -5496,13 +5411,13 @@ static BcStatus bc_program_read(void)
 
        ip.func = BC_PROG_READ;
        ip.idx = 0;
-       ip.len = p->results.len;
+       ip.len = G.prog.results.len;
 
        // Update this pointer, just in case.
-       f = bc_vec_item(&p->fns, BC_PROG_READ);
+       f = bc_vec_item(&G.prog.fns, BC_PROG_READ);
 
        bc_vec_pushByte(&f->code, BC_INST_POP_EXEC);
-       bc_vec_push(&p->stack, &ip);
+       bc_vec_push(&G.prog.stack, &ip);
 
 exec_err:
        bc_parse_free(&parse);
@@ -5624,7 +5539,7 @@ static void bc_program_printString(const char *str, size_t *nchars)
        }
 }
 
-static BcStatus bc_program_print(BcProgram *p, char inst, size_t idx)
+static BcStatus bc_program_print(char inst, size_t idx)
 {
        BcStatus s = BC_STATUS_SUCCESS;
        BcResult *r;
@@ -5633,59 +5548,59 @@ static BcStatus bc_program_print(BcProgram *p, char inst, size_t idx)
        BcNum *num = NULL;
        bool pop = inst != BC_INST_PRINT;
 
-       if (!BC_PROG_STACK(&p->results, idx + 1)) return BC_STATUS_EXEC_STACK;
+       if (!BC_PROG_STACK(&G.prog.results, idx + 1)) return BC_STATUS_EXEC_STACK;
 
-       r = bc_vec_item_rev(&p->results, idx);
-       s = bc_program_num(p, r, &num, false);
+       r = bc_vec_item_rev(&G.prog.results, idx);
+       s = bc_program_num(r, &num, false);
        if (s) return s;
 
        if (BC_PROG_NUM(r, num)) {
-               s = bc_num_print(num, &p->ob, p->ob_t, !pop, &p->nchars, p->len);
-               if (!s) bc_num_copy(&p->last, num);
+               s = bc_num_print(num, &G.prog.ob, G.prog.ob_t, !pop, &G.prog.nchars, G.prog.len);
+               if (!s) bc_num_copy(&G.prog.last, num);
        }
        else {
 
                idx = (r->t == BC_RESULT_STR) ? r->d.id.idx : num->rdx;
-               str = *((char **) bc_vec_item(&p->strs, idx));
+               str = *((char **) bc_vec_item(&G.prog.strs, idx));
 
                if (inst == BC_INST_PRINT_STR) {
                        for (i = 0, len = strlen(str); i < len; ++i) {
                                char c = str[i];
                                bb_putchar(c);
-                               if (c == '\n') p->nchars = SIZE_MAX;
-                               ++p->nchars;
+                               if (c == '\n') G.prog.nchars = SIZE_MAX;
+                               ++G.prog.nchars;
                        }
                }
                else {
-                       bc_program_printString(str, &p->nchars);
+                       bc_program_printString(str, &G.prog.nchars);
                        if (inst == BC_INST_PRINT) bb_putchar('\n');
                }
        }
 
-       if (!s && pop) bc_vec_pop(&p->results);
+       if (!s && pop) bc_vec_pop(&G.prog.results);
 
        return s;
 }
 
-static BcStatus bc_program_negate(BcProgram *p)
+static BcStatus bc_program_negate(void)
 {
        BcStatus s;
        BcResult res, *ptr;
        BcNum *num = NULL;
 
-       s = bc_program_prep(p, &ptr, &num);
+       s = bc_program_prep(&ptr, &num);
        if (s) return s;
 
        bc_num_init(&res.d.n, num->len);
        bc_num_copy(&res.d.n, num);
        if (res.d.n.len) res.d.n.neg = !res.d.n.neg;
 
-       bc_program_retire(p, &res, BC_RESULT_TEMP);
+       bc_program_retire(&res, BC_RESULT_TEMP);
 
        return s;
 }
 
-static BcStatus bc_program_logical(BcProgram *p, char inst)
+static BcStatus bc_program_logical(char inst)
 {
        BcStatus s;
        BcResult *opd1, *opd2, res;
@@ -5693,14 +5608,14 @@ static BcStatus bc_program_logical(BcProgram *p, char inst)
        bool cond = 0;
        ssize_t cmp;
 
-       s = bc_program_binOpPrep(p, &opd1, &n1, &opd2, &n2, false);
+       s = bc_program_binOpPrep(&opd1, &n1, &opd2, &n2, false);
        if (s) return s;
        bc_num_init(&res.d.n, BC_NUM_DEF_SIZE);
 
        if (inst == BC_INST_BOOL_AND)
-               cond = bc_num_cmp(n1, &p->zero) && bc_num_cmp(n2, &p->zero);
+               cond = bc_num_cmp(n1, &G.prog.zero) && bc_num_cmp(n2, &G.prog.zero);
        else if (inst == BC_INST_BOOL_OR)
-               cond = bc_num_cmp(n1, &p->zero) || bc_num_cmp(n2, &p->zero);
+               cond = bc_num_cmp(n1, &G.prog.zero) || bc_num_cmp(n2, &G.prog.zero);
        else {
 
                cmp = bc_num_cmp(n1, n2);
@@ -5747,13 +5662,13 @@ static BcStatus bc_program_logical(BcProgram *p, char inst)
 
        (cond ? bc_num_one : bc_num_zero)(&res.d.n);
 
-       bc_program_binOpRetire(p, &res);
+       bc_program_binOpRetire(&res);
 
        return s;
 }
 
 #if ENABLE_DC
-static BcStatus bc_program_assignStr(BcProgram *p, BcResult *r, BcVec *v,
+static BcStatus bc_program_assignStr(BcResult *r, BcVec *v,
                                      bool push)
 {
        BcNum n2;
@@ -5764,43 +5679,43 @@ static BcStatus bc_program_assignStr(BcProgram *p, BcResult *r, BcVec *v,
        res.t = BC_RESULT_STR;
 
        if (!push) {
-               if (!BC_PROG_STACK(&p->results, 2)) return BC_STATUS_EXEC_STACK;
+               if (!BC_PROG_STACK(&G.prog.results, 2)) return BC_STATUS_EXEC_STACK;
                bc_vec_pop(v);
-               bc_vec_pop(&p->results);
+               bc_vec_pop(&G.prog.results);
        }
 
-       bc_vec_pop(&p->results);
+       bc_vec_pop(&G.prog.results);
 
-       bc_vec_push(&p->results, &res);
+       bc_vec_push(&G.prog.results, &res);
        bc_vec_push(v, &n2);
 
        return BC_STATUS_SUCCESS;
 }
 #endif // ENABLE_DC
 
-static BcStatus bc_program_copyToVar(BcProgram *p, char *name, bool var)
+static BcStatus bc_program_copyToVar(char *name, bool var)
 {
        BcStatus s;
        BcResult *ptr, r;
        BcVec *v;
        BcNum *n;
 
-       if (!BC_PROG_STACK(&p->results, 1)) return BC_STATUS_EXEC_STACK;
+       if (!BC_PROG_STACK(&G.prog.results, 1)) return BC_STATUS_EXEC_STACK;
 
-       ptr = bc_vec_top(&p->results);
+       ptr = bc_vec_top(&G.prog.results);
        if ((ptr->t == BC_RESULT_ARRAY) != !var) return BC_STATUS_EXEC_BAD_TYPE;
-       bc_program_search(p, name, &v, var);
+       v = bc_program_search(name, var);
 
 #if ENABLE_DC
        if (ptr->t == BC_RESULT_STR && !var) return BC_STATUS_EXEC_BAD_TYPE;
-       if (ptr->t == BC_RESULT_STR) return bc_program_assignStr(p, ptr, v, true);
+       if (ptr->t == BC_RESULT_STR) return bc_program_assignStr(ptr, v, true);
 #endif
 
-       s = bc_program_num(p, ptr, &n, false);
+       s = bc_program_num(ptr, &n, false);
        if (s) return s;
 
        // Do this once more to make sure that pointers were not invalidated.
-       bc_program_search(p, name, &v, var);
+       v = bc_program_search(name, var);
 
        if (var) {
                bc_num_init(&r.d.n, BC_NUM_DEF_SIZE);
@@ -5812,12 +5727,12 @@ static BcStatus bc_program_copyToVar(BcProgram *p, char *name, bool var)
        }
 
        bc_vec_push(v, &r.d);
-       bc_vec_pop(&p->results);
+       bc_vec_pop(&G.prog.results);
 
        return s;
 }
 
-static BcStatus bc_program_assign(BcProgram *p, char inst)
+static BcStatus bc_program_assign(char inst)
 {
        BcStatus s;
        BcResult *left, *right, res;
@@ -5825,7 +5740,7 @@ static BcStatus bc_program_assign(BcProgram *p, char inst)
        unsigned long val, max;
        bool assign = inst == BC_INST_ASSIGN, ib, sc;
 
-       s = bc_program_binOpPrep(p, &left, &l, &right, &r, assign);
+       s = bc_program_binOpPrep(&left, &l, &right, &r, assign);
        if (s) return s;
 
        ib = left->t == BC_RESULT_IBASE;
@@ -5838,9 +5753,9 @@ static BcStatus bc_program_assign(BcProgram *p, char inst)
                BcVec *v;
 
                if (left->t != BC_RESULT_VAR) return BC_STATUS_EXEC_BAD_TYPE;
-               bc_program_search(p, left->d.id.name, &v, true);
+               v = bc_program_search(left->d.id.name, true);
 
-               return bc_program_assignStr(p, right, v, false);
+               return bc_program_assignStr(right, v, false);
        }
 #endif
 
@@ -5848,13 +5763,13 @@ static BcStatus bc_program_assign(BcProgram *p, char inst)
                return BC_STATUS_PARSE_BAD_ASSIGN;
 
 #if ENABLE_BC
-       if (inst == BC_INST_ASSIGN_DIVIDE && !bc_num_cmp(r, &p->zero))
+       if (inst == BC_INST_ASSIGN_DIVIDE && !bc_num_cmp(r, &G.prog.zero))
                return BC_STATUS_MATH_DIVIDE_BY_ZERO;
 
        if (assign)
                bc_num_copy(l, r);
        else
-               s = bc_program_ops[inst - BC_INST_ASSIGN_POWER](l, r, l, p->scale);
+               s = bc_program_ops[inst - BC_INST_ASSIGN_POWER](l, r, l, G.prog.scale);
 
        if (s) return s;
 #else
@@ -5871,16 +5786,16 @@ static BcStatus bc_program_assign(BcProgram *p, char inst)
 
                if (sc) {
                        max = BC_MAX_SCALE;
-                       ptr = &p->scale;
+                       ptr = &G.prog.scale;
                }
                else {
                        if (val < BC_NUM_MIN_BASE) return s;
                        max = ib ? BC_NUM_MAX_IBASE : BC_MAX_OBASE;
-                       ptr = ib ? &p->ib_t : &p->ob_t;
+                       ptr = ib ? &G.prog.ib_t : &G.prog.ob_t;
                }
 
                if (val > max) return s;
-               if (!sc) bc_num_copy(ib ? &p->ib : &p->ob, l);
+               if (!sc) bc_num_copy(ib ? &G.prog.ib : &G.prog.ob, l);
 
                *ptr = (size_t) val;
                s = BC_STATUS_SUCCESS;
@@ -5888,63 +5803,64 @@ static BcStatus bc_program_assign(BcProgram *p, char inst)
 
        bc_num_init(&res.d.n, l->len);
        bc_num_copy(&res.d.n, l);
-       bc_program_binOpRetire(p, &res);
+       bc_program_binOpRetire(&res);
 
        return s;
 }
 
-static BcStatus bc_program_pushVar(BcProgram *p, char *code, size_t *bgn,
+#if !ENABLE_DC
+#define bc_program_pushVar(code, bgn, pop, copy) \
+       bc_program_pushVar(code, bgn)
+// for bc, 'pop' and 'copy' are always false
+#endif
+static BcStatus bc_program_pushVar(char *code, size_t *bgn,
                                    bool pop, bool copy)
 {
        BcStatus s = BC_STATUS_SUCCESS;
        BcResult r;
        char *name = bc_program_name(code, bgn);
-#if ENABLE_DC // Exclude
-       BcNum *num;
-       BcVec *v;
-#else
-       (void) pop, (void) copy;
-#endif
 
        r.t = BC_RESULT_VAR;
        r.d.id.name = name;
 
 #if ENABLE_DC
-       bc_program_search(p, name, &v, true);
-       num = bc_vec_top(v);
+       {
+               BcVec *v = bc_program_search(name, true);
+               BcNum *num = bc_vec_top(v);
 
-       if (pop || copy) {
+               if (pop || copy) {
+
+                       if (!BC_PROG_STACK(v, 2 - copy)) {
+                               free(name);
+                               return BC_STATUS_EXEC_STACK;
+                       }
 
-               if (!BC_PROG_STACK(v, 2 - copy)) {
                        free(name);
-                       return BC_STATUS_EXEC_STACK;
-               }
+                       name = NULL;
 
-               free(name);
-               name = NULL;
+                       if (!BC_PROG_STR(num)) {
 
-               if (!BC_PROG_STR(num)) {
+                               r.t = BC_RESULT_TEMP;
 
-                       r.t = BC_RESULT_TEMP;
+                               bc_num_init(&r.d.n, BC_NUM_DEF_SIZE);
+                               bc_num_copy(&r.d.n, num);
+                       }
+                       else {
+                               r.t = BC_RESULT_STR;
+                               r.d.id.idx = num->rdx;
+                       }
 
-                       bc_num_init(&r.d.n, BC_NUM_DEF_SIZE);
-                       bc_num_copy(&r.d.n, num);
+                       if (!copy) bc_vec_pop(v);
                }
-               else {
-                       r.t = BC_RESULT_STR;
-                       r.d.id.idx = num->rdx;
-               }
-
-               if (!copy) bc_vec_pop(v);
        }
 #endif // ENABLE_DC
 
-       bc_vec_push(&p->results, &r);
+       bc_vec_push(&G.prog.results, &r);
 
        return s;
 }
 
-static BcStatus bc_program_pushArray(BcProgram *p, char *code, size_t *bgn,
+static BcStatus bc_program_pushArray(char *code, size_t *bgn,
                                      char inst)
 {
        BcStatus s = BC_STATUS_SUCCESS;
@@ -5955,14 +5871,14 @@ static BcStatus bc_program_pushArray(BcProgram *p, char *code, size_t *bgn,
 
        if (inst == BC_INST_ARRAY) {
                r.t = BC_RESULT_ARRAY;
-               bc_vec_push(&p->results, &r);
+               bc_vec_push(&G.prog.results, &r);
        }
        else {
 
                BcResult *operand;
                unsigned long temp;
 
-               s = bc_program_prep(p, &operand, &num);
+               s = bc_program_prep(&operand, &num);
                if (s) goto err;
                s = bc_num_ulong(num, &temp);
                if (s) goto err;
@@ -5973,7 +5889,7 @@ static BcStatus bc_program_pushArray(BcProgram *p, char *code, size_t *bgn,
                }
 
                r.d.id.idx = (size_t) temp;
-               bc_program_retire(p, &r, BC_RESULT_ARRAY_ELEM);
+               bc_program_retire(&r, BC_RESULT_ARRAY_ELEM);
        }
 
 err:
@@ -5982,14 +5898,14 @@ err:
 }
 
 #if ENABLE_BC
-static BcStatus bc_program_incdec(BcProgram *p, char inst)
+static BcStatus bc_program_incdec(char inst)
 {
        BcStatus s;
        BcResult *ptr, res, copy;
        BcNum *num = NULL;
        char inst2 = inst;
 
-       s = bc_program_prep(p, &ptr, &num);
+       s = bc_program_prep(&ptr, &num);
        if (s) return s;
 
        if (inst == BC_INST_INC_POST || inst == BC_INST_DEC_POST) {
@@ -6003,52 +5919,52 @@ static BcStatus bc_program_incdec(BcProgram *p, char inst)
                   BC_INST_ASSIGN_PLUS :
                   BC_INST_ASSIGN_MINUS;
 
-       bc_vec_push(&p->results, &res);
-       bc_program_assign(p, inst);
+       bc_vec_push(&G.prog.results, &res);
+       bc_program_assign(inst);
 
        if (inst2 == BC_INST_INC_POST || inst2 == BC_INST_DEC_POST) {
-               bc_vec_pop(&p->results);
-               bc_vec_push(&p->results, &copy);
+               bc_vec_pop(&G.prog.results);
+               bc_vec_push(&G.prog.results, &copy);
        }
 
        return s;
 }
 
-static BcStatus bc_program_call(BcProgram *p, char *code, size_t *idx)
+static BcStatus bc_program_call(char *code, size_t *idx)
 {
        BcStatus s = BC_STATUS_SUCCESS;
        BcInstPtr ip;
        size_t i, nparams = bc_program_index(code, idx);
        BcFunc *func;
-       BcVec *v;
        BcId *a;
        BcResultData param;
        BcResult *arg;
 
        ip.idx = 0;
        ip.func = bc_program_index(code, idx);
-       func = bc_vec_item(&p->fns, ip.func);
+       func = bc_vec_item(&G.prog.fns, ip.func);
 
        if (func->code.len == 0) return BC_STATUS_EXEC_UNDEFINED_FUNC;
        if (nparams != func->nparams) return BC_STATUS_EXEC_MISMATCHED_PARAMS;
-       ip.len = p->results.len - nparams;
+       ip.len = G.prog.results.len - nparams;
 
        for (i = 0; i < nparams; ++i) {
 
                a = bc_vec_item(&func->autos, nparams - 1 - i);
-               arg = bc_vec_top(&p->results);
+               arg = bc_vec_top(&G.prog.results);
 
                if ((!a->idx) != (arg->t == BC_RESULT_ARRAY) || arg->t == BC_RESULT_STR)
                        return BC_STATUS_EXEC_BAD_TYPE;
 
-               s = bc_program_copyToVar(p, a->name, a->idx);
+               s = bc_program_copyToVar(a->name, a->idx);
                if (s) return s;
        }
 
        for (; i < func->autos.len; ++i) {
+               BcVec *v;
 
                a = bc_vec_item(&func->autos, i);
-               bc_program_search(p, a->name, &v, a->idx);
+               v = bc_program_search(a->name, a->idx);
 
                if (a->idx) {
                        bc_num_init(&param.n, BC_NUM_DEF_SIZE);
@@ -6060,31 +5976,31 @@ static BcStatus bc_program_call(BcProgram *p, char *code, size_t *idx)
                }
        }
 
-       bc_vec_push(&p->stack, &ip);
+       bc_vec_push(&G.prog.stack, &ip);
 
        return BC_STATUS_SUCCESS;
 }
 
-static BcStatus bc_program_return(BcProgram *p, char inst)
+static BcStatus bc_program_return(char inst)
 {
        BcStatus s;
        BcResult res;
        BcFunc *f;
        size_t i;
-       BcInstPtr *ip = bc_vec_top(&p->stack);
+       BcInstPtr *ip = bc_vec_top(&G.prog.stack);
 
-       if (!BC_PROG_STACK(&p->results, ip->len + inst == BC_INST_RET))
+       if (!BC_PROG_STACK(&G.prog.results, ip->len + inst == BC_INST_RET))
                return BC_STATUS_EXEC_STACK;
 
-       f = bc_vec_item(&p->fns, ip->func);
+       f = bc_vec_item(&G.prog.fns, ip->func);
        res.t = BC_RESULT_TEMP;
 
        if (inst == BC_INST_RET) {
 
                BcNum *num;
-               BcResult *operand = bc_vec_top(&p->results);
+               BcResult *operand = bc_vec_top(&G.prog.results);
 
-               s = bc_program_num(p, operand, &num, false);
+               s = bc_program_num(operand, &num, false);
                if (s) return s;
                bc_num_init(&res.d.n, num->len);
                bc_num_copy(&res.d.n, num);
@@ -6100,13 +6016,13 @@ static BcStatus bc_program_return(BcProgram *p, char inst)
                BcVec *v;
                BcId *a = bc_vec_item(&f->autos, i);
 
-               bc_program_search(p, a->name, &v, a->idx);
+               v = bc_program_search(a->name, a->idx);
                bc_vec_pop(v);
        }
 
-       bc_vec_npop(&p->results, p->results.len - ip->len);
-       bc_vec_push(&p->results, &res);
-       bc_vec_pop(&p->stack);
+       bc_vec_npop(&G.prog.results, G.prog.results.len - ip->len);
+       bc_vec_push(&G.prog.results, &res);
+       bc_vec_pop(&G.prog.stack);
 
        return BC_STATUS_SUCCESS;
 }
@@ -6128,7 +6044,7 @@ static unsigned long bc_program_len(BcNum *n)
        return len;
 }
 
-static BcStatus bc_program_builtin(BcProgram *p, char inst)
+static BcStatus bc_program_builtin(char inst)
 {
        BcStatus s;
        BcResult *opnd;
@@ -6136,10 +6052,10 @@ static BcStatus bc_program_builtin(BcProgram *p, char inst)
        BcResult res;
        bool len = inst == BC_INST_LENGTH;
 
-       if (!BC_PROG_STACK(&p->results, 1)) return BC_STATUS_EXEC_STACK;
-       opnd = bc_vec_top(&p->results);
+       if (!BC_PROG_STACK(&G.prog.results, 1)) return BC_STATUS_EXEC_STACK;
+       opnd = bc_vec_top(&G.prog.results);
 
-       s = bc_program_num(p, opnd, &num, false);
+       s = bc_program_num(opnd, &num, false);
        if (s) return s;
 
 #if ENABLE_DC
@@ -6148,10 +6064,10 @@ static BcStatus bc_program_builtin(BcProgram *p, char inst)
 
        bc_num_init(&res.d.n, BC_NUM_DEF_SIZE);
 
-       if (inst == BC_INST_SQRT) s = bc_num_sqrt(num, &res.d.n, p->scale);
+       if (inst == BC_INST_SQRT) s = bc_num_sqrt(num, &res.d.n, G.prog.scale);
 #if ENABLE_BC
        else if (len != 0 && opnd->t == BC_RESULT_ARRAY) {
-               s = bc_num_ulong2num(&res.d.n, (unsigned long) ((BcVec *) num)->len);
+               bc_num_ulong2num(&res.d.n, (unsigned long) ((BcVec *) num)->len);
        }
 #endif
 #if ENABLE_DC
@@ -6160,45 +6076,39 @@ static BcStatus bc_program_builtin(BcProgram *p, char inst)
                char **str;
                size_t idx = opnd->t == BC_RESULT_STR ? opnd->d.id.idx : num->rdx;
 
-               str = bc_vec_item(&p->strs, idx);
-               s = bc_num_ulong2num(&res.d.n, strlen(*str));
-               if (s) goto err;
+               str = bc_vec_item(&G.prog.strs, idx);
+               bc_num_ulong2num(&res.d.n, strlen(*str));
        }
 #endif
        else {
                BcProgramBuiltIn f = len ? bc_program_len : bc_program_scale;
-               s = bc_num_ulong2num(&res.d.n, f(num));
-               if (s) goto err;
+               bc_num_ulong2num(&res.d.n, f(num));
        }
 
-       bc_program_retire(p, &res, BC_RESULT_TEMP);
-
-       return s;
+       bc_program_retire(&res, BC_RESULT_TEMP);
 
-err:
-       bc_num_free(&res.d.n);
        return s;
 }
 
 #if ENABLE_DC
-static BcStatus bc_program_divmod(BcProgram *p)
+static BcStatus bc_program_divmod(void)
 {
        BcStatus s;
        BcResult *opd1, *opd2, res, res2;
        BcNum *n1, *n2 = NULL;
 
-       s = bc_program_binOpPrep(p, &opd1, &n1, &opd2, &n2, false);
+       s = bc_program_binOpPrep(&opd1, &n1, &opd2, &n2, false);
        if (s) return s;
 
        bc_num_init(&res.d.n, BC_NUM_DEF_SIZE);
        bc_num_init(&res2.d.n, n2->len);
 
-       s = bc_num_divmod(n1, n2, &res2.d.n, &res.d.n, p->scale);
+       s = bc_num_divmod(n1, n2, &res2.d.n, &res.d.n, G.prog.scale);
        if (s) goto err;
 
-       bc_program_binOpRetire(p, &res2);
+       bc_program_binOpRetire(&res2);
        res.t = BC_RESULT_TEMP;
-       bc_vec_push(&p->results, &res);
+       bc_vec_push(&G.prog.results, &res);
 
        return s;
 
@@ -6208,18 +6118,18 @@ err:
        return s;
 }
 
-static BcStatus bc_program_modexp(BcProgram *p)
+static BcStatus bc_program_modexp(void)
 {
        BcStatus s;
        BcResult *r1, *r2, *r3, res;
        BcNum *n1, *n2, *n3;
 
-       if (!BC_PROG_STACK(&p->results, 3)) return BC_STATUS_EXEC_STACK;
-       s = bc_program_binOpPrep(p, &r2, &n2, &r3, &n3, false);
+       if (!BC_PROG_STACK(&G.prog.results, 3)) return BC_STATUS_EXEC_STACK;
+       s = bc_program_binOpPrep(&r2, &n2, &r3, &n3, false);
        if (s) return s;
 
-       r1 = bc_vec_item_rev(&p->results, 2);
-       s = bc_program_num(p, r1, &n1, false);
+       r1 = bc_vec_item_rev(&G.prog.results, 2);
+       s = bc_program_num(r1, &n1, false);
        if (s) return s;
        if (!BC_PROG_NUM(r1, n1)) return BC_STATUS_EXEC_BAD_TYPE;
 
@@ -6227,12 +6137,12 @@ static BcStatus bc_program_modexp(BcProgram *p)
        if (r1->t == BC_RESULT_VAR || r1->t == BC_RESULT_ARRAY_ELEM) {
 
                if (r1->t == r2->t) {
-                       s = bc_program_num(p, r2, &n2, false);
+                       s = bc_program_num(r2, &n2, false);
                        if (s) return s;
                }
 
                if (r1->t == r3->t) {
-                       s = bc_program_num(p, r3, &n3, false);
+                       s = bc_program_num(r3, &n3, false);
                        if (s) return s;
                }
        }
@@ -6241,8 +6151,8 @@ static BcStatus bc_program_modexp(BcProgram *p)
        s = bc_num_modexp(n1, n2, n3, &res.d.n);
        if (s) goto err;
 
-       bc_vec_pop(&p->results);
-       bc_program_binOpRetire(p, &res);
+       bc_vec_pop(&G.prog.results);
+       bc_program_binOpRetire(&res);
 
        return s;
 
@@ -6251,39 +6161,31 @@ err:
        return s;
 }
 
-static BcStatus bc_program_stackLen(BcProgram *p)
+static void bc_program_stackLen(void)
 {
-       BcStatus s;
        BcResult res;
-       size_t len = p->results.len;
+       size_t len = G.prog.results.len;
 
        res.t = BC_RESULT_TEMP;
 
        bc_num_init(&res.d.n, BC_NUM_DEF_SIZE);
-       s = bc_num_ulong2num(&res.d.n, len);
-       if (s) goto err;
-       bc_vec_push(&p->results, &res);
-
-       return s;
-
-err:
-       bc_num_free(&res.d.n);
-       return s;
+       bc_num_ulong2num(&res.d.n, len);
+       bc_vec_push(&G.prog.results, &res);
 }
 
-static BcStatus bc_program_asciify(BcProgram *p)
+static BcStatus bc_program_asciify(void)
 {
        BcStatus s;
        BcResult *r, res;
        BcNum *num = NULL, n;
        char *str, *str2, c;
-       size_t len = p->strs.len, idx;
+       size_t len = G.prog.strs.len, idx;
        unsigned long val;
 
-       if (!BC_PROG_STACK(&p->results, 1)) return BC_STATUS_EXEC_STACK;
-       r = bc_vec_top(&p->results);
+       if (!BC_PROG_STACK(&G.prog.results, 1)) return BC_STATUS_EXEC_STACK;
+       r = bc_vec_top(&G.prog.results);
 
-       s = bc_program_num(p, r, &num, false);
+       s = bc_program_num(r, &num, false);
        if (s) return s;
 
        if (BC_PROG_NUM(r, num)) {
@@ -6292,7 +6194,7 @@ static BcStatus bc_program_asciify(BcProgram *p)
                bc_num_copy(&n, num);
                bc_num_truncate(&n, n.rdx);
 
-               s = bc_num_mod(&n, &p->strmb, &n, 0);
+               s = bc_num_mod(&n, &G.prog.strmb, &n, 0);
                if (s) goto num_err;
                s = bc_num_ulong(&n, &val);
                if (s) goto num_err;
@@ -6303,7 +6205,7 @@ static BcStatus bc_program_asciify(BcProgram *p)
        }
        else {
                idx = (r->t == BC_RESULT_STR) ? r->d.id.idx : num->rdx;
-               str2 = *((char **) bc_vec_item(&p->strs, idx));
+               str2 = *((char **) bc_vec_item(&G.prog.strs, idx));
                c = str2[0];
        }
 
@@ -6312,12 +6214,12 @@ static BcStatus bc_program_asciify(BcProgram *p)
        str[1] = '\0';
 
        str2 = xstrdup(str);
-       bc_program_addFunc(p, str2, &idx);
+       bc_program_addFunc(str2, &idx);
 
        if (idx != len + BC_PROG_REQ_FUNCS) {
 
-               for (idx = 0; idx < p->strs.len; ++idx) {
-                       if (!strcmp(*((char **) bc_vec_item(&p->strs, idx)), str)) {
+               for (idx = 0; idx < G.prog.strs.len; ++idx) {
+                       if (!strcmp(*((char **) bc_vec_item(&G.prog.strs, idx)), str)) {
                                len = idx;
                                break;
                        }
@@ -6326,12 +6228,12 @@ static BcStatus bc_program_asciify(BcProgram *p)
                free(str);
        }
        else
-               bc_vec_push(&p->strs, &str);
+               bc_vec_push(&G.prog.strs, &str);
 
        res.t = BC_RESULT_STR;
        res.d.id.idx = len;
-       bc_vec_pop(&p->results);
-       bc_vec_push(&p->results, &res);
+       bc_vec_pop(&G.prog.results);
+       bc_vec_push(&G.prog.results, &res);
 
        return BC_STATUS_SUCCESS;
 
@@ -6340,7 +6242,7 @@ num_err:
        return s;
 }
 
-static BcStatus bc_program_printStream(BcProgram *p)
+static BcStatus bc_program_printStream(void)
 {
        BcStatus s;
        BcResult *r;
@@ -6348,17 +6250,17 @@ static BcStatus bc_program_printStream(BcProgram *p)
        size_t idx;
        char *str;
 
-       if (!BC_PROG_STACK(&p->results, 1)) return BC_STATUS_EXEC_STACK;
-       r = bc_vec_top(&p->results);
+       if (!BC_PROG_STACK(&G.prog.results, 1)) return BC_STATUS_EXEC_STACK;
+       r = bc_vec_top(&G.prog.results);
 
-       s = bc_program_num(p, r, &n, false);
+       s = bc_program_num(r, &n, false);
        if (s) return s;
 
        if (BC_PROG_NUM(r, n))
-               s = bc_num_stream(n, &p->strmb, &p->nchars, p->len);
+               s = bc_num_stream(n, &G.prog.strmb, &G.prog.nchars, G.prog.len);
        else {
                idx = (r->t == BC_RESULT_STR) ? r->d.id.idx : n->rdx;
-               str = *((char **) bc_vec_item(&p->strs, idx));
+               str = *((char **) bc_vec_item(&G.prog.strs, idx));
                printf("%s", str);
        }
 
@@ -6367,26 +6269,24 @@ static BcStatus bc_program_printStream(BcProgram *p)
 
 static BcStatus bc_program_nquit(void)
 {
-       BcProgram *p = &G.prog;
-
        BcStatus s;
        BcResult *opnd;
        BcNum *num = NULL;
        unsigned long val;
 
-       s = bc_program_prep(p, &opnd, &num);
+       s = bc_program_prep(&opnd, &num);
        if (s) return s;
        s = bc_num_ulong(num, &val);
        if (s) return s;
 
-       bc_vec_pop(&p->results);
+       bc_vec_pop(&G.prog.results);
 
-       if (p->stack.len < val)
+       if (G.prog.stack.len < val)
                return BC_STATUS_EXEC_STACK;
-       else if (p->stack.len == val)
+       else if (G.prog.stack.len == val)
                return BC_STATUS_QUIT;
 
-       bc_vec_npop(&p->stack, val);
+       bc_vec_npop(&G.prog.stack, val);
 
        return s;
 }
@@ -6394,8 +6294,6 @@ static BcStatus bc_program_nquit(void)
 static BcStatus bc_program_execStr(char *code, size_t *bgn,
                                    bool cond)
 {
-       BcProgram *p = &G.prog;
-
        BcStatus s = BC_STATUS_SUCCESS;
        BcResult *r;
        char **str;
@@ -6406,13 +6304,12 @@ static BcStatus bc_program_execStr(char *code, size_t *bgn,
        BcNum *n;
        bool exec;
 
-       if (!BC_PROG_STACK(&p->results, 1)) return BC_STATUS_EXEC_STACK;
+       if (!BC_PROG_STACK(&G.prog.results, 1)) return BC_STATUS_EXEC_STACK;
 
-       r = bc_vec_top(&p->results);
+       r = bc_vec_top(&G.prog.results);
 
        if (cond) {
 
-               BcVec *v;
                char *name, *then_name = bc_program_name(code, bgn), *else_name = NULL;
 
                if (code[*bgn] == BC_PARSE_STREND)
@@ -6430,7 +6327,8 @@ static BcStatus bc_program_execStr(char *code, size_t *bgn,
                }
 
                if (exec) {
-                       bc_program_search(p, name, &v, true);
+                       BcVec *v;
+                       v = bc_program_search(name, true);
                        n = bc_vec_top(v);
                }
 
@@ -6450,7 +6348,7 @@ static BcStatus bc_program_execStr(char *code, size_t *bgn,
                if (r->t == BC_RESULT_STR)
                        sidx = r->d.id.idx;
                else if (r->t == BC_RESULT_VAR) {
-                       s = bc_program_num(p, r, &n, false);
+                       s = bc_program_num(r, &n, false);
                        if (s || !BC_PROG_STR(n)) goto exit;
                        sidx = n->rdx;
                }
@@ -6460,11 +6358,11 @@ static BcStatus bc_program_execStr(char *code, size_t *bgn,
 
        fidx = sidx + BC_PROG_REQ_FUNCS;
 
-       str = bc_vec_item(&p->strs, sidx);
-       f = bc_vec_item(&p->fns, fidx);
+       str = bc_vec_item(&G.prog.strs, sidx);
+       f = bc_vec_item(&G.prog.fns, fidx);
 
        if (f->code.len == 0) {
-               common_parse_init(&prs, p, fidx);
+               common_parse_init(&prs, fidx);
                s = bc_parse_text(&prs, *str);
                if (s) goto err;
                s = common_parse_expr(&prs, BC_PARSE_NOCALL);
@@ -6479,68 +6377,60 @@ static BcStatus bc_program_execStr(char *code, size_t *bgn,
        }
 
        ip.idx = 0;
-       ip.len = p->results.len;
+       ip.len = G.prog.results.len;
        ip.func = fidx;
 
-       bc_vec_pop(&p->results);
-       bc_vec_push(&p->stack, &ip);
+       bc_vec_pop(&G.prog.results);
+       bc_vec_push(&G.prog.stack, &ip);
 
        return BC_STATUS_SUCCESS;
 
 err:
        bc_parse_free(&prs);
-       f = bc_vec_item(&p->fns, fidx);
+       f = bc_vec_item(&G.prog.fns, fidx);
        bc_vec_npop(&f->code, f->code.len);
 exit:
-       bc_vec_pop(&p->results);
+       bc_vec_pop(&G.prog.results);
        return s;
 }
 #endif // ENABLE_DC
 
-static BcStatus bc_program_pushGlobal(BcProgram *p, char inst)
+static void bc_program_pushGlobal(char inst)
 {
-       BcStatus s;
        BcResult res;
        unsigned long val;
 
        res.t = inst - BC_INST_IBASE + BC_RESULT_IBASE;
        if (inst == BC_INST_IBASE)
-               val = (unsigned long) p->ib_t;
+               val = (unsigned long) G.prog.ib_t;
        else if (inst == BC_INST_SCALE)
-               val = (unsigned long) p->scale;
+               val = (unsigned long) G.prog.scale;
        else
-               val = (unsigned long) p->ob_t;
+               val = (unsigned long) G.prog.ob_t;
 
        bc_num_init(&res.d.n, BC_NUM_DEF_SIZE);
-       s = bc_num_ulong2num(&res.d.n, val);
-       if (s) goto err;
-       bc_vec_push(&p->results, &res);
-
-       return s;
-
-err:
-       bc_num_free(&res.d.n);
-       return s;
+       bc_num_ulong2num(&res.d.n, val);
+       bc_vec_push(&G.prog.results, &res);
 }
 
-static void bc_program_addFunc(BcProgram *p, char *name, size_t *idx)
+static void bc_program_addFunc(char *name, size_t *idx)
 {
        BcStatus s;
        BcId entry, *entry_ptr;
        BcFunc f;
 
        entry.name = name;
-       entry.idx = p->fns.len;
+       entry.idx = G.prog.fns.len;
 
-       s = bc_map_insert(&p->fn_map, &entry, idx);
+       s = bc_map_insert(&G.prog.fn_map, &entry, idx);
        if (s) free(name);
 
-       entry_ptr = bc_vec_item(&p->fn_map, *idx);
+       entry_ptr = bc_vec_item(&G.prog.fn_map, *idx);
        *idx = entry_ptr->idx;
 
        if (s == BC_STATUS_VEC_ITEM_EXISTS) {
 
-               BcFunc *func = bc_vec_item(&p->fns, entry_ptr->idx);
+               BcFunc *func = bc_vec_item(&G.prog.fns, entry_ptr->idx);
 
                // We need to reset these, so the function can be repopulated.
                func->nparams = 0;
@@ -6550,20 +6440,20 @@ static void bc_program_addFunc(BcProgram *p, char *name, size_t *idx)
        }
        else {
                bc_func_init(&f);
-               bc_vec_push(&p->fns, &f);
+               bc_vec_push(&G.prog.fns, &f);
        }
 }
 
-static BcStatus bc_program_reset(BcProgram *p, BcStatus s)
+static BcStatus bc_program_reset(BcStatus s)
 {
        BcFunc *f;
        BcInstPtr *ip;
 
-       bc_vec_npop(&p->stack, p->stack.len - 1);
-       bc_vec_npop(&p->results, p->results.len);
+       bc_vec_npop(&G.prog.stack, G.prog.stack.len - 1);
+       bc_vec_npop(&G.prog.results, G.prog.results.len);
 
-       f = bc_vec_item(&p->fns, 0);
-       ip = bc_vec_top(&p->stack);
+       f = bc_vec_item(&G.prog.fns, 0);
+       ip = bc_vec_top(&G.prog.stack);
        ip->idx = f->code.len;
 
        if (!s && G_interrupt && !G.tty) return BC_STATUS_QUIT;
@@ -6584,14 +6474,12 @@ static BcStatus bc_program_reset(BcProgram *p, BcStatus s)
 
 static BcStatus bc_program_exec(void)
 {
-       BcProgram *p = &G.prog;
-
        BcStatus s = BC_STATUS_SUCCESS;
        size_t idx;
        BcResult r, *ptr;
        BcNum *num;
-       BcInstPtr *ip = bc_vec_top(&p->stack);
-       BcFunc *func = bc_vec_item(&p->fns, ip->func);
+       BcInstPtr *ip = bc_vec_top(&G.prog.stack);
+       BcFunc *func = bc_vec_item(&G.prog.fns, ip->func);
        char *code = func->code.v;
        bool cond = false;
 
@@ -6604,10 +6492,10 @@ static BcStatus bc_program_exec(void)
 #if ENABLE_BC
                        case BC_INST_JUMP_ZERO:
                        {
-                               s = bc_program_prep(p, &ptr, &num);
+                               s = bc_program_prep(&ptr, &num);
                                if (s) return s;
-                               cond = !bc_num_cmp(num, &p->zero);
-                               bc_vec_pop(&p->results);
+                               cond = !bc_num_cmp(num, &G.prog.zero);
+                               bc_vec_pop(&G.prog.results);
                        }
                        // Fallthrough.
                        case BC_INST_JUMP:
@@ -6621,7 +6509,7 @@ static BcStatus bc_program_exec(void)
 
                        case BC_INST_CALL:
                        {
-                               s = bc_program_call(p, code, &ip->idx);
+                               s = bc_program_call(code, &ip->idx);
                                break;
                        }
 
@@ -6630,7 +6518,7 @@ static BcStatus bc_program_exec(void)
                        case BC_INST_INC_POST:
                        case BC_INST_DEC_POST:
                        {
-                               s = bc_program_incdec(p, inst);
+                               s = bc_program_incdec(inst);
                                break;
                        }
 
@@ -6643,7 +6531,7 @@ static BcStatus bc_program_exec(void)
                        case BC_INST_RET:
                        case BC_INST_RET0:
                        {
-                               s = bc_program_return(p, inst);
+                               s = bc_program_return(inst);
                                break;
                        }
 
@@ -6657,7 +6545,7 @@ static BcStatus bc_program_exec(void)
                        case BC_INST_REL_LT:
                        case BC_INST_REL_GT:
                        {
-                               s = bc_program_logical(p, inst);
+                               s = bc_program_logical(inst);
                                break;
                        }
 
@@ -6669,21 +6557,21 @@ static BcStatus bc_program_exec(void)
 
                        case BC_INST_VAR:
                        {
-                               s = bc_program_pushVar(p, code, &ip->idx, false, false);
+                               s = bc_program_pushVar(code, &ip->idx, false, false);
                                break;
                        }
 
                        case BC_INST_ARRAY_ELEM:
                        case BC_INST_ARRAY:
                        {
-                               s = bc_program_pushArray(p, code, &ip->idx, inst);
+                               s = bc_program_pushArray(code, &ip->idx, inst);
                                break;
                        }
 
                        case BC_INST_LAST:
                        {
                                r.t = BC_RESULT_LAST;
-                               bc_vec_push(&p->results, &r);
+                               bc_vec_push(&G.prog.results, &r);
                                break;
                        }
 
@@ -6691,7 +6579,7 @@ static BcStatus bc_program_exec(void)
                        case BC_INST_SCALE:
                        case BC_INST_OBASE:
                        {
-                               s = bc_program_pushGlobal(p, inst);
+                               bc_program_pushGlobal(inst);
                                break;
                        }
 
@@ -6699,7 +6587,7 @@ static BcStatus bc_program_exec(void)
                        case BC_INST_LENGTH:
                        case BC_INST_SQRT:
                        {
-                               s = bc_program_builtin(p, inst);
+                               s = bc_program_builtin(inst);
                                break;
                        }
 
@@ -6707,22 +6595,22 @@ static BcStatus bc_program_exec(void)
                        {
                                r.t = BC_RESULT_CONSTANT;
                                r.d.id.idx = bc_program_index(code, &ip->idx);
-                               bc_vec_push(&p->results, &r);
+                               bc_vec_push(&G.prog.results, &r);
                                break;
                        }
 
                        case BC_INST_POP:
                        {
-                               if (!BC_PROG_STACK(&p->results, 1))
+                               if (!BC_PROG_STACK(&G.prog.results, 1))
                                        s = BC_STATUS_EXEC_STACK;
                                else
-                                       bc_vec_pop(&p->results);
+                                       bc_vec_pop(&G.prog.results);
                                break;
                        }
 
                        case BC_INST_POP_EXEC:
                        {
-                               bc_vec_pop(&p->stack);
+                               bc_vec_pop(&G.prog.stack);
                                break;
                        }
 
@@ -6730,7 +6618,7 @@ static BcStatus bc_program_exec(void)
                        case BC_INST_PRINT_POP:
                        case BC_INST_PRINT_STR:
                        {
-                               s = bc_program_print(p, inst, 0);
+                               s = bc_program_print(inst, 0);
                                break;
                        }
 
@@ -6738,7 +6626,7 @@ static BcStatus bc_program_exec(void)
                        {
                                r.t = BC_RESULT_STR;
                                r.d.id.idx = bc_program_index(code, &ip->idx);
-                               bc_vec_push(&p->results, &r);
+                               bc_vec_push(&G.prog.results, &r);
                                break;
                        }
 
@@ -6749,25 +6637,25 @@ static BcStatus bc_program_exec(void)
                        case BC_INST_PLUS:
                        case BC_INST_MINUS:
                        {
-                               s = bc_program_op(p, inst);
+                               s = bc_program_op(inst);
                                break;
                        }
 
                        case BC_INST_BOOL_NOT:
                        {
-                               s = bc_program_prep(p, &ptr, &num);
+                               s = bc_program_prep(&ptr, &num);
                                if (s) return s;
 
                                bc_num_init(&r.d.n, BC_NUM_DEF_SIZE);
-                               (!bc_num_cmp(num, &p->zero) ? bc_num_one : bc_num_zero)(&r.d.n);
-                               bc_program_retire(p, &r, BC_RESULT_TEMP);
+                               (!bc_num_cmp(num, &G.prog.zero) ? bc_num_one : bc_num_zero)(&r.d.n);
+                               bc_program_retire(&r, BC_RESULT_TEMP);
 
                                break;
                        }
 
                        case BC_INST_NEG:
                        {
-                               s = bc_program_negate(p);
+                               s = bc_program_negate();
                                break;
                        }
 
@@ -6781,19 +6669,19 @@ static BcStatus bc_program_exec(void)
 #endif
                        case BC_INST_ASSIGN:
                        {
-                               s = bc_program_assign(p, inst);
+                               s = bc_program_assign(inst);
                                break;
                        }
 #if ENABLE_DC
                        case BC_INST_MODEXP:
                        {
-                               s = bc_program_modexp(p);
+                               s = bc_program_modexp();
                                break;
                        }
 
                        case BC_INST_DIVMOD:
                        {
-                               s = bc_program_divmod(p);
+                               s = bc_program_divmod();
                                break;
                        }
 
@@ -6807,29 +6695,29 @@ static BcStatus bc_program_exec(void)
 
                        case BC_INST_PRINT_STACK:
                        {
-                               for (idx = 0; !s && idx < p->results.len; ++idx)
-                                       s = bc_program_print(p, BC_INST_PRINT, idx);
+                               for (idx = 0; !s && idx < G.prog.results.len; ++idx)
+                                       s = bc_program_print(BC_INST_PRINT, idx);
                                break;
                        }
 
                        case BC_INST_CLEAR_STACK:
                        {
-                               bc_vec_npop(&p->results, p->results.len);
+                               bc_vec_npop(&G.prog.results, G.prog.results.len);
                                break;
                        }
 
                        case BC_INST_STACK_LEN:
                        {
-                               s = bc_program_stackLen(p);
+                               bc_program_stackLen();
                                break;
                        }
 
                        case BC_INST_DUPLICATE:
                        {
-                               if (!BC_PROG_STACK(&p->results, 1)) return BC_STATUS_EXEC_STACK;
-                               ptr = bc_vec_top(&p->results);
+                               if (!BC_PROG_STACK(&G.prog.results, 1)) return BC_STATUS_EXEC_STACK;
+                               ptr = bc_vec_top(&G.prog.results);
                                bc_result_copy(&r, ptr);
-                               bc_vec_push(&p->results, &r);
+                               bc_vec_push(&G.prog.results, &r);
                                break;
                        }
 
@@ -6837,10 +6725,10 @@ static BcStatus bc_program_exec(void)
                        {
                                BcResult *ptr2;
 
-                               if (!BC_PROG_STACK(&p->results, 2)) return BC_STATUS_EXEC_STACK;
+                               if (!BC_PROG_STACK(&G.prog.results, 2)) return BC_STATUS_EXEC_STACK;
 
-                               ptr = bc_vec_item_rev(&p->results, 0);
-                               ptr2 = bc_vec_item_rev(&p->results, 1);
+                               ptr = bc_vec_item_rev(&G.prog.results, 0);
+                               ptr2 = bc_vec_item_rev(&G.prog.results, 1);
                                memcpy(&r, ptr, sizeof(BcResult));
                                memcpy(ptr, ptr2, sizeof(BcResult));
                                memcpy(ptr2, &r, sizeof(BcResult));
@@ -6850,13 +6738,13 @@ static BcStatus bc_program_exec(void)
 
                        case BC_INST_ASCIIFY:
                        {
-                               s = bc_program_asciify(p);
+                               s = bc_program_asciify();
                                break;
                        }
 
                        case BC_INST_PRINT_STREAM:
                        {
-                               s = bc_program_printStream(p);
+                               s = bc_program_printStream();
                                break;
                        }
 
@@ -6864,24 +6752,24 @@ static BcStatus bc_program_exec(void)
                        case BC_INST_PUSH_VAR:
                        {
                                bool copy = inst == BC_INST_LOAD;
-                               s = bc_program_pushVar(p, code, &ip->idx, true, copy);
+                               s = bc_program_pushVar(code, &ip->idx, true, copy);
                                break;
                        }
 
                        case BC_INST_PUSH_TO_VAR:
                        {
                                char *name = bc_program_name(code, &ip->idx);
-                               s = bc_program_copyToVar(p, name, true);
+                               s = bc_program_copyToVar(name, true);
                                free(name);
                                break;
                        }
 
                        case BC_INST_QUIT:
                        {
-                               if (p->stack.len <= 2)
+                               if (G.prog.stack.len <= 2)
                                        s = BC_STATUS_QUIT;
                                else
-                                       bc_vec_npop(&p->stack, 2);
+                                       bc_vec_npop(&G.prog.stack, 2);
                                break;
                        }
 
@@ -6893,11 +6781,11 @@ static BcStatus bc_program_exec(void)
 #endif // ENABLE_DC
                }
 
-               if ((s && s != BC_STATUS_QUIT) || G_interrupt) s = bc_program_reset(p, s);
+               if ((s && s != BC_STATUS_QUIT) || G_interrupt) s = bc_program_reset(s);
 
                // If the stack has changed, pointers may be invalid.
-               ip = bc_vec_top(&p->stack);
-               func = bc_vec_item(&p->fns, ip->func);
+               ip = bc_vec_top(&G.prog.stack);
+               func = bc_vec_item(&G.prog.fns, ip->func);
                code = func->code.v;
        }
 
@@ -6917,7 +6805,7 @@ static BcStatus bc_vm_error(BcStatus s, const char *file, size_t line)
 {
        if (!s || s > BC_STATUS_VEC_ITEM_EXISTS) return s;
 
-       fprintf(stderr, bc_err_fmt, bc_errs[bc_err_ids[s]], bc_err_msgs[s]);
+       fprintf(stderr, bc_err_fmt, bc_err_msgs[s]);
        fprintf(stderr, "    %s", file);
        fprintf(stderr, bc_err_line + 4 * !line, line);
 
@@ -6928,21 +6816,26 @@ static BcStatus bc_vm_error(BcStatus s, const char *file, size_t line)
 static BcStatus bc_vm_posixError(BcStatus s, const char *file, size_t line,
                                  const char *msg)
 {
-       int p = (int) G_posix, w = (int) G_warn;
-       const char *const fmt = p ? bc_err_fmt : bc_warn_fmt;
+       const char *fmt;
 
-       if (!(p || w) || s < BC_STATUS_POSIX_NAME_LEN) return BC_STATUS_SUCCESS;
+       if (!(G.flags & (BC_FLAG_S|BC_FLAG_W))) return BC_STATUS_SUCCESS;
+       if (s < BC_STATUS_POSIX_NAME_LEN) return BC_STATUS_SUCCESS;
 
-       fprintf(stderr, fmt, bc_errs[bc_err_ids[s]], bc_err_msgs[s]);
+       fmt = G_posix ? bc_err_fmt : bc_warn_fmt;
+       fprintf(stderr, fmt, bc_err_msgs[s]);
        if (msg) fprintf(stderr, "    %s\n", msg);
        fprintf(stderr, "    %s", file);
        fprintf(stderr, bc_err_line + 4 * !line, line);
 
-       return s * (!G.ttyin && !!p);
+       if (G.ttyin || !G_posix)
+               s = BC_STATUS_SUCCESS;
+       return s;
 }
 
 static void bc_vm_envArgs(void)
 {
+       static const char* const bc_args_env_name = "BC_ENV_ARGS";
+
        BcVec v;
        char *env_args = getenv(bc_args_env_name), *buf;
 
@@ -7004,16 +6897,14 @@ static BcStatus bc_vm_process(const char *text)
 
                if (s == BC_STATUS_LIMITS) {
 
-                       bb_putchar('\n');
-                       printf("BC_BASE_MAX     = %lu\n", BC_MAX_OBASE);
-                       printf("BC_DIM_MAX      = %lu\n", BC_MAX_DIM);
-                       printf("BC_SCALE_MAX    = %lu\n", BC_MAX_SCALE);
-                       printf("BC_STRING_MAX   = %lu\n", BC_MAX_STRING);
-                       printf("BC_NAME_MAX     = %lu\n", BC_MAX_NAME);
-                       printf("BC_NUM_MAX      = %lu\n", BC_MAX_NUM);
-                       printf("Max Exponent    = %lu\n", BC_MAX_EXP);
-                       printf("Number of Vars  = %lu\n", BC_MAX_VARS);
-                       bb_putchar('\n');
+                       printf("BC_BASE_MAX     = %u\n", BC_MAX_OBASE);
+                       printf("BC_DIM_MAX      = %u\n", BC_MAX_DIM);
+                       printf("BC_SCALE_MAX    = %u\n", BC_MAX_SCALE);
+                       printf("BC_STRING_MAX   = %u\n", BC_MAX_STRING);
+                       printf("BC_NAME_MAX     = %u\n", BC_MAX_NAME);
+                       printf("BC_NUM_MAX      = %u\n", BC_MAX_NUM);
+                       printf("MAX Exponent    = %lu\n", BC_MAX_EXP);
+                       printf("Number of vars  = %lu\n", BC_MAX_VARS);
 
                        s = BC_STATUS_SUCCESS;
                }
@@ -7028,7 +6919,7 @@ static BcStatus bc_vm_process(const char *text)
                s = bc_program_exec();
                if (!s && G.tty) fflush(stdout);
                if (s && s != BC_STATUS_QUIT)
-                       s = bc_vm_error(bc_program_reset(&G.prog, s), G.prs.l.f, 0);
+                       s = bc_vm_error(bc_program_reset(s), G.prs.l.f, 0);
        }
 
        return s;
@@ -7042,8 +6933,8 @@ static BcStatus bc_vm_file(const char *file)
        BcInstPtr *ip;
 
        G.prog.file = file;
-       s = bc_read_file(file, &data);
-       if (s) return bc_vm_error(s, file, 0);
+       data = bc_read_file(file);
+       if (!data) return bc_vm_error(BC_STATUS_BIN_FILE, file, 0);
 
        bc_lex_file(&G.prs.l, file);
        s = bc_vm_process(data);
@@ -7061,11 +6952,10 @@ err:
 
 static BcStatus bc_vm_stdin(void)
 {
-       BcStatus s = BC_STATUS_SUCCESS;
+       BcStatus s;
        BcVec buf, buffer;
-       char c;
        size_t len, i, str = 0;
-       bool comment = false, notend;
+       bool comment = false;
 
        G.prog.file = bc_program_stdin_name;
        bc_lex_file(&G.prs.l, bc_program_stdin_name);
@@ -7078,7 +6968,7 @@ static BcStatus bc_vm_stdin(void)
        // with a backslash to the parser. The reason for that is because the parser
        // treats a backslash+newline combo as whitespace, per the bc spec. In that
        // case, and for strings and comments, the parser will expect more stuff.
-       for (s = bc_read_line(&buf, ">>> "); !s; s = bc_read_line(&buf, ">>> ")) {
+       while ((s = bc_read_line(&buf, ">>> ")) == BC_STATUS_SUCCESS) {
 
                char *string = buf.v;
 
@@ -7094,8 +6984,8 @@ static BcStatus bc_vm_stdin(void)
 
                        for (i = 0; i < len; ++i) {
 
-                               notend = len > i + 1;
-                               c = string[i];
+                               bool notend = len > i + 1;
+                               char c = string[i];
 
                                if (i - 1 > len || string[i - 1] != '\\') {
                                        if (G.sbgn == G.send)
@@ -7179,33 +7069,33 @@ static BcStatus bc_vm_exec(void)
 }
 
 #if ENABLE_FEATURE_CLEAN_UP
-static void bc_program_free(BcProgram *p)
+static void bc_program_free()
 {
-       bc_num_free(&p->ib);
-       bc_num_free(&p->ob);
-       bc_num_free(&p->hexb);
+       bc_num_free(&G.prog.ib);
+       bc_num_free(&G.prog.ob);
+       bc_num_free(&G.prog.hexb);
 # if ENABLE_DC
-       bc_num_free(&p->strmb);
+       bc_num_free(&G.prog.strmb);
 # endif
-       bc_vec_free(&p->fns);
-       bc_vec_free(&p->fn_map);
-       bc_vec_free(&p->vars);
-       bc_vec_free(&p->var_map);
-       bc_vec_free(&p->arrs);
-       bc_vec_free(&p->arr_map);
-       bc_vec_free(&p->strs);
-       bc_vec_free(&p->consts);
-       bc_vec_free(&p->results);
-       bc_vec_free(&p->stack);
-       bc_num_free(&p->last);
-       bc_num_free(&p->zero);
-       bc_num_free(&p->one);
+       bc_vec_free(&G.prog.fns);
+       bc_vec_free(&G.prog.fn_map);
+       bc_vec_free(&G.prog.vars);
+       bc_vec_free(&G.prog.var_map);
+       bc_vec_free(&G.prog.arrs);
+       bc_vec_free(&G.prog.arr_map);
+       bc_vec_free(&G.prog.strs);
+       bc_vec_free(&G.prog.consts);
+       bc_vec_free(&G.prog.results);
+       bc_vec_free(&G.prog.stack);
+       bc_num_free(&G.prog.last);
+       bc_num_free(&G.prog.zero);
+       bc_num_free(&G.prog.one);
 }
 
 static void bc_vm_free(void)
 {
        bc_vec_free(&G.files);
-       bc_program_free(&G.prog);
+       bc_program_free();
        bc_parse_free(&G.prs);
        free(G.env_args);
 }
@@ -7251,8 +7141,8 @@ static void bc_program_init(size_t line_len)
        bc_vec_init(&G.prog.fns, sizeof(BcFunc), bc_func_free);
        bc_map_init(&G.prog.fn_map);
 
-       bc_program_addFunc(&G.prog, xstrdup(bc_func_main), &idx);
-       bc_program_addFunc(&G.prog, xstrdup(bc_func_read), &idx);
+       bc_program_addFunc(xstrdup("(main)"), &idx);
+       bc_program_addFunc(xstrdup("(read)"), &idx);
 
        bc_vec_init(&G.prog.vars, sizeof(BcVec), bc_vec_free);
        bc_map_init(&G.prog.var_map);
@@ -7285,9 +7175,9 @@ static void bc_vm_init(const char *env_len)
 
        bc_program_init(len);
        if (IS_BC) {
-               bc_parse_init(&G.prs, &G.prog, BC_PROG_MAIN);
+               bc_parse_init(&G.prs, BC_PROG_MAIN);
        } else {
-               dc_parse_init(&G.prs, &G.prog, BC_PROG_MAIN);
+               dc_parse_init(&G.prs, BC_PROG_MAIN);
        }
 }