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

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

unix.superglobalmegacorp.com

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