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