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

1.1       root        1: /*
                      2:  * C preprocessor.
                      3:  * Read next character.
                      4:  */
                      5: #include <time.h>
                      6: #ifdef   vax
                      7: #include "INC$LIB:cc0.h"
                      8: #else
                      9: #include "cc0.h"
                     10: #endif
                     11: 
                     12: /*
                     13:  * Look ahead for '#' or '(',
                     14:  * and restore the stream if you fail.
                     15:  * This gets reentered looking for '#'
                     16:  * when the search for a '(' passes newline.
                     17:  */
                     18: skipto(d) int d;
                     19: {
                     20:        register char *p, *sp;
                     21:        register int c;
                     22:        sp = dpshp;
                     23:        while ((c = get()) >= 0 && ct[c] == SKIP)
                     24:                dpshc(c);
                     25:        if (c >= 0)
                     26:                dpshc(c);
                     27:        if (c != d) {
                     28:                for (p = dpshp; p < sp; ++p)
                     29:                        unget(*p);
                     30:                dpshp = sp;
                     31:                return 0;
                     32:        }
                     33:        dpshp = sp;
                     34:        return 1;
                     35: }
                     36: 
                     37: /*
                     38:  * Look at a newly opened file.
                     39:  */
                     40: emptyfilep()
                     41: {
                     42:        int c;
                     43:        c = getc(ifp);
                     44:        if (c == EOF) {
                     45:                c = '\n';
                     46:        }
                     47:        ungetc(c, ifp);
                     48: }
                     49: 
                     50: /*
                     51:  * Get a character.
                     52:  * This function returns the next character,
                     53:  * and implements one character pushback,
                     54:  * as well as the expanded macro stack.
                     55:  */
                     56: get()
                     57: {
                     58:     register int c;
                     59: 
                     60:     for (;;) {
                     61:        switch (dstackp->ds_type) {
                     62: 
                     63:        case DS_FUNGET: /* Ungotten character from file */
                     64:                c = (dstackp++)->ds_char & 0377;
                     65:                goto file_char;
                     66: 
                     67:        case DS_FILE:   /* Read next character from source file */
                     68:                while ((c = getc(ifp)) < 0) {           /* Pop include stack */
                     69:  eof:                  fclose(ifp);
                     70:                        if (lastchar != '\n' && lastchar != EOF)
                     71:  eof_in_line:                  cfatal("EOF in midline");
                     72:                        if (istackp < istack+NLEV) {
                     73:                                if (cstackp != istackp->i_cstackp)
                     74:                                        cerror("missing #endif");
                     75:                                cstackp = istackp->i_cstackp;
                     76:                                line = istackp->i_line;
                     77:                                if (notvariant(VCPP)) {
                     78:                                        bput(LINE);
                     79:                                        iput((ival_t)line);
                     80:                                }
                     81:                                idp = istackp->i_file;
                     82:                                setfname();
                     83:                                ifp = istackp->i_fp;
                     84:                                ++istackp;
                     85:                                continue;
                     86:                        }
                     87:                        if (cstackp < cstack+NLEV)
                     88:                                cerror("missing #endif");
                     89:                        cstackp = cstack + NLEV;
                     90:                        lastchar = c;
                     91:                        return c;                       /* ie, EOF */
                     92:                }
                     93:   file_char:   lastchar = c;
                     94:                switch (ct[c]) {
                     95: 
                     96:                case SKIP:              /* New line? */
                     97: #if GEMDOS || MSDOS                    /* Assuming use of bingetc() */
                     98:                        if (c == '\r')
                     99:                                continue;
                    100: #endif
                    101:                        if (c == '\n') {
                    102:                                if (incpp) {
                    103:                                    ungetc(c, ifp);
                    104:                                    return EOF;
                    105:                                }
                    106:                                if (instring) {
                    107:                                    cerror("new line in %s literal",
                    108:                                      instring=='"' ? "string" : "character");
                    109:                                    ++line;
                    110:                                    c = ' ';
                    111:                                } else
                    112:                                    notskip = 0;
                    113:                        }
                    114:                        notskip -= 1;
                    115:                        break;
                    116: 
                    117:                case QUEST:             /* Trigraph? */
                    118:                        if (notvariant(V3GRAPH))
                    119:                                break;
                    120:                        if ((c = getc(ifp)) < 0)
                    121:                                goto eof_in_line;
                    122:                        if (c != '?') {
                    123:                                ungetc(c, ifp);
                    124:                                c = '?';
                    125:                                break;
                    126:                        }
                    127:                        if ((c = getc(ifp)) < 0)
                    128:                                goto eof_in_line;
                    129:                        switch (c) {
                    130:                        case '=': ungetc('#', ifp); continue;
                    131:                        case '(': ungetc('[', ifp); continue;
                    132:                        case '/': ungetc('\\', ifp); continue;
                    133:                        case ')': ungetc(']', ifp); continue;
                    134:                        case '\'': ungetc('^', ifp); continue;
                    135:                        case '<': ungetc('{', ifp); continue;
                    136:                        case '!': ungetc('|', ifp); continue;
                    137:                        case '>': ungetc('}', ifp); continue;
                    138:                        case '-': ungetc('~', ifp); continue;
                    139:                        default:
                    140:                                ungetc(c, ifp);
                    141:                                dspushc(DS_FUNGET, '?');
                    142:                                c = '?';
                    143:                        }
                    144:                        break;
                    145: 
                    146:                case DIV:               /* Comment? */
                    147:                        if (instring)
                    148:                                break;
                    149:                        if ((c = getc(ifp))< 0)
                    150:                                goto eof_in_line;
                    151:                        if (c != '*') {
                    152:                                ungetc(c, ifp);
                    153:                                c = '/';
                    154:                                break;
                    155:                        }
                    156:                        for (;;) {
                    157:                                if ((c = getc(ifp)) < 0)
                    158:  eof_in_comment:                       cfatal("EOF in comment");
                    159:                                if (c == '*') {
                    160:                                        if ((c = getc(ifp)) < 0)
                    161:                                                goto eof_in_comment;
                    162:                                        if (c == '/')
                    163:                                                break;
                    164:                                        ungetc(c, ifp);
                    165:                                } else if (c == '/') {
                    166:                                        if ((c = getc(ifp)) < 0)
                    167:                                                goto eof_in_comment;
                    168:                                        if (c == '*')
                    169:                                                cwarn("nested comments");
                    170:                                        ungetc(c, ifp);
                    171:                                } else if (c == '\n')
                    172:                                        ++line;
                    173:                        }
                    174:                        c = ' ';
                    175:                        break;
                    176: 
                    177:                case BACKDIV:           /* Splice? */
                    178:  try_again:            if ((c = getc(ifp)) < 0)
                    179:                                goto eof_in_line;
                    180:                        if (c != '\n') {
                    181: #if GEMDOS || MSDOS                    /* Assuming use of bingetc() */
                    182:                                if (c == '\r')
                    183:                                        goto try_again;
                    184: #endif
                    185:                                ungetc(c, ifp);
                    186:                                c = '\\';
                    187:                                break;
                    188:                        }
                    189:                        ++line;
                    190:                        continue;
                    191: 
                    192:                case HIGH0:
                    193:                case HIGH1:
                    194:                case HIGH2:
                    195:                case HIGH3:
                    196:                case JUNK:
                    197: #if GEMDOS || MSDOS                    /* Assuming use of bingetc() */
                    198:                        if (c == 26)    /* ^Z */
                    199:                                goto eof;
                    200: #endif
                    201:                        if (instring || (c > ' ' && c < 0177))
                    202:                                break;
                    203:                        cerror("illegal cpp character (%d decimal)", c);
                    204:                        continue;
                    205: 
                    206:                case SHARP:
                    207:                        if (notskip != 0)
                    208:                                break;
                    209:                        ++incpp;
                    210:                        control();
                    211:                        --incpp;
                    212:                        continue;
                    213:                }
                    214:                notskip += 1;
                    215:                break;
                    216: 
                    217:        case DS_UNGET:  /* Read ungotten character */
                    218:                c = (dstackp++)->ds_char & 0377;
                    219:                break;
                    220: 
                    221:        case DS_STRNG:
                    222:                if ((c = *dstackp->ds_ptr++ & 0377) == 0) {
                    223:                        ++dstackp;
                    224:                        continue;
                    225:                }
                    226:                break;
                    227: 
                    228:        case DS_UFILE:  /* Convert file name into string */
                    229:                if ((c = *dstackp->ds_ptr++ & 0377) == 0) {
                    230:                        ++dstackp;
                    231:                        continue;
                    232:                }
                    233:                if (c == '\\' || c == '"') {
                    234:                        unget(c);
                    235:                        c = '\\';
                    236:                }
                    237:                break;
                    238: 
                    239:        case DS_SHARP:  /* Read and stringize */
                    240:                if ((c = *dstackp->ds_ptr++ & 0377) == 0) {
                    241:                        ++dstackp;
                    242:                        continue;
                    243:                }
                    244:                if (dstackp->ds_char) {
                    245:                        if (c == dstackp->ds_char) {
                    246:                                dstackp->ds_char = 0;
                    247:                                if (c == '"') {
                    248:                                        unget(c);
                    249:                                        c = '\\';
                    250:                                }
                    251:                        } else if (c == '\\') {
                    252:                                c = *dstackp->ds_ptr++;
                    253:                                unget(c);
                    254:                                if (c == '"')
                    255:                                        unget('\\');
                    256:                                unget('\\');
                    257:                                c = '\\';
                    258:                        }
                    259:                } else if (c == '"') {
                    260:                        dstackp->ds_char = c;
                    261:                        unget(c);
                    262:                        c = '\\';
                    263:                } else if (c == '\'')
                    264:                        dstackp->ds_char = c;
                    265:                else if (c >= SET0)
                    266:                        continue;
                    267:                break;
                    268: 
                    269:        case DS_DPUTP:
                    270:                dputp = (dstackp++)->ds_ptr;
                    271:                continue;
                    272: 
                    273:        case DS_NAME:
                    274:                ++dstackp;
                    275:                continue;
                    276: 
                    277:        case DS_IEOF:
                    278:                c = EOF;
                    279:                break;
                    280: 
                    281:        default:
                    282:                cbotch("bad ds_type %d", dstackp->ds_type);
                    283:        }
                    284:        if (c == '\n') ++line;
                    285:        if (cstate != 0 && incpp == 0)
                    286:                continue;
                    287:        return c;
                    288:     }
                    289: }
                    290: 
                    291: /*
                    292:  * One character pushback
                    293:  * for the callers of get().
                    294:  */
                    295: unget(c) int c;
                    296: {
                    297:        if (c < 0)
                    298:                return;
                    299:        dspushc(DS_UNGET, c);
                    300:        if (c == '\n')
                    301:                --line;
                    302: }
                    303: 

unix.superglobalmegacorp.com

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