X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=miscutils%2Fbc.c;h=0200afca27d8ccec79176351c1e955756666f796;hb=4c9455f967e21d30db0de2e13b6e1115ab8f36ce;hp=40430d4113ab0da587b30eded78b675442bd4f09;hpb=e55a5726001ce23161c4bd0010b842578e7b722c;p=oweals%2Fbusybox.git diff --git a/miscutils/bc.c b/miscutils/bc.c index 40430d411..0200afca2 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c @@ -508,34 +508,35 @@ typedef enum BcLexType { struct BcLexKeyword { char name8[8]; }; -#define BC_LEX_KW_ENTRY(a, b, c) \ - { .name8 = a /*, .len = b, .posix = c*/ } +#define BC_LEX_KW_ENTRY(a, b) \ + { .name8 = a /*, .posix = b */ } static const struct BcLexKeyword bc_lex_kws[20] = { - BC_LEX_KW_ENTRY("auto" , 4, 1), // 0 - BC_LEX_KW_ENTRY("break" , 5, 1), // 1 - BC_LEX_KW_ENTRY("continue", 8, 0), // 2 note: this one has no terminating NUL - BC_LEX_KW_ENTRY("define" , 6, 1), // 3 - - BC_LEX_KW_ENTRY("else" , 4, 0), // 4 - BC_LEX_KW_ENTRY("for" , 3, 1), // 5 - BC_LEX_KW_ENTRY("halt" , 4, 0), // 6 - BC_LEX_KW_ENTRY("ibase" , 5, 1), // 7 - - BC_LEX_KW_ENTRY("if" , 2, 1), // 8 - BC_LEX_KW_ENTRY("last" , 4, 0), // 9 - BC_LEX_KW_ENTRY("length" , 6, 1), // 10 - BC_LEX_KW_ENTRY("limits" , 6, 0), // 11 - - BC_LEX_KW_ENTRY("obase" , 5, 1), // 12 - BC_LEX_KW_ENTRY("print" , 5, 0), // 13 - BC_LEX_KW_ENTRY("quit" , 4, 1), // 14 - BC_LEX_KW_ENTRY("read" , 4, 0), // 15 - - BC_LEX_KW_ENTRY("return" , 6, 1), // 16 - BC_LEX_KW_ENTRY("scale" , 5, 1), // 17 - BC_LEX_KW_ENTRY("sqrt" , 4, 1), // 18 - BC_LEX_KW_ENTRY("while" , 5, 1), // 19 + BC_LEX_KW_ENTRY("auto" , 1), // 0 + BC_LEX_KW_ENTRY("break" , 1), // 1 + BC_LEX_KW_ENTRY("continue", 0), // 2 note: this one has no terminating NUL + BC_LEX_KW_ENTRY("define" , 1), // 3 + + BC_LEX_KW_ENTRY("else" , 0), // 4 + BC_LEX_KW_ENTRY("for" , 1), // 5 + BC_LEX_KW_ENTRY("halt" , 0), // 6 + BC_LEX_KW_ENTRY("ibase" , 1), // 7 + + BC_LEX_KW_ENTRY("if" , 1), // 8 + BC_LEX_KW_ENTRY("last" , 0), // 9 + BC_LEX_KW_ENTRY("length" , 1), // 10 + BC_LEX_KW_ENTRY("limits" , 0), // 11 + + BC_LEX_KW_ENTRY("obase" , 1), // 12 + BC_LEX_KW_ENTRY("print" , 0), // 13 + BC_LEX_KW_ENTRY("quit" , 1), // 14 + BC_LEX_KW_ENTRY("read" , 0), // 15 + + BC_LEX_KW_ENTRY("return" , 1), // 16 + BC_LEX_KW_ENTRY("scale" , 1), // 17 + BC_LEX_KW_ENTRY("sqrt" , 1), // 18 + BC_LEX_KW_ENTRY("while" , 1), // 19 }; +#undef BC_LEX_KW_ENTRY enum { POSIX_KWORD_MASK = 0 | (1 << 0) @@ -563,6 +564,7 @@ enum { | (1 << 18) | (1 << 19) }; +#define bc_lex_kws_POSIX(i) ((1 << (i)) & POSIX_KWORD_MASK) #endif struct BcLex; @@ -716,9 +718,6 @@ typedef struct BcProgram { typedef unsigned long (*BcProgramBuiltIn)(BcNum *); -static void bc_program_addFunc(char *name, size_t *idx); -static void bc_program_reset(void); - #define BC_FLAG_X (1 << 0) #define BC_FLAG_W (1 << 1) #define BC_FLAG_V (1 << 2) @@ -1070,8 +1069,12 @@ static void bc_vec_expand(BcVec *v, size_t req) } } -#define bc_vec_pop(v) (bc_vec_npop((v), 1)) -#define bc_vec_top(v) (bc_vec_item_rev((v), 0)) +static void bc_vec_pop(BcVec *v) +{ + v->len--; + if (v->dtor) + v->dtor(v->v + (v->size * v->len)); +} static void bc_vec_npop(BcVec *v, size_t n) { @@ -1095,8 +1098,6 @@ static void bc_vec_push(BcVec *v, const void *data) v->len += 1; } -#define bc_parse_push(p, i) bc_vec_pushByte(&(p)->func->code, (char) (i)) - static void bc_vec_pushByte(BcVec *v, char data) { bc_vec_push(v, &data); @@ -1160,6 +1161,11 @@ static void *bc_vec_item_rev(const BcVec *v, size_t idx) return v->v + v->size * (v->len - idx - 1); } +static void *bc_vec_top(const BcVec *v) +{ + return v->v + v->size * (v->len - 1); +} + static void bc_vec_free(void *vec) { BcVec *v = (BcVec *) vec; @@ -1316,7 +1322,8 @@ static char* bc_read_file(const char *path) size_t size = ((size_t) -1); size_t i; - buf = xmalloc_open_read_close(path, &size); + // Never returns NULL (dies on errors) + buf = xmalloc_xopen_read_close(path, &size); for (i = 0; i < size; ++i) { char c = buf[i]; @@ -2985,7 +2992,7 @@ static BcStatus bc_lex_identifier(BcLex *l) match: // buf starts with keyword bc_lex_kws[i] l->t.t = BC_LEX_KEY_1st_keyword + i; - if (!((1 << i) & POSIX_KWORD_MASK)) { + if (!bc_lex_kws_POSIX(i)) { s = bc_posix_error_fmt("%sthe '%.8s' keyword", "POSIX does not allow ", bc_lex_kws[i].name8); if (s) return s; } @@ -3523,12 +3530,16 @@ static BcStatus dc_lex_token(BcLex *l) } #endif // ENABLE_DC +static void bc_program_addFunc(char *name, size_t *idx); + static void bc_parse_addFunc(BcParse *p, char *name, size_t *idx) { bc_program_addFunc(name, idx); p->func = bc_vec_item(&G.prog.fns, p->fidx); } +#define bc_parse_push(p, i) bc_vec_pushByte(&(p)->func->code, (char) (i)) + static void bc_parse_pushName(BcParse *p, char *name) { size_t i = 0, len = strlen(name); @@ -3583,6 +3594,21 @@ static BcStatus bc_parse_text(BcParse *p, const char *text) return bc_lex_text(&p->l, text); } +// Called when parsing or execution detects a failure, +// resets execution structures. +static void bc_program_reset(void) +{ + BcFunc *f; + BcInstPtr *ip; + + bc_vec_npop(&G.prog.stack, G.prog.stack.len - 1); + bc_vec_pop_all(&G.prog.results); + + f = bc_vec_item(&G.prog.fns, 0); + ip = bc_vec_top(&G.prog.stack); + ip->idx = f->code.len; +} + #define bc_parse_updateFunc(p, f) \ ((p)->func = bc_vec_item(&G.prog.fns, ((p)->fidx = (f)))) @@ -6548,24 +6574,6 @@ static void bc_program_addFunc(char *name, size_t *idx) } } -// Called when parsing or execution detects a failure, -// resets execution structures. -static void bc_program_reset(void) -{ - BcFunc *f; - BcInstPtr *ip; - - bc_vec_npop(&G.prog.stack, G.prog.stack.len - 1); - bc_vec_pop_all(&G.prog.results); - - f = bc_vec_item(&G.prog.fns, 0); - ip = bc_vec_top(&G.prog.stack); - ip->idx = f->code.len; - - // If !tty, no need to check for ^C: we don't have ^C handler, - // we would be killed by a signal and won't reach this place -} - static BcStatus bc_program_exec(void) { BcStatus s = BC_STATUS_SUCCESS;