/* 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; }
/* Recursively examines an expression tree and sets the definition * state of any identifiers within that appear in the given symset. * The third parameter indicates whether the identifiers are to be * treated as defined or as undefined. */ int markdefined(struct exptree *t, struct symset *set, int defined) { long value; int count, n; count = 0; for (n = 0 ; n < t->childcount ; ++n) count += markdefined(t->child[n], set, defined); if (!t->valued) { if (t->exp == expDefined) { if (findsymbolinset(set, t->identifier, NULL)) { t->valued = TRUE; t->value = defined ? 1 : 0; ++count; } } else if (t->exp == expMacro) { if (findsymbolinset(set, t->begin, &value)) { t->valued = TRUE; t->value = defined ? value : 0; ++count; } } } return count; }