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
gettbl(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
nodata(int il)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
oneh(int lin)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
permute(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
vspand(int ir,int ij,int ifform)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
vspen(char * s)193 vspen(char *s)
194 {
195 if (s==0) return(0);
196 if (!point(s)) return(0);
197 return(match(s, SPAN));
198 }
199