Mercurial > ~dholland > hg > tradcpp > index.cgi
diff macro.c @ 18:c08a947d8f30
deal with macro parameters
author | David A. Holland |
---|---|
date | Mon, 20 Dec 2010 01:51:47 -0500 (2010-12-20) |
parents | 76da41da923f |
children | f9792a9ec704 |
line wrap: on
line diff
--- a/macro.c Mon Dec 20 01:15:43 2010 -0500 +++ b/macro.c Mon Dec 20 01:51:47 2010 -0500 @@ -11,6 +11,8 @@ struct place expansionplace; unsigned hash; char *name; + bool hasparams; + struct stringarray params; char *expansion; }; DECLARRAY(macro); @@ -27,8 +29,8 @@ static struct macro * -macro_create(struct place *p1, struct place *p2, unsigned hash, - const char *name, const char *expansion) +macro_create(struct place *p1, const char *name, unsigned hash, + struct place *p2, const char *expansion) { struct macro *m; @@ -37,6 +39,8 @@ m->expansionplace = *p2; m->hash = hash; m->name = dostrdup(name); + m->hasparams = false; + stringarray_init(&m->params); m->expansion = dostrdup(expansion); return m; } @@ -50,6 +54,41 @@ free(m); } +static +bool +macro_eq(const struct macro *m1, const struct macro *m2) +{ + unsigned num1, num2, i; + const char *p1, *p2; + + if (strcmp(m1->name, m2->name) != 0) { + return false; + } + + if (m1->hasparams != m2->hasparams) { + return false; + } + + if (strcmp(m1->expansion, m2->expansion) != 0) { + return false; + } + + num1 = stringarray_num(&m1->params); + num2 = stringarray_num(&m2->params); + if (num1 != num2) { + return false; + } + + for (i=0; i<num1; i++) { + p1 = stringarray_get(&m1->params, i); + p2 = stringarray_get(&m2->params, i); + if (strcmp(p1, p2) != 0) { + return false; + } + } + return true; +} + //////////////////////////////////////////////////////////// // macro table @@ -238,28 +277,104 @@ //////////////////////////////////////////////////////////// // external macro definition interface -void -macro_define(struct place *p1, const char *macro, - struct place *p2, const char *expansion) +static +struct macro * +macro_define_common_start(struct place *p1, const char *macro, + struct place *p2, const char *expansion) { struct macro *m; - m = macrotable_find(macro, false); - if (m != NULL) { - if (!strcmp(expansion, m->expansion)) { - complain(p1, "Warning: redefinition of %s", macro); + if (!is_identifier(macro)) { + complain(p1, "Invalid macro name %s", macro); + complain_fail(); + } + + m = macro_create(p1, macro, hashfunc(macro), p2, expansion); + return m; +} + +static +void +macro_define_common_end(struct macro *m) +{ + struct macro *oldm; + bool ok; + + oldm = macrotable_find(m->name, false); + if (oldm != NULL) { + ok = macro_eq(m, oldm); + if (ok) { + complain(&m->defplace, + "Warning: redefinition of %s", m->name); if (mode.werror) { complain_fail(); } - return; + } else { + complain(&m->defplace, + "Redefinition of %s is not identical", + m->name); + complain_fail(); } - complain(p1, "Redefinition of %s is not identical", macro); - complain_fail(); + complain(&oldm->defplace, "Previous definition was here"); + macro_destroy(m); return; } + macrotable_add(m); +} - m = macro_create(p1, p2, hashfunc(macro), macro, expansion); - macrotable_add(m); +static +void +macro_parse_parameters(struct macro *m, struct place *p, const char *params) +{ + size_t len; + const char *s; + char *param; + + while (params != NULL) { + len = strspn(params, ws); + params += len; + p->column += len; + s = strchr(params, ','); + if (s) { + len = s-params; + param = dostrndup(params, len); + s++; + } else { + len = strlen(params); + param = dostrndup(params, len); + } + notrailingws(param, strlen(param)); + if (!is_identifier(param)) { + complain(p, "Invalid macro parameter name %s", param); + complain_fail(); + } else { + stringarray_add(&m->params, param, NULL); + } + params = s; + p->column += len; + } +} + +void +macro_define_plain(struct place *p1, const char *macro, + struct place *p2, const char *expansion) +{ + struct macro *m; + + m = macro_define_common_start(p1, macro, p2, expansion); + 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) +{ + struct macro *m; + + m = macro_define_common_start(p1, macro, p3, expansion); + macro_parse_parameters(m, p2, params); + macro_define_common_end(m); } void