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

📄 preproc.c

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

#define MAX_STRLEN 257

extern int prm_packing;
extern int prm_nasm;
extern short inputline[];
extern FILE *inputFile;
extern TABLE *gsyms, defsyms;
extern long ival;
extern char laststr[];
extern HASHREC **defhash;
extern char *infile;
extern int incconst;
extern char *prm_searchpath;
extern int prm_cplusplus, prm_ansi;
extern short *lptr;
extern int cantnewline;
extern char *infile;
extern int backupchar;
extern int prm_cmangle;
extern enum e_sym lastst;
extern char lastid[];
extern char laststr[];
extern int lastch;
extern int lineno;
typedef struct _startups_
{
    struct _startups_ *link;
    char *name;
    int prio;
} STARTUPS;
char *errfile;
int errlineno = 0;
IFSTRUCT *ifshold[10];
char *inclfname[10];
FILE *inclfile[10];
int incldepth = 0;
int inclline[10];
int inclhfile[10];
int inhfile;
short *lptr;
LIST *incfiles = 0,  *lastinc;

LIST *libincludes = 0;

IFSTRUCT *ifs = 0;
int ifskip = 0;
int elsetaken = 0;

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()
{
    skiplevel = 0;
    libincludes = 0;
    incldepth = 0;
    incfiles = 0;
    ifs = 0;
    ifskip = elsetaken = 0;
    unmangid = lastid;
    if (prm_cmangle)
        unmangid++;
    startuplist = rundownlist = 0;
}

/* Preprocessor dispatch */
int preprocess(void)
{
    ++lptr;
    lastch = ' ';
    getsym(); /* get first word on line */

    if (lastst != ident)
    {
        generror(ERR_IDEXPECT, 0, 0);
        return incldepth == 0;
    }
    if (strcmp(unmangid, "include") == 0)
        return doinclude(FALSE);
    else if (strcmp(unmangid, "define") == 0)
        return dodefine();
    else if (strcmp(unmangid, "endif") == 0)
        return doendif();
    else if (strcmp(unmangid, "else") == 0)
        return doelse();
    else if (strcmp(unmangid, "ifdef") == 0)
        return doifdef(TRUE);
    else if (strcmp(unmangid, "ifndef") == 0)
        return doifdef(FALSE);
    else if (strcmp(unmangid, "if") == 0)
    {
        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;
    temp = AllocateMemory(pstrlen(lptr) *3+2);
    pstrcpy(temp, lptr);
    while (*lptr)
        i += installphichar(*lptr++, temp, i);
    temp[i - 1] = 0;
    basicerror(ERR_ERROR, temp);
    return incldepth == 0;
}

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

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 != ident)
        return incldepth == 0;
    if (!strcmp(unmangid, "error"))
        return pragerror(ERR_USERERR);
    else if (!strcmp(unmangid, "warning"))
        return pragerror(ERR_USERWARN);
    else
        return incldepth == 0;

}

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

int doline(void)
/*
 * Handle #line directive
 */
{
    int n;
    if (ifskip)
        return incldepth == 0;
    getsym();
    if (lastst != iconst)
        gensymerror(ERR_PREPROCID, "#line");
    else
    {
        n = ival;
        getsym();
        if (lastst != sconst)
            gensymerror(ERR_PREPROCID, "#line");
        else
        {
            errfile = litlate(laststr);
            errlineno = n - 1;
        }
    }
    return incldepth == 0;
}

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

int doinclude(int unquoted)
/*
 * HAndle include files
 */
{
    int rv;
    FILE *oldfile = inputFile;
    incconst = TRUE;
    getsym(); /* get file to include */
    incconst = FALSE;
    if (ifskip)
        return incldepth == 0;
    if (!unquoted)
    {
        if (lastst != sconst)
        {
            gensymerror(ERR_INCLFILE, "include");
            return incldepth == 0;
        }
    }
    else if (lastst == ident)
        getfilename();
    if (incldepth > 9)
    {
        generror(ERR_PREPROCID, 0, 0);
        return incldepth == 0;
    }
    inputFile = SearchPath(laststr, prm_searchpath, "r");
    if (inputFile == 0)
    {
        gensymerror(ERR_CANTOPEN, laststr);
        inputFile = oldfile;
        rv = incldepth == 0;
    }
    else
    {
        LIST *list;
        pushif();
        ifshold[incldepth] = ifs;
        elsetaken = 0;
        ifskip = 0;
        ifs = 0;
        inclhfile[incldepth] = inhfile;
        inclline[incldepth] = lineno;
        inclfile[incldepth] = oldfile; /* push current input file */
        inclfname[incldepth++] = infile;
        infile = litlate(laststr);
        list = AllocateMemory(sizeof(LIST));
        list->data = infile;
        list->link = 0;
        if (incfiles)
            lastinc = lastinc->link = list;
        else
            incfiles = lastinc = list;
        errfile = infile;
        errlineno = 0;
        rv = incldepth == 1;
        lineno = 0;
        inhfile = !stricmp(infile + strlen(infile) - 2, ".h");
    }
    return rv;
}

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

short *plitlate(short *string)
{
    short *temp = AllocateMemory(pstrlen(string) *sizeof(short) + sizeof(short))
        ;
    pstrcpy(temp, string);
    return temp;
}

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

void glbdefine(char *name, char *value)
{
    {
        SYM *sp;
        short *p;
        DEFSTRUCT *def;
        if ((sp = search(name, &defsyms)) != 0)
            return ;
        sp = AllocateMemory(sizeof(SYM));
        sp->name = litlate(name);
        def = AllocateMemory(sizeof(DEFSTRUCT));
        def->args = 0;
        def->argcount = 0;
        def->string = p = AllocateMemory(strlen(value) *sizeof(short) + 2);
        while (*value)
            *p++ =  *value++;
        *p++ = 0;
        sp->value.s = (char*)def;
        insert(sp, &defsyms);
        return ;
    }
}

/* Handle #defines
 * Doesn't check for redefine with different value
 * Does handle ANSI macros
 */
int dodefine(void)
{
    SYM *sp;
    DEFSTRUCT *def;
    short *args[40], count = 0;
    short *olptr;
    int p;
    getsym(); /* get past #define */
    if (ifskip)
        return incldepth == 0;
    olptr = lptr;
    if (lastst != ident)
    {
        generror(ERR_IDEXPECT, 0, 0);
        return incldepth == 0;
    }
    if ((sp = search(unmangid, &defsyms)) != 0)
        undef2();
    sp = AllocateMemory(sizeof(SYM));
    sp->name = litlate(unmangid);
    def = AllocateMemory(sizeof(DEFSTRUCT));
    def->args = 0;
    def->argcount = 0;
    if (lastch == '(')
    {
        getdefsym();
        getdefsym();
        while (lastst == ident)
        {
            args[count++] = plitlate(unmangid);
            getdefsym();
            if (lastst != comma)
                break;
            getdefsym();
        }
        if (lastst != closepa)
            generror(ERR_PUNCT, closepa, 0);
        olptr = lptr - 1;
        def->args = AllocateMemory(count *sizeof(short*));
        memcpy(def->args, args, count *sizeof(short*));
        def->argcount = count + 1;
    }
    while (iswhitespacechar(*olptr))
        olptr++;
    p = pstrlen(olptr);
    if (olptr[p - 1] == 0x0a)
        olptr[p - 1] = 0;
    def->string = plitlate(olptr);
    sp->value.s = (char*)def;
    insert(sp, &defsyms);
    return incldepth == 0;
}

/*
 * Undefine
 */
int doundef(void)
{
    getsym();
    if (!ifskip)
        undef2();
    return (incldepth == 0);
}

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

int undef2(void)
{
    if (lastst != ident)
        generror(ERR_IDEXPECT, 0, 0);
    else
    {
        SYM **p = (SYM **)LookupHash(unmangid, defhash, HASHTABLESIZE);
        if (p)
        {
            *p = (*p)->next;
        }
    }
}

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

void getdefsym(void)
{
    if (backupchar !=  - 1)
    {
        lastst = backupchar;
        backupchar =  - 1;
        return ;
    }
    restart:  /* we come back here after comments */
    while (iswhitespacechar(lastch))
        getch();
    if (lastch ==  - 1)
        lastst = eof;
    else if (isdigit(lastch))
        getnum();
    else if (isstartchar(lastch))
    {
        lptr--;
        defid(unmangid, &lptr, 0);
        lastch =  *lptr++;
        lastst = ident;
    }
    else if (getsym2())
        goto restart;
}

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

int defid(short *name, short **p, char *q)
/*
 * Get an identifier during macro replacement
 */
{
    int count = 0, i = 0;
    while (issymchar(**p))
    {
        if (count < 100)
        {
            name[count++] = *(*p);
            if (q)
                i += installphichar(*(*p), q, i);
        }
        (*p)++;
    }
    if (q)
    {
        if ((q[i - 1] &0xf0) == 0x90)
            q[i - 1] = 0x90;
        q[i] = '\0';
    }
    name[count] = 0;
    return (count);
}

/* 
 * Insert a replacement string
 */
int definsert(short *end, short *begin, short *text, int len, int replen)
{
    short *q;
    int i, p, r;
    int val;
    if (begin != inputline)
    if (*(begin - 1) == '#')
    {
        if (*(begin - 2) != '#')
        {
            begin--;
            replen++;
            r = pstrlen(text);

⌨️ 快捷键说明

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