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