10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
70Sstevel@tonic-gate * with the License.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate * See the License for the specific language governing permissions
120Sstevel@tonic-gate * and limitations under the License.
130Sstevel@tonic-gate *
140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate *
200Sstevel@tonic-gate * CDDL HEADER END
210Sstevel@tonic-gate */
220Sstevel@tonic-gate /*
230Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
280Sstevel@tonic-gate /* All Rights Reserved */
290Sstevel@tonic-gate
300Sstevel@tonic-gate /*
310Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988
320Sstevel@tonic-gate * The Regents of the University of California
330Sstevel@tonic-gate * All Rights Reserved
340Sstevel@tonic-gate *
350Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from
360Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its
370Sstevel@tonic-gate * contributors.
380Sstevel@tonic-gate */
390Sstevel@tonic-gate
40*217Smuffin #pragma ident "%Z%%M% %I% %E% SMI"
41*217Smuffin
420Sstevel@tonic-gate #include <ctype.h>
430Sstevel@tonic-gate #include "tdef.h"
440Sstevel@tonic-gate #ifdef NROFF
450Sstevel@tonic-gate #include "tw.h"
460Sstevel@tonic-gate #endif
470Sstevel@tonic-gate #include "ext.h"
480Sstevel@tonic-gate /*
490Sstevel@tonic-gate * troff4.c
500Sstevel@tonic-gate *
510Sstevel@tonic-gate * number registers, conversion, arithmetic
520Sstevel@tonic-gate */
530Sstevel@tonic-gate
540Sstevel@tonic-gate
550Sstevel@tonic-gate int regcnt = NNAMES;
560Sstevel@tonic-gate int falsef = 0; /* on if inside false branch of if */
570Sstevel@tonic-gate #define NHASH(i) ((i>>6)^i)&0177
580Sstevel@tonic-gate struct numtab *nhash[128]; /* 128 == the 0177 on line above */
590Sstevel@tonic-gate
60*217Smuffin int
setn()610Sstevel@tonic-gate setn()
620Sstevel@tonic-gate {
63*217Smuffin int i, j;
64*217Smuffin tchar ii;
650Sstevel@tonic-gate int f;
660Sstevel@tonic-gate
670Sstevel@tonic-gate f = nform = 0;
680Sstevel@tonic-gate if ((i = cbits(ii = getach())) == '+')
690Sstevel@tonic-gate f = 1;
700Sstevel@tonic-gate else if (i == '-')
710Sstevel@tonic-gate f = -1;
720Sstevel@tonic-gate else
730Sstevel@tonic-gate ch = ii;
740Sstevel@tonic-gate if (falsef)
750Sstevel@tonic-gate f = 0;
760Sstevel@tonic-gate if ((i = getsn()) == 0)
77*217Smuffin return (0);
780Sstevel@tonic-gate if ((i & 0177) == '.')
790Sstevel@tonic-gate switch (i >> BYTE) {
800Sstevel@tonic-gate case 's':
810Sstevel@tonic-gate i = pts;
820Sstevel@tonic-gate break;
830Sstevel@tonic-gate case 'v':
840Sstevel@tonic-gate i = lss;
850Sstevel@tonic-gate break;
860Sstevel@tonic-gate case 'f':
870Sstevel@tonic-gate i = font;
880Sstevel@tonic-gate break;
890Sstevel@tonic-gate case 'p':
900Sstevel@tonic-gate i = pl;
910Sstevel@tonic-gate break;
920Sstevel@tonic-gate case 't':
930Sstevel@tonic-gate i = findt1();
940Sstevel@tonic-gate break;
950Sstevel@tonic-gate case 'o':
960Sstevel@tonic-gate i = po;
970Sstevel@tonic-gate break;
980Sstevel@tonic-gate case 'l':
990Sstevel@tonic-gate i = ll;
1000Sstevel@tonic-gate break;
1010Sstevel@tonic-gate case 'i':
1020Sstevel@tonic-gate i = in;
1030Sstevel@tonic-gate break;
1040Sstevel@tonic-gate case '$':
1050Sstevel@tonic-gate i = frame->nargs;
1060Sstevel@tonic-gate break;
1070Sstevel@tonic-gate case 'A':
1080Sstevel@tonic-gate i = ascii;
1090Sstevel@tonic-gate break;
1100Sstevel@tonic-gate case 'c':
1110Sstevel@tonic-gate i = numtab[CD].val;
1120Sstevel@tonic-gate break;
1130Sstevel@tonic-gate case 'n':
1140Sstevel@tonic-gate i = lastl;
1150Sstevel@tonic-gate break;
1160Sstevel@tonic-gate case 'a':
1170Sstevel@tonic-gate i = ralss;
1180Sstevel@tonic-gate break;
1190Sstevel@tonic-gate case 'h':
1200Sstevel@tonic-gate i = dip->hnl;
1210Sstevel@tonic-gate break;
1220Sstevel@tonic-gate case 'd':
1230Sstevel@tonic-gate if (dip != d)
1240Sstevel@tonic-gate i = dip->dnl;
1250Sstevel@tonic-gate else
1260Sstevel@tonic-gate i = numtab[NL].val;
1270Sstevel@tonic-gate break;
1280Sstevel@tonic-gate case 'u':
1290Sstevel@tonic-gate i = fi;
1300Sstevel@tonic-gate break;
1310Sstevel@tonic-gate case 'j':
1320Sstevel@tonic-gate i = ad + 2 * admod;
1330Sstevel@tonic-gate break;
1340Sstevel@tonic-gate case 'w':
1350Sstevel@tonic-gate i = widthp;
1360Sstevel@tonic-gate break;
1370Sstevel@tonic-gate case 'x':
1380Sstevel@tonic-gate i = nel;
1390Sstevel@tonic-gate break;
1400Sstevel@tonic-gate case 'y':
1410Sstevel@tonic-gate i = un;
1420Sstevel@tonic-gate break;
1430Sstevel@tonic-gate case 'T':
1440Sstevel@tonic-gate i = dotT;
1450Sstevel@tonic-gate break; /*-Tterm used in nroff*/
1460Sstevel@tonic-gate case 'V':
1470Sstevel@tonic-gate i = VERT;
1480Sstevel@tonic-gate break;
1490Sstevel@tonic-gate case 'H':
1500Sstevel@tonic-gate i = HOR;
1510Sstevel@tonic-gate break;
1520Sstevel@tonic-gate case 'k':
1530Sstevel@tonic-gate i = ne;
1540Sstevel@tonic-gate break;
1550Sstevel@tonic-gate case 'P':
1560Sstevel@tonic-gate i = print;
1570Sstevel@tonic-gate break;
1580Sstevel@tonic-gate case 'L':
1590Sstevel@tonic-gate i = ls;
1600Sstevel@tonic-gate break;
1610Sstevel@tonic-gate case 'R':
1620Sstevel@tonic-gate i = NN - regcnt;
1630Sstevel@tonic-gate break;
1640Sstevel@tonic-gate case 'z':
1650Sstevel@tonic-gate i = dip->curd;
1660Sstevel@tonic-gate *pbp++ = (i >> BYTE) & BYTEMASK;
1670Sstevel@tonic-gate *pbp++ = i & BYTEMASK;
168*217Smuffin return (0);
1690Sstevel@tonic-gate case 'b':
1700Sstevel@tonic-gate i = bdtab[font];
1710Sstevel@tonic-gate break;
1720Sstevel@tonic-gate case 'F':
1730Sstevel@tonic-gate cpushback(cfname[ifi]);
174*217Smuffin return (0);
1750Sstevel@tonic-gate
1760Sstevel@tonic-gate default:
1770Sstevel@tonic-gate goto s0;
1780Sstevel@tonic-gate }
1790Sstevel@tonic-gate else {
1800Sstevel@tonic-gate s0:
1810Sstevel@tonic-gate if ((j = findr(i)) == -1)
1820Sstevel@tonic-gate i = 0;
1830Sstevel@tonic-gate else {
1840Sstevel@tonic-gate i = numtab[j].val = (numtab[j].val+numtab[j].inc*f);
1850Sstevel@tonic-gate nform = numtab[j].fmt;
1860Sstevel@tonic-gate }
1870Sstevel@tonic-gate }
1880Sstevel@tonic-gate setn1(i, nform, (tchar) 0);
189*217Smuffin
190*217Smuffin return (0);
1910Sstevel@tonic-gate }
1920Sstevel@tonic-gate
1930Sstevel@tonic-gate tchar numbuf[17];
1940Sstevel@tonic-gate tchar *numbufp;
1950Sstevel@tonic-gate
196*217Smuffin int
wrc(i)1970Sstevel@tonic-gate wrc(i)
1980Sstevel@tonic-gate tchar i;
1990Sstevel@tonic-gate {
2000Sstevel@tonic-gate if (numbufp >= &numbuf[16])
2010Sstevel@tonic-gate return(0);
2020Sstevel@tonic-gate *numbufp++ = i;
2030Sstevel@tonic-gate return(1);
2040Sstevel@tonic-gate }
2050Sstevel@tonic-gate
2060Sstevel@tonic-gate
2070Sstevel@tonic-gate
2080Sstevel@tonic-gate /* insert into input number i, in format form, with size-font bits bits */
209*217Smuffin int
setn1(i,form,bits)2100Sstevel@tonic-gate setn1(i, form, bits)
2110Sstevel@tonic-gate int i;
2120Sstevel@tonic-gate tchar bits;
2130Sstevel@tonic-gate {
2140Sstevel@tonic-gate extern int wrc();
2150Sstevel@tonic-gate
2160Sstevel@tonic-gate numbufp = numbuf;
2170Sstevel@tonic-gate nrbits = bits;
2180Sstevel@tonic-gate nform = form;
2190Sstevel@tonic-gate fnumb(i, wrc);
2200Sstevel@tonic-gate *numbufp = 0;
2210Sstevel@tonic-gate pushback(numbuf);
222*217Smuffin
223*217Smuffin return (0);
2240Sstevel@tonic-gate }
2250Sstevel@tonic-gate
2260Sstevel@tonic-gate
227*217Smuffin int
nrehash()2280Sstevel@tonic-gate nrehash()
2290Sstevel@tonic-gate {
230*217Smuffin struct numtab *p;
231*217Smuffin int i;
2320Sstevel@tonic-gate
2330Sstevel@tonic-gate for (i=0; i<128; i++)
2340Sstevel@tonic-gate nhash[i] = 0;
2350Sstevel@tonic-gate for (p=numtab; p < &numtab[NN]; p++)
2360Sstevel@tonic-gate p->link = 0;
2370Sstevel@tonic-gate for (p=numtab; p < &numtab[NN]; p++) {
2380Sstevel@tonic-gate if (p->r == 0)
2390Sstevel@tonic-gate continue;
2400Sstevel@tonic-gate i = NHASH(p->r);
2410Sstevel@tonic-gate p->link = nhash[i];
2420Sstevel@tonic-gate nhash[i] = p;
2430Sstevel@tonic-gate }
244*217Smuffin
245*217Smuffin return (0);
2460Sstevel@tonic-gate }
2470Sstevel@tonic-gate
248*217Smuffin int
nunhash(rp)2490Sstevel@tonic-gate nunhash(rp)
250*217Smuffin struct numtab *rp;
2510Sstevel@tonic-gate {
252*217Smuffin struct numtab *p;
253*217Smuffin struct numtab **lp;
2540Sstevel@tonic-gate
2550Sstevel@tonic-gate if (rp->r == 0)
256*217Smuffin return (0);
2570Sstevel@tonic-gate lp = &nhash[NHASH(rp->r)];
2580Sstevel@tonic-gate p = *lp;
2590Sstevel@tonic-gate while (p) {
2600Sstevel@tonic-gate if (p == rp) {
2610Sstevel@tonic-gate *lp = p->link;
2620Sstevel@tonic-gate p->link = 0;
263*217Smuffin return (0);
2640Sstevel@tonic-gate }
2650Sstevel@tonic-gate lp = &p->link;
2660Sstevel@tonic-gate p = p->link;
2670Sstevel@tonic-gate }
268*217Smuffin return (0);
2690Sstevel@tonic-gate }
2700Sstevel@tonic-gate
271*217Smuffin int
findr(i)2720Sstevel@tonic-gate findr(i)
273*217Smuffin int i;
2740Sstevel@tonic-gate {
275*217Smuffin struct numtab *p;
276*217Smuffin int h = NHASH(i);
2770Sstevel@tonic-gate
2780Sstevel@tonic-gate if (i == 0)
2790Sstevel@tonic-gate return(-1);
2800Sstevel@tonic-gate for (p = nhash[h]; p; p = p->link)
2810Sstevel@tonic-gate if (i == p->r)
2820Sstevel@tonic-gate return(p - numtab);
2830Sstevel@tonic-gate for (p = numtab; p < &numtab[NN]; p++) {
2840Sstevel@tonic-gate if (p->r == 0) {
2850Sstevel@tonic-gate p->r = i;
2860Sstevel@tonic-gate p->link = nhash[h];
2870Sstevel@tonic-gate nhash[h] = p;
2880Sstevel@tonic-gate regcnt++;
2890Sstevel@tonic-gate return(p - numtab);
2900Sstevel@tonic-gate }
2910Sstevel@tonic-gate }
2920Sstevel@tonic-gate errprint(gettext("too many number registers (%d)."), NN);
2930Sstevel@tonic-gate done2(04);
2940Sstevel@tonic-gate /* NOTREACHED */
295*217Smuffin
296*217Smuffin return (0);
2970Sstevel@tonic-gate }
2980Sstevel@tonic-gate
299*217Smuffin int
usedr(i)3000Sstevel@tonic-gate usedr(i) /* returns -1 if nr i has never been used */
301*217Smuffin int i;
3020Sstevel@tonic-gate {
303*217Smuffin struct numtab *p;
3040Sstevel@tonic-gate
3050Sstevel@tonic-gate if (i == 0)
3060Sstevel@tonic-gate return(-1);
3070Sstevel@tonic-gate for (p = nhash[NHASH(i)]; p; p = p->link)
3080Sstevel@tonic-gate if (i == p->r)
3090Sstevel@tonic-gate return(p - numtab);
3100Sstevel@tonic-gate return -1;
3110Sstevel@tonic-gate }
3120Sstevel@tonic-gate
3130Sstevel@tonic-gate
314*217Smuffin int
3150Sstevel@tonic-gate fnumb(i, f)
316*217Smuffin int i, (*f)();
3170Sstevel@tonic-gate {
318*217Smuffin int j;
3190Sstevel@tonic-gate
3200Sstevel@tonic-gate j = 0;
3210Sstevel@tonic-gate if (i < 0) {
3220Sstevel@tonic-gate j = (*f)('-' | nrbits);
3230Sstevel@tonic-gate i = -i;
3240Sstevel@tonic-gate }
3250Sstevel@tonic-gate switch (nform) {
3260Sstevel@tonic-gate default:
3270Sstevel@tonic-gate case '1':
3280Sstevel@tonic-gate case 0:
3290Sstevel@tonic-gate return decml(i, f) + j;
3300Sstevel@tonic-gate break;
3310Sstevel@tonic-gate case 'i':
3320Sstevel@tonic-gate case 'I':
3330Sstevel@tonic-gate return roman(i, f) + j;
3340Sstevel@tonic-gate break;
3350Sstevel@tonic-gate case 'a':
3360Sstevel@tonic-gate case 'A':
3370Sstevel@tonic-gate return abc(i, f) + j;
3380Sstevel@tonic-gate break;
3390Sstevel@tonic-gate }
340*217Smuffin
341*217Smuffin return (0);
3420Sstevel@tonic-gate }
3430Sstevel@tonic-gate
3440Sstevel@tonic-gate
345*217Smuffin int
3460Sstevel@tonic-gate decml(i, f)
347*217Smuffin int i, (*f)();
3480Sstevel@tonic-gate {
349*217Smuffin int j, k;
3500Sstevel@tonic-gate
3510Sstevel@tonic-gate k = 0;
3520Sstevel@tonic-gate nform--;
3530Sstevel@tonic-gate if ((j = i / 10) || (nform > 0))
3540Sstevel@tonic-gate k = decml(j, f);
3550Sstevel@tonic-gate return(k + (*f)((i % 10 + '0') | nrbits));
3560Sstevel@tonic-gate }
3570Sstevel@tonic-gate
3580Sstevel@tonic-gate
359*217Smuffin int
3600Sstevel@tonic-gate roman(i, f)
3610Sstevel@tonic-gate int i, (*f)();
3620Sstevel@tonic-gate {
3630Sstevel@tonic-gate
3640Sstevel@tonic-gate if (!i)
3650Sstevel@tonic-gate return((*f)('0' | nrbits));
3660Sstevel@tonic-gate if (nform == 'i')
3670Sstevel@tonic-gate return(roman0(i, f, "ixcmz", "vldw"));
3680Sstevel@tonic-gate else
3690Sstevel@tonic-gate return(roman0(i, f, "IXCMZ", "VLDW"));
3700Sstevel@tonic-gate }
3710Sstevel@tonic-gate
3720Sstevel@tonic-gate
373*217Smuffin int
3740Sstevel@tonic-gate roman0(i, f, onesp, fivesp)
3750Sstevel@tonic-gate int i, (*f)();
3760Sstevel@tonic-gate char *onesp, *fivesp;
3770Sstevel@tonic-gate {
378*217Smuffin int q, rem, k;
3790Sstevel@tonic-gate
3800Sstevel@tonic-gate k = 0;
3810Sstevel@tonic-gate if (!i)
3820Sstevel@tonic-gate return(0);
3830Sstevel@tonic-gate k = roman0(i / 10, f, onesp + 1, fivesp + 1);
3840Sstevel@tonic-gate q = (i = i % 10) / 5;
3850Sstevel@tonic-gate rem = i % 5;
3860Sstevel@tonic-gate if (rem == 4) {
3870Sstevel@tonic-gate k += (*f)(*onesp | nrbits);
3880Sstevel@tonic-gate if (q)
3890Sstevel@tonic-gate i = *(onesp + 1);
3900Sstevel@tonic-gate else
3910Sstevel@tonic-gate i = *fivesp;
3920Sstevel@tonic-gate return(k += (*f)(i | nrbits));
3930Sstevel@tonic-gate }
3940Sstevel@tonic-gate if (q)
3950Sstevel@tonic-gate k += (*f)(*fivesp | nrbits);
3960Sstevel@tonic-gate while (--rem >= 0)
3970Sstevel@tonic-gate k += (*f)(*onesp | nrbits);
3980Sstevel@tonic-gate return(k);
3990Sstevel@tonic-gate }
4000Sstevel@tonic-gate
4010Sstevel@tonic-gate
402*217Smuffin int
4030Sstevel@tonic-gate abc(i, f)
4040Sstevel@tonic-gate int i, (*f)();
4050Sstevel@tonic-gate {
4060Sstevel@tonic-gate if (!i)
4070Sstevel@tonic-gate return((*f)('0' | nrbits));
4080Sstevel@tonic-gate else
4090Sstevel@tonic-gate return(abc0(i - 1, f));
4100Sstevel@tonic-gate }
4110Sstevel@tonic-gate
4120Sstevel@tonic-gate
413*217Smuffin int
4140Sstevel@tonic-gate abc0(i, f)
4150Sstevel@tonic-gate int i, (*f)();
4160Sstevel@tonic-gate {
417*217Smuffin int j, k;
4180Sstevel@tonic-gate
4190Sstevel@tonic-gate k = 0;
4200Sstevel@tonic-gate if (j = i / 26)
4210Sstevel@tonic-gate k = abc0(j - 1, f);
4220Sstevel@tonic-gate return(k + (*f)((i % 26 + nform) | nrbits));
4230Sstevel@tonic-gate }
4240Sstevel@tonic-gate
atoi0()4250Sstevel@tonic-gate long atoi0()
4260Sstevel@tonic-gate {
427*217Smuffin int c, k, cnt;
428*217Smuffin tchar ii;
4290Sstevel@tonic-gate long i, acc;
4300Sstevel@tonic-gate extern long ckph();
4310Sstevel@tonic-gate
4320Sstevel@tonic-gate i = 0;
4330Sstevel@tonic-gate acc = 0;
4340Sstevel@tonic-gate nonumb = 0;
4350Sstevel@tonic-gate cnt = -1;
4360Sstevel@tonic-gate a0:
4370Sstevel@tonic-gate cnt++;
4380Sstevel@tonic-gate ii = getch();
4390Sstevel@tonic-gate c = cbits(ii);
4400Sstevel@tonic-gate switch (c) {
4410Sstevel@tonic-gate default:
4420Sstevel@tonic-gate ch = ii;
4430Sstevel@tonic-gate if (cnt)
4440Sstevel@tonic-gate break;
4450Sstevel@tonic-gate case '+':
4460Sstevel@tonic-gate i = ckph();
4470Sstevel@tonic-gate if (nonumb)
4480Sstevel@tonic-gate break;
4490Sstevel@tonic-gate acc += i;
4500Sstevel@tonic-gate goto a0;
4510Sstevel@tonic-gate case '-':
4520Sstevel@tonic-gate i = ckph();
4530Sstevel@tonic-gate if (nonumb)
4540Sstevel@tonic-gate break;
4550Sstevel@tonic-gate acc -= i;
4560Sstevel@tonic-gate goto a0;
4570Sstevel@tonic-gate case '*':
4580Sstevel@tonic-gate i = ckph();
4590Sstevel@tonic-gate if (nonumb)
4600Sstevel@tonic-gate break;
4610Sstevel@tonic-gate acc *= i;
4620Sstevel@tonic-gate goto a0;
4630Sstevel@tonic-gate case '/':
4640Sstevel@tonic-gate i = ckph();
4650Sstevel@tonic-gate if (nonumb)
4660Sstevel@tonic-gate break;
4670Sstevel@tonic-gate if (i == 0) {
4680Sstevel@tonic-gate flusho();
4690Sstevel@tonic-gate errprint(gettext("divide by zero."));
4700Sstevel@tonic-gate acc = 0;
4710Sstevel@tonic-gate } else
4720Sstevel@tonic-gate acc /= i;
4730Sstevel@tonic-gate goto a0;
4740Sstevel@tonic-gate case '%':
4750Sstevel@tonic-gate i = ckph();
4760Sstevel@tonic-gate if (nonumb)
4770Sstevel@tonic-gate break;
4780Sstevel@tonic-gate acc %= i;
4790Sstevel@tonic-gate goto a0;
4800Sstevel@tonic-gate case '&': /*and*/
4810Sstevel@tonic-gate i = ckph();
4820Sstevel@tonic-gate if (nonumb)
4830Sstevel@tonic-gate break;
4840Sstevel@tonic-gate if ((acc > 0) && (i > 0))
4850Sstevel@tonic-gate acc = 1;
4860Sstevel@tonic-gate else
4870Sstevel@tonic-gate acc = 0;
4880Sstevel@tonic-gate goto a0;
4890Sstevel@tonic-gate case ':': /*or*/
4900Sstevel@tonic-gate i = ckph();
4910Sstevel@tonic-gate if (nonumb)
4920Sstevel@tonic-gate break;
4930Sstevel@tonic-gate if ((acc > 0) || (i > 0))
4940Sstevel@tonic-gate acc = 1;
4950Sstevel@tonic-gate else
4960Sstevel@tonic-gate acc = 0;
4970Sstevel@tonic-gate goto a0;
4980Sstevel@tonic-gate case '=':
4990Sstevel@tonic-gate if (cbits(ii = getch()) != '=')
5000Sstevel@tonic-gate ch = ii;
5010Sstevel@tonic-gate i = ckph();
5020Sstevel@tonic-gate if (nonumb) {
5030Sstevel@tonic-gate acc = 0;
5040Sstevel@tonic-gate break;
5050Sstevel@tonic-gate }
5060Sstevel@tonic-gate if (i == acc)
5070Sstevel@tonic-gate acc = 1;
5080Sstevel@tonic-gate else
5090Sstevel@tonic-gate acc = 0;
5100Sstevel@tonic-gate goto a0;
5110Sstevel@tonic-gate case '>':
5120Sstevel@tonic-gate k = 0;
5130Sstevel@tonic-gate if (cbits(ii = getch()) == '=')
5140Sstevel@tonic-gate k++;
5150Sstevel@tonic-gate else
5160Sstevel@tonic-gate ch = ii;
5170Sstevel@tonic-gate i = ckph();
5180Sstevel@tonic-gate if (nonumb) {
5190Sstevel@tonic-gate acc = 0;
5200Sstevel@tonic-gate break;
5210Sstevel@tonic-gate }
5220Sstevel@tonic-gate if (acc > (i - k))
5230Sstevel@tonic-gate acc = 1;
5240Sstevel@tonic-gate else
5250Sstevel@tonic-gate acc = 0;
5260Sstevel@tonic-gate goto a0;
5270Sstevel@tonic-gate case '<':
5280Sstevel@tonic-gate k = 0;
5290Sstevel@tonic-gate if (cbits(ii = getch()) == '=')
5300Sstevel@tonic-gate k++;
5310Sstevel@tonic-gate else
5320Sstevel@tonic-gate ch = ii;
5330Sstevel@tonic-gate i = ckph();
5340Sstevel@tonic-gate if (nonumb) {
5350Sstevel@tonic-gate acc = 0;
5360Sstevel@tonic-gate break;
5370Sstevel@tonic-gate }
5380Sstevel@tonic-gate if (acc < (i + k))
5390Sstevel@tonic-gate acc = 1;
5400Sstevel@tonic-gate else
5410Sstevel@tonic-gate acc = 0;
5420Sstevel@tonic-gate goto a0;
5430Sstevel@tonic-gate case ')':
5440Sstevel@tonic-gate break;
5450Sstevel@tonic-gate case '(':
5460Sstevel@tonic-gate acc = atoi0();
5470Sstevel@tonic-gate goto a0;
5480Sstevel@tonic-gate }
5490Sstevel@tonic-gate return(acc);
5500Sstevel@tonic-gate }
5510Sstevel@tonic-gate
5520Sstevel@tonic-gate
ckph()5530Sstevel@tonic-gate long ckph()
5540Sstevel@tonic-gate {
555*217Smuffin tchar i;
556*217Smuffin long j;
5570Sstevel@tonic-gate extern long atoi0();
5580Sstevel@tonic-gate extern long atoi1();
5590Sstevel@tonic-gate
5600Sstevel@tonic-gate if (cbits(i = getch()) == '(')
5610Sstevel@tonic-gate j = atoi0();
5620Sstevel@tonic-gate else {
5630Sstevel@tonic-gate j = atoi1(i);
5640Sstevel@tonic-gate }
5650Sstevel@tonic-gate return(j);
5660Sstevel@tonic-gate }
5670Sstevel@tonic-gate
5680Sstevel@tonic-gate
atoi1(ii)5690Sstevel@tonic-gate long atoi1(ii)
570*217Smuffin tchar ii;
5710Sstevel@tonic-gate {
572*217Smuffin int i, j, digits;
573*217Smuffin long acc;
5740Sstevel@tonic-gate int neg, abs, field;
5750Sstevel@tonic-gate
5760Sstevel@tonic-gate neg = abs = field = digits = 0;
5770Sstevel@tonic-gate acc = 0;
5780Sstevel@tonic-gate for (;;) {
5790Sstevel@tonic-gate i = cbits(ii);
5800Sstevel@tonic-gate switch (i) {
5810Sstevel@tonic-gate default:
5820Sstevel@tonic-gate break;
5830Sstevel@tonic-gate case '+':
5840Sstevel@tonic-gate ii = getch();
5850Sstevel@tonic-gate continue;
5860Sstevel@tonic-gate case '-':
5870Sstevel@tonic-gate neg = 1;
5880Sstevel@tonic-gate ii = getch();
5890Sstevel@tonic-gate continue;
5900Sstevel@tonic-gate case '|':
5910Sstevel@tonic-gate abs = 1 + neg;
5920Sstevel@tonic-gate neg = 0;
5930Sstevel@tonic-gate ii = getch();
5940Sstevel@tonic-gate continue;
5950Sstevel@tonic-gate }
5960Sstevel@tonic-gate break;
5970Sstevel@tonic-gate }
5980Sstevel@tonic-gate a1:
5990Sstevel@tonic-gate while (i >= '0' && i <= '9') {
6000Sstevel@tonic-gate field++;
6010Sstevel@tonic-gate digits++;
6020Sstevel@tonic-gate acc = 10 * acc + i - '0';
6030Sstevel@tonic-gate ii = getch();
6040Sstevel@tonic-gate i = cbits(ii);
6050Sstevel@tonic-gate }
6060Sstevel@tonic-gate if (i == '.') {
6070Sstevel@tonic-gate field++;
6080Sstevel@tonic-gate digits = 0;
6090Sstevel@tonic-gate ii = getch();
6100Sstevel@tonic-gate i = cbits(ii);
6110Sstevel@tonic-gate goto a1;
6120Sstevel@tonic-gate }
6130Sstevel@tonic-gate if (!field) {
6140Sstevel@tonic-gate ch = ii;
6150Sstevel@tonic-gate goto a2;
6160Sstevel@tonic-gate }
6170Sstevel@tonic-gate switch (i) {
6180Sstevel@tonic-gate case 'u':
6190Sstevel@tonic-gate i = j = 1; /* should this be related to HOR?? */
6200Sstevel@tonic-gate break;
6210Sstevel@tonic-gate case 'v': /*VSs - vert spacing*/
6220Sstevel@tonic-gate j = lss;
6230Sstevel@tonic-gate i = 1;
6240Sstevel@tonic-gate break;
6250Sstevel@tonic-gate case 'm': /*Ems*/
6260Sstevel@tonic-gate j = EM;
6270Sstevel@tonic-gate i = 1;
6280Sstevel@tonic-gate break;
6290Sstevel@tonic-gate case 'n': /*Ens*/
6300Sstevel@tonic-gate j = EM;
6310Sstevel@tonic-gate #ifndef NROFF
6320Sstevel@tonic-gate i = 2;
6330Sstevel@tonic-gate #endif
6340Sstevel@tonic-gate #ifdef NROFF
6350Sstevel@tonic-gate i = 1; /*Same as Ems in NROFF*/
6360Sstevel@tonic-gate #endif
6370Sstevel@tonic-gate break;
6380Sstevel@tonic-gate case 'p': /*Points*/
6390Sstevel@tonic-gate j = INCH;
6400Sstevel@tonic-gate i = 72;
6410Sstevel@tonic-gate break;
6420Sstevel@tonic-gate case 'i': /*Inches*/
6430Sstevel@tonic-gate j = INCH;
6440Sstevel@tonic-gate i = 1;
6450Sstevel@tonic-gate break;
6460Sstevel@tonic-gate case 'c': /*Centimeters*/
6470Sstevel@tonic-gate /* if INCH is too big, this will overflow */
6480Sstevel@tonic-gate j = INCH * 50;
6490Sstevel@tonic-gate i = 127;
6500Sstevel@tonic-gate break;
6510Sstevel@tonic-gate case 'P': /*Picas*/
6520Sstevel@tonic-gate j = INCH;
6530Sstevel@tonic-gate i = 6;
6540Sstevel@tonic-gate break;
6550Sstevel@tonic-gate default:
6560Sstevel@tonic-gate j = dfact;
6570Sstevel@tonic-gate ch = ii;
6580Sstevel@tonic-gate i = dfactd;
6590Sstevel@tonic-gate }
6600Sstevel@tonic-gate if (neg)
6610Sstevel@tonic-gate acc = -acc;
6620Sstevel@tonic-gate if (!noscale) {
6630Sstevel@tonic-gate acc = (acc * j) / i;
6640Sstevel@tonic-gate }
6650Sstevel@tonic-gate if ((field != digits) && (digits > 0))
6660Sstevel@tonic-gate while (digits--)
6670Sstevel@tonic-gate acc /= 10;
6680Sstevel@tonic-gate if (abs) {
6690Sstevel@tonic-gate if (dip != d)
6700Sstevel@tonic-gate j = dip->dnl;
6710Sstevel@tonic-gate else
6720Sstevel@tonic-gate j = numtab[NL].val;
6730Sstevel@tonic-gate if (!vflag) {
6740Sstevel@tonic-gate j = numtab[HP].val;
6750Sstevel@tonic-gate }
6760Sstevel@tonic-gate if (abs == 2)
6770Sstevel@tonic-gate j = -j;
6780Sstevel@tonic-gate acc -= j;
6790Sstevel@tonic-gate }
6800Sstevel@tonic-gate a2:
6810Sstevel@tonic-gate nonumb = !field;
6820Sstevel@tonic-gate return(acc);
6830Sstevel@tonic-gate }
6840Sstevel@tonic-gate
6850Sstevel@tonic-gate
686*217Smuffin int
caserr()6870Sstevel@tonic-gate caserr()
6880Sstevel@tonic-gate {
689*217Smuffin int i, j;
690*217Smuffin struct numtab *p;
6910Sstevel@tonic-gate
6920Sstevel@tonic-gate lgf++;
6930Sstevel@tonic-gate while (!skip() && (i = getrq()) ) {
6940Sstevel@tonic-gate j = usedr(i);
6950Sstevel@tonic-gate if (j < 0)
6960Sstevel@tonic-gate continue;
6970Sstevel@tonic-gate p = &numtab[j];
6980Sstevel@tonic-gate nunhash(p);
6990Sstevel@tonic-gate p->r = p->val = p->inc = p->fmt = 0;
7000Sstevel@tonic-gate regcnt--;
7010Sstevel@tonic-gate }
702*217Smuffin
703*217Smuffin return (0);
7040Sstevel@tonic-gate }
7050Sstevel@tonic-gate
7060Sstevel@tonic-gate
707*217Smuffin int
casenr()7080Sstevel@tonic-gate casenr()
7090Sstevel@tonic-gate {
710*217Smuffin int i, j;
7110Sstevel@tonic-gate
7120Sstevel@tonic-gate lgf++;
7130Sstevel@tonic-gate skip();
7140Sstevel@tonic-gate if ((i = findr(getrq())) == -1)
7150Sstevel@tonic-gate goto rtn;
7160Sstevel@tonic-gate skip();
7170Sstevel@tonic-gate j = inumb(&numtab[i].val);
7180Sstevel@tonic-gate if (nonumb)
7190Sstevel@tonic-gate goto rtn;
7200Sstevel@tonic-gate numtab[i].val = j;
7210Sstevel@tonic-gate skip();
7220Sstevel@tonic-gate j = atoi();
7230Sstevel@tonic-gate if (nonumb)
7240Sstevel@tonic-gate goto rtn;
7250Sstevel@tonic-gate numtab[i].inc = j;
7260Sstevel@tonic-gate rtn:
727*217Smuffin return (0);
7280Sstevel@tonic-gate }
7290Sstevel@tonic-gate
7300Sstevel@tonic-gate
731*217Smuffin int
caseaf()7320Sstevel@tonic-gate caseaf()
7330Sstevel@tonic-gate {
734*217Smuffin int i, k;
735*217Smuffin tchar j, jj;
7360Sstevel@tonic-gate
7370Sstevel@tonic-gate lgf++;
7380Sstevel@tonic-gate if (skip() || !(i = getrq()) || skip())
739*217Smuffin return (0);
7400Sstevel@tonic-gate k = 0;
7410Sstevel@tonic-gate j = getch();
7420Sstevel@tonic-gate if (!ischar(jj = cbits(j)) || !isalpha(jj)) {
7430Sstevel@tonic-gate ch = j;
7440Sstevel@tonic-gate while ((j = cbits(getch())) >= '0' && j <= '9')
7450Sstevel@tonic-gate k++;
7460Sstevel@tonic-gate }
7470Sstevel@tonic-gate if (!k)
7480Sstevel@tonic-gate k = j;
7490Sstevel@tonic-gate numtab[findr(i)].fmt = k & BYTEMASK;
750*217Smuffin
751*217Smuffin return (0);
7520Sstevel@tonic-gate }
7530Sstevel@tonic-gate
754*217Smuffin int
setaf()7550Sstevel@tonic-gate setaf() /* return format of number register */
7560Sstevel@tonic-gate {
757*217Smuffin int i, j;
7580Sstevel@tonic-gate
7590Sstevel@tonic-gate i = usedr(getsn());
7600Sstevel@tonic-gate if (i == -1)
761*217Smuffin return (0);
7620Sstevel@tonic-gate if (numtab[i].fmt > 20) /* it was probably a, A, i or I */
7630Sstevel@tonic-gate *pbp++ = numtab[i].fmt;
7640Sstevel@tonic-gate else
7650Sstevel@tonic-gate for (j = (numtab[i].fmt ? numtab[i].fmt : 1); j; j--)
7660Sstevel@tonic-gate *pbp++ = '0';
767*217Smuffin
768*217Smuffin return (0);
7690Sstevel@tonic-gate }
7700Sstevel@tonic-gate
7710Sstevel@tonic-gate
772*217Smuffin int
vnumb(i)7730Sstevel@tonic-gate vnumb(i)
7740Sstevel@tonic-gate int *i;
7750Sstevel@tonic-gate {
7760Sstevel@tonic-gate vflag++;
7770Sstevel@tonic-gate dfact = lss;
7780Sstevel@tonic-gate res = VERT;
7790Sstevel@tonic-gate return(inumb(i));
7800Sstevel@tonic-gate }
7810Sstevel@tonic-gate
7820Sstevel@tonic-gate
783*217Smuffin int
hnumb(i)7840Sstevel@tonic-gate hnumb(i)
7850Sstevel@tonic-gate int *i;
7860Sstevel@tonic-gate {
7870Sstevel@tonic-gate dfact = EM;
7880Sstevel@tonic-gate res = HOR;
7890Sstevel@tonic-gate return(inumb(i));
7900Sstevel@tonic-gate }
7910Sstevel@tonic-gate
7920Sstevel@tonic-gate
793*217Smuffin int
inumb(n)7940Sstevel@tonic-gate inumb(n)
7950Sstevel@tonic-gate int *n;
7960Sstevel@tonic-gate {
797*217Smuffin int i, j, f;
798*217Smuffin tchar ii;
7990Sstevel@tonic-gate
8000Sstevel@tonic-gate f = 0;
8010Sstevel@tonic-gate if (n) {
8020Sstevel@tonic-gate if ((j = cbits(ii = getch())) == '+')
8030Sstevel@tonic-gate f = 1;
8040Sstevel@tonic-gate else if (j == '-')
8050Sstevel@tonic-gate f = -1;
8060Sstevel@tonic-gate else
8070Sstevel@tonic-gate ch = ii;
8080Sstevel@tonic-gate }
8090Sstevel@tonic-gate i = atoi();
8100Sstevel@tonic-gate if (n && f)
8110Sstevel@tonic-gate i = *n + f * i;
8120Sstevel@tonic-gate i = quant(i, res);
8130Sstevel@tonic-gate vflag = 0;
8140Sstevel@tonic-gate res = dfactd = dfact = 1;
8150Sstevel@tonic-gate if (nonumb)
8160Sstevel@tonic-gate i = 0;
8170Sstevel@tonic-gate return(i);
8180Sstevel@tonic-gate }
8190Sstevel@tonic-gate
8200Sstevel@tonic-gate
821*217Smuffin int
quant(n,m)8220Sstevel@tonic-gate quant(n, m)
8230Sstevel@tonic-gate int n, m;
8240Sstevel@tonic-gate {
825*217Smuffin int i, neg;
8260Sstevel@tonic-gate
8270Sstevel@tonic-gate neg = 0;
8280Sstevel@tonic-gate if (n < 0) {
8290Sstevel@tonic-gate neg++;
8300Sstevel@tonic-gate n = -n;
8310Sstevel@tonic-gate }
8320Sstevel@tonic-gate /* better as i = ((n + (m/2))/m)*m */
8330Sstevel@tonic-gate i = n / m;
8340Sstevel@tonic-gate if ((n - m * i) > (m / 2))
8350Sstevel@tonic-gate i += 1;
8360Sstevel@tonic-gate i *= m;
8370Sstevel@tonic-gate if (neg)
8380Sstevel@tonic-gate i = -i;
8390Sstevel@tonic-gate return(i);
8400Sstevel@tonic-gate }
8410Sstevel@tonic-gate
8420Sstevel@tonic-gate
843