⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 getsym.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 
Copyright 2001-2003 Free Software Foundation, Inc.
Written by David Lindauer, LADSoft

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  

You may contact the author at:

mailto::camille@bluegrass.net

or by snail mail at:

David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222
 */
/* scanner
 */
/* Trigraphs implemented, won't work for token pasting though */
#include <stdio.h>
#include <ctype.h>
#include <limits.h>
#include <string.h>
#include "lists.h"
#include "utype.h"
#include "cmdline.h"
#include "preproc.h"
#include "interp.h"

#define MAX_STRLEN 257

/* #define DEMO */

extern int prm_errfile;
extern char version[];
extern FILE *cppFile,  *listFile,  *inputFile;
extern int prm_cplusplus, prm_cmangle, prm_ansi;
extern int ifskip, elsetaken;
extern IFSTRUCT *ifs;
extern char *errfile;
extern int errlineno;
extern int phiused, prm_trigraph;

char *infile;
extern short *lptr; /* shared with preproc */
extern FILE *inclfile[10]; /* shared with preproc */
extern char *inclfname[10]; /* shared with preproc */
extern IFSTRUCT *ifshold[10];
extern int inclline[10]; /* shared with preproc */
extern int incldepth; /* shared with preproc */
extern int inclhfile[10];
extern int inhfile;
extern int prm_listfile;
int lineno;
int laststrlen;
short inputline[4096];
int lastch;
enum e_sym lastst;
char lastid[100] = "";
char laststr[MAX_STRLEN + 1] = "";
long ival = 0;
long double rval = 0.0;
char *linstack[20]; /* stack for substitutions */
char chstack[20]; /* place to save lastch */
int lstackptr = 0; /* substitution stack pointer */
int incconst = FALSE;

int backupchar =  - 1;

int demolines;
static int phiputcpp, phiputlist, phiputerror;
static int commentlevel;

void initsym(void)
{
    lptr = inputline;
    inputline[0] = 0;
    lineno = 0;
    errlineno = 0;
    lastid[0] = 0;
    laststr[0] = 0;
    ival = 0;
    rval = 0.0;
    incconst = FALSE;
    backupchar =  - 1;
    phiputcpp = phiputlist = phiputerror = FALSE;
} 

void lineToCpp(void)
/*
 * line has been preprocessed, dump it to a file
 */
{
    if (cppFile)
    {
        char buf[100],  *q = buf;
        short *p = inputline;
        *q = 0;
        if (!phiputcpp)
        {
            phiputcpp = TRUE;
            if (phiused)
                fputc('\x1f', cppFile);
            fprintf(cppFile, "/* LADsoft C compiler Version %s */\n\n", version)
                ;
        }
        while (*p)
        {
            int i;
            if (*q)
            {
                buf[0] =  *q;
                i = 1;
            }
            else
                i = 0;
            i += installphichar(*p++, buf, i);
            buf[i] = 0;
            q = buf;
            while (*q && (*(q + 1) || ((*q &0xf0) != 0x90)))
                fputc(*q++, cppFile);
        }
    }
}

/* Strips comments and also the newline char at the end of the line */
static void stripcomment(short *line)
{
    short *s = line,  *e = s, instr = FALSE;
    while (*e)
    {
        if (!instr &&  *e == '/' && (!commentlevel || !prm_ansi ||
            prm_cplusplus))
        {
            if (*(e+1) == '*')
            {
                e++;
                commentlevel++;
            }
            else if (*(e+1) == '/' && !commentlevel && (!prm_ansi ||
                prm_cplusplus))
            {
                *s++ = '\n';
                *s++ = 0;
                return ;
            }
            else if (!commentlevel)
                *s++ =  *e;
        }
        else if (!instr && commentlevel &&  *e == '*' && *(e+1) == '/')
        {
            commentlevel--;
            e++;
            if (commentlevel == 0)
            {
                *s++ = ' '; /* Comments are whitespace */
            }
        }
        else if (!commentlevel)
        {
            if (instr)
            {
                if (*e == instr)
                    instr = 0;
                else if (*e == '\\')
                    *s++ =  *e++;
            }
            else if (*e == '"')
                instr = '"';
            else if (*e == '\'')
                instr = '\'';
            *s++ =  *e;
        }
        e++;
    }
    *s = 0;
}

/* strip trigraphs */
void striptrigraph(short *buf)
{
    short *cp = buf;
    while (*cp)
    {
        if (*cp == '?' && *(cp + 1) == '?')
        {
            cp += 2;
            switch (*cp++)
            {
                case '=':
                    *buf++ = '#';
                    break;
                case '(':
                    *buf++ = '[';
                    break;
                case '/':
                    *buf++ = '\\';
                    break;
                case ')':
                    *buf++ = ']';
                    break;
                case '\'':
                    *buf++ = '^';
                    break;
                case '<':
                    *buf++ = '{';
                    break;
                case '!':
                    *buf++ = '|';
                    break;
                case '>':
                    *buf++ = '}';
                    break;
                case '-':
                    *buf++ = '~';
                    break;
                default:
                    cp -= 2;
                    break;
            }
        }
        else
             *buf++ =  *cp++;
    }
    *buf = 0;
}

//-------------------------------------------------------------------------

int getline(int listflag)
/*
 * Read in a line, preprocess it, and dump it to the list and preproc files
 * Also strip comments and alter trigraphs
 */
{
    int rv, rvc, i, prepping, temp;
    static int inpreprocess;
    char ibuf[4096], xbuf[4096],  *xptr;
    int *ptr = ibuf;
    repeatit: 
    do
    {
        rv = FALSE;
        prepping = FALSE;
        rvc = 0;
        if (lineno > 0 && listflag && prm_listfile)
        {
            if (!phiputlist)
            {
                if (phiused)
                {
                    fputc('\x1f', listFile);
                }
                phiputlist = TRUE;
            }
        }
        if (lineno > 0 && prm_errfile)
        {
            if (!phiputerror)
            {
                if (phiused)
                {
                    fputc('\x1f', listFile);
                }
                phiputerror = TRUE;
            }
        }
        lferror();
        add: 
        while (rvc + 131 < 4096 && !rv)
        {
            ++lineno;
            ++errlineno;
            #ifdef DEMO
                if (++demolines > 100)fatal(
                    "Demo restricted to 100 lines of input")
                    ;
            #endif 
            rv = (philine(ibuf + rvc, 200, inputFile) == NULL);
            if (rv)
            {
                break;
            }
            rvc = strlen(ibuf);
            if (ibuf[rvc - 1] != '\n')
            {
                ibuf[rvc++] = '\n';
                ibuf[rvc] = 0;
            }
            rvc -= 2;
            while (ibuf[rvc] == ' ')
                rvc--;
            //					if (ibuf[rvc] != '\\')
            break;
        }
        if (rvc)
            rv = FALSE;
        if (rv)
        {
            if (ifs)
                generror(ERR_PREPROCMATCH, 0, 0);
            if (commentlevel)
                generror(ERR_COMMENTMATCH, 0, 0);
            if (incldepth > 0)
            {
                fclose(inputFile);
                inputFile = inclfile[--incldepth];
                lineno = inclline[incldepth];
                inhfile = inclhfile[incldepth];
                infile = inclfname[incldepth];
                errlineno = lineno;
                errfile = infile;
                ifs = ifshold[incldepth];
                commentlevel = 0;
                popif();
                goto repeatit;
            }
        }
        if (rv)
            return 1;
        lptr = inputline;
        ptr = ibuf;
        xptr = xbuf;
        while ((temp = parsechar(&ptr)) != 0)
        {
            *lptr++ = (unsigned char)temp;
            *xptr++ = (unsigned char)temp;
        }
        *lptr = 0;
        *xptr = 0;
        stripcomment(inputline);
        if (prm_trigraph)
            striptrigraph(inputline);
        lptr = inputline;
        while (iswhitespacechar(*lptr))
            lptr++;
        if (lptr[0] == '#')
        {
            inpreprocess++;
            listflag = preprocess();
            inpreprocess--;
            prepping = TRUE;
            lastst = eol;
        }
        if (incldepth)
            lastst = eol;
    }
    while (ifskip || prepping || inhfile && !inpreprocess)
        ;
    rvc = strlen(ibuf);
    if (defcheck(inputline) ==  - 10 && rvc + 131 < 4096)
    {
        if (ibuf[rvc - 1] == '\n')
            ibuf[rvc - 1] = ' ';
        goto add;
    }
    if (prm_listfile)
    {
        if (!phiputlist)
        {
            if (phiused)
            {
                fputc('\x1f', listFile);
            }
            fprintf(listFile, "LADsoft RC compiler Version %s\n\n", version);
            phiputlist = TRUE;
        }
        fprintf(listFile, "%5d: %s", lineno, xbuf);
    }
    lineToCpp();
    return 0;
}

/*
 *      getch - basic get character routine.
 */
int getch(void)
{
    while ((lastch =  *lptr++) == '\0')
    {
        if (lstackptr > 0)
        {
            lptr = linstack[--lstackptr];
            lastch = chstack[lstackptr];
            return lastch;
        }
        if (getline(incldepth == 0))
            return lastch =  - 1;
    }
    return lastch;
}

/*
 *      getid - get an identifier.
 *
 *      identifiers are any isidch conglomerate
 *      that doesn't start with a numeric character.
 *      this set INCLUDES keywords.
 */
void getid()
{
    register int i;
    i = 0;
    if (prm_cmangle)
        lastid[i++] = '_';
     /* Mangling */
    if (lastch == 'L')
    {
        lastid[i++] = 'L';
        getch();
        if (lastch == '\"')
        {
            getch();
            i = 0;
            while (lastch != '\"' && lastch)
            {
                *(((short*)(laststr)) + i++) = lastch;
                getch();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -