|
|
1.1 root 1: #include <ctype.h>
2: #include "tdef.h"
3: extern
4: #include "d.h"
5: extern
6: #include "v.h"
7: #ifdef NROFF
8: extern
9: #include "tw.h"
10: #endif
11: #include "s.h"
12: /*
13: troff4.c
14:
15: number registers, conversion, arithmetic
16: */
17:
18: #include <sgtty.h>
19: #include "ext.h"
20:
21: int regcnt = NNAMES;
22: int falsef = 0; /* on if inside false branch of if */
23:
24: setn()
25: {
26: register i, j;
27: tchar ii;
28: int f;
29:
30: f = nform = 0;
31: if ((i = cbits(ii = getch())) == '+')
32: f = 1;
33: else if (i == '-')
34: f = -1;
35: else
36: ch = ii;
37: if (falsef)
38: f = 0;
39: if ((i = getsn()) == 0)
40: return;
41: if ((i & 0177) == '.')
42: switch (i >> BYTE) {
43: case 's':
44: i = pts;
45: break;
46: case 'v':
47: i = lss;
48: break;
49: case 'f':
50: i = font;
51: break;
52: case 'p':
53: i = pl;
54: break;
55: case 't':
56: i = findt1();
57: break;
58: case 'o':
59: i = po;
60: break;
61: case 'l':
62: i = ll;
63: break;
64: case 'i':
65: i = in;
66: break;
67: case '$':
68: i = frame->nargs;
69: break;
70: case 'A':
71: i = ascii;
72: break;
73: case 'c':
74: i = v.cd;
75: break;
76: case 'n':
77: i = lastl;
78: break;
79: case 'a':
80: i = ralss;
81: break;
82: case 'h':
83: i = dip->hnl;
84: break;
85: case 'd':
86: if (dip != d)
87: i = dip->dnl;
88: else
89: i = v.nl;
90: break;
91: case 'u':
92: i = fi;
93: break;
94: case 'j':
95: i = ad + 2 * admod;
96: break;
97: case 'w':
98: i = width(*(pinchar-1)); /* XXX */
99: break;
100: case 'x':
101: i = nel;
102: break;
103: case 'y':
104: i = un;
105: break;
106: case 'T':
107: i = dotT;
108: break; /*-Tterm used in nroff*/
109: case 'V':
110: i = VERT;
111: break;
112: case 'H':
113: i = HOR;
114: break;
115: case 'k':
116: i = ne;
117: break;
118: case 'P':
119: i = print;
120: break;
121: case 'L':
122: i = ls;
123: break;
124: case 'R':
125: i = NN - regcnt;
126: break;
127: case 'z':
128: i = dip->curd;
129: cbuf[0] = i & BMASK;
130: cbuf[1] = (i >> BYTE) & BMASK;
131: cbuf[2] = 0;
132: cp = cbuf;
133: return;
134: case 'b':
135: i = bdtab[font];
136: break;
137:
138: default:
139: goto s0;
140: }
141: else {
142: s0:
143: if ((j = findr(i)) == -1)
144: i = 0;
145: else {
146: i = (vlist[j] = (vlist[j] + inc[j] * f));
147: nform = fmt[j];
148: }
149: }
150: setn1(i);
151: cp = cbuf;
152: }
153:
154:
155: setn1(i)
156: int i;
157: {
158: extern int wrc();
159:
160: cp = cbuf;
161: nrbits = 0;
162: fnumb(i, wrc);
163: *cp = 0;
164: cp = cbuf;
165: }
166:
167:
168: findr(i)
169: register int i;
170: {
171: register j;
172: register int *p;
173:
174: if (i == 0)
175: return(-1);
176: for (p = r; p < &r[NN]; p++) {
177: if (i == *p)
178: break;
179: }
180: if (p != &r[NN])
181: return(p - r);
182: for (p = r; p < &r[NN]; p++) {
183: if (*p == 0) {
184: *p = i;
185: regcnt++;
186: break;
187: }
188: }
189: if (p == &r[NN]) {
190: fprintf(stderr, "troff: too many number registers (%d).\n", NN);
191: done2(04);
192: }
193: return(p - r);
194: }
195:
196: usedr(i) /* returns -1 if nr i has never been used */
197: register int i;
198: {
199: register j;
200: register int *p;
201:
202: if (i == 0)
203: return(-1);
204: for (p = r; p < &r[NN]; p++) {
205: if (i == *p)
206: break;
207: }
208: if (p != &r[NN])
209: return(p - r);
210: else
211: return -1;
212: }
213:
214:
215: fnumb(i, f)
216: int i, (*f)();
217: {
218: register j;
219:
220: j = 0;
221: if (i < 0) {
222: j = (*f)('-' | nrbits);
223: i = -i;
224: }
225: switch (nform) {
226: default:
227: case '1':
228: case 0:
229: return(decml(i, f) + j);
230: case 'i':
231: case 'I':
232: return(roman(i, f) + j);
233: case 'a':
234: case 'A':
235: return(abc(i, f) + j);
236: }
237: }
238:
239:
240: decml(i, f)
241: int i, (*f)();
242: {
243: register j, k;
244:
245: k = 0;
246: nform--;
247: if ((j = i / 10) || (nform > 0))
248: k = decml(j, f);
249: return(k + (*f)((i % 10 + '0') | nrbits));
250: }
251:
252:
253: roman(i, f)
254: int i, (*f)();
255: {
256:
257: if (!i)
258: return((*f)('0' | nrbits));
259: if (nform == 'i')
260: return(roman0(i, f, "ixcmz", "vldw"));
261: else
262: return(roman0(i, f, "IXCMZ", "VLDW"));
263: }
264:
265:
266: roman0(i, f, onesp, fivesp)
267: int i, (*f)();
268: char *onesp, *fivesp;
269: {
270: register q, rem, k;
271:
272: k = 0;
273: if (!i)
274: return(0);
275: k = roman0(i / 10, f, onesp + 1, fivesp + 1);
276: q = (i = i % 10) / 5;
277: rem = i % 5;
278: if (rem == 4) {
279: k += (*f)(*onesp | nrbits);
280: if (q)
281: i = *(onesp + 1);
282: else
283: i = *fivesp;
284: return(k += (*f)(i | nrbits));
285: }
286: if (q)
287: k += (*f)(*fivesp | nrbits);
288: while (--rem >= 0)
289: k += (*f)(*onesp | nrbits);
290: return(k);
291: }
292:
293:
294: abc(i, f)
295: int i, (*f)();
296: {
297: if (!i)
298: return((*f)('0' | nrbits));
299: else
300: return(abc0(i - 1, f));
301: }
302:
303:
304: abc0(i, f)
305: int i, (*f)();
306: {
307: register j, k;
308:
309: k = 0;
310: if (j = i / 26)
311: k = abc0(j - 1, f);
312: return(k + (*f)((i % 26 + nform) | nrbits));
313: }
314:
315:
316: wrc(i)
317: tchar i;
318: {
319: if (cp >= &cbuf[NC])
320: return(0);
321: *cp++ = i;
322: return(1);
323: }
324:
325:
326: long atoi0()
327: {
328: register c, k, cnt;
329: tchar ii;
330: long i, acc;
331: extern long ckph();
332:
333: i = 0;
334: acc = 0;
335: nonumb = 0;
336: cnt = -1;
337: a0:
338: cnt++;
339: ii = getch();
340: c = cbits(ii);
341: switch (c) {
342: default:
343: ch = ii;
344: if (cnt)
345: break;
346: case '+':
347: i = ckph();
348: if (nonumb)
349: break;
350: acc += i;
351: goto a0;
352: case '-':
353: i = ckph();
354: if (nonumb)
355: break;
356: acc -= i;
357: goto a0;
358: case '*':
359: i = ckph();
360: if (nonumb)
361: break;
362: acc *= i;
363: goto a0;
364: case '/':
365: i = ckph();
366: if (nonumb)
367: break;
368: if (i == 0) {
369: flusho();
370: fprintf(stderr, "troff: divide by zero.\n");
371: acc = 0;
372: } else
373: acc /= i;
374: goto a0;
375: case '%':
376: i = ckph();
377: if (nonumb)
378: break;
379: acc %= i;
380: goto a0;
381: case '&': /*and*/
382: i = ckph();
383: if (nonumb)
384: break;
385: if ((acc > 0) && (i > 0))
386: acc = 1;
387: else
388: acc = 0;
389: goto a0;
390: case ':': /*or*/
391: i = ckph();
392: if (nonumb)
393: break;
394: if ((acc > 0) || (i > 0))
395: acc = 1;
396: else
397: acc = 0;
398: goto a0;
399: case '=':
400: if (cbits(ii = getch()) != '=')
401: ch = ii;
402: i = ckph();
403: if (nonumb) {
404: acc = 0;
405: break;
406: }
407: if (i == acc)
408: acc = 1;
409: else
410: acc = 0;
411: goto a0;
412: case '>':
413: k = 0;
414: if (cbits(ii = getch()) == '=')
415: k++;
416: else
417: ch = ii;
418: i = ckph();
419: if (nonumb) {
420: acc = 0;
421: break;
422: }
423: if (acc > (i - k))
424: acc = 1;
425: else
426: acc = 0;
427: goto a0;
428: case '<':
429: k = 0;
430: if (cbits(ii = getch()) == '=')
431: k++;
432: else
433: ch = ii;
434: i = ckph();
435: if (nonumb) {
436: acc = 0;
437: break;
438: }
439: if (acc < (i + k))
440: acc = 1;
441: else
442: acc = 0;
443: goto a0;
444: case ')':
445: break;
446: case '(':
447: acc = atoi0();
448: goto a0;
449: }
450: return(acc);
451: }
452:
453:
454: long ckph()
455: {
456: tchar i;
457: long j;
458: extern long atoi0();
459: extern long atoi1();
460:
461: if (cbits(i = getch()) == '(')
462: j = atoi0();
463: else {
464: ch = i;
465: j = atoi1();
466: }
467: return(j);
468: }
469:
470:
471: long atoi1()
472: {
473: register i, j, digits;
474: tchar ii;
475: long acc;
476: int neg, abs, field;
477:
478: neg = abs = field = digits = 0;
479: acc = 0;
480: a0:
481: ii = getch();
482: i = cbits(ii);
483: switch (i) {
484: default:
485: ch = ii;
486: break;
487: case '+':
488: goto a0;
489: case '-':
490: neg = 1;
491: goto a0;
492: case '|':
493: abs = 1 + neg;
494: neg = 0;
495: goto a0;
496: }
497: a1:
498: while (((j = (cbits(ii = getch())) - '0') >= 0) && (j <= 9)) {
499: field++;
500: digits++;
501: acc = 10 * acc + j;
502: }
503: if (cbits(ii) == '.') {
504: field++;
505: digits = 0;
506: goto a1;
507: }
508: ch = ii;
509: if (!field)
510: goto a2;
511: ii = getch();
512: switch (i = cbits(ii)) {
513: case 'u':
514: i = j = 1; /* should this be related to HOR?? */
515: break;
516: case 'v': /*VSs - vert spacing*/
517: j = lss;
518: i = 1;
519: break;
520: case 'm': /*Ems*/
521: j = EM;
522: i = 1;
523: break;
524: case 'n': /*Ens*/
525: j = EM;
526: #ifndef NROFF
527: i = 2;
528: #endif
529: #ifdef NROFF
530: i = 1; /*Same as Ems in NROFF*/
531: #endif
532: break;
533: case 'p': /*Points*/
534: j = INCH;
535: i = 72;
536: break;
537: case 'i': /*Inches*/
538: j = INCH;
539: i = 1;
540: break;
541: case 'c': /*Centimeters*/
542: /* if INCH is too big, this will overflow */
543: j = INCH * 50;
544: i = 127;
545: break;
546: case 'P': /*Picas*/
547: j = INCH;
548: i = 6;
549: break;
550: default:
551: j = dfact;
552: ch = ii;
553: i = dfactd;
554: }
555: if (neg)
556: acc = -acc;
557: if (!noscale) {
558: acc = (acc * j) / i;
559: }
560: if ((field != digits) && (digits > 0))
561: while (digits--)
562: acc /= 10;
563: if (abs) {
564: if (dip != d)
565: j = dip->dnl;
566: else
567: j = v.nl;
568: if (!vflag) {
569: j = v.hp = sumhp(); /* XXX */
570: }
571: if (abs == 2)
572: j = -j;
573: acc -= j;
574: }
575: a2:
576: nonumb = !field;
577: return(acc);
578: }
579:
580:
581: caserr()
582: {
583: register i, j;
584:
585: lgf++;
586: while (!skip() && (i = getrq()) ) {
587: for (j = NNAMES; j < NN; j++) { /*NNAMES predefined names*/
588: if (i == r[j])
589: break;
590: }
591: if (j != NN) {
592: r[j] = vlist[j] = inc[j] = fmt[j] = 0;
593: regcnt--;
594: }
595: }
596: }
597:
598:
599: casenr()
600: {
601: register i, j;
602:
603: lgf++;
604: skip();
605: if ((i = findr(getrq())) == -1)
606: goto rtn;
607: skip();
608: j = inumb(&vlist[i]);
609: if (nonumb)
610: goto rtn;
611: vlist[i] = j;
612: skip();
613: j = atoi();
614: if (nonumb)
615: goto rtn;
616: inc[i] = j;
617: rtn:
618: return;
619: }
620:
621:
622: caseaf()
623: {
624: register i, k;
625: tchar j;
626:
627: lgf++;
628: if (skip() || !(i = getrq()) || skip())
629: return;
630: k = 0;
631: j = getch();
632: if (!isalpha(cbits(j))) {
633: ch = j;
634: while ((j = cbits(getch())) >= '0' && j <= '9')
635: k++;
636: }
637: if (!k)
638: k = j;
639: fmt[findr(i)] = k & BMASK;
640: }
641:
642: setaf() /* return format of number register */
643: {
644: register int i, j;
645:
646: i = usedr(getsn());
647: if (i == -1)
648: return;
649: cp = cbuf;
650: if (fmt[i] > 20) /* it was probably a, A, i or I */
651: *cp++ = fmt[i];
652: else
653: for (j = (fmt[i] ? fmt[i] : 1); j; j--)
654: *cp++ = '0';
655: *cp = 0;
656: cp = cbuf;
657: }
658:
659:
660: vnumb(i)
661: int *i;
662: {
663: vflag++;
664: dfact = lss;
665: res = VERT;
666: return(inumb(i));
667: }
668:
669:
670: hnumb(i)
671: int *i;
672: {
673: dfact = EM;
674: res = HOR;
675: return(inumb(i));
676: }
677:
678:
679: inumb(n)
680: int *n;
681: {
682: register i, j, f;
683: tchar ii;
684:
685: f = 0;
686: if (n) {
687: if ((j = cbits(ii = getch())) == '+')
688: f = 1;
689: else if (j == '-')
690: f = -1;
691: else
692: ch = ii;
693: }
694: i = atoi();
695: if (n && f)
696: i = *n + f * i;
697: i = quant(i, res);
698: vflag = 0;
699: res = dfactd = dfact = 1;
700: if (nonumb)
701: i = 0;
702: return(i);
703: }
704:
705:
706: quant(n, m)
707: int n, m;
708: {
709: register i, neg;
710:
711: neg = 0;
712: if (n < 0) {
713: neg++;
714: n = -n;
715: }
716: /* better as i = ((n + (m/2))/m)*m */
717: i = n / m;
718: if ((n - m * i) > (m / 2))
719: i += 1;
720: i *= m;
721: if (neg)
722: i = -i;
723: return(i);
724: }
725:
726:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.