bc: replace G.eof with a special exit code of bc_vm_stdin()

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>
This commit is contained in:
Denys Vlasenko 2018-12-07 16:35:43 +01:00
parent 2d615fee38
commit f522dd9420

View File

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