コード例 #1
0
ファイル: ppproc.c プロジェクト: BR903/cppp
/* 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;
}
コード例 #2
0
ファイル: exptree.c プロジェクト: pix/cppp
/* Reads a constant from the C source at input via the given lexer,
 * and uses it to initialize the expression tree. Literal numbers,
 * strings, characters, macro identifiers and function-like macro
 * invocations, and uses of the defined operator are all considered
 * constants by this function. The return value is the text following
 * the constant.
 */
static char const *parseconstant(struct exptree *t, struct clexer *cl,
				 char const *input)
{
    char *p;
    int size, paren, mark;

    mark = geterrormark();
    t->begin = input;
    if (charquotep(cl)) {
	t->exp = expConstant;
	t->valued = TRUE;
	t->value = getcharconstant(input + 1);
	while (!endoflinep(cl) && charquotep(cl))
	    input = nextchar(cl, input);
	t->end = input;
	input = skipwhite(cl, input);
    } else if (!memcmp(input, "defined", 7)) {
	t->exp = expDefined;
	input = skipwhite(cl, nextchars(cl, input, 7));
	paren = *input == '(';
	if (paren)
	    input = skipwhite(cl, nextchar(cl, input));
	size = getidentifierlength(input);
	if (!size) {
	    error(errDefinedSyntax);
	    goto failure;
	}
	t->identifier = input;
	input = nextchars(cl, input, size);
	if (paren) {
	    input = skipwhite(cl, input);
	    if (*input != ')') {
		error(errDefinedSyntax);
		goto failure;
	    }
	    input = nextchar(cl, input);
	}
	t->valued = FALSE;
	t->end = input;
	input = skipwhite(cl, input);
    } else if (isdigit(*input)) {
	t->exp = expConstant;
	if (*input == '0') {
	    input = nextchar(cl, input);
	    if (tolower(*input) == 'x') {
		do
		    input = nextchar(cl, input);
		while (isxdigit(*input));
	    } else {
		while (*input >= '0' && *input <= '7')
		    input = nextchar(cl, input);
	    }
	} else {
	    do
		input = nextchar(cl, input);
	    while (isdigit(*input));
	}
	t->value = strtol(t->begin, &p, 0);
	t->valued = p == input;
	if (toupper(*input) == 'L') {
	    input = nextchar(cl, input);
	    if (toupper(*input) == 'L')
		input = nextchar(cl, input);
	    if (toupper(*input) == 'U')
		input = nextchar(cl, input);
	} else if (toupper(*input) == 'U') {
	    input = nextchar(cl, input);
	    if (toupper(*input) == 'L') {
		input = nextchar(cl, input);
		if (toupper(*input) == 'L')
		    input = nextchar(cl, input);
	    }
	}
	t->end = input;
	input = skipwhite(cl, input);
    } else if (_issym(*input)) {
	do
	    input = nextchar(cl, input);
	while (_issym(*input));
	t->end = input;
	input = skipwhite(cl, input);
	if (*input == '(') {
	    t->exp = expParamMacro;
	    paren = getparenlevel(cl);
	    do {
		input = nextchar(cl, input);
		if (endoflinep(cl)) {
		    error(errOpenParenthesis);
		    goto failure;
		}
	    } while (getparenlevel(cl) >= paren);
	    t->valued = FALSE;
	    t->end = input;
	    input = skipwhite(cl, input);
	} else {
	    t->exp = expMacro;
	}
    } else {
	error(errSyntax);
	goto failure;
    }

    if (!errorsincemark(mark))
	return input;

  failure:
    t->exp = expNone;
    t->end = input;
    return input;
}