# HG changeset patch # User David A. Holland # Date 1434088552 14400 # Node ID 8d8a4bfd4684013fd66628b7d221d1c59ca7fb02 # Parent fa9752f194c6538336d48e4ab5fc98dce7fe5d92# Parent e6eb15635a48ee437e97154dbc62d840e45ce80b Merge from upstream diff -r e6eb15635a48 -r 8d8a4bfd4684 directive.c --- a/directive.c Fri Jun 12 01:53:42 2015 -0400 +++ b/directive.c Fri Jun 12 01:55:52 2015 -0400 @@ -31,6 +31,7 @@ #include #include #include +#include #include "utils.h" #include "mode.h" @@ -415,11 +416,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_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; + +fail: + complain(&lp->current, "Before macro expansion: #line %s", line); + complain(&lp->current, "After macro expansion: #line %s", text); + complain_fail(); + dostrfree(text); } //////////////////////////////////////////////////////////// diff -r e6eb15635a48 -r 8d8a4bfd4684 directive.h diff -r e6eb15635a48 -r 8d8a4bfd4684 files.c diff -r e6eb15635a48 -r 8d8a4bfd4684 macro.c --- a/macro.c Fri Jun 12 01:53:42 2015 -0400 +++ b/macro.c Fri Jun 12 01:55:52 2015 -0400 @@ -28,6 +28,7 @@ */ #include +#include #include #include @@ -38,7 +39,7 @@ #include "output.h" struct expansionitem { - bool isstring; + enum { EI_PARAM, EI_STRING, EI_FILE, EI_LINE } itemtype; union { char *string; unsigned param; @@ -50,11 +51,12 @@ struct macro { struct place defplace; struct place expansionplace; - unsigned hash; - char *name; - bool hasparams; struct stringarray params; struct expansionitemarray expansion; + char *name; + unsigned hash; + bool hasparams; + bool isspecial; bool inuse; }; DECLARRAY(macro, static UNUSED); @@ -76,7 +78,7 @@ struct expansionitem *ei; ei = domalloc(sizeof(*ei)); - ei->isstring = true; + ei->itemtype = EI_STRING; ei->string = dostrdup(string); return ei; } @@ -88,7 +90,7 @@ struct expansionitem *ei; ei = domalloc(sizeof(*ei)); - ei->isstring = true; + ei->itemtype = EI_STRING; ei->string = dostrndup(string, len); return ei; } @@ -100,16 +102,38 @@ struct expansionitem *ei; ei = domalloc(sizeof(*ei)); - ei->isstring = false; + ei->itemtype = EI_PARAM; ei->param = param; return ei; } static +struct expansionitem * +expansionitem_create_file(void) +{ + struct expansionitem *ei; + + ei = domalloc(sizeof(*ei)); + ei->itemtype = EI_FILE; + return ei; +} + +static +struct expansionitem * +expansionitem_create_line(void) +{ + struct expansionitem *ei; + + ei = domalloc(sizeof(*ei)); + ei->itemtype = EI_LINE; + return ei; +} + +static void expansionitem_destroy(struct expansionitem *ei) { - if (ei->isstring) { + if (ei->itemtype == EI_STRING) { dostrfree(ei->string); } dofree(ei, sizeof(*ei)); @@ -120,10 +144,10 @@ expansionitem_eq(const struct expansionitem *ei1, const struct expansionitem *ei2) { - if (ei1->isstring != ei2->isstring) { + if ((ei1->itemtype == EI_STRING) != (ei2->itemtype == EI_STRING)) { return false; } - if (ei1->isstring) { + if (ei1->itemtype == EI_STRING) { if (strcmp(ei1->string, ei2->string) != 0) { return false; } @@ -148,6 +172,7 @@ m->hash = hash; m->name = dostrdup(name); m->hasparams = false; + m->isspecial = false; stringarray_init(&m->params); expansionitemarray_init(&m->expansion); m->inuse = false; @@ -174,6 +199,10 @@ struct expansionitem *ei1, *ei2; const char *p1, *p2; + if (m2->isspecial) { + return false; + } + if (strcmp(m1->name, m2->name) != 0) { return false; } @@ -573,6 +602,32 @@ } void +macro_define_file(struct place *p) +{ + struct macro *m; + struct expansionitem *ei; + + m = macro_define_common_start(p, "__FILE__", p); + m->isspecial = true; + ei = expansionitem_create_file(); + expansionitemarray_add(&m->expansion, ei, NULL); + macro_define_common_end(m); +} + +void +macro_define_line(struct place *p) +{ + struct macro *m; + struct expansionitem *ei; + + m = macro_define_common_start(p, "__LINE__", p); + m->isspecial = true; + ei = expansionitem_create_line(); + expansionitemarray_add(&m->expansion, ei, NULL); + macro_define_common_end(m); +} + +void macro_define_params(struct place *p1, const char *macro, struct place *p2, const char *params, struct place *p3, const char *expansion) @@ -705,7 +760,7 @@ static void -expand_newarg(struct expstate *es, char *buf, size_t len) +expand_newarg(struct expstate *es, const char *buf, size_t len) { char *text; @@ -715,7 +770,7 @@ static void -expand_appendarg(struct expstate *es, char *buf, size_t len) +expand_appendarg(struct expstate *es, const char *buf, size_t len) { unsigned num; char *text; @@ -742,6 +797,7 @@ char *arg; char *ret; unsigned numargs, numparams; + char numbuf[64]; numargs = stringarray_num(&es->args); numparams = stringarray_num(&es->curmacro->params); @@ -766,11 +822,20 @@ num = expansionitemarray_num(&es->curmacro->expansion); for (i=0; icurmacro->expansion, i); - if (ei->isstring) { + switch (ei->itemtype) { + case EI_STRING: len += strlen(ei->string); - } else { + break; + case EI_PARAM: arg = stringarray_get(&es->args, ei->param); len += strlen(arg); + break; + case EI_FILE: + len += strlen(place_getname(p)) + 2; + break; + case EI_LINE: + len += snprintf(numbuf, sizeof(numbuf), "%u", p->line); + break; } } @@ -778,11 +843,23 @@ *ret = '\0'; for (i=0; icurmacro->expansion, i); - if (ei->isstring) { + switch (ei->itemtype) { + case EI_STRING: strcat(ret, ei->string); - } else { + break; + case EI_PARAM: arg = stringarray_get(&es->args, ei->param); strcat(ret, arg); + break; + case EI_FILE: + strcat(ret, "\""); + strcat(ret, place_getname(p)); + strcat(ret, "\""); + break; + case EI_LINE: + snprintf(numbuf, sizeof(numbuf), "%u", p->line); + strcat(ret, numbuf); + break; } } @@ -846,7 +923,7 @@ static void -expand_got_ws(struct expstate *es, struct place *p, char *buf, size_t len) +expand_got_ws(struct expstate *es, struct place *p, const char *buf, size_t len) { switch (es->state) { case ES_NORMAL: @@ -1169,7 +1246,16 @@ macro_sendline(struct place *p, char *buf, size_t len) { doexpand(&mainstate, p, buf, len); - output(p, "\n", 1); + switch (mainstate.state) { + case ES_NORMAL: + output(p, "\n", 1); + break; + case ES_WANTLPAREN: + case ES_NOARG: + case ES_HAVEARG: + expand_got_ws(&mainstate, p, " ", 1); + break; + } } void diff -r e6eb15635a48 -r 8d8a4bfd4684 macro.h --- a/macro.h Fri Jun 12 01:53:42 2015 -0400 +++ b/macro.h Fri Jun 12 01:55:52 2015 -0400 @@ -35,6 +35,8 @@ void macros_init(void); void macros_cleanup(void); +void macro_define_file(struct place *); +void macro_define_line(struct place *); void macro_define_plain(struct place *, const char *macro, struct place *, const char *expansion); void macro_define_params(struct place *, const char *macro, diff -r e6eb15635a48 -r 8d8a4bfd4684 main.c --- a/main.c Fri Jun 12 01:53:42 2015 -0400 +++ b/main.c Fri Jun 12 01:55:52 2015 -0400 @@ -195,6 +195,18 @@ static void +apply_special_macros(unsigned *builtin_counter) +{ + struct place p; + + place_setbuiltin(&p, ++(*builtin_counter)); + macro_define_file(&p); + place_setbuiltin(&p, ++(*builtin_counter)); + macro_define_line(&p); +} + +static +void apply_builtin_macro(unsigned num, const char *name, const char *val) { struct place p; @@ -205,35 +217,35 @@ static void -apply_builtin_macros(void) +apply_builtin_macros(unsigned *builtin_counter) { - unsigned n = 1; - #ifdef CONFIG_OS - apply_builtin_macro(n++, CONFIG_OS, "1"); + apply_builtin_macro(++(*builtin_counter), CONFIG_OS, "1"); #endif #ifdef CONFIG_OS_2 - apply_builtin_macro(n++, CONFIG_OS_2, "1"); + apply_builtin_macro(++(*builtin_counter), CONFIG_OS_2, "1"); #endif #ifdef CONFIG_CPU - apply_builtin_macro(n++, CONFIG_CPU, "1"); + apply_builtin_macro(++(*builtin_counter), CONFIG_CPU, "1"); #endif #ifdef CONFIG_CPU_2 - apply_builtin_macro(n++, CONFIG_CPU_2, "1"); + apply_builtin_macro(++(*builtin_counter), CONFIG_CPU_2, "1"); #endif #ifdef CONFIG_SIZE - apply_builtin_macro(n++, CONFIG_SIZE, "1"); + apply_builtin_macro(++(*builtin_counter), CONFIG_SIZE, "1"); #endif #ifdef CONFIG_BINFMT - apply_builtin_macro(n++, CONFIG_BINFMT, "1"); + apply_builtin_macro(++(*builtin_counter), CONFIG_BINFMT, "1"); #endif #ifdef CONFIG_COMPILER - apply_builtin_macro(n++, CONFIG_COMPILER, VERSION_MAJOR); - apply_builtin_macro(n++, CONFIG_COMPILER_MINOR, VERSION_MINOR); - apply_builtin_macro(n++, "__VERSION__", VERSION_LONG); + apply_builtin_macro(++(*builtin_counter), CONFIG_COMPILER, + VERSION_MAJOR); + apply_builtin_macro(++(*builtin_counter), CONFIG_COMPILER_MINOR, + VERSION_MINOR); + apply_builtin_macro(++(*builtin_counter), "__VERSION__", VERSION_LONG); #endif } @@ -1031,6 +1043,7 @@ const char *inputfile = NULL; const char *outputfile = NULL; struct place cmdplace; + unsigned builtin_counter; int i; progname = strrchr(argv[0], '/'); @@ -1076,7 +1089,11 @@ mode.output_file = outputfile; loadincludepath(); - apply_builtin_macros(); + + builtin_counter = 0; + apply_special_macros(&builtin_counter); + apply_builtin_macros(&builtin_counter); + apply_commandline_macros(); read_commandline_files(); place_setnowhere(&cmdplace); diff -r e6eb15635a48 -r 8d8a4bfd4684 place.c --- a/place.c Fri Jun 12 01:53:42 2015 -0400 +++ b/place.c Fri Jun 12 01:55:52 2015 -0400 @@ -154,7 +154,17 @@ p->column = 1; } -static +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) { diff -r e6eb15635a48 -r 8d8a4bfd4684 place.h --- a/place.h Fri Jun 12 01:53:42 2015 -0400 +++ b/place.h Fri Jun 12 01:55:52 2015 -0400 @@ -47,11 +47,13 @@ void place_init(void); void place_cleanup(void); +const char *place_getname(const struct place *); void place_setnowhere(struct place *p); 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); diff -r e6eb15635a48 -r 8d8a4bfd4684 tests/Makefile --- a/tests/Makefile Fri Jun 12 01:53:42 2015 -0400 +++ b/tests/Makefile Fri Jun 12 01:55:52 2015 -0400 @@ -4,7 +4,7 @@ TESTS=\ t01 t02 t03 t04 t05 t06 t07 t08 t09 t10 t11 t12 t13 t14 t15 t16 \ t17 t18 t19 t20 t21 t22 t23 t24 t25 t26 t27 t28 t29 t30 t31 t32 \ - t33 t34 t35 t36 t37 + t33 t34 t35 t36 t37 t38 t39 all: run-tests .WAIT show-diffs diff -r e6eb15635a48 -r 8d8a4bfd4684 tests/t38.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/t38.c Fri Jun 12 01:55:52 2015 -0400 @@ -0,0 +1,9 @@ +#define m() __FILE__:__LINE__ +__LINE__ +__FILE__ +__LINE__ +m() +#line 500 +m() +#line 600 "foo.c" +m() diff -r e6eb15635a48 -r 8d8a4bfd4684 tests/t38.good --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/t38.good Fri Jun 12 01:55:52 2015 -0400 @@ -0,0 +1,6 @@ +2 +"t38.c" +4 +"t38.c":5 +"t38.c":500 +"foo.c":600 diff -r e6eb15635a48 -r 8d8a4bfd4684 tests/t39.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/t39.c Fri Jun 12 01:55:52 2015 -0400 @@ -0,0 +1,3 @@ +#define m(a,b) a::b +=m(123, +456) diff -r e6eb15635a48 -r 8d8a4bfd4684 tests/t39.good --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/t39.good Fri Jun 12 01:55:52 2015 -0400 @@ -0,0 +1,1 @@ +=123:: 456 diff -r e6eb15635a48 -r 8d8a4bfd4684 utils.c diff -r e6eb15635a48 -r 8d8a4bfd4684 utils.h