diff options
author | Gavin Howard <yzena.tech@gmail.com> | 2021-03-31 10:55:06 -0600 |
---|---|---|
committer | Gavin Howard <yzena.tech@gmail.com> | 2021-03-31 10:55:06 -0600 |
commit | 7378a7abe1ec13adbb01212dff12346f2eff003d (patch) | |
tree | 54fb83b1aedbd47d8e5dc15c086f49ca9357bb1e | |
parent | 9f8f9bc7f3bdf9d544947103855811b360301c7f (diff) | |
download | bc-7378a7abe1ec13adbb01212dff12346f2eff003d.tar.gz |
Fix problems with printing stuff without newlines
The problem was not that stuff was printed without newlines, it was that
history did not recognize it as such. This commit fixes that.
To do that, I had a way for bc_file_* functions to know what kind of
flush they needed to do. I added an enum for it and updated all of the
places. This ensures that there isn't an infinite loop or other such
problem when flushing during history.
This commit does not complete the change. I have to ensure it builds
with history turned off still.
-rw-r--r-- | include/file.h | 29 | ||||
-rw-r--r-- | include/history.h | 3 | ||||
-rw-r--r-- | include/vm.h | 2 | ||||
-rw-r--r-- | src/data.c | 4 | ||||
-rw-r--r-- | src/file.c | 64 | ||||
-rw-r--r-- | src/history.c | 67 | ||||
-rw-r--r-- | src/num.c | 8 | ||||
-rw-r--r-- | src/program.c | 20 | ||||
-rw-r--r-- | src/read.c | 9 | ||||
-rw-r--r-- | src/vm.c | 56 |
10 files changed, 160 insertions, 102 deletions
diff --git a/include/file.h b/include/file.h index 1c3273b7..95d1f643 100644 --- a/include/file.h +++ b/include/file.h @@ -51,15 +51,30 @@ typedef struct BcFile { } BcFile; +typedef enum BcFlushType { + + BC_FLUSH_NO_EXTRAS_NO_CLEAR, + BC_FLUSH_SAVE_EXTRAS_NO_CLEAR, + BC_FLUSH_NO_EXTRAS_CLEAR, + BC_FLUSH_SAVE_EXTRAS_CLEAR, + +} BcFlushType; + void bc_file_init(BcFile *f, int fd, char *buf, size_t cap); void bc_file_free(BcFile *f); -void bc_file_putchar(BcFile *restrict f, uchar c); -BcStatus bc_file_flushErr(BcFile *restrict f); -void bc_file_flush(BcFile *restrict f); -void bc_file_write(BcFile *restrict f, const char *buf, size_t n); -void bc_file_printf(BcFile *restrict f, const char *fmt, ...); -void bc_file_vprintf(BcFile *restrict f, const char *fmt, va_list args); -void bc_file_puts(BcFile *restrict f, const char *str); +void bc_file_putchar(BcFile *restrict f, BcFlushType type, uchar c); +BcStatus bc_file_flushErr(BcFile *restrict f, BcFlushType type); +void bc_file_flush(BcFile *restrict f, BcFlushType type); +void bc_file_write(BcFile *restrict f, BcFlushType type, + const char *buf, size_t n); +void bc_file_printf(BcFile *restrict f, BcFlushType type, const char *fmt, ...); +void bc_file_vprintf(BcFile *restrict f, BcFlushType type, + const char *fmt, va_list args); +void bc_file_puts(BcFile *restrict f, BcFlushType type, const char *str); + +extern const BcFlushType bc_flush_none; +extern const BcFlushType bc_flush_err; +extern const BcFlushType bc_flush_save; #endif // BC_FILE_H diff --git a/include/history.h b/include/history.h index d3622ae1..469785a1 100644 --- a/include/history.h +++ b/include/history.h @@ -186,6 +186,9 @@ typedef struct BcHistory { /// The history. BcVec history; + /// Any material printed without a trailing newline. + BcVec extras; + #if BC_ENABLE_PROMPT /// Prompt to display. const char *prompt; diff --git a/include/vm.h b/include/vm.h index 1c1cd938..23844d4b 100644 --- a/include/vm.h +++ b/include/vm.h @@ -424,7 +424,7 @@ void bc_vm_shutdown(void); void bc_vm_freeTemps(void); void bc_vm_printf(const char *fmt, ...); -void bc_vm_putchar(int c); +void bc_vm_putchar(int c, BcFlushType type); size_t bc_vm_arraySize(size_t n, size_t size); size_t bc_vm_growSize(size_t a, size_t b); void* bc_vm_malloc(size_t n); @@ -172,6 +172,10 @@ const char* const bc_err_msgs[] = { }; +const BcFlushType bc_flush_none = BC_FLUSH_NO_EXTRAS_NO_CLEAR; +const BcFlushType bc_flush_err = BC_FLUSH_NO_EXTRAS_CLEAR; +const BcFlushType bc_flush_save = BC_FLUSH_SAVE_EXTRAS_CLEAR; + #if BC_ENABLE_HISTORY const char *bc_history_bad_terms[] = { "dumb", "cons25", "emacs", NULL }; @@ -82,11 +82,27 @@ static BcStatus bc_file_output(int fd, const char *buf, size_t n) { return BC_STATUS_SUCCESS; } -BcStatus bc_file_flushErr(BcFile *restrict f) { - +BcStatus bc_file_flushErr(BcFile *restrict f, BcFlushType type) +{ BcStatus s; if (f->len) { + + if (f->buf[f->len - 1] != '\n' && + (type == BC_FLUSH_SAVE_EXTRAS_CLEAR || + type == BC_FLUSH_SAVE_EXTRAS_NO_CLEAR)) + { + size_t i; + + for (i = f->len - 2; i < f->len && f->buf[i] != '\n'; --i); + + i += 1; + + bc_vec_string(&vm.history.extras, f->len - i, f->buf + i); + } + else if (type >= BC_FLUSH_NO_EXTRAS_CLEAR) + bc_vec_popAll(&vm.history.extras); + s = bc_file_output(f->fd, f->buf, f->len); f->len = 0; } @@ -95,9 +111,9 @@ BcStatus bc_file_flushErr(BcFile *restrict f) { return s; } -void bc_file_flush(BcFile *restrict f) { +void bc_file_flush(BcFile *restrict f, BcFlushType type) { - BcStatus s = bc_file_flushErr(f); + BcStatus s = bc_file_flushErr(f, type); if (BC_ERR(s)) { @@ -109,10 +125,11 @@ void bc_file_flush(BcFile *restrict f) { } } -void bc_file_write(BcFile *restrict f, const char *buf, size_t n) { - +void bc_file_write(BcFile *restrict f, BcFlushType type, + const char *buf, size_t n) +{ if (n > f->cap - f->len) { - bc_file_flush(f); + bc_file_flush(f, type); assert(!f->len); } @@ -123,17 +140,18 @@ void bc_file_write(BcFile *restrict f, const char *buf, size_t n) { } } -void bc_file_printf(BcFile *restrict f, const char *fmt, ...) { - +void bc_file_printf(BcFile *restrict f, BcFlushType type, const char *fmt, ...) +{ va_list args; va_start(args, fmt); - bc_file_vprintf(f, fmt, args); + bc_file_vprintf(f, type, fmt, args); va_end(args); } -void bc_file_vprintf(BcFile *restrict f, const char *fmt, va_list args) { - +void bc_file_vprintf(BcFile *restrict f, BcFlushType type, + const char *fmt, va_list args) +{ char *percent; const char *ptr = fmt; char buf[BC_FILE_ULL_LENGTH]; @@ -144,7 +162,7 @@ void bc_file_vprintf(BcFile *restrict f, const char *fmt, va_list args) { if (percent != ptr) { size_t len = (size_t) (percent - ptr); - bc_file_write(f, ptr, len); + bc_file_write(f, type, ptr, len); } c = percent[1]; @@ -153,13 +171,13 @@ void bc_file_vprintf(BcFile *restrict f, const char *fmt, va_list args) { uchar uc = (uchar) va_arg(args, int); - bc_file_putchar(f, uc); + bc_file_putchar(f, type, uc); } else if (c == 's') { char *s = va_arg(args, char*); - bc_file_puts(f, s); + bc_file_puts(f, type, s); } #if BC_DEBUG_CODE else if (c == 'd') { @@ -187,25 +205,25 @@ void bc_file_vprintf(BcFile *restrict f, const char *fmt, va_list args) { if (c == 'z') ull = (unsigned long long) va_arg(args, size_t); else ull = (unsigned long long) va_arg(args, unsigned long); - if (!ull) bc_file_putchar(f, '0'); + if (!ull) bc_file_putchar(f, type, '0'); else { bc_file_ultoa(ull, buf); - bc_file_puts(f, buf); + bc_file_puts(f, type, buf); } } ptr = percent + 2 + (c == 'l' || c == 'z'); } - if (ptr[0]) bc_file_puts(f, ptr); + if (ptr[0]) bc_file_puts(f, type, ptr); } -void bc_file_puts(BcFile *restrict f, const char *str) { - bc_file_write(f, str, strlen(str)); +void bc_file_puts(BcFile *restrict f, BcFlushType type, const char *str) { + bc_file_write(f, type, str, strlen(str)); } -void bc_file_putchar(BcFile *restrict f, uchar c) { - if (f->len == f->cap) bc_file_flush(f); +void bc_file_putchar(BcFile *restrict f, BcFlushType type, uchar c) { + if (f->len == f->cap) bc_file_flush(f, type); assert(f->len < f->cap); f->buf[f->len] = (char) c; f->len += 1; @@ -221,5 +239,5 @@ void bc_file_init(BcFile *f, int fd, char *buf, size_t cap) { void bc_file_free(BcFile *f) { BC_SIG_ASSERT_LOCKED; - bc_file_flush(f); + bc_file_flush(f, bc_flush_none); } diff --git a/src/history.c b/src/history.c index 7c4f0ceb..8acf2cc9 100644 --- a/src/history.c +++ b/src/history.c @@ -505,8 +505,8 @@ static size_t bc_history_cursorPos(void) { size_t cols, rows, i; // Report cursor location. - bc_file_write(&vm.fout, "\x1b[6n", 4); - bc_file_flush(&vm.fout); + bc_file_write(&vm.fout, bc_flush_none, "\x1b[6n", 4); + bc_file_flush(&vm.fout, bc_flush_none); // Read the response: ESC [ rows ; cols R. for (i = 0; i < sizeof(buf) - 1; ++i) { @@ -556,15 +556,15 @@ static size_t bc_history_columns(void) { if (BC_ERR(start == SIZE_MAX)) return BC_HIST_DEF_COLS; // Go to right margin and get position. - bc_file_write(&vm.fout, "\x1b[999C", 6); - bc_file_flush(&vm.fout); + bc_file_write(&vm.fout, bc_flush_none, "\x1b[999C", 6); + bc_file_flush(&vm.fout, bc_flush_none); cols = bc_history_cursorPos(); if (BC_ERR(cols == SIZE_MAX)) return BC_HIST_DEF_COLS; // Restore position. if (cols > start) { - bc_file_printf(&vm.fout, "\x1b[%zuD", cols - start); - bc_file_flush(&vm.fout); + bc_file_printf(&vm.fout, bc_flush_none, "\x1b[%zuD", cols - start); + bc_file_flush(&vm.fout, bc_flush_none); } return cols; @@ -632,7 +632,7 @@ static void bc_history_refresh(BcHistory *h) { char* buf = h->buf.v; size_t colpos, len = BC_HIST_BUF_LEN(h), pos = h->pos; - bc_file_flush(&vm.fout); + bc_file_flush(&vm.fout, bc_flush_none); while(h->pcol + bc_history_colPos(buf, len, pos) >= h->cols) { @@ -647,24 +647,32 @@ static void bc_history_refresh(BcHistory *h) { len -= bc_history_prevLen(buf, len, NULL); // Cursor to left edge. - bc_file_write(&vm.fout, "\r", 1); + bc_file_write(&vm.fout, bc_flush_none, "\r", 1); + + // Take the extra stuff into account. + if (h->extras.len > 1) { + len += h->extras.len - 1; + pos += h->extras.len - 1; + bc_file_write(&vm.fout, bc_flush_none, h->extras.v, h->extras.len - 1); + } // Write the prompt, if desired. #if BC_ENABLE_PROMPT - if (BC_USE_PROMPT) bc_file_write(&vm.fout, h->prompt, h->plen); + if (BC_USE_PROMPT) + bc_file_write(&vm.fout, bc_flush_none, h->prompt, h->plen); #endif // BC_ENABLE_PROMPT - bc_file_write(&vm.fout, buf, BC_HIST_BUF_LEN(h)); + bc_file_write(&vm.fout, bc_flush_none, buf, BC_HIST_BUF_LEN(h)); // Erase to right. - bc_file_write(&vm.fout, "\x1b[0K", 4); + bc_file_write(&vm.fout, bc_flush_none, "\x1b[0K", 4); // Move cursor to original position. colpos = bc_history_colPos(buf, len, pos) + h->pcol; - if (colpos) bc_file_printf(&vm.fout, "\r\x1b[%zuC", colpos); + if (colpos) bc_file_printf(&vm.fout, bc_flush_none, "\r\x1b[%zuC", colpos); - bc_file_flush(&vm.fout); + bc_file_flush(&vm.fout, bc_flush_none); } /** @@ -684,7 +692,7 @@ static void bc_history_edit_insert(BcHistory *h, const char *cbuf, size_t clen) h->buf.len += clen - 1; bc_vec_pushByte(&h->buf, '\0'); - len = BC_HIST_BUF_LEN(h); + len = BC_HIST_BUF_LEN(h) + h->extras.len - 1; #if BC_ENABLE_PROMPT colpos = bc_history_promptColLen(h->prompt, h->plen); #endif // BC_ENABLE_PROMPT @@ -693,8 +701,8 @@ static void bc_history_edit_insert(BcHistory *h, const char *cbuf, size_t clen) if (colpos < h->cols) { // Avoid a full update of the line in the trivial case. - bc_file_write(&vm.fout, cbuf, clen); - bc_file_flush(&vm.fout); + bc_file_write(&vm.fout, bc_flush_none, cbuf, clen); + bc_file_flush(&vm.fout, bc_flush_none); } else bc_history_refresh(h); } @@ -1102,7 +1110,7 @@ static void bc_history_printCtrl(BcHistory *h, unsigned int c) { bc_vec_pushByte(&h->buf, '\0'); if (c != BC_ACTION_CTRL_C && c != BC_ACTION_CTRL_D) { - bc_file_write(&vm.fout, newline, sizeof(newline) - 1); + bc_file_write(&vm.fout, bc_flush_none, newline, sizeof(newline) - 1); bc_history_refresh(h); } } @@ -1116,6 +1124,11 @@ static BcStatus bc_history_edit(BcHistory *h, const char *prompt) { bc_history_reset(h); + // Don't write the saved output the first time. This is because it has + // already been written to output. In other words, don't uncomment the + // line below or add anything like it. + // bc_file_write(&vm.fout, bc_flush_none, h->extras.v, h->extras.len - 1); + #if BC_ENABLE_PROMPT if (BC_USE_PROMPT) { @@ -1123,8 +1136,8 @@ static BcStatus bc_history_edit(BcHistory *h, const char *prompt) { h->plen = strlen(prompt); h->pcol = bc_history_promptColLen(prompt, h->plen); - bc_file_write(&vm.fout, prompt, h->plen); - bc_file_flush(&vm.fout); + bc_file_write(&vm.fout, bc_flush_none, prompt, h->plen); + bc_file_flush(&vm.fout, bc_flush_none); } #endif // BC_ENABLE_PROMPT @@ -1158,8 +1171,8 @@ static BcStatus bc_history_edit(BcHistory *h, const char *prompt) { case BC_ACTION_CTRL_C: { bc_history_printCtrl(h, c); - bc_file_write(&vm.fout, vm.sigmsg, vm.siglen); - bc_file_write(&vm.fout, bc_program_ready_msg, + bc_file_write(&vm.fout, bc_flush_none, vm.sigmsg, vm.siglen); + bc_file_write(&vm.fout, bc_flush_none, bc_program_ready_msg, bc_program_ready_msg_len); bc_history_reset(h); bc_history_refresh(h); @@ -1254,7 +1267,7 @@ static BcStatus bc_history_edit(BcHistory *h, const char *prompt) { // Clear screen. case BC_ACTION_CTRL_L: { - bc_file_write(&vm.fout, "\x1b[H\x1b[2J", 7); + bc_file_write(&vm.fout, bc_flush_none, "\x1b[H\x1b[2J", 7); bc_history_refresh(h); break; } @@ -1302,8 +1315,8 @@ static BcStatus bc_history_raw(BcHistory *h, const char *prompt) { h->stdin_has_data = bc_history_stdinHasData(h); if (!h->stdin_has_data) bc_history_disableRaw(h); - bc_file_write(&vm.fout, "\n", 1); - bc_file_flush(&vm.fout); + bc_file_write(&vm.fout, bc_flush_none, "\n", 1); + bc_file_flush(&vm.fout, bc_flush_none); return s; } @@ -1382,6 +1395,7 @@ void bc_history_init(BcHistory *h) { bc_vec_init(&h->buf, sizeof(char), NULL); bc_vec_init(&h->history, sizeof(char*), bc_history_string_free); + bc_vec_init(&h->extras, sizeof(char), NULL); FD_ZERO(&h->rdset); FD_SET(STDIN_FILENO, &h->rdset); @@ -1401,6 +1415,7 @@ void bc_history_free(BcHistory *h) { #ifndef NDEBUG bc_vec_free(&h->buf); bc_vec_free(&h->history); + bc_vec_free(&h->extras); #endif // NDEBUG } @@ -1439,8 +1454,8 @@ void bc_history_printKeyCodes(BcHistory *h) { isprint(c) ? c : '?', (unsigned long) c); // Go left edge manually, we are in raw mode. - bc_vm_putchar('\r'); - bc_file_flush(&vm.fout); + bc_vm_putchar('\r', bc_flush_none); + bc_file_flush(&vm.fout, bc_flush_none); } bc_history_disableRaw(h); @@ -1655,15 +1655,15 @@ int_err: static inline void bc_num_printNewline(void) { #if !BC_ENABLE_LIBRARY if (vm.nchars >= vm.line_len - 1) { - bc_vm_putchar('\\'); - bc_vm_putchar('\n'); + bc_vm_putchar('\\', bc_flush_none); + bc_vm_putchar('\n', bc_flush_err); } #endif // !BC_ENABLE_LIBRARY } static void bc_num_putchar(int c) { if (c != '\n') bc_num_printNewline(); - bc_vm_putchar(c); + bc_vm_putchar(c, bc_flush_save); } #if DC_ENABLED && !BC_ENABLE_LIBRARY @@ -1671,7 +1671,7 @@ static void bc_num_printChar(size_t n, size_t len, bool rdx) { BC_UNUSED(rdx); BC_UNUSED(len); assert(len == 1); - bc_vm_putchar((uchar) n); + bc_vm_putchar((uchar) n, bc_flush_save); } #endif // DC_ENABLED && !BC_ENABLE_LIBRARY diff --git a/src/program.c b/src/program.c index 4ea635b2..5e65804d 100644 --- a/src/program.c +++ b/src/program.c @@ -514,7 +514,7 @@ static void bc_program_printChars(const char *str) { const char *nl; size_t len = vm.nchars + strlen(str); - bc_file_puts(&vm.fout, str); + bc_file_puts(&vm.fout, bc_flush_save, str); nl = strrchr(str, '\n'); if (nl != NULL) len = strlen(nl + 1); @@ -528,7 +528,7 @@ static void bc_program_printString(const char *restrict str) { #if DC_ENABLED if (!len && BC_IS_DC) { - bc_vm_putchar('\0'); + bc_vm_putchar('\0', bc_flush_save); return; } #endif // DC_ENABLED @@ -551,11 +551,11 @@ static void bc_program_printString(const char *restrict str) { else { // Just print the backslash. The following // character will be printed later. - bc_vm_putchar('\\'); + bc_vm_putchar('\\', bc_flush_save); } } - bc_vm_putchar(c); + bc_vm_putchar(c, bc_flush_save); } } @@ -600,13 +600,14 @@ static void bc_program_print(BcProgram *p, uchar inst, size_t idx) { size_t i = (r->t == BC_RESULT_STR) ? r->d.loc.loc : n->scale; - bc_file_flush(&vm.fout); + bc_file_flush(&vm.fout, bc_flush_save); str = *((char**) bc_vec_item(p->strs, i)); if (inst == BC_INST_PRINT_STR) bc_program_printChars(str); else { bc_program_printString(str); - if (inst == BC_INST_PRINT) bc_vm_putchar('\n'); + if (inst == BC_INST_PRINT) + bc_vm_putchar('\n', bc_flush_err); } } @@ -1809,8 +1810,9 @@ void bc_program_reset(BcProgram *p) { memset(ip, 0, sizeof(BcInstPtr)); if (vm.sig) { - bc_file_write(&vm.fout, bc_program_ready_msg, bc_program_ready_msg_len); - bc_file_flush(&vm.fout); + bc_file_write(&vm.fout, bc_flush_none, bc_program_ready_msg, + bc_program_ready_msg_len); + bc_file_flush(&vm.fout, bc_flush_err); vm.sig = 0; } } @@ -1932,7 +1934,7 @@ void bc_program_exec(BcProgram *p) { { // We want to flush output before // this in case there is a prompt. - bc_file_flush(&vm.fout); + bc_file_flush(&vm.fout, bc_flush_save); bc_program_read(p); @@ -100,8 +100,8 @@ BcStatus bc_read_chars(BcVec *vec, const char *prompt) { #if BC_ENABLE_PROMPT if (BC_USE_PROMPT) { - bc_file_puts(&vm.fout, prompt); - bc_file_flush(&vm.fout); + bc_file_puts(&vm.fout, bc_flush_none, prompt); + bc_file_flush(&vm.fout, bc_flush_none); } #endif // BC_ENABLE_PROMPT @@ -132,9 +132,10 @@ BcStatus bc_read_chars(BcVec *vec, const char *prompt) { vm.status = (sig_atomic_t) BC_STATUS_SUCCESS; #if BC_ENABLE_PROMPT - if (BC_USE_PROMPT) bc_file_puts(&vm.fout, prompt); + if (BC_USE_PROMPT) + bc_file_puts(&vm.fout, bc_flush_none, prompt); #endif // BC_ENABLE_PROMPT - bc_file_flush(&vm.fout); + bc_file_flush(&vm.fout, bc_flush_none); BC_SIG_UNLOCK; @@ -79,7 +79,7 @@ BC_NORETURN void bc_vm_jmp(void) { bc_file_puts(&vm.ferr, "Longjmp: "); bc_file_puts(&vm.ferr, f); bc_file_putchar(&vm.ferr, '\n'); - bc_file_flush(&vm.ferr); + bc_file_flush(&vm.ferr, bc_flush_none); #endif // BC_DEBUG_CODE #ifndef NDEBUG @@ -123,18 +123,18 @@ void bc_vm_info(const char* const help) { BC_SIG_ASSERT_LOCKED; - bc_file_puts(&vm.fout, vm.name); - bc_file_putchar(&vm.fout, ' '); - bc_file_puts(&vm.fout, BC_VERSION); - bc_file_putchar(&vm.fout, '\n'); - bc_file_puts(&vm.fout, bc_copyright); + bc_file_puts(&vm.fout, bc_flush_none, vm.name); + bc_file_putchar(&vm.fout, bc_flush_none, ' '); + bc_file_puts(&vm.fout, bc_flush_none, BC_VERSION); + bc_file_putchar(&vm.fout, bc_flush_none, '\n'); + bc_file_puts(&vm.fout, bc_flush_none, bc_copyright); if (help) { - bc_file_putchar(&vm.fout, '\n'); - bc_file_printf(&vm.fout, help, vm.name, vm.name); + bc_file_putchar(&vm.fout, bc_flush_none, '\n'); + bc_file_printf(&vm.fout, bc_flush_none, help, vm.name, vm.name); } - bc_file_flush(&vm.fout); + bc_file_flush(&vm.fout, bc_flush_err); } #endif // !BC_ENABLE_LIBRARY @@ -192,7 +192,7 @@ void bc_vm_handleError(BcErr e, size_t line, ...) { BC_SIG_TRYLOCK(lock); // Make sure all of stdout is written first. - s = bc_file_flushErr(&vm.fout); + s = bc_file_flushErr(&vm.fout, bc_flush_err); if (BC_ERR(s == BC_STATUS_ERROR_FATAL)) { vm.status = (sig_atomic_t) s; @@ -200,10 +200,10 @@ void bc_vm_handleError(BcErr e, size_t line, ...) { } va_start(args, line); - bc_file_putchar(&vm.ferr, '\n'); - bc_file_puts(&vm.ferr, err_type); - bc_file_putchar(&vm.ferr, ' '); - bc_file_vprintf(&vm.ferr, vm.err_msgs[e], args); + bc_file_putchar(&vm.ferr, bc_flush_none, '\n'); + bc_file_puts(&vm.ferr, bc_flush_none, err_type); + bc_file_putchar(&vm.ferr, bc_flush_none, ' '); + bc_file_vprintf(&vm.ferr, bc_flush_none, vm.err_msgs[e], args); va_end(args); if (BC_NO_ERR(vm.file)) { @@ -211,33 +211,33 @@ void bc_vm_handleError(BcErr e, size_t line, ...) { // This is the condition for parsing vs runtime. // If line is not 0, it is parsing. if (line) { - bc_file_puts(&vm.ferr, "\n "); - bc_file_puts(&vm.ferr, vm.file); - bc_file_printf(&vm.ferr, bc_err_line, line); + bc_file_puts(&vm.ferr, bc_flush_none, "\n "); + bc_file_puts(&vm.ferr, bc_flush_none, vm.file); + bc_file_printf(&vm.ferr, bc_flush_none, bc_err_line, line); } else { BcInstPtr *ip = bc_vec_item_rev(&vm.prog.stack, 0); BcFunc *f = bc_vec_item(&vm.prog.fns, ip->func); - bc_file_puts(&vm.ferr, "\n "); - bc_file_puts(&vm.ferr, vm.func_header); - bc_file_putchar(&vm.ferr, ' '); - bc_file_puts(&vm.ferr, f->name); + bc_file_puts(&vm.ferr, bc_flush_none, "\n "); + bc_file_puts(&vm.ferr, bc_flush_none, vm.func_header); + bc_file_putchar(&vm.ferr, bc_flush_none, ' '); + bc_file_puts(&vm.ferr, bc_flush_none, f->name); #if BC_ENABLED if (BC_IS_BC && ip->func != BC_PROG_MAIN && ip->func != BC_PROG_READ) { - bc_file_puts(&vm.ferr, "()"); + bc_file_puts(&vm.ferr, bc_flush_none, "()"); } #endif // BC_ENABLED } } - bc_file_puts(&vm.ferr, "\n\n"); + bc_file_puts(&vm.ferr, bc_flush_none, "\n\n"); - s = bc_file_flushErr(&vm.ferr); + s = bc_file_flushErr(&vm.ferr, bc_flush_err); #if !BC_ENABLE_MEMCHECK // Because this function is called by a BC_NORETURN function when fatal @@ -446,7 +446,7 @@ void bc_vm_printf(const char *fmt, ...) { BC_SIG_LOCK; va_start(args, fmt); - bc_file_vprintf(&vm.fout, fmt, args); + bc_file_vprintf(&vm.fout, bc_flush_none, fmt, args); va_end(args); vm.nchars = 0; @@ -455,11 +455,11 @@ void bc_vm_printf(const char *fmt, ...) { } #endif // !BC_ENABLE_LIBRARY -void bc_vm_putchar(int c) { +void bc_vm_putchar(int c, BcFlushType type) { #if BC_ENABLE_LIBRARY bc_vec_pushByte(&vm.out, (uchar) c); #else // BC_ENABLE_LIBRARY - bc_file_putchar(&vm.fout, (uchar) c); + bc_file_putchar(&vm.fout, type, (uchar) c); vm.nchars = (c == '\n' ? 0 : vm.nchars + 1); #endif // BC_ENABLE_LIBRARY } @@ -531,7 +531,7 @@ static void bc_vm_process(const char *text) { assert(BC_IS_DC || vm.prog.results.len == 0); - if (BC_I) bc_file_flush(&vm.fout); + if (BC_I) bc_file_flush(&vm.fout, bc_flush_save); } while (vm.prs.l.t != BC_LEX_EOF); } |