aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-12-03 14:28:51 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-12-05 15:43:35 +0100
commitd4744adf35c678554e609a74eeebc7b7603ee25d (patch)
tree2021cc4bda715c01517b578f7d863a1914d67505
parentcfdc1334c3e0cfbbe41f850e426c51c37a653dfb (diff)
downloadbusybox-w32-d4744adf35c678554e609a74eeebc7b7603ee25d.tar.gz
busybox-w32-d4744adf35c678554e609a74eeebc7b7603ee25d.tar.bz2
busybox-w32-d4744adf35c678554e609a74eeebc7b7603ee25d.zip
bc: eliminate BC_STATUS_INPUT_EOF
function old new delta fflush_and_check - 36 +36 bc_num_a 445 456 +11 bc_num_ulong 85 95 +10 bc_vm_run 1978 1984 +6 bc_num_s 246 252 +6 bc_err_msgs 192 188 -4 quit 38 32 -6 bc_vm_process 139 132 -7 bc_program_reset 172 159 -13 bc_parse_create 192 175 -17 bc_read_line 349 311 -38 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 4/6 up/down: 69/-85) Total: -16 bytes text data bss dec hex filename 987844 485 7296 995625 f3129 busybox_old 987828 485 7296 995609 f3119 busybox_unstripped Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--miscutils/bc.c48
1 files changed, 27 insertions, 21 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c
index c3d118417..c819decff 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -171,7 +171,7 @@ typedef enum BcStatus {
171 BC_STATUS_SUCCESS, 171 BC_STATUS_SUCCESS,
172 172
173// BC_STATUS_ALLOC_ERR, 173// BC_STATUS_ALLOC_ERR,
174 BC_STATUS_INPUT_EOF, 174// BC_STATUS_INPUT_EOF,
175 BC_STATUS_BIN_FILE, 175 BC_STATUS_BIN_FILE,
176// BC_STATUS_PATH_IS_DIR, 176// BC_STATUS_PATH_IS_DIR,
177 177
@@ -240,7 +240,7 @@ typedef enum BcStatus {
240static const char *const bc_err_msgs[] = { 240static const char *const bc_err_msgs[] = {
241 NULL, 241 NULL,
242// "memory allocation error", 242// "memory allocation error",
243 "I/O error", 243// "I/O error",
244 "file is not text:", 244 "file is not text:",
245// "path is a directory:", 245// "path is a directory:",
246 246
@@ -875,6 +875,7 @@ struct globals {
875 875
876 smallint tty; 876 smallint tty;
877 smallint ttyin; 877 smallint ttyin;
878 smallint eof;
878} FIX_ALIASING; 879} FIX_ALIASING;
879#define G (*ptr_to_globals) 880#define G (*ptr_to_globals)
880#define INIT_G() do { \ 881#define INIT_G() do { \
@@ -1121,11 +1122,20 @@ static const char bc_lib[] = {
1121}; 1122};
1122#endif // ENABLE_BC 1123#endif // ENABLE_BC
1123 1124
1125static void fflush_and_check(void)
1126{
1127 fflush_all();
1128 if (ferror(stdout) || ferror(stderr))
1129 bb_perror_msg_and_die("output error");
1130}
1131
1124static void quit(void) NORETURN; 1132static void quit(void) NORETURN;
1125static void quit(void) 1133static void quit(void)
1126{ 1134{
1127 fflush_all(); 1135 if (ferror(stdin))
1128 exit(ferror(stdout) || ferror(stderr)); 1136 bb_perror_msg_and_die("input error");
1137 fflush_and_check();
1138 exit(0);
1129} 1139}
1130 1140
1131static void bc_vec_grow(BcVec *v, size_t n) 1141static void bc_vec_grow(BcVec *v, size_t n)
@@ -1284,7 +1294,7 @@ static BcStatus bc_read_line(BcVec *vec, const char *prompt)
1284 1294
1285 bc_vec_npop(vec, vec->len); 1295 bc_vec_npop(vec, vec->len);
1286 1296
1287 fflush(stdout); 1297 fflush_and_check();
1288#if ENABLE_FEATURE_BC_SIGNALS 1298#if ENABLE_FEATURE_BC_SIGNALS
1289 if (bb_got_signal) { // ^C was pressed 1299 if (bb_got_signal) { // ^C was pressed
1290 intr: 1300 intr:
@@ -1297,15 +1307,12 @@ static BcStatus bc_read_line(BcVec *vec, const char *prompt)
1297#endif 1307#endif
1298 if (G.ttyin && !G_posix) 1308 if (G.ttyin && !G_posix)
1299 fputs(prompt, stderr); 1309 fputs(prompt, stderr);
1300 fflush(stderr); 1310 fflush_and_check();
1301 1311
1302#if ENABLE_FEATURE_BC_SIGNALS 1312#if ENABLE_FEATURE_BC_SIGNALS
1303 errno = 0; 1313 errno = 0;
1304#endif 1314#endif
1305 do { 1315 do {
1306 if (ferror(stdout) || ferror(stderr))
1307 bb_perror_msg_and_die("output error");
1308
1309 i = fgetc(stdin); 1316 i = fgetc(stdin);
1310 1317
1311 if (i == EOF) { 1318 if (i == EOF) {
@@ -1318,8 +1325,12 @@ static BcStatus bc_read_line(BcVec *vec, const char *prompt)
1318 } 1325 }
1319#endif 1326#endif
1320 if (ferror(stdin)) 1327 if (ferror(stdin))
1321 bb_perror_msg_and_die("input error"); 1328 quit(); // this emits error message
1322 return BC_STATUS_INPUT_EOF; 1329 G.eof = 1;
1330 // Note: EOF does not append '\n', therefore:
1331 // printf 'print 123\n' | bc - works
1332 // printf 'print 123' | bc - fails (syntax error)
1333 break;
1323 } 1334 }
1324 1335
1325 c = (signed char) i; 1336 c = (signed char) i;
@@ -3627,7 +3638,7 @@ static void bc_parse_create(BcParse *p, size_t func,
3627 bc_vec_init(&p->ops, sizeof(BcLexType), NULL); 3638 bc_vec_init(&p->ops, sizeof(BcLexType), NULL);
3628 3639
3629 p->parse = parse; 3640 p->parse = parse;
3630 p->auto_part = (p->nbraces = 0); 3641 // p->auto_part = p->nbraces = 0; - already is
3631 bc_parse_updateFunc(p, func); 3642 bc_parse_updateFunc(p, func);
3632} 3643}
3633 3644
@@ -6473,9 +6484,9 @@ static BcStatus bc_program_reset(BcStatus s)
6473 if (!s || s == BC_STATUS_EXEC_SIGNAL) { 6484 if (!s || s == BC_STATUS_EXEC_SIGNAL) {
6474 if (!G.ttyin) 6485 if (!G.ttyin)
6475 quit(); 6486 quit();
6476 fflush(stdout); 6487 fflush_and_check(); // make sure buffered stdout is printed
6477 fputs(bc_program_ready_msg, stderr); 6488 fputs(bc_program_ready_msg, stderr);
6478 fflush(stderr); 6489 fflush_and_check();
6479 s = BC_STATUS_SUCCESS; 6490 s = BC_STATUS_SUCCESS;
6480 } 6491 }
6481 6492
@@ -6910,7 +6921,7 @@ static BcStatus bc_vm_process(const char *text)
6910 6921
6911 if (BC_PARSE_CAN_EXEC(&G.prs)) { 6922 if (BC_PARSE_CAN_EXEC(&G.prs)) {
6912 s = bc_program_exec(); 6923 s = bc_program_exec();
6913 fflush(stdout); 6924 fflush_and_check();
6914 if (s) 6925 if (s)
6915 s = bc_vm_error(bc_program_reset(s), G.prs.l.f, 0); 6926 s = bc_vm_error(bc_program_reset(s), G.prs.l.f, 0);
6916 } 6927 }
@@ -6961,7 +6972,7 @@ static BcStatus bc_vm_stdin(void)
6961 // with a backslash to the parser. The reason for that is because the parser 6972 // with a backslash to the parser. The reason for that is because the parser
6962 // treats a backslash+newline combo as whitespace, per the bc spec. In that 6973 // treats a backslash+newline combo as whitespace, per the bc spec. In that
6963 // case, and for strings and comments, the parser will expect more stuff. 6974 // case, and for strings and comments, the parser will expect more stuff.
6964 while ((s = bc_read_line(&buf, ">>> ")) == BC_STATUS_SUCCESS) { 6975 while (!G.eof && (s = bc_read_line(&buf, ">>> ")) == BC_STATUS_SUCCESS) {
6965 6976
6966 char *string = buf.v; 6977 char *string = buf.v;
6967 6978
@@ -7012,11 +7023,6 @@ static BcStatus bc_vm_stdin(void)
7012 7023
7013 if (s == BC_STATUS_BIN_FILE) s = bc_vm_error(s, G.prs.l.f, 0); 7024 if (s == BC_STATUS_BIN_FILE) s = bc_vm_error(s, G.prs.l.f, 0);
7014 7025
7015 // INPUT_EOF will always happen when stdin is
7016 // closed. It's not a problem in that case.
7017 if (s == BC_STATUS_INPUT_EOF)
7018 s = BC_STATUS_SUCCESS;
7019
7020 if (str) 7026 if (str)
7021 s = bc_vm_error(BC_STATUS_LEX_NO_STRING_END, G.prs.l.f, 7027 s = bc_vm_error(BC_STATUS_LEX_NO_STRING_END, G.prs.l.f,
7022 G.prs.l.line); 7028 G.prs.l.line);