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

📄 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 1994-2003 Free Software Foundation, Inc.

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.  

This program is derived from the cc68k complier by 
Matthew Brandt (mattb@walkingdog.net) 

You may contact the author of this derivative 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 <string.h>
#include <float.h>
#include <limits.h>
#include <math.h>
#include "lists.h"
#include "expr.h"
#include "c.h"
#include "ccerr.h"
#include "utype.h"

/* #define DEMO */

// The following would need to be changed if hosting on something other than an x86

#define LDBL_INFNAN 0x7fff
#define LDBL_SHIFTWORDS 4

extern int outputFile;
extern int prm_c99;
extern short *interjectptr;
extern int recordingTemplate, recordingClassFunc;
extern int prm_errfile;
extern char version[];
extern LIST *clist;
extern FILE *cppFile,  *listFile;
extern int inputFile;
extern int prm_cplusplus, prm_cmangle, prm_ansi;
extern int ifskip, elsetaken;
extern IFSTRUCT *ifs;
extern char *errfile;
extern int errlineno;
extern int prm_trigraph;
extern int sys_inc;

extern int currentfile;
extern char *infile;
extern short *lptr; /* shared with preproc */
extern int inclfile[20]; /* shared with preproc */
extern char *inclfname[20]; /* shared with preproc */
extern IFSTRUCT *ifshold[70];
extern int inclline[20]; /* shared with preproc */
extern int inclcurrent[20];
extern int inclpos[20];
extern char *incldata[20];
extern char *inclptr[20];
extern int inclsysflags[20];
extern int incldepth; /* shared with preproc */
extern int prm_listfile;

int sym_charindex;
int lineno;
int laststrlen;
short inputline[MACRO_REPLACE_SIZE+1], unalteredline[MACRO_REPLACE_SIZE+1];
int lastch;
enum e_sym lastst, lastlastst;
char lastid[101] = "", backupid[101];
char laststr[MAX_STRLEN *2+1] = "";
LLONG_TYPE 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 cantnewline = FALSE;
int incconst = FALSE;

int backupchar =  - 1;

int demolines;
char inputbuffer[32768];
int inputlen;
char *ibufPtr;

static int commentlevel;
static ULLONG_TYPE llminus1;
static int recordingOff;
static int floating_infinity = 0x7f800000;

int phiputcpp, phiputlist;
void initsym(void)
{
    lptr = inputline;
    phiputcpp = 0;
    phiputlist = 0;
    inputline[0] = 0;
    lineno = 0;
    errlineno = 1;
    lastid[0] = 0;
    laststr[0] = 0;
    ival = 0;
    rval = 0.0;
    cantnewline = FALSE;
    incconst = FALSE;
    backupchar =  - 1;
    llminus1 = 0;
    llminus1--; // done at run-time so I don't have to compile twice
    recordingOff = FALSE;
    inputlen = 0;
} 

void lineToCpp(void)
/*
 * line has been preprocessed, dump it to a file
 */
{
    if (cppFile)
    {
        short *p = inputline;
        if (!phiputcpp)
        {
            phiputcpp = TRUE;
            fprintf(cppFile, "/* LADsoft C compiler Version %s */\n\n", version)
                ;
        }
        while (*p)
        {
            fputc(*p++, cppFile);
        }
    }
}

/* Strips comments */
static void stripcomment(char *line)
{
    char *s = line,  *e = s, instr = 0;
    while (*e)
    {
        if (!instr)
        {
            if (!commentlevel)
            {
                if (*e == '/')
                {
                    if (*(e+1) == '*')
                    {
                        e += 2;
                        *s++ = ' ';
                        commentlevel = 1;
                        continue;
                    }
                    else if (*(e+1) == '/' && (!prm_ansi || prm_c99 || prm_cplusplus))
                    {
                        *s++ = '\n';
                        *s = 0;
                        return ;
                    }
                }
                else
                    if (*e == '"' ||  *e == '\'')
                        instr =  *e;
            }
            else
            {
                if (*e == '*')
                {
                    if (*(e+1) == '/')
                    {
                        commentlevel = 0;
                        e++;
                    }
                }
                e++;
                continue;
            }
        }
        else
        if (!commentlevel &&  *e == instr)
        {
            int count = 0;
            while (s - count > line && *(s - count - 1) == '\\')
                count++;
            if (!(count &1))
                instr = 0;
        }
        *s++ =  *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 getstring(char *s, int len, int file)
{
    char *olds = s;
    while (TRUE)
    {
        while (inputlen--)
        {
            if (*ibufPtr == 0x1a)
            {
                *s = 0;
                inputlen = 0;
                return s == olds;
            }
            if (*ibufPtr != '\r')
            {
                if ((*s++ =  *ibufPtr++) == '\n' || !--len)
                {
                    *s = 0;
                    return 0;
                }
            }
            else
                ibufPtr++;
        }
        inputlen = read(file, inputbuffer, sizeof(inputbuffer));
        ibufPtr = inputbuffer;
        if (inputlen <= 0)
        {
            *s = 0;
            inputlen = 0;
            return s == olds;
        }
    }
}

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

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 char ibuf[MACRO_REPLACE_SIZE], xbuf[MACRO_REPLACE_SIZE] ;
    char  *xptr;
    char *ptr = ibuf, dcrv;
    short *uptr;
    if (cantnewline)
    {
        return (0);
    }
    repeatit: 
    do
    {
        rv = FALSE;
        prepping = FALSE;
        rvc = 0;
        lferror();
        add:
             
        while (rvc + 131 < MACRO_REPLACE_SIZE && !rv)
        {
            ++lineno;
            rv = getstring(ibuf + rvc, MACRO_REPLACE_SIZE-132-rvc, inputFile);
            if (rv)
                break;
            if (prm_listfile && !sys_inc)
            {
                fprintf(listFile, "%5d: %s", lineno, ibuf+rvc);
            }
            rvc = strlen(ibuf);
            while (rvc && isspace(ibuf[rvc - 1]))
                rvc--;

            if (!rvc || ibuf[rvc - 1] != '\\')
                break;
            rvc--;
        }
        if (rvc)
            ibuf[rvc++] = '\n';
        ibuf[rvc] = 0;
        stripcomment(ibuf);
        rvc = strlen(ibuf);
        if (rvc)
            rv = FALSE;
        if (rv)
        {
            if (ifs)
                generror(ERR_PREPROCMATCH, 0, 0);
            if (commentlevel)
                generror(ERR_COMMENTMATCH, 0, 0);
            if (incldepth > 0)
            {
                close(inputFile);
                inputFile = inclfile[--incldepth];
                lineno = inclline[incldepth];
                infile = inclfname[incldepth];
                currentfile = inclcurrent[incldepth];
                inputlen = inclpos[incldepth];
                ibufPtr = inclptr[incldepth];
                sys_inc = inclsysflags[incldepth];
                memcpy(inputbuffer, incldata[incldepth], sizeof(inputbuffer));
                errlineno = lineno;
                errfile = infile;
                ifs = ifshold[incldepth];
                commentlevel = 0;
                popif();
                browse_startfile(infile);
                if (prm_listfile)
                    fprintf(listFile,"\n");
                goto repeatit;
            }
            currentfile = 0;
        }
        if (rv)
            return 1;
        lptr = inputline;
        ptr = ibuf;
        xptr = xbuf;
        uptr = unalteredline;
        while (*ptr)
        {
            *lptr++ =  *ptr;
            *xptr++ =  *ptr;
            *uptr++ =  *ptr++;
        }
        *lptr = 0;
        *xptr = 0;
        *uptr = 0;
        if (prm_trigraph)
            striptrigraph(inputline);
        lptr = inputline;

        while (*lptr != '\n' && isspace(*lptr))
            lptr++;
        if (lptr[0] == '#')
        {
            recordingOff = TRUE;
            errlineno = lineno;
            listflag = preprocess();
            prepping = TRUE;
            recordingOff = FALSE;
        }
    }
    while (ifskip || prepping)
        ;
    rvc = strlen(ibuf);
    if (defcheck(inputline) ==  INT_MIN+1 && rvc + 131 < MACRO_REPLACE_SIZE)
    {
        if (ibuf[rvc - 1] == '\n')
            ibuf[rvc - 1] = ' ';
        goto add;
    }
    //      for (i=0; i < pstrlen(inputline); i++)
    //         if (inputline[i] == '/' && inputline[i+1] == '/') {
    //            inputline[i] = ' ' ;
    //            inputline[i+1] = 0 ;
    //            break ;
    //         }
    lineToCpp();
    return 0;
}

/*
 *      getch - basic get character routine.
 */
int getch(void)

{
    if (interjectptr)
    {
        if (lastch == '\n')
        {
            short *p = interjectptr;
            short *q = unalteredline;
            while (*p &&  *p != '\n')
                *q++ =  *p++;
            *q++ = '\n';
            *q++ = 0;
            lineno++;
        }
        if ((lastch =  *interjectptr++) == 0)
        {
            interjectptr--;
            lastch =  - 1;
        }
    }
    else
    while ((lastch =  *lptr++) == '\0')
    {
        if (lstackptr > 0)
        {
            lptr = linstack[--lstackptr];
            lastch = chstack[lstackptr];
            break;
        }
        if (cantnewline)
        {
            lptr--;
            lastch = ' ';
            break;
        }
        if (getline(incldepth == 0))
            return lastch =  - 1;
    }
    if ((recordingTemplate || recordingClassFunc) && !recordingOff && !ifskip)
        insertTemplateChar(lastch);
    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;
            lastst = lsconst;
            while (lastch != '\"' && lastch)
            {
                if (i >= MAX_STRLEN/2) {
                    generror(ERR_STRINGTOOBIG,0,0);
                    return ;
                }
                *(((short*)(laststr)) + i++) = getsch(2);
            }
            if ((lastch &0x7f) != '\"')
                generror(ERR_NEEDCHAR, '\"', 0);
            else
                getch();
            *(((short*)(laststr)) + i) = 0;
            laststrlen = i;
            return ;
        }
        else if (lastch == '\'')
        {
            getch();

⌨️ 快捷键说明

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