Exemplo n.º 1
0
static int getop2(char *s)
{
    int c;

    /* skip the white space */
    while (isspace(c = *s = mygetchar()) && c != '\n')
        ;

    s[1] = '\0';

    if (!isdigit(c) && !issign(c) && c != '.') {
        return c;
    }

    /* scan the char after the sign */
    if (issign(c)) {
        if (isdigit(c = mygetchar())) {
            *++s = c;
        } else {
            myungetc(c);
            return *s;
        }
    }

    /* scan for the integral part */
    while (isdigit(c = mygetchar())) {
        *++s = c;
    }

    /* not a digit, is it a decimal point? */
    if (c == '.') {
        *++s = c;

        /* scan for the floating part */
        while (isdigit(c = mygetchar())) {
            *++s = c;
        }
    }

    if (c != EOF) {
        myungetc(c);
    }

    *++s = '\0';
    return NUMBER;
}
Exemplo n.º 2
0
// output the result in *pa, return the status
static int getint(double *pa) {
  int c;
  // skip the space
  for (c = mygetc(); isspace(c) && c != EOF; c = mygetc());
  if (c == EOF) return EOF;
  // not a number
  if (!isdigit(c) && c != '+' && c != '-') return 0;

  int sign;
  sign = 1;
  if (c == '+' || c == '-') {
    if (c == '-') sign = -1;
    // have '+' or '-', but not a number
    if (isspace(c = mygetc()) || c == EOF) {
      *pa = 0;
      if (c != EOF) myungetc(c);
      return c;
    }
  }
  // is a number
  *pa = 0;
  for (; isdigit(c) && c != EOF; c = mygetc()) {
    //printf("%c\n", c);
    //getchar();
    *pa = *pa * 10 + (c - '0');
    //printf("%d\n", *pa);
  }
  // the fraction
  if (c == '.') {
    double fac;
    for (fac = 0.1, c = mygetc(); isdigit(c) && c != EOF; c = mygetc(), fac /= 10.0) {
      *pa += (c - '0') * fac;
    }
  }
  *pa *= sign;
  if (c != EOF) myungetc(c);
  return c;
}
Exemplo n.º 3
0
static int
yylex1(void)
{
    register char *yyp;
    register int c;
    register int c1, c2;
    
    for (;;)
    {
	if (lex_fatal)
	{
	    return -1;
	}
	switch(c = mygetc())
	{
	case EOF:
	    if (inctop)
	    {
		struct incstate *p;
		p = inctop;
		(void)fclose(yyin);
		/*(void)fprintf(stderr, "popping to %s\n", p->file);*/
		free(current_file);
		nexpands = 0;
		current_file = p->file;
		current_line = p->line + 1;
		current_incfile = p->incfnum;
		pragma_strict_types = p->pragma_strict_types;
		yyin = p->yyin;
		slast = p->slast;
		lastchar = p->lastchar;
		inctop = p->next;
		
		if (p->nbuf)
		{
		    nbuf = p->nbuf;
		    outp = defbuf + DEFMAX - nbuf;
		    memcpy(outp, p->outp, nbuf);
		    free((char *)p->outp);
		}
		else
		{
		    nbuf = 0;
		    outp = defbuf + DEFMAX;
		}
		
		store_line_number_info(current_incfile, current_line);
		incdepth--;
		
		free((char *)p);
		break;
	    }
	    if (iftop)
	    {
		struct ifstate *p = iftop;
		lexerror(p->state == EXPECT_ENDIF ? "Missing #endif" : "Missing #else");
		while (iftop)
		{
		    p = iftop;
		    iftop = p->next;
		    free((char *)p);
		}
	    }
	    return -1;
	case '\n':
	{
	    nexpands=0;
	    store_line_number_info(current_incfile, current_line);
	    current_line++;
	    total_lines++;
	}
        /* FALLTHROUGH */
	case ' ':
	case '\t':
	case '\f':
	case '\v':
	    break;
	case '+':
	    TRY('+', F_INC);
	    TRY('=', F_ADD_EQ);
	    return c;
	case '-':
	    TRY('>', F_ARROW);
	    TRY('-', F_DEC);
	    TRY('=', F_SUB_EQ);
	    return c;
	case '&':
	    TRY('&', F_LAND);
	    TRY('=', F_AND_EQ);
	    return c;
	case '|':
	    TRY('|', F_LOR);
	    TRY('=', F_OR_EQ);
	    return c;
	case '^':
	    TRY('=', F_XOR_EQ);
	    return c;
	case '<':
	    if (gobble('<')) {
		TRY('=', F_LSH_EQ);
		return F_LSH;
	    }
	    TRY('=', F_LE);
	    return c;
	case '>':
	    if (gobble('>'))
	    {
		TRY('=', F_RSH_EQ);
		return F_RSH;
	    }
	    TRY('=', F_GE);
	    return c;
	case '*':
	    TRY('=', F_MULT_EQ);
	    return c;
	case '%':
	    TRY('=', F_MOD_EQ);
	    return F_MOD;
	case '/':
	    if (gobble('*'))
	    {
		skip_comment();
		break;
	    }
	    else if (gobble('/'))
	    {
		skip_comment2();
		break;
	    }
	    TRY('=', F_DIV_EQ);
	    return c;
	case '=':
	    TRY('=', F_EQ);
	    return c;
	case ';':
	case '(':
	case ')':
	case ',':
	case '{':
	case '}':
	case '~':
	case '[':
	case ']':
	case '?':
	case '@':
	    return c;
	case '!':
	    TRY('=', F_NE);
	    return F_NOT;
	case ':':
	    TRY(':', F_COLON_COLON);
	    return ':';
	case '.':
	    if (gobble('.'))
	    {
		if (gobble('.'))
		    return F_VARARG;
		else
		    return F_RANGE;
	    }
	    return c;
	case '#':
	    if (lastchar == '\n') 
	    {
		char *ssp = 0;
		int quote;
		
		yyp = yytext;
		do 
		{
		    c = mygetc();
		} while (isspace(c));
		
		for (quote = 0;;) 
		{
		    if (c == '"')
			quote ^= 1;
		    
		    /*gc - handle comments cpp-like! 1.6.91 @@@*/
		    while (!quote && c == '/')  
		    {
			if (gobble('*')) 
			{ 
			    skip_comment();
			    c = mygetc();
			}
			else 
			    break;
		    }
		    
		    if (!ssp && isspace(c))
			ssp = yyp;
		    if (c == '\n' || c == EOF)
			break;
		    SAVEC;
		    c = mygetc();
		}
		if (ssp) 
		{
		    *ssp++ = 0;
		    while (isspace(*ssp))
			ssp++;
		} 
		else 
		{
		    ssp = yyp;
		}
		*yyp = 0;
		if (strcmp("define", yytext) == 0) 
		{
		    handle_define(ssp);
		} 
		else if (strcmp("if", yytext) == 0) 
		{
#if 0
		    short int nega=0; /*@@@ allow #if !VAR gc 1.6.91*/
		    if (*ssp=='!'){ ssp++; nega=1;}
		    if (isdigit(*ssp))
		    {
			char *p;
			long l;
			l = strtol(ssp, &p, 10);
			while (isspace(*p))
			    p++;
			if (*p)
			    lexerror("Condition too complex in #if");
			else
			    handle_cond(nega ? !(int)l : (int)l);
		    }
		    else if (isalunum(*ssp))
		    {
			char *p = ssp;
			while (isalunum(*p))
			    p++;
			if (*p)
			{
			    *p++ = 0;
			    while (isspace(*p))
				p++;
			}
			if (*p)
			    lexerror("Condition too complex in #if");
			else
			{
			    struct defn *d;
			    d = lookup_define(ssp);
			    if (d)
			    {
				handle_cond(nega ? !atoi(d->exps) : atoi(d->exps));/* a hack! */
			    }
			    else
			    {
				handle_cond(nega?1:0); /* cpp-like gc*/
			    }
			}
		    }
		    else
			lexerror("Condition too complex in #if");
#else
		    int cond;
            
		    myungetc(0);
		    add_input(ssp);
		    cond = cond_get_exp(0);
		    if (mygetc()) 
		    {
			lexerror("Condition too complex in #if");
			while (mygetc())
			    ;
		    }
		    else
			handle_cond(cond);
#endif
		}
		else if (strcmp("ifdef", yytext) == 0) 
		{
		    deltrail(ssp);
		    handle_cond(lookup_define(ssp) != 0);
		}
		else if (strcmp("ifndef", yytext) == 0)
		{
		    deltrail(ssp);
		    handle_cond(lookup_define(ssp) == 0);
		} 
		else if (strcmp("else", yytext) == 0) 
		{
		    if (iftop && iftop->state == EXPECT_ELSE) 
		    {
			struct ifstate *p = iftop;
			
			/*(void)fprintf(stderr, "found else\n");*/
			iftop = p->next;
			free((char *)p);
			(void)skip_to("endif", (char *)0);
			store_line_number_info(current_incfile, current_line);
			current_line++;
			total_lines++;
		    }
		    else
		    {
			lexerror("Unexpected #else");
		    }
		} 
		else if (strcmp("endif", yytext) == 0) 
		{
		    if (iftop && (iftop->state == EXPECT_ENDIF ||
				  iftop->state == EXPECT_ELSE)) 
		    {
			struct ifstate *p = iftop;
			
			/*(void)fprintf(stderr, "found endif\n");*/
			iftop = p->next;
			free((char *)p);
		    } 
		    else 
		    {
			lexerror("Unexpected #endif");
		    }
		} 
		else if (strcmp("undef", yytext) == 0) 
		{
		    struct defn *d;
		    
		    deltrail(ssp);
		    if ((d = lookup_define(ssp)) != NULL )
			d->undef++;
		} 
		else if (strcmp("echo", yytext) == 0) 
		{
		    (void)fprintf(stderr, "%s\n", ssp);
		} 
		else if (strcmp("include", yytext) == 0) 
		{
		    /*(void)fprintf(stderr, "including %s\n", ssp);     */
		    handle_include(ssp, 0);
		}
		else if (strcmp("pragma", yytext) == 0)
		{
		    deltrail(ssp);
		    handle_pragma(ssp);
		} 
		else if (strcmp("error", yytext) == 0)
		{
		    handle_exception(ERROR, ssp);
		}
		else if (strcmp("warning", yytext) == 0)
		{
		    handle_exception(WARNING, ssp);
		}
		else 
		{
		    lexerror("Unrecognised # directive");
		}
		myungetc('\n');
		break;
	    }
	    else
		goto badlex;
	case '\'':
	    yylval.number = mygetc();
	    if (yylval.number == '\\')
	    {
		int tmp = mygetc();
		switch (tmp)
		{
		case 'n': yylval.number = '\n'; break;
		case 't': yylval.number = '\t'; break;
		case 'b': yylval.number = '\b'; break;
		case 'a': yylval.number = '\a'; break;
		case 'v': yylval.number = '\v'; break;
		case '\'':
		case '\\':
		case '"':
		    yylval.number = tmp; break;
		default:
		    lexwarning("Bad character escape sequence");
		    yylval.number = tmp;
		    break;
		}
	    }
	    if (!gobble('\''))
		lexerror("Illegal character constant");
	    return F_NUMBER;
	case '"':
	    yyp = yytext;
	    *yyp++ = c;
	    for (;;)
	    {
		c = mygetc();
		if (c == EOF)
		{
		    lexerror("End of file in string");
		    return string("\"\"");
		}
		else if (c == '\n')
		{
		    lexerror("Newline in string");
		    return string("\"\"");
		}
		SAVEC;
		if (c == '"')
		    break;
		if (c == '\\')
		{
		    c = mygetc();
		    if ( c == '\n' )
		    {
			yyp--;
			store_line_number_info(current_incfile, current_line);
			current_line++;
			total_lines++;
		    } 
		    else if ( c == EOF ) 
		    {
			/* some operating systems give EOF only once */
			myungetc(c); 
		    } 
		    else
			*yyp++ = c;
		}
	    }
	    *yyp = 0;
	    return string(yytext);

	case '0':
	    c = mygetc();
	    if ( c == 'X' || c == 'x' || c == 'o') 
	    {
                char *endptr;
                long long value;
                int base = 16;
                if (c == 'o')
                    base = 8;

                
		yyp = yytext;

		for (;;) 
		{
		    c = mygetc();
		    if (!isxdigit(c))
			break;
                    SAVEC;
		}
		myungetc(c);
                *yyp = '\0';
                
                value = strtoll(yytext, &endptr, base);
                if (*endptr != '\0')
                {
                    fprintf(stderr, "%s\n", yytext);
                    lexwarning("Invalid digits in octal number number");
                }
                
                return number(value);
	    }
	    myungetc(c);
	    c = '0';
	    /* FALLTHROUGH */
	case '1':
	case '2':
	case '3':
	case '4':
	case '5':
	case '6':
	case '7':
	case '8':
	case '9':
	    yyp = yytext;
	    *yyp++ = c;
	    for (;;)
	    {
		c = mygetc();
		if (!isdigit(c))
		    break;
		SAVEC;
	    }
	    if (c == '.')
	    {
		if (isdigit(c1 = mygetc()))
		{
		    SAVEC;
		    c = c1;
		    SAVEC;
		    for (c = mygetc(); isdigit(c); c = mygetc())
			SAVEC;
		    if (c == 'e' || c == 'E')
		    {
			c1 = mygetc();
			if (c1 == '-' || c1 == '+')
			{
			    c2 = mygetc();
			    if (isdigit(c2))
			    {
				SAVEC;
				c = c1;
				SAVEC;
				c = c2;
				SAVEC;
				for (c = mygetc(); isdigit(c); c = mygetc())
				    SAVEC;
			    }
			    else
			    {
				myungetc(c2);
				myungetc(c1);
			    }
			}
			else if (isdigit(c1))
			{
			    SAVEC;
			    c = c1;
			    SAVEC;
			    for (c = mygetc(); isdigit(c); c = mygetc())
				SAVEC;
			}
			else
			    myungetc(c1);
		    }
		    myungetc(c);
		    *yyp = 0;
		    return real(strtod(yytext, NULL));
		}
		myungetc(c1);
	    }
	    myungetc(c);
	    *yyp = 0;
	    if (*yytext == '0')
            {
                /* OCTALS */
                char *endptr;
                long long value;

                value = strtoll(yytext, &endptr, 010);

                if (*endptr != '\0')
                    lexwarning("Invalid digits in octal number");

                if (value != 0)
                    lexwarning("Obsolete octal format used. Use 0o111 syntax");
                
		return number(value);
            }
	    return number(atoll(yytext));
	default:
	    if (isalpha(c) || c == '_') {
		int r;
		
		yyp = yytext;
		*yyp++ = c;
		for (;;)
		{
		    c = mygetc();
		    if (!isalunum(c))
			break;
		    SAVEC;
		}
		*yyp = 0;
		
		myungetc(c);
		if (!expand_define())
		{
		    r = lookup_resword(yytext);
		    if (r >= 0)
		    {
			return r;
		    }
		    else
			return ident(yytext);
		}
		break;
	    }
	    goto badlex;
	}
    }
  badlex:
    {
	lexerror("Illegal character (hex %02x) '%c'", c, c);
        return ' '; 
    }
}
Exemplo n.º 4
0
static int 
cond_get_exp(int priority)
{
    int c;
    int value, value2, x;
    
    do
	c = exgetc();
    while (isspace(c));
    
    if (c == '(')
    {
	value = cond_get_exp(0);
	do
	    c = exgetc();
	while (isspace(c));
	if (c != ')')
	{
	    lexerror("bracket not paired in #if");
	    if (!c)
		myungetc('\0');
	}
    }
    else if (ispunct(c))
    {
	x = (_optab-' ')[c];
	if (!x)
	{
	    lexerror("illegal character in #if");
	    return 0;
	}
	value = cond_get_exp(12);
	switch ( optab2[x-1] )
	{
	case BNOT  : value = ~value; break;
	case LNOT  : value = !value; break;
	case UMINUS: value = -value; break;
	case UPLUS : value =  value; break;
	default :
	    lexerror("illegal unary operator in #if");
	    return 0;
	}
    }
    else
    {
	int base;
	
	if (!isdigit(c))
	{
	    if (!c)
	    {
		lexerror("missing expression in #if");
		myungetc('\0');
	    }
	    else
		lexerror("illegal character in #if");
	    return 0;
	}
	value = 0;
	if (c!='0')
	    base = 10;
	else
	{
	    c = mygetc();
	    if ( c == 'x' || c == 'X' )
	    {
		base = 16;
		c = mygetc();
	    }
	    else
		base=8;
	}
	for (;;)
	{
	    if ( isdigit(c) )
		x = -'0';
	    else if (isupper(c))
		x = -'A' + 10;
	    else if (islower(c))
		x = -'a' + 10;
	    else
		break;
	    x += c;
	    if (x > base)
		break;
	    value = value*base + x;
	    c = mygetc();
	}
	myungetc(c);
    }
    for (;;)
    {
	do
	    c = exgetc();
	while (isspace(c));
	
	if (!ispunct(c))
	    break;
	x = (_optab-' ')[c];
	if (!x)
	    break;
	value2 = mygetc();
	for (;;x += 3)
	{
	    if (!optab2[x])
	    {
		myungetc(value2);
		if (!optab2[x + 1])
		{
		    lexerror("illegal operator use in #if");
		    return 0;
		}
		break;
	    }
	    if (value2 == optab2[x])
		break;
	}
	if (priority >= optab2[x + 2])
	{
	    if (optab2[x])
		myungetc(value2);
	    break;
	}
	value2 = cond_get_exp(optab2[x + 2]);
	switch ( optab2[x + 1] )
	{
	case MULT   : value *=  value2;                    break;
	case DIV    : value /=  value2;                    break;
	case MOD    : value %=  value2;                    break;
	case BPLUS  : value +=  value2;                    break;
	case BMINUS : value -=  value2;                    break;
	case LSHIFT : value <<= value2;                    break;
	case RSHIFT : value =   (unsigned)value >> value2; break;
	case LESS   : value =   value <  value2;           break;
	case LEQ    : value =   value <= value2;           break;
	case GREAT  : value =   value >  value2;           break;
	case GEQ    : value =   value >= value2;           break;
	case EQ     : value =   value == value2;           break;
	case NEQ    : value =   value != value2;           break;
	case BAND   : value &=  value2;                    break;
	case XOR    : value ^=  value2;                    break;
	case BOR    : value |=  value2;                    break;
	case LAND   : value =  value && value2;            break;
	case LOR    : value =  value || value2;            break;
	case QMARK  :
	    do
		c = exgetc();
	    while (isspace(c));
            if (c != ':')
	    {
		lexerror("'?' without ':' in #if");
		myungetc(c);
		return 0;
	    }
	    if (value) 
	    {
		(void)cond_get_exp(1);
		value = value2;
	    }
	    else
		value = cond_get_exp(1);
	    break;
	}
    }
    myungetc(c);
    return value;
}
Exemplo n.º 5
0
/* Stuff to evaluate expression.  I havn't really checked it. /LA
** Written by "J\"orn Rennecke" <*****@*****.**>
*/
static int
exgetc(void)
{
    register char c, *yyp;
    
    c = mygetc();
    while (isalpha(c) || c == '_')
    {
	yyp = yytext;
	do
	{
	    SAVEC;
	    c = mygetc();
	} while (isalunum(c));
	myungetc(c);
	*yyp = '\0';
	if (strcmp(yytext, "defined") == 0)
	{
	    /* handle the defined "function" in #if */
	    do
		c = mygetc();
	    while (isspace(c));
	    
	    if (c != '(')
	    {
		lexerror("Missing ( in defined");
		continue;
	    }
	    do
		c = mygetc();
	    while (isspace(c));
	    
	    yyp = yytext;
	    while (isalunum(c))
	    {
		SAVEC;
		c = mygetc();
	    }
	    *yyp = '\0';
	    while (isspace(c))
		c = mygetc();
	    if (c != ')')
	    {
		lexerror("Missing ) in defined");
		continue;
	    }

	    /* Skip whitespace */
	    do
		c = mygetc();
	    while (isspace(c)); 
	    myungetc(c);

	    if (lookup_define(yytext))
		add_input(" 1 ");
	    else
		add_input(" 0 ");
	}
	else
	{
	    if (!expand_define()) add_input(" 0 ");
	}
	c = mygetc();
    }
    return c;
}
Exemplo n.º 6
0
static void parse_token(struct token *t)
{
    int c;

    while (isspace(c = mygetc()) && (c != '\n'))
        continue;

retry:
    if (isdigit(c)) {
        t->type = NUM;
        t->u.num.start = c - '0';
        while (isdigit(c = mygetc()))
            t->u.num.start = t->u.num.start * 10 + c - '0';
        t->u.num.end = t->u.num.start;
        t->u.num.step = 1;
        if (c == '-') {
            t->u.num.end = 0;
            while (isdigit(c = mygetc()))
                t->u.num.end = t->u.num.end * 10 + c - '0';
            if (t->u.num.end < t->u.num.start)
                parse_err("bad range %u-%u", t->u.num.start, t->u.num.end);
        }
        if (c == '/') {
            t->u.num.step = 0;
            while (isdigit(c = mygetc()))
                t->u.num.step = t->u.num.step * 10 + c - '0';
        }
        myungetc(c);
    } else if (c == '"') {
        char *p = t->u.str;
        t->type = STR;
        while ((c = mygetc()) != '"') {
            if ((c == '\n') || (c == '\r') || (c == EOF))
                parse_err("unexpected newline or end-of-file in string");
            *p++ = c;
            if ((p - t->u.str) >= (sizeof(t->u.str)-1))
                parse_err("string too long");
        }
        *p = '\0';
    } else if (isalpha(c)) {
        char *p = t->u.str;
        t->type = STR;
        *p++ = c;
        while (isalnum(c = mygetc()) || (c == '_')) {
            *p++ = c;
            if ((p - t->u.str) >= (sizeof(t->u.str)-1))
                parse_err("string too long");
        }
        *p = '\0';
        myungetc(c);
    } else if (c == '\\') { /* ignore EOL at line break */
        while (isspace(c = mygetc()) && (c != '\n'))
            continue;
        if (c != '\n')
            parse_err("expected newline after backslash");
        while (isspace(c = mygetc()) && (c != '\n'))
            continue;
        goto retry;
    } else if (c == '#') { /* ignore until EOL */
        while (((c = mygetc()) != EOF) && (c != '\n'))
            continue;
        goto retry;
    } else if ((c == EOF) || (c == '\n')) {
        t->type = EOL;
        t->u.ch = c;
    } else {
        t->type = CHR;
        t->u.ch = c;
    }
}