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

📄 preproc.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 4 页
字号:
/* 
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
 */
#include <stdio.h>
#include <fcntl.h>
#include <ctype.h>
#include <string.h>
#include <limits.h>
#include "utype.h"
#include "cmdline.h"
#include "lists.h"
#include "expr.h"
#include "c.h"
#include "ccerr.h"
#include <time.h>

#define REPLACED_TOKENIZING 0x80
#define TOKENIZING_PLACEHOLDER 0x81

extern int prm_nasm, prm_c99;
extern short inputline[];
extern int inputFile;
extern TABLE *gsyms, defsyms;
extern LLONG_TYPE ival;
extern char laststr[];
extern HASHREC **defhash;
extern char *infile;
extern int incconst;
extern char *prm_searchpath,  *sys_searchpath;
extern int prm_cplusplus, prm_ansi;
extern short *lptr;
extern int cantnewline;
extern int backupchar;
extern int floatregs, dataregs, addrregs, basefr, basedr, basear;
extern int prm_cmangle;
extern enum e_sym lastst;
extern char lastid[];
extern int lastch;
extern int lineno;
extern int global_flag;
extern char inputbuffer[32768];
extern int inputlen;
extern char *ibufPtr;

typedef struct _startups_
{
    struct _startups_ *link;
    char *name;
    int prio;
} STARTUPS;

#define INCL_LEVEL_MAX 16

char *errfile;
int sys_inc;
int errlineno = 0;
IFSTRUCT *ifshold[70];
char *inclfname[INCL_LEVEL_MAX];
int inclfile[INCL_LEVEL_MAX];
int incldepth = 0;
int inclline[64];
int inclcurrent[INCL_LEVEL_MAX];
char *incldata[INCL_LEVEL_MAX];
int inclpos[INCL_LEVEL_MAX];
int inclsysflags[INCL_LEVEL_MAX];
char *inclptr[INCL_LEVEL_MAX];
short *lptr;
int stdpragmas;

FILELIST *incfiles = 0,  *lastinc;

LIST *libincludes = 0;

IFSTRUCT *ifs = 0;
int ifskip = 0;
int elsetaken = 0;
int currentfile = 0;
AUXLIST *auxlist;
int packdata[100] = 
{
    1
};
int packlevel;

void filemac(short *string);
void datemac(short *string);
void timemac(short *string);
void linemac(short *string);

static char *unmangid; /* In this module we have to ignore leading underscores
    */
static STARTUPS *startuplist,  *rundownlist;
static short defkw[] = 
{
    'd', 'e', 'f', 'i', 'n', 'e', 'd', 0
};
static int definelistcount;
static SYM *definelist[100]; /* Way deep but hey! */
static int skiplevel;
/* List of standard macros */
#define INGROWNMACROS 4

struct inmac
{
    char *s;
    void(*func)();
} ingrownmacros[INGROWNMACROS] = 
{
    {
        "__FILE__", filemac
    }
    , 
    {
        "__DATE__", datemac, 
    }
    , 
    {
        "__TIME__", timemac
    }
    , 
    {
        "__LINE__", linemac
    }
};

static void repdefines(short *lptr);

void pushif(void);

/* Moudle init */
void preprocini()
{
    stdpragmas = STD_PRAGMA_FCONTRACT ;
    skiplevel = 0;
    libincludes = 0;
    floatregs = basefr;
    dataregs = basedr;
    addrregs = basear;
    incldepth = 0;
    incfiles = 0;
    ifs = 0;
    ifskip = elsetaken = 0;
    currentfile = 0;
    unmangid = lastid;
    if (prm_cmangle)
        unmangid++;
    startuplist = rundownlist = 0;
    lastinc = 0;
}

/* Preprocessor dispatch */
int preprocess(void)
{
    ++lptr;
    lastch = ' ';
    while (isspace (*lptr))
        lptr++ ;
    if (*lptr == '\n' || ! *lptr)
        return incldepth == 0;
    getsym(); /* get first word on line */

    if (lastst != id && lastst != kw_else && lastst != kw_if)
    {
        generror(ERR_IDEXPECT, 0, 0);
        return incldepth == 0;
    }
    if (strcmp(unmangid, "include") == 0)
        return doinclude();
    else if (strcmp(unmangid, "define") == 0)
        return dodefine();
    else if (strcmp(unmangid, "endif") == 0)
        return doendif();
    else if (lastst == kw_else)
        return doelse();
    else if (strcmp(unmangid, "ifdef") == 0)
        return doifdef(TRUE);
    else if (strcmp(unmangid, "ifndef") == 0)
        return doifdef(FALSE);
    else if (lastst == kw_if)
    {
        repdefines(lptr);
        defcheck(lptr);
        return doif(0);
    }
    else if (strcmp(unmangid, "elif") == 0)
    {
        repdefines(lptr);
        defcheck(lptr);
        return doelif();
    }
    else if (strcmp(unmangid, "undef") == 0)
        return (doundef());
    else if (strcmp(unmangid, "error") == 0)
        return (doerror());
    else if (strcmp(unmangid, "pragma") == 0)
        return (dopragma());
    else if (strcmp(unmangid, "line") == 0)
        return (doline());
    else
    {
        gensymerror(ERR_PREPROCID, unmangid);
        return incldepth == 0;
    }
}

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

int doerror(void)
{
    char *temp;
    int i = 0;
    if (ifskip)
        return incldepth == 0;
    global_flag++;
    temp = xalloc(pstrlen(lptr) *3+2);
    pstrcpy(temp, lptr);
    while (*lptr)
        temp[i++] =  *lptr++;
    temp[i - 1] = 0;
    global_flag--;
    basicerror(ERR_ERROR, temp);
    return incldepth == 0;
}

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

char *getauxname(short *ptr, char **bufp)
{
    char buf[200],  *bp = buf;
    while (isspace(*ptr))
        ptr++;
    if (*ptr != '"' &&  *ptr != '<')
    {
        generror(ERR_ILLCHAR,  *ptr, 0);
        return 0;
    }
    ptr++;
    if (prm_cmangle)
        *bp++ = '_';
    while (*ptr &&  *ptr != '>' &&  *ptr != '"')
        *bp++ =  *ptr++;
    *bp++ = 0;
    if (! *ptr ||  *ptr != '"' &&  *ptr != '>')
    {
        generror(ERR_ILLCHAR, *(ptr - 1), 0);
        return 0;
    }
    ptr++;
    while (isspace(*ptr))
        ptr++;
    *bufp = xalloc(strlen(buf) + 1);
    strcpy(*bufp, buf);
    return ptr;
}

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

static int pragerror(int errno)
{
    char buf[100],  *p = buf, i = 99;
    short *s = lptr;
    while (i-- &&  *s &&  *s != '\n')
        *p++ =  *s++;
    *p = 0;
    basicerror(errno, buf);
    return (incldepth == 0);
}

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

int dopragma(void)
{
    char buf[40],  *p = buf;
    STARTUPS *a;
    int val = 0, sflag;
    if (ifskip)
        return incldepth == 0;
    cantnewline = TRUE;
    lineToCpp();
    getsym();
    cantnewline = FALSE;
    if (lastst != id)
        return incldepth == 0;
    if (!strcmp(unmangid, "error"))
        return pragerror(ERR_USERERR);
    else if (!strcmp(unmangid, "warning"))
        return pragerror(ERR_USERWARN);
    else if (!strcmp(unmangid, "startup"))
        sflag = 1;
    else if (!strcmp(unmangid, "rundown"))
        sflag = 0;
    else if (!strncmp(unmangid, "regopt", 6))
    {
        short *s = lptr;
        dataregs = floatregs = addrregs = 0;
        while (*s != '\n')
        {
            switch (*s)
            {
                case 'a':
                case 'A':
                    addrregs = 1;
                    break;
                case 'f':
                case 'F':
                    floatregs = 1;
                    break;
                case 'd':
                case 'D':
                    dataregs = 1;
                    break;
            }
            s++;
        }
        return incldepth == 0;
    }
    else if (!strncmp(unmangid, "STDC", 4))
    {
        int val = 0, on = 0;
        cantnewline = TRUE;
        getsym();
        cantnewline = FALSE;
        if (!strncmp(unmangid, "FENV_ACCESS", 11))
            val = STD_PRAGMA_FENV;
        else if (!strncmp(unmangid, "CX_LIMITED_RANGE", 16))
            val = STD_PRAGMA_CXLIMITED;
        else if (!strncmp(unmangid, "FP_CONTRACT", 11))
            val = STD_PRAGMA_FCONTRACT;
        else
            return incldepth == 0;
        cantnewline = TRUE;
        getsym();
        cantnewline = FALSE;
        if (!strncmp(unmangid, "ON", 2))
            on = 1;
        else if (strncmp(unmangid, "OFF", 3))
            return incldepth == 0;
        if (on)
            stdpragmas |= val;
        else
            stdpragmas &= ~val;
        return incldepth == 0;
    }
    else
    if (!strncmp(unmangid, "library", 7))
    {
        if (prm_nasm)
        {
            generror(ERR_PREPIG,  *lptr, 0);
        }
        else
        {
            short *s = lptr - 1;
            char buf[128],  *p = buf;
            while (isspace(*s))
                s++;
            if (*s++ != '(')
            {
                generror(ERR_ILLCHAR,  *lptr, 0);
            }
            else
            {
                while (isspace(*s))
                    s++;
                while (isalnum(*s) ||  *s == '.' ||  *s == ':' ||  *s == '\\')
                    *p++ =  *s++;
                *p = 0;
                while (isspace(*s))
                    s++;
                if (*s++ != ')')
                {
                    generror(ERR_ILLCHAR,  *lptr, 0);
                }
                else
                {
                    LIST *l;
                    char *f;
                    global_flag++;
                    f = litlate(buf);
                    l = xalloc(sizeof(LIST));
                    l->data = f;
                    l->link = libincludes;
                    libincludes = l;
                    global_flag--;
                }
            }
        }
        return incldepth == 0;
    }
    else
    if (!strncmp(unmangid, "pack", 4))
    {
        lptr--;
        while (isspace(*lptr))
            lptr++;
        if (*lptr != '(')
        {
            generror(ERR_ILLCHAR,  *lptr, 0);
            return incldepth = 0;
        }
        lptr++;
        while (isspace(*lptr))
            lptr++;
        if (*lptr == ')')
        {
            if (packlevel)
                packlevel--;
        }
        else if (isdigit(*lptr))
        {
            if (packlevel < sizeof(packdata) - 1)
            {
                packdata[++packlevel] = 0;
                while (isdigit(*lptr))
                {
                    packdata[packlevel] *= 10;
                    packdata[packlevel] +=  *lptr++ - '0';
                }
                if (packdata[packlevel] < 1)
                    packdata[packlevel] = 1;
            }
            while (isdigit(*lptr))
                lptr++;
            while (isspace(*lptr))
                lptr++;
            if (*lptr != ')')
                generror(ERR_ILLCHAR,  *lptr, 0);
        }
        return incldepth == 0;
    }
    else
    if (!strcmp(unmangid, "aux"))
    {
        AUXLIST *newaux;
        SYM *sp;
        char *name;
        char *alias;
        ++global_flag;
        lptr = getauxname(lptr, &name);
        --global_flag;
        if (!lptr)

⌨️ 快捷键说明

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