Annotation of coherent/b/bin/as/getline.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Special Getline for tabbld. Keeps comments in char *comment.
                      3:  *
                      4:  * char * getline(ifp, lineno) FILE *ifp; int *lineno;
                      5:  *
                      6:  * Function to get lines from an input file.
                      7:  * Returns the address of the line, or NULL for eof.
                      8:  *
                      9:  * lineno should usually be started at 1. lineno will
                     10:  * be incremented by the number of lines in the previous call.
                     11:  * Thus lineno will be the number of the line just gotten.
                     12:  *
                     13:  * # to end of line is ignored.
                     14:  * \ whitespace through end of line is ignored.
                     15:  * \n newline
                     16:  * \p #
                     17:  * \b backspace
                     18:  * \r carrage return
                     19:  * \f form feed
                     20:  * \t tab
                     21:  * \\ backslash
                     22:  * \ddd octal number
                     23:  * all other \ sequences are errors.
                     24:  */
                     25: #include <misc.h>
                     26: 
                     27: extern char *realloc();
                     28: 
                     29: static char *line = NULL;
                     30: char *comment = NULL;
                     31: static int oldline = 0;
                     32: static int i = 0, size = 0;    /* stuff for line */
                     33: static int j = 0, csize = 0;   /* stuff for comment */
                     34: 
                     35: /*
                     36:  * Add char to line.
                     37:  */
                     38: static void
                     39: addchr(c)
                     40: {
                     41:        while (i >= size)
                     42:                if (NULL == (line = realloc(line, size += 80)))
                     43:                        fatal("Out of space");
                     44:                        /* NODOC */
                     45:        line[i++] = c;
                     46: }
                     47: 
                     48: /*
                     49:  * Add char to comment.
                     50:  */
                     51: static void
                     52: addcom(c)
                     53: {
                     54:        while (j >= csize)
                     55:                if (NULL == (comment = realloc(comment, csize += 80)))
                     56:                        fatal("Out of space");  /* NODOC */
                     57:        comment[j++] = c;
                     58: }
                     59: 
                     60: char *
                     61: getline(ifp, lineno)
                     62: FILE *ifp;
                     63: int *lineno;
                     64: {
                     65:        int c, octacc, octcnt;
                     66:        enum state { normal, incont, incomm, incommb, bsl, octdig } state;
                     67: 
                     68:        *lineno += oldline;
                     69:        for (state = normal, oldline = j = i = 0;;) {
                     70:                if (EOF == (c = fgetc(ifp))) {
                     71:                        if (i)
                     72:                                fprintf(stderr, 
                     73:                                        "line %d truncated at end\n", 
                     74:                                                *lineno + oldline);
                     75:                        return (NULL);
                     76:                }
                     77: 
                     78:                switch (state) {
                     79:                case normal:
                     80:                        switch (c) {
                     81:                        case '\\':
                     82:                                state = bsl;
                     83:                                continue;
                     84: 
                     85:                        case '#':
                     86:                                state = incomm;
                     87:                                continue;
                     88: 
                     89:                        case '\n':
                     90:                                oldline++;
                     91:                                addcom(0);
                     92:                                addchr(0);
                     93:                                return (line);
                     94:                        }
                     95: 
                     96:                        addchr(c);
                     97:                        continue;
                     98: 
                     99:                case incont:
                    100:                        if ('\n' == c) {
                    101:                                oldline++;
                    102:                                state = normal;
                    103:                        }
                    104:                        continue;
                    105: 
                    106:                case incomm:
                    107:                        switch (c) {
                    108:                        case ' ':
                    109:                        case '\t':
                    110:                                continue;
                    111:                        case '\n':
                    112:                                state = normal;
                    113:                                oldline++;
                    114:                                addchr(0);
                    115:                                addcom(0);
                    116:                                return (line);
                    117:                        }
                    118:                        state = incommb;
                    119:                        addcom(c);
                    120:                        continue;
                    121: 
                    122:                case incommb:
                    123:                        if ('\n' == c) {
                    124:                                state = normal;
                    125:                                oldline++;
                    126:                                addchr(0);
                    127:                                addcom(0);
                    128:                                return (line);
                    129:                        }
                    130:                        addcom(c);
                    131:                        continue;
                    132: 
                    133:                case bsl:
                    134:                        switch (c) {
                    135:                        case 'b':
                    136:                                c = '\b';
                    137: 
                    138:                        case '\\':
                    139:                                break;
                    140: 
                    141:                        case 'p':
                    142:                                c = '#';
                    143:                                break;
                    144: 
                    145:                        case 'f':
                    146:                                c = '\f';
                    147:                                break;
                    148: 
                    149:                        case 'a':
                    150:                                c = '\a';
                    151:                                break;
                    152: 
                    153:                        case 'r':
                    154:                                c = '\r';
                    155:                                break;
                    156: 
                    157:                        case 't':
                    158:                                c = '\t';
                    159:                                break;
                    160: 
                    161:                        case 'n':
                    162:                                c = '\n';
                    163:                                break;
                    164: 
                    165:                        case ' ':
                    166:                        case '\t':
                    167:                                state = incont;
                    168:                                continue;
                    169: 
                    170:                        case '\n':
                    171:                                oldline++;
                    172:                                state = normal;
                    173:                                continue;
                    174: 
                    175:                        default:
                    176:                                if (('0' <= c) && ('7' >= c)) {
                    177:                                        state = octdig;
                    178:                                        octcnt = 1;
                    179:                                        octacc = c - '0';
                    180:                                        continue;
                    181:                                }
                    182:                                fprintf(stderr, 
                    183:                                        "%d: '%c' 0x%2x after \\\n",
                    184:                                                *lineno + oldline, c, c);
                    185:                        }
                    186:                        state = normal;
                    187:                        addchr(c);
                    188:                        continue;
                    189: 
                    190:                case octdig:
                    191:                        if (('0' <= c) && ('7' >= c)) {
                    192:                                octacc *= 8;
                    193:                                octacc += c - '0';
                    194:                                if (3 == ++octcnt) {
                    195:                                        state = normal;
                    196:                                        addchr(octacc);
                    197:                                }
                    198:                        }
                    199:                        else {
                    200:                                ungetc(c, ifp);
                    201:                                state = normal;
                    202:                                addchr(octacc);
                    203:                        }
                    204:                        continue;
                    205:                }
                    206:        }
                    207:        
                    208: }
                    209: 
                    210: #ifdef TEST
                    211: main()
                    212: {
                    213:        int line = 1;
                    214:        char *got;
                    215: 
                    216:        for (;;) {
                    217:                if (NULL == (got = getline(stdin, &line)))
                    218:                        exit(0);
                    219: 
                    220:                if (*comment)
                    221:                        printf("%d: %s #%s\n", line, got, comment);
                    222:                else
                    223:                        printf("%d: %s\n", line, got);
                    224:        }
                    225: }
                    226: #endif

unix.superglobalmegacorp.com

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