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