125073Sjaap #ifndef lint
2*64045Sbostic static char sccsid[] = "@(#)rdata.c 1.3 (CWI) 93/07/27";
325073Sjaap #endif lint
425073Sjaap
525073Sjaap
625091Sjaap /*
725091Sjaap * read data for table
825091Sjaap */
925073Sjaap
1025073Sjaap #include "defs.h"
1125073Sjaap #include "ext.h"
1225073Sjaap #include <signal.h>
1325073Sjaap
gettbl()1425073Sjaap gettbl(){
1525073Sjaap int icol, ch;
1625073Sjaap extern interr();
1725073Sjaap extern char *chspace();
1825073Sjaap extern char *maknew();
1925073Sjaap extern int *alocv();
2025073Sjaap extern char *gettext();
21*64045Sbostic sig_t savsign;
2225073Sjaap
2325073Sjaap cstore = cspace = chspace();
2425073Sjaap textflg = 0;
2525073Sjaap for(nlin = nslin = 0; gets1(cstore); nlin++){
2625073Sjaap stynum[nlin] = nslin;
2725073Sjaap if(prefix(".TE", cstore)){
2825073Sjaap leftover = 0;
2925073Sjaap break;
3025073Sjaap }
3125073Sjaap if(prefix(".TC", cstore) || prefix(".T&", cstore)){
3225073Sjaap readspec();
3325073Sjaap nslin++;
3425073Sjaap }
3525073Sjaap if(nlin >= MAXLIN){
3625073Sjaap leftover = (int)cstore;
3725073Sjaap break;
3825073Sjaap }
3925073Sjaap fullbot[nlin] = 0;
4025073Sjaap if(cstore[0] == '.' && !isdigit(cstore[1])){
4125073Sjaap instead[nlin] = cstore;
4225073Sjaap while(*cstore++)
4325073Sjaap ;
4425073Sjaap continue;
4525073Sjaap } else
4625073Sjaap instead[nlin] = 0;
4725073Sjaap if(nodata(nlin)){
4825073Sjaap if(ch = oneh(nlin))
4925073Sjaap fullbot[nlin] = ch;
5025073Sjaap #ifdef FIX
5125073Sjaap This FIX didn't work, so commented out for the time being,
5225073Sjaap problem temporarily solved with signal catching...
5325091Sjaap dprint(".\\\" FIX nlin = %d\n", nlin);
5425091Sjaap dprint(".\\\" FIXgettbl: alocv %d\n", (ncol + 2) * sizeof(table[0][0]));
5525073Sjaap /*
5625073Sjaap * start of FIX?
5725073Sjaap *
5825073Sjaap * Need to allocate pointers as well, in case
5925073Sjaap * of vertical spanning.
6025073Sjaap * I hope this works
6125073Sjaap */
6225073Sjaap table[nlin] = (struct colstr *) alocv((ncol + 2) *
6325073Sjaap sizeof(*table[0]));
6425073Sjaap /*
6525073Sjaap * Does alocv clears the pointers?
6625073Sjaap */
6725073Sjaap { int tmp;
6825073Sjaap for( tmp = 0; tmp < ncol +2; tmp++) {
6925073Sjaap table[nlin][tmp].col = "";
7025073Sjaap table[nlin][tmp].rcol = (char*)0;
7125073Sjaap printf(".\\\"FIX table[%d][%d].col: <%s>\n", nlin, tmp, table[nlin][tmp].col);
7225073Sjaap printf(".\\\"FIX table[%d][%d].rcol: <%s>\n", nlin, tmp, table[nlin][tmp].rcol);
7325073Sjaap }
7425073Sjaap }
7525073Sjaap /*
7625073Sjaap * End of FIX
7725073Sjaap */
7825073Sjaap #endif FIX
7925073Sjaap nlin++;
8025073Sjaap nslin++;
8125073Sjaap instead[nlin] = (char *) 0;
8225073Sjaap fullbot[nlin] = 0;
8325091Sjaap dprint(".\\\" gettbl continue, due to nodata\n");
8425073Sjaap }
8525073Sjaap table[nlin] = (struct colstr *) alocv((ncol + 2) *
8625073Sjaap sizeof(*table[0]));
8725073Sjaap if(cstore[1] == 0) {
8825073Sjaap switch(cstore[0]){
8925073Sjaap
9025073Sjaap case '_':
9125073Sjaap fullbot[nlin] = '-';
9225073Sjaap continue;
9325073Sjaap case '=':
9425073Sjaap fullbot[nlin] = '=';
9525073Sjaap continue;
9625073Sjaap }
9725073Sjaap }
9825073Sjaap stynum[nlin] = nslin;
9925073Sjaap nslin = min(nslin + 1, nclin - 1);
10025073Sjaap for(icol = 0; icol < ncol; icol++){
10125073Sjaap table[nlin][icol].col = cstore;
10225073Sjaap table[nlin][icol].rcol = (char*)0;
10325073Sjaap ch = 1;
10425073Sjaap if(strcmp(cstore, "T{") == 0) {
10525073Sjaap /*
10625073Sjaap * text follows
10725073Sjaap */
10825073Sjaap table[nlin][icol].col =
10925073Sjaap gettext(cstore, nlin, icol,
11025073Sjaap font[stynum[nlin]][icol],
11125073Sjaap csize[stynum[nlin]][icol]);
11225073Sjaap } else {
11325073Sjaap for(; (ch = *cstore) != '\0' && ch != tab; cstore++)
11425073Sjaap ;
11525073Sjaap *cstore++ = '\0';
11625073Sjaap switch(ctype(nlin, icol)){
11725073Sjaap /*
11825073Sjaap * numerical or alpha, subcol
11925073Sjaap */
12025073Sjaap case 'n':
12125073Sjaap table[nlin][icol].rcol = maknew(table[nlin][icol].col);
12225073Sjaap break;
12325073Sjaap case 'a':
12425073Sjaap table[nlin][icol].rcol = table[nlin][icol].col;
12525073Sjaap table[nlin][icol].col = "";
12625073Sjaap break;
12725073Sjaap }
12825073Sjaap }
12925073Sjaap while(ctype(nlin, icol + 1) == 's'){
13025073Sjaap /*
13125073Sjaap * spanning
13225073Sjaap */
13325073Sjaap table[nlin][++icol].col = "";
13425073Sjaap }
13525073Sjaap if(ch == '\0')
13625073Sjaap break;
13725073Sjaap }
13825073Sjaap while(++icol < ncol + 2){
13925073Sjaap table[nlin][icol].col = "";
14025073Sjaap table[nlin][icol].rcol = (char*)0;
14125073Sjaap }
14225073Sjaap while(*cstore != '\0')
14325073Sjaap cstore++;
14425073Sjaap if(cstore - cspace > MAXCHS)
14525073Sjaap cstore = cspace = chspace();
14625073Sjaap }
14725073Sjaap last = cstore;
14825091Sjaap /*
14925091Sjaap * the next example is weird & legal tbl input.
15025091Sjaap * however, it generates a bus error.
15125091Sjaap .TS
15225091Sjaap linesize(24) tab(@);
15325091Sjaap ct| c cf3
15425091Sjaap ^ | _ _
15525091Sjaap ^ | cf3 cf3
15625091Sjaap ^ | c s.
15725091Sjaap 0,0@0,1@0,2
15825091Sjaap @1,1@1,2
15925091Sjaap @2,1@2,2
16025091Sjaap .TE
16125091Sjaap * This works:
16225091Sjaap .TS
16325091Sjaap linesize(24) tab(@);
16425091Sjaap ct| c cf3
16525091Sjaap ^ | cf3 cf3
16625091Sjaap ^ | c s.
16725091Sjaap 0,0@0,1@0,2
16825091Sjaap @1,1@1,2
16925091Sjaap @2,1@2,2
17025091Sjaap .TE
17125091Sjaap * So it is the vertical spanning of an empty column which
17225091Sjaap * cuases problems
17325091Sjaap */
17425073Sjaap savsign = signal(SIGBUS, interr);
17525073Sjaap permute();
17625073Sjaap signal(SIGBUS, savsign);
17725073Sjaap if(textflg)
17825073Sjaap untext();
17925073Sjaap return;
18025073Sjaap }
18125073Sjaap
18225073Sjaap /*
18325073Sjaap * return 1 if no type of column specified for this line
18425073Sjaap */
18525073Sjaap nodata(il){
18625073Sjaap int c;
18725073Sjaap
18825073Sjaap for(c = 0; c < ncol; c++){
18925073Sjaap switch(ctype(il, c)){
19025073Sjaap
19125073Sjaap case 'c':
19225073Sjaap case 'n':
19325073Sjaap case 'r':
19425073Sjaap case 'l':
19525073Sjaap case 's':
19625073Sjaap case 'a':
19725073Sjaap return(0);
19825073Sjaap }
19925073Sjaap }
20025073Sjaap return(1);
20125073Sjaap }
20225073Sjaap
20325073Sjaap /*
20425073Sjaap * returns the type of heading if they are all the same for the table
20525073Sjaap * line?
20625073Sjaap */
20725073Sjaap oneh(lin){
20825073Sjaap int k, icol;
20925073Sjaap
21025073Sjaap k = ctype(lin, 0);
21125073Sjaap for(icol = 1; icol < ncol; icol++){
21225073Sjaap if(k != ctype(lin, icol))
21325073Sjaap return(0);
21425073Sjaap }
21525073Sjaap return(k);
21625073Sjaap }
21725073Sjaap
21825073Sjaap #define SPAN "\\^"
21925073Sjaap
22025073Sjaap permute(){
22125073Sjaap register int irow, jcol, is;
22225073Sjaap char *start, *strig;
22325073Sjaap
22425073Sjaap for(jcol = 0; jcol < ncol; jcol++){
22525073Sjaap for(irow = 1; irow < nlin; irow++){
22625073Sjaap if(vspand(irow, jcol, 0)){
22725073Sjaap is = prev(irow);
22825073Sjaap if(is < 0)
22925073Sjaap error("Vertical spanning in first row not allowed");
23025073Sjaap start = table[is][jcol].col;
23125073Sjaap strig = table[is][jcol].rcol;
23225073Sjaap while(irow < nlin && vspand(irow, jcol, 0)){
23325073Sjaap irow++;
23425073Sjaap }
23525073Sjaap table[--irow][jcol].col = start;
23625073Sjaap table[irow][jcol].rcol = strig;
23725073Sjaap while(is < irow){
23825073Sjaap table[is][jcol].col = SPAN;
23925073Sjaap table[is][jcol].rcol = (char*)0;
24025073Sjaap is = next(is);
24125073Sjaap }
24225073Sjaap }
24325073Sjaap }
24425073Sjaap }
24525073Sjaap }
24625073Sjaap
24725073Sjaap /*
24825073Sjaap * return 1 if vertical spanning is row ir, column ij, from position ifrom
24925073Sjaap */
25025073Sjaap vspand(ir, ij, ifform)
25125073Sjaap {
25225073Sjaap if(ir < 0)
25325073Sjaap return(0);
25425073Sjaap if(ir >= nlin)
25525073Sjaap return(0);
25625073Sjaap if(instead[ir])
25725073Sjaap return(0);
25825073Sjaap if(ifform == 0 && ctype(ir, ij) == '^'){
25925073Sjaap return(1);
26025073Sjaap }
26125073Sjaap if(table[ir][ij].rcol != (char*)0)
26225073Sjaap return(0);
26325073Sjaap if(fullbot[ir])
26425073Sjaap return(0);
26525073Sjaap return(vspen(table[ir][ij].col));
26625073Sjaap }
26725073Sjaap
26825073Sjaap /*
26925073Sjaap * return 1 if the string is the same as SPAN
27025073Sjaap */
27125073Sjaap vspen(s)
27225073Sjaap char *s;
27325073Sjaap {
27425073Sjaap if(s == 0)
27525073Sjaap return(0);
27625073Sjaap if(!point(s))
27725073Sjaap return(0);
27825073Sjaap return(strcmp(s, SPAN) == 0);
27925073Sjaap }
28025073Sjaap
28125073Sjaap static
28225073Sjaap interr()
28325073Sjaap {
28425073Sjaap error("internal tbl error -- function: permute");
28525073Sjaap }
286