123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- /* 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);
- }
|