aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-12-02 15:48:37 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-12-05 15:43:35 +0100
commit6d9146ab56018b232a178b8fa463338cf731a832 (patch)
treeb645f5033fe4dc29a697323d2b115f48b97998c1
parent5a9fef5b599b0e9c31d4e1dffbb3e3f9d19a9603 (diff)
downloadbusybox-w32-6d9146ab56018b232a178b8fa463338cf731a832.tar.gz
busybox-w32-6d9146ab56018b232a178b8fa463338cf731a832.tar.bz2
busybox-w32-6d9146ab56018b232a178b8fa463338cf731a832.zip
bc: convert to "G trick" - this returns bc to zero bss increase
function old new delta bc_num_p 518 540 +22 bc_num_k 1010 1031 +21 bc_vm_process 312 327 +15 bc_program_exec 4401 4413 +12 bc_vm_posixError 194 205 +11 bc_num_a 480 491 +11 bc_program_reset 182 192 +10 bc_vm_sig 88 97 +9 bc_vm_error 148 156 +8 bc_parse_expr 2215 2222 +7 bc_num_compare 84 90 +6 dc_parse_parse 53 58 +5 dc_lex_token 670 675 +5 bc_read_line 359 364 +5 bc_parse_parse 471 476 +5 bc_num_cmp 294 299 +5 bc_num_subArrays 84 82 -2 bc_num_d 614 609 -5 dc_main 80 72 -8 bc_main 80 72 -8 bcg 40 - -40 bc_vm_run 2569 2382 -187 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 16/5 up/down: 157/-250) Total: -93 bytes text data bss dec hex filename 989425 485 7336 997246 f377e busybox_old 989372 485 7296 997153 f3721 busybox_unstripped Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--miscutils/bc.c292
1 files changed, 133 insertions, 159 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index d5f577598..e13b2283c 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -812,44 +812,39 @@ static BcStatus bc_program_exec(BcProgram *p);
812#define BC_MAX_EXP ((unsigned long) LONG_MAX) 812#define BC_MAX_EXP ((unsigned long) LONG_MAX)
813#define BC_MAX_VARS ((unsigned long) SIZE_MAX - 1) 813#define BC_MAX_VARS ((unsigned long) SIZE_MAX - 1)
814 814
815typedef struct BcVmExe { 815struct globals {
816 BcParseInit init; 816 BcParseInit init;
817 BcParseExpr exp; 817 BcParseExpr exp;
818 char sbgn; 818 char sbgn;
819 char send; 819 char send;
820} BcVmExe;
821
822typedef struct BcVm {
823 820
824 BcParse prs; 821 BcParse prs;
825 BcProgram prog; 822 BcProgram prog;
826 823
827 uint32_t flags; 824 unsigned flags;
828 BcVec files; 825 BcVec files;
829 826
830 char *env_args; 827 char *env_args;
831 BcVmExe exe;
832
833} BcVm;
834 828
835typedef struct BcGlobals { 829 unsigned sig; //counter?
830 unsigned sigc; //counter?
831 smallint signe; //flag
836 832
837 unsigned long sig; 833 smallint tty;
838 unsigned long sigc; 834 smallint ttyin;
839 unsigned long signe;
840
841 long tty;
842 long ttyin;
843 long posix;
844 long warn;
845 long exreg;
846 835
847#if ENABLE_FEATURE_BC_SIGNALS 836#if ENABLE_FEATURE_BC_SIGNALS
848 const char *sig_msg; 837 const char *sig_msg;
849#endif 838#endif
850 const char *help; 839} FIX_ALIASING;
840#define G (*ptr_to_globals)
841#define INIT_G() do { \
842 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
843} while (0)
844#define G_posix (ENABLE_BC && (G.flags & BC_FLAG_S))
845#define G_warn (ENABLE_BC && (G.flags & BC_FLAG_W))
846#define G_exreg (ENABLE_DC && (G.flags & BC_FLAG_X))
851 847
852} BcGlobals;
853 848
854#define IS_BC (ENABLE_BC && (!ENABLE_DC || applet_name[0] == 'b')) 849#define IS_BC (ENABLE_BC && (!ENABLE_DC || applet_name[0] == 'b'))
855 850
@@ -860,8 +855,6 @@ static BcStatus bc_vm_posixError(BcStatus s, const char *file, size_t line,
860 855
861static void bc_vm_info(void); 856static void bc_vm_info(void);
862 857
863static BcGlobals bcg;
864
865static const char* const bc_args_env_name = "BC_ENV_ARGS"; 858static const char* const bc_args_env_name = "BC_ENV_ARGS";
866 859
867static const char bc_err_fmt[] = "\n%s error: %s\n"; 860static const char bc_err_fmt[] = "\n%s error: %s\n";
@@ -1356,7 +1349,7 @@ static BcStatus bc_read_line(BcVec *vec, const char *prompt)
1356 int i; 1349 int i;
1357 signed char c; 1350 signed char c;
1358 1351
1359 if (bcg.ttyin && !bcg.posix) { 1352 if (G.ttyin && !G_posix) {
1360 fputs(prompt, stderr); 1353 fputs(prompt, stderr);
1361 fflush(stderr); 1354 fflush(stderr);
1362 } 1355 }
@@ -1373,11 +1366,11 @@ static BcStatus bc_read_line(BcVec *vec, const char *prompt)
1373 if (i == EOF) { 1366 if (i == EOF) {
1374#if ENABLE_FEATURE_BC_SIGNALS 1367#if ENABLE_FEATURE_BC_SIGNALS
1375 if (errno == EINTR) { 1368 if (errno == EINTR) {
1376 bcg.sigc = bcg.sig; 1369 G.sigc = G.sig;
1377 bcg.signe = 0; 1370 G.signe = 0;
1378 if (bcg.ttyin) { 1371 if (G.ttyin) {
1379 fputs(bc_program_ready_msg, stderr); 1372 fputs(bc_program_ready_msg, stderr);
1380 if (!bcg.posix) fputs(prompt, stderr); 1373 if (!G_posix) fputs(prompt, stderr);
1381 fflush(stderr); 1374 fflush(stderr);
1382 } 1375 }
1383 clearerr(stdin); 1376 clearerr(stdin);
@@ -1478,20 +1471,20 @@ static BcStatus bc_num_subArrays(BcDig *restrict a, BcDig *restrict b,
1478 size_t len) 1471 size_t len)
1479{ 1472{
1480 size_t i, j; 1473 size_t i, j;
1481 for (i = 0; !bcg.signe && i < len; ++i) { 1474 for (i = 0; !G.signe && i < len; ++i) {
1482 for (a[i] -= b[i], j = 0; !bcg.signe && a[i + j] < 0;) { 1475 for (a[i] -= b[i], j = 0; !G.signe && a[i + j] < 0;) {
1483 a[i + j++] += 10; 1476 a[i + j++] += 10;
1484 a[i + j] -= 1; 1477 a[i + j] -= 1;
1485 } 1478 }
1486 } 1479 }
1487 return bcg.signe ? BC_STATUS_EXEC_SIGNAL : BC_STATUS_SUCCESS; 1480 return G.signe ? BC_STATUS_EXEC_SIGNAL : BC_STATUS_SUCCESS;
1488} 1481}
1489 1482
1490static ssize_t bc_num_compare(BcDig *restrict a, BcDig *restrict b, size_t len) 1483static ssize_t bc_num_compare(BcDig *restrict a, BcDig *restrict b, size_t len)
1491{ 1484{
1492 size_t i; 1485 size_t i;
1493 int c = 0; 1486 int c = 0;
1494 for (i = len - 1; !bcg.signe && i < len && !(c = a[i] - b[i]); --i); 1487 for (i = len - 1; !G.signe && i < len && !(c = a[i] - b[i]); --i);
1495 return BC_NUM_NEG(i + 1, c < 0); 1488 return BC_NUM_NEG(i + 1, c < 0);
1496} 1489}
1497 1490
@@ -1537,7 +1530,7 @@ static ssize_t bc_num_cmp(BcNum *a, BcNum *b)
1537 cmp = bc_num_compare(max_num, min_num, b_int + min); 1530 cmp = bc_num_compare(max_num, min_num, b_int + min);
1538 if (cmp != 0) return BC_NUM_NEG(cmp, (!a_max) != neg); 1531 if (cmp != 0) return BC_NUM_NEG(cmp, (!a_max) != neg);
1539 1532
1540 for (max_num -= diff, i = diff - 1; !bcg.signe && i < diff; --i) { 1533 for (max_num -= diff, i = diff - 1; !G.signe && i < diff; --i) {
1541 if (max_num[i]) return BC_NUM_NEG(1, (!a_max) != neg); 1534 if (max_num[i]) return BC_NUM_NEG(1, (!a_max) != neg);
1542 } 1535 }
1543 1536
@@ -1696,13 +1689,13 @@ static BcStatus bc_num_a(BcNum *a, BcNum *b, BcNum *restrict c, size_t sub)
1696 ptr = ptr_b; 1689 ptr = ptr_b;
1697 } 1690 }
1698 1691
1699 for (carry = 0, i = 0; !bcg.signe && i < min_rdx + min_int; ++i, ++c->len) { 1692 for (carry = 0, i = 0; !G.signe && i < min_rdx + min_int; ++i, ++c->len) {
1700 in = ((int) ptr_a[i]) + ((int) ptr_b[i]) + carry; 1693 in = ((int) ptr_a[i]) + ((int) ptr_b[i]) + carry;
1701 carry = in / 10; 1694 carry = in / 10;
1702 ptr_c[i] = (BcDig)(in % 10); 1695 ptr_c[i] = (BcDig)(in % 10);
1703 } 1696 }
1704 1697
1705 for (; !bcg.signe && i < max + min_rdx; ++i, ++c->len) { 1698 for (; !G.signe && i < max + min_rdx; ++i, ++c->len) {
1706 in = ((int) ptr[i]) + carry; 1699 in = ((int) ptr[i]) + carry;
1707 carry = in / 10; 1700 carry = in / 10;
1708 ptr_c[i] = (BcDig)(in % 10); 1701 ptr_c[i] = (BcDig)(in % 10);
@@ -1710,7 +1703,7 @@ static BcStatus bc_num_a(BcNum *a, BcNum *b, BcNum *restrict c, size_t sub)
1710 1703
1711 if (carry != 0) c->num[c->len++] = (BcDig) carry; 1704 if (carry != 0) c->num[c->len++] = (BcDig) carry;
1712 1705
1713 return bcg.signe ? BC_STATUS_EXEC_SIGNAL : BC_STATUS_SUCCESS; 1706 return G.signe ? BC_STATUS_EXEC_SIGNAL : BC_STATUS_SUCCESS;
1714} 1707}
1715 1708
1716static BcStatus bc_num_s(BcNum *a, BcNum *b, BcNum *restrict c, size_t sub) 1709static BcStatus bc_num_s(BcNum *a, BcNum *b, BcNum *restrict c, size_t sub)
@@ -1785,7 +1778,7 @@ static BcStatus bc_num_k(BcNum *restrict a, BcNum *restrict b,
1785 BcNum l1, h1, l2, h2, m2, m1, z0, z1, z2, temp; 1778 BcNum l1, h1, l2, h2, m2, m1, z0, z1, z2, temp;
1786 bool aone = BC_NUM_ONE(a); 1779 bool aone = BC_NUM_ONE(a);
1787 1780
1788 if (bcg.signe) return BC_STATUS_EXEC_SIGNAL; 1781 if (G.signe) return BC_STATUS_EXEC_SIGNAL;
1789 if (a->len == 0 || b->len == 0) { 1782 if (a->len == 0 || b->len == 0) {
1790 bc_num_zero(c); 1783 bc_num_zero(c);
1791 return BC_STATUS_SUCCESS; 1784 return BC_STATUS_SUCCESS;
@@ -1803,9 +1796,9 @@ static BcStatus bc_num_k(BcNum *restrict a, BcNum *restrict b,
1803 memset(c->num, 0, sizeof(BcDig) * c->cap); 1796 memset(c->num, 0, sizeof(BcDig) * c->cap);
1804 c->len = carry = len = 0; 1797 c->len = carry = len = 0;
1805 1798
1806 for (i = 0; !bcg.signe && i < b->len; ++i) { 1799 for (i = 0; !G.signe && i < b->len; ++i) {
1807 1800
1808 for (j = 0; !bcg.signe && j < a->len; ++j) { 1801 for (j = 0; !G.signe && j < a->len; ++j) {
1809 int in = (int) c->num[i + j]; 1802 int in = (int) c->num[i + j];
1810 in += ((int) a->num[j]) * ((int) b->num[i]) + carry; 1803 in += ((int) a->num[j]) * ((int) b->num[i]) + carry;
1811 carry = in / 10; 1804 carry = in / 10;
@@ -1819,7 +1812,7 @@ static BcStatus bc_num_k(BcNum *restrict a, BcNum *restrict b,
1819 1812
1820 c->len = len; 1813 c->len = len;
1821 1814
1822 return bcg.signe ? BC_STATUS_EXEC_SIGNAL : BC_STATUS_SUCCESS; 1815 return G.signe ? BC_STATUS_EXEC_SIGNAL : BC_STATUS_SUCCESS;
1823 } 1816 }
1824 1817
1825 bc_num_init(&l1, max); 1818 bc_num_init(&l1, max);
@@ -1969,7 +1962,7 @@ static BcStatus bc_num_d(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale)
1969 c->len = cp.len; 1962 c->len = cp.len;
1970 p = b->num; 1963 p = b->num;
1971 1964
1972 for (i = end - 1; !bcg.signe && !s && i < end; --i) { 1965 for (i = end - 1; !G.signe && !s && i < end; --i) {
1973 n = cp.num + i; 1966 n = cp.num + i;
1974 for (q = 0; (!s && n[len] != 0) || bc_num_compare(n, p, len) >= 0; ++q) 1967 for (q = 0; (!s && n[len] != 0) || bc_num_compare(n, p, len) >= 0; ++q)
1975 s = bc_num_subArrays(n, p, len); 1968 s = bc_num_subArrays(n, p, len);
@@ -2069,20 +2062,20 @@ static BcStatus bc_num_p(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale)
2069 2062
2070 b->neg = neg; 2063 b->neg = neg;
2071 2064
2072 for (powrdx = a->rdx; !bcg.signe && !(pow & 1); pow >>= 1) { 2065 for (powrdx = a->rdx; !G.signe && !(pow & 1); pow >>= 1) {
2073 powrdx <<= 1; 2066 powrdx <<= 1;
2074 s = bc_num_mul(&copy, &copy, &copy, powrdx); 2067 s = bc_num_mul(&copy, &copy, &copy, powrdx);
2075 if (s) goto err; 2068 if (s) goto err;
2076 } 2069 }
2077 2070
2078 if (bcg.signe) { 2071 if (G.signe) {
2079 s = BC_STATUS_EXEC_SIGNAL; 2072 s = BC_STATUS_EXEC_SIGNAL;
2080 goto err; 2073 goto err;
2081 } 2074 }
2082 2075
2083 bc_num_copy(c, &copy); 2076 bc_num_copy(c, &copy);
2084 2077
2085 for (resrdx = powrdx, pow >>= 1; !bcg.signe && pow != 0; pow >>= 1) { 2078 for (resrdx = powrdx, pow >>= 1; !G.signe && pow != 0; pow >>= 1) {
2086 2079
2087 powrdx <<= 1; 2080 powrdx <<= 1;
2088 s = bc_num_mul(&copy, &copy, &copy, powrdx); 2081 s = bc_num_mul(&copy, &copy, &copy, powrdx);
@@ -2100,7 +2093,7 @@ static BcStatus bc_num_p(BcNum *a, BcNum *b, BcNum *restrict c, size_t scale)
2100 if (s) goto err; 2093 if (s) goto err;
2101 } 2094 }
2102 2095
2103 if (bcg.signe) { 2096 if (G.signe) {
2104 s = BC_STATUS_EXEC_SIGNAL; 2097 s = BC_STATUS_EXEC_SIGNAL;
2105 goto err; 2098 goto err;
2106 } 2099 }
@@ -2657,7 +2650,7 @@ static BcStatus bc_num_sqrt(BcNum *a, BcNum *restrict b, size_t scale)
2657 resrdx = scale + 2; 2650 resrdx = scale + 2;
2658 len = BC_NUM_INT(x0) + resrdx - 1; 2651 len = BC_NUM_INT(x0) + resrdx - 1;
2659 2652
2660 while (!bcg.signe && (cmp != 0 || digs < len)) { 2653 while (!G.signe && (cmp != 0 || digs < len)) {
2661 2654
2662 s = bc_num_div(a, x0, &f, resrdx); 2655 s = bc_num_div(a, x0, &f, resrdx);
2663 if (s) goto err; 2656 if (s) goto err;
@@ -2685,7 +2678,7 @@ static BcStatus bc_num_sqrt(BcNum *a, BcNum *restrict b, size_t scale)
2685 x1 = temp; 2678 x1 = temp;
2686 } 2679 }
2687 2680
2688 if (bcg.signe) { 2681 if (G.signe) {
2689 s = BC_STATUS_EXEC_SIGNAL; 2682 s = BC_STATUS_EXEC_SIGNAL;
2690 goto err; 2683 goto err;
2691 } 2684 }
@@ -3461,7 +3454,7 @@ static BcStatus dc_lex_register(BcLex *l)
3461 if (isspace(l->buf[l->i - 1])) { 3454 if (isspace(l->buf[l->i - 1])) {
3462 bc_lex_whitespace(l); 3455 bc_lex_whitespace(l);
3463 ++l->i; 3456 ++l->i;
3464 if (!bcg.exreg) 3457 if (!G_exreg)
3465 s = BC_STATUS_LEX_EXTENDED_REG; 3458 s = BC_STATUS_LEX_EXTENDED_REG;
3466 else 3459 else
3467 s = bc_lex_name(l); 3460 s = bc_lex_name(l);
@@ -4782,7 +4775,7 @@ static BcStatus bc_parse_parse(BcParse *p)
4782 else 4775 else
4783 s = bc_parse_stmt(p); 4776 s = bc_parse_stmt(p);
4784 4777
4785 if ((s && s != BC_STATUS_QUIT && s != BC_STATUS_LIMITS) || bcg.signe) 4778 if ((s && s != BC_STATUS_QUIT && s != BC_STATUS_LIMITS) || G.signe)
4786 s = bc_parse_reset(p, s); 4779 s = bc_parse_reset(p, s);
4787 4780
4788 return s; 4781 return s;
@@ -4802,7 +4795,7 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next)
4802 paren_expr = rprn = done = get_token = assign = false; 4795 paren_expr = rprn = done = get_token = assign = false;
4803 bin_last = true; 4796 bin_last = true;
4804 4797
4805 for (; !bcg.signe && !s && !done && bc_parse_exprs[t]; t = p->l.t.t) { 4798 for (; !G.signe && !s && !done && bc_parse_exprs[t]; t = p->l.t.t) {
4806 switch (t) { 4799 switch (t) {
4807 4800
4808 case BC_LEX_OP_INC: 4801 case BC_LEX_OP_INC:
@@ -4996,7 +4989,7 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next)
4996 } 4989 }
4997 4990
4998 if (s) return s; 4991 if (s) return s;
4999 if (bcg.signe) return BC_STATUS_EXEC_SIGNAL; 4992 if (G.signe) return BC_STATUS_EXEC_SIGNAL;
5000 4993
5001 while (p->ops.len > ops_bgn) { 4994 while (p->ops.len > ops_bgn) {
5002 4995
@@ -5256,7 +5249,7 @@ static BcStatus dc_parse_parse(BcParse *p)
5256 else 5249 else
5257 s = dc_parse_expr(p, 0); 5250 s = dc_parse_expr(p, 0);
5258 5251
5259 if (s || bcg.signe) s = bc_parse_reset(p, s); 5252 if (s || G.signe) s = bc_parse_reset(p, s);
5260 5253
5261 return s; 5254 return s;
5262} 5255}
@@ -6639,13 +6632,13 @@ static BcStatus bc_program_reset(BcProgram *p, BcStatus s)
6639 ip = bc_vec_top(&p->stack); 6632 ip = bc_vec_top(&p->stack);
6640 ip->idx = f->code.len; 6633 ip->idx = f->code.len;
6641 6634
6642 if (!s && bcg.signe && !bcg.tty) return BC_STATUS_QUIT; 6635 if (!s && G.signe && !G.tty) return BC_STATUS_QUIT;
6643 6636
6644 bcg.sigc += bcg.signe; 6637 G.sigc += G.signe;
6645 bcg.signe = bcg.sig != bcg.sigc; 6638 G.signe = G.sig != G.sigc;
6646 6639
6647 if (!s || s == BC_STATUS_EXEC_SIGNAL) { 6640 if (!s || s == BC_STATUS_EXEC_SIGNAL) {
6648 if (bcg.ttyin) { 6641 if (G.ttyin) {
6649 fputs(bc_program_ready_msg, stderr); 6642 fputs(bc_program_ready_msg, stderr);
6650 fflush(stderr); 6643 fflush(stderr);
6651 s = BC_STATUS_SUCCESS; 6644 s = BC_STATUS_SUCCESS;
@@ -6966,7 +6959,7 @@ static BcStatus bc_program_exec(BcProgram *p)
6966#endif // ENABLE_DC 6959#endif // ENABLE_DC
6967 } 6960 }
6968 6961
6969 if ((s && s != BC_STATUS_QUIT) || bcg.signe) s = bc_program_reset(p, s); 6962 if ((s && s != BC_STATUS_QUIT) || G.signe) s = bc_program_reset(p, s);
6970 6963
6971 // If the stack has changed, pointers may be invalid. 6964 // If the stack has changed, pointers may be invalid.
6972 ip = bc_vec_top(&p->stack); 6965 ip = bc_vec_top(&p->stack);
@@ -6981,10 +6974,10 @@ static BcStatus bc_program_exec(BcProgram *p)
6981static void bc_vm_sig(int sig) 6974static void bc_vm_sig(int sig)
6982{ 6975{
6983 int err = errno; 6976 int err = errno;
6984 size_t len = strlen(bcg.sig_msg); 6977 size_t len = strlen(G.sig_msg);
6985 if (sig == SIGINT && write(2, bcg.sig_msg, len) == (ssize_t) len) { 6978 if (sig == SIGINT && write(2, G.sig_msg, len) == (ssize_t) len) {
6986 bcg.signe = bcg.sig == bcg.sigc; 6979 G.signe = G.sig == G.sigc;
6987 bcg.sig += bcg.signe; 6980 G.sig += G.signe;
6988 } 6981 }
6989 errno = err; 6982 errno = err;
6990} 6983}
@@ -7007,14 +7000,14 @@ static BcStatus bc_vm_error(BcStatus s, const char *file, size_t line)
7007 fprintf(stderr, " %s", file); 7000 fprintf(stderr, " %s", file);
7008 fprintf(stderr, bc_err_line + 4 * !line, line); 7001 fprintf(stderr, bc_err_line + 4 * !line, line);
7009 7002
7010 return s * (!bcg.ttyin || !!strcmp(file, bc_program_stdin_name)); 7003 return s * (!G.ttyin || !!strcmp(file, bc_program_stdin_name));
7011} 7004}
7012 7005
7013#if ENABLE_BC 7006#if ENABLE_BC
7014static BcStatus bc_vm_posixError(BcStatus s, const char *file, size_t line, 7007static BcStatus bc_vm_posixError(BcStatus s, const char *file, size_t line,
7015 const char *msg) 7008 const char *msg)
7016{ 7009{
7017 int p = (int) bcg.posix, w = (int) bcg.warn; 7010 int p = (int) G_posix, w = (int) G_warn;
7018 const char *const fmt = p ? bc_err_fmt : bc_warn_fmt; 7011 const char *const fmt = p ? bc_err_fmt : bc_warn_fmt;
7019 7012
7020 if (!(p || w) || s < BC_STATUS_POSIX_NAME_LEN) return BC_STATUS_SUCCESS; 7013 if (!(p || w) || s < BC_STATUS_POSIX_NAME_LEN) return BC_STATUS_SUCCESS;
@@ -7024,18 +7017,18 @@ static BcStatus bc_vm_posixError(BcStatus s, const char *file, size_t line,
7024 fprintf(stderr, " %s", file); 7017 fprintf(stderr, " %s", file);
7025 fprintf(stderr, bc_err_line + 4 * !line, line); 7018 fprintf(stderr, bc_err_line + 4 * !line, line);
7026 7019
7027 return s * (!bcg.ttyin && !!p); 7020 return s * (!G.ttyin && !!p);
7028} 7021}
7029 7022
7030static void bc_vm_envArgs(BcVm *vm) 7023static void bc_vm_envArgs(void)
7031{ 7024{
7032 BcVec v; 7025 BcVec v;
7033 char *env_args = getenv(bc_args_env_name), *buf; 7026 char *env_args = getenv(bc_args_env_name), *buf;
7034 7027
7035 if (!env_args) return; 7028 if (!env_args) return;
7036 7029
7037 vm->env_args = xstrdup(env_args); 7030 G.env_args = xstrdup(env_args);
7038 buf = vm->env_args; 7031 buf = G.env_args;
7039 7032
7040 bc_vec_init(&v, sizeof(char *), NULL); 7033 bc_vec_init(&v, sizeof(char *), NULL);
7041 bc_vec_push(&v, &bc_args_env_name); 7034 bc_vec_push(&v, &bc_args_env_name);
@@ -7050,7 +7043,7 @@ static void bc_vm_envArgs(BcVm *vm)
7050 ++buf; 7043 ++buf;
7051 } 7044 }
7052 7045
7053 bc_args((int) v.len, (char **) v.v, &vm->flags, &vm->files); 7046 bc_args((int) v.len, (char **) v.v, &G.flags, &G.files);
7054 7047
7055 bc_vec_free(&v); 7048 bc_vec_free(&v);
7056} 7049}
@@ -7077,16 +7070,16 @@ static size_t bc_vm_envLen(const char *var)
7077 return len; 7070 return len;
7078} 7071}
7079 7072
7080static BcStatus bc_vm_process(BcVm *vm, const char *text) 7073static BcStatus bc_vm_process(const char *text)
7081{ 7074{
7082 BcStatus s = bc_parse_text(&vm->prs, text); 7075 BcStatus s = bc_parse_text(&G.prs, text);
7083 7076
7084 s = bc_vm_error(s, vm->prs.l.f, vm->prs.l.line); 7077 s = bc_vm_error(s, G.prs.l.f, G.prs.l.line);
7085 if (s) return s; 7078 if (s) return s;
7086 7079
7087 while (vm->prs.l.t.t != BC_LEX_EOF) { 7080 while (G.prs.l.t.t != BC_LEX_EOF) {
7088 7081
7089 s = vm->prs.parse(&vm->prs); 7082 s = G.prs.parse(&G.prs);
7090 7083
7091 if (s == BC_STATUS_LIMITS) { 7084 if (s == BC_STATUS_LIMITS) {
7092 7085
@@ -7105,38 +7098,38 @@ static BcStatus bc_vm_process(BcVm *vm, const char *text)
7105 } 7098 }
7106 else { 7099 else {
7107 if (s == BC_STATUS_QUIT) return s; 7100 if (s == BC_STATUS_QUIT) return s;
7108 s = bc_vm_error(s, vm->prs.l.f, vm->prs.l.line); 7101 s = bc_vm_error(s, G.prs.l.f, G.prs.l.line);
7109 if (s) return s; 7102 if (s) return s;
7110 } 7103 }
7111 } 7104 }
7112 7105
7113 if (BC_PARSE_CAN_EXEC(&vm->prs)) { 7106 if (BC_PARSE_CAN_EXEC(&G.prs)) {
7114 s = bc_program_exec(&vm->prog); 7107 s = bc_program_exec(&G.prog);
7115 if (!s && bcg.tty) fflush(stdout); 7108 if (!s && G.tty) fflush(stdout);
7116 if (s && s != BC_STATUS_QUIT) 7109 if (s && s != BC_STATUS_QUIT)
7117 s = bc_vm_error(bc_program_reset(&vm->prog, s), vm->prs.l.f, 0); 7110 s = bc_vm_error(bc_program_reset(&G.prog, s), G.prs.l.f, 0);
7118 } 7111 }
7119 7112
7120 return s; 7113 return s;
7121} 7114}
7122 7115
7123static BcStatus bc_vm_file(BcVm *vm, const char *file) 7116static BcStatus bc_vm_file(const char *file)
7124{ 7117{
7125 BcStatus s; 7118 BcStatus s;
7126 char *data; 7119 char *data;
7127 BcFunc *main_func; 7120 BcFunc *main_func;
7128 BcInstPtr *ip; 7121 BcInstPtr *ip;
7129 7122
7130 vm->prog.file = file; 7123 G.prog.file = file;
7131 s = bc_read_file(file, &data); 7124 s = bc_read_file(file, &data);
7132 if (s) return bc_vm_error(s, file, 0); 7125 if (s) return bc_vm_error(s, file, 0);
7133 7126
7134 bc_lex_file(&vm->prs.l, file); 7127 bc_lex_file(&G.prs.l, file);
7135 s = bc_vm_process(vm, data); 7128 s = bc_vm_process(data);
7136 if (s) goto err; 7129 if (s) goto err;
7137 7130
7138 main_func = bc_vec_item(&vm->prog.fns, BC_PROG_MAIN); 7131 main_func = bc_vec_item(&G.prog.fns, BC_PROG_MAIN);
7139 ip = bc_vec_item(&vm->prog.stack, 0); 7132 ip = bc_vec_item(&G.prog.stack, 0);
7140 7133
7141 if (main_func->code.len < ip->idx) s = BC_STATUS_EXEC_FILE_NOT_EXECUTABLE; 7134 if (main_func->code.len < ip->idx) s = BC_STATUS_EXEC_FILE_NOT_EXECUTABLE;
7142 7135
@@ -7145,7 +7138,7 @@ err:
7145 return s; 7138 return s;
7146} 7139}
7147 7140
7148static BcStatus bc_vm_stdin(BcVm *vm) 7141static BcStatus bc_vm_stdin(void)
7149{ 7142{
7150 BcStatus s = BC_STATUS_SUCCESS; 7143 BcStatus s = BC_STATUS_SUCCESS;
7151 BcVec buf, buffer; 7144 BcVec buf, buffer;
@@ -7153,8 +7146,8 @@ static BcStatus bc_vm_stdin(BcVm *vm)
7153 size_t len, i, str = 0; 7146 size_t len, i, str = 0;
7154 bool comment = false, notend; 7147 bool comment = false, notend;
7155 7148
7156 vm->prog.file = bc_program_stdin_name; 7149 G.prog.file = bc_program_stdin_name;
7157 bc_lex_file(&vm->prs.l, bc_program_stdin_name); 7150 bc_lex_file(&G.prs.l, bc_program_stdin_name);
7158 7151
7159 bc_vec_init(&buffer, sizeof(char), NULL); 7152 bc_vec_init(&buffer, sizeof(char), NULL);
7160 bc_vec_init(&buf, sizeof(char), NULL); 7153 bc_vec_init(&buf, sizeof(char), NULL);
@@ -7171,9 +7164,9 @@ static BcStatus bc_vm_stdin(BcVm *vm)
7171 len = buf.len - 1; 7164 len = buf.len - 1;
7172 7165
7173 if (len == 1) { 7166 if (len == 1) {
7174 if (str && buf.v[0] == vm->exe.send) 7167 if (str && buf.v[0] == G.send)
7175 str -= 1; 7168 str -= 1;
7176 else if (buf.v[0] == vm->exe.sbgn) 7169 else if (buf.v[0] == G.sbgn)
7177 str += 1; 7170 str += 1;
7178 } 7171 }
7179 else if (len > 1 || comment) { 7172 else if (len > 1 || comment) {
@@ -7184,11 +7177,11 @@ static BcStatus bc_vm_stdin(BcVm *vm)
7184 c = string[i]; 7177 c = string[i];
7185 7178
7186 if (i - 1 > len || string[i - 1] != '\\') { 7179 if (i - 1 > len || string[i - 1] != '\\') {
7187 if (vm->exe.sbgn == vm->exe.send) 7180 if (G.sbgn == G.send)
7188 str ^= c == vm->exe.sbgn; 7181 str ^= c == G.sbgn;
7189 else if (c == vm->exe.send) 7182 else if (c == G.send)
7190 str -= 1; 7183 str -= 1;
7191 else if (c == vm->exe.sbgn) 7184 else if (c == G.sbgn)
7192 str += 1; 7185 str += 1;
7193 } 7186 }
7194 7187
@@ -7207,13 +7200,13 @@ static BcStatus bc_vm_stdin(BcVm *vm)
7207 } 7200 }
7208 7201
7209 bc_vec_concat(&buffer, buf.v); 7202 bc_vec_concat(&buffer, buf.v);
7210 s = bc_vm_process(vm, buffer.v); 7203 s = bc_vm_process(buffer.v);
7211 if (s) goto err; 7204 if (s) goto err;
7212 7205
7213 bc_vec_npop(&buffer, buffer.len); 7206 bc_vec_npop(&buffer, buffer.len);
7214 } 7207 }
7215 7208
7216 if (s == BC_STATUS_BIN_FILE) s = bc_vm_error(s, vm->prs.l.f, 0); 7209 if (s == BC_STATUS_BIN_FILE) s = bc_vm_error(s, G.prs.l.f, 0);
7217 7210
7218 // INPUT_EOF will always happen when stdin is 7211 // INPUT_EOF will always happen when stdin is
7219 // closed. It's not a problem in that case. 7212 // closed. It's not a problem in that case.
@@ -7221,11 +7214,11 @@ static BcStatus bc_vm_stdin(BcVm *vm)
7221 s = BC_STATUS_SUCCESS; 7214 s = BC_STATUS_SUCCESS;
7222 7215
7223 if (str) 7216 if (str)
7224 s = bc_vm_error(BC_STATUS_LEX_NO_STRING_END, vm->prs.l.f, 7217 s = bc_vm_error(BC_STATUS_LEX_NO_STRING_END, G.prs.l.f,
7225 vm->prs.l.line); 7218 G.prs.l.line);
7226 else if (comment) 7219 else if (comment)
7227 s = bc_vm_error(BC_STATUS_LEX_NO_COMMENT_END, vm->prs.l.f, 7220 s = bc_vm_error(BC_STATUS_LEX_NO_COMMENT_END, G.prs.l.f,
7228 vm->prs.l.line); 7221 G.prs.l.line);
7229 7222
7230err: 7223err:
7231 bc_vec_free(&buf); 7224 bc_vec_free(&buf);
@@ -7233,46 +7226,46 @@ err:
7233 return s; 7226 return s;
7234} 7227}
7235 7228
7236static BcStatus bc_vm_exec(BcVm *vm) 7229static BcStatus bc_vm_exec(void)
7237{ 7230{
7238 BcStatus s = BC_STATUS_SUCCESS; 7231 BcStatus s = BC_STATUS_SUCCESS;
7239 size_t i; 7232 size_t i;
7240 7233
7241#if ENABLE_BC 7234#if ENABLE_BC
7242 if (vm->flags & BC_FLAG_L) { 7235 if (G.flags & BC_FLAG_L) {
7243 7236
7244 bc_lex_file(&vm->prs.l, bc_lib_name); 7237 bc_lex_file(&G.prs.l, bc_lib_name);
7245 s = bc_parse_text(&vm->prs, bc_lib); 7238 s = bc_parse_text(&G.prs, bc_lib);
7246 7239
7247 while (!s && vm->prs.l.t.t != BC_LEX_EOF) s = vm->prs.parse(&vm->prs); 7240 while (!s && G.prs.l.t.t != BC_LEX_EOF) s = G.prs.parse(&G.prs);
7248 7241
7249 if (s) return s; 7242 if (s) return s;
7250 s = bc_program_exec(&vm->prog); 7243 s = bc_program_exec(&G.prog);
7251 if (s) return s; 7244 if (s) return s;
7252 } 7245 }
7253#endif 7246#endif
7254 7247
7255 for (i = 0; !s && i < vm->files.len; ++i) 7248 for (i = 0; !s && i < G.files.len; ++i)
7256 s = bc_vm_file(vm, *((char **) bc_vec_item(&vm->files, i))); 7249 s = bc_vm_file(*((char **) bc_vec_item(&G.files, i)));
7257 if (s && s != BC_STATUS_QUIT) return s; 7250 if (s && s != BC_STATUS_QUIT) return s;
7258 7251
7259 if (IS_BC || !vm->files.len) s = bc_vm_stdin(vm); 7252 if (IS_BC || !G.files.len) s = bc_vm_stdin();
7260 if (!s && !BC_PARSE_CAN_EXEC(&vm->prs)) s = bc_vm_process(vm, ""); 7253 if (!s && !BC_PARSE_CAN_EXEC(&G.prs)) s = bc_vm_process("");
7261 7254
7262 if (s == BC_STATUS_QUIT) 7255 if (s == BC_STATUS_QUIT)
7263 s = BC_STATUS_SUCCESS; 7256 s = BC_STATUS_SUCCESS;
7264 return s; 7257 return s;
7265} 7258}
7266 7259
7267static void bc_vm_free(BcVm *vm) 7260static void bc_vm_free(void)
7268{ 7261{
7269 bc_vec_free(&vm->files); 7262 bc_vec_free(&G.files);
7270 bc_program_free(&vm->prog); 7263 bc_program_free(&G.prog);
7271 bc_parse_free(&vm->prs); 7264 bc_parse_free(&G.prs);
7272 free(vm->env_args); 7265 free(G.env_args);
7273} 7266}
7274 7267
7275static void bc_vm_init(BcVm *vm, BcVmExe exe, const char *env_len) 7268static void bc_vm_init(const char *env_len)
7276{ 7269{
7277 size_t len = bc_vm_envLen(env_len); 7270 size_t len = bc_vm_envLen(env_len);
7278#if ENABLE_FEATURE_BC_SIGNALS 7271#if ENABLE_FEATURE_BC_SIGNALS
@@ -7284,47 +7277,32 @@ static void bc_vm_init(BcVm *vm, BcVmExe exe, const char *env_len)
7284 sigaction(SIGINT, &sa, NULL); 7277 sigaction(SIGINT, &sa, NULL);
7285#endif 7278#endif
7286 7279
7287 memset(vm, 0, sizeof(BcVm)); 7280 bc_vec_init(&G.files, sizeof(char *), NULL);
7288
7289 vm->exe = exe;
7290 vm->flags = 0;
7291 vm->env_args = NULL;
7292
7293 bc_vec_init(&vm->files, sizeof(char *), NULL);
7294 7281
7295#if ENABLE_BC 7282#if ENABLE_BC
7296 vm->flags |= BC_FLAG_S * IS_BC * (getenv("POSIXLY_CORRECT") != NULL); 7283 G.flags |= BC_FLAG_S * IS_BC * (getenv("POSIXLY_CORRECT") != NULL);
7297 if (IS_BC) bc_vm_envArgs(vm); 7284 if (IS_BC) bc_vm_envArgs();
7298#endif 7285#endif
7299 7286
7300 bc_program_init(&vm->prog, len, exe.init, exe.exp); 7287 bc_program_init(&G.prog, len, G.init, G.exp);
7301 exe.init(&vm->prs, &vm->prog, BC_PROG_MAIN); 7288 G.init(&G.prs, &G.prog, BC_PROG_MAIN);
7302} 7289}
7303 7290
7304static BcStatus bc_vm_run(int argc, char *argv[], BcVmExe exe, 7291static BcStatus bc_vm_run(int argc, char *argv[],
7305 const char *env_len) 7292 const char *env_len)
7306{ 7293{
7307 BcStatus st; 7294 BcStatus st;
7308 BcVm vm;
7309 7295
7310 bc_vm_init(&vm, exe, env_len); 7296 bc_vm_init(env_len);
7311 bc_args(argc, argv, &vm.flags, &vm.files); 7297 bc_args(argc, argv, &G.flags, &G.files);
7312 7298
7313 bcg.ttyin = isatty(0); 7299 G.ttyin = isatty(0);
7314 bcg.tty = bcg.ttyin || (vm.flags & BC_FLAG_I) || isatty(1); 7300 G.tty = G.ttyin || (G.flags & BC_FLAG_I) || isatty(1);
7315 7301
7316#if ENABLE_BC 7302 if (G.ttyin && !(G.flags & BC_FLAG_Q)) bc_vm_info();
7317 bcg.posix = vm.flags & BC_FLAG_S; 7303 st = bc_vm_exec();
7318 bcg.warn = vm.flags & BC_FLAG_W;
7319#endif
7320#if ENABLE_DC
7321 bcg.exreg = vm.flags & BC_FLAG_X;
7322#endif
7323 7304
7324 if (bcg.ttyin && !(vm.flags & BC_FLAG_Q)) bc_vm_info(); 7305 bc_vm_free();
7325 st = bc_vm_exec(&vm);
7326
7327 bc_vm_free(&vm);
7328 return st; 7306 return st;
7329} 7307}
7330 7308
@@ -7332,17 +7310,15 @@ static BcStatus bc_vm_run(int argc, char *argv[], BcVmExe exe,
7332int bc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 7310int bc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
7333int bc_main(int argc, char **argv) 7311int bc_main(int argc, char **argv)
7334{ 7312{
7335 BcVmExe exec; 7313 INIT_G();
7336
7337# if ENABLE_FEATURE_BC_SIGNALS 7314# if ENABLE_FEATURE_BC_SIGNALS
7338 bcg.sig_msg = "\ninterrupt (type \"quit\" to exit)\n"; 7315 G.sig_msg = "\ninterrupt (type \"quit\" to exit)\n";
7339# endif 7316# endif
7317 G.init = bc_parse_init;
7318 G.exp = bc_parse_expression;
7319 G.sbgn = G.send = '"';
7340 7320
7341 exec.init = bc_parse_init; 7321 return bc_vm_run(argc, argv, "BC_LINE_LENGTH");
7342 exec.exp = bc_parse_expression;
7343 exec.sbgn = exec.send = '"';
7344
7345 return bc_vm_run(argc, argv, exec, "BC_LINE_LENGTH");
7346} 7322}
7347#endif 7323#endif
7348 7324
@@ -7350,17 +7326,15 @@ int bc_main(int argc, char **argv)
7350int dc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 7326int dc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
7351int dc_main(int argc, char **argv) 7327int dc_main(int argc, char **argv)
7352{ 7328{
7353 BcVmExe exec; 7329 INIT_G();
7354
7355# if ENABLE_FEATURE_BC_SIGNALS 7330# if ENABLE_FEATURE_BC_SIGNALS
7356 bcg.sig_msg = "\ninterrupt (type \"q\" to exit)\n"; 7331 G.sig_msg = "\ninterrupt (type \"q\" to exit)\n";
7357# endif 7332# endif
7333 G.init = dc_parse_init;
7334 G.exp = dc_parse_expr;
7335 G.sbgn = '[';
7336 G.send = ']';
7358 7337
7359 exec.init = dc_parse_init; 7338 return bc_vm_run(argc, argv, "DC_LINE_LENGTH");
7360 exec.exp = dc_parse_expr;
7361 exec.sbgn = '[';
7362 exec.send = ']';
7363
7364 return bc_vm_run(argc, argv, exec, "DC_LINE_LENGTH");
7365} 7339}
7366#endif 7340#endif