bc: replace G.eof with a special exit code of bc_vm_stdin()
authorDenys Vlasenko <vda.linux@googlemail.com>
Fri, 7 Dec 2018 15:35:43 +0000 (16:35 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Fri, 7 Dec 2018 15:35:43 +0000 (16:35 +0100)
function                                             old     new   delta
bc_read_line                                         305     307      +2
bc_vm_run                                            701     689     -12
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 2/-12)             Total: -10 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
miscutils/bc.c

index 2cfe87b1e67429bd037479495d96909b3fef273a..24e4b639202ab50e58047c7c897f79ef662076e4 100644 (file)
@@ -191,6 +191,7 @@ typedef enum BcStatus {
        BC_STATUS_SUCCESS = 0,
        BC_STATUS_FAILURE = 1,
        BC_STATUS_PARSE_EMPTY_EXP = 2, // bc_parse_expr() uses this
+       BC_STATUS_EOF = 3, // bc_vm_stdin() uses this
 } BcStatus;
 
 #define BC_VEC_INVALID_IDX ((size_t) -1)
@@ -754,7 +755,6 @@ typedef unsigned long (*BcProgramBuiltIn)(BcNum *);
 struct globals {
        IF_FEATURE_BC_SIGNALS(smallint ttyin;)
        IF_FEATURE_CLEAN_UP(smallint exiting;)
-       smallint eof;
        char sbgn;
        char send;
 
@@ -1270,10 +1270,12 @@ static int push_input_byte(BcVec *vec, char c)
 
 static BcStatus bc_read_line(BcVec *vec, const char *prompt)
 {
+       BcStatus s;
        bool bad_chars;
 
        if (G_posix) prompt = "";
 
+       s = BC_STATUS_SUCCESS;
        do {
                int c;
 
@@ -1299,7 +1301,7 @@ static BcStatus bc_read_line(BcVec *vec, const char *prompt)
                        if (n <= 0) { // read errors or EOF, or ^D, or ^C
                                if (n == 0) // ^C
                                        goto intr;
-                               G.eof = 1;
+                               s = BC_STATUS_EOF;
                                break;
                        }
                        i = 0;
@@ -1329,7 +1331,7 @@ static BcStatus bc_read_line(BcVec *vec, const char *prompt)
                                if (c == EOF) {
                                        if (ferror(stdin))
                                                quit(); // this emits error message
-                                       G.eof = 1;
+                                       s = BC_STATUS_EOF;
                                        // Note: EOF does not append '\n', therefore:
                                        // printf 'print 123\n' | bc - works
                                        // printf 'print 123' | bc   - fails (syntax error)
@@ -1342,7 +1344,7 @@ static BcStatus bc_read_line(BcVec *vec, const char *prompt)
 
        bc_vec_pushZeroByte(vec);
 
-       return BC_STATUS_SUCCESS;
+       return s;
 }
 
 static char* bc_read_file(const char *path)
@@ -7129,8 +7131,7 @@ static BcStatus bc_vm_stdin(void)
        // with a backslash to the parser. The reason for that is because the parser
        // treats a backslash+newline combo as whitespace, per the bc spec. In that
        // case, and for strings and comments, the parser will expect more stuff.
-       s = BC_STATUS_SUCCESS;
-       while (!G.eof && (s = bc_read_line(&buf, ">>> ")) == BC_STATUS_SUCCESS) {
+       while ((s = bc_read_line(&buf, ">>> ")) == BC_STATUS_SUCCESS) {
 
                char *string = buf.v;
 
@@ -7187,6 +7188,8 @@ static BcStatus bc_vm_stdin(void)
 
                bc_vec_pop_all(&buffer);
        }
+       if (s == BC_STATUS_EOF) // input EOF (^D) is not an error
+               s = BC_STATUS_SUCCESS;
 
        if (str) {
                s = bc_error("string end could not be found");