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

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

unix.superglobalmegacorp.com

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