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