/* Partially preprocesses a #if expression. ifexp points to the text * immediately following the #if. The function seeks to the end of the * expression and evaluates it. The return value points to the text * immediately following the expression. If the expression has a * defined state, status receives either statDefined or statUndefined. * If the expression's contents are disjoint from the defined and * undefined symbols, status receives statUnaffected. Otherwise the * expression is in a partial state, in which case status receives * statPartDefined, and the original string is modified so as to * remove the parts of the expression that have a defined state. */ static char const *seqif(struct ppproc *ppp, char *ifexp, enum status *status) { struct exptree *tree; char const *ret; char *str; int defined, n; tree = initexptree(); *status = statUnaffected; n = geterrormark(); ret = parseexptree(tree, ppp->cl, ifexp); if (errorsincemark(n)) { *status = statError; goto quit; } n = markdefined(tree, ppp->defs, TRUE) + markdefined(tree, ppp->undefs, FALSE); if (n) { *status = evaltree(tree, &defined) ? statDefined : statUndefined; if (!defined) { *status = statPartDefined; str = allocate(strlen(ifexp) + 1); n = unparseevaluated(tree, str); strcpy(str + n, ifexp + getexplength(tree)); strcpy(ifexp, str); deallocate(str); } } quit: freeexptree(tree); return ret; }
/* Deallocates the expression tree. */ void freeexptree(struct exptree *t) { int n; if (t) { for (n = 0 ; n < t->childcount ; ++n) freeexptree(t->child[n]); deallocate(t); } }