|  | /* t5.c: read data for table */ | 
|  | # include "t.h" | 
|  |  | 
|  | void | 
|  | gettbl(void) | 
|  | { | 
|  | int	icol, ch; | 
|  |  | 
|  | cstore = cspace = chspace(); | 
|  | textflg = 0; | 
|  | for (nlin = nslin = 0; gets1(cstore, MAXCHS - (cstore - cspace)); nlin++) { | 
|  | stynum[nlin] = nslin; | 
|  | if (prefix(".TE", cstore)) { | 
|  | leftover = 0; | 
|  | break; | 
|  | } | 
|  | if (prefix(".TC", cstore) || prefix(".T&", cstore)) { | 
|  | readspec(); | 
|  | nslin++; | 
|  | } | 
|  | if (nlin >= MAXLIN) { | 
|  | leftover = cstore; | 
|  | break; | 
|  | } | 
|  | fullbot[nlin] = 0; | 
|  | if (cstore[0] == '.' && !isdigit((uchar)cstore[1])) { | 
|  | instead[nlin] = cstore; | 
|  | while (*cstore++) | 
|  | ; | 
|  | continue; | 
|  | } else | 
|  | instead[nlin] = 0; | 
|  | if (nodata(nlin)) { | 
|  | if (ch = oneh(nlin)) | 
|  | fullbot[nlin] = ch; | 
|  | table[nlin] = (struct colstr *) alocv((ncol + 2) * sizeof(table[0][0])); | 
|  | for (icol = 0; icol < ncol; icol++) { | 
|  | table[nlin][icol].rcol = ""; | 
|  | table[nlin][icol].col = ""; | 
|  | } | 
|  | nlin++; | 
|  | nslin++; | 
|  | fullbot[nlin] = 0; | 
|  | instead[nlin] = (char *) 0; | 
|  | } | 
|  | table[nlin] = (struct colstr *) alocv((ncol + 2) * sizeof(table[0][0])); | 
|  | if (cstore[1] == 0) | 
|  | switch (cstore[0]) { | 
|  | case '_': | 
|  | fullbot[nlin] = '-'; | 
|  | continue; | 
|  | case '=': | 
|  | fullbot[nlin] = '='; | 
|  | continue; | 
|  | } | 
|  | stynum[nlin] = nslin; | 
|  | nslin = min(nslin + 1, nclin - 1); | 
|  | for (icol = 0; icol < ncol; icol++) { | 
|  | table[nlin][icol].col = cstore; | 
|  | table[nlin][icol].rcol = 0; | 
|  | ch = 1; | 
|  | if (match(cstore, "T{")) { /* text follows */ | 
|  | table[nlin][icol].col = | 
|  | (char *)(uintptr)gettext(cstore, nlin, icol, | 
|  | font[icol][stynum[nlin]], | 
|  | csize[icol][stynum[nlin]]); | 
|  | } else | 
|  | { | 
|  | for (; (ch = *cstore) != '\0' && ch != tab; cstore++) | 
|  | ; | 
|  | *cstore++ = '\0'; | 
|  | switch (ctype(nlin, icol)) /* numerical or alpha, subcol */ { | 
|  | case 'n': | 
|  | table[nlin][icol].rcol = maknew(table[nlin][icol].col); | 
|  | break; | 
|  | case 'a': | 
|  | table[nlin][icol].rcol = table[nlin][icol].col; | 
|  | table[nlin][icol].col = ""; | 
|  | break; | 
|  | } | 
|  | } | 
|  | while (ctype(nlin, icol + 1) == 's') /* spanning */ | 
|  | table[nlin][++icol].col = ""; | 
|  | if (ch == '\0') | 
|  | break; | 
|  | } | 
|  | while (++icol < ncol + 2) { | 
|  | table[nlin][icol].col = ""; | 
|  | table [nlin][icol].rcol = 0; | 
|  | } | 
|  | while (*cstore != '\0') | 
|  | cstore++; | 
|  | if (cstore - cspace + MAXLINLEN > MAXCHS) | 
|  | cstore = cspace = chspace(); | 
|  | } | 
|  | last = cstore; | 
|  | permute(); | 
|  | if (textflg) | 
|  | untext(); | 
|  | return; | 
|  | } | 
|  |  | 
|  |  | 
|  | int | 
|  | nodata(int il) | 
|  | { | 
|  | int	c; | 
|  |  | 
|  | for (c = 0; c < ncol; c++) { | 
|  | switch (ctype(il, c)) { | 
|  | case 'c': | 
|  | case 'n': | 
|  | case 'r': | 
|  | case 'l': | 
|  | case 's': | 
|  | case 'a': | 
|  | return(0); | 
|  | } | 
|  | } | 
|  | return(1); | 
|  | } | 
|  |  | 
|  |  | 
|  | int | 
|  | oneh(int lin) | 
|  | { | 
|  | int	k, icol; | 
|  |  | 
|  | k = ctype(lin, 0); | 
|  | for (icol = 1; icol < ncol; icol++) { | 
|  | if (k != ctype(lin, icol)) | 
|  | return(0); | 
|  | } | 
|  | return(k); | 
|  | } | 
|  |  | 
|  |  | 
|  | # define SPAN "\\^" | 
|  |  | 
|  | void | 
|  | permute(void) | 
|  | { | 
|  | int	irow, jcol, is; | 
|  | char	*start, *strig; | 
|  |  | 
|  | for (jcol = 0; jcol < ncol; jcol++) { | 
|  | for (irow = 1; irow < nlin; irow++) { | 
|  | if (vspand(irow, jcol, 0)) { | 
|  | is = prev(irow); | 
|  | if (is < 0) | 
|  | error("Vertical spanning in first row not allowed"); | 
|  | start = table[is][jcol].col; | 
|  | strig = table[is][jcol].rcol; | 
|  | while (irow < nlin && vspand(irow, jcol, 0)) | 
|  | irow++; | 
|  | table[--irow][jcol].col = start; | 
|  | table[irow][jcol].rcol = strig; | 
|  | while (is < irow) { | 
|  | table[is][jcol].rcol = 0; | 
|  | table[is][jcol].col = SPAN; | 
|  | is = next(is); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  |  | 
|  | int | 
|  | vspand(int ir, int ij, int ifform) | 
|  | { | 
|  | if (ir < 0) | 
|  | return(0); | 
|  | if (ir >= nlin) | 
|  | return(0); | 
|  | if (instead[ir]) | 
|  | return(0); | 
|  | if (ifform == 0 && ctype(ir, ij) == '^') | 
|  | return(1); | 
|  | if (table[ir][ij].rcol != 0) | 
|  | return(0); | 
|  | if (fullbot[ir]) | 
|  | return(0); | 
|  | return(vspen(table[ir][ij].col)); | 
|  | } | 
|  |  | 
|  |  | 
|  | int | 
|  | vspen(char *s) | 
|  | { | 
|  | if (s == 0) | 
|  | return(0); | 
|  | if (!point(s)) | 
|  | return(0); | 
|  | return(match(s, SPAN)); | 
|  | } | 
|  |  | 
|  |  |