Annotation of coherent/b/bin/c/n0/sharp.c, revision 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.