/* t4.c: read table specification */ # include "t..c" int oncol; getspec() { 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(); fprintf(tabout, ".rm"); for(i=0; i<ncol; i++) fprintf(tabout, " %2s", reg(i, CRIGHT)); fprintf(tabout, "\n"); } readspec() { int icol, c, sawchar, stopc, i; char sn[10], *snp, *temp; sawchar=icol=0; while (c=get1char()) { switch(c) { default: if (c != tab) error("bad table specification character"); 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') { fprintf(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') { fprintf(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) { fprintf(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"); } findcol() { # 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())!=EOF && c == ' ') ; if (c!='\n') un1getc(c); for(s=line; *s = c = get1char(); s++) { if (c==')') inpar=0; if (inpar) continue; if (c=='\n' || c == EOF || 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 (c= *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); } garray(qcol) { char * getcore(); 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(a,b) { char *x, *calloc(); x = calloc(a,b); if (x==0) error("Couldn't get memory"); return(x); } freearr() { cfree(style); cfree(evenup); cfree(lefline); cfree(flags); cfree(font); cfree(csize); cfree(vsize); cfree(cll); cfree(--sep); /* netnews says this should be --sep because incremented earlier! */ cfree(used); cfree(lused); cfree(rused); cfree(doubled); cfree(acase); cfree(topat); }