From b779c6f7d73e5f70b2d886ed75e6e65217ad1e85 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Tue, 19 May 2020 19:12:10 -0700 Subject: checkin: found a large bug associated to ident resetting the buffer vector --- include/u.h | 4 +--- sys/cmd/cc/cc.c | 4 ++-- sys/cmd/cc/cc.h | 1 + sys/cmd/cc/lex.c | 53 +++++++++++++++++++++++++++++++++++++++-------------- sys/cmd/cc/pp.c | 34 +++++++++++++++++----------------- sys/libn/bufio.c | 5 +++++ sys/libn/os.c | 2 +- 7 files changed, 66 insertions(+), 37 deletions(-) diff --git a/include/u.h b/include/u.h index 28bc2e4..3fafcda 100644 --- a/include/u.h +++ b/include/u.h @@ -17,7 +17,7 @@ typedef char byte; typedef unsigned char ubyte; typedef signed char sbyte; -typedef long long vlong; +typedef long long vlong; typedef unsigned long long uvlong; typedef unsigned int uint; @@ -39,8 +39,6 @@ typedef intptr_t intptr; typedef int error; -typedef void* Iface; - #define nil NULL // ------------------------------------------------------------------ diff --git a/sys/cmd/cc/cc.c b/sys/cmd/cc/cc.c index e348893..74040eb 100644 --- a/sys/cmd/cc/cc.c +++ b/sys/cmd/cc/cc.c @@ -286,10 +286,10 @@ compile(byte *path) .line = 1, .col = 1, }; + while (tok = lex(&C.lxr), tok.kind > Aeof) { - puttok(tok); + // puttok(tok); } - freeio(C.lxr.io); return tok.kind != Anil; } diff --git a/sys/cmd/cc/cc.h b/sys/cmd/cc/cc.h index dab351a..8a9fd80 100644 --- a/sys/cmd/cc/cc.h +++ b/sys/cmd/cc/cc.h @@ -92,6 +92,7 @@ struct Range }; void errorat(Pos x, byte *fmt, ...); +void warnat(Pos x, byte *fmt, ...); /* pre-processor */ #define DIRECTIVES \ diff --git a/sys/cmd/cc/lex.c b/sys/cmd/cc/lex.c index fc9dc0f..2a637da 100644 --- a/sys/cmd/cc/lex.c +++ b/sys/cmd/cc/lex.c @@ -38,9 +38,12 @@ getnsbyte(Lexer *lx) b = getbyte(lx); for (;;) { if (b == EOF) { - popio(lx); - b = getbyte(lx); - continue; + if (lx->io->link) { + popio(lx); + b = getbyte(lx); + continue; + } else + return b; } if (b >= RuneSelf || !isspace(b)) return b; @@ -293,6 +296,12 @@ Dispatch: lx->pos.line++; goto Dispatch; + case '\\': + b = getbyte(lx); + if (b != '\n') + errorat(lx->pos, "'\\' without a trailing newline"); + goto GetByte; + Tchar: case '\'': if (escapechar(lx, '\'', 0, 0, &v)) { @@ -493,7 +502,10 @@ Dispatch: } lx->b = s; /* reparse number, now with base info */ - while (b = getbyte(lx), (isdigit(b) || ('a' <= b && b <= 'f') || ('A' <= b && b <= 'F') || b == '_')) + while (b = getbyte(lx), (isdigit(b) || + ('a' <= b && b <= 'f') || + ('A' <= b && b <= 'F') || + b == '_')) *lx->b++ = b; } Rint: @@ -545,10 +557,12 @@ Dispatch: tok.kind |= Vun; goto Return; } + ungetbyte(lx); - } else - tok.kind |= Vint; + goto Return; + } + tok.kind |= Vint; ungetbyte(lx); goto Return; @@ -624,7 +638,8 @@ Dispatch: sym = lookup(&lx->sym, tok.val.s); if (sym) { io = makeio(); - io->buf.end += expandmacro(lx, sym, io->b); + io->buf.end += expandmacro(lx, sym, io->b); + *io->buf.end++ = EOF; pushio(lx, io); goto GetByte; } @@ -673,17 +688,14 @@ popio(Lexer *lx) Io *prev; prev = lx->io->link; + freeio(lx->io); + + lx->io = prev; if (!prev) { - panicf("no buffer left"); + return; } - /* - * NOTE: should we copy over unget bytes here? - * would modify the buffer... - */ - freeio(lx->io); lx->pos = prev->store; - lx->io = prev; } // ----------------------------------------------------------------------- @@ -763,5 +775,18 @@ errorat(Pos x, byte *fmt, ...) printf("\n"); va_end(args); + assert(0); } +void +warnat(Pos x, byte *fmt, ...) +{ + va_list args; + va_start(args, fmt); + + printf("warning:%s:%d:%d: ", os·basename(x.path), x.line, x.col); + vprintf(fmt, args); + printf("\n"); + + va_end(args); +} diff --git a/sys/cmd/cc/pp.c b/sys/cmd/cc/pp.c index 2aa1291..264f11a 100644 --- a/sys/cmd/cc/pp.c +++ b/sys/cmd/cc/pp.c @@ -34,7 +34,7 @@ string identdots(Lexer *lx, int *dots) { int c; - string s; + byte *s; s = ident(lx); if (s != nil) @@ -62,7 +62,7 @@ defmacro(Lexer *lx, string name, string macro) { Sym *mac; - printf("DEFINING MACRO %s = %s, ON LINE %d\n", name, macro+2, lx->pos.line); + printf("DEFINING MACRO %s ON LINE %d, file %s\n", name, lx->pos.line, os·basename(lx->pos.path)); mac = define(&lx->sym, name, Smacro); mac->macro = macro; @@ -397,6 +397,7 @@ enum // ----------------------------------------------------------------------- // preprocessor functions +/* #endif */ static error ppend(Lexer *lx) @@ -426,10 +427,9 @@ ppund(Lexer *lx) printf("FORGETTING %s\n", s); err = forget(&lx->sym, s); - if (err) { - errorat(lx->pos, "attempting to undefine unrecognized symbol '%s'", s); - return err; - } + if (err) + warnat(lx->pos, "attempting to undefine unrecognized symbol '%s'", s); + ppend(lx); return 0; } @@ -442,7 +442,7 @@ ppdef(Lexer *lx) int b; Sym *sym; int i, j, f, n, dot; - string s, a, buf, args[PPnarg]; + string s, a, base, buf, args[PPnarg]; s = ident(lx); if (!s) { @@ -452,11 +452,8 @@ ppdef(Lexer *lx) intern(&s); sym = lookup(&lx->sym, s); - if (sym) { - // TODO: should be a warning... - errorat(lx->pos, "macro redefined: '%s'", sym->name); - // goto Bad; - } + if (sym) + warnat(lx->pos, "macro redefined: '%s'", sym->name); n = 0; dot = 0; @@ -494,10 +491,10 @@ ppdef(Lexer *lx) if (b != '\n') b = getnsbyte(lx); - buf = str·makef("%c%c", n, PPbeg); + base = lx->b; + buf = str·makef("%c%c", n, PPbeg); for (;;) { if (isalpha(b) || b == '_') { - lx->b = lx->buf; *lx->b++ = b; b = getbyte(lx); @@ -505,7 +502,7 @@ ppdef(Lexer *lx) *lx->b++ = b; b = getbyte(lx); } - *lx->b = '\0'; + *lx->b++ = '\0'; for (i = 0; i < n; i++) { if (strcmp(lx->buf, args[i]) == 0) { @@ -999,6 +996,10 @@ Skip: lx->pos.line++; b = 1; } + if (c == EOF) { + errorat(lx->pos, "EOF hit while skipping if block. Missing endif"); + goto Bad; + } continue; } if (!b) @@ -1007,7 +1008,7 @@ Skip: if (!s) continue; - if ((strcmp(s, "elif") == 0) && l == 0) + if (l == 0 && (strcmp(s, "elif") == 0)) ppif(lx, 0); if (strcmp(s, "endif") == 0) { @@ -1019,7 +1020,6 @@ Skip: return 0; } if (strcmp(s, "if") == 0 || - strcmp(s, "elif") == 0 || strcmp(s, "ifdef") == 0 || strcmp(s, "ifndef") == 0) { l++; diff --git a/sys/libn/bufio.c b/sys/libn/bufio.c index 9bca46a..0a3c419 100644 --- a/sys/libn/bufio.c +++ b/sys/libn/bufio.c @@ -53,6 +53,11 @@ refill(io·Buffer *buf) buf->pos = buf->beg; buf->end = buf->pos + n; + // TEST: put a physical EOF byte at the end + // this would allow for an unget operation + if (n < buf->size) + *buf->end++ = EOF; + return n; } diff --git a/sys/libn/os.c b/sys/libn/os.c index c9cc0ae..75688e9 100644 --- a/sys/libn/os.c +++ b/sys/libn/os.c @@ -26,5 +26,5 @@ os·basename(byte *path) byte *sep; sep = utf8·findrrune(path, os·sep()); - return sep+1; + return (sep == nil) ? path : sep+1; } -- cgit v1.2.1