tradcpp: upgrade to 0.5.3

This commit is contained in:
Jon Trulson
2019-12-03 18:12:22 -07:00
parent 15dfdf231a
commit ec8f4b7464
28 changed files with 843 additions and 186 deletions

View File

@@ -28,9 +28,11 @@
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "union.h"
#include "array.h"
#include "mode.h"
#include "place.h"
@@ -38,15 +40,21 @@
#include "output.h"
struct expansionitem {
bool isstring;
enum { EI_STRING, EI_PARAM, EI_FILE, EI_LINE } itemtype;
union {
char *string;
unsigned param;
};
char *ei_string; /* for EI_STRING */
unsigned ei_param; /* for EI_PARAM */
} UN;
};
DECLARRAY(expansionitem, static UNUSED);
DEFARRAY(expansionitem, static);
#ifdef NEED_UNION_ACCESSORS
#define ei_string un.ei_string
#define ei_param un.ei_param
#endif
struct macro {
struct place defplace;
struct place expansionplace;
@@ -76,8 +84,8 @@ expansionitem_create_string(const char *string)
struct expansionitem *ei;
ei = domalloc(sizeof(*ei));
ei->isstring = true;
ei->string = dostrdup(string);
ei->itemtype = EI_STRING;
ei->ei_string = dostrdup(string);
return ei;
}
@@ -88,8 +96,8 @@ expansionitem_create_stringlen(const char *string, size_t len)
struct expansionitem *ei;
ei = domalloc(sizeof(*ei));
ei->isstring = true;
ei->string = dostrndup(string, len);
ei->itemtype = EI_STRING;
ei->ei_string = dostrndup(string, len);
return ei;
}
@@ -100,8 +108,30 @@ expansionitem_create_param(unsigned param)
struct expansionitem *ei;
ei = domalloc(sizeof(*ei));
ei->isstring = false;
ei->param = param;
ei->itemtype = EI_PARAM;
ei->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;
}
@@ -109,8 +139,14 @@ static
void
expansionitem_destroy(struct expansionitem *ei)
{
if (ei->isstring) {
dostrfree(ei->string);
switch (ei->itemtype) {
case EI_STRING:
dostrfree(ei->ei_string);
break;
case EI_PARAM:
case EI_FILE:
case EI_LINE:
break;
}
dofree(ei, sizeof(*ei));
}
@@ -120,17 +156,23 @@ bool
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) {
if (strcmp(ei1->string, ei2->string) != 0) {
switch (ei1->itemtype) {
case EI_STRING:
if (strcmp(ei1->ei_string, ei2->ei_string) != 0) {
return false;
}
} else {
if (ei1->param != ei2->param) {
break;
case EI_PARAM:
if (ei1->ei_param != ei2->ei_param) {
return false;
}
break;
case EI_FILE:
case EI_LINE:
break;
}
return true;
}
@@ -298,7 +340,7 @@ macrotable_cleanup(void)
static
struct macro *
macrotable_findlen(const char *name, size_t len, bool remove)
macrotable_findlen(const char *name, size_t len, bool remove_it)
{
unsigned hash;
struct macroarray *bucket;
@@ -319,7 +361,7 @@ macrotable_findlen(const char *name, size_t len, bool remove)
}
mlen = strlen(m->name);
if (len == mlen && !memcmp(name, m->name, len)) {
if (remove) {
if (remove_it) {
if (i < num-1) {
m2 = macroarray_get(bucket, num-1);
macroarray_set(bucket, i, m2);
@@ -335,9 +377,9 @@ macrotable_findlen(const char *name, size_t len, bool remove)
static
struct macro *
macrotable_find(const char *name, bool remove)
macrotable_find(const char *name, bool remove_it)
{
return macrotable_findlen(name, strlen(name), remove);
return macrotable_findlen(name, strlen(name), remove_it);
}
static
@@ -481,7 +523,7 @@ macro_parse_parameters(struct macro *m, struct place *p, const char *params)
while (params != NULL) {
len = strspn(params, ws);
params += len;
p->column += len;
place_addcolumns(p, len);
s = strchr(params, ',');
if (s) {
len = s-params;
@@ -499,7 +541,7 @@ macro_parse_parameters(struct macro *m, struct place *p, const char *params)
stringarray_add(&m->params, param, NULL);
}
params = s;
p->column += len;
place_addcolumns(p, len);
}
}
@@ -586,6 +628,24 @@ macro_define_params(struct place *p1, const char *macro,
macro_define_common_end(m);
}
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)
{
@@ -624,7 +684,7 @@ struct expstate {
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 +765,7 @@ expand_send_eof(struct expstate *es, struct place *p)
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 +775,7 @@ expand_newarg(struct expstate *es, char *buf, size_t len)
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 +802,7 @@ expand_substitute(struct place *p, struct expstate *es)
char *arg;
char *ret;
unsigned numargs, numparams;
char numbuf[64];
numargs = stringarray_num(&es->args);
numparams = stringarray_num(&es->curmacro->params);
@@ -766,11 +827,20 @@ expand_substitute(struct place *p, struct expstate *es)
num = expansionitemarray_num(&es->curmacro->expansion);
for (i=0; i<num; i++) {
ei = expansionitemarray_get(&es->curmacro->expansion, i);
if (ei->isstring) {
len += strlen(ei->string);
} else {
arg = stringarray_get(&es->args, ei->param);
switch (ei->itemtype) {
case EI_STRING:
len += strlen(ei->ei_string);
break;
case EI_PARAM:
arg = stringarray_get(&es->args, ei->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 +848,23 @@ expand_substitute(struct place *p, struct expstate *es)
*ret = '\0';
for (i=0; i<num; i++) {
ei = expansionitemarray_get(&es->curmacro->expansion, i);
if (ei->isstring) {
strcat(ret, ei->string);
} else {
arg = stringarray_get(&es->args, ei->param);
switch (ei->itemtype) {
case EI_STRING:
strcat(ret, ei->ei_string);
break;
case EI_PARAM:
arg = stringarray_get(&es->args, ei->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;
}
}
@@ -794,6 +876,7 @@ void
expand_domacro(struct expstate *es, struct place *p)
{
struct macro *m;
const char *name, *val;
char *newbuf, *newbuf2;
if (es->curmacro == NULL) {
@@ -804,23 +887,32 @@ expand_domacro(struct expstate *es, struct place *p)
expand_send(es, p, "0", 1);
return;
}
m = macrotable_find(stringarray_get(&es->args, 0), false);
expand_send(es, p, (m != NULL) ? "1" : "0", 1);
name = stringarray_get(&es->args, 0);
m = macrotable_find(name, false);
val = (m != NULL) ? "1" : "0";
debuglog(p, "defined(%s): %s", name, val);
expand_send(es, p, val, 1);
expstate_destroyargs(es);
return;
}
assert(es->curmacro->inuse == false);
es->curmacro->inuse = true;
m = es->curmacro;
assert(m->inuse == false);
m->inuse = true;
debuglog(p, "Expanding macro %s", m->name);
newbuf = expand_substitute(p, es);
debuglog(p, "Substituting for %s: %s", m->name, newbuf);
newbuf2 = macroexpand(p, newbuf, strlen(newbuf), false);
dostrfree(newbuf);
expstate_destroyargs(es);
debuglog(p, "Complete expansion for %s: %s", m->name, newbuf2);
doexpand(es, p, newbuf2, strlen(newbuf2));
dostrfree(newbuf2);
es->curmacro->inuse = false;
m->inuse = false;
}
/*
@@ -846,13 +938,16 @@ expand_missingargs(struct expstate *es, struct place *p, bool needspace)
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:
expand_send(es, p, buf, len);
break;
case ES_WANTLPAREN:
/* XXX notyet */
//expand_send(es, p, buf, len);
break;
case ES_NOARG:
expand_newarg(es, buf, len);
@@ -866,11 +961,10 @@ expand_got_ws(struct expstate *es, struct place *p, char *buf, size_t len)
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;
struct expansionitem *ei;
char *newbuf;
switch (es->state) {
case ES_NORMAL:
@@ -884,15 +978,8 @@ expand_got_word(struct expstate *es, struct place *p, char *buf, size_t len)
if (m == NULL || m->inuse) {
expand_send(es, p, buf, len);
} else if (!m->hasparams) {
m->inuse = true;
assert(expansionitemarray_num(&m->expansion) == 1);
ei = expansionitemarray_get(&m->expansion, 0);
assert(ei->isstring);
newbuf = macroexpand(p, ei->string,
strlen(ei->string), false);
doexpand(es, p, newbuf, strlen(newbuf));
dostrfree(newbuf);
m->inuse = false;
es->curmacro = m;
expand_domacro(es, p);
} else {
es->curmacro = m;
es->state = ES_WANTLPAREN;
@@ -923,7 +1010,8 @@ expand_got_word(struct expstate *es, struct place *p, char *buf, size_t len)
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:
@@ -946,7 +1034,8 @@ expand_got_lparen(struct expstate *es, struct place *p, char *buf, size_t len)
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:
@@ -981,7 +1070,8 @@ expand_got_rparen(struct expstate *es, struct place *p, char *buf, size_t len)
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:
@@ -1009,7 +1099,8 @@ expand_got_comma(struct expstate *es, struct place *p, char *buf, size_t len)
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:
@@ -1061,7 +1152,7 @@ expand_got_eof(struct expstate *es, struct place *p)
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;
@@ -1150,7 +1241,7 @@ doexpand(struct expstate *es, struct place *p, char *buf, size_t len)
}
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;
@@ -1172,10 +1263,30 @@ macroexpand(struct place *p, char *buf, size_t len, bool honordefined)
}
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