diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-04 20:51:40 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-05 15:43:35 +0100 |
commit | 9b70f197b4dd5be47c5d0d4479525efe012964ee (patch) | |
tree | 0a5c20c6b57ffb60f81cfbff511755353035dfde | |
parent | 60cf747b6c234958387298068da658cfee9c42cb (diff) | |
download | busybox-w32-9b70f197b4dd5be47c5d0d4479525efe012964ee.tar.gz busybox-w32-9b70f197b4dd5be47c5d0d4479525efe012964ee.tar.bz2 busybox-w32-9b70f197b4dd5be47c5d0d4479525efe012964ee.zip |
bc: convert all status codes, remove bc_err_msgs[], bc_vm_error(), bc_vm_posixError()
function old new delta
bc_posix_error - 65 +65
bc_vm_run 1995 2039 +44
bc_err_line 7 - -7
bc_num_ulong 103 93 -10
bc_parse_parse 495 483 -12
bc_err_fmt 12 - -12
bc_warn_fmt 14 - -14
bc_parse_expr 2210 2194 -16
bc_program_reset 105 78 -27
bc_vm_process 130 94 -36
bc_parse_stmt 2313 2277 -36
bc_err_msgs 60 - -60
bc_lex_token 1367 1282 -85
bc_vm_error 143 - -143
bc_vm_posixError 189 - -189
------------------------------------------------------------------------------
(add/remove: 1/6 grow/shrink: 1/7 up/down: 109/-647) Total: -538 bytes
text data bss dec hex filename
988258 485 7296 996039 f32c7 busybox_old
987717 485 7296 995498 f30aa busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | miscutils/bc.c | 267 |
1 files changed, 52 insertions, 215 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index 7b20a94cc..bc5501d91 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -171,141 +171,7 @@ typedef enum BcStatus { | |||
171 | BC_STATUS_SUCCESS = 0, | 171 | BC_STATUS_SUCCESS = 0, |
172 | BC_STATUS_FAILURE = 1, | 172 | BC_STATUS_FAILURE = 1, |
173 | BC_STATUS_PARSE_EMPTY_EXP = 2, // bc_parse_expr() uses this | 173 | BC_STATUS_PARSE_EMPTY_EXP = 2, // bc_parse_expr() uses this |
174 | |||
175 | // BC_STATUS_ALLOC_ERR, | ||
176 | // BC_STATUS_INPUT_EOF, | ||
177 | // BC_STATUS_BIN_FILE, | ||
178 | // BC_STATUS_PATH_IS_DIR, | ||
179 | |||
180 | // BC_STATUS_LEX_BAD_CHAR, | ||
181 | // BC_STATUS_LEX_NO_STRING_END, | ||
182 | // BC_STATUS_LEX_NO_COMMENT_END, | ||
183 | // BC_STATUS_LEX_EOF, | ||
184 | #if ENABLE_DC | ||
185 | // BC_STATUS_LEX_EXTENDED_REG, | ||
186 | #endif | ||
187 | // BC_STATUS_PARSE_BAD_TOKEN, | ||
188 | // BC_STATUS_PARSE_BAD_EXP, | ||
189 | // BC_STATUS_PARSE_BAD_PRINT, | ||
190 | // BC_STATUS_PARSE_BAD_FUNC, | ||
191 | // BC_STATUS_PARSE_BAD_ASSIGN, | ||
192 | // BC_STATUS_PARSE_NO_AUTO, | ||
193 | // BC_STATUS_PARSE_DUPLICATE_LOCAL, | ||
194 | // BC_STATUS_PARSE_NO_BLOCK_END, | ||
195 | |||
196 | // BC_STATUS_MATH_NEGATIVE, | ||
197 | // BC_STATUS_MATH_NON_INTEGER, | ||
198 | // BC_STATUS_MATH_OVERFLOW, | ||
199 | // BC_STATUS_MATH_DIVIDE_BY_ZERO, | ||
200 | // BC_STATUS_MATH_BAD_STRING, | ||
201 | |||
202 | // BC_STATUS_EXEC_FILE_ERR, | ||
203 | // BC_STATUS_EXEC_MISMATCHED_PARAMS, | ||
204 | // BC_STATUS_EXEC_UNDEFINED_FUNC, | ||
205 | // BC_STATUS_EXEC_FILE_NOT_EXECUTABLE, | ||
206 | // BC_STATUS_EXEC_NUM_LEN, | ||
207 | // BC_STATUS_EXEC_NAME_LEN, | ||
208 | // BC_STATUS_EXEC_STRING_LEN, | ||
209 | // BC_STATUS_EXEC_ARRAY_LEN, | ||
210 | // BC_STATUS_EXEC_BAD_IBASE, | ||
211 | // BC_STATUS_EXEC_BAD_SCALE, | ||
212 | // BC_STATUS_EXEC_BAD_READ_EXPR, | ||
213 | // BC_STATUS_EXEC_REC_READ, | ||
214 | // BC_STATUS_EXEC_BAD_TYPE, | ||
215 | // BC_STATUS_EXEC_BAD_OBASE, | ||
216 | // BC_STATUS_EXEC_SIGNAL, | ||
217 | // BC_STATUS_EXEC_STACK, | ||
218 | |||
219 | // BC_STATUS_VEC_OUT_OF_BOUNDS, | ||
220 | // BC_STATUS_VEC_ITEM_EXISTS, | ||
221 | BC_STATUS_BEFORE_POSIX = BC_STATUS_PARSE_EMPTY_EXP, | ||
222 | #if ENABLE_BC | ||
223 | BC_STATUS_POSIX_NAME_LEN, | ||
224 | BC_STATUS_POSIX_COMMENT, | ||
225 | BC_STATUS_POSIX_BAD_KW, | ||
226 | BC_STATUS_POSIX_DOT, | ||
227 | BC_STATUS_POSIX_RET, | ||
228 | BC_STATUS_POSIX_BOOL, | ||
229 | BC_STATUS_POSIX_REL_POS, | ||
230 | BC_STATUS_POSIX_MULTIREL, | ||
231 | BC_STATUS_POSIX_FOR1, | ||
232 | BC_STATUS_POSIX_FOR2, | ||
233 | BC_STATUS_POSIX_FOR3, | ||
234 | BC_STATUS_POSIX_BRACE, | ||
235 | #endif | ||
236 | // BC_STATUS_QUIT, | ||
237 | // BC_STATUS_LIMITS, | ||
238 | |||
239 | // BC_STATUS_INVALID_OPTION, | ||
240 | } BcStatus; | 174 | } BcStatus; |
241 | // Keep enum above and messages below in sync! | ||
242 | static const char *const bc_err_msgs[] = { | ||
243 | NULL, | ||
244 | NULL, | ||
245 | NULL, | ||
246 | |||
247 | // "memory allocation error", | ||
248 | // "I/O error", | ||
249 | // "file is not text:", | ||
250 | // "path is a directory:", | ||
251 | |||
252 | // "bad character", | ||
253 | // "string end could not be found", | ||
254 | // "comment end could not be found", | ||
255 | // "end of file", | ||
256 | #if ENABLE_DC | ||
257 | // "extended register", | ||
258 | #endif | ||
259 | // "bad token", | ||
260 | // "bad expression", | ||
261 | // "bad print statement", | ||
262 | // "bad function definition", | ||
263 | // "bad assignment: left side must be scale, ibase, " | ||
264 | // "obase, last, var, or array element", | ||
265 | // "no auto variable found", | ||
266 | // "function parameter or auto var has the same name as another", | ||
267 | // "block end could not be found", | ||
268 | |||
269 | // "negative number", | ||
270 | // "non integer number", | ||
271 | // "overflow", | ||
272 | // "divide by zero", | ||
273 | // "bad number string", | ||
274 | |||
275 | // "could not open file:", | ||
276 | // "mismatched parameters", // wrong number of them, to be exact | ||
277 | // "undefined function", | ||
278 | // "file is not executable:", | ||
279 | // "number too long: must be [1, BC_NUM_MAX]", | ||
280 | // "name too long: must be [1, BC_NAME_MAX]", | ||
281 | // "string too long: must be [1, BC_STRING_MAX]", | ||
282 | // "array too long; must be [1, BC_DIM_MAX]", | ||
283 | // "bad ibase; must be [2, 16]", | ||
284 | // "bad scale; must be [0, BC_SCALE_MAX]", | ||
285 | // "bad read() expression", | ||
286 | // "read() call inside of a read() call", | ||
287 | // "variable is wrong type", | ||
288 | // "bad obase; must be [2, BC_BASE_MAX]", | ||
289 | // "signal caught and not handled", | ||
290 | // "stack has too few elements", | ||
291 | |||
292 | // "index is out of bounds", | ||
293 | // "item already exists", | ||
294 | #if ENABLE_BC | ||
295 | "POSIX only allows one character names; the following is bad:", | ||
296 | "POSIX does not allow '#' script comments", | ||
297 | "POSIX does not allow the following keyword:", | ||
298 | "POSIX does not allow a period ('.') as a shortcut for the last result", | ||
299 | "POSIX requires parentheses around return expressions", | ||
300 | "POSIX does not allow boolean operators; the following is bad:", | ||
301 | "POSIX does not allow comparison operators outside if or loops", | ||
302 | "POSIX requires exactly one comparison operator per condition", | ||
303 | "POSIX does not allow an empty init expression in a for loop", | ||
304 | "POSIX does not allow an empty condition expression in a for loop", | ||
305 | "POSIX does not allow an empty update expression in a for loop", | ||
306 | "POSIX requires the left brace be on the same line as the function header", | ||
307 | #endif | ||
308 | }; | ||
309 | 175 | ||
310 | #define BC_VEC_INVALID_IDX ((size_t) -1) | 176 | #define BC_VEC_INVALID_IDX ((size_t) -1) |
311 | #define BC_VEC_START_CAP (1 << 5) | 177 | #define BC_VEC_START_CAP (1 << 5) |
@@ -891,17 +757,8 @@ struct globals { | |||
891 | 757 | ||
892 | #define IS_BC (ENABLE_BC && (!ENABLE_DC || applet_name[0] == 'b')) | 758 | #define IS_BC (ENABLE_BC && (!ENABLE_DC || applet_name[0] == 'b')) |
893 | 759 | ||
894 | #if ENABLE_BC | ||
895 | static BcStatus bc_vm_posixError(BcStatus s, const char *file, size_t line, | ||
896 | const char *msg); | ||
897 | #endif | ||
898 | |||
899 | static void bc_vm_info(void); | 760 | static void bc_vm_info(void); |
900 | 761 | ||
901 | static const char bc_err_fmt[] = "\nerror: %s\n"; | ||
902 | static const char bc_warn_fmt[] = "\nwarning: %s\n"; | ||
903 | static const char bc_err_line[] = ":%zu\n\n"; | ||
904 | |||
905 | #if ENABLE_BC | 762 | #if ENABLE_BC |
906 | static const BcLexKeyword bc_lex_kws[20] = { | 763 | static const BcLexKeyword bc_lex_kws[20] = { |
907 | BC_LEX_KW_ENTRY("auto", 4, true), | 764 | BC_LEX_KW_ENTRY("auto", 4, true), |
@@ -1151,6 +1008,25 @@ static int bc_error(const char *fmt, ...) | |||
1151 | return BC_STATUS_FAILURE; | 1008 | return BC_STATUS_FAILURE; |
1152 | } | 1009 | } |
1153 | 1010 | ||
1011 | static int bc_posix_error(const char *fmt, ...) | ||
1012 | { | ||
1013 | va_list p; | ||
1014 | |||
1015 | if (!(G.flags & (BC_FLAG_S|BC_FLAG_W))) | ||
1016 | return BC_STATUS_SUCCESS; | ||
1017 | |||
1018 | va_start(p, fmt); | ||
1019 | bb_verror_msg(fmt, p, NULL); | ||
1020 | va_end(p); | ||
1021 | |||
1022 | // Do we treat non-POSIX constructs as errors? | ||
1023 | if (!(G.flags & BC_FLAG_S)) | ||
1024 | return BC_STATUS_SUCCESS; // no, it's a warning | ||
1025 | if (!G.ttyin) | ||
1026 | exit(1); | ||
1027 | return BC_STATUS_FAILURE; | ||
1028 | } | ||
1029 | |||
1154 | static void bc_vec_grow(BcVec *v, size_t n) | 1030 | static void bc_vec_grow(BcVec *v, size_t n) |
1155 | { | 1031 | { |
1156 | size_t cap = v->cap * 2; | 1032 | size_t cap = v->cap * 2; |
@@ -3039,8 +2915,7 @@ static BcStatus bc_lex_identifier(BcLex *l) | |||
3039 | l->t.t = BC_LEX_KEY_AUTO + (BcLexType) i; | 2915 | l->t.t = BC_LEX_KEY_AUTO + (BcLexType) i; |
3040 | 2916 | ||
3041 | if (!bc_lex_kws[i].posix) { | 2917 | if (!bc_lex_kws[i].posix) { |
3042 | s = bc_vm_posixError(BC_STATUS_POSIX_BAD_KW, l->f, l->line, | 2918 | s = bc_posix_error("POSIX does not allow the following keyword:"); // bc_lex_kws[i].name |
3043 | bc_lex_kws[i].name); | ||
3044 | if (s) return s; | 2919 | if (s) return s; |
3045 | } | 2920 | } |
3046 | 2921 | ||
@@ -3054,7 +2929,7 @@ static BcStatus bc_lex_identifier(BcLex *l) | |||
3054 | if (s) return s; | 2929 | if (s) return s; |
3055 | 2930 | ||
3056 | if (l->t.v.len - 1 > 1) | 2931 | if (l->t.v.len - 1 > 1) |
3057 | s = bc_vm_posixError(BC_STATUS_POSIX_NAME_LEN, l->f, l->line, buf); | 2932 | s = bc_posix_error("POSIX only allows one character names; the following is bad:"); // buf |
3058 | 2933 | ||
3059 | return s; | 2934 | return s; |
3060 | } | 2935 | } |
@@ -3155,7 +3030,7 @@ static BcStatus bc_lex_token(BcLex *l) | |||
3155 | bc_lex_assign(l, BC_LEX_OP_REL_NE, BC_LEX_OP_BOOL_NOT); | 3030 | bc_lex_assign(l, BC_LEX_OP_REL_NE, BC_LEX_OP_BOOL_NOT); |
3156 | 3031 | ||
3157 | if (l->t.t == BC_LEX_OP_BOOL_NOT) { | 3032 | if (l->t.t == BC_LEX_OP_BOOL_NOT) { |
3158 | s = bc_vm_posixError(BC_STATUS_POSIX_BOOL, l->f, l->line, "!"); | 3033 | s = bc_posix_error("POSIX does not allow boolean operators; the following is bad:"); // "!" |
3159 | if (s) return s; | 3034 | if (s) return s; |
3160 | } | 3035 | } |
3161 | 3036 | ||
@@ -3170,7 +3045,7 @@ static BcStatus bc_lex_token(BcLex *l) | |||
3170 | 3045 | ||
3171 | case '#': | 3046 | case '#': |
3172 | { | 3047 | { |
3173 | s = bc_vm_posixError(BC_STATUS_POSIX_COMMENT, l->f, l->line, NULL); | 3048 | s = bc_posix_error("POSIX does not allow '#' script comments"); |
3174 | if (s) return s; | 3049 | if (s) return s; |
3175 | 3050 | ||
3176 | bc_lex_lineComment(l); | 3051 | bc_lex_lineComment(l); |
@@ -3189,7 +3064,7 @@ static BcStatus bc_lex_token(BcLex *l) | |||
3189 | c2 = l->buf[l->i]; | 3064 | c2 = l->buf[l->i]; |
3190 | if (c2 == '&') { | 3065 | if (c2 == '&') { |
3191 | 3066 | ||
3192 | s = bc_vm_posixError(BC_STATUS_POSIX_BOOL, l->f, l->line, "&&"); | 3067 | s = bc_posix_error("POSIX does not allow boolean operators; the following is bad:"); // "&&" |
3193 | if (s) return s; | 3068 | if (s) return s; |
3194 | 3069 | ||
3195 | ++l->i; | 3070 | ++l->i; |
@@ -3252,7 +3127,7 @@ static BcStatus bc_lex_token(BcLex *l) | |||
3252 | s = bc_lex_number(l, c); | 3127 | s = bc_lex_number(l, c); |
3253 | else { | 3128 | else { |
3254 | l->t.t = BC_LEX_KEY_LAST; | 3129 | l->t.t = BC_LEX_KEY_LAST; |
3255 | s = bc_vm_posixError(BC_STATUS_POSIX_DOT, l->f, l->line, NULL); | 3130 | s = bc_posix_error("POSIX does not allow a period ('.') as a shortcut for the last result"); |
3256 | } | 3131 | } |
3257 | break; | 3132 | break; |
3258 | } | 3133 | } |
@@ -3379,8 +3254,7 @@ static BcStatus bc_lex_token(BcLex *l) | |||
3379 | c2 = l->buf[l->i]; | 3254 | c2 = l->buf[l->i]; |
3380 | 3255 | ||
3381 | if (c2 == '|') { | 3256 | if (c2 == '|') { |
3382 | 3257 | s = bc_posix_error("POSIX does not allow boolean operators; the following is bad:"); // "||" | |
3383 | s = bc_vm_posixError(BC_STATUS_POSIX_BOOL, l->f, l->line, "||"); | ||
3384 | if (s) return s; | 3258 | if (s) return s; |
3385 | 3259 | ||
3386 | ++l->i; | 3260 | ++l->i; |
@@ -4106,7 +3980,7 @@ static BcStatus bc_parse_return(BcParse *p) | |||
4106 | } | 3980 | } |
4107 | 3981 | ||
4108 | if (!paren || p->l.t.last != BC_LEX_RPAREN) { | 3982 | if (!paren || p->l.t.last != BC_LEX_RPAREN) { |
4109 | s = bc_vm_posixError(BC_STATUS_POSIX_RET, p->l.f, p->l.line, NULL); | 3983 | s = bc_posix_error("POSIX requires parentheses around return expressions"); |
4110 | if (s) return s; | 3984 | if (s) return s; |
4111 | } | 3985 | } |
4112 | 3986 | ||
@@ -4313,7 +4187,7 @@ static BcStatus bc_parse_for(BcParse *p) | |||
4313 | if (p->l.t.t != BC_LEX_SCOLON) | 4187 | if (p->l.t.t != BC_LEX_SCOLON) |
4314 | s = bc_parse_expr(p, 0, bc_parse_next_for); | 4188 | s = bc_parse_expr(p, 0, bc_parse_next_for); |
4315 | else | 4189 | else |
4316 | s = bc_vm_posixError(BC_STATUS_POSIX_FOR1, p->l.f, p->l.line, NULL); | 4190 | s = bc_posix_error("POSIX does not allow an empty init expression in a for loop"); |
4317 | 4191 | ||
4318 | if (s) return s; | 4192 | if (s) return s; |
4319 | if (p->l.t.t != BC_LEX_SCOLON) return bc_error("bad token"); | 4193 | if (p->l.t.t != BC_LEX_SCOLON) return bc_error("bad token"); |
@@ -4330,7 +4204,7 @@ static BcStatus bc_parse_for(BcParse *p) | |||
4330 | if (p->l.t.t != BC_LEX_SCOLON) | 4204 | if (p->l.t.t != BC_LEX_SCOLON) |
4331 | s = bc_parse_expr(p, BC_PARSE_REL, bc_parse_next_for); | 4205 | s = bc_parse_expr(p, BC_PARSE_REL, bc_parse_next_for); |
4332 | else | 4206 | else |
4333 | s = bc_vm_posixError(BC_STATUS_POSIX_FOR2, p->l.f, p->l.line, NULL); | 4207 | s = bc_posix_error("POSIX does not allow an empty condition expression in a for loop"); |
4334 | 4208 | ||
4335 | if (s) return s; | 4209 | if (s) return s; |
4336 | if (p->l.t.t != BC_LEX_SCOLON) return bc_error("bad token"); | 4210 | if (p->l.t.t != BC_LEX_SCOLON) return bc_error("bad token"); |
@@ -4351,7 +4225,7 @@ static BcStatus bc_parse_for(BcParse *p) | |||
4351 | if (p->l.t.t != BC_LEX_RPAREN) | 4225 | if (p->l.t.t != BC_LEX_RPAREN) |
4352 | s = bc_parse_expr(p, 0, bc_parse_next_rel); | 4226 | s = bc_parse_expr(p, 0, bc_parse_next_rel); |
4353 | else | 4227 | else |
4354 | s = bc_vm_posixError(BC_STATUS_POSIX_FOR3, p->l.f, p->l.line, NULL); | 4228 | s = bc_posix_error("POSIX does not allow an empty update expression in a for loop"); |
4355 | 4229 | ||
4356 | if (s) return s; | 4230 | if (s) return s; |
4357 | 4231 | ||
@@ -4475,7 +4349,7 @@ static BcStatus bc_parse_func(BcParse *p) | |||
4475 | if (s) return s; | 4349 | if (s) return s; |
4476 | 4350 | ||
4477 | if (p->l.t.t != BC_LEX_LBRACE) | 4351 | if (p->l.t.t != BC_LEX_LBRACE) |
4478 | s = bc_vm_posixError(BC_STATUS_POSIX_BRACE, p->l.f, p->l.line, NULL); | 4352 | s = bc_posix_error("POSIX requires the left brace be on the same line as the function header"); |
4479 | 4353 | ||
4480 | return s; | 4354 | return s; |
4481 | 4355 | ||
@@ -4999,11 +4873,11 @@ static BcStatus bc_parse_expr(BcParse *p, uint8_t flags, BcParseNext next) | |||
4999 | ok: | 4873 | ok: |
5000 | 4874 | ||
5001 | if (!(flags & BC_PARSE_REL) && nrelops) { | 4875 | if (!(flags & BC_PARSE_REL) && nrelops) { |
5002 | s = bc_vm_posixError(BC_STATUS_POSIX_REL_POS, p->l.f, p->l.line, NULL); | 4876 | s = bc_posix_error("POSIX does not allow comparison operators outside if or loops"); |
5003 | if (s) return s; | 4877 | if (s) return s; |
5004 | } | 4878 | } |
5005 | else if ((flags & BC_PARSE_REL) && nrelops > 1) { | 4879 | else if ((flags & BC_PARSE_REL) && nrelops > 1) { |
5006 | s = bc_vm_posixError(BC_STATUS_POSIX_MULTIREL, p->l.f, p->l.line, NULL); | 4880 | s = bc_posix_error("POSIX requires exactly one comparison operator per condition"); |
5007 | if (s) return s; | 4881 | if (s) return s; |
5008 | } | 4882 | } |
5009 | 4883 | ||
@@ -6575,10 +6449,6 @@ static void bc_program_reset(void) | |||
6575 | 6449 | ||
6576 | // If !tty, no need to check for ^C: we don't have ^C handler, | 6450 | // If !tty, no need to check for ^C: we don't have ^C handler, |
6577 | // we would be killed by a signal and won't reach this place | 6451 | // we would be killed by a signal and won't reach this place |
6578 | |||
6579 | fflush_and_check(); // make sure buffered stdout is printed | ||
6580 | fputs("ready for more input\n", stderr); | ||
6581 | fflush_and_check(); | ||
6582 | } | 6452 | } |
6583 | 6453 | ||
6584 | static BcStatus bc_program_exec(void) | 6454 | static BcStatus bc_program_exec(void) |
@@ -6914,40 +6784,7 @@ static void bc_vm_info(void) | |||
6914 | , applet_name); | 6784 | , applet_name); |
6915 | } | 6785 | } |
6916 | 6786 | ||
6917 | static BcStatus bc_vm_error(BcStatus s, const char *file, size_t line) | ||
6918 | { | ||
6919 | if (!s || s > BC_STATUS_BEFORE_POSIX) return s; | ||
6920 | |||
6921 | if (bc_err_msgs[s]) { | ||
6922 | fprintf(stderr, bc_err_fmt, bc_err_msgs[s]); | ||
6923 | fprintf(stderr, " %s", file); | ||
6924 | fprintf(stderr, bc_err_line + 4 * !line, line); | ||
6925 | } | ||
6926 | |||
6927 | /// | ||
6928 | return s * (!G.ttyin || !!strcmp(file, bc_program_stdin_name)); | ||
6929 | } | ||
6930 | |||
6931 | #if ENABLE_BC | 6787 | #if ENABLE_BC |
6932 | static BcStatus bc_vm_posixError(BcStatus s, const char *file, size_t line, | ||
6933 | const char *msg) | ||
6934 | { | ||
6935 | const char *fmt; | ||
6936 | |||
6937 | if (!(G.flags & (BC_FLAG_S|BC_FLAG_W))) return BC_STATUS_SUCCESS; | ||
6938 | if (s < BC_STATUS_POSIX_NAME_LEN) return BC_STATUS_SUCCESS; | ||
6939 | |||
6940 | fmt = G_posix ? bc_err_fmt : bc_warn_fmt; | ||
6941 | fprintf(stderr, fmt, bc_err_msgs[s]); | ||
6942 | if (msg) fprintf(stderr, " %s\n", msg); | ||
6943 | fprintf(stderr, " %s", file); | ||
6944 | fprintf(stderr, bc_err_line + 4 * !line, line); | ||
6945 | |||
6946 | if (G.ttyin || !G_posix) | ||
6947 | s = BC_STATUS_SUCCESS; | ||
6948 | return s; | ||
6949 | } | ||
6950 | |||
6951 | static void bc_vm_envArgs(void) | 6788 | static void bc_vm_envArgs(void) |
6952 | { | 6789 | { |
6953 | static const char* const bc_args_env_name = "BC_ENV_ARGS"; | 6790 | static const char* const bc_args_env_name = "BC_ENV_ARGS"; |
@@ -7004,24 +6841,18 @@ static BcStatus bc_vm_process(const char *text) | |||
7004 | { | 6841 | { |
7005 | BcStatus s = bc_parse_text(&G.prs, text); | 6842 | BcStatus s = bc_parse_text(&G.prs, text); |
7006 | 6843 | ||
7007 | s = bc_vm_error(s, G.prs.l.f, G.prs.l.line); | ||
7008 | if (s) return s; | 6844 | if (s) return s; |
7009 | 6845 | ||
7010 | while (G.prs.l.t.t != BC_LEX_EOF) { | 6846 | while (G.prs.l.t.t != BC_LEX_EOF) { |
7011 | |||
7012 | s = G.prs.parse(&G.prs); | 6847 | s = G.prs.parse(&G.prs); |
7013 | |||
7014 | s = bc_vm_error(s, G.prs.l.f, G.prs.l.line); | ||
7015 | if (s) return s; | 6848 | if (s) return s; |
7016 | } | 6849 | } |
7017 | 6850 | ||
7018 | if (BC_PARSE_CAN_EXEC(&G.prs)) { | 6851 | if (BC_PARSE_CAN_EXEC(&G.prs)) { |
7019 | s = bc_program_exec(); | 6852 | s = bc_program_exec(); |
7020 | fflush_and_check(); | 6853 | fflush_and_check(); |
7021 | if (s) { | 6854 | if (s) |
7022 | bc_program_reset(); | 6855 | bc_program_reset(); |
7023 | s = bc_vm_error(s, G.prs.l.f, 0); | ||
7024 | } | ||
7025 | } | 6856 | } |
7026 | 6857 | ||
7027 | return s; | 6858 | return s; |
@@ -7115,23 +6946,21 @@ static BcStatus bc_vm_stdin(void) | |||
7115 | 6946 | ||
7116 | bc_vec_concat(&buffer, buf.v); | 6947 | bc_vec_concat(&buffer, buf.v); |
7117 | s = bc_vm_process(buffer.v); | 6948 | s = bc_vm_process(buffer.v); |
7118 | if (s) goto err; | 6949 | if (s) { |
6950 | fflush_and_check(); | ||
6951 | fputs("ready for more input\n", stderr); | ||
6952 | } | ||
7119 | 6953 | ||
7120 | bc_vec_npop(&buffer, buffer.len); | 6954 | bc_vec_npop(&buffer, buffer.len); |
7121 | } | 6955 | } |
7122 | 6956 | ||
7123 | if (str) { | 6957 | if (str) { |
7124 | bc_error("string end could not be found"); | 6958 | s = bc_error("string end could not be found"); |
7125 | s = bc_vm_error(BC_STATUS_FAILURE, G.prs.l.f, | ||
7126 | G.prs.l.line); | ||
7127 | } | 6959 | } |
7128 | else if (comment) { | 6960 | else if (comment) { |
7129 | bc_error("comment end could not be found"); | 6961 | s = bc_error("comment end could not be found"); |
7130 | s = bc_vm_error(BC_STATUS_FAILURE, G.prs.l.f, | ||
7131 | G.prs.l.line); | ||
7132 | } | 6962 | } |
7133 | 6963 | ||
7134 | err: | ||
7135 | bc_vec_free(&buf); | 6964 | bc_vec_free(&buf); |
7136 | bc_vec_free(&buffer); | 6965 | bc_vec_free(&buffer); |
7137 | return s; | 6966 | return s; |
@@ -7148,7 +6977,8 @@ static BcStatus bc_vm_exec(void) | |||
7148 | bc_lex_file(&G.prs.l, bc_lib_name); | 6977 | bc_lex_file(&G.prs.l, bc_lib_name); |
7149 | s = bc_parse_text(&G.prs, bc_lib); | 6978 | s = bc_parse_text(&G.prs, bc_lib); |
7150 | 6979 | ||
7151 | while (!s && G.prs.l.t.t != BC_LEX_EOF) s = G.prs.parse(&G.prs); | 6980 | while (!s && G.prs.l.t.t != BC_LEX_EOF) |
6981 | s = G.prs.parse(&G.prs); | ||
7152 | 6982 | ||
7153 | if (s) return s; | 6983 | if (s) return s; |
7154 | s = bc_program_exec(); | 6984 | s = bc_program_exec(); |
@@ -7158,10 +6988,17 @@ static BcStatus bc_vm_exec(void) | |||
7158 | 6988 | ||
7159 | for (i = 0; !s && i < G.files.len; ++i) | 6989 | for (i = 0; !s && i < G.files.len; ++i) |
7160 | s = bc_vm_file(*((char **) bc_vec_item(&G.files, i))); | 6990 | s = bc_vm_file(*((char **) bc_vec_item(&G.files, i))); |
7161 | if (s) return s; | 6991 | if (s) { |
6992 | if (!G.tty) | ||
6993 | return s; | ||
6994 | fflush_and_check(); | ||
6995 | fputs("ready for more input\n", stderr); | ||
6996 | } | ||
7162 | 6997 | ||
7163 | if (IS_BC || !G.files.len) s = bc_vm_stdin(); | 6998 | if (IS_BC || !G.files.len) |
7164 | if (!s && !BC_PARSE_CAN_EXEC(&G.prs)) s = bc_vm_process(""); | 6999 | s = bc_vm_stdin(); |
7000 | if (!s && !BC_PARSE_CAN_EXEC(&G.prs)) | ||
7001 | s = bc_vm_process(""); | ||
7165 | 7002 | ||
7166 | return s; | 7003 | return s; |
7167 | } | 7004 | } |