diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-03 14:28:51 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-05 15:43:35 +0100 |
commit | d4744adf35c678554e609a74eeebc7b7603ee25d (patch) | |
tree | 2021cc4bda715c01517b578f7d863a1914d67505 | |
parent | cfdc1334c3e0cfbbe41f850e426c51c37a653dfb (diff) | |
download | busybox-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.c | 48 |
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 { | |||
240 | static const char *const bc_err_msgs[] = { | 240 | static 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 | ||
1125 | static 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 | |||
1124 | static void quit(void) NORETURN; | 1132 | static void quit(void) NORETURN; |
1125 | static void quit(void) | 1133 | static 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 | ||
1131 | static void bc_vec_grow(BcVec *v, size_t n) | 1141 | static 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); |