Annotation of coherent/d/bin/cc/c/n0/sharp.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * C preprocessor.
                      3:  * This version of cpp runs as a module of cc0.
                      4:  */
                      5: #ifdef   vax
                      6: #include "INC$LIB:cc0.h"
                      7: #else
                      8: #include "cc0.h"
                      9: #endif
                     10: 
                     11: /*
                     12:  * Define a macro.
                     13:  */
                     14: define()
                     15: {
                     16:        register int c, narg;
                     17:        register CPPSYM *sp;
                     18:        register TOK *tp;
                     19:        TOK *targ[NARGS];
                     20: 
                     21:        c = getnb();
                     22:        if (c < 0 || ct[c] != ID)
                     23:                goto bad;
                     24:        getid(c);
                     25:        tp = idp;
                     26:        if ((sp = tp->t_sym) != NULL && sp->s_slevel == SL_CPP)
                     27:                ;
                     28:        else
                     29:                sp = NULL;
                     30:        /*
                     31:         * Gather up the arguments.
                     32:         */
                     33:        narg = -1;
                     34:        if ((c = get()) == '(') {
                     35:                ++narg;
                     36:                do {
                     37:                        if ((c = getnb()) == ')')
                     38:                                break;
                     39:                        if (c<0 || ct[c]!=ID)
                     40:                                goto bad;
                     41:                        getid(c);
                     42:                        if (narg < NARGS)
                     43:                                targ[narg] = idp;
                     44:                        ++narg;
                     45:                        c = getnb();
                     46:                } while (c == ',');
                     47:                if (c != ')')
                     48:                        goto bad;
                     49:                c = getnb();
                     50:        } else if (c == ' ' || c == '\t')
                     51:                c = getnb();
                     52:        /*
                     53:         * Gather macro body.
                     54:         */
                     55:        unget(c);
                     56:        while ((c = get()) >= 0) {
                     57:                switch (ct[c]) {
                     58:                case QUOTE:
                     59:                case STRING:
                     60:                        dputstr(c);
                     61:                        continue;
                     62:                case SKIP:
                     63:                        unget(c = getnb());
                     64:                        dputc(' ');
                     65:                        continue;
                     66:                case SHARP:
                     67:                        if (nextis(c)) {
                     68:                                if (dputp > dbuf && dputp[-1] == ' ')
                     69:                                        --dputp;
                     70:                                if (dputp == dbuf) {
                     71:                                        cerror("## at beginning of macro");
                     72:                                        continue;
                     73:                                }
                     74:                                c = getnb();
                     75:                                if (c < 0) {
                     76:                                        cerror("## at end of macro");
                     77:                                        continue;
                     78:                                }
                     79:                                unget(c);
                     80:                                dputc('#');
                     81:                                dputc('#');
                     82:                                continue;
                     83:                        }
                     84:                        c = getnb();
                     85:                        if (ct[c] != ID) {
                     86:                                unget(c);
                     87:                                c = narg;
                     88:                        } else {
                     89:                                getid(c);
                     90:                                for (c = 0; c < narg; c += 1)
                     91:                                        if (idp == targ[c])
                     92:                                                break;
                     93:                        }
                     94:                        if (c >= narg)
                     95:                                cerror("parameter must follow #");
                     96:                        else {
                     97:                                dputc('#');
                     98:                                dputc(ARG0+c);
                     99:                        }
                    100:                        continue;
                    101:                case CON:
                    102:                case DOT:
                    103:                        dputnum(c);
                    104:                        continue;
                    105:                case ID:
                    106:                        getid(c);
                    107:                        for (c = 0; c < narg; c += 1)
                    108:                                if (idp == targ[c])
                    109:                                        break;
                    110:                        if (c >= narg)
                    111:                                dputs(id);
                    112:                        else
                    113:                                dputc(ARG0+c);
                    114:                        continue;
                    115:                default:
                    116:                        dputc(c);
                    117:                        continue;
                    118:                }
                    119:        }
                    120:        if (dputp > dbuf && dputp[-1] == ' ')
                    121:                --dputp;
                    122:        dputc(0);
                    123:        if (sp != NULL) {
                    124:                if (sp->s_value > XUSERA
                    125:                 || strcmp(dbuf, sp->s_body) != 0
                    126:                 || sp->s_narg != narg)
                    127:                        cerror("\"%s\" redefined", tp->t_id);
                    128: #if ANSI_STUPID
                    129:                else
                    130:                        for (c = 0; c < narg; c += 1)
                    131:                                if (targ[c] != sp->s_targ[c])
                    132:                                        cerror("\"%s\" redefined", tp->t_id);
                    133: #endif
                    134:        } else {
                    135:                if (narg > NARGS) {
                    136:                        cerror("\"%s\" has too many arguments", tp->t_id);
                    137:                        narg = NARGS;
                    138:                }
                    139:                sp = newcpp(narg, dbuf, dputp-dbuf);
                    140:                sp->s_sp = tp->t_sym;
                    141:                tp->t_sym = sp;
                    142: #if ANSI_STUPID
                    143:                if (narg > 0) {
                    144:                        sp->s_targ = new(narg * sizeof(TOK *));
                    145:                        for (c = 0; c < sp->s_narg; c += 1)
                    146:                                sp->s_targ[c] = targ[c];
                    147:                }
                    148: #endif
                    149:        }
                    150:        dputp = dbuf;
                    151:        return;
                    152: 
                    153:  bad:
                    154:        cerror("error in #define syntax");
                    155:        while (c >= 0)
                    156:                c = get();
                    157:        dputp = dbuf;
                    158: }
                    159: 
                    160: /*
                    161:  * Read a file name for #include or #line
                    162:  * into dbuf.
                    163:  * Return quote character on success,
                    164:  * 0 for any kind of error.
                    165:  */
                    166: getfname()
                    167: {
                    168:        register int    c, d;
                    169:        register char *spshp, *p;
                    170: 
                    171:        d = 0;
                    172:        spshp = dpshp;
                    173:        while ((c = getnb()) >= 0 && ct[c] == ID)
                    174:                if ( ! expand(c))
                    175:                        goto done;
                    176:        if (c == '<')
                    177:                d = '>';
                    178:        else if (c == '"')
                    179:                d = c;
                    180:        else
                    181:                goto done;
                    182:        instring = d;
                    183:        while ((c=get()) >= 0 && c != d)
                    184:                dpshc(c);
                    185:        instring = 0;
                    186:        if (c != d)
                    187:                d = 0;
                    188:  done: while (c >= 0)
                    189:                c = get();
                    190:        for (p = spshp; --p >= dpshp; )
                    191:                dputc(*p);
                    192:        dputc(0);
                    193:        dpshp = spshp;
                    194:        return d;
                    195: }
                    196: 
                    197: /*
                    198:  * File inclusion.
                    199:  * incdirs[0] is always "".
                    200:  */
                    201: include()
                    202: {
                    203:        register int    c, d;
                    204:        char *fbuf;
                    205:        FILE *fp;
                    206: 
                    207:        if (istackp == istack)
                    208:                cfatal("include stack overflow");
                    209:        if ((d = getfname()) == 0) {
                    210:                dputp = dbuf;
                    211:                cerror("error in #include syntax");
                    212:                return;
                    213:        }
                    214:        fp = NULL;
                    215:        fbuf = dputp;
                    216:        dputp = dbuf;
                    217:        for (c = (d != '"'); c < ndirs; c += 1) {
                    218:                strcpy(fbuf, incdirs[c]);
                    219: #ifdef COHERENT
                    220:                if (fbuf[0] != '\0')
                    221:                        strcat(fbuf, "/");
                    222: #endif
                    223: #if GEMDOS || MSDOS
                    224:                if (fbuf[0] != 0 && fbuf[strlen(fbuf)-1] != '\\')
                    225:                        strcat(fbuf, "\\");
                    226: #endif
                    227:                strcat(fbuf, dbuf);
                    228:                if ((fp=fopen(fbuf, "r")) != NULL)
                    229:                        break;
                    230:        }
                    231:        if (fp == NULL)
                    232:                return cfatal("cannot open include file \"%s\"", dbuf);
                    233:        --istackp;
                    234:        istackp->i_fp = ifp;
                    235:        istackp->i_file = tfile;
                    236:        istackp->i_line = line;
                    237:        istackp->i_cstackp = cstackp;
                    238:        ifp = fp;
                    239:        line = 1;
                    240:        notskip = 0;
                    241:        setid(fbuf);
                    242:        setfname();
                    243:        emptyfilep();
                    244:        return;
                    245: }
                    246: 
                    247: /*
                    248:  * Undefine the name in 'id'.
                    249:  */
                    250: undefine()
                    251: {
                    252:        register CPPSYM *sp;
                    253: 
                    254:        if ((sp = idp->t_sym) != NULL
                    255:         && sp->s_slevel == SL_CPP
                    256:         && sp->s_value <= XUSERA) {
                    257:                idp->t_sym = sp->s_sp;
                    258: #if ANSI_STUPID
                    259:                if (sp->s_narg > 0)
                    260:                        free(sp->s_targ);
                    261: #endif
                    262:                free(sp);
                    263:        }
                    264: }
                    265: 
                    266: /*
                    267:  * Read a constant expression in cpp.
                    268:  * As it turns out, this will accept
                    269:  * sizeof() and casts if the terms are
                    270:  * defined at the time of the reference.
                    271:  */
                    272: cppexpr()
                    273: {
                    274:        TREE *stp;
                    275:        register TREE *tp;
                    276:        register int con;
                    277: 
                    278:        ++incpp;
                    279:        stp = talloc();
                    280:        lex();
                    281:        tp = expr();
                    282:        if (tp->t_op == ICON)
                    283:                con = tp->t_ival == 0;
                    284:        else if (tp->t_op == LCON)
                    285:                con = tp->t_lval == 0;
                    286:        else if (tp->t_op == ZCON)
                    287:                con = tp->t_zval == 0;
                    288:        else
                    289:                cerror("constant expression required");
                    290:        treset(stp);
                    291:        --incpp;
                    292:        return con;
                    293: }
                    294: 
                    295: /*
                    296:  * Entry to process a control line
                    297:  * after # has been read.
                    298:  * Called from within get().
                    299:  */
                    300: control()
                    301: {
                    302:     register int c;
                    303:     register SYM *sp;
                    304:     register int true;
                    305:     register char *p;
                    306:     TOK *tp;
                    307: 
                    308:     unget(c = getnb());
                    309:     if (c < 0)
                    310:        return;
                    311:     getid('#');
                    312:     tp = idp;
                    313:     if ((sp = idp->t_sym) == NULL || sp->s_slevel != SL_CPP)
                    314:        goto bad;
                    315:     if (cstate == 0 || sp->s_value >= XIF)
                    316:        switch (sp->s_value) {
                    317: 
                    318:        case XDEFINE:
                    319:                define();
                    320:                break;
                    321: 
                    322:        case XINCLUDE:
                    323:                include();
                    324:                return;
                    325: 
                    326:        case XASSERT:
                    327:                if (cppexpr())
                    328:                        cerror("#assert failure");
                    329:                break;
                    330: 
                    331:        case XERROR:
                    332:                p = dputp;
                    333:                while ((c = get()) > 0)
                    334:                        dputc(c);
                    335:                dputc(0);
                    336:                cfatal("#error: %s", p);
                    337:                break;
                    338: 
                    339:        case XPRAGMA:
                    340:                break;
                    341: 
                    342:        case XIFDEF:
                    343:        case XIFNDEF:
                    344:                c = getnb();
                    345:                if (ct[c] != ID)
                    346:                        goto bad;
                    347:                getid(c);
                    348:                if (sp->s_value == XIFDEF)
                    349:                true = ! ((sp = idp->t_sym) != NULL && sp->s_slevel == SL_CPP);
                    350:                else
                    351:                true = ((sp = idp->t_sym) != NULL && sp->s_slevel == SL_CPP);
                    352:                goto new_if;
                    353: 
                    354:        case XIF:
                    355:                /* 0 indicates a true section */
                    356:                /* 1 indicates a false section */
                    357:                /* 2 indicates a section which was true already */
                    358:                true = cstate!=0 ? 1 : cppexpr();
                    359:        new_if:
                    360:                if (cstackp == cstack)
                    361:                        cfatal("conditional stack overflow");
                    362:                --cstackp;
                    363:                cstackp->c_op = XIF;
                    364:                cstackp->c_state = cstate;
                    365:                cstate = cstate!=0 ? 2 : true;
                    366:                break;
                    367: 
                    368:        case XELSE:
                    369:                if (cstackp == cstack+NLEV)
                    370:                        cerror("#else used without #if or #ifdef");
                    371:                else if (cstackp->c_op == XELSE)
                    372:                        cerror("multiple #else's");
                    373:                else {
                    374:                        cstackp->c_op = XELSE;
                    375:                        cstate = cstate==1 ? 0 : 2;
                    376:                }
                    377:                break;
                    378: 
                    379:        case XELIF:
                    380:                if (cstackp == cstack+NLEV)
                    381:                        cerror("#elif used without #if or #ifdef");
                    382:                else if (cstackp->c_op == XELSE)
                    383:                        cerror("#elif used after #else");
                    384:                else {
                    385:                        cstackp->c_op = XELIF;
                    386:                        cstate = cstate==1 ? cppexpr() : 2;
                    387:                }
                    388:                break;
                    389: 
                    390:        case XENDIF:
                    391:                if (cstackp == cstack+NLEV)
                    392:                        cerror("#endif used without #if or #ifdef");
                    393:                else {
                    394:                        cstate = cstackp->c_state;
                    395:                        ++cstackp;
                    396:                }
                    397:                break;
                    398: 
                    399:        case XUNDEF:
                    400:                if ((c = getnb()) < 0 || ct[c] != ID)
                    401:                        goto bad;
                    402:                getid(c);
                    403:                undefine();
                    404:                break;
                    405: 
                    406:        case XLINE:
                    407:                while ((c = getnb()) >= 0 && ct[c] == ID)
                    408:                        if ( ! expand(c))
                    409:                                goto bad;
                    410:                if (c < 0 || ct[c] != CON)
                    411:                        goto bad;
                    412:                getnum(c, 0);
                    413:                line = ival;
                    414:                c = getfname();
                    415:                dputp = dbuf;
                    416:                if (c != 0) {
                    417:                        setid(dbuf);
                    418:                        setfname();
                    419:                }
                    420:                break;
                    421: 
                    422:        default:
                    423:        bad:    cerror("illegal control line");
                    424:        }
                    425:     while ((c = get()) >= 0)   /* incpp, new line follows EOF */
                    426:        ;
                    427: }
                    428: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.