| 1 | /* t4.c: read table specification */ |
| 2 | # include "t..c" |
| 3 | int oncol; |
| 4 | getspec() |
| 5 | { |
| 6 | int icol, i; |
| 7 | for(icol=0; icol<MAXCOL; icol++) |
| 8 | { |
| 9 | sep[icol]= -1; |
| 10 | evenup[icol]=0; |
| 11 | cll[icol][0]=0; |
| 12 | for(i=0; i<MAXHEAD; i++) |
| 13 | { |
| 14 | csize[i][icol][0]=0; |
| 15 | vsize[i][icol][0]=0; |
| 16 | font[i][icol][0] = lefline[i][icol] = 0; |
| 17 | ctop[i][icol]=0; |
| 18 | style[i][icol]= 'l'; |
| 19 | } |
| 20 | } |
| 21 | nclin=ncol=0; |
| 22 | oncol =0; |
| 23 | left1flg=rightl=0; |
| 24 | readspec(); |
| 25 | fprintf(tabout, ".rm"); |
| 26 | for(i=0; i<ncol; i++) |
| 27 | fprintf(tabout, " %02d", 80+i); |
| 28 | fprintf(tabout, "\n"); |
| 29 | } |
| 30 | readspec() |
| 31 | { |
| 32 | int icol, c, sawchar, stopc, i; |
| 33 | char sn[10], *snp, *temp; |
| 34 | sawchar=icol=0; |
| 35 | while (c=get1char()) |
| 36 | { |
| 37 | switch(c) |
| 38 | { |
| 39 | default: |
| 40 | if (c != tab) |
| 41 | error("bad table specification character"); |
| 42 | case ' ': /* note this is also case tab */ |
| 43 | continue; |
| 44 | case '\n': |
| 45 | if(sawchar==0) continue; |
| 46 | case ',': |
| 47 | case '.': /* end of table specification */ |
| 48 | ncol = max(ncol, icol); |
| 49 | if (lefline[nclin][ncol]>0) {ncol++; rightl++;}; |
| 50 | if(sawchar) |
| 51 | nclin++; |
| 52 | if (nclin>=MAXHEAD) |
| 53 | error("too many lines in specification"); |
| 54 | icol=0; |
| 55 | if (ncol==0 || nclin==0) |
| 56 | error("no specification"); |
| 57 | if (c== '.') |
| 58 | { |
| 59 | while ((c=get1char()) && c != '\n') |
| 60 | if (c != ' ' && c != '\t') |
| 61 | error("dot not last character on format line"); |
| 62 | /* fix up sep - default is 3 except at edge */ |
| 63 | for(icol=0; icol<ncol; icol++) |
| 64 | if (sep[icol]<0) |
| 65 | sep[icol] = icol+1<ncol ? 3 : 1; |
| 66 | if (oncol == 0) |
| 67 | oncol = ncol; |
| 68 | else if (oncol +2 <ncol) |
| 69 | error("tried to widen table in T&, not allowed"); |
| 70 | return; |
| 71 | } |
| 72 | sawchar=0; |
| 73 | continue; |
| 74 | case 'C': case 'S': case 'R': case 'N': case 'L': case 'A': |
| 75 | c += ('a'-'A'); |
| 76 | case '_': if (c=='_') c= '-'; |
| 77 | case '=': case '-': |
| 78 | case '^': |
| 79 | case 'c': case 's': case 'n': case 'r': case 'l': case 'a': |
| 80 | style[nclin][icol]=c; |
| 81 | if (c== 's' && icol<=0) |
| 82 | error("first column can not be S-type"); |
| 83 | if (c=='s' && style[nclin][icol-1] == 'a') |
| 84 | { |
| 85 | fprintf(tabout, ".tm warning: can't span a-type cols, changed to l\n"); |
| 86 | style[nclin][icol-1] = 'l'; |
| 87 | } |
| 88 | if (c=='s' && style[nclin][icol-1] == 'n') |
| 89 | { |
| 90 | fprintf(tabout, ".tm warning: can't span n-type cols, changed to c\n"); |
| 91 | style[nclin][icol-1] = 'c'; |
| 92 | } |
| 93 | icol++; |
| 94 | if (c=='^' && nclin<=0) |
| 95 | error("first row can not contain vertical span"); |
| 96 | if (icol>=MAXCOL) |
| 97 | error("too many columns in table"); |
| 98 | sawchar=1; |
| 99 | continue; |
| 100 | case 'b': case 'i': |
| 101 | c += 'A'-'a'; |
| 102 | case 'B': case 'I': |
| 103 | if (icol==0) continue; |
| 104 | snp=font[nclin][icol-1]; |
| 105 | snp[0]= (c=='I' ? '2' : '3'); |
| 106 | snp[1]=0; |
| 107 | continue; |
| 108 | case 't': case 'T': |
| 109 | if (icol>0) |
| 110 | ctop[nclin][icol-1] = 1; |
| 111 | continue; |
| 112 | case 'd': case 'D': |
| 113 | if (icol>0) |
| 114 | ctop[nclin][icol-1] = -1; |
| 115 | continue; |
| 116 | case 'f': case 'F': |
| 117 | if (icol==0) continue; |
| 118 | snp=font[nclin][icol-1]; |
| 119 | snp[0]=snp[1]=stopc=0; |
| 120 | for(i=0; i<2; i++) |
| 121 | { |
| 122 | c = get1char(); |
| 123 | if (i==0 && c=='(') |
| 124 | { |
| 125 | stopc=')'; |
| 126 | c = get1char(); |
| 127 | } |
| 128 | if (c==0) break; |
| 129 | if (c==stopc) {stopc=0; break;} |
| 130 | if (stopc==0) if (c==' ' || c== tab ) break; |
| 131 | if (c=='\n'){un1getc(c); break;} |
| 132 | snp[i] = c; |
| 133 | if (c>= '0' && c<= '9') break; |
| 134 | } |
| 135 | if (stopc) if (get1char()!=stopc) |
| 136 | error("Nonterminated font name"); |
| 137 | continue; |
| 138 | case 'P': case 'p': |
| 139 | if (icol<=0) continue; |
| 140 | temp = snp = csize[nclin][icol-1]; |
| 141 | while (c = get1char()) |
| 142 | { |
| 143 | if (c== ' ' || c== tab || c=='\n') break; |
| 144 | if (c=='-' || c == '+') |
| 145 | if (snp>temp) |
| 146 | break; |
| 147 | else |
| 148 | *snp++=c; |
| 149 | else |
| 150 | if (digit(c)) |
| 151 | *snp++ = c; |
| 152 | else break; |
| 153 | if (snp-temp>4) |
| 154 | error("point size too large"); |
| 155 | } |
| 156 | *snp = 0; |
| 157 | if (atoi(temp)>36) |
| 158 | error("point size unreasonable"); |
| 159 | un1getc (c); |
| 160 | continue; |
| 161 | case 'V': case 'v': |
| 162 | if (icol<=0) continue; |
| 163 | temp = snp = vsize[nclin][icol-1]; |
| 164 | while (c = get1char()) |
| 165 | { |
| 166 | if (c== ' ' || c== tab || c=='\n') break; |
| 167 | if (c=='-' || c == '+') |
| 168 | if (snp>temp) |
| 169 | break; |
| 170 | else |
| 171 | *snp++=c; |
| 172 | else |
| 173 | if (digit(c)) |
| 174 | *snp++ = c; |
| 175 | else break; |
| 176 | if (snp-temp>4) |
| 177 | error("vertical spacing value too large"); |
| 178 | } |
| 179 | *snp=0; |
| 180 | un1getc(c); |
| 181 | continue; |
| 182 | case 'w': case 'W': |
| 183 | snp = cll [icol-1]; |
| 184 | /* Dale Smith didn't like this check - possible to have two text blocks |
| 185 | of different widths now .... |
| 186 | if (*snp) |
| 187 | { |
| 188 | fprintf(tabout, "Ignored second width specification"); |
| 189 | continue; |
| 190 | } |
| 191 | /* end commented out code ... */ |
| 192 | stopc=0; |
| 193 | while (c = get1char()) |
| 194 | { |
| 195 | if (snp==cll[icol-1] && c=='(') |
| 196 | { |
| 197 | stopc = ')'; |
| 198 | continue; |
| 199 | } |
| 200 | if ( !stopc && (c>'9' || c< '0')) |
| 201 | break; |
| 202 | if (stopc && c== stopc) |
| 203 | break; |
| 204 | *snp++ =c; |
| 205 | } |
| 206 | *snp=0; |
| 207 | if (snp-cll[icol-1]>CLLEN) |
| 208 | error ("column width too long"); |
| 209 | if (!stopc) |
| 210 | un1getc(c); |
| 211 | continue; |
| 212 | case 'e': case 'E': |
| 213 | if (icol<1) continue; |
| 214 | evenup[icol-1]=1; |
| 215 | evenflg=1; |
| 216 | continue; |
| 217 | case '0': case '1': case '2': case '3': case '4': |
| 218 | case '5': case '6': case '7': case '8': case '9': |
| 219 | sn[0] = c; |
| 220 | snp=sn+1; |
| 221 | while (digit(*snp++ = c = get1char())) |
| 222 | ; |
| 223 | un1getc(c); |
| 224 | sep[icol-1] = max(sep[icol-1], numb(sn)); |
| 225 | continue; |
| 226 | case '|': |
| 227 | lefline[nclin][icol]++; |
| 228 | if (icol==0) left1flg=1; |
| 229 | continue; |
| 230 | } |
| 231 | } |
| 232 | error("EOF reading table specification"); |
| 233 | } |