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