t4.c revision 9807e1309317ed174757f9890d2b220d4fdeb3cf
1/*
2 * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
3 * Use is subject to license terms.
4 */
5
6/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
7/*	  All Rights Reserved  	*/
8
9
10/*
11 * Copyright (c) 1980 Regents of the University of California.
12 * All rights reserved. The Berkeley software License Agreement
13 * specifies the terms and conditions for redistribution.
14 */
15
16 /* t4.c: read table specification */
17# include "t..c"
18int oncol;
19
20void	readspec(void);
21
22void
23getspec(void)
24{
25int icol, i;
26for(icol=0; icol<MAXCOL; icol++)
27	{
28	sep[icol]= -1;
29	evenup[icol]=0;
30	cll[icol][0]=0;
31	for(i=0; i<MAXHEAD; i++)
32		{
33		csize[i][icol][0]=0;
34		vsize[i][icol][0]=0;
35		font[i][icol][0] = lefline[i][icol] = 0;
36		ctop[i][icol]=0;
37		style[i][icol]= 'l';
38		}
39	}
40nclin=ncol=0;
41oncol =0;
42left1flg=rightl=0;
43readspec();
44fprintf(tabout, ".rm");
45for(i=0; i<ncol; i++)
46	fprintf(tabout, " %02d", 80+i);
47fprintf(tabout, "\n");
48}
49
50void
51readspec(void)
52{
53int icol, c, sawchar, stopc, i;
54char sn[10], *snp, *temp;
55sawchar=icol=0;
56while (c=get1char())
57	{
58	switch(c)
59		{
60		default:
61			if (c != tab)
62			error(gettext("bad table specification character"));
63			/* FALLTHROUGH */
64		case ' ': /* note this is also case tab */
65			continue;
66		case '\n':
67			if(sawchar==0) continue;
68			/* FALLTHROUGH */
69		case ',':
70		case '.': /* end of table specification */
71			ncol = max(ncol, icol);
72			if (lefline[nclin][ncol]>0) {ncol++; rightl++;};
73			if(sawchar)
74				nclin++;
75			if (nclin>=MAXHEAD)
76				error(gettext("too many lines in specification"));
77			icol=0;
78			if (ncol==0 || nclin==0)
79				error(gettext("no specification"));
80			if (c== '.')
81				{
82				while ((c=get1char()) && c != '\n')
83					if (c != ' ' && c != '\t')
84						error(gettext("dot not last character on format line"));
85				/* fix up sep - default is 3 except at edge */
86				for(icol=0; icol<ncol; icol++)
87					if (sep[icol]<0)
88						sep[icol] =  icol+1<ncol ? 3 : 1;
89				if (oncol == 0)
90					oncol = ncol;
91				else if (oncol +2 <ncol)
92					error(gettext("tried to widen table in T&, not allowed"));
93				return;
94				}
95			sawchar=0;
96			continue;
97		case 'C': case 'S': case 'R': case 'N': case 'L':  case 'A':
98			c += ('a'-'A');
99			/* FALLTHROUGH */
100		case '_': if (c=='_') c= '-';
101			/* FALLTHROUGH */
102		case '=': case '-':
103		case '^':
104		case 'c': case 's': case 'n': case 'r': case 'l':  case 'a':
105			style[nclin][icol]=c;
106			if (c== 's' && icol<=0)
107				error(gettext("first column can not be S-type"));
108			if (c=='s' && style[nclin][icol-1] == 'a')
109				{
110				fprintf(tabout, ".tm warning: can't span a-type cols, changed to l\n");
111				style[nclin][icol-1] = 'l';
112				}
113			if (c=='s' && style[nclin][icol-1] == 'n')
114				{
115				fprintf(tabout, ".tm warning: can't span n-type cols, changed to c\n");
116				style[nclin][icol-1] = 'c';
117				}
118			icol++;
119			if (c=='^' && nclin<=0)
120				error(gettext("first row can not contain vertical span"));
121			if (icol>=MAXCOL)
122				error(gettext("too many columns in table"));
123			sawchar=1;
124			continue;
125		case 'b': case 'i':
126			c += 'A'-'a';
127			/* FALLTHRU */
128		case 'B': case 'I':
129			if (sawchar == 0)
130				continue;
131			if (icol==0) continue;
132			snp=font[nclin][icol-1];
133			snp[0]= (c=='I' ? '2' : '3');
134			snp[1]=0;
135			continue;
136		case 't': case 'T':
137			if (sawchar == 0) {
138				continue;
139			}
140			if (icol>0)
141			ctop[nclin][icol-1] = 1;
142			continue;
143		case 'd': case 'D':
144			if (sawchar == 0)
145				continue;
146			if (icol>0)
147			ctop[nclin][icol-1] = -1;
148			continue;
149		case 'f': case 'F':
150			if (sawchar == 0)
151				continue;
152			if (icol==0) continue;
153			snp=font[nclin][icol-1];
154			snp[0]=snp[1]=stopc=0;
155			for(i=0; i<2; i++)
156				{
157				c = get1char();
158				if (i==0 && c=='(')
159					{
160					stopc=')';
161					c = get1char();
162					}
163				if (c==0) break;
164				if (c==stopc) {stopc=0; break;}
165				if (stopc==0)  if (c==' ' || c== tab ) break;
166				if (c=='\n'){un1getc(c); break;}
167				snp[i] = c;
168				if (c>= '0' && c<= '9') break;
169				}
170			if (stopc) if (get1char()!=stopc)
171				error(gettext("Nonterminated font name"));
172			continue;
173		case 'P': case 'p':
174			if (sawchar == 0)
175				continue;
176			if (icol<=0) continue;
177			temp = snp = csize[nclin][icol-1];
178			while (c = get1char())
179				{
180				if (c== ' ' || c== tab || c=='\n') break;
181				if (c=='-' || c == '+')
182					if (snp>temp)
183						break;
184					else
185						*snp++=c;
186				else
187				if (digit(c))
188					*snp++ = c;
189				else break;
190				if (snp-temp>4)
191					error(gettext("point size too large"));
192				}
193			*snp = 0;
194			if (atoi(temp)>36)
195				error(gettext("point size unreasonable"));
196			un1getc (c);
197			continue;
198		case 'V': case 'v':
199			if (sawchar == 0)
200				continue;
201			if (icol<=0) continue;
202			temp = snp = vsize[nclin][icol-1];
203			while (c = get1char())
204				{
205				if (c== ' ' || c== tab || c=='\n') break;
206				if (c=='-' || c == '+')
207					if (snp>temp)
208						break;
209					else
210						*snp++=c;
211				else
212				if (digit(c))
213					*snp++ = c;
214				else break;
215				if (snp-temp>4)
216					error(
217					gettext("vertical spacing value too large")
218					);
219				}
220			*snp=0;
221			un1getc(c);
222			continue;
223		case 'w': case 'W':
224			if (sawchar == 0) {
225				/*
226				 * This should be an error case.
227				 * However, for the backward-compatibility,
228				 * treat as if 'c' was specified.
229				 */
230				style[nclin][icol] = 'c';
231				icol++;
232				if (icol >= MAXCOL) {
233					error(gettext(
234						  "too many columns in table"));
235				}
236				sawchar = 1;
237			}
238
239			snp = cll [icol-1];
240		/* Dale Smith didn't like this check
241		 * possible to have two text blocks
242		 *  of different widths now ....
243			if (*snp)
244				{
245				fprintf(tabout,
246				gettext("Ignored second width specification"));
247				continue;
248				}
249		* end commented out code ... */
250			stopc=0;
251			while (c = get1char())
252				{
253				if (snp==cll[icol-1] && c=='(')
254					{
255					stopc = ')';
256					continue;
257					}
258				if ( !stopc && (c>'9' || c< '0'))
259					break;
260				if (stopc && c== stopc)
261					break;
262				*snp++ =c;
263				}
264			*snp=0;
265			if (snp-cll[icol-1]>CLLEN)
266				error (gettext("column width too long"));
267			if (!stopc)
268				un1getc(c);
269			continue;
270		case 'e': case 'E':
271			if (sawchar == 0)
272				continue;
273			if (icol<1) continue;
274			evenup[icol-1]=1;
275			evenflg=1;
276			continue;
277		case '0': case '1': case '2': case '3': case '4':
278		case '5': case '6': case '7': case '8': case '9':
279			sn[0] = c;
280			snp=sn+1;
281			while (digit(*snp++ = c = get1char()))
282				;
283			un1getc(c);
284			sep[icol-1] = max(sep[icol-1], numb(sn));
285			continue;
286		case '|':
287			lefline[nclin][icol]++;
288			if (icol==0) left1flg=1;
289			continue;
290		}
291	}
292error(gettext("EOF reading table specification"));
293}
294