Blob


1 /* t4.c: read table specification */
2 # include "t.h"
3 int oncol;
5 void
6 getspec(void)
7 {
8 int icol, i;
10 qcol = findcol() + 1;/* must allow one extra for line at right */
11 garray(qcol);
12 sep[-1] = -1;
13 for (icol = 0; icol < qcol; icol++) {
14 sep[icol] = -1;
15 evenup[icol] = 0;
16 cll[icol][0] = 0;
17 for (i = 0; i < MAXHEAD; i++) {
18 csize[icol][i][0] = 0;
19 vsize[icol][i][0] = 0;
20 font[icol][i][0] = lefline[icol][i] = 0;
21 flags[icol][i] = 0;
22 style[icol][i] = 'l';
23 }
24 }
25 for (i = 0; i < MAXHEAD; i++)
26 lefline[qcol][i] = 0; /* fixes sample55 looping */
27 nclin = ncol = 0;
28 oncol = 0;
29 left1flg = rightl = 0;
30 readspec();
31 Bprint(&tabout, ".rm");
32 for (i = 0; i < ncol; i++)
33 Bprint(&tabout, " %2s", reg(i, CRIGHT));
34 Bprint(&tabout, "\n");
35 }
38 void
39 readspec(void)
40 {
41 int icol, c, sawchar, stopc, i;
42 char sn[10], *snp, *temp;
44 sawchar = icol = 0;
45 while (c = get1char()) {
46 switch (c) {
47 default:
48 if (c != tab) {
49 char buf[64];
50 sprint(buf, "bad table specification character %c", c);
51 error(buf);
52 }
53 case ' ': /* note this is also case tab */
54 continue;
55 case '\n':
56 if (sawchar == 0)
57 continue;
58 case ',':
59 case '.': /* end of table specification */
60 ncol = max(ncol, icol);
61 if (lefline[ncol][nclin] > 0) {
62 ncol++;
63 rightl++;
64 };
65 if (sawchar)
66 nclin++;
67 if (nclin >= MAXHEAD)
68 error("too many lines in specification");
69 icol = 0;
70 if (ncol == 0 || nclin == 0)
71 error("no specification");
72 if (c == '.') {
73 while ((c = get1char()) && c != '\n')
74 if (c != ' ' && c != '\t')
75 error("dot not last character on format line");
76 /* fix up sep - default is 3 except at edge */
77 for (icol = 0; icol < ncol; icol++)
78 if (sep[icol] < 0)
79 sep[icol] = icol + 1 < ncol ? 3 : 2;
80 if (oncol == 0)
81 oncol = ncol;
82 else if (oncol + 2 < ncol)
83 error("tried to widen table in T&, not allowed");
84 return;
85 }
86 sawchar = 0;
87 continue;
88 case 'C':
89 case 'S':
90 case 'R':
91 case 'N':
92 case 'L':
93 case 'A':
94 c += ('a' - 'A');
95 case '_':
96 if (c == '_')
97 c = '-';
98 case '=':
99 case '-':
100 case '^':
101 case 'c':
102 case 's':
103 case 'n':
104 case 'r':
105 case 'l':
106 case 'a':
107 style[icol][nclin] = c;
108 if (c == 's' && icol <= 0)
109 error("first column can not be S-type");
110 if (c == 's' && style[icol-1][nclin] == 'a') {
111 Bprint(&tabout, ".tm warning: can't span a-type cols, changed to l\n");
112 style[icol-1][nclin] = 'l';
114 if (c == 's' && style[icol-1][nclin] == 'n') {
115 Bprint(&tabout, ".tm warning: can't span n-type cols, changed to c\n");
116 style[icol-1][nclin] = 'c';
118 icol++;
119 if (c == '^' && nclin <= 0)
120 error("first row can not contain vertical span");
121 if (icol > qcol)
122 error("too many columns in table");
123 sawchar = 1;
124 continue;
125 case 'b':
126 case 'i':
127 c += 'A' - 'a';
128 case 'B':
129 case 'I':
130 if (icol == 0)
131 continue;
132 snp = font[icol-1][nclin];
133 snp[0] = (c == 'I' ? '2' : '3');
134 snp[1] = 0;
135 continue;
136 case 't':
137 case 'T':
138 if (icol > 0)
139 flags[icol-1][nclin] |= CTOP;
140 continue;
141 case 'd':
142 case 'D':
143 if (icol > 0)
144 flags[icol-1][nclin] |= CDOWN;
145 continue;
146 case 'f':
147 case 'F':
148 if (icol == 0)
149 continue;
150 snp = font[icol-1][nclin];
151 snp[0] = snp[1] = stopc = 0;
152 for (i = 0; i < 2; i++) {
153 c = get1char();
154 if (i == 0 && c == '(') {
155 stopc = ')';
156 c = get1char();
158 if (c == 0)
159 break;
160 if (c == stopc) {
161 stopc = 0;
162 break;
164 if (stopc == 0)
165 if (c == ' ' || c == tab )
166 break;
167 if (c == '\n' || c == '|') {
168 un1getc(c);
169 break;
171 snp[i] = c;
172 if (c >= '0' && c <= '9')
173 break;
175 if (stopc)
176 if (get1char() != stopc)
177 error("Nonterminated font name");
178 continue;
179 case 'P':
180 case 'p':
181 if (icol <= 0)
182 continue;
183 temp = snp = csize[icol-1][nclin];
184 while (c = get1char()) {
185 if (c == ' ' || c == tab || c == '\n')
186 break;
187 if (c == '-' || c == '+')
188 if (snp > temp)
189 break;
190 else
191 *snp++ = c;
192 else if (digit(c))
193 *snp++ = c;
194 else
195 break;
196 if (snp - temp > 4)
197 error("point size too large");
199 *snp = 0;
200 if (atoi(temp) > 36)
201 error("point size unreasonable");
202 un1getc (c);
203 continue;
204 case 'V':
205 case 'v':
206 if (icol <= 0)
207 continue;
208 temp = snp = vsize[icol-1][nclin];
209 while (c = get1char()) {
210 if (c == ' ' || c == tab || c == '\n')
211 break;
212 if (c == '-' || c == '+')
213 if (snp > temp)
214 break;
215 else
216 *snp++ = c;
217 else if (digit(c))
218 *snp++ = c;
219 else
220 break;
221 if (snp - temp > 4)
222 error("vertical spacing value too large");
224 *snp = 0;
225 un1getc(c);
226 continue;
227 case 'w':
228 case 'W':
229 snp = cll [icol-1];
230 /* Dale Smith didn't like this check - possible to have two text blocks
231 of different widths now ....
232 if (*snp)
234 Bprint(&tabout, "Ignored second width specification");
235 continue;
237 /* end commented out code ... */
238 stopc = 0;
239 while (c = get1char()) {
240 if (snp == cll[icol-1] && c == '(') {
241 stopc = ')';
242 continue;
244 if ( !stopc && (c > '9' || c < '0'))
245 break;
246 if (stopc && c == stopc)
247 break;
248 *snp++ = c;
250 *snp = 0;
251 if (snp - cll[icol-1] > CLLEN)
252 error ("column width too long");
253 if (!stopc)
254 un1getc(c);
255 continue;
256 case 'e':
257 case 'E':
258 if (icol < 1)
259 continue;
260 evenup[icol-1] = 1;
261 evenflg = 1;
262 continue;
263 case 'z':
264 case 'Z': /* zero width-ignre width this item */
265 if (icol < 1)
266 continue;
267 flags[icol-1][nclin] |= ZEROW;
268 continue;
269 case 'u':
270 case 'U': /* half line up */
271 if (icol < 1)
272 continue;
273 flags[icol-1][nclin] |= HALFUP;
274 continue;
275 case '0':
276 case '1':
277 case '2':
278 case '3':
279 case '4':
280 case '5':
281 case '6':
282 case '7':
283 case '8':
284 case '9':
285 sn[0] = c;
286 snp = sn + 1;
287 while (digit(*snp++ = c = get1char()))
289 un1getc(c);
290 sep[icol-1] = max(sep[icol-1], numb(sn));
291 continue;
292 case '|':
293 lefline[icol][nclin]++;
294 if (icol == 0)
295 left1flg = 1;
296 continue;
299 error("EOF reading table specification");
303 int
304 findcol(void)
306 # define FLNLIM 200
307 /* this counts the number of columns and then puts the line back*/
308 char *s, line[FLNLIM+2], *p;
309 int c, n = 0, inpar = 0;
311 while ((c = get1char()) != 0 && c == ' ')
313 if (c != '\n')
314 un1getc(c);
315 for (s = line; *s = c = get1char(); s++) {
316 if (c == ')')
317 inpar = 0;
318 if (inpar)
319 continue;
320 if (c == '\n' || c == 0 || c == '.' || c == ',')
321 break;
322 else if (c == '(')
323 inpar = 1;
324 else if (s >= line + FLNLIM)
325 error("too long spec line");
327 for (p = line; p < s; p++)
328 switch (*p) {
329 case 'l':
330 case 'r':
331 case 'c':
332 case 'n':
333 case 'a':
334 case 's':
335 case 'L':
336 case 'R':
337 case 'C':
338 case 'N':
339 case 'A':
340 case 'S':
341 case '-':
342 case '=':
343 case '_':
344 n++;
346 while (p >= line)
347 un1getc(*p--);
348 return(n);
352 void
353 garray(int qcol)
355 style = (int (*)[]) getcore(MAXHEAD * qcol, sizeof(int));
356 evenup = (int *) getcore(qcol, sizeof(int));
357 lefline = (int (*)[]) getcore(MAXHEAD * (qcol + 1), sizeof (int)); /*+1 for sample55 loop - others may need it too*/
358 font = (char (*)[][2]) getcore(MAXHEAD * qcol, 2);
359 csize = (char (*)[MAXHEAD][4]) getcore(MAXHEAD * qcol, 4);
360 vsize = (char (*)[MAXHEAD][4]) getcore(MAXHEAD * qcol, 4);
361 flags = (int (*)[]) getcore(MAXHEAD * qcol, sizeof(int));
362 cll = (char (*)[])getcore(qcol, CLLEN);
363 sep = (int *) getcore(qcol + 1, sizeof(int));
364 sep++; /* sep[-1] must be legal */
365 used = (int *) getcore(qcol + 1, sizeof(int));
366 lused = (int *) getcore(qcol + 1, sizeof(int));
367 rused = (int *) getcore(qcol + 1, sizeof(int));
368 doubled = (int *) getcore(qcol + 1, sizeof(int));
369 acase = (int *) getcore(qcol + 1, sizeof(int));
370 topat = (int *) getcore(qcol + 1, sizeof(int));
374 char *
375 getcore(int a, int b)
377 char *x;
378 x = calloc(a, b);
379 if (x == 0)
380 error("Couldn't get memory");
381 return(x);
385 void
386 freearr(void)
388 free(style);
389 free(evenup);
390 free(lefline);
391 free(flags);
392 free(font);
393 free(csize);
394 free(vsize);
395 free(cll);
396 free(--sep); /* netnews says this should be --sep because incremented earlier! */
397 free(used);
398 free(lused);
399 free(rused);
400 free(doubled);
401 free(acase);
402 free(topat);