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