Mercurial > ~dholland > hg > tradcpp > index.cgi
diff directive.c @ 64:f50b4ea6cbfe
Prune single-line comments from (most) directive lines.
Also, don't pass the string length to the directive processing
functions, as half of them weren't honoring it. Instead, ensure that
the directive line is terminated at the place the directive processing
functions should stop looking at it.
author | David A. Holland |
---|---|
date | Sun, 31 Mar 2013 02:04:56 -0400 |
parents | 90c6052410ce |
children | f8507e5ed84c |
line wrap: on
line diff
--- a/directive.c Sun Mar 31 02:02:16 2013 -0400 +++ b/directive.c Sun Mar 31 02:04:56 2013 -0400 @@ -57,6 +57,41 @@ static void +uncomment(char *buf) +{ + char *s, *t, *u = NULL; + bool incomment = false; + + for (s = t = buf; *s; s++) { + if (incomment) { + if (s[0] == '*' && s[1] == '/') { + s++; + incomment = false; + } + } else { + if (s[0] == '/' && s[1] == '*') { + incomment = true; + } else { + if (t != s) { + *t = *s; + } + if (!strchr(ws, *t)) { + u = t; + } + t++; + } + } + } + if (u) { + /* end string after last non-whitespace char */ + u[1] = '\0'; + } else { + *t = '\0'; + } +} + +static +void oneword(const char *what, struct place *p2, char *line) { size_t pos; @@ -119,13 +154,14 @@ static void -d_if(struct place *p, struct place *p2, char *line, size_t len) +d_if(struct place *p, struct place *p2, char *line) { char *expr; bool val; struct place p3 = *p2; - expr = macroexpand(p2, line, len, true); + uncomment(line); + expr = macroexpand(p2, line, strlen(line), true); val = eval(&p3, expr); ifstate_push(p, val); dostrfree(expr); @@ -133,23 +169,25 @@ static void -d_ifdef(struct place *p, struct place *p2, char *line, size_t len) +d_ifdef(struct place *p, struct place *p2, char *line) { + uncomment(line); oneword("#ifdef", p2, line); ifstate_push(p, macro_isdefined(line)); } static void -d_ifndef(struct place *p, struct place *p2, char *line, size_t len) +d_ifndef(struct place *p, struct place *p2, char *line) { + uncomment(line); oneword("#ifndef", p2, line); ifstate_push(p, !macro_isdefined(line)); } static void -d_elif(struct place *p, struct place *p2, char *line, size_t len) +d_elif(struct place *p, struct place *p2, char *line) { char *expr; struct place p3 = *p2; @@ -162,7 +200,8 @@ if (ifstate->evertrue) { ifstate->curtrue = false; } else { - expr = macroexpand(p2, line, len, true); + uncomment(line); + expr = macroexpand(p2, line, strlen(line), true); ifstate->curtrue = eval(&p3, expr); ifstate->evertrue = ifstate->curtrue; dostrfree(expr); @@ -171,7 +210,7 @@ static void -d_else(struct place *p, struct place *p2, char *line, size_t len) +d_else(struct place *p, struct place *p2, char *line) { if (ifstate->seenelse) { complain(p, "Multiple #else directives in one conditional"); @@ -185,7 +224,7 @@ static void -d_endif(struct place *p, struct place *p2, char *line, size_t len) +d_endif(struct place *p, struct place *p2, char *line) { if (ifstate->prev == NULL) { complain(p, "Unmatched #endif"); @@ -200,7 +239,7 @@ static void -d_define(struct place *p, struct place *p2, char *line, size_t len) +d_define(struct place *p, struct place *p2, char *line) { size_t pos, argpos; struct place p3, p4; @@ -263,8 +302,9 @@ static void -d_undef(struct place *p, struct place *p2, char *line, size_t len) +d_undef(struct place *p, struct place *p2, char *line) { + uncomment(line); oneword("#undef", p2, line); macro_undef(line); } @@ -274,8 +314,11 @@ static bool -tryinclude(struct place *p, char *line, size_t len) +tryinclude(struct place *p, char *line) { + size_t len; + + len = strlen(line); if (len > 2 && line[0] == '"' && line[len-1] == '"') { line[len-1] = '\0'; file_readquote(p, line+1); @@ -293,15 +336,16 @@ static void -d_include(struct place *p, struct place *p2, char *line, size_t len) +d_include(struct place *p, struct place *p2, char *line) { char *text; - if (tryinclude(p, line, len)) { + uncomment(line); + if (tryinclude(p, line)) { return; } - text = macroexpand(p2, line, len, false); - if (tryinclude(p, text, strlen(text))) { + text = macroexpand(p2, line, strlen(line), false); + if (tryinclude(p, text)) { dostrfree(text); return; } @@ -312,7 +356,7 @@ static void -d_line(struct place *p, struct place *p2, char *line, size_t len) +d_line(struct place *p, struct place *p2, char *line) { /* XXX */ complain(p, "Sorry, no #line yet"); @@ -323,11 +367,11 @@ static void -d_warning(struct place *p, struct place *p2, char *line, size_t len) +d_warning(struct place *p, struct place *p2, char *line) { char *msg; - msg = macroexpand(p2, line, len, false); + msg = macroexpand(p2, line, strlen(line), false); complain(p, "#warning: %s", msg); if (mode.werror) { complain_fail(); @@ -337,11 +381,11 @@ static void -d_error(struct place *p, struct place *p2, char *line, size_t len) +d_error(struct place *p, struct place *p2, char *line) { char *msg; - msg = macroexpand(p2, line, len, false); + msg = macroexpand(p2, line, strlen(line), false); complain(p, "#error: %s", msg); complain_fail(); dostrfree(msg); @@ -352,7 +396,7 @@ static void -d_pragma(struct place *p, struct place *p2, char *line, size_t len) +d_pragma(struct place *p, struct place *p2, char *line) { complain(p, "#pragma %s", line); complain_fail(); @@ -364,7 +408,7 @@ static const struct { const char *name; bool ifskip; - void (*func)(struct place *, struct place *, char *line, size_t len); + void (*func)(struct place *, struct place *, char *line); } directives[] = { { "define", true, d_define }, { "elif", false, d_elif }, @@ -384,7 +428,7 @@ static void -directive_gotdirective(struct place *p, char *line, size_t linelen) +directive_gotdirective(struct place *p, char *line) { struct place p2; size_t len, skip; @@ -401,9 +445,13 @@ skip = len + strspn(line+len, ws); p2.column += skip; line += skip; - linelen -= skip; - linelen = notrailingws(line, linelen); - directives[i].func(p, &p2, line, linelen); + + len = strlen(line); + len = notrailingws(line, len); + if (len < strlen(line)) { + line[len] = '\0'; + } + directives[i].func(p, &p2, line); return; } } @@ -526,10 +574,19 @@ /* check if we have a directive line */ skip = strspn(line + acomm, ws); if (acomm == 0 && line[skip] == '#') { + char ch; + skip = skip + 1 + strspn(line + skip + 1, ws); assert(skip <= text); p->column += skip; - directive_gotdirective(p, line+skip, text-skip); + assert(line[len] == '\0'); + /* ensure null termination for directives */ + ch = line[text]; + if (ch != '\0') { + line[text] = '\0'; + } + directive_gotdirective(p, line+skip /*, length = text-skip */); + line[text] = ch; p->column += text-skip; } else if (ifstate->curtrue) { macro_sendline(p, line + acomm, text);