Mercurial > ~dholland > hg > tradcpp > index.cgi
changeset 160:d6e6b3940780
Fully implement #line.
author | Joerg Sonnenberger <joerg@bec.de> |
---|---|
date | Fri, 27 Feb 2015 02:06:49 +0100 |
parents | 8cef6d7227a8 |
children | 4a4b3d5c41fa |
files | directive.c directive.h files.c place.c place.h tests/t38.c tests/t38.good utils.c utils.h |
diffstat | 9 files changed, 97 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- a/directive.c Fri Feb 27 00:41:46 2015 +0100 +++ b/directive.c Fri Feb 27 02:06:49 2015 +0100 @@ -175,7 +175,7 @@ static void -d_if(struct place *p, struct place *p2, char *line) +d_if(struct place *p, struct place *p2, struct place *np, char *line) { char *expr; bool val; @@ -200,7 +200,7 @@ static void -d_ifdef(struct place *p, struct place *p2, char *line) +d_ifdef(struct place *p, struct place *p2, struct place *np, char *line) { uncomment(line); oneword("#ifdef", p2, line); @@ -209,7 +209,7 @@ static void -d_ifndef(struct place *p, struct place *p2, char *line) +d_ifndef(struct place *p, struct place *p2, struct place *np, char *line) { uncomment(line); oneword("#ifndef", p2, line); @@ -218,7 +218,7 @@ static void -d_elif(struct place *p, struct place *p2, char *line) +d_elif(struct place *p, struct place *p2, struct place *np, char *line) { char *expr; struct place p3 = *p2; @@ -247,7 +247,7 @@ static void -d_else(struct place *p, struct place *p2, char *line) +d_else(struct place *p, struct place *p2, struct place *np, char *line) { (void)p2; (void)line; @@ -264,7 +264,7 @@ static void -d_endif(struct place *p, struct place *p2, char *line) +d_endif(struct place *p, struct place *p2, struct place *np, char *line) { (void)p2; (void)line; @@ -282,7 +282,7 @@ static void -d_define(struct place *p, struct place *p2, char *line) +d_define(struct place *p, struct place *p2, struct place *np, char *line) { size_t pos, argpos; struct place p3, p4; @@ -347,7 +347,7 @@ static void -d_undef(struct place *p, struct place *p2, char *line) +d_undef(struct place *p, struct place *p2, struct place *np, char *line) { (void)p; @@ -383,7 +383,7 @@ static void -d_include(struct place *p, struct place *p2, char *line) +d_include(struct place *p, struct place *p2, struct place *np, char *line) { char *text; size_t oldlen; @@ -412,13 +412,63 @@ static void -d_line(struct place *p, struct place *p2, char *line) +d_line(struct place *p, struct place *p2, struct place *np, char *line) { - (void)p2; - (void)line; + char *text; + size_t oldlen; + const char *token, *start_lineno, *start_filename; + size_t len_lineno, len_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); - /* XXX */ - complain(p, "Sorry, no #line yet"); + token = text; + token += strspn(token, ws); + start_lineno = token; + len_lineno = strspn(token, digits); + if (len_lineno == 0) { + goto illegal_line; + } + 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; + } + } + np->line = atoi(start_lineno); + if (len_filename) { + char *filename = dostrndup(start_filename, len_filename); + place_setfile(np, filename); + dostrfree(filename); + } + dostrfree(text); + return; + +illegal_line: + complain(p, "Illegal #line directive"); + complain(p, "Before macro expansion: #include %s", line); + complain(p, "After macro expansion: #include %s", text); + dostrfree(text); } //////////////////////////////////////////////////////////// @@ -426,7 +476,7 @@ static void -d_warning(struct place *p, struct place *p2, char *line) +d_warning(struct place *p, struct place *p2, struct place *np, char *line) { char *msg; @@ -440,7 +490,7 @@ static void -d_error(struct place *p, struct place *p2, char *line) +d_error(struct place *p, struct place *p2, struct place *np, char *line) { char *msg; @@ -455,7 +505,7 @@ static void -d_pragma(struct place *p, struct place *p2, char *line) +d_pragma(struct place *p, struct place *p2, struct place *np, char *line) { (void)p2; @@ -469,7 +519,8 @@ static const struct { const char *name; bool ifskip; - void (*func)(struct place *, struct place *, char *line); + void (*func)(struct place *, struct place *, struct place *, + char *line); } directives[] = { { "define", true, d_define }, { "elif", false, d_elif }, @@ -489,7 +540,7 @@ static void -directive_gotdirective(struct place *p, char *line) +directive_gotdirective(struct place *p, struct place *np, char *line) { struct place p2; size_t len, skip; @@ -512,7 +563,7 @@ if (len < strlen(line)) { line[len] = '\0'; } - directives[i].func(p, &p2, line); + directives[i].func(p, &p2, np, line); return; } } @@ -574,7 +625,7 @@ } void -directive_gotline(struct place *p, char *line, size_t len) +directive_gotline(struct place *p, struct place *np, char *line, size_t len) { size_t skip; @@ -588,7 +639,7 @@ assert(skip <= len); p->column += skip; assert(line[len] == '\0'); - directive_gotdirective(p, line+skip /*, length = len-skip */); + directive_gotdirective(p, np, line+skip); p->column += len-skip; } else if (ifstate->curtrue) { macro_sendline(p, line, len);
--- a/directive.h Fri Feb 27 00:41:46 2015 +0100 +++ b/directive.h Fri Feb 27 02:06:49 2015 +0100 @@ -34,6 +34,6 @@ void directive_init(void); void directive_cleanup(void); -void directive_gotline(struct place *p, char *line, size_t len); +void directive_gotline(struct place *p, struct place *np, char *line, size_t len); void directive_goteof(struct place *p);
--- a/files.c Fri Feb 27 00:41:46 2015 +0100 +++ b/files.c Fri Feb 27 02:06:49 2015 +0100 @@ -275,7 +275,7 @@ /* if the line isn't empty, process it */ if (lineend > linestart) { - directive_gotline(&linestartplace, + directive_gotline(&linestartplace, &nextlinestartplace, buf+linestart, lineend-linestart); }
--- a/place.c Fri Feb 27 00:41:46 2015 +0100 +++ b/place.c Fri Feb 27 02:06:49 2015 +0100 @@ -154,6 +154,17 @@ p->column = 1; } +void +place_setfile(struct place *p, const char *name) +{ + assert(p->type == P_FILE); + if (strcmp(name, p->file->name) == 0) { + return; + } + p->file = placefile_create(&p->file->includedfrom, name, + p->file->fromsystemdir); +} + const char * place_getname(const struct place *p) {
--- a/place.h Fri Feb 27 00:41:46 2015 +0100 +++ b/place.h Fri Feb 27 02:06:49 2015 +0100 @@ -50,6 +50,7 @@ void place_setbuiltin(struct place *p, unsigned num); void place_setcommandline(struct place *p, unsigned word, unsigned column); void place_setfilestart(struct place *p, const struct placefile *pf); +void place_setfile(struct place *p, const char *name); const char *place_getparsedir(const struct place *incplace);
--- a/tests/t38.c Fri Feb 27 00:41:46 2015 +0100 +++ b/tests/t38.c Fri Feb 27 02:06:49 2015 +0100 @@ -3,3 +3,7 @@ __FILE__ __LINE__ m() +#line 500 +m() +#line 600 "foo.c" +m()
--- a/tests/t38.good Fri Feb 27 00:41:46 2015 +0100 +++ b/tests/t38.good Fri Feb 27 02:06:49 2015 +0100 @@ -2,3 +2,5 @@ "t38.c" 4 "t38.c":5 +"t38.c":500 +"foo.c":600