date and time created 85/07/17 17:54:30 by jaap
authorJaap Akkerhuis <jaap@ucbvax.Berkeley.EDU>
Thu, 18 Jul 1985 08:54:30 +0000 (00:54 -0800)
committerJaap Akkerhuis <jaap@ucbvax.Berkeley.EDU>
Thu, 18 Jul 1985 08:54:30 +0000 (00:54 -0800)
SCCS-vsn: local/ditroff/ditroff.okeeffe/n4.c 1.1
SCCS-vsn: local/ditroff/ditroff.okeeffe/troff/n4.c 1.1

usr/src/local/ditroff/ditroff.okeeffe/n4.c [new file with mode: 0644]
usr/src/local/ditroff/ditroff.okeeffe/troff/n4.c [new file with mode: 0644]

diff --git a/usr/src/local/ditroff/ditroff.okeeffe/n4.c b/usr/src/local/ditroff/ditroff.okeeffe/n4.c
new file mode 100644 (file)
index 0000000..9e5b942
--- /dev/null
@@ -0,0 +1,736 @@
+#ifndef lint
+static char sccsid[] = "@(#)n4.c       1.1 (CWI) 85/07/17";
+#endif lint
+
+#include       <ctype.h>
+#include "tdef.h"
+extern
+#include "d.h"
+extern
+#include "v.h"
+#ifdef NROFF
+extern
+#include "tw.h"
+#endif
+#include "s.h"
+/*
+troff4.c
+
+number registers, conversion, arithmetic
+*/
+
+#include <sgtty.h>
+#include "ext.h"
+
+int    regcnt = NNAMES;
+int    falsef  = 0;    /* on if inside false branch of if */
+
+setn()
+{
+       register i, j;
+       tchar ii;
+       int     f;
+
+       f = nform = 0;
+       if ((i = cbits(ii = getach())) == '+')
+               f = 1;
+       else if (i == '-')
+               f = -1;
+       else 
+               ch = ii;
+       if (falsef)
+               f = 0;
+       if ((i = getsn()) == 0)
+               return;
+       if ((i & 0177) == '.')
+               switch (i >> BYTE) {
+               case 's': 
+                       i = pts;        
+                       break;
+               case 'v': 
+                       i = lss;                
+                       break;
+               case 'f': 
+                       i = font;       
+                       break;
+               case 'p': 
+                       i = pl;         
+                       break;
+               case 't':  
+                       i = findt1();   
+                       break;
+               case 'o': 
+                       i = po;         
+                       break;
+               case 'l': 
+                       i = ll;         
+                       break;
+               case 'i': 
+                       i = in;         
+                       break;
+               case '$': 
+                       i = frame->nargs;               
+                       break;
+               case 'A': 
+                       i = ascii;              
+                       break;
+               case 'c': 
+                       i = v.cd;               
+                       break;
+               case 'n': 
+                       i = lastl;              
+                       break;
+               case 'a': 
+                       i = ralss;              
+                       break;
+               case 'h': 
+                       i = dip->hnl;   
+                       break;
+               case 'd':
+                       if (dip != d)
+                               i = dip->dnl; 
+                       else 
+                               i = v.nl;
+                       break;
+               case 'u': 
+                       i = fi;         
+                       break;
+               case 'j': 
+                       i = ad + 2 * admod;     
+                       break;
+               case 'w': 
+                       i = width(*(pinchar-1));        /* XXX */
+                       break;
+               case 'x': 
+                       i = nel;        
+                       break;
+               case 'y': 
+                       i = un;         
+                       break;
+               case 'T': 
+                       i = dotT;               
+                       break; /*-Tterm used in nroff*/
+               case 'V': 
+                       i = VERT;               
+                       break;
+               case 'H': 
+                       i = HOR;                
+                       break;
+               case 'k': 
+                       i = ne;         
+                       break;
+               case 'P': 
+                       i = print;              
+                       break;
+               case 'L': 
+                       i = ls;         
+                       break;
+               case 'R': 
+                       i = NN - regcnt;        
+                       break;
+               case 'z': 
+                       i = dip->curd;
+                       cbuf[0] = i & BMASK;
+                       cbuf[1] = (i >> BYTE) & BMASK;
+                       cbuf[2] = 0;
+                       cp = cbuf;
+                       return;
+               case 'b': 
+                       i = bdtab[font];
+                       break;
+               case 'D':               /* Dialect, hyphenation algoritm jna */
+                       i = hyalg;
+                       break;
+               case 'e':
+                       i = thresh;
+                       break;
+
+               default:
+                       goto s0;
+               }
+       else {
+s0:
+               if ((j = findr(i)) == -1)
+                       i = 0;
+               else {
+                       i = (vlist[j] = (vlist[j] + inc[j] * f));
+                       nform = fmt[j];
+               }
+       }
+       setn1(i);
+       cp = cbuf;
+}
+
+
+setn1(i)
+int    i;
+{
+       extern int      wrc();
+
+       cp = cbuf;
+       nrbits = 0;
+       fnumb(i, wrc);
+       *cp = 0;
+       cp = cbuf;
+}
+
+
+findr(i)
+register int   i;
+{
+       register j;
+       register int *p;
+
+       if (i == 0)
+               return(-1);
+       for (p = r; p < &r[NN]; p++) {
+               if (i == *p)
+                       break;
+       }
+       if (p != &r[NN])
+               return(p - r);
+       for (p = r; p < &r[NN]; p++) {
+               if (*p == 0) {
+                       *p = i;
+                       regcnt++;
+                       break;
+               }
+       }
+       if (p == &r[NN]) {
+               fprintf(stderr, "troff: too many number registers (%d).\n", NN);
+               done2(04); 
+       }
+       return(p - r);
+}
+
+usedr(i)       /* returns -1 if nr i has never been used */
+register int   i;
+{
+       register j;
+       register int *p;
+
+       if (i == 0)
+               return(-1);
+       for (p = r; p < &r[NN]; p++) {
+               if (i == *p)
+                       break;
+       }
+       if (p != &r[NN])
+               return(p - r);
+       else
+               return -1;
+}
+
+
+fnumb(i, f)
+int    i, (*f)();
+{
+       register j;
+
+       j = 0;
+       if (i < 0) {
+               j = (*f)('-' | nrbits);
+               i = -i;
+       }
+       switch (nform) {
+       default:
+       case '1':
+       case 0: 
+               return(decml(i, f) + j);
+       case 'i':
+       case 'I': 
+               return(roman(i, f) + j);
+       case 'a':
+       case 'A': 
+               return(abc(i, f) + j);
+       }
+}
+
+
+decml(i, f)
+int    i, (*f)();
+{
+       register j, k;
+
+       k = 0;
+       nform--;
+       if ((j = i / 10) || (nform > 0))
+               k = decml(j, f);
+       return(k + (*f)((i % 10 + '0') | nrbits));
+}
+
+
+roman(i, f)
+int    i, (*f)();
+{
+
+       if (!i)
+               return((*f)('0' | nrbits));
+       if (nform == 'i')
+               return(roman0(i, f, "ixcmz", "vldw"));
+       else 
+               return(roman0(i, f, "IXCMZ", "VLDW"));
+}
+
+
+roman0(i, f, onesp, fivesp)
+int    i, (*f)();
+char   *onesp, *fivesp;
+{
+       register q, rem, k;
+
+       k = 0;
+       if (!i)
+               return(0);
+       k = roman0(i / 10, f, onesp + 1, fivesp + 1);
+       q = (i = i % 10) / 5;
+       rem = i % 5;
+       if (rem == 4) {
+               k += (*f)(*onesp | nrbits);
+               if (q)
+                       i = *(onesp + 1);
+               else 
+                       i = *fivesp;
+               return(k += (*f)(i | nrbits));
+       }
+       if (q)
+               k += (*f)(*fivesp | nrbits);
+       while (--rem >= 0)
+               k += (*f)(*onesp | nrbits);
+       return(k);
+}
+
+
+abc(i, f)
+int    i, (*f)();
+{
+       if (!i)
+               return((*f)('0' | nrbits));
+       else 
+               return(abc0(i - 1, f));
+}
+
+
+abc0(i, f)
+int    i, (*f)();
+{
+       register j, k;
+
+       k = 0;
+       if (j = i / 26)
+               k = abc0(j - 1, f);
+       return(k + (*f)((i % 26 + nform) | nrbits));
+}
+
+
+wrc(i)
+tchar i;
+{
+       if (cp >= &cbuf[NC])
+               return(0);
+       *cp++ = i;
+       return(1);
+}
+
+
+long   atoi0()
+{
+       register c, k, cnt;
+       tchar ii;
+       long    i, acc;
+       extern long     ckph();
+
+       i = 0; 
+       acc = 0;
+       nonumb = 0;
+       cnt = -1;
+a0:
+       cnt++;
+       ii = getch();
+       c = cbits(ii);
+       switch (c) {
+       default:
+               ch = ii;
+               if (cnt)
+                       break;
+       case '+':
+               i = ckph();
+               if (nonumb)
+                       break;
+               acc += i;
+               goto a0;
+       case '-':
+               i = ckph();
+               if (nonumb)
+                       break;
+               acc -= i;
+               goto a0;
+       case '*':
+               i = ckph();
+               if (nonumb)
+                       break;
+               acc *= i;
+               goto a0;
+       case '/':
+               i = ckph();
+               if (nonumb)
+                       break;
+               if (i == 0) {
+                       flusho();
+                       fprintf(stderr, "troff: divide by zero.\n");
+                       acc = 0;
+               } else 
+                       acc /= i;
+               goto a0;
+       case '%':
+               i = ckph();
+               if (nonumb)
+                       break;
+               acc %= i;
+               goto a0;
+       case '&':       /*and*/
+               i = ckph();
+               if (nonumb)
+                       break;
+               if ((acc > 0) && (i > 0))
+                       acc = 1; 
+               else 
+                       acc = 0;
+               goto a0;
+       case ':':       /*or*/
+               i = ckph();
+               if (nonumb)
+                       break;
+               if ((acc > 0) || (i > 0))
+                       acc = 1; 
+               else 
+                       acc = 0;
+               goto a0;
+       case '=':
+               if (cbits(ii = getch()) != '=')
+                       ch = ii;
+               i = ckph();
+               if (nonumb) {
+                       acc = 0; 
+                       break;
+               }
+               if (i == acc)
+                       acc = 1;
+               else 
+                       acc = 0;
+               goto a0;
+       case '>':
+               k = 0;
+               if (cbits(ii = getch()) == '=')
+                       k++; 
+               else 
+                       ch = ii;
+               i = ckph();
+               if (nonumb) {
+                       acc = 0; 
+                       break;
+               }
+               if (acc > (i - k))
+                       acc = 1; 
+               else 
+                       acc = 0;
+               goto a0;
+       case '<':
+               k = 0;
+               if (cbits(ii = getch()) == '=')
+                       k++; 
+               else 
+                       ch = ii;
+               i = ckph();
+               if (nonumb) {
+                       acc = 0; 
+                       break;
+               }
+               if (acc < (i + k))
+                       acc = 1; 
+               else 
+                       acc = 0;
+               goto a0;
+       case ')': 
+               break;
+       case '(':
+               acc = atoi0();
+               goto a0;
+       }
+       return(acc);
+}
+
+
+long   ckph()
+{
+       tchar i;
+       long    j;
+       extern long     atoi0();
+       extern long     atoi1();
+
+       if (cbits(i = getch()) == '(')
+               j = atoi0();
+       else {
+               ch = i;
+               j = atoi1();
+       }
+       return(j);
+}
+
+
+long   atoi1()
+{
+       register i, j, digits;
+       tchar ii;
+       long    acc;
+       int     neg, abs, field;
+
+       neg = abs = field = digits = 0;
+       acc = 0;
+a0:
+       ii = getch();
+       i = cbits(ii);
+       switch (i) {
+       default:
+               ch = ii;
+               break;
+       case '+':
+               goto a0;
+       case '-':
+               neg = 1;
+               goto a0;
+       case '|':
+               abs = 1 + neg;
+               neg = 0;
+               goto a0;
+       }
+a1:
+       while (((j = (cbits(ii = getch())) - '0') >= 0) && (j <= 9)) {
+               field++;
+               digits++;
+               acc = 10 * acc + j;
+       }
+       if (cbits(ii) == '.') {
+               field++;
+               digits = 0;
+               goto a1;
+       }
+       ch = ii;
+       if (!field)
+               goto a2;
+       ii = getch();
+       switch (i = cbits(ii)) {
+       case 'u':
+               i = j = 1;      /* should this be related to HOR?? */
+               break;
+       case 'v':       /*VSs - vert spacing*/
+               j = lss;
+               i = 1;
+               break;
+       case 'm':       /*Ems*/
+               j = EM;
+               i = 1;
+               break;
+       case 'n':       /*Ens*/
+               j = EM;
+#ifndef NROFF
+               i = 2;
+#endif
+#ifdef NROFF
+               i = 1;  /*Same as Ems in NROFF*/
+#endif
+               break;
+       case 'p':       /*Points*/
+               j = INCH;
+               i = 72;
+               break;
+       case 'i':       /*Inches*/
+               j = INCH;
+               i = 1;
+               break;
+       case 'c':       /*Centimeters*/
+               /* if INCH is too big, this will overflow */
+               j = INCH * 50;
+               i = 127;
+               break;
+       case 'P':       /*Picas*/
+               j = INCH;
+               i = 6;
+               break;
+       default:
+               j = dfact;
+               ch = ii;
+               i = dfactd;
+       }
+       if (neg) 
+               acc = -acc;
+       if (!noscale) {
+               acc = (acc * j) / i;
+       }
+       if ((field != digits) && (digits > 0))
+               while (digits--)
+                       acc /= 10;
+       if (abs) {
+               if (dip != d)
+                       j = dip->dnl; 
+               else 
+                       j = v.nl;
+               if (!vflag) {
+                       j = v.hp = sumhp();     /* XXX */
+               }
+               if (abs == 2)
+                       j = -j;
+               acc -= j;
+       }
+a2:
+       nonumb = !field;
+       return(acc);
+}
+
+
+caserr()
+{
+       register i, j;
+
+       lgf++;
+       while (!skip() && (i = getrq()) ) {
+               for (j = NNAMES; j < NN; j++) {  /*NNAMES predefined names*/
+                       if (i == r[j])
+                               break;
+               }
+               if (j != NN) {
+                       r[j] = vlist[j] = inc[j] = fmt[j] = 0;
+                       regcnt--;
+               }
+       }
+}
+
+
+casenr()
+{
+       register i, j;
+
+       lgf++;
+       skip();
+       if ((i = findr(getrq())) == -1)
+               goto rtn;
+       skip();
+       j = inumb(&vlist[i]);
+       if (nonumb)
+               goto rtn;
+       vlist[i] = j;
+       skip();
+       j = atoi();
+       if (nonumb)
+               goto rtn;
+       inc[i] = j;
+rtn:
+       return;
+}
+
+
+caseaf()
+{
+       register i, k;
+       tchar j;
+
+       lgf++;
+       if (skip() || !(i = getrq()) || skip())
+               return;
+       k = 0;
+       j = getch();
+       if (!isalpha(cbits(j))) {
+               ch = j;
+               while ((j = cbits(getch())) >= '0' &&  j <= '9')
+                       k++;
+       }
+       if (!k)
+               k = j;
+       fmt[findr(i)] = k & BMASK;
+}
+
+setaf()        /* return format of number register */
+{
+       register int i, j;
+
+       i = usedr(getsn());
+       if (i == -1)
+               return;
+       cp = cbuf;
+       if (fmt[i] > 20)        /* it was probably a, A, i or I */
+               *cp++ = fmt[i];
+       else
+               for (j = (fmt[i] ? fmt[i] : 1); j; j--)
+                       *cp++ = '0';
+       *cp = 0;
+       cp = cbuf;
+}
+
+
+vnumb(i)
+int    *i;
+{
+       vflag++;
+       dfact = lss;
+       res = VERT;
+       return(inumb(i));
+}
+
+
+hnumb(i)
+int    *i;
+{
+       dfact = EM;
+       res = HOR;
+       return(inumb(i));
+}
+
+
+inumb(n)
+int    *n;
+{
+       register i, j, f;
+       tchar ii;
+
+       f = 0;
+       if (n) {
+               if ((j = cbits(ii = getch())) == '+')
+                       f = 1;
+               else if (j == '-')
+                       f = -1;
+               else 
+                       ch = ii;
+       }
+       i = atoi();
+       if (n && f)
+               i = *n + f * i;
+       i = quant(i, res);
+       vflag = 0;
+       res = dfactd = dfact = 1;
+       if (nonumb)
+               i = 0;
+       return(i);
+}
+
+
+quant(n, m)
+int    n, m;
+{
+       register i, neg;
+
+       neg = 0;
+       if (n < 0) {
+               neg++;
+               n = -n;
+       }
+       /* better as i = ((n + (m/2))/m)*m */
+       i = n / m;
+       if ((n - m * i) > (m / 2))
+               i += 1;
+       i *= m;
+       if (neg)
+               i = -i;
+       return(i);
+}
+
+
diff --git a/usr/src/local/ditroff/ditroff.okeeffe/troff/n4.c b/usr/src/local/ditroff/ditroff.okeeffe/troff/n4.c
new file mode 100644 (file)
index 0000000..9e5b942
--- /dev/null
@@ -0,0 +1,736 @@
+#ifndef lint
+static char sccsid[] = "@(#)n4.c       1.1 (CWI) 85/07/17";
+#endif lint
+
+#include       <ctype.h>
+#include "tdef.h"
+extern
+#include "d.h"
+extern
+#include "v.h"
+#ifdef NROFF
+extern
+#include "tw.h"
+#endif
+#include "s.h"
+/*
+troff4.c
+
+number registers, conversion, arithmetic
+*/
+
+#include <sgtty.h>
+#include "ext.h"
+
+int    regcnt = NNAMES;
+int    falsef  = 0;    /* on if inside false branch of if */
+
+setn()
+{
+       register i, j;
+       tchar ii;
+       int     f;
+
+       f = nform = 0;
+       if ((i = cbits(ii = getach())) == '+')
+               f = 1;
+       else if (i == '-')
+               f = -1;
+       else 
+               ch = ii;
+       if (falsef)
+               f = 0;
+       if ((i = getsn()) == 0)
+               return;
+       if ((i & 0177) == '.')
+               switch (i >> BYTE) {
+               case 's': 
+                       i = pts;        
+                       break;
+               case 'v': 
+                       i = lss;                
+                       break;
+               case 'f': 
+                       i = font;       
+                       break;
+               case 'p': 
+                       i = pl;         
+                       break;
+               case 't':  
+                       i = findt1();   
+                       break;
+               case 'o': 
+                       i = po;         
+                       break;
+               case 'l': 
+                       i = ll;         
+                       break;
+               case 'i': 
+                       i = in;         
+                       break;
+               case '$': 
+                       i = frame->nargs;               
+                       break;
+               case 'A': 
+                       i = ascii;              
+                       break;
+               case 'c': 
+                       i = v.cd;               
+                       break;
+               case 'n': 
+                       i = lastl;              
+                       break;
+               case 'a': 
+                       i = ralss;              
+                       break;
+               case 'h': 
+                       i = dip->hnl;   
+                       break;
+               case 'd':
+                       if (dip != d)
+                               i = dip->dnl; 
+                       else 
+                               i = v.nl;
+                       break;
+               case 'u': 
+                       i = fi;         
+                       break;
+               case 'j': 
+                       i = ad + 2 * admod;     
+                       break;
+               case 'w': 
+                       i = width(*(pinchar-1));        /* XXX */
+                       break;
+               case 'x': 
+                       i = nel;        
+                       break;
+               case 'y': 
+                       i = un;         
+                       break;
+               case 'T': 
+                       i = dotT;               
+                       break; /*-Tterm used in nroff*/
+               case 'V': 
+                       i = VERT;               
+                       break;
+               case 'H': 
+                       i = HOR;                
+                       break;
+               case 'k': 
+                       i = ne;         
+                       break;
+               case 'P': 
+                       i = print;              
+                       break;
+               case 'L': 
+                       i = ls;         
+                       break;
+               case 'R': 
+                       i = NN - regcnt;        
+                       break;
+               case 'z': 
+                       i = dip->curd;
+                       cbuf[0] = i & BMASK;
+                       cbuf[1] = (i >> BYTE) & BMASK;
+                       cbuf[2] = 0;
+                       cp = cbuf;
+                       return;
+               case 'b': 
+                       i = bdtab[font];
+                       break;
+               case 'D':               /* Dialect, hyphenation algoritm jna */
+                       i = hyalg;
+                       break;
+               case 'e':
+                       i = thresh;
+                       break;
+
+               default:
+                       goto s0;
+               }
+       else {
+s0:
+               if ((j = findr(i)) == -1)
+                       i = 0;
+               else {
+                       i = (vlist[j] = (vlist[j] + inc[j] * f));
+                       nform = fmt[j];
+               }
+       }
+       setn1(i);
+       cp = cbuf;
+}
+
+
+setn1(i)
+int    i;
+{
+       extern int      wrc();
+
+       cp = cbuf;
+       nrbits = 0;
+       fnumb(i, wrc);
+       *cp = 0;
+       cp = cbuf;
+}
+
+
+findr(i)
+register int   i;
+{
+       register j;
+       register int *p;
+
+       if (i == 0)
+               return(-1);
+       for (p = r; p < &r[NN]; p++) {
+               if (i == *p)
+                       break;
+       }
+       if (p != &r[NN])
+               return(p - r);
+       for (p = r; p < &r[NN]; p++) {
+               if (*p == 0) {
+                       *p = i;
+                       regcnt++;
+                       break;
+               }
+       }
+       if (p == &r[NN]) {
+               fprintf(stderr, "troff: too many number registers (%d).\n", NN);
+               done2(04); 
+       }
+       return(p - r);
+}
+
+usedr(i)       /* returns -1 if nr i has never been used */
+register int   i;
+{
+       register j;
+       register int *p;
+
+       if (i == 0)
+               return(-1);
+       for (p = r; p < &r[NN]; p++) {
+               if (i == *p)
+                       break;
+       }
+       if (p != &r[NN])
+               return(p - r);
+       else
+               return -1;
+}
+
+
+fnumb(i, f)
+int    i, (*f)();
+{
+       register j;
+
+       j = 0;
+       if (i < 0) {
+               j = (*f)('-' | nrbits);
+               i = -i;
+       }
+       switch (nform) {
+       default:
+       case '1':
+       case 0: 
+               return(decml(i, f) + j);
+       case 'i':
+       case 'I': 
+               return(roman(i, f) + j);
+       case 'a':
+       case 'A': 
+               return(abc(i, f) + j);
+       }
+}
+
+
+decml(i, f)
+int    i, (*f)();
+{
+       register j, k;
+
+       k = 0;
+       nform--;
+       if ((j = i / 10) || (nform > 0))
+               k = decml(j, f);
+       return(k + (*f)((i % 10 + '0') | nrbits));
+}
+
+
+roman(i, f)
+int    i, (*f)();
+{
+
+       if (!i)
+               return((*f)('0' | nrbits));
+       if (nform == 'i')
+               return(roman0(i, f, "ixcmz", "vldw"));
+       else 
+               return(roman0(i, f, "IXCMZ", "VLDW"));
+}
+
+
+roman0(i, f, onesp, fivesp)
+int    i, (*f)();
+char   *onesp, *fivesp;
+{
+       register q, rem, k;
+
+       k = 0;
+       if (!i)
+               return(0);
+       k = roman0(i / 10, f, onesp + 1, fivesp + 1);
+       q = (i = i % 10) / 5;
+       rem = i % 5;
+       if (rem == 4) {
+               k += (*f)(*onesp | nrbits);
+               if (q)
+                       i = *(onesp + 1);
+               else 
+                       i = *fivesp;
+               return(k += (*f)(i | nrbits));
+       }
+       if (q)
+               k += (*f)(*fivesp | nrbits);
+       while (--rem >= 0)
+               k += (*f)(*onesp | nrbits);
+       return(k);
+}
+
+
+abc(i, f)
+int    i, (*f)();
+{
+       if (!i)
+               return((*f)('0' | nrbits));
+       else 
+               return(abc0(i - 1, f));
+}
+
+
+abc0(i, f)
+int    i, (*f)();
+{
+       register j, k;
+
+       k = 0;
+       if (j = i / 26)
+               k = abc0(j - 1, f);
+       return(k + (*f)((i % 26 + nform) | nrbits));
+}
+
+
+wrc(i)
+tchar i;
+{
+       if (cp >= &cbuf[NC])
+               return(0);
+       *cp++ = i;
+       return(1);
+}
+
+
+long   atoi0()
+{
+       register c, k, cnt;
+       tchar ii;
+       long    i, acc;
+       extern long     ckph();
+
+       i = 0; 
+       acc = 0;
+       nonumb = 0;
+       cnt = -1;
+a0:
+       cnt++;
+       ii = getch();
+       c = cbits(ii);
+       switch (c) {
+       default:
+               ch = ii;
+               if (cnt)
+                       break;
+       case '+':
+               i = ckph();
+               if (nonumb)
+                       break;
+               acc += i;
+               goto a0;
+       case '-':
+               i = ckph();
+               if (nonumb)
+                       break;
+               acc -= i;
+               goto a0;
+       case '*':
+               i = ckph();
+               if (nonumb)
+                       break;
+               acc *= i;
+               goto a0;
+       case '/':
+               i = ckph();
+               if (nonumb)
+                       break;
+               if (i == 0) {
+                       flusho();
+                       fprintf(stderr, "troff: divide by zero.\n");
+                       acc = 0;
+               } else 
+                       acc /= i;
+               goto a0;
+       case '%':
+               i = ckph();
+               if (nonumb)
+                       break;
+               acc %= i;
+               goto a0;
+       case '&':       /*and*/
+               i = ckph();
+               if (nonumb)
+                       break;
+               if ((acc > 0) && (i > 0))
+                       acc = 1; 
+               else 
+                       acc = 0;
+               goto a0;
+       case ':':       /*or*/
+               i = ckph();
+               if (nonumb)
+                       break;
+               if ((acc > 0) || (i > 0))
+                       acc = 1; 
+               else 
+                       acc = 0;
+               goto a0;
+       case '=':
+               if (cbits(ii = getch()) != '=')
+                       ch = ii;
+               i = ckph();
+               if (nonumb) {
+                       acc = 0; 
+                       break;
+               }
+               if (i == acc)
+                       acc = 1;
+               else 
+                       acc = 0;
+               goto a0;
+       case '>':
+               k = 0;
+               if (cbits(ii = getch()) == '=')
+                       k++; 
+               else 
+                       ch = ii;
+               i = ckph();
+               if (nonumb) {
+                       acc = 0; 
+                       break;
+               }
+               if (acc > (i - k))
+                       acc = 1; 
+               else 
+                       acc = 0;
+               goto a0;
+       case '<':
+               k = 0;
+               if (cbits(ii = getch()) == '=')
+                       k++; 
+               else 
+                       ch = ii;
+               i = ckph();
+               if (nonumb) {
+                       acc = 0; 
+                       break;
+               }
+               if (acc < (i + k))
+                       acc = 1; 
+               else 
+                       acc = 0;
+               goto a0;
+       case ')': 
+               break;
+       case '(':
+               acc = atoi0();
+               goto a0;
+       }
+       return(acc);
+}
+
+
+long   ckph()
+{
+       tchar i;
+       long    j;
+       extern long     atoi0();
+       extern long     atoi1();
+
+       if (cbits(i = getch()) == '(')
+               j = atoi0();
+       else {
+               ch = i;
+               j = atoi1();
+       }
+       return(j);
+}
+
+
+long   atoi1()
+{
+       register i, j, digits;
+       tchar ii;
+       long    acc;
+       int     neg, abs, field;
+
+       neg = abs = field = digits = 0;
+       acc = 0;
+a0:
+       ii = getch();
+       i = cbits(ii);
+       switch (i) {
+       default:
+               ch = ii;
+               break;
+       case '+':
+               goto a0;
+       case '-':
+               neg = 1;
+               goto a0;
+       case '|':
+               abs = 1 + neg;
+               neg = 0;
+               goto a0;
+       }
+a1:
+       while (((j = (cbits(ii = getch())) - '0') >= 0) && (j <= 9)) {
+               field++;
+               digits++;
+               acc = 10 * acc + j;
+       }
+       if (cbits(ii) == '.') {
+               field++;
+               digits = 0;
+               goto a1;
+       }
+       ch = ii;
+       if (!field)
+               goto a2;
+       ii = getch();
+       switch (i = cbits(ii)) {
+       case 'u':
+               i = j = 1;      /* should this be related to HOR?? */
+               break;
+       case 'v':       /*VSs - vert spacing*/
+               j = lss;
+               i = 1;
+               break;
+       case 'm':       /*Ems*/
+               j = EM;
+               i = 1;
+               break;
+       case 'n':       /*Ens*/
+               j = EM;
+#ifndef NROFF
+               i = 2;
+#endif
+#ifdef NROFF
+               i = 1;  /*Same as Ems in NROFF*/
+#endif
+               break;
+       case 'p':       /*Points*/
+               j = INCH;
+               i = 72;
+               break;
+       case 'i':       /*Inches*/
+               j = INCH;
+               i = 1;
+               break;
+       case 'c':       /*Centimeters*/
+               /* if INCH is too big, this will overflow */
+               j = INCH * 50;
+               i = 127;
+               break;
+       case 'P':       /*Picas*/
+               j = INCH;
+               i = 6;
+               break;
+       default:
+               j = dfact;
+               ch = ii;
+               i = dfactd;
+       }
+       if (neg) 
+               acc = -acc;
+       if (!noscale) {
+               acc = (acc * j) / i;
+       }
+       if ((field != digits) && (digits > 0))
+               while (digits--)
+                       acc /= 10;
+       if (abs) {
+               if (dip != d)
+                       j = dip->dnl; 
+               else 
+                       j = v.nl;
+               if (!vflag) {
+                       j = v.hp = sumhp();     /* XXX */
+               }
+               if (abs == 2)
+                       j = -j;
+               acc -= j;
+       }
+a2:
+       nonumb = !field;
+       return(acc);
+}
+
+
+caserr()
+{
+       register i, j;
+
+       lgf++;
+       while (!skip() && (i = getrq()) ) {
+               for (j = NNAMES; j < NN; j++) {  /*NNAMES predefined names*/
+                       if (i == r[j])
+                               break;
+               }
+               if (j != NN) {
+                       r[j] = vlist[j] = inc[j] = fmt[j] = 0;
+                       regcnt--;
+               }
+       }
+}
+
+
+casenr()
+{
+       register i, j;
+
+       lgf++;
+       skip();
+       if ((i = findr(getrq())) == -1)
+               goto rtn;
+       skip();
+       j = inumb(&vlist[i]);
+       if (nonumb)
+               goto rtn;
+       vlist[i] = j;
+       skip();
+       j = atoi();
+       if (nonumb)
+               goto rtn;
+       inc[i] = j;
+rtn:
+       return;
+}
+
+
+caseaf()
+{
+       register i, k;
+       tchar j;
+
+       lgf++;
+       if (skip() || !(i = getrq()) || skip())
+               return;
+       k = 0;
+       j = getch();
+       if (!isalpha(cbits(j))) {
+               ch = j;
+               while ((j = cbits(getch())) >= '0' &&  j <= '9')
+                       k++;
+       }
+       if (!k)
+               k = j;
+       fmt[findr(i)] = k & BMASK;
+}
+
+setaf()        /* return format of number register */
+{
+       register int i, j;
+
+       i = usedr(getsn());
+       if (i == -1)
+               return;
+       cp = cbuf;
+       if (fmt[i] > 20)        /* it was probably a, A, i or I */
+               *cp++ = fmt[i];
+       else
+               for (j = (fmt[i] ? fmt[i] : 1); j; j--)
+                       *cp++ = '0';
+       *cp = 0;
+       cp = cbuf;
+}
+
+
+vnumb(i)
+int    *i;
+{
+       vflag++;
+       dfact = lss;
+       res = VERT;
+       return(inumb(i));
+}
+
+
+hnumb(i)
+int    *i;
+{
+       dfact = EM;
+       res = HOR;
+       return(inumb(i));
+}
+
+
+inumb(n)
+int    *n;
+{
+       register i, j, f;
+       tchar ii;
+
+       f = 0;
+       if (n) {
+               if ((j = cbits(ii = getch())) == '+')
+                       f = 1;
+               else if (j == '-')
+                       f = -1;
+               else 
+                       ch = ii;
+       }
+       i = atoi();
+       if (n && f)
+               i = *n + f * i;
+       i = quant(i, res);
+       vflag = 0;
+       res = dfactd = dfact = 1;
+       if (nonumb)
+               i = 0;
+       return(i);
+}
+
+
+quant(n, m)
+int    n, m;
+{
+       register i, neg;
+
+       neg = 0;
+       if (n < 0) {
+               neg++;
+               n = -n;
+       }
+       /* better as i = ((n + (m/2))/m)*m */
+       i = n / m;
+       if ((n - m * i) > (m / 2))
+               i += 1;
+       i *= m;
+       if (neg)
+               i = -i;
+       return(i);
+}
+
+