aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGavin Howard <yzena.tech@gmail.com>2021-03-31 10:55:06 -0600
committerGavin Howard <yzena.tech@gmail.com>2021-03-31 10:55:06 -0600
commit7378a7abe1ec13adbb01212dff12346f2eff003d (patch)
tree54fb83b1aedbd47d8e5dc15c086f49ca9357bb1e
parent9f8f9bc7f3bdf9d544947103855811b360301c7f (diff)
downloadbc-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.h29
-rw-r--r--include/history.h3
-rw-r--r--include/vm.h2
-rw-r--r--src/data.c4
-rw-r--r--src/file.c64
-rw-r--r--src/history.c67
-rw-r--r--src/num.c8
-rw-r--r--src/program.c20
-rw-r--r--src/read.c9
-rw-r--r--src/vm.c56
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);
diff --git a/src/data.c b/src/data.c
index 08b8b19b..993c8937 100644
--- a/src/data.c
+++ b/src/data.c
@@ -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 };
diff --git a/src/file.c b/src/file.c
index e69092f6..7175d791 100644
--- a/src/file.c
+++ b/src/file.c
@@ -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);
diff --git a/src/num.c b/src/num.c
index 6131034a..a7ab282a 100644
--- a/src/num.c
+++ b/src/num.c
@@ -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);
diff --git a/src/read.c b/src/read.c
index e593b3c2..b0c5d9f8 100644
--- a/src/read.c
+++ b/src/read.c
@@ -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;
diff --git a/src/vm.c b/src/vm.c
index 87036c7b..942cbbc6 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -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);
}