Mercurial > ~dholland > hg > tradcpp > index.cgi
diff macro.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 | 6119608a9817 |
children | d359d9b86327 |
line wrap: on
line diff
--- a/macro.c Fri Jun 12 03:04:48 2015 -0400 +++ b/macro.c Fri Jun 12 03:05:49 2015 -0400 @@ -28,6 +28,7 @@ */ #include <stdint.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> @@ -38,10 +39,10 @@ #include "output.h" struct expansionitem { - bool isstring; + enum { EI_STRING, EI_PARAM, EI_FILE, EI_LINE } itemtype; union { - char *string; - unsigned param; + char *string; /* EI_STRING */ + unsigned param; /* EI_PARAM */ }; }; DECLARRAY(expansionitem, static UNUSED); @@ -76,7 +77,7 @@ struct expansionitem *ei; ei = domalloc(sizeof(*ei)); - ei->isstring = true; + ei->itemtype = EI_STRING; ei->string = dostrdup(string); return ei; } @@ -88,7 +89,7 @@ struct expansionitem *ei; ei = domalloc(sizeof(*ei)); - ei->isstring = true; + ei->itemtype = EI_STRING; ei->string = dostrndup(string, len); return ei; } @@ -100,17 +101,45 @@ 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) { + switch (ei->itemtype) { + case EI_STRING: dostrfree(ei->string); + break; + case EI_PARAM: + case EI_FILE: + case EI_LINE: + break; } dofree(ei, sizeof(*ei)); } @@ -120,17 +149,23 @@ expansionitem_eq(const struct expansionitem *ei1, const struct expansionitem *ei2) { - if (ei1->isstring != ei2->isstring) { + if (ei1->itemtype != ei2->itemtype) { return false; } - if (ei1->isstring) { + switch (ei1->itemtype) { + case EI_STRING: if (strcmp(ei1->string, ei2->string) != 0) { return false; } - } else { + break; + case EI_PARAM: if (ei1->param != ei2->param) { return false; } + break; + case EI_FILE: + case EI_LINE: + break; } return true; } @@ -587,6 +622,24 @@ } void +macro_define_magic(struct place *p, const char *macro) +{ + struct macro *m; + struct expansionitem *ei; + + m = macro_define_common_start(p, macro, p); + if (!strcmp(macro, "__FILE__")) { + ei = expansionitem_create_file(); + } + else { + assert(!strcmp(macro, "__LINE__")); + ei = expansionitem_create_line(); + } + expansionitemarray_add(&m->expansion, ei, NULL); + macro_define_common_end(m); +} + +void macro_undef(const char *macro) { struct macro *m; @@ -624,7 +677,7 @@ static struct expstate mainstate; static void doexpand(struct expstate *es, struct place *p, - char *buf, size_t len); + const char *buf, size_t len); static void @@ -705,7 +758,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 +768,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 +795,7 @@ char *arg; char *ret; unsigned numargs, numparams; + char numbuf[64]; numargs = stringarray_num(&es->args); numparams = stringarray_num(&es->curmacro->params); @@ -766,11 +820,20 @@ num = expansionitemarray_num(&es->curmacro->expansion); for (i=0; i<num; i++) { ei = expansionitemarray_get(&es->curmacro->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 +841,23 @@ *ret = '\0'; for (i=0; i<num; i++) { ei = expansionitemarray_get(&es->curmacro->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 +921,8 @@ 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: @@ -868,7 +944,8 @@ static void -expand_got_word(struct expstate *es, struct place *p, char *buf, size_t len) +expand_got_word(struct expstate *es, struct place *p, + const char *buf, size_t len) { struct macro *m; @@ -917,7 +994,8 @@ static void -expand_got_lparen(struct expstate *es, struct place *p, char *buf, size_t len) +expand_got_lparen(struct expstate *es, struct place *p, + const char *buf, size_t len) { switch (es->state) { case ES_NORMAL: @@ -940,7 +1018,8 @@ static void -expand_got_rparen(struct expstate *es, struct place *p, char *buf, size_t len) +expand_got_rparen(struct expstate *es, struct place *p, + const char *buf, size_t len) { switch (es->state) { case ES_NORMAL: @@ -975,7 +1054,8 @@ static void -expand_got_comma(struct expstate *es, struct place *p, char *buf, size_t len) +expand_got_comma(struct expstate *es, struct place *p, + const char *buf, size_t len) { switch (es->state) { case ES_NORMAL: @@ -1003,7 +1083,8 @@ static void -expand_got_other(struct expstate *es, struct place *p, char *buf, size_t len) +expand_got_other(struct expstate *es, struct place *p, + const char *buf, size_t len) { switch (es->state) { case ES_NORMAL: @@ -1055,7 +1136,7 @@ static void -doexpand(struct expstate *es, struct place *p, char *buf, size_t len) +doexpand(struct expstate *es, struct place *p, const char *buf, size_t len) { char *s; size_t x; @@ -1144,7 +1225,7 @@ } char * -macroexpand(struct place *p, char *buf, size_t len, bool honordefined) +macroexpand(struct place *p, const char *buf, size_t len, bool honordefined) { struct expstate es; char *ret; @@ -1166,10 +1247,30 @@ } void -macro_sendline(struct place *p, char *buf, size_t len) +macro_sendline(struct place *p, const char *buf, size_t len) { doexpand(&mainstate, p, buf, len); - output(p, "\n", 1); + switch (mainstate.state) { + case ES_NORMAL: + /* + * If we were sent a blank line, don't emit a newline + * for it. This matches the prior behavior of tradcpp. + */ + if (len > 0) { + output(p, "\n", 1); + } + break; + case ES_WANTLPAREN: + case ES_NOARG: + case ES_HAVEARG: + /* + * Apparently to match gcc's -traditional behavior we + * need to emit a space for each newline that appears + * while processing macro args. + */ + expand_got_ws(&mainstate, p, " ", 1); + break; + } } void