plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

t5.c (3717B)


      1 /* t5.c: read data for table */
      2 # include "t.h"
      3 
      4 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((uchar)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 *)(uintptr)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 	return;
    101 }
    102 
    103 
    104 int
    105 nodata(int il)
    106 {
    107 	int	c;
    108 
    109 	for (c = 0; c < ncol; c++) {
    110 		switch (ctype(il, c)) {
    111 		case 'c':
    112 		case 'n':
    113 		case 'r':
    114 		case 'l':
    115 		case 's':
    116 		case 'a':
    117 			return(0);
    118 		}
    119 	}
    120 	return(1);
    121 }
    122 
    123 
    124 int
    125 oneh(int lin)
    126 {
    127 	int	k, icol;
    128 
    129 	k = ctype(lin, 0);
    130 	for (icol = 1; icol < ncol; icol++) {
    131 		if (k != ctype(lin, icol))
    132 			return(0);
    133 	}
    134 	return(k);
    135 }
    136 
    137 
    138 # define SPAN "\\^"
    139 
    140 void
    141 permute(void)
    142 {
    143 	int	irow, jcol, is;
    144 	char	*start, *strig;
    145 
    146 	for (jcol = 0; jcol < ncol; jcol++) {
    147 		for (irow = 1; irow < nlin; irow++) {
    148 			if (vspand(irow, jcol, 0)) {
    149 				is = prev(irow);
    150 				if (is < 0)
    151 					error("Vertical spanning in first row not allowed");
    152 				start = table[is][jcol].col;
    153 				strig = table[is][jcol].rcol;
    154 				while (irow < nlin && vspand(irow, jcol, 0))
    155 					irow++;
    156 				table[--irow][jcol].col = start;
    157 				table[irow][jcol].rcol = strig;
    158 				while (is < irow) {
    159 					table[is][jcol].rcol = 0;
    160 					table[is][jcol].col = SPAN;
    161 					is = next(is);
    162 				}
    163 			}
    164 		}
    165 	}
    166 }
    167 
    168 
    169 int
    170 vspand(int ir, int ij, int ifform)
    171 {
    172 	if (ir < 0)
    173 		return(0);
    174 	if (ir >= nlin)
    175 		return(0);
    176 	if (instead[ir])
    177 		return(0);
    178 	if (ifform == 0 && ctype(ir, ij) == '^')
    179 		return(1);
    180 	if (table[ir][ij].rcol != 0)
    181 		return(0);
    182 	if (fullbot[ir])
    183 		return(0);
    184 	return(vspen(table[ir][ij].col));
    185 }
    186 
    187 
    188 int
    189 vspen(char *s)
    190 {
    191 	if (s == 0)
    192 		return(0);
    193 	if (!point(s))
    194 		return(0);
    195 	return(match(s, SPAN));
    196 }