1 #ifndef lint 2 static char sccsid[] = "@(#)rdata.c 1.3 (CWI) 93/07/27"; 3 #endif lint 4 5 6 /* 7 * read data for table 8 */ 9 10 #include "defs.h" 11 #include "ext.h" 12 #include <signal.h> 13 14 gettbl(){ 15 int icol, ch; 16 extern interr(); 17 extern char *chspace(); 18 extern char *maknew(); 19 extern int *alocv(); 20 extern char *gettext(); 21 sig_t savsign; 22 23 cstore = cspace = chspace(); 24 textflg = 0; 25 for(nlin = nslin = 0; gets1(cstore); nlin++){ 26 stynum[nlin] = nslin; 27 if(prefix(".TE", cstore)){ 28 leftover = 0; 29 break; 30 } 31 if(prefix(".TC", cstore) || prefix(".T&", cstore)){ 32 readspec(); 33 nslin++; 34 } 35 if(nlin >= MAXLIN){ 36 leftover = (int)cstore; 37 break; 38 } 39 fullbot[nlin] = 0; 40 if(cstore[0] == '.' && !isdigit(cstore[1])){ 41 instead[nlin] = cstore; 42 while(*cstore++) 43 ; 44 continue; 45 } else 46 instead[nlin] = 0; 47 if(nodata(nlin)){ 48 if(ch = oneh(nlin)) 49 fullbot[nlin] = ch; 50 #ifdef FIX 51 This FIX didn't work, so commented out for the time being, 52 problem temporarily solved with signal catching... 53 dprint(".\\\" FIX nlin = %d\n", nlin); 54 dprint(".\\\" FIXgettbl: alocv %d\n", (ncol + 2) * sizeof(table[0][0])); 55 /* 56 * start of FIX? 57 * 58 * Need to allocate pointers as well, in case 59 * of vertical spanning. 60 * I hope this works 61 */ 62 table[nlin] = (struct colstr *) alocv((ncol + 2) * 63 sizeof(*table[0])); 64 /* 65 * Does alocv clears the pointers? 66 */ 67 { int tmp; 68 for( tmp = 0; tmp < ncol +2; tmp++) { 69 table[nlin][tmp].col = ""; 70 table[nlin][tmp].rcol = (char*)0; 71 printf(".\\\"FIX table[%d][%d].col: <%s>\n", nlin, tmp, table[nlin][tmp].col); 72 printf(".\\\"FIX table[%d][%d].rcol: <%s>\n", nlin, tmp, table[nlin][tmp].rcol); 73 } 74 } 75 /* 76 * End of FIX 77 */ 78 #endif FIX 79 nlin++; 80 nslin++; 81 instead[nlin] = (char *) 0; 82 fullbot[nlin] = 0; 83 dprint(".\\\" gettbl continue, due to nodata\n"); 84 } 85 table[nlin] = (struct colstr *) alocv((ncol + 2) * 86 sizeof(*table[0])); 87 if(cstore[1] == 0) { 88 switch(cstore[0]){ 89 90 case '_': 91 fullbot[nlin] = '-'; 92 continue; 93 case '=': 94 fullbot[nlin] = '='; 95 continue; 96 } 97 } 98 stynum[nlin] = nslin; 99 nslin = min(nslin + 1, nclin - 1); 100 for(icol = 0; icol < ncol; icol++){ 101 table[nlin][icol].col = cstore; 102 table[nlin][icol].rcol = (char*)0; 103 ch = 1; 104 if(strcmp(cstore, "T{") == 0) { 105 /* 106 * text follows 107 */ 108 table[nlin][icol].col = 109 gettext(cstore, nlin, icol, 110 font[stynum[nlin]][icol], 111 csize[stynum[nlin]][icol]); 112 } else { 113 for(; (ch = *cstore) != '\0' && ch != tab; cstore++) 114 ; 115 *cstore++ = '\0'; 116 switch(ctype(nlin, icol)){ 117 /* 118 * numerical or alpha, subcol 119 */ 120 case 'n': 121 table[nlin][icol].rcol = maknew(table[nlin][icol].col); 122 break; 123 case 'a': 124 table[nlin][icol].rcol = table[nlin][icol].col; 125 table[nlin][icol].col = ""; 126 break; 127 } 128 } 129 while(ctype(nlin, icol + 1) == 's'){ 130 /* 131 * spanning 132 */ 133 table[nlin][++icol].col = ""; 134 } 135 if(ch == '\0') 136 break; 137 } 138 while(++icol < ncol + 2){ 139 table[nlin][icol].col = ""; 140 table[nlin][icol].rcol = (char*)0; 141 } 142 while(*cstore != '\0') 143 cstore++; 144 if(cstore - cspace > MAXCHS) 145 cstore = cspace = chspace(); 146 } 147 last = cstore; 148 /* 149 * the next example is weird & legal tbl input. 150 * however, it generates a bus error. 151 .TS 152 linesize(24) tab(@); 153 ct| c cf3 154 ^ | _ _ 155 ^ | cf3 cf3 156 ^ | c s. 157 0,0@0,1@0,2 158 @1,1@1,2 159 @2,1@2,2 160 .TE 161 * This works: 162 .TS 163 linesize(24) tab(@); 164 ct| c cf3 165 ^ | cf3 cf3 166 ^ | c s. 167 0,0@0,1@0,2 168 @1,1@1,2 169 @2,1@2,2 170 .TE 171 * So it is the vertical spanning of an empty column which 172 * cuases problems 173 */ 174 savsign = signal(SIGBUS, interr); 175 permute(); 176 signal(SIGBUS, savsign); 177 if(textflg) 178 untext(); 179 return; 180 } 181 182 /* 183 * return 1 if no type of column specified for this line 184 */ 185 nodata(il){ 186 int c; 187 188 for(c = 0; c < ncol; c++){ 189 switch(ctype(il, c)){ 190 191 case 'c': 192 case 'n': 193 case 'r': 194 case 'l': 195 case 's': 196 case 'a': 197 return(0); 198 } 199 } 200 return(1); 201 } 202 203 /* 204 * returns the type of heading if they are all the same for the table 205 * line? 206 */ 207 oneh(lin){ 208 int k, icol; 209 210 k = ctype(lin, 0); 211 for(icol = 1; icol < ncol; icol++){ 212 if(k != ctype(lin, icol)) 213 return(0); 214 } 215 return(k); 216 } 217 218 #define SPAN "\\^" 219 220 permute(){ 221 register int irow, jcol, is; 222 char *start, *strig; 223 224 for(jcol = 0; jcol < ncol; jcol++){ 225 for(irow = 1; irow < nlin; irow++){ 226 if(vspand(irow, jcol, 0)){ 227 is = prev(irow); 228 if(is < 0) 229 error("Vertical spanning in first row not allowed"); 230 start = table[is][jcol].col; 231 strig = table[is][jcol].rcol; 232 while(irow < nlin && vspand(irow, jcol, 0)){ 233 irow++; 234 } 235 table[--irow][jcol].col = start; 236 table[irow][jcol].rcol = strig; 237 while(is < irow){ 238 table[is][jcol].col = SPAN; 239 table[is][jcol].rcol = (char*)0; 240 is = next(is); 241 } 242 } 243 } 244 } 245 } 246 247 /* 248 * return 1 if vertical spanning is row ir, column ij, from position ifrom 249 */ 250 vspand(ir, ij, ifform) 251 { 252 if(ir < 0) 253 return(0); 254 if(ir >= nlin) 255 return(0); 256 if(instead[ir]) 257 return(0); 258 if(ifform == 0 && ctype(ir, ij) == '^'){ 259 return(1); 260 } 261 if(table[ir][ij].rcol != (char*)0) 262 return(0); 263 if(fullbot[ir]) 264 return(0); 265 return(vspen(table[ir][ij].col)); 266 } 267 268 /* 269 * return 1 if the string is the same as SPAN 270 */ 271 vspen(s) 272 char *s; 273 { 274 if(s == 0) 275 return(0); 276 if(!point(s)) 277 return(0); 278 return(strcmp(s, SPAN) == 0); 279 } 280 281 static 282 interr() 283 { 284 error("internal tbl error -- function: permute"); 285 } 286