예제 #1
0
파일: exptree.c 프로젝트: pix/cppp
/* 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;
}
예제 #2
0
파일: ppproc.c 프로젝트: BR903/cppp
/* Partially preprocesses the current line of input. If the input
 * contains a preprocessor statement, the state of ppproc is updated
 * to reflect the current section, and if necessary the line of input
 * will be altered for output.
 */
static void seq(struct ppproc *ppp)
{
    char const *input;
    char const *cmd;
    enum status status;
    int incomment;
    enum ppcmd id;
    int size, n;

    incomment = ccommentp(ppp->cl);
    ppp->absorb = FALSE;
    input = examinechar(ppp->cl, ppp->line);
    while (!preproclinep(ppp->cl)) {
	if (endoflinep(ppp->cl))
	    return;
	input = nextchar(ppp->cl, input);
    }

    cmd = skipwhite(ppp->cl, nextchar(ppp->cl, input));
    input = getpreprocessorcmd(ppp->cl, cmd, &id);

    switch (id) {
      case cmdIfdef:
      case cmdIfndef:
	if (ppp->level + 1 >= sizearray(ppp->stack)) {
	    error(errIfsTooDeep);
	    break;
	}
	++ppp->level;
	ppp->stack[ppp->level] = F_If | F_Ifdef;
	if (!ppp->copy) {
	    input = restofline(ppp->cl, input);
	    break;
	}
	ppp->stack[ppp->level] |= F_Copy;
	size = getidentifierlength(input);
	if (!size) {
	    error(errEmptyIf);
	    break;
	}
	if (findsymbolinset(ppp->defs, input, NULL))
	    n = statDefined;
	else if (findsymbolinset(ppp->undefs, input, NULL))
	    n = statUndefined;
	else
	    n = statUnaffected;
	input = skipwhite(ppp->cl, nextchars(ppp->cl, input, size));
	if (!endoflinep(ppp->cl)) {
	    error(errSyntax);
	    break;
	}
	if (n != statUnaffected) {
	    ppp->absorb = TRUE;
	    ppp->stack[ppp->level] |= F_Ours;
	    ppp->copy = n == (id == cmdIfdef ? statDefined : statUndefined);
	}
	break;

      case cmdIf:
	if (ppp->level + 1 >= sizearray(ppp->stack)) {
	    error(errIfsTooDeep);
	    break;
	}
	++ppp->level;
	ppp->stack[ppp->level] = F_If | (ppp->copy ? F_Copy : 0);
	if (!ppp->copy) {
	    input = restofline(ppp->cl, input);
	    break;
	}
	input = seqif(ppp, (char*)input, &status);
	if (status == statError)
	    break;
	input = skipwhite(ppp->cl, input);
	if (!endoflinep(ppp->cl)) {
	    error(errIfSyntax);
	    break;
	}
	if (status == statDefined || status == statUndefined) {
	    ppp->absorb = TRUE;
	    ppp->stack[ppp->level] |= F_Ours;
	    ppp->copy = status == statDefined;
	}
	break;

      case cmdElse:
	if (ppp->level < 0 || (ppp->stack[ppp->level] & F_Else)) {
	    error(errDanglingElse);
	    break;
	}
	ppp->stack[ppp->level] |= F_Else;
	if (!endoflinep(ppp->cl)) {
	    error(errSyntax);
	    break;
	}
	if (ppp->stack[ppp->level] & F_Ours) {
	    ppp->copy = !ppp->copy;
	    ppp->absorb = TRUE;
	    n = ppp->level;
	    while (ppp->stack[n] & F_Elif) {
		if (ppp->stack[n] & F_ElseModify) {
		    ppp->absorb = TRUE;
		    break;
		}
		--n;
		if (!(ppp->stack[n] & F_Ours))
		    ppp->absorb = FALSE;
	    }
	}
	break;

      case cmdElif:
	if (ppp->level < 0 || !(ppp->stack[ppp->level] & F_If)
			   || (ppp->stack[ppp->level] & F_Else)) {
	    error(errDanglingElse);
	    break;
	} else if (ppp->level + 1 >= sizearray(ppp->stack)) {
	    error(errIfsTooDeep);
	    break;
	}
	if (ppp->stack[ppp->level] & F_Ifdef)
	    error(errElifWithIfdef);
	ppp->stack[ppp->level] |= F_Else;
	if (ppp->stack[ppp->level] & F_Ours)
	    ppp->copy = !ppp->copy;
	++ppp->level;
	ppp->stack[ppp->level] = F_If | F_Elif | (ppp->copy ? F_Copy : 0);
	if (!ppp->copy) {
	    input = restofline(ppp->cl, input);
	    break;
	}
	input = seqif(ppp, (char*)input, &status);
	if (status == statError)
	    break;
	input = skipwhite(ppp->cl, input);
	if (!endoflinep(ppp->cl)) {
	    error(errIfSyntax);
	    break;
	}
	if (status == statUndefined) {
	    ppp->copy = FALSE;
	    ppp->absorb = TRUE;
	    ppp->stack[ppp->level] |= F_Ours;
	} else if (status == statDefined) {
	    ppp->absorb = TRUE;
	    n = ppp->level;
	    while (ppp->stack[n] & F_Elif) {
		--n;
		if (!(ppp->stack[n] & F_Ours)) {
		    strcpy((char*)cmd, "else");
		    ppp->stack[ppp->level] |= F_ElseModify;
		    ppp->absorb = FALSE;
		    break;
		}
	    }
	    ppp->stack[ppp->level] |= F_Ours;
	} else {
	    n = ppp->level;
	    while (ppp->stack[n] & F_Elif) {
		--n;
		if (!(ppp->stack[n] & F_Ours)) {
		    n = -1;
		    break;
		}
	    }
	    if (n >= 0) {
		memmove((char*)cmd, cmd + 2, strlen(cmd + 2) + 1);
		ppp->stack[ppp->level] |= F_IfModify;
	    }
	}
	break;

      case cmdEndif:
	if (ppp->level < 0) {
	    error(errDanglingEnd);
	    break;
	}
	if (!endoflinep(ppp->cl)) {
	    error(errSyntax);
	    input = restofline(ppp->cl, input);
	}
	ppp->absorb = TRUE;
	for ( ; ppp->stack[ppp->level] & F_Elif ; --ppp->level) {
	    if (ppp->stack[ppp->level] & (F_IfModify | F_ElseModify))
		ppp->absorb = FALSE;
	}
	if (ppp->absorb)
	    ppp->absorb = ppp->stack[ppp->level] & F_Ours;
	ppp->copy = ppp->stack[ppp->level] & F_Copy;
	--ppp->level;
	break;

      default:
	input = restofline(ppp->cl, input);
	break;
    }

    if (ppp->absorb && incomment != ccommentp(ppp->cl))
	error(errBrokenComment);
}