aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-12-04 20:51:40 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-12-05 15:43:35 +0100
commit9b70f197b4dd5be47c5d0d4479525efe012964ee (patch)
tree0a5c20c6b57ffb60f81cfbff511755353035dfde
parent60cf747b6c234958387298068da658cfee9c42cb (diff)
downloadbusybox-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.c267
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!
242static 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
895static BcStatus bc_vm_posixError(BcStatus s, const char *file, size_t line,
896 const char *msg);
897#endif
898
899static void bc_vm_info(void); 760static void bc_vm_info(void);
900 761
901static const char bc_err_fmt[] = "\nerror: %s\n";
902static const char bc_warn_fmt[] = "\nwarning: %s\n";
903static const char bc_err_line[] = ":%zu\n\n";
904
905#if ENABLE_BC 762#if ENABLE_BC
906static const BcLexKeyword bc_lex_kws[20] = { 763static 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
1011static 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
1154static void bc_vec_grow(BcVec *v, size_t n) 1030static 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
6584static BcStatus bc_program_exec(void) 6454static 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
6917static 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
6932static 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
6951static void bc_vm_envArgs(void) 6788static 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
7134err:
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}