2 5cedca1b 2004-05-15 devnull * troff4.c
4 5cedca1b 2004-05-15 devnull * number registers, conversion, arithmetic
7 5cedca1b 2004-05-15 devnull #include "tdef.h"
8 5cedca1b 2004-05-15 devnull #include "fns.h"
9 5cedca1b 2004-05-15 devnull #include "ext.h"
12 5cedca1b 2004-05-15 devnull int regcnt = NNAMES;
13 5cedca1b 2004-05-15 devnull int falsef = 0; /* on if inside false branch of if */
15 5cedca1b 2004-05-15 devnull #define NHASHSIZE 128 /* must be 2**n */
16 5cedca1b 2004-05-15 devnull #define NHASH(i) ((i>>6)^i) & (NHASHSIZE-1)
17 5cedca1b 2004-05-15 devnull Numtab *nhash[NHASHSIZE];
19 5cedca1b 2004-05-15 devnull Numtab *numtabp = NULL;
20 5cedca1b 2004-05-15 devnull #define NDELTA 400
21 5cedca1b 2004-05-15 devnull int ncnt = 0;
23 5cedca1b 2004-05-15 devnull void setn(void)
25 5cedca1b 2004-05-15 devnull int i, j, f;
26 5cedca1b 2004-05-15 devnull Tchar ii;
27 5cedca1b 2004-05-15 devnull Uchar *p;
28 5cedca1b 2004-05-15 devnull char buf[NTM]; /* for \n(.S */
30 5cedca1b 2004-05-15 devnull f = nform = 0;
31 5cedca1b 2004-05-15 devnull if ((i = cbits(ii = getach())) == '+')
33 5cedca1b 2004-05-15 devnull else if (i == '-')
35 5cedca1b 2004-05-15 devnull else if (ii) /* don't put it back if it's already back (thanks to jaap) */
37 5cedca1b 2004-05-15 devnull if (falsef)
39 5cedca1b 2004-05-15 devnull if ((i = getsn()) == 0)
41 5cedca1b 2004-05-15 devnull p = unpair(i);
42 5cedca1b 2004-05-15 devnull if (p[0] == '.')
43 5cedca1b 2004-05-15 devnull switch (p[1]) {
44 5cedca1b 2004-05-15 devnull case 's':
47 5cedca1b 2004-05-15 devnull case 'v':
50 5cedca1b 2004-05-15 devnull case 'f':
51 5cedca1b 2004-05-15 devnull i = font;
53 5cedca1b 2004-05-15 devnull case 'p':
56 5cedca1b 2004-05-15 devnull case 't':
57 5cedca1b 2004-05-15 devnull i = findt1();
59 5cedca1b 2004-05-15 devnull case 'o':
62 5cedca1b 2004-05-15 devnull case 'l':
65 5cedca1b 2004-05-15 devnull case 'i':
68 5cedca1b 2004-05-15 devnull case '$':
69 5cedca1b 2004-05-15 devnull i = frame->nargs;
71 5cedca1b 2004-05-15 devnull case 'A':
72 5cedca1b 2004-05-15 devnull i = ascii;
74 5cedca1b 2004-05-15 devnull case 'c':
75 5cedca1b 2004-05-15 devnull i = numtabp[CD].val;
77 5cedca1b 2004-05-15 devnull case 'n':
78 5cedca1b 2004-05-15 devnull i = lastl;
80 5cedca1b 2004-05-15 devnull case 'a':
81 5cedca1b 2004-05-15 devnull i = ralss;
83 5cedca1b 2004-05-15 devnull case 'h':
84 5cedca1b 2004-05-15 devnull i = dip->hnl;
86 5cedca1b 2004-05-15 devnull case 'd':
87 5cedca1b 2004-05-15 devnull if (dip != d)
88 5cedca1b 2004-05-15 devnull i = dip->dnl;
90 5cedca1b 2004-05-15 devnull i = numtabp[NL].val;
92 5cedca1b 2004-05-15 devnull case 'u':
95 5cedca1b 2004-05-15 devnull case 'j':
96 5cedca1b 2004-05-15 devnull i = ad + 2 * admod;
98 5cedca1b 2004-05-15 devnull case 'w':
99 5cedca1b 2004-05-15 devnull i = widthp;
101 5cedca1b 2004-05-15 devnull case 'x':
102 5cedca1b 2004-05-15 devnull i = nel;
104 5cedca1b 2004-05-15 devnull case 'y':
107 5cedca1b 2004-05-15 devnull case 'T':
108 5cedca1b 2004-05-15 devnull i = dotT;
109 5cedca1b 2004-05-15 devnull break; /* -Tterm used in nroff */
110 5cedca1b 2004-05-15 devnull case 'V':
111 5cedca1b 2004-05-15 devnull i = VERT;
113 5cedca1b 2004-05-15 devnull case 'H':
114 5cedca1b 2004-05-15 devnull i = HOR;
116 5cedca1b 2004-05-15 devnull case 'k':
119 5cedca1b 2004-05-15 devnull case 'P':
120 5cedca1b 2004-05-15 devnull i = print;
122 5cedca1b 2004-05-15 devnull case 'L':
125 5cedca1b 2004-05-15 devnull case 'R': /* maximal # of regs that can be addressed */
126 fa325e9b 2020-01-10 cross i = 255*256 - regcnt;
128 5cedca1b 2004-05-15 devnull case 'z':
129 5cedca1b 2004-05-15 devnull p = unpair(dip->curd);
130 5cedca1b 2004-05-15 devnull *pbp++ = p[1]; /* watch order */
131 5cedca1b 2004-05-15 devnull *pbp++ = p[0];
133 5cedca1b 2004-05-15 devnull case 'b':
134 5cedca1b 2004-05-15 devnull i = bdtab[font];
136 5cedca1b 2004-05-15 devnull case 'F':
137 5cedca1b 2004-05-15 devnull cpushback(cfname[ifi]);
139 5cedca1b 2004-05-15 devnull case 'S':
140 fa325e9b 2020-01-10 cross buf[0] = j = 0;
141 5cedca1b 2004-05-15 devnull for( i = 0; tabtab[i] != 0 && i < NTAB; i++) {
142 5cedca1b 2004-05-15 devnull if (i > 0)
143 5cedca1b 2004-05-15 devnull buf[j++] = ' ';
144 c5561c23 2004-05-16 devnull sprintf(&buf[j], "%ld", tabtab[i] & TABMASK);
145 5cedca1b 2004-05-15 devnull j = strlen(buf);
146 5cedca1b 2004-05-15 devnull if ( tabtab[i] & RTAB)
147 5cedca1b 2004-05-15 devnull sprintf(&buf[j], "uR");
148 5cedca1b 2004-05-15 devnull else if (tabtab[i] & CTAB)
149 5cedca1b 2004-05-15 devnull sprintf(&buf[j], "uC");
151 5cedca1b 2004-05-15 devnull sprintf(&buf[j], "uL");
154 5cedca1b 2004-05-15 devnull cpushback(buf);
156 5cedca1b 2004-05-15 devnull default:
157 5cedca1b 2004-05-15 devnull goto s0;
161 5cedca1b 2004-05-15 devnull if ((j = findr(i)) == -1)
164 5cedca1b 2004-05-15 devnull i = numtabp[j].val = numtabp[j].val + numtabp[j].inc * f;
165 5cedca1b 2004-05-15 devnull nform = numtabp[j].fmt;
168 5cedca1b 2004-05-15 devnull setn1(i, nform, (Tchar) 0);
171 5cedca1b 2004-05-15 devnull Tchar numbuf[25];
172 5cedca1b 2004-05-15 devnull Tchar *numbufp;
174 5cedca1b 2004-05-15 devnull int wrc(Tchar i)
176 5cedca1b 2004-05-15 devnull if (numbufp >= &numbuf[24])
177 5cedca1b 2004-05-15 devnull return(0);
178 5cedca1b 2004-05-15 devnull *numbufp++ = i;
179 5cedca1b 2004-05-15 devnull return(1);
184 5cedca1b 2004-05-15 devnull /* insert into input number i, in format form, with size-font bits bits */
185 5cedca1b 2004-05-15 devnull void setn1(int i, int form, Tchar bits)
187 5cedca1b 2004-05-15 devnull numbufp = numbuf;
188 5cedca1b 2004-05-15 devnull nrbits = bits;
189 5cedca1b 2004-05-15 devnull nform = form;
190 5cedca1b 2004-05-15 devnull fnumb(i, wrc);
191 5cedca1b 2004-05-15 devnull *numbufp = 0;
192 5cedca1b 2004-05-15 devnull pushback(numbuf);
195 5cedca1b 2004-05-15 devnull void prnumtab(Numtab *p)
198 5cedca1b 2004-05-15 devnull for (i = 0; i < ncnt; i++)
200 5cedca1b 2004-05-15 devnull if (p[i].r != 0)
201 5cedca1b 2004-05-15 devnull fprintf(stderr, "slot %d, %s, val %d\n", i, unpair(p[i].r), p[i].val);
203 5cedca1b 2004-05-15 devnull fprintf(stderr, "slot %d empty\n", i);
205 5cedca1b 2004-05-15 devnull fprintf(stderr, "slot %d empty\n", i);
208 5cedca1b 2004-05-15 devnull void nnspace(void)
210 5cedca1b 2004-05-15 devnull ncnt = sizeof(numtab)/sizeof(Numtab) + NDELTA;
211 5cedca1b 2004-05-15 devnull numtabp = (Numtab *) grow((char *)numtabp, ncnt, sizeof(Numtab));
212 5cedca1b 2004-05-15 devnull if (numtabp == NULL) {
213 5cedca1b 2004-05-15 devnull ERROR "not enough memory for registers (%d)", ncnt WARN;
214 5cedca1b 2004-05-15 devnull exit(1);
216 5cedca1b 2004-05-15 devnull numtabp = (Numtab *) memcpy((char *)numtabp, (char *)numtab,
217 5cedca1b 2004-05-15 devnull sizeof(numtab));
218 5cedca1b 2004-05-15 devnull if (numtabp == NULL) {
219 5cedca1b 2004-05-15 devnull ERROR "Cannot initialize registers" WARN;
220 5cedca1b 2004-05-15 devnull exit(1);
224 5cedca1b 2004-05-15 devnull void grownumtab(void)
226 5cedca1b 2004-05-15 devnull ncnt += NDELTA;
227 5cedca1b 2004-05-15 devnull numtabp = (Numtab *) grow((char *) numtabp, ncnt, sizeof(Numtab));
228 5cedca1b 2004-05-15 devnull if (numtabp == NULL) {
229 5cedca1b 2004-05-15 devnull ERROR "Too many number registers (%d)", ncnt WARN;
230 5cedca1b 2004-05-15 devnull done2(04);
231 5cedca1b 2004-05-15 devnull } else {
232 5cedca1b 2004-05-15 devnull memset((char *)(numtabp) + (ncnt - NDELTA) * sizeof(Numtab),
233 5cedca1b 2004-05-15 devnull 0, NDELTA * sizeof(Numtab));
234 5cedca1b 2004-05-15 devnull nrehash();
238 5cedca1b 2004-05-15 devnull void nrehash(void)
240 5cedca1b 2004-05-15 devnull Numtab *p;
243 5cedca1b 2004-05-15 devnull for (i=0; i<NHASHSIZE; i++)
244 5cedca1b 2004-05-15 devnull nhash[i] = 0;
245 5cedca1b 2004-05-15 devnull for (p=numtabp; p < &numtabp[ncnt]; p++)
246 5cedca1b 2004-05-15 devnull p->link = 0;
247 5cedca1b 2004-05-15 devnull for (p=numtabp; p < &numtabp[ncnt]; p++) {
248 5cedca1b 2004-05-15 devnull if (p->r == 0)
249 5cedca1b 2004-05-15 devnull continue;
250 5cedca1b 2004-05-15 devnull i = NHASH(p->r);
251 5cedca1b 2004-05-15 devnull p->link = nhash[i];
252 5cedca1b 2004-05-15 devnull nhash[i] = p;
256 5cedca1b 2004-05-15 devnull void nunhash(Numtab *rp)
258 5cedca1b 2004-05-15 devnull Numtab *p;
259 5cedca1b 2004-05-15 devnull Numtab **lp;
261 5cedca1b 2004-05-15 devnull if (rp->r == 0)
263 5cedca1b 2004-05-15 devnull lp = &nhash[NHASH(rp->r)];
264 5cedca1b 2004-05-15 devnull p = *lp;
265 5cedca1b 2004-05-15 devnull while (p) {
266 5cedca1b 2004-05-15 devnull if (p == rp) {
267 5cedca1b 2004-05-15 devnull *lp = p->link;
268 5cedca1b 2004-05-15 devnull p->link = 0;
271 5cedca1b 2004-05-15 devnull lp = &p->link;
272 5cedca1b 2004-05-15 devnull p = p->link;
276 5cedca1b 2004-05-15 devnull int findr(int i)
278 5cedca1b 2004-05-15 devnull Numtab *p;
279 5cedca1b 2004-05-15 devnull int h = NHASH(i);
281 5cedca1b 2004-05-15 devnull if (i == 0)
282 5cedca1b 2004-05-15 devnull return(-1);
284 5cedca1b 2004-05-15 devnull for (p = nhash[h]; p; p = p->link)
285 5cedca1b 2004-05-15 devnull if (i == p->r)
286 5cedca1b 2004-05-15 devnull return(p - numtabp);
287 5cedca1b 2004-05-15 devnull for (p = numtabp; p < &numtabp[ncnt]; p++) {
288 5cedca1b 2004-05-15 devnull if (p->r == 0) {
289 5cedca1b 2004-05-15 devnull p->r = i;
290 5cedca1b 2004-05-15 devnull p->link = nhash[h];
291 5cedca1b 2004-05-15 devnull nhash[h] = p;
292 5cedca1b 2004-05-15 devnull regcnt++;
293 5cedca1b 2004-05-15 devnull return(p - numtabp);
296 5cedca1b 2004-05-15 devnull grownumtab();
297 5cedca1b 2004-05-15 devnull goto a0;
300 5cedca1b 2004-05-15 devnull int usedr(int i) /* returns -1 if nr i has never been used */
302 5cedca1b 2004-05-15 devnull Numtab *p;
304 5cedca1b 2004-05-15 devnull if (i == 0)
305 5cedca1b 2004-05-15 devnull return(-1);
306 5cedca1b 2004-05-15 devnull for (p = nhash[NHASH(i)]; p; p = p->link)
307 5cedca1b 2004-05-15 devnull if (i == p->r)
308 5cedca1b 2004-05-15 devnull return(p - numtabp);
309 5cedca1b 2004-05-15 devnull return -1;
313 5cedca1b 2004-05-15 devnull int fnumb(int i, int (*f)(Tchar))
318 5cedca1b 2004-05-15 devnull if (i < 0) {
319 5cedca1b 2004-05-15 devnull j = (*f)('-' | nrbits);
322 5cedca1b 2004-05-15 devnull switch (nform) {
323 5cedca1b 2004-05-15 devnull default:
324 5cedca1b 2004-05-15 devnull case '1':
326 5cedca1b 2004-05-15 devnull return decml(i, f) + j;
327 5cedca1b 2004-05-15 devnull case 'i':
328 5cedca1b 2004-05-15 devnull case 'I':
329 5cedca1b 2004-05-15 devnull return roman(i, f) + j;
330 5cedca1b 2004-05-15 devnull case 'a':
331 5cedca1b 2004-05-15 devnull case 'A':
332 5cedca1b 2004-05-15 devnull return abc(i, f) + j;
337 5cedca1b 2004-05-15 devnull int decml(int i, int (*f)(Tchar))
339 5cedca1b 2004-05-15 devnull int j, k;
342 5cedca1b 2004-05-15 devnull nform--;
343 5cedca1b 2004-05-15 devnull if ((j = i / 10) || (nform > 0))
344 5cedca1b 2004-05-15 devnull k = decml(j, f);
345 5cedca1b 2004-05-15 devnull return(k + (*f)((i % 10 + '0') | nrbits));
349 5cedca1b 2004-05-15 devnull int roman(int i, int (*f)(Tchar))
353 5cedca1b 2004-05-15 devnull return((*f)('0' | nrbits));
354 5cedca1b 2004-05-15 devnull if (nform == 'i')
355 5cedca1b 2004-05-15 devnull return(roman0(i, f, "ixcmz", "vldw"));
357 5cedca1b 2004-05-15 devnull return(roman0(i, f, "IXCMZ", "VLDW"));
361 5cedca1b 2004-05-15 devnull int roman0(int i, int (*f)(Tchar), char *onesp, char *fivesp)
363 5cedca1b 2004-05-15 devnull int q, rem, k;
366 5cedca1b 2004-05-15 devnull return(0);
367 5cedca1b 2004-05-15 devnull k = roman0(i / 10, f, onesp + 1, fivesp + 1);
368 5cedca1b 2004-05-15 devnull q = (i = i % 10) / 5;
369 5cedca1b 2004-05-15 devnull rem = i % 5;
370 5cedca1b 2004-05-15 devnull if (rem == 4) {
371 5cedca1b 2004-05-15 devnull k += (*f)(*onesp | nrbits);
373 5cedca1b 2004-05-15 devnull i = *(onesp + 1);
375 5cedca1b 2004-05-15 devnull i = *fivesp;
376 5cedca1b 2004-05-15 devnull return(k += (*f)(i | nrbits));
379 5cedca1b 2004-05-15 devnull k += (*f)(*fivesp | nrbits);
380 5cedca1b 2004-05-15 devnull while (--rem >= 0)
381 5cedca1b 2004-05-15 devnull k += (*f)(*onesp | nrbits);
382 5cedca1b 2004-05-15 devnull return(k);
386 5cedca1b 2004-05-15 devnull int abc(int i, int (*f)(Tchar))
389 5cedca1b 2004-05-15 devnull return((*f)('0' | nrbits));
391 5cedca1b 2004-05-15 devnull return(abc0(i - 1, f));
395 5cedca1b 2004-05-15 devnull int abc0(int i, int (*f)(Tchar))
397 5cedca1b 2004-05-15 devnull int j, k;
400 5cedca1b 2004-05-15 devnull if (j = i / 26)
401 5cedca1b 2004-05-15 devnull k = abc0(j - 1, f);
402 5cedca1b 2004-05-15 devnull return(k + (*f)((i % 26 + nform) | nrbits));
405 5cedca1b 2004-05-15 devnull long atoi0(void)
407 5cedca1b 2004-05-15 devnull int c, k, cnt;
408 5cedca1b 2004-05-15 devnull Tchar ii;
409 5cedca1b 2004-05-15 devnull long i, acc;
411 5cedca1b 2004-05-15 devnull acc = 0;
412 5cedca1b 2004-05-15 devnull nonumb = 0;
413 5cedca1b 2004-05-15 devnull cnt = -1;
416 5cedca1b 2004-05-15 devnull ii = getch();
417 5cedca1b 2004-05-15 devnull c = cbits(ii);
418 5cedca1b 2004-05-15 devnull switch (c) {
419 5cedca1b 2004-05-15 devnull default:
420 5cedca1b 2004-05-15 devnull ch = ii;
421 5cedca1b 2004-05-15 devnull if (cnt)
423 5cedca1b 2004-05-15 devnull case '+':
424 5cedca1b 2004-05-15 devnull i = ckph();
425 5cedca1b 2004-05-15 devnull if (nonumb)
427 5cedca1b 2004-05-15 devnull acc += i;
428 5cedca1b 2004-05-15 devnull goto a0;
429 5cedca1b 2004-05-15 devnull case '-':
430 5cedca1b 2004-05-15 devnull i = ckph();
431 5cedca1b 2004-05-15 devnull if (nonumb)
433 5cedca1b 2004-05-15 devnull acc -= i;
434 5cedca1b 2004-05-15 devnull goto a0;
435 5cedca1b 2004-05-15 devnull case '*':
436 5cedca1b 2004-05-15 devnull i = ckph();
437 5cedca1b 2004-05-15 devnull if (nonumb)
439 5cedca1b 2004-05-15 devnull acc *= i;
440 5cedca1b 2004-05-15 devnull goto a0;
441 5cedca1b 2004-05-15 devnull case '/':
442 5cedca1b 2004-05-15 devnull i = ckph();
443 5cedca1b 2004-05-15 devnull if (nonumb)
445 5cedca1b 2004-05-15 devnull if (i == 0) {
446 5cedca1b 2004-05-15 devnull flusho();
447 5cedca1b 2004-05-15 devnull ERROR "divide by zero." WARN;
448 5cedca1b 2004-05-15 devnull acc = 0;
450 5cedca1b 2004-05-15 devnull acc /= i;
451 5cedca1b 2004-05-15 devnull goto a0;
452 5cedca1b 2004-05-15 devnull case '%':
453 5cedca1b 2004-05-15 devnull i = ckph();
454 5cedca1b 2004-05-15 devnull if (nonumb)
456 5cedca1b 2004-05-15 devnull acc %= i;
457 5cedca1b 2004-05-15 devnull goto a0;
458 5cedca1b 2004-05-15 devnull case '&': /*and*/
459 5cedca1b 2004-05-15 devnull i = ckph();
460 5cedca1b 2004-05-15 devnull if (nonumb)
462 5cedca1b 2004-05-15 devnull if ((acc > 0) && (i > 0))
463 5cedca1b 2004-05-15 devnull acc = 1;
465 5cedca1b 2004-05-15 devnull acc = 0;
466 5cedca1b 2004-05-15 devnull goto a0;
467 5cedca1b 2004-05-15 devnull case ':': /*or*/
468 5cedca1b 2004-05-15 devnull i = ckph();
469 5cedca1b 2004-05-15 devnull if (nonumb)
471 5cedca1b 2004-05-15 devnull if ((acc > 0) || (i > 0))
472 5cedca1b 2004-05-15 devnull acc = 1;
474 5cedca1b 2004-05-15 devnull acc = 0;
475 5cedca1b 2004-05-15 devnull goto a0;
476 5cedca1b 2004-05-15 devnull case '=':
477 5cedca1b 2004-05-15 devnull if (cbits(ii = getch()) != '=')
478 5cedca1b 2004-05-15 devnull ch = ii;
479 5cedca1b 2004-05-15 devnull i = ckph();
480 5cedca1b 2004-05-15 devnull if (nonumb) {
481 5cedca1b 2004-05-15 devnull acc = 0;
484 5cedca1b 2004-05-15 devnull if (i == acc)
485 5cedca1b 2004-05-15 devnull acc = 1;
487 5cedca1b 2004-05-15 devnull acc = 0;
488 5cedca1b 2004-05-15 devnull goto a0;
489 5cedca1b 2004-05-15 devnull case '>':
491 5cedca1b 2004-05-15 devnull if (cbits(ii = getch()) == '=')
494 5cedca1b 2004-05-15 devnull ch = ii;
495 5cedca1b 2004-05-15 devnull i = ckph();
496 5cedca1b 2004-05-15 devnull if (nonumb) {
497 5cedca1b 2004-05-15 devnull acc = 0;
500 5cedca1b 2004-05-15 devnull if (acc > (i - k))
501 5cedca1b 2004-05-15 devnull acc = 1;
503 5cedca1b 2004-05-15 devnull acc = 0;
504 5cedca1b 2004-05-15 devnull goto a0;
505 5cedca1b 2004-05-15 devnull case '<':
507 5cedca1b 2004-05-15 devnull if (cbits(ii = getch()) == '=')
510 5cedca1b 2004-05-15 devnull ch = ii;
511 5cedca1b 2004-05-15 devnull i = ckph();
512 5cedca1b 2004-05-15 devnull if (nonumb) {
513 5cedca1b 2004-05-15 devnull acc = 0;
516 5cedca1b 2004-05-15 devnull if (acc < (i + k))
517 5cedca1b 2004-05-15 devnull acc = 1;
519 5cedca1b 2004-05-15 devnull acc = 0;
520 5cedca1b 2004-05-15 devnull goto a0;
521 5cedca1b 2004-05-15 devnull case ')':
523 5cedca1b 2004-05-15 devnull case '(':
524 5cedca1b 2004-05-15 devnull acc = atoi0();
525 5cedca1b 2004-05-15 devnull goto a0;
527 5cedca1b 2004-05-15 devnull return(acc);
531 5cedca1b 2004-05-15 devnull long ckph(void)
533 5cedca1b 2004-05-15 devnull Tchar i;
536 5cedca1b 2004-05-15 devnull if (cbits(i = getch()) == '(')
537 5cedca1b 2004-05-15 devnull j = atoi0();
539 5cedca1b 2004-05-15 devnull j = atoi1(i);
541 5cedca1b 2004-05-15 devnull return(j);
546 5cedca1b 2004-05-15 devnull * print error about illegal numeric argument;
548 5cedca1b 2004-05-15 devnull void prnumerr(void)
550 5cedca1b 2004-05-15 devnull char err_buf[40];
551 5cedca1b 2004-05-15 devnull static char warn[] = "Numeric argument expected";
552 5cedca1b 2004-05-15 devnull int savcd = numtabp[CD].val;
554 5cedca1b 2004-05-15 devnull if (numerr.type == RQERR)
555 5cedca1b 2004-05-15 devnull sprintf(err_buf, "%c%s: %s", nb ? cbits(c2) : cbits(cc),
556 5cedca1b 2004-05-15 devnull unpair(numerr.req), warn);
558 5cedca1b 2004-05-15 devnull sprintf(err_buf, "\\%c'%s': %s", numerr.esc, &numerr.escarg,
560 5cedca1b 2004-05-15 devnull if (frame != stk) /* uncertainty correction */
561 5cedca1b 2004-05-15 devnull numtabp[CD].val--;
562 c8d681e8 2008-11-18 rsc ERROR "%s", err_buf WARN;
563 5cedca1b 2004-05-15 devnull numtabp[CD].val = savcd;
567 5cedca1b 2004-05-15 devnull long atoi1(Tchar ii)
569 5cedca1b 2004-05-15 devnull int i, j, digits;
570 5cedca1b 2004-05-15 devnull double acc; /* this is the only double in troff! */
571 5cedca1b 2004-05-15 devnull int neg, abs, field, decpnt;
572 5cedca1b 2004-05-15 devnull extern int ifnum;
575 5cedca1b 2004-05-15 devnull neg = abs = field = decpnt = digits = 0;
576 5cedca1b 2004-05-15 devnull acc = 0;
577 5cedca1b 2004-05-15 devnull for (;;) {
578 5cedca1b 2004-05-15 devnull i = cbits(ii);
579 5cedca1b 2004-05-15 devnull switch (i) {
580 5cedca1b 2004-05-15 devnull default:
582 5cedca1b 2004-05-15 devnull case '+':
583 5cedca1b 2004-05-15 devnull ii = getch();
584 5cedca1b 2004-05-15 devnull continue;
585 5cedca1b 2004-05-15 devnull case '-':
586 5cedca1b 2004-05-15 devnull neg = 1;
587 5cedca1b 2004-05-15 devnull ii = getch();
588 5cedca1b 2004-05-15 devnull continue;
589 5cedca1b 2004-05-15 devnull case '|':
590 5cedca1b 2004-05-15 devnull abs = 1 + neg;
591 5cedca1b 2004-05-15 devnull neg = 0;
592 5cedca1b 2004-05-15 devnull ii = getch();
593 5cedca1b 2004-05-15 devnull continue;
598 5cedca1b 2004-05-15 devnull while (i >= '0' && i <= '9') {
599 5cedca1b 2004-05-15 devnull field++;
600 5cedca1b 2004-05-15 devnull digits++;
601 5cedca1b 2004-05-15 devnull acc = 10 * acc + i - '0';
602 5cedca1b 2004-05-15 devnull ii = getch();
603 5cedca1b 2004-05-15 devnull i = cbits(ii);
605 5cedca1b 2004-05-15 devnull if (i == '.' && !decpnt++) {
606 5cedca1b 2004-05-15 devnull field++;
607 5cedca1b 2004-05-15 devnull digits = 0;
608 5cedca1b 2004-05-15 devnull ii = getch();
609 5cedca1b 2004-05-15 devnull i = cbits(ii);
610 5cedca1b 2004-05-15 devnull goto a1;
612 5cedca1b 2004-05-15 devnull if (!field) {
613 5cedca1b 2004-05-15 devnull ch = ii;
614 5cedca1b 2004-05-15 devnull goto a2;
616 5cedca1b 2004-05-15 devnull switch (i) {
617 5cedca1b 2004-05-15 devnull case 'u':
618 5cedca1b 2004-05-15 devnull i = j = 1; /* should this be related to HOR?? */
620 5cedca1b 2004-05-15 devnull case 'v': /*VSs - vert spacing*/
621 5cedca1b 2004-05-15 devnull j = lss;
624 5cedca1b 2004-05-15 devnull case 'm': /*Ems*/
628 5cedca1b 2004-05-15 devnull case 'n': /*Ens*/
630 5cedca1b 2004-05-15 devnull if (TROFF)
633 5cedca1b 2004-05-15 devnull i = 1; /*Same as Ems in NROFF*/
635 5cedca1b 2004-05-15 devnull case 'p': /*Points*/
636 5cedca1b 2004-05-15 devnull j = INCH;
639 5cedca1b 2004-05-15 devnull case 'i': /*Inches*/
640 5cedca1b 2004-05-15 devnull j = INCH;
643 5cedca1b 2004-05-15 devnull case 'c': /*Centimeters*/
644 5cedca1b 2004-05-15 devnull /* if INCH is too big, this will overflow */
645 5cedca1b 2004-05-15 devnull j = INCH * 50;
646 5cedca1b 2004-05-15 devnull i = 127;
648 5cedca1b 2004-05-15 devnull case 'P': /*Picas*/
649 5cedca1b 2004-05-15 devnull j = INCH;
652 5cedca1b 2004-05-15 devnull default:
653 5cedca1b 2004-05-15 devnull j = dfact;
654 5cedca1b 2004-05-15 devnull ch = ii;
655 5cedca1b 2004-05-15 devnull i = dfactd;
657 5cedca1b 2004-05-15 devnull if (neg)
658 5cedca1b 2004-05-15 devnull acc = -acc;
659 5cedca1b 2004-05-15 devnull if (!noscale) {
660 5cedca1b 2004-05-15 devnull acc = (acc * j) / i;
662 5cedca1b 2004-05-15 devnull if (field != digits && digits > 0)
663 5cedca1b 2004-05-15 devnull while (digits--)
664 5cedca1b 2004-05-15 devnull acc /= 10;
665 5cedca1b 2004-05-15 devnull if (abs) {
666 5cedca1b 2004-05-15 devnull if (dip != d)
667 5cedca1b 2004-05-15 devnull j = dip->dnl;
669 5cedca1b 2004-05-15 devnull j = numtabp[NL].val;
670 5cedca1b 2004-05-15 devnull if (!vflag) {
671 5cedca1b 2004-05-15 devnull j = numtabp[HP].val;
673 5cedca1b 2004-05-15 devnull if (abs == 2)
675 5cedca1b 2004-05-15 devnull acc -= j;
678 5cedca1b 2004-05-15 devnull nonumb = (!field || field == decpnt);
679 5cedca1b 2004-05-15 devnull if (nonumb && (trace & TRNARGS) && !ismot(ii) && !nlflg && !ifnum) {
680 5cedca1b 2004-05-15 devnull if (cbits(ii) != RIGHT ) /* Too painful to do right */
681 5cedca1b 2004-05-15 devnull prnumerr();
683 5cedca1b 2004-05-15 devnull return(acc);
687 5cedca1b 2004-05-15 devnull void caserr(void)
689 5cedca1b 2004-05-15 devnull int i, j;
690 5cedca1b 2004-05-15 devnull Numtab *p;
693 5cedca1b 2004-05-15 devnull while (!skip() && (i = getrq()) ) {
694 5cedca1b 2004-05-15 devnull j = usedr(i);
695 5cedca1b 2004-05-15 devnull if (j < 0)
696 5cedca1b 2004-05-15 devnull continue;
697 5cedca1b 2004-05-15 devnull p = &numtabp[j];
698 5cedca1b 2004-05-15 devnull nunhash(p);
699 5cedca1b 2004-05-15 devnull p->r = p->val = p->inc = p->fmt = 0;
700 5cedca1b 2004-05-15 devnull regcnt--;
705 5cedca1b 2004-05-15 devnull * .nr request; if tracing, don't check optional
706 5cedca1b 2004-05-15 devnull * 2nd argument because tbl generates .in 1.5n
708 5cedca1b 2004-05-15 devnull void casenr(void)
710 5cedca1b 2004-05-15 devnull int i, j;
711 5cedca1b 2004-05-15 devnull int savtr = trace;
715 5cedca1b 2004-05-15 devnull if ((i = findr(getrq())) == -1)
716 5cedca1b 2004-05-15 devnull goto rtn;
718 5cedca1b 2004-05-15 devnull j = inumb(&numtabp[i].val);
719 5cedca1b 2004-05-15 devnull if (nonumb)
720 5cedca1b 2004-05-15 devnull goto rtn;
721 5cedca1b 2004-05-15 devnull numtabp[i].val = j;
723 5cedca1b 2004-05-15 devnull trace = 0;
724 5cedca1b 2004-05-15 devnull j = atoi0(); /* BUG??? */
725 5cedca1b 2004-05-15 devnull trace = savtr;
726 5cedca1b 2004-05-15 devnull if (nonumb)
727 5cedca1b 2004-05-15 devnull goto rtn;
728 5cedca1b 2004-05-15 devnull numtabp[i].inc = j;
733 5cedca1b 2004-05-15 devnull void caseaf(void)
735 5cedca1b 2004-05-15 devnull int i, k;
736 5cedca1b 2004-05-15 devnull Tchar j;
739 5cedca1b 2004-05-15 devnull if (skip() || !(i = getrq()) || skip())
742 5cedca1b 2004-05-15 devnull j = getch();
743 5cedca1b 2004-05-15 devnull if (!isalpha(cbits(j))) {
745 5cedca1b 2004-05-15 devnull while ((j = cbits(getch())) >= '0' && j <= '9')
750 5cedca1b 2004-05-15 devnull numtabp[findr(i)].fmt = k; /* was k & BYTEMASK */
753 5cedca1b 2004-05-15 devnull void setaf(void) /* return format of number register */
755 5cedca1b 2004-05-15 devnull int i, j;
757 5cedca1b 2004-05-15 devnull i = usedr(getsn());
758 5cedca1b 2004-05-15 devnull if (i == -1)
760 5cedca1b 2004-05-15 devnull if (numtabp[i].fmt > 20) /* it was probably a, A, i or I */
761 5cedca1b 2004-05-15 devnull *pbp++ = numtabp[i].fmt;
763 5cedca1b 2004-05-15 devnull for (j = (numtabp[i].fmt ? numtabp[i].fmt : 1); j; j--)
764 5cedca1b 2004-05-15 devnull *pbp++ = '0';
768 5cedca1b 2004-05-15 devnull int vnumb(int *i)
770 5cedca1b 2004-05-15 devnull vflag++;
771 5cedca1b 2004-05-15 devnull dfact = lss;
772 5cedca1b 2004-05-15 devnull res = VERT;
773 5cedca1b 2004-05-15 devnull return(inumb(i));
777 5cedca1b 2004-05-15 devnull int hnumb(int *i)
779 5cedca1b 2004-05-15 devnull dfact = EM;
780 5cedca1b 2004-05-15 devnull res = HOR;
781 5cedca1b 2004-05-15 devnull return(inumb(i));
785 5cedca1b 2004-05-15 devnull int inumb(int *n)
787 5cedca1b 2004-05-15 devnull int i, j, f;
788 5cedca1b 2004-05-15 devnull Tchar ii;
791 5cedca1b 2004-05-15 devnull if (n) {
792 5cedca1b 2004-05-15 devnull if ((j = cbits(ii = getch())) == '+')
794 5cedca1b 2004-05-15 devnull else if (j == '-')
797 5cedca1b 2004-05-15 devnull ch = ii;
799 5cedca1b 2004-05-15 devnull i = atoi0();
800 5cedca1b 2004-05-15 devnull if (n && f)
801 5cedca1b 2004-05-15 devnull i = *n + f * i;
802 5cedca1b 2004-05-15 devnull i = quant(i, res);
803 5cedca1b 2004-05-15 devnull vflag = 0;
804 5cedca1b 2004-05-15 devnull res = dfactd = dfact = 1;
805 5cedca1b 2004-05-15 devnull if (nonumb)
807 5cedca1b 2004-05-15 devnull return(i);
811 5cedca1b 2004-05-15 devnull int quant(int n, int m)
813 5cedca1b 2004-05-15 devnull int i, neg;
815 5cedca1b 2004-05-15 devnull neg = 0;
816 5cedca1b 2004-05-15 devnull if (n < 0) {
820 5cedca1b 2004-05-15 devnull /* better as i = ((n + m/2)/m)*m */
821 5cedca1b 2004-05-15 devnull i = n / m;
822 5cedca1b 2004-05-15 devnull if (n - m * i > m / 2)
825 5cedca1b 2004-05-15 devnull if (neg)
827 5cedca1b 2004-05-15 devnull return(i);