Ejemplo n.º 1
0
/*
 ****************************************************************
 *	Analisa uma Linha de Controle				*
 ****************************************************************
 */
void
directive (void)
{
	SYMTB		*sp, **link_place;
	MAJOR		maj;
	char		*cp, c;

	/*
	 *	Convenção da STACK:
	 *		'U': é indefinido, e nunca foi definido
	 *		'N': é indefinido, mas já foi definido
	 *		'D': é definido
	 */
	if ((maj = scan ()) == EOL)
	{
		skipline ();
		return;
	}

	if (maj != ID || !TYPE (sp, token.l_name, S_KEYWORD))
	{
		err_msg
		(	ERRO, TOKMARK,
			"Esperava uma diretiva de préprocessamento"
		);
		skipline ();
		return;
	}

	switch (sp->s_index)
	{
	    case DEFINE:
		if (falselevel == 0)
			dodefine ();
		break;

	    case UNDEF:
		if (falselevel == 0)
			doundef ();
		break;

	    case INCLUDE:
		if (falselevel == 0)
		{
			doinclude ();
			return;
		}
		break;

	    case IF:
		if (falselevel == 0)
		{
			if (expression ())
			{
				*stackp++ = 'D';
				putoutnl ();
			}
			else
			{
				*stackp++ = 'U';
				falselevel++;
			}
	
			/*
			 *	A análise de expressões já processou
			 *	o fim de linha.	Não devemos avançar mais.
			 */
			return;
		}
		else
		{
			*stackp++ = 'U';
			falselevel++;
		}
		break;

	    case IFDEF:
		if (scan () != ID)
		{
			err_msg (ERRO, TOKMARK, "Esperava um identificador");
			*stackp++ = 'D';
			break;
		}

		if (TYPE (sp, token.l_name, S_MACRO))
		{
			*stackp++ = 'D';
			if (falselevel == 0)
				putoutnl ();
		}
		else
		{
			*stackp++ = 'U';
			falselevel++;
		}

		break;

	    case IFNDEF:
		if (scan () != ID)
		{
			err_msg (ERRO, TOKMARK, "Esperava um identificador");
			*stackp++ = 'D';
			break;
		}

		if (!TYPE (sp, token.l_name, S_MACRO))
		{
			*stackp++ = 'D';
			if (falselevel == 0)
				putoutnl ();
		}
		else
		{
			*stackp++ = 'U';
			falselevel++;
		}

		break;

	    case ELIF:
		if (stackp <= stack)
		{
			err_msg
			(	ERRO, TOKMARK,
				"\"elif\" sem prévio \"if\" ou \"ifdef\""
			);
			break;
		}

		switch (stackp[-1])
		{
		    case 'U':
			if (falselevel == 1)
			{
				if (expression ())
				{
					stackp[-1] = 'D';
					falselevel--;	/* == 0 */
					putlineno (lineno);
				}
				else
				{
					/* Nada faz */
				}

				return;
			}
			else
			{
				/* Nada faz */
			}
			break;

		    case 'N':
			/* Nada faz */
			break;

		    case 'D':
			stackp[-1] = 'N';
			falselevel++;
			putoutnl ();
			break;

		    default:
			err_msg
			(	ERRO, TOKMARK,
				"Estado inválido da STACK: '%c'",
				stackp[-1]
			);
		}

		break;

	    case ELSE:
		if (stackp <= stack)
		{
			err_msg
			(	ERRO, TOKMARK,
				"\"else\" sem prévio \"if\" ou \"ifdef\""
			);
			break;
		}

		switch (stackp[-1])
		{
		    case 'U':
			stackp[-1] = 'D';
			if (--falselevel == 0)
				putlineno (lineno + 1);
			break;

		    case 'N':
			/* Nada faz */
			break;

		    case 'D':
			stackp[-1] = 'U';
			falselevel++;
			break;

		    default:
			err_msg
			(	ERRO, TOKMARK,
				"Estado inválido da STACK: '%c'",
				stackp[-1]
			);
		}

		break;

	    case ENDIF:
		if (stackp <= stack)
		{
			err_msg
			(	ERRO, TOKMARK,
				"\"endif\" sem prévio \"if\" ou \"ifdef\""
			);
			break;
		}

		switch (*--stackp)
		{
		    case 'U':
		    case 'N':
			if (--falselevel == 0)
				putlineno (lineno + 1);
			break;

		    case 'D':
			putoutnl ();
			break;

		    default:
			err_msg
			(	ERRO, TOKMARK,
				"Estado inválido da STACK: '%c'",
				stackp[0]
			);
		}

		break;

	    case ERROR:
		if (falselevel == 0)
		{
			const char	*msg;

			for (cp = (char *)nextp; CATEG (cp) == SEPAR; cp++)
				/* vazio */;

			msg = cp;

			while (*cp != '\n' && (*cp != '/' || cp[1] != '*'))
				cp++;

			c = *cp; *cp = '\0';

			err_msg (ERRO, NOMARK, msg);

			*cp = c; nextp = msg; putoutnl ();
		}

		break;

	    case PRAGMA:
		if (falselevel == 0)
			dopragma ();
		break;

	    case LINE:
		if (falselevel == 0)
		{
			if (scan () != ICTE)
			{
				err_msg
				(
					ERRO,
					TOKMARK,
					"Esperava uma constante"
				);
			};

			lineno = token.l_ival - 1;

			if (scan () == STR)
			{
				srcname = token.l_begin + 1;
				((char *)token.l_end)[0] = '\0';
				scan ();
			}

			return;
		}
		break;

	    default:
		err_msg
		(	COMP, TOKMARK,
			"Erro no s_index para diretivas"
		);

	}	/* end switch (sp->s_index) */

	skipline ();

}	/* end directive */
Ejemplo n.º 2
0
int
prep (void)                     /* Check for preprocessor commands */
{
    int b, c;
    char *ln;

    ln = line;

    while (*(++ln) == '#' || *ln == ' ') /* locate first directive character */
        ;
    
    if ( ! *ln)                   /* NULL directive */
        return (killine ());
    
    /* fprintf(stderr,"prep - line=%s\n",ln); */

    if (strcmp2 (ln, "if ") || strcmp2 (ln, "ifdef ") ||
                                strcmp2 (ln, "ifndef "))
    {
        /* fprintf(stderr,"prep - calling doif(%s)\n",ln); */
        doif (ln);
        return (killine ());
    }

    if (strcmp2 (ln, "else"))
    {
        doelse ();
        return (killine ());
    }

    if (strcmp2 (ln, "endif"))
    {
        doendif ();
        return (killine ());
    }
    
    if (strcmp2 (ln, "elif "))
    {
        doelif (ln);
        return (killine ());
    }
    
    if (procsw)
    {
        if (strcmp2 (ln, "define "))
        {
            c = getident (ln, 7) + 2;   /* get end of identifier */
            splittok (ln, c);   /* tokenize rest of line */
            dodefine (strlen (line), &ln[7] - line);    /* store #define info */
/*          fprintf(stderr,"PREP (after dodef): line=|%s|\n",line); */
            tstdupdef ();       /* Check for def duplication and fix */
            return (killine ());        /* Discard #define line */
        }
        
        if (strcmp2 (ln, "include "))
        {
            doinclude (&ln[8]); /* open include file */
            return (killine ());        /* Discard #include line */
        }
        
        if (strcmp2 (ln, "undef "))
        {
            /* fprintf(stderr,"prep - undef found %s\n",ln); */
            doundef (&ln[6]);   /* remove undef identifier from def table */
            /* fprintf(stderr,"prep - doundef done\n"); */
            return (killine ());        /* Discard #undef line */
        }
        
        if (strcmp2 (ln, "error "))
        {
            fprintf (stderr, "User error - %s\n", &ln[6]);      /* print error */
            return (killine ());        /* Discard #error line */
        }
        
        if (strcmp2 (ln, "asm"))
        {
            for (;;)            /* send all following lines through for assembler */
            {
                getln (0);
                if (eflag)
                    break;
                if (findstr (1, line, "#endasm"))
                    break;
                if (cflag)
                    puts ("#2");
                else
                    printf ("#pragma asm ");
                printf ("%s\n", line);
            }
            if (eflag && cflag) /* error only in Microware mode (no #endasm) */
                doerr (18, 1);
            return (killine ());
        }
        if (strcmp2 (ln, "pragma "))
        {
            dopragma (ln + 7);
            return (killine ());
        }
        if (strcmp2 (ln, "line "))
        {
            doline (ln + 5);
            return (killine ());
        }
        doerr (17, 1);          /* Illegal preprocessor directive */
        return (killine ());
    }
}
Ejemplo n.º 3
0
int
yylex()
{
    int c;
    int nextc;
    char *ptr = Tok;
    char *eptr = &Tok[MAXTOK];
    const char *cptr;
    int startline;
    int val;
    static int bol = 1;	/* true if we're at beginning of line */

    for (;;) {
        while (Fp == NULL) {
            char ibuf[80];

            if (*Files == NULL)
                return (record(EOF, NULL));
            Fileopened = stable(*Files++);
#ifdef	ESC
            sprintf(Tok, "%s %s %s %s",
                    Cpp, Cppstdargs, Cppargs, Fileopened);
            if ((Fp = popen(Tok, "r")) == NULL)
                out(O_DIE|O_SYS, "%s", Tok);
#else
            Fp = eftread_fopen(Fileopened, ibuf, sizeof (ibuf));
#endif	/* ESC */
            Line = 1;
            bol = 1;

            /* add name to stats for visibility */
            if (Fp != NULL) {
                static int fnum;
                char nbuf[100];
                struct filestats *nfs = MALLOC(sizeof (*nfs));

                (void) sprintf(nbuf, "lex.file%d", fnum);
                nfs->stats = stats_new_string(nbuf, "", 0);
                stats_string_set(nfs->stats, Fileopened);

                if (ibuf[0] != '\0') {
                    (void) sprintf(nbuf, "lex.file%d-ident",
                                   fnum);
                    nfs->idstats =
                        stats_new_string(nbuf, "", 0);
                    stats_string_set(nfs->idstats, ibuf);
                } else {
                    nfs->idstats = NULL;
                }

                nfs->next = Fstats;
                Fstats = nfs;
                fnum++;
            }
        }

        switch (c = getc(Fp)) {
        case '#':
            /* enforce that we're at beginning of line */
            if (!bol)
                return (record(c, NULL));

            while ((c = getc(Fp)) != EOF &&
                    (c == ' ' || c == '\t'))
                ;
            if (!isdigit(c)) {
                /*
                 * three cases here:
                 *	#pragma
                 *	#ident
                 *	#something-we-don't-understand
                 * anything we don't expect we just ignore.
                 */
                *ptr++ = c;
                while ((c = getc(Fp)) != EOF && isalnum(c))
                    if (ptr < eptr - 1)
                        *ptr++ = c;
                *ptr++ = '\0';
                if (strcmp(Tok, "pragma") == 0) {
                    /* skip white space */
                    while ((c = getc(Fp)) != EOF &&
                            (c == ' ' || c == '\t'))
                        ;

                    if (c == EOF || c == '\n')
                        outfl(O_DIE, File, Line,
                              "bad #pragma");

                    /* pull in next token */
                    ptr = Tok;
                    *ptr++ = c;
                    while ((c = getc(Fp)) != EOF &&
                            !isspace(c))
                        if (ptr < eptr - 1)
                            *ptr++ = c;
                    *ptr++ = '\0';
                    (void) ungetc(c, Fp);

                    dopragma(Tok);
                } else if (strcmp(Tok, "ident") == 0)
                    doident();
            } else {
                /* handle file & line info from cpp */
                Line = 0;
                do {
                    if (!isdigit(c))
                        break;
                    Line = Line * 10 + c - '0';
                } while ((c = getc(Fp)) != EOF);
                Line--;		/* newline will increment it */
                while (c != EOF && isspace(c))
                    c = getc(Fp);
                if (c != '"')
                    outfl(O_DIE, File, Line,
                          "bad # statement (file name)");
                while ((c = getc(Fp)) != EOF && c != '"')
                    if (ptr < eptr - 1)
                        *ptr++ = c;
                *ptr++ = '\0';
                if (c != '"')
                    outfl(O_DIE, File, Line,
                          "bad # statement (quotes)");
                File = stable(Tok);
            }
            /* skip the rest of the cpp line */
            while ((c = getc(Fp)) != EOF && c != '\n' && c != '\r')
                ;
            if (c == EOF)
                return (record(c, NULL));
            else
                (void) ungetc(c, Fp);
            ptr = Tok;
            break;

        case EOF:
            closefile();
            continue;

        case '\n':
            Line++;
            bol = 1;
            break;

        case '\r':
        case ' ':
        case '\t':
            bol = 0;
            break;

        case '/':
            bol = 0;
            /* comment handling */
            if ((nextc = getc(Fp)) == EOF)
                outfl(O_DIE, File, Line, "unexpected EOF");
            else if (nextc == '*') {
                startline = Line;
                while ((c = getc(Fp)) != EOF) {
                    if (c == '\n')
                        Line++;
                    else if (c == '*' &&
                             (((c = getc(Fp)) == EOF) ||
                              (c == '/')))
                        break;
                }
                if (c == EOF) {
                    outfl(O_DIE, File, Line,
                          "end of comment not seen "
                          "(started on line %d)",
                          startline);
                }
            } else {
                /* wasn't a comment, return the '/' token */
                (void) ungetc(nextc, Fp);
                return (record(c, NULL));
            }
            break;

        case '"': {
            int prevc;

            bol = 0;
            prevc = '\0';
            /* quoted string handling */
            startline = Line;
            for (;;) {
                c = getc(Fp);
                if (c == EOF)
                    outfl(O_DIE, File, Line,
                          "end of string not seen "
                          "(started on line %d)",
                          startline);
                else if (c == '\n')
                    Line++;
                else if (c == '"' && prevc != '\\')
                    break;
                else if (ptr < eptr)
                    *ptr++ = c;
                prevc = c;
            }
            if (ptr >= eptr)
                out(O_DIE, File, Line, "string too long");
            *ptr++ = '\0';
            return (record(QUOTE, stable(Tok)));
        }
        case '&':
            bol = 0;
            /* && */
            if ((nextc = getc(Fp)) == '&')
                return (record(AND, NULL));
            else {
                (void) ungetc(nextc, Fp);
                return (record(c, NULL));
            }
            /*NOTREACHED*/
            break;

        case '|':
            bol = 0;
            /* || */
            if ((nextc = getc(Fp)) == '|')
                return (record(OR, NULL));
            else {
                (void) ungetc(nextc, Fp);
                return (record(c, NULL));
            }
            /*NOTREACHED*/
            break;

        case '!':
            bol = 0;
            /* ! or != */
            if ((nextc = getc(Fp)) == '=')
                return (record(NE, NULL));
            else {
                (void) ungetc(nextc, Fp);
                return (record(c, NULL));
            }
            /*NOTREACHED*/
            break;

        case '=':
            bol = 0;
            /* == */
            if ((nextc = getc(Fp)) == '=')
                return (record(EQ, NULL));
            else {
                (void) ungetc(nextc, Fp);
                return (record(c, NULL));
            }
            /*NOTREACHED*/
            break;

        case '-':
            bol = 0;
            /* -> */
            if ((nextc = getc(Fp)) == '>')
                return (record(ARROW, stable(Tok)));
            else {
                (void) ungetc(nextc, Fp);
                return (record(c, NULL));
            }
            /*NOTREACHED*/
            break;

        case '<':
            bol = 0;
            if ((nextc = getc(Fp)) == '=')
                /* <= */
                return (record(LE, NULL));
            else if (nextc == '<')
                /* << */
                return (record(LSHIFT, NULL));
            else {
                (void) ungetc(nextc, Fp);
                return (record(c, NULL));
            }
            /*NOTREACHED*/
            break;

        case '>':
            bol = 0;
            if ((nextc = getc(Fp)) == '=')
                /* >= */
                return (record(GE, NULL));
            else if (nextc == '>')
                /* >> */
                return (record(RSHIFT, NULL));
            else {
                (void) ungetc(nextc, Fp);
                return (record(c, NULL));
            }
            /*NOTREACHED*/
            break;

        default:
            bol = 0;
            if (isdigit(c)) {
                int base;

                /* collect rest of number */
                if (c == '0') {
                    *ptr++ = c;
                    if ((c = getc(Fp)) == EOF) {
                        *ptr++ = '\0';
                        return (record(NUMBER,
                                       stable(Tok)));
                    } else if (c == 'x' || c == 'X') {
                        *ptr++ = c;
                        base = 16;
                    } else {
                        (void) ungetc(c, Fp);
                        base = 8;
                    }
                } else {
                    *ptr++ = c;
                    base = 10;
                }
                while ((c = getc(Fp)) != EOF) {
                    if (ptr >= eptr)
                        out(O_DIE, File, Line,
                            "number too long");

                    switch (base) {
                    case 16:
                        if (c >= 'a' && c <= 'f' ||
                                c >= 'A' && c <= 'F') {
                            *ptr++ = c;
                            continue;
                        }
                    /*FALLTHRU*/
                    case 10:
                        if (c >= '8' && c <= '9') {
                            *ptr++ = c;
                            continue;
                        }
                    /*FALLTHRU*/
                    case 8:
                        if (c >= '0' && c <= '7') {
                            *ptr++ = c;
                            continue;
                        }
                        /* not valid for this base */
                        *ptr++ = '\0';
                        (void) ungetc(c, Fp);
                        return (record(NUMBER,
                                       stable(Tok)));
                    }
                }
                *ptr++ = '\0';
                return (record(NUMBER, stable(Tok)));
            } else if (isalpha(c)) {
                /* collect identifier */
                *ptr++ = c;
                for (;;) {
                    c = getc(Fp);
                    if ((isalnum(c) || c == '_') &&
                            ptr < eptr)
                        *ptr++ = c;
                    else {
                        (void) ungetc(c, Fp);
                        break;
                    }
                }
                if (ptr >= eptr)
                    out(O_DIE, File, Line,
                        "identifier too long");
                *ptr++ = '\0';
                cptr = stable(Tok);
                if (val = lex_s2i_lut_lookup(Rwordslut, cptr)) {
                    return (record(val, cptr));
                }
                return (record(ID, cptr));
            } else
                return (record(c, NULL));
        }
        /*NOTREACHED*/
    }
}