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

📄 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 页
字号:

            text[r++] = '\"';
            text[r] = 0;
            for (i = r; i >= 0; i--)
                text[i + 1] = text[i];
            *text = '\"';
        }
    }
    p = pstrlen(text);
    val = p - replen;
    r = pstrlen(begin);
    if (val + (int)strlen(begin) + 1 >= len)
    {
        generror(ERR_MACROSUBS, 0, 0);
        return ( - 8000);
    }
    if (val > 0)
        for (q = begin + r + 1; q >= end; q--)
            *(q + val) =  *q;
        else
    if (val < 0)
    {
        r = pstrlen(end) + 1;
        for (q = end; q < end + r; q++)
                *(q + val) =  *q;
    }
    for (i = 0; i < p; i++)
        begin[i] = text[i];
    return (p);
}

/* replace macro args */
int defreplace(short *macro, int count, short **oldargs, short **newargs)
{
    int i, rv;
    int instring = 0;
    short narg[1024];
    short name[100];
    short *p = macro,  *q;
    while (*p)
    {
        if (*p == instring)
            instring = 0;
        else if (*p == '\'' ||  *p == '"')
            instring =  *p;
        else if (!instring && isstartchar(*p))
        {
            q = p;
            defid(name, &p, 0);
            for (i = 0; i < count; i++)
            if (!pstrcmp(name, oldargs[i]))
            {
                pstrcpy(narg, newargs[i]);
                if ((rv = definsert(p, q, narg, 1024-(q - macro), p - q)) ==  -
                    8000)
                    return (FALSE);
                else
                {
                    p = q + rv;
                    break;
                }
            }
        }
        p++;
    }
    return (TRUE);
}

/* Handlers for default macros */
void cnvt(short *out, char *in)
{
    while (*in)
        *out++ =  *in++;
    *out = 0;
}

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

void filemac(short *string)
{
    char str1[40];
    sprintf(str1, "\"%s\"", infile);
    cnvt(string, str1);
}

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

void datemac(short *string)
{
    char str1[40];
    struct tm *t1;
    time_t t2;
    time(&t2);
    t1 = localtime(&t2);
    strftime(str1, 40, "\"%b %d %Y\"", t1);
    cnvt(string, str1);
}

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

void timemac(short *string)
{
    char str1[40];
    struct tm *t1;
    time_t t2;
    time(&t2);
    t1 = localtime(&t2);
    str1[0] = '"';
    strftime(str1, 40, "\"%X\"", t1);
    cnvt(string, str1);
}

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

void linemac(short *string)
{
    char str1[40];
    sprintf(str1, "%d", lineno);
    cnvt(string, str1);
} 
/* Scan for default macros and replace them */
void defmacroreplace(short *macro, short *name)
{
    int i;
    macro[0] = 0;
    for (i = 0; i < INGROWNMACROS; i++)
    if (!strcmp(name, ingrownmacros[i].s))
    {
        (ingrownmacros[i].func)(macro);
        break;
    }
}

/* The next few functions support recursion blocking for macros.
 * Basicall a list of all active macros is kept and if a lookup would 
 * result in one of those macros, no replacement is done.
 */
void nodefines(void)
{
    definelistcount = 0;
}

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

int indefine(SYM *sp)
{
    int i;
    for (i = 0; i < definelistcount; i++)
        if (sp == definelist[i])
            return TRUE;

    return FALSE;
}

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

void enterdefine(SYM *sp)
{
    definelist[definelistcount++] = sp;
}

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

void exitdefine(void)
{
    definelistcount--;
}

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

int replacesegment(short *start, short *end, int *inbuffer, int totallen, int
    *changed)
{
    short macro[1024];
    short name[1024];
    short *args[40];
    char ascii[60];
    int waiting = FALSE, rv;
    short *p,  *q;
    SYM *sp;
    p = start;
    while (p < end)
    {
        q = p;
        if (*p == '"')
        {
            waiting = !waiting;
            p++;
        }
        else if (waiting)
            p++;
        else if (isstartchar(*p))
        {
            defid(name, &p, ascii);
            if ((sp = search(ascii, &defsyms)) != 0 && !indefine(sp))
            {
                DEFSTRUCT *def = sp->value.s;
                enterdefine(sp);
                pstrcpy(macro, def->string);
                if (def->argcount)
                {
                    int count = 0;
                    short *q = p;
                    while (iswhitespacechar(*q))
                        q++;
                    if (*q++ != '(')
                    {
                        exitdefine();
                        goto join;
                    }
                    p = q;
                    if (def->argcount > 1)
                    {
                        do
                        {
                            short *nm = name;
                            int nestedparen = 0;
                            int nestedstring = 0;
                            while (((*p != ',' &&  *p != ')') || nestedparen ||
                                nestedstring) &&  *p != '\n')
                            {
                                if (*p == '(')nestedparen++;
                                if (*p == ')' && nestedparen)
                                    nestedparen--;
                                if (nestedstring)
                                {
                                    if (*p == nestedstring)
                                        nestedstring = 0;
                                }
                                else if (*p == '\'' ||  *p == '"')
                                    nestedstring =  *p;
                                *nm++ =  *p++;
                            }
                            while (iswhitespacechar(*(nm - 1)))
                                nm--;
                            *nm = 0;
                            nm = name;
                            while (iswhitespacechar(*nm))
                                nm++;
                            args[count++] = plitlate(nm);
                        }
                        while (*p++ == ',')
                            ;
                    }
                    else
                        while (iswhitespacechar(*p++))
                            ;
                    if (*(p - 1) != ')' || count != def->argcount - 1)
                    {
                        if (*(p - 1) == '\n')
                            return  - 10;
                        gensymerror(ERR_WRONGMACROARGS, ascii);
                        return  - 1;
                    }
                    /* Can't replace if tokenizing next */
                    if (*p == '#' && *(p + 1) == '#')
                        continue;
                    if (count == 0)
                        goto insert;
                    if (!defreplace(macro, count, def->args, args))
                        return  - 1;
                }
                insert: if ((rv = definsert(p, q, macro, totallen -  *inbuffer,
                    p - q)) ==  - 8000)
                    return  - 1;
                *changed = TRUE;
                rv = replacesegment(q, q + rv, inbuffer, totallen, changed);
                if (rv < 0)
                    return rv;
                end += rv - (p - q);
                *inbuffer += rv - (p - q);
                p = q + rv;
                exitdefine();
                *changed = TRUE;
            }
            else
            {
                join: defmacroreplace(macro, ascii);
                if (macro[0])
                {
                    if ((rv = definsert(p, q, macro, totallen -  *inbuffer, p -
                        q)) ==  - 8000)
                        return  - 1;
                    *changed = TRUE;
                    end += rv - (p - q);
                    *inbuffer += rv - (p - q);
                    p = q + rv;
                }
            }
        }
        else
            p++;
    }
    return (int)(end - start);
}

/* Scan line for macros and do replacements */
int defcheck(short *line)
{
    int x;
    short *p = line,  *q;
    int inbuffer = pstrlen(line);
    int changed = FALSE;
    nodefines();
    if ((x = replacesegment(line, line + inbuffer, &inbuffer, 4096, &changed))
        < 0)
        return x;

    /* Token pasting */
    if (changed)
    {
        p = q = line;
        while (*p)
        {
            if (*p == '#' && *(p + 1) == '#')
                p += 2;
            else
                *q++ =  *p++;
        }
        *q = 0;
    }
    return 0;
}

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

static void repdefines(short *lptr)
/*
 * replace 'defined' keyword in #IF and #ELIF statements
 */
{
    short *q = lptr;
    short name[40];
    char ascii[60];
    while (*lptr)
    {
        if (!pstrncmp(lptr, defkw, 7))
        {
            int needend = FALSE;
            lptr += 7;
            if (*lptr == '(')
            {
                lptr++;
                needend = TRUE;
            }
            while (iswhitespacechar(*lptr))
                lptr++;
            defid(name, &lptr, ascii);
            while (iswhitespacechar(*lptr))
                lptr++;
            if (needend)
                if (*lptr == ')')
                    lptr++;
                else
                    expecttoken(closepa, 0);
            if (search(ascii, &defsyms) != 0)
                *q++ = '1';
            else
                *q++ = '0';
            *q++ = ' ';

        }
        else
        {
            *q++ =  *lptr++;
        }
    }
    *q = 0;
}

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

void pushif(void)
/* Push an if context */
{
    IFSTRUCT *p;
    p = AllocateMemory(sizeof(IFSTRUCT));
    p->link = ifs;
    p->iflevel = ifskip;
    p->elsetaken = elsetaken;
    elsetaken = FALSE;
    ifs = p;
}

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

void popif(void)
/* Pop an if context */
{
    if (ifs)
    {
        ifskip = ifs->iflevel;
        elsetaken = ifs->elsetaken;
        ifs = ifs->link;
    }
    else
    {
        ifskip = 0;
        elsetaken = 0;
    }
}

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

void ansieol(void)
{
    if (prm_ansi)
    {
        while (iswhitespacechar(*lptr))
            lptr++;
        if (*lptr)
        {
            lastch =  *lptr;
            lastst = ident;
            generror(ERR_UNEXPECT, 0, 0);
        }
    }
}

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

int doifdef(int flag)
/* Handle IFDEF */
{
    SYM *sp;
    if (ifskip)
    {
        skiplevel++;
        return (incldepth == 0);
    }
    getch();
    while (isspace(lastch))
        getch();
    if (!isstartchar(lastch))
    {
        generror(ERR_IDEXPECT, 0, 0);
        return incldepth == 0;
    }
    else
        getid();
    sp = search(unmangid, &defsyms);
    pushif();
    if (sp && !flag || !sp && flag)
        ifskip = TRUE;
    ansieol();
    return (incldepth == 0);
}

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

int doif(int flag)
/* Handle #if */
{
    if (ifskip)
    {
        skiplevel++;
        return (incldepth == 0);
    }
    getsym();
    pushif();
    //	cantnewline = TRUE;
    if (!intexpr())
        ifskip = TRUE;
    else
        elsetaken = TRUE;
    //	cantnewline = FALSE;
    ansieol();
    return (incldepth == 0);
}

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

int doelif(void)
/* Handle #elif */
{
    int is;
    if (skiplevel)
    {
        return (incldepth == 0);
    }

    getsym();
    //		cantnewline = TRUE;
    is = !intexpr();
    //		cantnewline = FALSE;
    if (!elsetaken)
    {
        if (ifs)
        {
            if (!ifs->iflevel)
                ifskip = !ifskip || is || elsetaken;
            if (!ifskip)
                elsetaken = TRUE;
        }
        else
            generror(ERR_PREPROCMATCH, 0, 0);
    }
    else
        ifskip = TRUE;
    ansieol();
    return (incldepth == 0);
}

/* handle else */
int doelse(void)
{
    if (skiplevel)
    {
        return (incldepth == 0);
    }
    if (ifs)
    {
        if (!ifs->iflevel)
            ifskip = !ifskip || elsetaken;
    }
    else
        generror(ERR_PREPROCMATCH, 0, 0);
    ansieol();
    return (incldepth == 0);
}

/* HAndle endif */
int doendif(void)
{
    if (skiplevel)
    {
        skiplevel--;
        return (incldepth == 0);
    }
    if (!ifs)
        generror(ERR_PREPROCMATCH, 0, 0);
    popif();
    ansieol();
    return (incldepth == 0);
}

⌨️ 快捷键说明

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