diff options
author | rsc <devnull@localhost> | 2004-05-15 23:24:00 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2004-05-15 23:24:00 +0000 |
commit | 5cedca1b69d020c32466f70843a11767773d7e3b (patch) | |
tree | a15a3d84e92aa262543b0010763a5e6920c9ba24 /src/cmd/tbl | |
parent | 76e6aca867e3e48ea04fbcf7284c45369a69829e (diff) | |
download | plan9port-5cedca1b69d020c32466f70843a11767773d7e3b.tar.gz plan9port-5cedca1b69d020c32466f70843a11767773d7e3b.tar.bz2 plan9port-5cedca1b69d020c32466f70843a11767773d7e3b.zip |
Let's try this. It's BUGGERED.
Diffstat (limited to 'src/cmd/tbl')
-rw-r--r-- | src/cmd/tbl/mkfile | 32 | ||||
-rw-r--r-- | src/cmd/tbl/t.h | 192 | ||||
-rw-r--r-- | src/cmd/tbl/t0.c | 49 | ||||
-rw-r--r-- | src/cmd/tbl/t1.c | 95 | ||||
-rw-r--r-- | src/cmd/tbl/t2.c | 25 | ||||
-rw-r--r-- | src/cmd/tbl/t3.c | 104 | ||||
-rw-r--r-- | src/cmd/tbl/t4.c | 405 | ||||
-rw-r--r-- | src/cmd/tbl/t5.c | 198 | ||||
-rw-r--r-- | src/cmd/tbl/t6.c | 223 | ||||
-rw-r--r-- | src/cmd/tbl/t7.c | 150 | ||||
-rw-r--r-- | src/cmd/tbl/t8.c | 367 | ||||
-rw-r--r-- | src/cmd/tbl/t9.c | 76 | ||||
-rw-r--r-- | src/cmd/tbl/tb.c | 101 | ||||
-rw-r--r-- | src/cmd/tbl/tc.c | 65 | ||||
-rw-r--r-- | src/cmd/tbl/te.c | 75 | ||||
-rw-r--r-- | src/cmd/tbl/tf.c | 74 | ||||
-rw-r--r-- | src/cmd/tbl/tg.c | 81 | ||||
-rw-r--r-- | src/cmd/tbl/ti.c | 75 | ||||
-rw-r--r-- | src/cmd/tbl/tm.c | 65 | ||||
-rw-r--r-- | src/cmd/tbl/tr.c | 28 | ||||
-rw-r--r-- | src/cmd/tbl/ts.c | 71 | ||||
-rw-r--r-- | src/cmd/tbl/tt.c | 127 | ||||
-rw-r--r-- | src/cmd/tbl/tu.c | 257 | ||||
-rw-r--r-- | src/cmd/tbl/tv.c | 183 |
24 files changed, 3118 insertions, 0 deletions
diff --git a/src/cmd/tbl/mkfile b/src/cmd/tbl/mkfile new file mode 100644 index 00000000..cdaf4a7e --- /dev/null +++ b/src/cmd/tbl/mkfile @@ -0,0 +1,32 @@ +<$PLAN9/src/mkhdr + +TARG=tbl +OFILES=\ + t8.$O\ + t4.$O\ + t6.$O\ + tu.$O\ + t5.$O\ + t7.$O\ + tv.$O\ + tg.$O\ + t3.$O\ + tb.$O\ + tt.$O\ + t9.$O\ + t1.$O\ + tf.$O\ + tc.$O\ + ti.$O\ + tm.$O\ + t0.$O\ + tr.$O\ + te.$O\ + ts.$O\ + t2.$O\ + +HFILES=\ + t.h\ + +SHORTLIB=bio 9 +<$PLAN9/src/mkone diff --git a/src/cmd/tbl/t.h b/src/cmd/tbl/t.h new file mode 100644 index 00000000..efcab373 --- /dev/null +++ b/src/cmd/tbl/t.h @@ -0,0 +1,192 @@ +/* t..c : external declarations */ + +#include <u.h> +#include <libc.h> +#include <bio.h> +# include <ctype.h> + +# define MAXLIN 250 +# define MAXHEAD 44 +# define MAXCOL 30 + /* Do NOT make MAXCOL bigger with adjusting nregs[] in tr.c */ +# define MAXCHS 2000 +#define MAXLINLEN 300 +# define MAXRPT 100 +# define CLLEN 10 +# define SHORTLINE 4 +extern int nlin, ncol, iline, nclin, nslin; + +extern int (*style)[MAXHEAD]; +extern char (*font)[MAXHEAD][2]; +extern char (*csize)[MAXHEAD][4]; +extern char (*vsize)[MAXHEAD][4]; +extern char (*cll)[CLLEN]; +extern int (*flags)[MAXHEAD]; +# define ZEROW 001 +# define HALFUP 002 +# define CTOP 004 +# define CDOWN 010 +extern int stynum[]; +extern int qcol; +extern int *doubled, *acase, *topat; +extern int F1, F2; +extern int (*lefline)[MAXHEAD]; +extern int fullbot[]; +extern char *instead[]; +extern int expflg; +extern int ctrflg; +extern int evenflg; +extern int *evenup; +extern int boxflg; +extern int dboxflg; +extern int linsize; +extern int tab; +extern int pr1403; +extern int linsize, delim1, delim2; +extern int allflg; +extern int textflg; +extern int left1flg; +extern int rightl; +struct colstr {char *col, *rcol;}; +extern struct colstr *table[]; +extern char *cspace, *cstore; +extern char *exstore, *exlim, *exspace; +extern int *sep; +extern int *used, *lused, *rused; +extern int linestop[]; +extern char *leftover; +extern char *last, *ifile; +extern int texname; +extern int texct, texmax; +extern char texstr[]; +extern int linstart; + + +extern Biobuf *tabin, tabout; +# define CRIGHT 2 +# define CLEFT 0 +# define CMID 1 +# define S1 31 +# define S2 32 +# define S3 33 +# define TMP 38 +#define S9 39 +# define SF 35 +# define SL 34 +# define LSIZE 33 +# define SIND 37 +# define SVS 36 +/* this refers to the relative position of lines */ +# define LEFT 1 +# define RIGHT 2 +# define THRU 3 +# define TOP 1 +# define BOT 2 + +int tbl(int argc,char *argv[]); /*t1.c*/ +void setinp(int, char **); +int swapin(void); + +void tableput(void); /*t2.c*/ + +void getcomm(void); /*t3.c*/ +void backrest(char *); + +void getspec(void); /*t4.c*/ +void readspec(void); +int findcol(void); +void garray(int); +char *getcore(int, int); +void freearr(void); + +void gettbl(void); /*t5.c*/ +int nodata(int); +int oneh(int); +int vspand(int, int, int); +int vspen(char *); +void permute(void); + +void maktab(void); /*t6.c*/ +void wide(char *, char *, char *); +int filler(char *); + +void runout(void); /*t7.c*/ +void runtabs(int, int); +int ifline(char *); +void need(void); +void deftail(void); + +void putline(int, int); /*t8.c*/ +void puttext(char *, char *, char *); +void funnies(int, int); +void putfont(char *); +void putsize(char *); + +void yetmore(void); /*t9.c*/ +int domore(char *); + +void checkuse(void); /*tb.c*/ +int real(char *); +char *chspace(void); +int *alocv(int); +void release(void); + +void choochar(void); /*tc.c*/ +int point(char *); + +void error(char *); /*te.c*/ +char *gets1(char *, int); +void un1getc(int); +int get1char(void); + +void savefill(void); /*tf.c*/ +void rstofill(void); +void endoff(void); +void freearr(void); +void saveline(void); +void ifdivert(void); +void restline(void); +void cleanfc(void); + +int gettext(char *, int, int, char *, char *); /*tg.c*/ +void untext(void); + +int interv(int, int); /*ti.c*/ +int interh(int, int); +int up1(int); + +char *maknew(char *); /*tm.c*/ +int ineqn (char *, char *); + +char *reg(int, int); /*tr.c*/ + +int match (char *, char *); /*ts.c*/ +int prefix(char *, char *); +int letter (int); +int numb(char *); +int digit(int); +int max(int, int); +void tcopy (char *, char *); + +int ctype(int, int); /*tt.c*/ +int min(int, int); +int fspan(int, int); +int lspan(int, int); +int ctspan(int, int); +void tohcol(int); +int allh(int); +int thish(int, int); + +void makeline(int, int, int); /*tu.c*/ +void fullwide(int, int); +void drawline(int, int, int, int, int, int); +void getstop(void); +int left(int, int, int *); +int lefdata(int, int); +int next(int); +int prev(int); + +void drawvert(int, int, int, int); /*tv.c*/ +int midbar(int, int); +int midbcol(int, int); +int barent(char *); diff --git a/src/cmd/tbl/t0.c b/src/cmd/tbl/t0.c new file mode 100644 index 00000000..0c0895bd --- /dev/null +++ b/src/cmd/tbl/t0.c @@ -0,0 +1,49 @@ + /* t0.c: storage allocation */ +# +# include "t.h" +int expflg = 0; +int ctrflg = 0; +int boxflg = 0; +int dboxflg = 0; +int tab = '\t'; +int linsize; +int pr1403; +int delim1, delim2; +int evenflg; +int *evenup; +int F1 = 0; +int F2 = 0; +int allflg = 0; +char *leftover = 0; +int textflg = 0; +int left1flg = 0; +int rightl = 0; +char *cstore, *cspace; +char *last; +struct colstr *table[MAXLIN]; +int stynum[MAXLIN+1]; +int fullbot[MAXLIN]; +char *instead[MAXLIN]; +int linestop[MAXLIN]; +int (*style)[MAXHEAD]; +char (*font)[MAXHEAD][2]; +char (*csize)[MAXHEAD][4]; +char (*vsize)[MAXHEAD][4]; +int (*lefline)[MAXHEAD]; +char (*cll)[CLLEN]; +int (*flags)[MAXHEAD]; +int qcol; +int *doubled, *acase, *topat; +int nslin, nclin; +int *sep; +int *used, *lused, *rused; +int nlin, ncol; +int iline = 1; +char *ifile = "Input"; +int texname = 'a'; +int texct = 0; +char texstr[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYXZ0123456789"; +int linstart; +char *exstore, *exlim, *exspace; +Biobuf *tabin /*= stdin */; +Biobuf tabout /* = stdout */; diff --git a/src/cmd/tbl/t1.c b/src/cmd/tbl/t1.c new file mode 100644 index 00000000..1e6cbf11 --- /dev/null +++ b/src/cmd/tbl/t1.c @@ -0,0 +1,95 @@ +/* t1.c: main control and input switching */ +# +# include "t.h" + +# define MACROS "/usr/lib/tmac.s" +# define PYMACS "/usr/lib/tmac.m" + + +# define ever (;;) + +void +main(int argc, char *argv[]) +{ + exits(tbl(argc, argv)? "error" : 0); +} + + +int +tbl(int argc, char *argv[]) +{ + char line[5120]; + /*int x;*/ + /*x=malloc((char *)0); uncomment when allocation breaks*/ + Binit(&tabout, 1, OWRITE); + setinp(argc, argv); + while (gets1(line, sizeof(line))) { + Bprint(&tabout, "%s\n", line); + if (prefix(".TS", line)) + tableput(); + } + Bterm(tabin); + return(0); +} + + +int sargc; +char **sargv; + +void +setinp(int argc, char **argv) +{ + sargc = argc; + sargv = argv; + sargc--; + sargv++; + if (sargc > 0) + swapin(); + else { + tabin = (Biobuf*)getcore(sizeof(Biobuf), 1); + Binit(tabin, 0, OREAD); + } +} + + +int +swapin(void) +{ + char *name; + while (sargc > 0 && **sargv == '-') { + if (match("-ms", *sargv)) { + *sargv = MACROS; + break; + } + if (match("-mm", *sargv)) { + *sargv = PYMACS; + break; + } + if (match("-TX", *sargv)) + pr1403 = 1; + if (match("-", *sargv)) + break; + sargc--; + sargv++; + } + if (sargc <= 0) + return(0); + /* file closing is done by GCOS troff preprocessor */ + if(tabin) + Bterm(tabin); + ifile = *sargv; + name = ifile; + if (match(ifile, "-")) { + tabin = (Biobuf*)getcore(sizeof(Biobuf), 1); + Binit(tabin, 0, OREAD); + } else + tabin = Bopen(ifile, OREAD); + iline = 1; + Bprint(&tabout, ".ds f. %s\n", ifile); + Bprint(&tabout, ".lf %d %s\n", iline, name); + if (tabin == 0) + error("Can't open file"); + sargc--; + sargv++; + return(1); +} diff --git a/src/cmd/tbl/t2.c b/src/cmd/tbl/t2.c new file mode 100644 index 00000000..6d2d7414 --- /dev/null +++ b/src/cmd/tbl/t2.c @@ -0,0 +1,25 @@ +/* t2.c: subroutine sequencing for one table */ +# include "t.h" +void +tableput(void) +{ + saveline(); + savefill(); + ifdivert(); + cleanfc(); + getcomm(); + getspec(); + gettbl(); + getstop(); + checkuse(); + choochar(); + maktab(); + runout(); + release(); + rstofill(); + endoff(); + freearr(); + restline(); +} + + diff --git a/src/cmd/tbl/t3.c b/src/cmd/tbl/t3.c new file mode 100644 index 00000000..a4dc9f9f --- /dev/null +++ b/src/cmd/tbl/t3.c @@ -0,0 +1,104 @@ +/* t3.c: interpret commands affecting whole table */ +# include "t.h" +struct optstr { + char *optnam; + int *optadd; +} options [] = { + "expand", &expflg, + "EXPAND", &expflg, + "center", &ctrflg, + "CENTER", &ctrflg, + "box", &boxflg, + "BOX", &boxflg, + "allbox", &allflg, + "ALLBOX", &allflg, + "doublebox", &dboxflg, + "DOUBLEBOX", &dboxflg, + "frame", &boxflg, + "FRAME", &boxflg, + "doubleframe", &dboxflg, + "DOUBLEFRAME", &dboxflg, + "tab", &tab, + "TAB", &tab, + "linesize", &linsize, + "LINESIZE", &linsize, + "delim", &delim1, + "DELIM", &delim1, + 0, 0}; + + +void +getcomm(void) +{ + char line[200], *cp, nb[25], *t; + struct optstr *lp; + int c, ci, found; + + for (lp = options; lp->optnam; lp++) + *(lp->optadd) = 0; + texname = texstr[texct=0]; + tab = '\t'; + Bprint(&tabout, ".nr %d \\n(.s\n", LSIZE); + gets1(line, sizeof(line)); + /* see if this is a command line */ + if (strchr(line, ';') == 0) { + backrest(line); + return; + } + for (cp = line; (c = *cp) != ';'; cp++) { + if (!letter(c)) + continue; + found = 0; + for (lp = options; lp->optadd; lp++) { + if (prefix(lp->optnam, cp)) { + *(lp->optadd) = 1; + cp += strlen(lp->optnam); + if (letter(*cp)) + error("Misspelled global option"); + while (*cp == ' ') + cp++; + t = nb; + if ( *cp == '(') + while ((ci = *++cp) != ')') + *t++ = ci; + else + cp--; + *t++ = 0; + *t = 0; + if (lp->optadd == &tab) { + if (nb[0]) + *(lp->optadd) = nb[0]; + } + if (lp->optadd == &linsize) + Bprint(&tabout, ".nr %d %s\n", LSIZE, nb); + if (lp->optadd == &delim1) { + delim1 = nb[0]; + delim2 = nb[1]; + } + found = 1; + break; + } + } + if (!found) + error("Illegal option"); + } + cp++; + backrest(cp); + return; +} + + +void +backrest(char *cp) +{ + char *s; + + for (s = cp; *s; s++) + ; + un1getc('\n'); + while (s > cp) + un1getc(*--s); + return; +} + + diff --git a/src/cmd/tbl/t4.c b/src/cmd/tbl/t4.c new file mode 100644 index 00000000..558d3ba3 --- /dev/null +++ b/src/cmd/tbl/t4.c @@ -0,0 +1,405 @@ +/* t4.c: read table specification */ +# include "t.h" +int oncol; + +void +getspec(void) +{ + int icol, i; + + qcol = findcol() + 1;/* must allow one extra for line at right */ + garray(qcol); + sep[-1] = -1; + for (icol = 0; icol < qcol; icol++) { + sep[icol] = -1; + evenup[icol] = 0; + cll[icol][0] = 0; + for (i = 0; i < MAXHEAD; i++) { + csize[icol][i][0] = 0; + vsize[icol][i][0] = 0; + font[icol][i][0] = lefline[icol][i] = 0; + flags[icol][i] = 0; + style[icol][i] = 'l'; + } + } + for (i = 0; i < MAXHEAD; i++) + lefline[qcol][i] = 0; /* fixes sample55 looping */ + nclin = ncol = 0; + oncol = 0; + left1flg = rightl = 0; + readspec(); + Bprint(&tabout, ".rm"); + for (i = 0; i < ncol; i++) + Bprint(&tabout, " %2s", reg(i, CRIGHT)); + Bprint(&tabout, "\n"); +} + + +void +readspec(void) +{ + int icol, c, sawchar, stopc, i; + char sn[10], *snp, *temp; + + sawchar = icol = 0; + while (c = get1char()) { + switch (c) { + default: + if (c != tab) { + char buf[64]; + sprint(buf, "bad table specification character %c", c); + error(buf); + } + case ' ': /* note this is also case tab */ + continue; + case '\n': + if (sawchar == 0) + continue; + case ',': + case '.': /* end of table specification */ + ncol = max(ncol, icol); + if (lefline[ncol][nclin] > 0) { + ncol++; + rightl++; + }; + if (sawchar) + nclin++; + if (nclin >= MAXHEAD) + error("too many lines in specification"); + icol = 0; + if (ncol == 0 || nclin == 0) + error("no specification"); + if (c == '.') { + while ((c = get1char()) && c != '\n') + if (c != ' ' && c != '\t') + error("dot not last character on format line"); + /* fix up sep - default is 3 except at edge */ + for (icol = 0; icol < ncol; icol++) + if (sep[icol] < 0) + sep[icol] = icol + 1 < ncol ? 3 : 2; + if (oncol == 0) + oncol = ncol; + else if (oncol + 2 < ncol) + error("tried to widen table in T&, not allowed"); + return; + } + sawchar = 0; + continue; + case 'C': + case 'S': + case 'R': + case 'N': + case 'L': + case 'A': + c += ('a' - 'A'); + case '_': + if (c == '_') + c = '-'; + case '=': + case '-': + case '^': + case 'c': + case 's': + case 'n': + case 'r': + case 'l': + case 'a': + style[icol][nclin] = c; + if (c == 's' && icol <= 0) + error("first column can not be S-type"); + if (c == 's' && style[icol-1][nclin] == 'a') { + Bprint(&tabout, ".tm warning: can't span a-type cols, changed to l\n"); + style[icol-1][nclin] = 'l'; + } + if (c == 's' && style[icol-1][nclin] == 'n') { + Bprint(&tabout, ".tm warning: can't span n-type cols, changed to c\n"); + style[icol-1][nclin] = 'c'; + } + icol++; + if (c == '^' && nclin <= 0) + error("first row can not contain vertical span"); + if (icol > qcol) + error("too many columns in table"); + sawchar = 1; + continue; + case 'b': + case 'i': + c += 'A' - 'a'; + case 'B': + case 'I': + if (icol == 0) + continue; + snp = font[icol-1][nclin]; + snp[0] = (c == 'I' ? '2' : '3'); + snp[1] = 0; + continue; + case 't': + case 'T': + if (icol > 0) + flags[icol-1][nclin] |= CTOP; + continue; + case 'd': + case 'D': + if (icol > 0) + flags[icol-1][nclin] |= CDOWN; + continue; + case 'f': + case 'F': + if (icol == 0) + continue; + snp = font[icol-1][nclin]; + snp[0] = snp[1] = stopc = 0; + for (i = 0; i < 2; i++) { + c = get1char(); + if (i == 0 && c == '(') { + stopc = ')'; + c = get1char(); + } + if (c == 0) + break; + if (c == stopc) { + stopc = 0; + break; + } + if (stopc == 0) + if (c == ' ' || c == tab ) + break; + if (c == '\n' || c == '|') { + un1getc(c); + break; + } + snp[i] = c; + if (c >= '0' && c <= '9') + break; + } + if (stopc) + if (get1char() != stopc) + error("Nonterminated font name"); + continue; + case 'P': + case 'p': + if (icol <= 0) + continue; + temp = snp = csize[icol-1][nclin]; + while (c = get1char()) { + if (c == ' ' || c == tab || c == '\n') + break; + if (c == '-' || c == '+') + if (snp > temp) + break; + else + *snp++ = c; + else if (digit(c)) + *snp++ = c; + else + break; + if (snp - temp > 4) + error("point size too large"); + } + *snp = 0; + if (atoi(temp) > 36) + error("point size unreasonable"); + un1getc (c); + continue; + case 'V': + case 'v': + if (icol <= 0) + continue; + temp = snp = vsize[icol-1][nclin]; + while (c = get1char()) { + if (c == ' ' || c == tab || c == '\n') + break; + if (c == '-' || c == '+') + if (snp > temp) + break; + else + *snp++ = c; + else if (digit(c)) + *snp++ = c; + else + break; + if (snp - temp > 4) + error("vertical spacing value too large"); + } + *snp = 0; + un1getc(c); + continue; + case 'w': + case 'W': + snp = cll [icol-1]; + /* Dale Smith didn't like this check - possible to have two text blocks + of different widths now .... + if (*snp) + { + Bprint(&tabout, "Ignored second width specification"); + continue; + } + /* end commented out code ... */ + stopc = 0; + while (c = get1char()) { + if (snp == cll[icol-1] && c == '(') { + stopc = ')'; + continue; + } + if ( !stopc && (c > '9' || c < '0')) + break; + if (stopc && c == stopc) + break; + *snp++ = c; + } + *snp = 0; + if (snp - cll[icol-1] > CLLEN) + error ("column width too long"); + if (!stopc) + un1getc(c); + continue; + case 'e': + case 'E': + if (icol < 1) + continue; + evenup[icol-1] = 1; + evenflg = 1; + continue; + case 'z': + case 'Z': /* zero width-ignre width this item */ + if (icol < 1) + continue; + flags[icol-1][nclin] |= ZEROW; + continue; + case 'u': + case 'U': /* half line up */ + if (icol < 1) + continue; + flags[icol-1][nclin] |= HALFUP; + continue; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + sn[0] = c; + snp = sn + 1; + while (digit(*snp++ = c = get1char())) + ; + un1getc(c); + sep[icol-1] = max(sep[icol-1], numb(sn)); + continue; + case '|': + lefline[icol][nclin]++; + if (icol == 0) + left1flg = 1; + continue; + } + } + error("EOF reading table specification"); +} + + +int +findcol(void) +{ +# define FLNLIM 200 + /* this counts the number of columns and then puts the line back*/ + char *s, line[FLNLIM+2], *p; + int c, n = 0, inpar = 0; + + while ((c = get1char()) != 0 && c == ' ') + ; + if (c != '\n') + un1getc(c); + for (s = line; *s = c = get1char(); s++) { + if (c == ')') + inpar = 0; + if (inpar) + continue; + if (c == '\n' || c == 0 || c == '.' || c == ',') + break; + else if (c == '(') + inpar = 1; + else if (s >= line + FLNLIM) + error("too long spec line"); + } + for (p = line; p < s; p++) + switch (*p) { + case 'l': + case 'r': + case 'c': + case 'n': + case 'a': + case 's': + case 'L': + case 'R': + case 'C': + case 'N': + case 'A': + case 'S': + case '-': + case '=': + case '_': + n++; + } + while (p >= line) + un1getc(*p--); + return(n); +} + + +void +garray(int qcol) +{ + style = (int (*)[]) getcore(MAXHEAD * qcol, sizeof(int)); + evenup = (int *) getcore(qcol, sizeof(int)); + lefline = (int (*)[]) getcore(MAXHEAD * (qcol + 1), sizeof (int)); /*+1 for sample55 loop - others may need it too*/ + font = (char (*)[][2]) getcore(MAXHEAD * qcol, 2); + csize = (char (*)[MAXHEAD][4]) getcore(MAXHEAD * qcol, 4); + vsize = (char (*)[MAXHEAD][4]) getcore(MAXHEAD * qcol, 4); + flags = (int (*)[]) getcore(MAXHEAD * qcol, sizeof(int)); + cll = (char (*)[])getcore(qcol, CLLEN); + sep = (int *) getcore(qcol + 1, sizeof(int)); + sep++; /* sep[-1] must be legal */ + used = (int *) getcore(qcol + 1, sizeof(int)); + lused = (int *) getcore(qcol + 1, sizeof(int)); + rused = (int *) getcore(qcol + 1, sizeof(int)); + doubled = (int *) getcore(qcol + 1, sizeof(int)); + acase = (int *) getcore(qcol + 1, sizeof(int)); + topat = (int *) getcore(qcol + 1, sizeof(int)); +} + + +char * +getcore(int a, int b) +{ + char *x; + x = calloc(a, b); + if (x == 0) + error("Couldn't get memory"); + return(x); +} + + +void +freearr(void) +{ + free(style); + free(evenup); + free(lefline); + free(flags); + free(font); + free(csize); + free(vsize); + free(cll); + free(--sep); /* netnews says this should be --sep because incremented earlier! */ + free(used); + free(lused); + free(rused); + free(doubled); + free(acase); + free(topat); +} + + diff --git a/src/cmd/tbl/t5.c b/src/cmd/tbl/t5.c new file mode 100644 index 00000000..8b7a65d8 --- /dev/null +++ b/src/cmd/tbl/t5.c @@ -0,0 +1,198 @@ +/* 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(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 *)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)); +} + + diff --git a/src/cmd/tbl/t6.c b/src/cmd/tbl/t6.c new file mode 100644 index 00000000..a78368fc --- /dev/null +++ b/src/cmd/tbl/t6.c @@ -0,0 +1,223 @@ +/* t6.c: compute tab stops */ +# define tx(a) (a>0 && a<128) +# include "t.h" +# define FN(i,c) font[c][stynum[i]] +# define SZ(i,c) csize[c][stynum[i]] +# define TMP1 S1 +# define TMP2 S2 + +void +maktab(void) /* define the tab stops of the table */ +{ + int icol, ilin, tsep, k, ik, vforml, il, text; + char *s; + + for (icol = 0; icol < ncol; icol++) { + doubled[icol] = acase[icol] = 0; + Bprint(&tabout, ".nr %2s 0\n", reg(icol, CRIGHT)); + for (text = 0; text < 2; text++) { + if (text) + Bprint(&tabout, ".%2s\n.rm %2s\n", reg(icol, CRIGHT), + reg(icol, CRIGHT)); + for (ilin = 0; ilin < nlin; ilin++) { + if (instead[ilin] || fullbot[ilin]) + continue; + vforml = ilin; + for (il = prev(ilin); il >= 0 && vspen(table[il][icol].col); il = prev(il)) + vforml = il; + if (fspan(vforml, icol)) + continue; + if (filler(table[ilin][icol].col)) + continue; + if ((flags[icol][stynum[ilin]] & ZEROW) != 0) + continue; + switch (ctype(vforml, icol)) { + case 'a': + acase[icol] = 1; + s = table[ilin][icol].col; + if ((int)s > 0 && (int)s < 128 && text) { + if (doubled[icol] == 0) + Bprint(&tabout, ".nr %d 0\n.nr %d 0\n", + S1, S2); + doubled[icol] = 1; + Bprint(&tabout, ".if \\n(%c->\\n(%d .nr %d \\n(%c-\n", + (int)s, S2, S2, (int)s); + } + case 'n': + if (table[ilin][icol].rcol != 0) { + if (doubled[icol] == 0 && text == 0) + Bprint(&tabout, ".nr %d 0\n.nr %d 0\n", + S1, S2); + doubled[icol] = 1; + if (real(s = table[ilin][icol].col) && !vspen(s)) { + if (tx((int)s) != text) + continue; + Bprint(&tabout, ".nr %d ", TMP); + wide(s, FN(vforml, icol), SZ(vforml, icol)); + Bprint(&tabout, "\n"); + Bprint(&tabout, ".if \\n(%d<\\n(%d .nr %d \\n(%d\n", + S1, TMP, S1, TMP); + } + if (text == 0 && real(s = table[ilin][icol].rcol) && !vspen(s) && !barent(s)) { + Bprint(&tabout, ".nr %d \\w%c%s%c\n", + TMP, F1, s, F1); + Bprint(&tabout, ".if \\n(%d<\\n(%d .nr %d \\n(%d\n", S2, TMP, S2, + TMP); + } + continue; + } + case 'r': + case 'c': + case 'l': + if (real(s = table[ilin][icol].col) && !vspen(s)) { + if (tx((int)s) != text) + continue; + Bprint(&tabout, ".nr %d ", TMP); + wide(s, FN(vforml, icol), SZ(vforml, icol)); + Bprint(&tabout, "\n"); + Bprint(&tabout, ".if \\n(%2s<\\n(%d .nr %2s \\n(%d\n", + reg(icol, CRIGHT), TMP, reg(icol, CRIGHT), TMP); + } + } + } + } + if (acase[icol]) { + Bprint(&tabout, ".if \\n(%d>=\\n(%2s .nr %2s \\n(%du+2n\n", + S2, reg(icol, CRIGHT), reg(icol, CRIGHT), S2); + } + if (doubled[icol]) { + Bprint(&tabout, ".nr %2s \\n(%d\n", reg(icol, CMID), S1); + Bprint(&tabout, ".nr %d \\n(%2s+\\n(%d\n", TMP, reg(icol, CMID), S2); + Bprint(&tabout, ".if \\n(%d>\\n(%2s .nr %2s \\n(%d\n", TMP, + reg(icol, CRIGHT), reg(icol, CRIGHT), TMP); + Bprint(&tabout, ".if \\n(%d<\\n(%2s .nr %2s +(\\n(%2s-\\n(%d)/2\n", + TMP, reg(icol, CRIGHT), reg(icol, CMID), reg(icol, CRIGHT), TMP); + } + if (cll[icol][0]) { + Bprint(&tabout, ".nr %d %sn\n", TMP, cll[icol]); + Bprint(&tabout, ".if \\n(%2s<\\n(%d .nr %2s \\n(%d\n", + reg(icol, CRIGHT), TMP, reg(icol, CRIGHT), TMP); + } + for (ilin = 0; ilin < nlin; ilin++) + if (k = lspan(ilin, icol)) { + s = table[ilin][icol-k].col; + if (!real(s) || barent(s) || vspen(s) ) + continue; + Bprint(&tabout, ".nr %d ", TMP); + wide(table[ilin][icol-k].col, FN(ilin, icol - k), SZ(ilin, icol - k)); + for (ik = k; ik >= 0; ik--) { + Bprint(&tabout, "-\\n(%2s", reg(icol - ik, CRIGHT)); + if (!expflg && ik > 0) + Bprint(&tabout, "-%dn", sep[icol-ik]); + } + Bprint(&tabout, "\n"); + Bprint(&tabout, ".if \\n(%d>0 .nr %d \\n(%d/%d\n", TMP, + TMP, TMP, k); + Bprint(&tabout, ".if \\n(%d<0 .nr %d 0\n", TMP, TMP); + for (ik = 1; ik <= k; ik++) { + if (doubled[icol-k+ik]) + Bprint(&tabout, ".nr %2s +\\n(%d/2\n", + reg(icol - k + ik, CMID), TMP); + Bprint(&tabout, ".nr %2s +\\n(%d\n", + reg(icol - k + ik, CRIGHT), TMP); + } + } + } + if (textflg) + untext(); + /* if even requested, make all columns widest width */ + if (evenflg) { + Bprint(&tabout, ".nr %d 0\n", TMP); + for (icol = 0; icol < ncol; icol++) { + if (evenup[icol] == 0) + continue; + Bprint(&tabout, ".if \\n(%2s>\\n(%d .nr %d \\n(%2s\n", + reg(icol, CRIGHT), TMP, TMP, reg(icol, CRIGHT)); + } + for (icol = 0; icol < ncol; icol++) { + if (evenup[icol] == 0) + /* if column not evened just retain old interval */ + continue; + if (doubled[icol]) + Bprint(&tabout, ".nr %2s (100*\\n(%2s/\\n(%2s)*\\n(%d/100\n", + reg(icol, CMID), reg(icol, CMID), reg(icol, CRIGHT), TMP); + /* that nonsense with the 100's and parens tries + to avoid overflow while proportionally shifting + the middle of the number */ + Bprint(&tabout, ".nr %2s \\n(%d\n", reg(icol, CRIGHT), TMP); + } + } + /* now adjust for total table width */ + for (tsep = icol = 0; icol < ncol; icol++) + tsep += sep[icol]; + if (expflg) { + Bprint(&tabout, ".nr %d 0", TMP); + for (icol = 0; icol < ncol; icol++) + Bprint(&tabout, "+\\n(%2s", reg(icol, CRIGHT)); + Bprint(&tabout, "\n"); + Bprint(&tabout, ".nr %d \\n(.l-\\n(%d\n", TMP, TMP); + if (boxflg || dboxflg || allflg) + /* tsep += 1; */ {} + else + tsep -= sep[ncol-1]; + Bprint(&tabout, ".nr %d \\n(%d/%d\n", TMP, TMP, tsep); + Bprint(&tabout, ".if \\n(%d<0 .nr %d 0\n", TMP, TMP); + } else + Bprint(&tabout, ".nr %d 1n\n", TMP); + Bprint(&tabout, ".nr %2s 0\n", reg(-1, CRIGHT)); + tsep = (boxflg || allflg || dboxflg || left1flg) ? 2 : 0; + if (sep[-1] >= 0) + tsep = sep[-1]; + for (icol = 0; icol < ncol; icol++) { + Bprint(&tabout, ".nr %2s \\n(%2s+((%d*\\n(%d)/2)\n", reg(icol, CLEFT), + reg(icol - 1, CRIGHT), tsep, TMP); + Bprint(&tabout, ".nr %2s +\\n(%2s\n", reg(icol, CRIGHT), reg(icol, CLEFT)); + if (doubled[icol]) { + /* the next line is last-ditch effort to avoid zero field width */ + /*Bprint(&tabout, ".if \\n(%2s=0 .nr %2s 1\n",reg(icol,CMID), reg(icol,CMID));*/ + Bprint(&tabout, ".nr %2s +\\n(%2s\n", reg(icol, CMID), + reg(icol, CLEFT)); + /* Bprint(&tabout, ".if n .if \\n(%s%%24>0 .nr %s +12u\n",reg(icol,CMID), reg(icol,CMID)); */ + } + tsep = sep[icol] * 2; + } + if (rightl) + Bprint(&tabout, ".nr %s (\\n(%s+\\n(%s)/2\n", reg(ncol - 1, CRIGHT), + reg(ncol - 1, CLEFT), reg(ncol - 2, CRIGHT)); + Bprint(&tabout, ".nr TW \\n(%2s\n", reg(ncol - 1, CRIGHT)); + tsep = sep[ncol-1]; + if (boxflg || allflg || dboxflg) + Bprint(&tabout, ".nr TW +((%d*\\n(%d)/2)\n", tsep, TMP); + Bprint(&tabout, + ".if t .if (\\n(TW+\\n(.o)>7.65i .tm Table at line %d file %s is too wide - \\n(TW units\n", iline - 1, ifile); + return; +} + + +void +wide(char *s, char *fn, char *size) +{ + if (point(s)) { + Bprint(&tabout, "\\w%c", F1); + if (*fn > 0) + putfont(fn); + if (*size) + putsize(size); + Bprint(&tabout, "%s", s); + if (*fn > 0) + putfont("P"); + if (*size) + putsize("0"); + Bprint(&tabout, "%c", F1); + } else + Bprint(&tabout, "\\n(%c-", (int)s); +} + + +int +filler(char *s) +{ + return (point(s) && s[0] == '\\' && s[1] == 'R'); +} + + diff --git a/src/cmd/tbl/t7.c b/src/cmd/tbl/t7.c new file mode 100644 index 00000000..2fa9de53 --- /dev/null +++ b/src/cmd/tbl/t7.c @@ -0,0 +1,150 @@ +/* t7.c: control to write table entries */ +# include "t.h" +# define realsplit ((ct=='a'||ct=='n') && table[ldata][c].rcol) + +void +runout(void) +{ + int i; + + if (boxflg || allflg || dboxflg) + need(); + if (ctrflg) { + Bprint(&tabout, ".nr #I \\n(.i\n"); + Bprint(&tabout, ".in +(\\n(.lu-\\n(TWu-\\n(.iu)/2u\n"); + } + Bprint(&tabout, ".fc %c %c\n", F1, F2); + Bprint(&tabout, ".nr #T 0-1\n"); + deftail(); + for (i = 0; i < nlin; i++) + putline(i, i); + if (leftover) + yetmore(); + Bprint(&tabout, ".fc\n"); + Bprint(&tabout, ".nr T. 1\n"); + Bprint(&tabout, ".T# 1\n"); + if (ctrflg) + Bprint(&tabout, ".in \\n(#Iu\n"); +} + + +void +runtabs(int lform, int ldata) +{ + int c, ct, vforml, lf; + + Bprint(&tabout, ".ta "); + for (c = 0; c < ncol; c++) { + vforml = lform; + for (lf = prev(lform); lf >= 0 && vspen(table[lf][c].col); lf = prev(lf)) + vforml = lf; + if (fspan(vforml, c)) + continue; + switch (ct = ctype(vforml, c)) { + case 'n': + case 'a': + if (table[ldata][c].rcol) + if (lused[c]) /*Zero field width*/ + Bprint(&tabout, "\\n(%2su ", reg(c, CMID)); + case 'c': + case 'l': + case 'r': + if (realsplit ? rused[c] : (used[c] + lused[c])) + Bprint(&tabout, "\\n(%2su ", reg(c, CRIGHT)); + continue; + case 's': + if (lspan(lform, c)) + Bprint(&tabout, "\\n(%2su ", reg(c, CRIGHT)); + continue; + } + } + Bprint(&tabout, "\n"); +} + + +int +ifline(char *s) +{ + if (!point(s)) + return(0); + if (s[0] == '\\') + s++; + if (s[1] ) + return(0); + if (s[0] == '_') + return('-'); + if (s[0] == '=') + return('='); + return(0); +} + + +void +need(void) +{ + int texlin, horlin, i; + + for (texlin = horlin = i = 0; i < nlin; i++) { + if (fullbot[i] != 0) + horlin++; + else if (instead[i] != 0) + continue; + else + texlin++; + } + Bprint(&tabout, ".ne %dv+%dp\n", texlin, 2 * horlin); +} + + +void +deftail(void) +{ + int i, c, lf, lwid; + + for (i = 0; i < MAXHEAD; i++) + if (linestop[i]) + Bprint(&tabout, ".nr #%c 0-1\n", linestop[i] + 'a' - 1); + Bprint(&tabout, ".nr #a 0-1\n"); + Bprint(&tabout, ".eo\n"); + Bprint(&tabout, ".de T#\n"); + Bprint(&tabout, ".nr 35 1m\n"); + Bprint(&tabout, ".ds #d .d\n"); + Bprint(&tabout, ".if \\(ts\\n(.z\\(ts\\(ts .ds #d nl\n"); + Bprint(&tabout, ".mk ##\n"); + Bprint(&tabout, ".nr ## -1v\n"); + Bprint(&tabout, ".ls 1\n"); + for (i = 0; i < MAXHEAD; i++) + if (linestop[i]) + Bprint(&tabout, ".if \\n(#T>=0 .nr #%c \\n(#T\n", + linestop[i] + 'a' - 1); + if (boxflg || allflg || dboxflg) /* bottom of table line */ + if (fullbot[nlin-1] == 0) { + if (!pr1403) + Bprint(&tabout, ".if \\n(T. .vs \\n(.vu-\\n(.sp\n"); + Bprint(&tabout, ".if \\n(T. "); + drawline(nlin, 0, ncol, dboxflg ? '=' : '-', 1, 0); + Bprint(&tabout, "\n.if \\n(T. .vs\n"); + /* T. is really an argument to a macro but because of + eqn we don't dare pass it as an argument and reference by $1 */ + } + for (c = 0; c < ncol; c++) { + if ((lf = left(nlin - 1, c, &lwid)) >= 0) { + Bprint(&tabout, ".if \\n(#%c>=0 .sp -1\n", linestop[lf] + 'a' - 1); + Bprint(&tabout, ".if \\n(#%c>=0 ", linestop[lf] + 'a' - 1); + tohcol(c); + drawvert(lf, nlin - 1, c, lwid); + Bprint(&tabout, "\\h'|\\n(TWu'\n"); + } + } + if (boxflg || allflg || dboxflg) /* right hand line */ { + Bprint(&tabout, ".if \\n(#a>=0 .sp -1\n"); + Bprint(&tabout, ".if \\n(#a>=0 \\h'|\\n(TWu'"); + drawvert (0, nlin - 1, ncol, dboxflg ? 2 : 1); + Bprint(&tabout, "\n"); + } + Bprint(&tabout, ".ls\n"); + Bprint(&tabout, "..\n"); + Bprint(&tabout, ".ec\n"); +} + + diff --git a/src/cmd/tbl/t8.c b/src/cmd/tbl/t8.c new file mode 100644 index 00000000..92277e2a --- /dev/null +++ b/src/cmd/tbl/t8.c @@ -0,0 +1,367 @@ +/* t8.c: write out one line of output table */ +# include "t.h" +# define realsplit ((ct=='a'||ct=='n') && table[nl][c].rcol) +int watchout; +int once; + +void +putline(int i, int nl) + /* i is line number for deciding format */ + /* nl is line number for finding data usually identical */ +{ + int c, lf, ct, form, lwid, vspf, ip, cmidx, exvspen, vforml; + int vct, chfont, uphalf; + char *s, *size, *fn, *rct; + + cmidx = watchout = vspf = exvspen = 0; + if (i == 0) + once = 0; + if (i == 0 && ( allflg || boxflg || dboxflg)) + fullwide(0, dboxflg ? '=' : '-'); + if (instead[nl] == 0 && fullbot[nl] == 0) + for (c = 0; c < ncol; c++) { + s = table[nl][c].col; + if (s == 0) + continue; + if (vspen(s)) { + for (ip = nl; ip < nlin; ip = next(ip)) + if (!vspen(s = table[ip][c].col)) + break; + if ((int)s > 0 && (int)s < 128) + Bprint(&tabout, ".ne \\n(%c|u+\\n(.Vu\n", (int)s); + continue; + } + if (point(s)) + continue; + Bprint(&tabout, ".ne \\n(%c|u+\\n(.Vu\n", (int)s); + watchout = 1; + } + if (linestop[nl]) + Bprint(&tabout, ".mk #%c\n", linestop[nl] + 'a' - 1); + lf = prev(nl); + if (instead[nl]) { + Bprint(&tabout, "%s\n", instead[nl]); + return; + } + if (fullbot[nl]) { + switch (ct = fullbot[nl]) { + case '=': + case '-': + fullwide(nl, ct); + } + return; + } + for (c = 0; c < ncol; c++) { + if (instead[nl] == 0 && fullbot[nl] == 0) + if (vspen(table[nl][c].col)) + vspf = 1; + if (lf >= 0) + if (vspen(table[lf][c].col)) + vspf = 1; + } + if (vspf) { + Bprint(&tabout, ".nr #^ \\n(\\*(#du\n"); + Bprint(&tabout, ".nr #- \\n(#^\n"); /* current line position relative to bottom */ + } + vspf = 0; + chfont = 0; + for (c = 0; c < ncol; c++) { + s = table[nl][c].col; + if (s == 0) + continue; + chfont |= (int)(font[c][stynum[nl]]); + if (point(s) ) + continue; + lf = prev(nl); + if (lf >= 0 && vspen(table[lf][c].col)) + Bprint(&tabout, + ".if (\\n(%c|+\\n(^%c-1v)>\\n(#- .nr #- +(\\n(%c|+\\n(^%c-\\n(#--1v)\n", + (int)s, 'a' + c, (int)s, 'a' + c); + else + Bprint(&tabout, + ".if (\\n(%c|+\\n(#^-1v)>\\n(#- .nr #- +(\\n(%c|+\\n(#^-\\n(#--1v)\n", + (int)s, (int)s); + } + if (allflg && once > 0 ) + fullwide(i, '-'); + once = 1; + runtabs(i, nl); + if (allh(i) && !pr1403) { + Bprint(&tabout, ".nr %d \\n(.v\n", SVS); + Bprint(&tabout, ".vs \\n(.vu-\\n(.sp\n"); + Bprint(&tabout, ".nr 35 \\n(.vu\n"); + } else + Bprint(&tabout, ".nr 35 1m\n"); + if (chfont) + Bprint(&tabout, ".nr %2d \\n(.f\n", S1); + Bprint(&tabout, "\\&"); + vct = 0; + for (c = 0; c < ncol; c++) { + uphalf = 0; + if (watchout == 0 && i + 1 < nlin && (lf = left(i, c, &lwid)) >= 0) { + tohcol(c); + drawvert(lf, i, c, lwid); + vct += 2; + } + if (rightl && c + 1 == ncol) + continue; + vforml = i; + for (lf = prev(nl); lf >= 0 && vspen(table[lf][c].col); lf = prev(lf)) + vforml = lf; + form = ctype(vforml, c); + if (form != 's') { + rct = reg(c, CLEFT); + if (form == 'a') + rct = reg(c, CMID); + if (form == 'n' && table[nl][c].rcol && lused[c] == 0) + rct = reg(c, CMID); + Bprint(&tabout, "\\h'|\\n(%2su'", rct); + } + s = table[nl][c].col; + fn = font[c][stynum[vforml]]; + size = csize[c][stynum[vforml]]; + if (*size == 0) + size = 0; + if ((flags[c][stynum[nl]] & HALFUP) != 0 && pr1403 == 0) + uphalf = 1; + switch (ct = ctype(vforml, c)) { + case 'n': + case 'a': + if (table[nl][c].rcol) { + if (lused[c]) /*Zero field width*/ { + ip = prev(nl); + if (ip >= 0) + if (vspen(table[ip][c].col)) { + if (exvspen == 0) { + Bprint(&tabout, "\\v'-(\\n(\\*(#du-\\n(^%cu", c + 'a'); + if (cmidx) +/* code folded from here */ + Bprint(&tabout, "-((\\n(#-u-\\n(^%cu)/2u)", c + 'a'); +/* unfolding */ + vct++; + if (pr1403) /* must round to whole lines */ +/* code folded from here */ + Bprint(&tabout, "/1v*1v"); +/* unfolding */ + Bprint(&tabout, "'"); + exvspen = 1; + } + } + Bprint(&tabout, "%c%c", F1, F2); + if (uphalf) + Bprint(&tabout, "\\u"); + puttext(s, fn, size); + if (uphalf) + Bprint(&tabout, "\\d"); + Bprint(&tabout, "%c", F1); + } + s = table[nl][c].rcol; + form = 1; + break; + } + case 'c': + form = 3; + break; + case 'r': + form = 2; + break; + case 'l': + form = 1; + break; + case '-': + case '=': + if (real(table[nl][c].col)) + fprint(2, "%s: line %d: Data ignored on table line %d\n", ifile, iline - 1, i + 1); + makeline(i, c, ct); + continue; + default: + continue; + } + if (realsplit ? rused[c] : used[c]) /*Zero field width*/ { + /* form: 1 left, 2 right, 3 center adjust */ + if (ifline(s)) { + makeline(i, c, ifline(s)); + continue; + } + if (filler(s)) { + Bprint(&tabout, "\\l'|\\n(%2su\\&%s'", reg(c, CRIGHT), s + 2); + continue; + } + ip = prev(nl); + cmidx = (flags[c][stynum[nl]] & (CTOP | CDOWN)) == 0; + if (ip >= 0) + if (vspen(table[ip][c].col)) { + if (exvspen == 0) { + Bprint(&tabout, "\\v'-(\\n(\\*(#du-\\n(^%cu", c + 'a'); + if (cmidx) + Bprint(&tabout, "-((\\n(#-u-\\n(^%cu)/2u)", c + 'a'); + vct++; + if (pr1403) /* round to whole lines */ + Bprint(&tabout, "/1v*1v"); + Bprint(&tabout, "'"); + } + } + Bprint(&tabout, "%c", F1); + if (form != 1) + Bprint(&tabout, "%c", F2); + if (vspen(s)) + vspf = 1; + else + { + if (uphalf) + Bprint(&tabout, "\\u"); + puttext(s, fn, size); + if (uphalf) + Bprint(&tabout, "\\d"); + } + if (form != 2) + Bprint(&tabout, "%c", F2); + Bprint(&tabout, "%c", F1); + } + ip = prev(nl); + if (ip >= 0) + if (vspen(table[ip][c].col)) { + exvspen = (c + 1 < ncol) && vspen(table[ip][c+1].col) && + (topat[c] == topat[c+1]) && + (cmidx == (flags[c+1] [stynum[nl]] & (CTOP | CDOWN) == 0)) + && (left(i, c + 1, &lwid) < 0); + if (exvspen == 0) { + Bprint(&tabout, "\\v'(\\n(\\*(#du-\\n(^%cu", c + 'a'); + if (cmidx) + Bprint(&tabout, "-((\\n(#-u-\\n(^%cu)/2u)", c + 'a'); + vct++; + if (pr1403) /* round to whole lines */ + Bprint(&tabout, "/1v*1v"); + Bprint(&tabout, "'"); + } + } + else + exvspen = 0; + /* if lines need to be split for gcos here is the place for a backslash */ + if (vct > 7 && c < ncol) { + Bprint(&tabout, "\n.sp-1\n\\&"); + vct = 0; + } + } + Bprint(&tabout, "\n"); + if (allh(i) && !pr1403) + Bprint(&tabout, ".vs \\n(%du\n", SVS); + if (watchout) + funnies(i, nl); + if (vspf) { + for (c = 0; c < ncol; c++) + if (vspen(table[nl][c].col) && (nl == 0 || (lf = prev(nl)) < 0 || + !vspen(table[lf][c].col))) { + Bprint(&tabout, ".nr ^%c \\n(#^u\n", 'a' + c); + topat[c] = nl; + } + } +} + + +void +puttext(char *s, char *fn, char *size) +{ + if (point(s)) { + putfont(fn); + putsize(size); + Bprint(&tabout, "%s", s); + if (*fn > 0) + Bprint(&tabout, "\\f\\n(%2d", S1); + if (size != 0) + putsize("0"); + } +} + + +void +funnies(int stl, int lin) +{ + /* write out funny diverted things */ + int c, s, pl, lwid, dv, lf, ct; + char *fn, *ss; + + Bprint(&tabout, ".mk ##\n"); /* rmember current vertical position */ + Bprint(&tabout, ".nr %d \\n(##\n", S1); /* bottom position */ + for (c = 0; c < ncol; c++) { + ss = table[lin][c].col; + if (point(ss)) + continue; + if (ss == 0) + continue; + s = (int)ss; + Bprint(&tabout, ".sp |\\n(##u-1v\n"); + Bprint(&tabout, ".nr %d ", SIND); + ct = 0; + for (pl = stl; pl >= 0 && !isalpha(ct = ctype(pl, c)); pl = prev(pl)) + ; + switch (ct) { + case 'n': + case 'c': + Bprint(&tabout, "(\\n(%2su+\\n(%2su-\\n(%c-u)/2u\n", reg(c, CLEFT), + reg(c - 1 + ctspan(lin, c), CRIGHT), + s); + break; + case 'l': + Bprint(&tabout, "\\n(%2su\n", reg(c, CLEFT)); + break; + case 'a': + Bprint(&tabout, "\\n(%2su\n", reg(c, CMID)); + break; + case 'r': + Bprint(&tabout, "\\n(%2su-\\n(%c-u\n", reg(c, CRIGHT), s); + break; + } + Bprint(&tabout, ".in +\\n(%du\n", SIND); + fn = font[c][stynum[stl]]; + putfont(fn); + pl = prev(stl); + if (stl > 0 && pl >= 0 && vspen(table[pl][c].col)) { + Bprint(&tabout, ".sp |\\n(^%cu\n", 'a' + c); + if ((flags[c][stynum[stl]] & (CTOP | CDOWN)) == 0) { + Bprint(&tabout, ".nr %d \\n(#-u-\\n(^%c-\\n(%c|+1v\n", + TMP, 'a' + c, s); + Bprint(&tabout, ".if \\n(%d>0 .sp \\n(%du/2u", TMP, TMP); + if (pr1403) /* round */ + Bprint(&tabout, "/1v*1v"); + Bprint(&tabout, "\n"); + } + } + Bprint(&tabout, ".%c+\n", s); + Bprint(&tabout, ".in -\\n(%du\n", SIND); + if (*fn > 0) + putfont("P"); + Bprint(&tabout, ".mk %d\n", S2); + Bprint(&tabout, ".if \\n(%d>\\n(%d .nr %d \\n(%d\n", S2, S1, S1, S2); + } + Bprint(&tabout, ".sp |\\n(%du\n", S1); + for (c = dv = 0; c < ncol; c++) { + if (stl + 1 < nlin && (lf = left(stl, c, &lwid)) >= 0) { + if (dv++ == 0) + Bprint(&tabout, ".sp -1\n"); + tohcol(c); + dv++; + drawvert(lf, stl, c, lwid); + } + } + if (dv) + Bprint(&tabout, "\n"); +} + + +void +putfont(char *fn) +{ + if (fn && *fn) + Bprint(&tabout, fn[1] ? "\\f(%.2s" : "\\f%.2s", fn); +} + + +void +putsize(char *s) +{ + if (s && *s) + Bprint(&tabout, "\\s%s", s); +} + + diff --git a/src/cmd/tbl/t9.c b/src/cmd/tbl/t9.c new file mode 100644 index 00000000..bf1978a9 --- /dev/null +++ b/src/cmd/tbl/t9.c @@ -0,0 +1,76 @@ +/* t9.c: write lines for tables over 200 lines */ +# include "t.h" +static useln; + +void +yetmore(void) +{ + for (useln = 0; useln < MAXLIN && table[useln] == 0; useln++) + ; + if (useln >= MAXLIN) + error("Wierd. No data in table."); + table[0] = table[useln]; + for (useln = nlin - 1; useln >= 0 && (fullbot[useln] || instead[useln]); useln--) + ; + if (useln < 0) + error("Wierd. No real lines in table."); + domore(leftover); + while (gets1(cstore = cspace, MAXCHS) && domore(cstore)) + ; + last = cstore; + return; +} + + +int +domore(char *dataln) +{ + int icol, ch; + + if (prefix(".TE", dataln)) + return(0); + if (dataln[0] == '.' && !isdigit(dataln[1])) { + Bprint(&tabout, "%s\n", dataln); + return(1); + } + fullbot[0] = 0; + instead[0] = (char *)0; + if (dataln[1] == 0) + switch (dataln[0]) { + case '_': + fullbot[0] = '-'; + putline(useln, 0); + return(1); + case '=': + fullbot[0] = '='; + putline(useln, 0); + return(1); + } + for (icol = 0; icol < ncol; icol++) { + table[0][icol].col = dataln; + table[0][icol].rcol = 0; + for (; (ch = *dataln) != '\0' && ch != tab; dataln++) + ; + *dataln++ = '\0'; + switch (ctype(useln, icol)) { + case 'n': + table[0][icol].rcol = maknew(table[0][icol].col); + break; + case 'a': + table[0][icol].rcol = table[0][icol].col; + table[0][icol].col = ""; + break; + } + while (ctype(useln, icol + 1) == 's') /* spanning */ + table[0][++icol].col = ""; + if (ch == '\0') + break; + } + while (++icol < ncol) + table[0][icol].col = ""; + putline(useln, 0); + exstore = exspace; /* reuse space for numerical items */ + return(1); +} + + diff --git a/src/cmd/tbl/tb.c b/src/cmd/tbl/tb.c new file mode 100644 index 00000000..5cc59880 --- /dev/null +++ b/src/cmd/tbl/tb.c @@ -0,0 +1,101 @@ +/* tb.c: check which entries exist, also storage allocation */ +# include "t.h" + +void +checkuse(void) +{ + int i, c, k; + + for (c = 0; c < ncol; c++) { + used[c] = lused[c] = rused[c] = 0; + for (i = 0; i < nlin; i++) { + if (instead[i] || fullbot[i]) + continue; + k = ctype(i, c); + if (k == '-' || k == '=') + continue; + if ((k == 'n' || k == 'a')) { + rused[c] |= real(table[i][c].rcol); + if ( !real(table[i][c].rcol)) + used[c] |= real(table[i][c].col); + if (table[i][c].rcol) + lused[c] |= real(table[i][c].col); + } else + used[c] |= real(table[i][c].col); + } + } +} + + +int +real(char *s) +{ + if (s == 0) + return(0); + if (!point(s)) + return(1); + if (*s == 0) + return(0); + return(1); +} + + +int spcount = 0; +# define MAXVEC 20 +char *spvecs[MAXVEC]; + +char * +chspace(void) +{ + char *pp; + + if (spvecs[spcount]) + return(spvecs[spcount++]); + if (spcount >= MAXVEC) + error("Too many characters in table"); + spvecs[spcount++] = pp = calloc(MAXCHS + MAXLINLEN, 1); + if (pp == (char *) - 1 || pp == (char *)0) + error("no space for characters"); + return(pp); +} + + +# define MAXPC 50 +char *thisvec; +int tpcount = -1; +char *tpvecs[MAXPC]; + +int * +alocv(int n) +{ + int *tp, *q; + + if (tpcount < 0 || thisvec + n > tpvecs[tpcount] + MAXCHS) { + tpcount++; + if (tpvecs[tpcount] == 0) { + tpvecs[tpcount] = calloc(MAXCHS, 1); + } + thisvec = tpvecs[tpcount]; + if (thisvec == (char *)0) + error("no space for vectors"); + } + tp = (int *)thisvec; + thisvec += n; + for (q = tp; q < (int *)thisvec; q++) + *q = 0; + return(tp); +} + + +void +release(void) +{ + /* give back unwanted space in some vectors */ + /* this should call free; it does not because + alloc() is so buggy */ + spcount = 0; + tpcount = -1; + exstore = 0; +} + + diff --git a/src/cmd/tbl/tc.c b/src/cmd/tbl/tc.c new file mode 100644 index 00000000..635dbf8a --- /dev/null +++ b/src/cmd/tbl/tc.c @@ -0,0 +1,65 @@ +/* tc.c: find character not in table to delimit fields */ +# include "t.h" + +void +choochar(void) +{ + /* choose funny characters to delimit fields */ + int had[128], ilin, icol, k; + char *s; + + for (icol = 0; icol < 128; icol++) + had[icol] = 0; + F1 = F2 = 0; + for (ilin = 0; ilin < nlin; ilin++) { + if (instead[ilin]) + continue; + if (fullbot[ilin]) + continue; + for (icol = 0; icol < ncol; icol++) { + k = ctype(ilin, icol); + if (k == 0 || k == '-' || k == '=') + continue; + s = table[ilin][icol].col; + if (point(s)) + while (*s) + had[*s++] = 1; + s = table[ilin][icol].rcol; + if (point(s)) + while (*s) + had[*s++] = 1; + } + } + /* choose first funny character */ + for ( + s = "\002\003\005\006\007!%&#/?,:;<=>@`^~_{}+-*ABCDEFGHIJKMNOPQRSTUVWXYZabcdefgjkoqrstwxyz"; + *s; s++) { + if (had[*s] == 0) { + F1 = *s; + had[F1] = 1; + break; + } + } + /* choose second funny character */ + for ( + s = "\002\003\005\006\007:_~^`@;,<=>#%&!/?{}+-*ABCDEFGHIJKMNOPQRSTUVWXZabcdefgjkoqrstuwxyz"; + *s; s++) { + if (had[*s] == 0) { + F2 = *s; + break; + } + } + if (F1 == 0 || F2 == 0) + error("couldn't find characters to use for delimiters"); + return; +} + + +int +point(char *s) +{ + int ss = (int)s; + return(ss >= 128 || ss < 0); +} + + diff --git a/src/cmd/tbl/te.c b/src/cmd/tbl/te.c new file mode 100644 index 00000000..3df8d445 --- /dev/null +++ b/src/cmd/tbl/te.c @@ -0,0 +1,75 @@ +/* te.c: error message control, input line count */ +# include "t.h" + +void +error(char *s) +{ + fprint(2, "\n%s:%d: %s\n", ifile, iline, s); + fprint(2, "tbl quits\n"); + exits(s); +} + + +char * +gets1(char *s, int size) +{ + char *p, *ns; + int nbl; + + iline++; + ns = s; + p = Brdline(tabin, '\n'); + while (p == 0) { + if (swapin() == 0) + return(0); + p = Brdline(tabin, '\n'); + } + nbl = Blinelen(tabin)-1; + if(nbl >= size) + error("input buffer too small"); + p[nbl] = 0; + strcpy(s, p); + s += nbl; + for (nbl = 0; *s == '\\' && s > ns; s--) + nbl++; + if (linstart && nbl % 2) /* fold escaped nl if in table */ + gets1(s + 1, size - (s-ns)); + + return(p); +} + + +# define BACKMAX 500 +char backup[BACKMAX]; +char *backp = backup; + +void +un1getc(int c) +{ + if (c == '\n') + iline--; + *backp++ = c; + if (backp >= backup + BACKMAX) + error("too much backup"); +} + + +int +get1char(void) +{ + int c; + if (backp > backup) + c = *--backp; + else + c = Bgetc(tabin); + if (c == 0) /* EOF */ { + if (swapin() == 0) + error("unexpected EOF"); + c = Bgetc(tabin); + } + if (c == '\n') + iline++; + return(c); +} + + diff --git a/src/cmd/tbl/tf.c b/src/cmd/tbl/tf.c new file mode 100644 index 00000000..3791c32f --- /dev/null +++ b/src/cmd/tbl/tf.c @@ -0,0 +1,74 @@ +/* tf.c: save and restore fill mode around table */ +# include "t.h" + +void +savefill(void) +{ + /* remembers various things: fill mode, vs, ps in mac 35 (SF) */ + Bprint(&tabout, ".de %d\n", SF); + Bprint(&tabout, ".ps \\n(.s\n"); + Bprint(&tabout, ".vs \\n(.vu\n"); + Bprint(&tabout, ".in \\n(.iu\n"); + Bprint(&tabout, ".if \\n(.u .fi\n"); + Bprint(&tabout, ".if \\n(.j .ad\n"); + Bprint(&tabout, ".if \\n(.j=0 .na\n"); + Bprint(&tabout, "..\n"); + Bprint(&tabout, ".nf\n"); + /* set obx offset if useful */ + Bprint(&tabout, ".nr #~ 0\n"); + Bprint(&tabout, ".if \\n(.T .if n .nr #~ 0.6n\n"); +} + + +void +rstofill(void) +{ + Bprint(&tabout, ".%d\n", SF); +} + + +void +endoff(void) +{ + int i; + + for (i = 0; i < MAXHEAD; i++) + if (linestop[i]) + Bprint(&tabout, ".nr #%c 0\n", linestop[i] + 'a' - 1); + for (i = 0; i < texct; i++) + Bprint(&tabout, ".rm %c+\n", texstr[i]); + Bprint(&tabout, "%s\n", last); +} + + +void +ifdivert(void) +{ + Bprint(&tabout, ".ds #d .d\n"); + Bprint(&tabout, ".if \\(ts\\n(.z\\(ts\\(ts .ds #d nl\n"); +} + + +void +saveline(void) +{ + Bprint(&tabout, ".if \\n+(b.=1 .nr d. \\n(.c-\\n(c.-1\n"); + linstart = iline; +} + + +void +restline(void) +{ + Bprint(&tabout, ".if \\n-(b.=0 .nr c. \\n(.c-\\n(d.-%d\n", iline - linstart); + linstart = 0; +} + + +void +cleanfc(void) +{ + Bprint(&tabout, ".fc\n"); +} + + diff --git a/src/cmd/tbl/tg.c b/src/cmd/tbl/tg.c new file mode 100644 index 00000000..6abb1490 --- /dev/null +++ b/src/cmd/tbl/tg.c @@ -0,0 +1,81 @@ +/* tg.c: process included text blocks */ +# include "t.h" + +int +gettext(char *sp, int ilin, int icol, char *fn, char *sz) +{ + /* get a section of text */ + char line[4096]; + int oname; + char *vs; + + if (texname == 0) + error("Too many text block diversions"); + if (textflg == 0) { + Bprint(&tabout, ".nr %d \\n(.lu\n", SL); /* remember old line length */ + textflg = 1; + } + Bprint(&tabout, ".eo\n"); + Bprint(&tabout, ".am %s\n", reg(icol, CRIGHT)); + Bprint(&tabout, ".br\n"); + Bprint(&tabout, ".di %c+\n", texname); + rstofill(); + if (fn && *fn) + Bprint(&tabout, ".nr %d \\n(.f\n.ft %s\n", S1, fn); + Bprint(&tabout, ".ft \\n(.f\n"); /* protect font */ + vs = vsize[icol][stynum[ilin]]; + if ((sz && *sz) || (vs && *vs)) { + Bprint(&tabout, ".nr %d \\n(.v\n", S9); + if (vs == 0 || *vs == 0) + vs = "\\n(.s+2"; + if (sz && *sz) + Bprint(&tabout, ".ps %s\n", sz); + Bprint(&tabout, ".vs %s\n", vs); + Bprint(&tabout, ".if \\n(%du>\\n(.vu .sp \\n(%du-\\n(.vu\n", S9, S9); + } + if (cll[icol][0]) + Bprint(&tabout, ".ll %sn\n", cll[icol]); + else + Bprint(&tabout, ".ll \\n(%du*%du/%du\n", SL, ctspan(ilin, icol), ncol + 1); + Bprint(&tabout, ".if \\n(.l<\\n(%2s .ll \\n(%2su\n", reg(icol, CRIGHT), + reg(icol, CRIGHT)); + if (ctype(ilin, icol) == 'a') + Bprint(&tabout, ".ll -2n\n"); + Bprint(&tabout, ".in 0\n"); + while (gets1(line, sizeof(line))) { + if (line[0] == 'T' && line[1] == '}' && line[2] == tab) + break; + if (match("T}", line)) + break; + Bprint(&tabout, "%s\n", line); + } + if (fn && *fn) + Bprint(&tabout, ".ft \\n(%d\n", S1); + if (sz && *sz) + Bprint(&tabout, ".br\n.ps\n.vs\n"); + Bprint(&tabout, ".br\n"); + Bprint(&tabout, ".di\n"); + Bprint(&tabout, ".nr %c| \\n(dn\n", texname); + Bprint(&tabout, ".nr %c- \\n(dl\n", texname); + Bprint(&tabout, "..\n"); + Bprint(&tabout, ".ec \\\n"); + /* copy remainder of line */ + if (line[2]) + tcopy (sp, line + 3); + else + *sp = 0; + oname = texname; + texname = texstr[++texct]; + return(oname); +} + + +void +untext(void) +{ + rstofill(); + Bprint(&tabout, ".nf\n"); + Bprint(&tabout, ".ll \\n(%du\n", SL); +} + + diff --git a/src/cmd/tbl/ti.c b/src/cmd/tbl/ti.c new file mode 100644 index 00000000..ef995bbb --- /dev/null +++ b/src/cmd/tbl/ti.c @@ -0,0 +1,75 @@ +/* ti.c: classify line intersections */ +# include "t.h" +/* determine local environment for intersections */ + +int +interv(int i, int c) +{ + int ku, kl; + + if (c >= ncol || c == 0) { + if (dboxflg) { + if (i == 0) + return(BOT); + if (i >= nlin) + return(TOP); + return(THRU); + } + if (c >= ncol) + return(0); + } + ku = i > 0 ? lefdata(i - 1, c) : 0; + if (i + 1 >= nlin && allh(i)) + kl = 0; + else + kl = lefdata(allh(i) ? i + 1 : i, c); + if (ku == 2 && kl == 2) + return(THRU); + if (ku == 2) + return(TOP); + if (kl == BOT) + return(2); + return(0); +} + + +int +interh(int i, int c) +{ + int kl, kr; + + if (fullbot[i] == '=' || (dboxflg && (i == 0 || i >= nlin - 1))) { + if (c == ncol) + return(LEFT); + if (c == 0) + return(RIGHT); + return(THRU); + } + if (i >= nlin) + return(0); + kl = c > 0 ? thish (i, c - 1) : 0; + if (kl <= 1 && i > 0 && allh(up1(i))) + kl = c > 0 ? thish(up1(i), c - 1) : 0; + kr = thish(i, c); + if (kr <= 1 && i > 0 && allh(up1(i))) + kr = c > 0 ? thish(up1(i), c) : 0; + if (kl == '=' && kr == '=') + return(THRU); + if (kl == '=') + return(LEFT); + if (kr == '=') + return(RIGHT); + return(0); +} + + +int +up1(int i) +{ + i--; + while (instead[i] && i > 0) + i--; + return(i); +} + + diff --git a/src/cmd/tbl/tm.c b/src/cmd/tbl/tm.c new file mode 100644 index 00000000..8fa4e497 --- /dev/null +++ b/src/cmd/tbl/tm.c @@ -0,0 +1,65 @@ +/* tm.c: split numerical fields */ +# include "t.h" + +char * +maknew(char *str) +{ + /* make two numerical fields */ + int dpoint, c; + char *p, *q, *ba; + + p = str; + for (ba = 0; c = *str; str++) + if (c == '\\' && *(str + 1) == '&') + ba = str; + str = p; + if (ba == 0) { + for (dpoint = 0; *str; str++) { + if (*str == '.' && !ineqn(str, p) && + (str > p && digit(*(str - 1)) || + digit(*(str + 1)))) + dpoint = (int)str; + } + if (dpoint == 0) + for (; str > p; str--) { + if (digit( *(str - 1) ) && !ineqn(str, p)) + break; + } + if (!dpoint && p == str) /* not numerical, don't split */ + return(0); + if (dpoint) + str = (char *)dpoint; + } else + str = ba; + p = str; + if (exstore == 0 || exstore > exlim) { + exstore = exspace = chspace(); + exlim = exstore + MAXCHS; + } + q = exstore; + while (*exstore++ = *str++) + ; + *p = 0; + return(q); +} + + +int +ineqn (char *s, char *p) +{ + /* true if s is in a eqn within p */ + int ineq = 0, c; + + while (c = *p) { + if (s == p) + return(ineq); + p++; + if ((ineq == 0) && (c == delim1)) + ineq = 1; + else if ((ineq == 1) && (c == delim2)) + ineq = 0; + } + return(0); +} + + diff --git a/src/cmd/tbl/tr.c b/src/cmd/tbl/tr.c new file mode 100644 index 00000000..7d586e8b --- /dev/null +++ b/src/cmd/tbl/tr.c @@ -0,0 +1,28 @@ +# include "t.h" +/* tr.c: number register allocation */ +char *nregs[] = { + /* this array must have at least 3*qcol entries + or illegal register names will result */ + "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", + "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", + "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", + "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", + "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", + "90", "91", "92", "93", "94", "95", "96", "97", "4q", "4r", + "4s", "4t", "4u", "4v", "4w", "4x", "4y", "4z", "4;", "4.", + "4a", "4b", "4c", "4d", "4e", "4f", "4g", "4h", "4i", "4j", + "4k", "4l", "4m", "4n", "4o", "4p", "5a", "5b", "5c", "5d", + "5e", "5f", "5g", "5h", "5i", "5j", "5k", "5l", "5m", "5n", + "5o", "5p", "5q", "5r", "5s", "5t", "5u", "5v", "5w", "5x", + 0}; + + +char * +reg(int col, int place) +{ + if (sizeof(nregs) < 2 * 3 * qcol) + error("Too many columns for registers"); + return (nregs[qcol*place+col]); +} + + diff --git a/src/cmd/tbl/ts.c b/src/cmd/tbl/ts.c new file mode 100644 index 00000000..43cc84ec --- /dev/null +++ b/src/cmd/tbl/ts.c @@ -0,0 +1,71 @@ +/* ts.c: minor string processing subroutines */ +#include "t.h" + +int +match (char *s1, char *s2) +{ + while (*s1 == *s2) + if (*s1++ == '\0') + return(1); + else + s2++; + return(0); +} + + +int +prefix(char *small, char *big) +{ + int c; + + while ((c = *small++) == *big++) + if (c == 0) + return(1); + return(c == 0); +} + + +int +letter (int ch) +{ + if (ch >= 'a' && ch <= 'z') + return(1); + if (ch >= 'A' && ch <= 'Z') + return(1); + return(0); +} + + +int +numb(char *str) +{ + /* convert to integer */ + int k; + for (k = 0; *str >= '0' && *str <= '9'; str++) + k = k * 10 + *str - '0'; + return(k); +} + + +int +digit(int x) +{ + return(x >= '0' && x <= '9'); +} + + +int +max(int a, int b) +{ + return( a > b ? a : b); +} + + +void +tcopy (char *s, char *t) +{ + while (*s++ = *t++) + ; +} + + diff --git a/src/cmd/tbl/tt.c b/src/cmd/tbl/tt.c new file mode 100644 index 00000000..96270b75 --- /dev/null +++ b/src/cmd/tbl/tt.c @@ -0,0 +1,127 @@ +/* tt.c: subroutines for drawing horizontal lines */ +# include "t.h" + +int +ctype(int il, int ic) +{ + if (instead[il]) + return(0); + if (fullbot[il]) + return(0); + il = stynum[il]; + return(style[ic][il]); +} + + +int +min(int a, int b) +{ + return(a < b ? a : b); +} + + +int +fspan(int i, int c) +{ + c++; + return(c < ncol && ctype(i, c) == 's'); +} + + +int +lspan(int i, int c) +{ + int k; + + if (ctype(i, c) != 's') + return(0); + c++; + if (c < ncol && ctype(i, c) == 's') + return(0); + for (k = 0; ctype(i, --c) == 's'; k++) + ; + return(k); +} + + +int +ctspan(int i, int c) +{ + int k; + c++; + for (k = 1; c < ncol && ctype(i, c) == 's'; k++) + c++; + return(k); +} + + +void +tohcol(int ic) +{ + if (ic == 0) + Bprint(&tabout, "\\h'|0'"); + else + Bprint(&tabout, "\\h'(|\\n(%2su+|\\n(%2su)/2u'", reg(ic, CLEFT), + reg(ic - 1, CRIGHT)); +} + + +int +allh(int i) +{ + /* return true if every element in line i is horizontal */ + /* also at least one must be horizontl */ + int c, one, k; + + if (fullbot[i]) + return(1); + if (i >= nlin) + return(dboxflg || boxflg); + for (one = c = 0; c < ncol; c++) { + k = thish(i, c); + if (k == 0) + return(0); + if (k == 1) + continue; + one = 1; + } + return(one); +} + + +int +thish(int i, int c) +{ + int t; + char *s; + struct colstr *pc; + + if (c < 0) + return(0); + if (i < 0) + return(0); + t = ctype(i, c); + if (t == '_' || t == '-') + return('-'); + if (t == '=') + return('='); + if (t == '^') + return(1); + if (fullbot[i] ) + return(fullbot[i]); + if (t == 's') + return(thish(i, c - 1)); + if (t == 0) + return(1); + pc = &table[i][c]; + s = (t == 'a' ? pc->rcol : pc->col); + if (s == 0 || (point(s) && *s == 0)) + return(1); + if (vspen(s)) + return(1); + if (t = barent( s)) + return(t); + return(0); +} + + diff --git a/src/cmd/tbl/tu.c b/src/cmd/tbl/tu.c new file mode 100644 index 00000000..217869e1 --- /dev/null +++ b/src/cmd/tbl/tu.c @@ -0,0 +1,257 @@ +/* tu.c: draws horizontal lines */ +# include "t.h" + +void +makeline(int i, int c, int lintype) +{ + int cr, type, shortl; + + type = thish(i, c); + if (type == 0) + return; + shortl = (table[i][c].col[0] == '\\'); + if (c > 0 && !shortl && thish(i, c - 1) == type) + return; + if (shortl == 0) + for (cr = c; cr < ncol && (ctype(i, cr) == 's' || type == thish(i, cr)); cr++) + ; + else + for (cr = c + 1; cr < ncol && ctype(i, cr) == 's'; cr++) + ; + drawline(i, c, cr - 1, lintype, 0, shortl); +} + + +void +fullwide(int i, int lintype) +{ + int cr, cl; + + if (!pr1403) + Bprint(&tabout, ".nr %d \\n(.v\n.vs \\n(.vu-\\n(.sp\n", SVS); + cr = 0; + while (cr < ncol) { + cl = cr; + while (i > 0 && vspand(prev(i), cl, 1)) + cl++; + for (cr = cl; cr < ncol; cr++) + if (i > 0 && vspand(prev(i), cr, 1)) + break; + if (cl < ncol) + drawline(i, cl, (cr < ncol ? cr - 1 : cr), lintype, 1, 0); + } + Bprint(&tabout, "\n"); + if (!pr1403) + Bprint(&tabout, ".vs \\n(%du\n", SVS); +} + + +void +drawline(int i, int cl, int cr, int lintype, int noheight, int shortl) +{ + char *exhr, *exhl, *lnch; + int lcount, ln, linpos, oldpos, nodata; + + lcount = 0; + exhr = exhl = ""; + switch (lintype) { + case '-': + lcount = 1; + break; + case '=': + lcount = pr1403 ? 1 : 2; + break; + case SHORTLINE: + lcount = 1; + break; + } + if (lcount <= 0) + return; + nodata = cr - cl >= ncol || noheight || allh(i); + if (!nodata) + Bprint(&tabout, "\\v'-.5m'"); + for (ln = oldpos = 0; ln < lcount; ln++) { + linpos = 2 * ln - lcount + 1; + if (linpos != oldpos) + Bprint(&tabout, "\\v'%dp'", linpos - oldpos); + oldpos = linpos; + if (shortl == 0) { + tohcol(cl); + if (lcount > 1) { + switch (interv(i, cl)) { + case TOP: + exhl = ln == 0 ? "1p" : "-1p"; + break; + case BOT: + exhl = ln == 1 ? "1p" : "-1p"; + break; + case THRU: + exhl = "1p"; + break; + } + if (exhl[0]) + Bprint(&tabout, "\\h'%s'", exhl); + } else if (lcount == 1) { + switch (interv(i, cl)) { + case TOP: + case BOT: + exhl = "-1p"; + break; + case THRU: + exhl = "1p"; + break; + } + if (exhl[0]) + Bprint(&tabout, "\\h'%s'", exhl); + } + if (lcount > 1) { + switch (interv(i, cr + 1)) { + case TOP: + exhr = ln == 0 ? "-1p" : "+1p"; + break; + case BOT: + exhr = ln == 1 ? "-1p" : "+1p"; + break; + case THRU: + exhr = "-1p"; + break; + } + } else if (lcount == 1) { + switch (interv(i, cr + 1)) { + case TOP: + case BOT: + exhr = "+1p"; + break; + case THRU: + exhr = "-1p"; + break; + } + } + } else + Bprint(&tabout, "\\h'|\\n(%2su'", reg(cl, CLEFT)); + Bprint(&tabout, "\\s\\n(%d", LSIZE); + if (linsize) + Bprint(&tabout, "\\v'-\\n(%dp/6u'", LSIZE); + if (shortl) + Bprint(&tabout, "\\l'|\\n(%2su'", reg(cr, CRIGHT)); + else + { + lnch = "\\(ul"; + if (pr1403) + lnch = lintype == 2 ? "=" : "\\(ru"; + if (cr + 1 >= ncol) + Bprint(&tabout, "\\l'|\\n(TWu%s%s'", exhr, lnch); + else + Bprint(&tabout, "\\l'(|\\n(%2su+|\\n(%2su)/2u%s%s'", reg(cr, CRIGHT), + reg(cr + 1, CLEFT), exhr, lnch); + } + if (linsize) + Bprint(&tabout, "\\v'\\n(%dp/6u'", LSIZE); + Bprint(&tabout, "\\s0"); + } + if (oldpos != 0) + Bprint(&tabout, "\\v'%dp'", -oldpos); + if (!nodata) + Bprint(&tabout, "\\v'+.5m'"); +} + + +void +getstop(void) +{ + int i, c, k, junk, stopp; + + stopp = 1; + for (i = 0; i < MAXLIN; i++) + linestop[i] = 0; + for (i = 0; i < nlin; i++) + for (c = 0; c < ncol; c++) { + k = left(i, c, &junk); + if (k >= 0 && linestop[k] == 0) + linestop[k] = ++stopp; + } + if (boxflg || allflg || dboxflg) + linestop[0] = 1; +} + + +int +left(int i, int c, int *lwidp) +{ + int kind, li, lj; + /* returns -1 if no line to left */ + /* returns number of line where it starts */ + /* stores into lwid the kind of line */ + *lwidp = 0; + if (i < 0) + return(-1); + kind = lefdata(i, c); + if (kind == 0) + return(-1); + if (i + 1 < nlin) + if (lefdata(next(i), c) == kind) + return(-1); + li = i; + while (i >= 0 && lefdata(i, c) == kind) + i = prev(li = i); + if (prev(li) == -1) + li = 0; + *lwidp = kind; + for (lj = i + 1; lj < li; lj++) + if (instead[lj] && strcmp(instead[lj], ".TH") == 0) + return(li); + for (i = i + 1; i < li; i++) + if (fullbot[i]) + li = i; + return(li); +} + + +int +lefdata(int i, int c) +{ + int ck; + + if (i >= nlin) + i = nlin - 1; + if (ctype(i, c) == 's') { + for (ck = c; ctype(i, ck) == 's'; ck--) + ; + if (thish(i, ck) == 0) + return(0); + } + i = stynum[i]; + i = lefline[c][i]; + if (i > 0) + return(i); + if (dboxflg && c == 0) + return(2); + if (allflg) + return(1); + if (boxflg && c == 0) + return(1); + return(0); +} + + +int +next(int i) +{ + while (i + 1 < nlin) { + i++; + if (!fullbot[i] && !instead[i]) + break; + } + return(i); +} + + +int +prev(int i) +{ + while (--i >= 0 && (fullbot[i] || instead[i])) + ; + return(i); +} + + diff --git a/src/cmd/tbl/tv.c b/src/cmd/tbl/tv.c new file mode 100644 index 00000000..19a4b03f --- /dev/null +++ b/src/cmd/tbl/tv.c @@ -0,0 +1,183 @@ +/* tv.c: draw vertical lines */ +# include "t.h" + +void +drawvert(int start, int end, int c, int lwid) +{ + char *exb = 0, *ext = 0; + int tp = 0, sl, ln, pos, epb, ept, vm; + + end++; + vm = 'v'; + /* note: nr 35 has value of 1m outside of linesize */ + while (instead[end]) + end++; + for (ln = 0; ln < lwid; ln++) { + epb = ept = 0; + pos = 2 * ln - lwid + 1; + if (pos != tp) + Bprint(&tabout, "\\h'%dp'", pos - tp); + tp = pos; + if (end < nlin) { + if (fullbot[end] || (!instead[end] && allh(end))) + epb = 2; + else + switch (midbar(end, c)) { + case '-': + exb = "1v-.5m"; + break; + case '=': + exb = "1v-.5m"; + epb = 1; + break; + } + } + if (lwid > 1) + switch (interh(end, c)) { + case THRU: + epb -= 1; + break; + case RIGHT: + epb += (ln == 0 ? 1 : -1); + break; + case LEFT: + epb += (ln == 1 ? 1 : -1); + break; + } + if (lwid == 1) + switch (interh(end, c)) { + case THRU: + epb -= 1; + break; + case RIGHT: + case LEFT: + epb += 1; + break; + } + if (start > 0) { + sl = start - 1; + while (sl >= 0 && instead[sl]) + sl--; + if (sl >= 0 && (fullbot[sl] || allh(sl))) + ept = 0; + else if (sl >= 0) + switch (midbar(sl, c)) { + case '-': + ext = ".5m"; + break; + case '=': + ext = ".5m"; + ept = -1; + break; + default: + vm = 'm'; + break; + } + else + ept = -4; + } else if (start == 0 && allh(0)) { + ept = 0; + vm = 'm'; + } + if (lwid > 1) + switch (interh(start, c)) { + case THRU: + ept += 1; + break; + case LEFT: + ept += (ln == 0 ? 1 : -1); + break; + case RIGHT: + ept += (ln == 1 ? 1 : -1); + break; + } + else if (lwid == 1) + switch (interh(start, c)) { + case THRU: + ept += 1; + break; + case LEFT: + case RIGHT: + ept -= 1; + break; + } + if (exb) + Bprint(&tabout, "\\v'%s'", exb); + if (epb) + Bprint(&tabout, "\\v'%dp'", epb); + Bprint(&tabout, "\\s\\n(%d", LSIZE); + if (linsize) + Bprint(&tabout, "\\v'-\\n(%dp/6u'", LSIZE); + Bprint(&tabout, "\\h'-\\n(#~u'"); /* adjustment for T450 nroff boxes */ + Bprint(&tabout, "\\L'|\\n(#%cu-%s", linestop[start] + 'a' - 1, + vm == 'v' ? "1v" : "\\n(35u"); + if (ext) + Bprint(&tabout, "-(%s)", ext); + if (exb) + Bprint(&tabout, "-(%s)", exb); + pos = ept - epb; + if (pos) + Bprint(&tabout, "%s%dp", pos >= 0 ? "+" : "", pos); + /* the string #d is either "nl" or ".d" depending + on diversions; on GCOS not the same */ + Bprint(&tabout, "'\\s0\\v'\\n(\\*(#du-\\n(#%cu+%s", + linestop[start] + 'a' - 1, vm == 'v' ? "1v" : "\\n(35u"); + if (ext) + Bprint(&tabout, "+%s", ext); + if (ept) + Bprint(&tabout, "%s%dp", (-ept) > 0 ? "+" : "", (-ept)); + Bprint(&tabout, "'"); + if (linsize) + Bprint(&tabout, "\\v'\\n(%dp/6u'", LSIZE); + } +} + + +int +midbar(int i, int c) +{ + int k; + + k = midbcol(i, c); + if (k == 0 && c > 0) + k = midbcol(i, c - 1); + return(k); +} + + +int +midbcol(int i, int c) +{ + int ct; + + while ( (ct = ctype(i, c)) == 's') + c--; + if (ct == '-' || ct == '=') + return(ct); + if (ct = barent(table[i][c].col)) + return(ct); + return(0); +} + + +int +barent(char *s) +{ + if (s == 0) + return (1); + if (!point(s)) + return(0); + if (s[0] == '\\') + s++; + if (s[1] != 0) + return(0); + switch (s[0]) { + case '_': + return('-'); + case '=': + return('='); + } + return(0); +} + + |