Mercurial > ~dholland > hg > tradcpp > index.cgi
diff directive.c @ 165:cc6d6f27d6ee
Fix Joerg's #line code.
(avoid redundant whitespace grinding, don't use atoi, be simpler and
tidier, etc.)
author | David A. Holland |
---|---|
date | Fri, 12 Jun 2015 01:30:13 -0400 |
parents | f14f5352956c |
children | 6ff17ab68b16 |
line wrap: on
line diff
--- a/directive.c Fri Jun 12 01:00:38 2015 -0400 +++ b/directive.c Fri Jun 12 01:30:13 2015 -0400 @@ -31,6 +31,7 @@ #include <stdbool.h> #include <stdlib.h> #include <string.h> +#include <errno.h> #include "utils.h" #include "mode.h" @@ -417,8 +418,10 @@ { char *text; size_t oldlen; - const char *token, *start_lineno, *start_filename; - size_t len_lineno, len_filename; + unsigned long val; + char *moretext; + size_t moretextlen; + char *filename; text = macroexpand(p2, line, strlen(line), true); @@ -427,48 +430,48 @@ /* trim to fit, so the malloc debugging won't complain */ text = dorealloc(text, oldlen + 1, strlen(text) + 1); - token = text; - token += strspn(token, ws); - start_lineno = token; - len_lineno = strspn(token, digits); - if (len_lineno == 0) { - goto illegal_line; + /* + * What we should have here: either 1234 "file.c", + * or just 1234. + */ + + errno = 0; + val = strtoul(text, &moretext, 10); + if (errno) { + complain(&lp->current, "No line number in #line directive"); + goto fail; } - token += len_lineno; - token += strspn(ws, token); - if (*token == '"') { - ++token; - start_filename = token; - len_filename = strcspn(token, "\""); - token += len_filename; - if (*token != '"' || len_filename == 0) { - goto illegal_line; - } - ++token; - token += strspn(token, ws); - if (*token != '\0') { - goto illegal_line; - } - } else { - len_filename = 0; - token += strspn(token, ws); - if (*token != '\0') { - goto illegal_line; - } +#if UINT_MAX < ULONG_MAX + if (val > UINT_MAX) { + complain(&lp->current, + "Line number in #line directive too large"); + goto fail; } - lp->nextline.line = atoi(start_lineno); - if (len_filename) { - char *filename = dostrndup(start_filename, len_filename); +#endif + moretext += strspn(moretext, ws); + moretextlen = strlen(moretext); + lp->current.column += (moretext - text); + + if (moretextlen > 2 && + moretext[0] == '"' && moretext[moretextlen-1] == '"') { + filename = dostrndup(moretext+1, moretextlen-2); place_setfile(&lp->nextline, filename); dostrfree(filename); } + else if (moretextlen > 0) { + complain(&lp->current, + "Invalid file name in #line directive"); + goto fail; + } + + lp->nextline.line = val; dostrfree(text); return; -illegal_line: - complain(&lp->current, "Illegal #line directive"); - complain(&lp->current, "Before macro expansion: #include %s", line); - complain(&lp->current, "After macro expansion: #include %s", text); +fail: + complain(&lp->current, "Before macro expansion: #line %s", line); + complain(&lp->current, "After macro expansion: #line %s", text); + complain_fail(); dostrfree(text); }