aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/cc/pp.c
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2020-05-19 16:37:23 -0700
committerNicholas Noll <nbnoll@eml.cc>2020-05-19 16:37:23 -0700
commit13772a8a2120017981d280bfe120fdbb74f27860 (patch)
tree0dcd2245580572297fe258f3bc4d681df2756680 /sys/cmd/cc/pp.c
parent02103dfd518faf327f7edc13695435308ddcead8 (diff)
fix: many bug fixes to number parsing
Diffstat (limited to 'sys/cmd/cc/pp.c')
-rw-r--r--sys/cmd/cc/pp.c58
1 files changed, 45 insertions, 13 deletions
diff --git a/sys/cmd/cc/pp.c b/sys/cmd/cc/pp.c
index 16fac29..2aa1291 100644
--- a/sys/cmd/cc/pp.c
+++ b/sys/cmd/cc/pp.c
@@ -62,7 +62,7 @@ defmacro(Lexer *lx, string name, string macro)
{
Sym *mac;
- printf("DEFINING MACRO %s = %s, ON LINE %d\n", name, macro+1, lx->pos.line);
+ printf("DEFINING MACRO %s = %s, ON LINE %d\n", name, macro+2, lx->pos.line);
mac = define(&lx->sym, name, Smacro);
mac->macro = macro;
@@ -187,7 +187,10 @@ evalmacro(Lexer *lx, byte prec)
l = opand(lx);
for (;;) {
b = getnsbyte(lx);
- if (b == '\n') {
+ // NOTE: Either this or we pass in what are stopping byte is
+ // New line should always stop us...
+ // Is there any case where we SHOULDN'T STOP ON ')'?
+ if (b == '\n' || b == ')') {
ungetbyte(lx);
break;
}
@@ -196,7 +199,6 @@ evalmacro(Lexer *lx, byte prec)
tok = lex(lx);
// simplified jump table of precedence
// unpacked to evaluate inline
- // NOTE: You might have to unget bytes to replace token on stack
switch (tok.kind & Vmask) {
case Astar:
if (prec > 10) {
@@ -451,12 +453,14 @@ ppdef(Lexer *lx)
sym = lookup(&lx->sym, s);
if (sym) {
+ // TODO: should be a warning...
errorat(lx->pos, "macro redefined: '%s'", sym->name);
// goto Bad;
}
- n = 0;
- b = getbyte(lx);
+ n = 0;
+ dot = 0;
+ b = getbyte(lx);
if (b == '(') {
b = getnsbyte(lx);
if (b != ')') {
@@ -490,7 +494,7 @@ ppdef(Lexer *lx)
if (b != '\n')
b = getnsbyte(lx);
- buf = str·makef("%d%c", n, PPbeg);
+ buf = str·makef("%c%c", n, PPbeg);
for (;;) {
if (isalpha(b) || b == '_') {
lx->b = lx->buf;
@@ -512,7 +516,8 @@ ppdef(Lexer *lx)
continue;
Args:
/* Check for argx ## argy OR argx##argy */
- if (isspace(b)) {
+ f = 0;
+ if (b != '\n' && isspace(b)) {
b = getnsbyte(lx);
f = 1;
}
@@ -550,6 +555,7 @@ ppdef(Lexer *lx)
str·appendbyte(&buf, 'a' + i);
continue;
}
+
if (b == '/') {
b = getbyte(lx);
if (b == '/') {
@@ -577,6 +583,7 @@ ppdef(Lexer *lx)
str·appendbyte(&buf, '/');
continue;
}
+
if (b == '\\') {
b = getbyte(lx);
/* unix */
@@ -607,6 +614,7 @@ ppdef(Lexer *lx)
errorat(lx->pos, "macro operator '##' must be proceeded by a valid variable identifier");
goto Bad;
}
+
lx->b = lx->buf;
while (isalnum(b) || b == '_') {
*lx->b++ = b;
@@ -654,17 +662,25 @@ expandmacro(Lexer *lx, Sym *s, byte *dst)
byte b, *it, *e, *arg[PPnarg];
/* not a function macro */
- if (*s->macro == '\0') {
- strcpy(dst, s->macro + 1);
- return 0;
+ if (s->macro[0] == '\0') {
+ if (s->macro[1] != PPbeg) {
+ errorat(lx->pos, "malformed macro");
+ goto Bad;
+ }
+ strcpy(dst, s->macro + 2);
+ return str·len(s->macro)-2;
}
+ printf("%c\n", s->macro[0]);
+ printf("%c\n", s->macro[1]);
dots = *s->macro & PPvar;
nargs = (*s->macro & ~PPvar) - 1;
b = getnsbyte(lx);
- if (b != '(')
+ if (b != '(') {
+ errorat(lx->pos, "macro function not given arguments");
goto Bad;
+ }
n = 0;
b = getbyte(lx);
if (b != ')') {
@@ -791,23 +807,39 @@ expandmacro(Lexer *lx, Sym *s, byte *dst)
}
strcpy(dst, arg[b]);
dst += strlen(arg[b]);
+
break;
case PPstr:
b = *it++;
b -= 'a';
+ if (b < 0 && b > n) {
+ errorat(lx->pos, "malformed macro index: %s", s->name);
+ goto Bad;
+ }
*dst++ = '"';
strcpy(dst, arg[b]);
*dst++ = '"';
+
break;
case PPcat:
b = *it++;
b -= 'a';
+ if (b < 0 && b > n) {
+ errorat(lx->pos, "malformed macro index: %s", s->name);
+ goto Bad;
+ }
strcpy(dst, arg[b]);
+
b = *it++;
b -= 'a';
+ if (b < 0 && b > n) {
+ errorat(lx->pos, "malformed macro index: %s", s->name);
+ goto Bad;
+ }
strcpy(dst, arg[b]);
+
break;
case '\0':
@@ -822,10 +854,10 @@ End:
*dst = '\0';
return dst - e;
Nospace:
- errorf("out of memory during macro expansion %s", s->name);
+ errorat(lx->pos, "out of memory during macro expansion %s", s->name);
Bad:
ppend(lx);
- errorf("failed to expand macro %s", s->name);
+ errorat(lx->pos, "failed to expand macro %s", s->name);
return -1;
}