Example #1
0
File: exptree.c Project: 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;
}
Example #2
0
File: ppproc.c Project: 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);
}