xref: /illumos-gate/usr/src/cmd/tbl/t5.c (revision 20a7641f9918de8574b8b3b47dbe35c4bfc78df1)
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  * Copyright (c) 1980 Regents of the University of California.
11  * All rights reserved. The Berkeley software License Agreement
12  * specifies the terms and conditions for redistribution.
13  */
14 
15  /* t5.c: read data for table */
16 # include "t..c"
17 
18 void	permute(void);
19 
20 void
21 gettbl(void)
22 {
23 int icol, ch;
24 cstore=cspace= chspace();
25 textflg=0;
26 for (nlin=nslin=0; gets1(cstore, MAXSTR); nlin++)
27 	{
28 	stynum[nlin]=nslin;
29 	if (prefix(".TE", cstore))
30 		{
31 		leftover=0;
32 		break;
33 		}
34 	if (prefix(".TC", cstore) || prefix(".T&", cstore))
35 		{
36 		readspec();
37 		nslin++;
38 		}
39 	if (nlin>=MAXLIN)
40 		{
41 		leftover=cstore;
42 		break;
43 		}
44 	fullbot[nlin]=0;
45 	if (cstore[0] == '.' && !isdigit((unsigned char)cstore[1]))
46 		{
47 		instead[nlin] = cstore;
48 		while (*cstore++);
49 		continue;
50 		}
51 	else instead[nlin] = 0;
52 	if (nodata(nlin))
53 		{
54 		if (ch = oneh(nlin))
55 			fullbot[nlin]= ch;
56 		nlin++;
57 		nslin++;
58 		instead[nlin]=(char *)0;
59 		fullbot[nlin]=0;
60 		}
61 	table[nlin] = (struct colstr *) alocv((ncol+2)*sizeof(table[0][0]));
62 	if (cstore[1]==0)
63 	switch(cstore[0])
64 		{
65 		case '_': fullbot[nlin]= '-'; continue;
66 		case '=': fullbot[nlin]= '='; continue;
67 		}
68 	stynum[nlin] = nslin;
69 	nslin = min(nslin+1, nclin-1);
70 	for (icol = 0; icol <ncol; icol++)
71 		{
72 		table[nlin][icol].col = cstore;
73 		table[nlin][icol].rcol=0;
74 		ch=1;
75 		if (match(cstore, "T{")) /* text follows */
76 			/* get_text was originally gettext and was renamed */
77 			table[nlin][icol].col =
78 				(char *)get_text(cstore, nlin, icol,
79 					font[stynum[nlin]][icol],
80 					csize[stynum[nlin]][icol]);
81 		else
82 			{
83 			for(; (ch= *cstore) != '\0' && ch != tab; cstore++)
84 					;
85 			*cstore++ = '\0';
86 			switch(ctype(nlin,icol)) /* numerical or alpha, subcol */
87 				{
88 				case 'n':
89 					table[nlin][icol].rcol =
90 					    (char *)maknew(table[nlin][icol].col);
91 					break;
92 				case 'a':
93 					table[nlin][icol].rcol = table[nlin][icol].col;
94 					table[nlin][icol].col = "";
95 					break;
96 				}
97 			}
98 		while (ctype(nlin,icol+1)== 's') /* spanning */
99 			table[nlin][++icol].col = "";
100 		if (ch == '\0') break;
101 		}
102 	while (++icol <ncol+2)
103 		{
104 		table[nlin][icol].col = "";
105 		table [nlin][icol].rcol=0;
106 		}
107 	while (*cstore != '\0')
108 		 cstore++;
109 	if (cstore-cspace > MAXCHS)
110 		cstore = cspace = chspace();
111 	}
112 last = cstore;
113 permute();
114 if (textflg) untext();
115 return;
116 }
117 
118 int
119 nodata(int il)
120 {
121 int c;
122 for (c=0; c<ncol;c++)
123 	{
124 	switch(ctype(il,c))
125 		{
126 		case 'c': case 'n': case 'r': case 'l': case 's': case 'a':
127 			return(0);
128 		}
129 	}
130 return(1);
131 }
132 
133 int
134 oneh(int lin)
135 {
136 int k, icol;
137 k = ctype(lin,0);
138 for(icol=1; icol<ncol; icol++)
139 	{
140 	if (k != ctype(lin,icol))
141 		return(0);
142 	}
143 return(k);
144 }
145 
146 # define SPAN "\\^"
147 
148 void
149 permute(void)
150 {
151 int irow, jcol, is;
152 char *start, *strig;
153 for(jcol=0; jcol<ncol; jcol++)
154 	{
155 	for(irow=1; irow<nlin; irow++)
156 		{
157 		if (vspand(irow,jcol,0))
158 			{
159 			is = prev(irow);
160 			if (is<0)
161 				error(gettext("Vertical spanning in first row not allowed"));
162 			start = table[is][jcol].col;
163 			strig = table[is][jcol].rcol;
164 			while (irow<nlin &&vspand(irow,jcol,0))
165 				irow++;
166 			table[--irow][jcol].col = start;
167 			table[irow][jcol].rcol = strig;
168 			while (is<irow)
169 				{
170 				table[is][jcol].rcol =0;
171 				table[is][jcol].col= SPAN;
172 				is = next(is);
173 				}
174 			}
175 		}
176 	}
177 }
178 
179 int
180 vspand(int ir, int ij, int ifform)
181 {
182 if (ir<0) return(0);
183 if (ir>=nlin)return(0);
184 if (instead[ir]) return(0);
185 if (ifform==0 && ctype(ir,ij)=='^') return(1);
186 if (table[ir]==0) return(0);
187 if (table[ir][ij].rcol!=0) return(0);
188 if (fullbot[ir]) return(0);
189 return(vspen(table[ir][ij].col));
190 }
191 
192 int
193 vspen(char *s)
194 {
195 if (s==0) return(0);
196 if (!point(s)) return(0);
197 return(match(s, SPAN));
198 }
199