|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.