# HG changeset patch # User Joerg Sonnenberger # Date 1424994106 -3600 # Node ID 8cef6d7227a854fefadb2ac6ca9ea6f57fc820f3 # Parent 19278e2f885d07b3b9ab1d54a7b1a201f63cdb23 Expand __FILE__ and __LINE__. diff -r 19278e2f885d -r 8cef6d7227a8 macro.c --- a/macro.c Fri Feb 27 00:23:01 2015 +0100 +++ b/macro.c Fri Feb 27 00:41:46 2015 +0100 @@ -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; @@ -55,6 +56,7 @@ 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; } @@ -174,6 +198,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 +601,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) @@ -742,6 +796,7 @@ char *arg; char *ret; unsigned numargs, numparams; + char numbuf[64]; numargs = stringarray_num(&es->args); numparams = stringarray_num(&es->curmacro->params); @@ -766,11 +821,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 +842,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; } } @@ -883,11 +959,18 @@ m = macrotable_findlen(buf, len, false); if (m == NULL || m->inuse) { expand_send(es, p, buf, len); + } else if (m->isspecial) { + es->curmacro = m; + newbuf = expand_substitute(p, es); + expand_send(es, p, newbuf, strlen(newbuf)); + dostrfree(newbuf); + es->curmacro = NULL; + m->inuse = false; } else if (!m->hasparams) { m->inuse = true; assert(expansionitemarray_num(&m->expansion) == 1); ei = expansionitemarray_get(&m->expansion, 0); - assert(ei->isstring); + assert(ei->itemtype == EI_STRING); newbuf = macroexpand(p, ei->string, strlen(ei->string), false); doexpand(es, p, newbuf, strlen(newbuf)); diff -r 19278e2f885d -r 8cef6d7227a8 macro.h --- a/macro.h Fri Feb 27 00:23:01 2015 +0100 +++ b/macro.h Fri Feb 27 00:41:46 2015 +0100 @@ -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 19278e2f885d -r 8cef6d7227a8 main.c --- a/main.c Fri Feb 27 00:23:01 2015 +0100 +++ b/main.c Fri Feb 27 00:41:46 2015 +0100 @@ -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 19278e2f885d -r 8cef6d7227a8 tests/Makefile --- a/tests/Makefile Fri Feb 27 00:23:01 2015 +0100 +++ b/tests/Makefile Fri Feb 27 00:41:46 2015 +0100 @@ -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 all: run-tests .WAIT show-diffs diff -r 19278e2f885d -r 8cef6d7227a8 tests/t38.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/t38.c Fri Feb 27 00:41:46 2015 +0100 @@ -0,0 +1,5 @@ +#define m() __FILE__:__LINE__ +__LINE__ +__FILE__ +__LINE__ +m() diff -r 19278e2f885d -r 8cef6d7227a8 tests/t38.good --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/t38.good Fri Feb 27 00:41:46 2015 +0100 @@ -0,0 +1,4 @@ +2 +"t38.c" +4 +"t38.c":5