Mercurial > ~dholland > hg > tradcpp > index.cgi
diff directive.c @ 178:0d5b9651b240
Merge Joerg's changes into upstream.
(now that they've been thrashed out a bit, include CHANGES entries, etc.)
author | David A. Holland |
---|---|
date | Fri, 12 Jun 2015 03:05:49 -0400 |
parents | a2f047301c15 |
children | 4c3375895c6e |
line wrap: on
line diff
--- a/directive.c Fri Jun 12 03:04:48 2015 -0400 +++ b/directive.c Fri Jun 12 03:05:49 2015 -0400 @@ -31,6 +31,8 @@ #include <stdbool.h> #include <stdlib.h> #include <string.h> +#include <limits.h> +#include <errno.h> #include "utils.h" #include "mode.h" @@ -415,11 +417,63 @@ void d_line(struct lineplace *lp, struct place *p2, char *line) { - (void)p2; - (void)line; + char *text; + size_t oldlen; + unsigned long val; + char *moretext; + size_t moretextlen; + char *filename; + + text = macroexpand(p2, line, strlen(line), true); + + oldlen = strlen(text); + uncomment(text); + /* trim to fit, so the malloc debugging won't complain */ + text = dorealloc(text, oldlen + 1, strlen(text) + 1); + + /* + * What we should have here: either 1234 "file.c", + * or just 1234. + */ - /* XXX */ - complain(&lp->current, "Sorry, no #line yet"); + errno = 0; + val = strtoul(text, &moretext, 10); + if (errno) { + complain(&lp->current, "No line number in #line directive"); + goto fail; + } +#if UINT_MAX < ULONG_MAX + if (val > UINT_MAX) { + complain(&lp->current, + "Line number in #line directive too large"); + goto fail; + } +#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_changefile(&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; + +fail: + complain(&lp->current, "Before macro expansion: #line %s", line); + complain(&lp->current, "After macro expansion: #line %s", text); + complain_fail(); + dostrfree(text); } //////////////////////////////////////////////////////////// @@ -584,7 +638,7 @@ } /* check if we have a directive line (# exactly in column 0) */ - if (line[0] == '#') { + if (len > 0 && line[0] == '#') { skip = 1 + strspn(line + 1, ws); assert(skip <= len); lp->current.column += skip;