diff options
| -rw-r--r-- | c/lex.c | 2 | ||||
| -rw-r--r-- | common.h | 19 | ||||
| -rw-r--r-- | io.c | 67 | ||||
| -rw-r--r-- | main.c | 11 |
4 files changed, 66 insertions, 33 deletions
@@ -1206,7 +1206,7 @@ advancemacro(struct lexer *lx, struct token *tk) return 0; } *tk = rl.tk[lx->macstk->idx++]; - assert(tk->t); + assert(tk->t && tk->t != TKEOF); tk->span.ex = lx->macstk->exspan; if (tryexpand(lx, tk)) return 0; @@ -541,11 +541,17 @@ rsiter(int *i, uvlong rs) /********/ struct wbuf { - char *buf; - const uint cap; - uint len; - int fd; + union { + struct { + char *buf; + const uint cap; + uint len; + int fd; + }; + void *fp; + }; bool err; + bool isfp; }; /* read-only file mapping that is at least 1 page larger than the real file @@ -562,9 +568,10 @@ struct embedfile { size_t len; }; -#define MEMBUF(buf, cap) { (buf), (cap), .fd = -1 } -#define FDBUF(buf, cap, fd_) { (buf), (cap), .fd = (fd_) } +#define MEMBUF(buf_, cap_) { .buf = (buf_), .cap = (cap_), .fd = -1 } +#define FDBUF(buf_, cap_, fd_) { .buf = (buf_), .cap = (cap_), .fd = (fd_) } extern struct wbuf bstdout, bstderr; +void ioinit(void); void iowrite(struct wbuf *, const void *src, int n); void ioputc(struct wbuf *, uchar); void ioflush(struct wbuf *); @@ -1,22 +1,35 @@ #include "c/lex.h" +#include <errno.h> +#include <fcntl.h> #include <limits.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> -#include <fcntl.h> #include <sys/mman.h> #include <sys/stat.h> #include <unistd.h> -#include <errno.h> -static char stdoutbuf[1024], stderrbuf[1024]; -struct wbuf bstdout = FDBUF(stdoutbuf, sizeof stdoutbuf, 1), - bstderr = FDBUF(stderrbuf, sizeof stderrbuf, 2); +struct wbuf bstdout, bstderr; + +void +ioinit(void) +{ + bstdout.fp = stdout; + bstdout.isfp = 1; + bstderr.fp = stderr; + bstderr.isfp = 1; +} void iowrite(struct wbuf *buf, const void *Src, int n) { const uchar *src = Src; + if (buf->isfp) { + fwrite(Src, 1, n, buf->fp); + buf->err = ferror(buf->fp) != 0; + return; + } while (n > 0) { int avail = buf->cap - buf->len; int amt = avail < n ? avail : n; @@ -40,6 +53,11 @@ ioflush(struct wbuf *buf) { int i, ret; + if (buf->isfp) { + fflush(buf->fp); + buf->err = ferror(buf->fp) != 0; + return; + } buf->err = 0; if (buf->fd < 0) { buf->len = 0; @@ -63,6 +81,10 @@ ioflush(struct wbuf *buf) void ioputc(struct wbuf *buf, uchar c) { + if (buf->isfp) { + buf->err = fputc(c, buf->fp) != EOF; + return; + } if (buf->len == buf->cap) { if (buf->fd < 0) { buf->err = 1; @@ -381,6 +403,7 @@ vbfmt(struct wbuf *out, const char *fmt, va_list ap) case 'S': /* string ptr + len */ s = va_arg(ap, const char *); i = va_arg(ap, uint); + PriS: assert(s && "%S null"); if (quote) { n += bputc(buf, '"'); @@ -468,9 +491,16 @@ vbfmt(struct wbuf *out, const char *fmt, va_list ap) n += bwriteS(buf, "\?\?\?"); break; case TKNUMLIT: - if (quote) n += bputc(buf, '`'); - n += bfmt(buf, "%S", tok->s, tok->len); - if (quote) n += bputc(buf, '\''); + if (quote) { + n += bputc(buf, '`'); + iowrite(buf, tok->s, tok->len); + n += tok->len; + n += bputc(buf, '\''); + } else { + s = tok->s; + i = tok->len; + goto PriS; + } break; case TKCHRLIT: if (tok->wide) n += bputc(buf, tok->wideuni ? tok->wide == 1 ? 'u' : 'U' : 'L'); @@ -490,9 +520,12 @@ vbfmt(struct wbuf *out, const char *fmt, va_list ap) n += bputc(buf, '\''); break; case TKSTRLIT: - if (tok->wide == 0) - n += bfmt(buf, "%'S", tok->s, tok->len); - else { + if (tok->wide == 0) { + s = tok->s; + i = tok->len; + quote = 1; + goto PriS; + } else { n += bputc(buf, tok->wideuni ? tok->wide == 1 ? 'u' : 'U' : 'L'); n += bputc(buf, '\"'); for (int i = 0; i < tok->len; ++i) { @@ -547,7 +580,8 @@ vbfmt(struct wbuf *out, const char *fmt, va_list ap) default: if (quote) n += bputc(buf, '`'); if (in_range(tok->t, TKWBEGIN_, TKWEND_)) { - n += bfmt(buf, "%s", tok->s); + iowrite(buf, tok->s, tok->len); + n += tok->len; } else if (aisprint(tok->t)) { n += bputc(buf, tok->t); } else { @@ -561,16 +595,16 @@ vbfmt(struct wbuf *out, const char *fmt, va_list ap) tok = &(struct token) { va_arg(ap, int) }; switch (tok->t) { case TKNUMLIT: - n += bfmt(buf, "numeric literal"); + n += bwriteS(buf, "numeric literal"); break; case TKSTRLIT: - n += bfmt(buf, "string literal"); + n += bwriteS(buf, "string literal"); break; case TKIDENT: - n += bfmt(buf, "identifier"); + n += bwriteS(buf, "identifier"); break; case TKEOF: - n += bfmt(buf, "<end-of-file>"); + n += bwriteS(buf, "<end-of-file>"); break; default: if (tok->t >= TKWBEGIN_ && tok->t <= TKWEND_) { @@ -628,6 +662,7 @@ vbfmt(struct wbuf *out, const char *fmt, va_list ap) if (pad > 0) { /* left pad */ while (pad-- > buf->len) n += bputc(out, ' '); + assert(buf != out); iowrite(out, buf->buf, buf->len); out->err |= buf->err; } else if (pad < 0) { /* right pad */ @@ -9,13 +9,6 @@ struct option ccopt; struct inclpaths *cinclpaths; -static void -flushstd(void) -{ - ioflush(&bstdout); - ioflush(&bstderr); -} - /* parse an argument of the form 'opt=abcd' * e.g. arg="foo=bar123"; opt="foo"; returns "bar123" */ static const char * @@ -236,7 +229,6 @@ compileobjs(void) if (!ccopt.dbg.any) mktemps(); for (int i = 0; i < task.ninf; ++i) { - flushstd(); if ((p = fork()) < 0) { error(NULL, "fork(): %s\n", strerror(errno)); exit(1); @@ -284,7 +276,6 @@ dolink(void) efmt("\n"); } vpush(&cmd, NULL); - flushstd(); if ((p = fork()) < 0) { error(NULL, "fork(): %s\n", strerror(errno)); exit(1); @@ -410,9 +401,9 @@ sysinclpaths(void) int main(int argc, char **argv) { - atexit(flushstd); globarena->cap = sizeof(_arenamem.mem) - sizeof(struct arena); + ioinit(); /* setup defaults */ detectcolor(); sysinclpaths(); |