1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*0Sstevel@tonic-gate /* All Rights Reserved */ 29*0Sstevel@tonic-gate 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 32*0Sstevel@tonic-gate 33*0Sstevel@tonic-gate /* 34*0Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 35*0Sstevel@tonic-gate * The Regents of the University of California 36*0Sstevel@tonic-gate * All Rights Reserved 37*0Sstevel@tonic-gate * 38*0Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 39*0Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 40*0Sstevel@tonic-gate * contributors. 41*0Sstevel@tonic-gate */ 42*0Sstevel@tonic-gate 43*0Sstevel@tonic-gate #include <ctype.h> 44*0Sstevel@tonic-gate #include "tdef.h" 45*0Sstevel@tonic-gate #ifdef NROFF 46*0Sstevel@tonic-gate #include "tw.h" 47*0Sstevel@tonic-gate #endif 48*0Sstevel@tonic-gate #include "ext.h" 49*0Sstevel@tonic-gate /* 50*0Sstevel@tonic-gate * troff4.c 51*0Sstevel@tonic-gate * 52*0Sstevel@tonic-gate * number registers, conversion, arithmetic 53*0Sstevel@tonic-gate */ 54*0Sstevel@tonic-gate 55*0Sstevel@tonic-gate 56*0Sstevel@tonic-gate int regcnt = NNAMES; 57*0Sstevel@tonic-gate int falsef = 0; /* on if inside false branch of if */ 58*0Sstevel@tonic-gate #define NHASH(i) ((i>>6)^i)&0177 59*0Sstevel@tonic-gate struct numtab *nhash[128]; /* 128 == the 0177 on line above */ 60*0Sstevel@tonic-gate 61*0Sstevel@tonic-gate setn() 62*0Sstevel@tonic-gate { 63*0Sstevel@tonic-gate register i, j; 64*0Sstevel@tonic-gate register tchar ii; 65*0Sstevel@tonic-gate int f; 66*0Sstevel@tonic-gate 67*0Sstevel@tonic-gate f = nform = 0; 68*0Sstevel@tonic-gate if ((i = cbits(ii = getach())) == '+') 69*0Sstevel@tonic-gate f = 1; 70*0Sstevel@tonic-gate else if (i == '-') 71*0Sstevel@tonic-gate f = -1; 72*0Sstevel@tonic-gate else 73*0Sstevel@tonic-gate ch = ii; 74*0Sstevel@tonic-gate if (falsef) 75*0Sstevel@tonic-gate f = 0; 76*0Sstevel@tonic-gate if ((i = getsn()) == 0) 77*0Sstevel@tonic-gate return; 78*0Sstevel@tonic-gate if ((i & 0177) == '.') 79*0Sstevel@tonic-gate switch (i >> BYTE) { 80*0Sstevel@tonic-gate case 's': 81*0Sstevel@tonic-gate i = pts; 82*0Sstevel@tonic-gate break; 83*0Sstevel@tonic-gate case 'v': 84*0Sstevel@tonic-gate i = lss; 85*0Sstevel@tonic-gate break; 86*0Sstevel@tonic-gate case 'f': 87*0Sstevel@tonic-gate i = font; 88*0Sstevel@tonic-gate break; 89*0Sstevel@tonic-gate case 'p': 90*0Sstevel@tonic-gate i = pl; 91*0Sstevel@tonic-gate break; 92*0Sstevel@tonic-gate case 't': 93*0Sstevel@tonic-gate i = findt1(); 94*0Sstevel@tonic-gate break; 95*0Sstevel@tonic-gate case 'o': 96*0Sstevel@tonic-gate i = po; 97*0Sstevel@tonic-gate break; 98*0Sstevel@tonic-gate case 'l': 99*0Sstevel@tonic-gate i = ll; 100*0Sstevel@tonic-gate break; 101*0Sstevel@tonic-gate case 'i': 102*0Sstevel@tonic-gate i = in; 103*0Sstevel@tonic-gate break; 104*0Sstevel@tonic-gate case '$': 105*0Sstevel@tonic-gate i = frame->nargs; 106*0Sstevel@tonic-gate break; 107*0Sstevel@tonic-gate case 'A': 108*0Sstevel@tonic-gate i = ascii; 109*0Sstevel@tonic-gate break; 110*0Sstevel@tonic-gate case 'c': 111*0Sstevel@tonic-gate i = numtab[CD].val; 112*0Sstevel@tonic-gate break; 113*0Sstevel@tonic-gate case 'n': 114*0Sstevel@tonic-gate i = lastl; 115*0Sstevel@tonic-gate break; 116*0Sstevel@tonic-gate case 'a': 117*0Sstevel@tonic-gate i = ralss; 118*0Sstevel@tonic-gate break; 119*0Sstevel@tonic-gate case 'h': 120*0Sstevel@tonic-gate i = dip->hnl; 121*0Sstevel@tonic-gate break; 122*0Sstevel@tonic-gate case 'd': 123*0Sstevel@tonic-gate if (dip != d) 124*0Sstevel@tonic-gate i = dip->dnl; 125*0Sstevel@tonic-gate else 126*0Sstevel@tonic-gate i = numtab[NL].val; 127*0Sstevel@tonic-gate break; 128*0Sstevel@tonic-gate case 'u': 129*0Sstevel@tonic-gate i = fi; 130*0Sstevel@tonic-gate break; 131*0Sstevel@tonic-gate case 'j': 132*0Sstevel@tonic-gate i = ad + 2 * admod; 133*0Sstevel@tonic-gate break; 134*0Sstevel@tonic-gate case 'w': 135*0Sstevel@tonic-gate i = widthp; 136*0Sstevel@tonic-gate break; 137*0Sstevel@tonic-gate case 'x': 138*0Sstevel@tonic-gate i = nel; 139*0Sstevel@tonic-gate break; 140*0Sstevel@tonic-gate case 'y': 141*0Sstevel@tonic-gate i = un; 142*0Sstevel@tonic-gate break; 143*0Sstevel@tonic-gate case 'T': 144*0Sstevel@tonic-gate i = dotT; 145*0Sstevel@tonic-gate break; /*-Tterm used in nroff*/ 146*0Sstevel@tonic-gate case 'V': 147*0Sstevel@tonic-gate i = VERT; 148*0Sstevel@tonic-gate break; 149*0Sstevel@tonic-gate case 'H': 150*0Sstevel@tonic-gate i = HOR; 151*0Sstevel@tonic-gate break; 152*0Sstevel@tonic-gate case 'k': 153*0Sstevel@tonic-gate i = ne; 154*0Sstevel@tonic-gate break; 155*0Sstevel@tonic-gate case 'P': 156*0Sstevel@tonic-gate i = print; 157*0Sstevel@tonic-gate break; 158*0Sstevel@tonic-gate case 'L': 159*0Sstevel@tonic-gate i = ls; 160*0Sstevel@tonic-gate break; 161*0Sstevel@tonic-gate case 'R': 162*0Sstevel@tonic-gate i = NN - regcnt; 163*0Sstevel@tonic-gate break; 164*0Sstevel@tonic-gate case 'z': 165*0Sstevel@tonic-gate i = dip->curd; 166*0Sstevel@tonic-gate *pbp++ = (i >> BYTE) & BYTEMASK; 167*0Sstevel@tonic-gate *pbp++ = i & BYTEMASK; 168*0Sstevel@tonic-gate return; 169*0Sstevel@tonic-gate case 'b': 170*0Sstevel@tonic-gate i = bdtab[font]; 171*0Sstevel@tonic-gate break; 172*0Sstevel@tonic-gate case 'F': 173*0Sstevel@tonic-gate cpushback(cfname[ifi]); 174*0Sstevel@tonic-gate return; 175*0Sstevel@tonic-gate 176*0Sstevel@tonic-gate default: 177*0Sstevel@tonic-gate goto s0; 178*0Sstevel@tonic-gate } 179*0Sstevel@tonic-gate else { 180*0Sstevel@tonic-gate s0: 181*0Sstevel@tonic-gate if ((j = findr(i)) == -1) 182*0Sstevel@tonic-gate i = 0; 183*0Sstevel@tonic-gate else { 184*0Sstevel@tonic-gate i = numtab[j].val = (numtab[j].val+numtab[j].inc*f); 185*0Sstevel@tonic-gate nform = numtab[j].fmt; 186*0Sstevel@tonic-gate } 187*0Sstevel@tonic-gate } 188*0Sstevel@tonic-gate setn1(i, nform, (tchar) 0); 189*0Sstevel@tonic-gate } 190*0Sstevel@tonic-gate 191*0Sstevel@tonic-gate tchar numbuf[17]; 192*0Sstevel@tonic-gate tchar *numbufp; 193*0Sstevel@tonic-gate 194*0Sstevel@tonic-gate wrc(i) 195*0Sstevel@tonic-gate tchar i; 196*0Sstevel@tonic-gate { 197*0Sstevel@tonic-gate if (numbufp >= &numbuf[16]) 198*0Sstevel@tonic-gate return(0); 199*0Sstevel@tonic-gate *numbufp++ = i; 200*0Sstevel@tonic-gate return(1); 201*0Sstevel@tonic-gate } 202*0Sstevel@tonic-gate 203*0Sstevel@tonic-gate 204*0Sstevel@tonic-gate 205*0Sstevel@tonic-gate /* insert into input number i, in format form, with size-font bits bits */ 206*0Sstevel@tonic-gate setn1(i, form, bits) 207*0Sstevel@tonic-gate int i; 208*0Sstevel@tonic-gate tchar bits; 209*0Sstevel@tonic-gate { 210*0Sstevel@tonic-gate extern int wrc(); 211*0Sstevel@tonic-gate 212*0Sstevel@tonic-gate numbufp = numbuf; 213*0Sstevel@tonic-gate nrbits = bits; 214*0Sstevel@tonic-gate nform = form; 215*0Sstevel@tonic-gate fnumb(i, wrc); 216*0Sstevel@tonic-gate *numbufp = 0; 217*0Sstevel@tonic-gate pushback(numbuf); 218*0Sstevel@tonic-gate } 219*0Sstevel@tonic-gate 220*0Sstevel@tonic-gate 221*0Sstevel@tonic-gate nrehash() 222*0Sstevel@tonic-gate { 223*0Sstevel@tonic-gate register struct numtab *p; 224*0Sstevel@tonic-gate register i; 225*0Sstevel@tonic-gate 226*0Sstevel@tonic-gate for (i=0; i<128; i++) 227*0Sstevel@tonic-gate nhash[i] = 0; 228*0Sstevel@tonic-gate for (p=numtab; p < &numtab[NN]; p++) 229*0Sstevel@tonic-gate p->link = 0; 230*0Sstevel@tonic-gate for (p=numtab; p < &numtab[NN]; p++) { 231*0Sstevel@tonic-gate if (p->r == 0) 232*0Sstevel@tonic-gate continue; 233*0Sstevel@tonic-gate i = NHASH(p->r); 234*0Sstevel@tonic-gate p->link = nhash[i]; 235*0Sstevel@tonic-gate nhash[i] = p; 236*0Sstevel@tonic-gate } 237*0Sstevel@tonic-gate } 238*0Sstevel@tonic-gate 239*0Sstevel@tonic-gate nunhash(rp) 240*0Sstevel@tonic-gate register struct numtab *rp; 241*0Sstevel@tonic-gate { 242*0Sstevel@tonic-gate register struct numtab *p; 243*0Sstevel@tonic-gate register struct numtab **lp; 244*0Sstevel@tonic-gate 245*0Sstevel@tonic-gate if (rp->r == 0) 246*0Sstevel@tonic-gate return; 247*0Sstevel@tonic-gate lp = &nhash[NHASH(rp->r)]; 248*0Sstevel@tonic-gate p = *lp; 249*0Sstevel@tonic-gate while (p) { 250*0Sstevel@tonic-gate if (p == rp) { 251*0Sstevel@tonic-gate *lp = p->link; 252*0Sstevel@tonic-gate p->link = 0; 253*0Sstevel@tonic-gate return; 254*0Sstevel@tonic-gate } 255*0Sstevel@tonic-gate lp = &p->link; 256*0Sstevel@tonic-gate p = p->link; 257*0Sstevel@tonic-gate } 258*0Sstevel@tonic-gate } 259*0Sstevel@tonic-gate 260*0Sstevel@tonic-gate findr(i) 261*0Sstevel@tonic-gate register int i; 262*0Sstevel@tonic-gate { 263*0Sstevel@tonic-gate register struct numtab *p; 264*0Sstevel@tonic-gate register h = NHASH(i); 265*0Sstevel@tonic-gate 266*0Sstevel@tonic-gate if (i == 0) 267*0Sstevel@tonic-gate return(-1); 268*0Sstevel@tonic-gate for (p = nhash[h]; p; p = p->link) 269*0Sstevel@tonic-gate if (i == p->r) 270*0Sstevel@tonic-gate return(p - numtab); 271*0Sstevel@tonic-gate for (p = numtab; p < &numtab[NN]; p++) { 272*0Sstevel@tonic-gate if (p->r == 0) { 273*0Sstevel@tonic-gate p->r = i; 274*0Sstevel@tonic-gate p->link = nhash[h]; 275*0Sstevel@tonic-gate nhash[h] = p; 276*0Sstevel@tonic-gate regcnt++; 277*0Sstevel@tonic-gate return(p - numtab); 278*0Sstevel@tonic-gate } 279*0Sstevel@tonic-gate } 280*0Sstevel@tonic-gate errprint(gettext("too many number registers (%d)."), NN); 281*0Sstevel@tonic-gate done2(04); 282*0Sstevel@tonic-gate /* NOTREACHED */ 283*0Sstevel@tonic-gate } 284*0Sstevel@tonic-gate 285*0Sstevel@tonic-gate usedr(i) /* returns -1 if nr i has never been used */ 286*0Sstevel@tonic-gate register int i; 287*0Sstevel@tonic-gate { 288*0Sstevel@tonic-gate register struct numtab *p; 289*0Sstevel@tonic-gate 290*0Sstevel@tonic-gate if (i == 0) 291*0Sstevel@tonic-gate return(-1); 292*0Sstevel@tonic-gate for (p = nhash[NHASH(i)]; p; p = p->link) 293*0Sstevel@tonic-gate if (i == p->r) 294*0Sstevel@tonic-gate return(p - numtab); 295*0Sstevel@tonic-gate return -1; 296*0Sstevel@tonic-gate } 297*0Sstevel@tonic-gate 298*0Sstevel@tonic-gate 299*0Sstevel@tonic-gate fnumb(i, f) 300*0Sstevel@tonic-gate register int i, (*f)(); 301*0Sstevel@tonic-gate { 302*0Sstevel@tonic-gate register j; 303*0Sstevel@tonic-gate 304*0Sstevel@tonic-gate j = 0; 305*0Sstevel@tonic-gate if (i < 0) { 306*0Sstevel@tonic-gate j = (*f)('-' | nrbits); 307*0Sstevel@tonic-gate i = -i; 308*0Sstevel@tonic-gate } 309*0Sstevel@tonic-gate switch (nform) { 310*0Sstevel@tonic-gate default: 311*0Sstevel@tonic-gate case '1': 312*0Sstevel@tonic-gate case 0: 313*0Sstevel@tonic-gate return decml(i, f) + j; 314*0Sstevel@tonic-gate break; 315*0Sstevel@tonic-gate case 'i': 316*0Sstevel@tonic-gate case 'I': 317*0Sstevel@tonic-gate return roman(i, f) + j; 318*0Sstevel@tonic-gate break; 319*0Sstevel@tonic-gate case 'a': 320*0Sstevel@tonic-gate case 'A': 321*0Sstevel@tonic-gate return abc(i, f) + j; 322*0Sstevel@tonic-gate break; 323*0Sstevel@tonic-gate } 324*0Sstevel@tonic-gate } 325*0Sstevel@tonic-gate 326*0Sstevel@tonic-gate 327*0Sstevel@tonic-gate decml(i, f) 328*0Sstevel@tonic-gate register int i, (*f)(); 329*0Sstevel@tonic-gate { 330*0Sstevel@tonic-gate register j, k; 331*0Sstevel@tonic-gate 332*0Sstevel@tonic-gate k = 0; 333*0Sstevel@tonic-gate nform--; 334*0Sstevel@tonic-gate if ((j = i / 10) || (nform > 0)) 335*0Sstevel@tonic-gate k = decml(j, f); 336*0Sstevel@tonic-gate return(k + (*f)((i % 10 + '0') | nrbits)); 337*0Sstevel@tonic-gate } 338*0Sstevel@tonic-gate 339*0Sstevel@tonic-gate 340*0Sstevel@tonic-gate roman(i, f) 341*0Sstevel@tonic-gate int i, (*f)(); 342*0Sstevel@tonic-gate { 343*0Sstevel@tonic-gate 344*0Sstevel@tonic-gate if (!i) 345*0Sstevel@tonic-gate return((*f)('0' | nrbits)); 346*0Sstevel@tonic-gate if (nform == 'i') 347*0Sstevel@tonic-gate return(roman0(i, f, "ixcmz", "vldw")); 348*0Sstevel@tonic-gate else 349*0Sstevel@tonic-gate return(roman0(i, f, "IXCMZ", "VLDW")); 350*0Sstevel@tonic-gate } 351*0Sstevel@tonic-gate 352*0Sstevel@tonic-gate 353*0Sstevel@tonic-gate roman0(i, f, onesp, fivesp) 354*0Sstevel@tonic-gate int i, (*f)(); 355*0Sstevel@tonic-gate char *onesp, *fivesp; 356*0Sstevel@tonic-gate { 357*0Sstevel@tonic-gate register q, rem, k; 358*0Sstevel@tonic-gate 359*0Sstevel@tonic-gate k = 0; 360*0Sstevel@tonic-gate if (!i) 361*0Sstevel@tonic-gate return(0); 362*0Sstevel@tonic-gate k = roman0(i / 10, f, onesp + 1, fivesp + 1); 363*0Sstevel@tonic-gate q = (i = i % 10) / 5; 364*0Sstevel@tonic-gate rem = i % 5; 365*0Sstevel@tonic-gate if (rem == 4) { 366*0Sstevel@tonic-gate k += (*f)(*onesp | nrbits); 367*0Sstevel@tonic-gate if (q) 368*0Sstevel@tonic-gate i = *(onesp + 1); 369*0Sstevel@tonic-gate else 370*0Sstevel@tonic-gate i = *fivesp; 371*0Sstevel@tonic-gate return(k += (*f)(i | nrbits)); 372*0Sstevel@tonic-gate } 373*0Sstevel@tonic-gate if (q) 374*0Sstevel@tonic-gate k += (*f)(*fivesp | nrbits); 375*0Sstevel@tonic-gate while (--rem >= 0) 376*0Sstevel@tonic-gate k += (*f)(*onesp | nrbits); 377*0Sstevel@tonic-gate return(k); 378*0Sstevel@tonic-gate } 379*0Sstevel@tonic-gate 380*0Sstevel@tonic-gate 381*0Sstevel@tonic-gate abc(i, f) 382*0Sstevel@tonic-gate int i, (*f)(); 383*0Sstevel@tonic-gate { 384*0Sstevel@tonic-gate if (!i) 385*0Sstevel@tonic-gate return((*f)('0' | nrbits)); 386*0Sstevel@tonic-gate else 387*0Sstevel@tonic-gate return(abc0(i - 1, f)); 388*0Sstevel@tonic-gate } 389*0Sstevel@tonic-gate 390*0Sstevel@tonic-gate 391*0Sstevel@tonic-gate abc0(i, f) 392*0Sstevel@tonic-gate int i, (*f)(); 393*0Sstevel@tonic-gate { 394*0Sstevel@tonic-gate register j, k; 395*0Sstevel@tonic-gate 396*0Sstevel@tonic-gate k = 0; 397*0Sstevel@tonic-gate if (j = i / 26) 398*0Sstevel@tonic-gate k = abc0(j - 1, f); 399*0Sstevel@tonic-gate return(k + (*f)((i % 26 + nform) | nrbits)); 400*0Sstevel@tonic-gate } 401*0Sstevel@tonic-gate 402*0Sstevel@tonic-gate long atoi0() 403*0Sstevel@tonic-gate { 404*0Sstevel@tonic-gate register c, k, cnt; 405*0Sstevel@tonic-gate register tchar ii; 406*0Sstevel@tonic-gate long i, acc; 407*0Sstevel@tonic-gate extern long ckph(); 408*0Sstevel@tonic-gate 409*0Sstevel@tonic-gate i = 0; 410*0Sstevel@tonic-gate acc = 0; 411*0Sstevel@tonic-gate nonumb = 0; 412*0Sstevel@tonic-gate cnt = -1; 413*0Sstevel@tonic-gate a0: 414*0Sstevel@tonic-gate cnt++; 415*0Sstevel@tonic-gate ii = getch(); 416*0Sstevel@tonic-gate c = cbits(ii); 417*0Sstevel@tonic-gate switch (c) { 418*0Sstevel@tonic-gate default: 419*0Sstevel@tonic-gate ch = ii; 420*0Sstevel@tonic-gate if (cnt) 421*0Sstevel@tonic-gate break; 422*0Sstevel@tonic-gate case '+': 423*0Sstevel@tonic-gate i = ckph(); 424*0Sstevel@tonic-gate if (nonumb) 425*0Sstevel@tonic-gate break; 426*0Sstevel@tonic-gate acc += i; 427*0Sstevel@tonic-gate goto a0; 428*0Sstevel@tonic-gate case '-': 429*0Sstevel@tonic-gate i = ckph(); 430*0Sstevel@tonic-gate if (nonumb) 431*0Sstevel@tonic-gate break; 432*0Sstevel@tonic-gate acc -= i; 433*0Sstevel@tonic-gate goto a0; 434*0Sstevel@tonic-gate case '*': 435*0Sstevel@tonic-gate i = ckph(); 436*0Sstevel@tonic-gate if (nonumb) 437*0Sstevel@tonic-gate break; 438*0Sstevel@tonic-gate acc *= i; 439*0Sstevel@tonic-gate goto a0; 440*0Sstevel@tonic-gate case '/': 441*0Sstevel@tonic-gate i = ckph(); 442*0Sstevel@tonic-gate if (nonumb) 443*0Sstevel@tonic-gate break; 444*0Sstevel@tonic-gate if (i == 0) { 445*0Sstevel@tonic-gate flusho(); 446*0Sstevel@tonic-gate errprint(gettext("divide by zero.")); 447*0Sstevel@tonic-gate acc = 0; 448*0Sstevel@tonic-gate } else 449*0Sstevel@tonic-gate acc /= i; 450*0Sstevel@tonic-gate goto a0; 451*0Sstevel@tonic-gate case '%': 452*0Sstevel@tonic-gate i = ckph(); 453*0Sstevel@tonic-gate if (nonumb) 454*0Sstevel@tonic-gate break; 455*0Sstevel@tonic-gate acc %= i; 456*0Sstevel@tonic-gate goto a0; 457*0Sstevel@tonic-gate case '&': /*and*/ 458*0Sstevel@tonic-gate i = ckph(); 459*0Sstevel@tonic-gate if (nonumb) 460*0Sstevel@tonic-gate break; 461*0Sstevel@tonic-gate if ((acc > 0) && (i > 0)) 462*0Sstevel@tonic-gate acc = 1; 463*0Sstevel@tonic-gate else 464*0Sstevel@tonic-gate acc = 0; 465*0Sstevel@tonic-gate goto a0; 466*0Sstevel@tonic-gate case ':': /*or*/ 467*0Sstevel@tonic-gate i = ckph(); 468*0Sstevel@tonic-gate if (nonumb) 469*0Sstevel@tonic-gate break; 470*0Sstevel@tonic-gate if ((acc > 0) || (i > 0)) 471*0Sstevel@tonic-gate acc = 1; 472*0Sstevel@tonic-gate else 473*0Sstevel@tonic-gate acc = 0; 474*0Sstevel@tonic-gate goto a0; 475*0Sstevel@tonic-gate case '=': 476*0Sstevel@tonic-gate if (cbits(ii = getch()) != '=') 477*0Sstevel@tonic-gate ch = ii; 478*0Sstevel@tonic-gate i = ckph(); 479*0Sstevel@tonic-gate if (nonumb) { 480*0Sstevel@tonic-gate acc = 0; 481*0Sstevel@tonic-gate break; 482*0Sstevel@tonic-gate } 483*0Sstevel@tonic-gate if (i == acc) 484*0Sstevel@tonic-gate acc = 1; 485*0Sstevel@tonic-gate else 486*0Sstevel@tonic-gate acc = 0; 487*0Sstevel@tonic-gate goto a0; 488*0Sstevel@tonic-gate case '>': 489*0Sstevel@tonic-gate k = 0; 490*0Sstevel@tonic-gate if (cbits(ii = getch()) == '=') 491*0Sstevel@tonic-gate k++; 492*0Sstevel@tonic-gate else 493*0Sstevel@tonic-gate ch = ii; 494*0Sstevel@tonic-gate i = ckph(); 495*0Sstevel@tonic-gate if (nonumb) { 496*0Sstevel@tonic-gate acc = 0; 497*0Sstevel@tonic-gate break; 498*0Sstevel@tonic-gate } 499*0Sstevel@tonic-gate if (acc > (i - k)) 500*0Sstevel@tonic-gate acc = 1; 501*0Sstevel@tonic-gate else 502*0Sstevel@tonic-gate acc = 0; 503*0Sstevel@tonic-gate goto a0; 504*0Sstevel@tonic-gate case '<': 505*0Sstevel@tonic-gate k = 0; 506*0Sstevel@tonic-gate if (cbits(ii = getch()) == '=') 507*0Sstevel@tonic-gate k++; 508*0Sstevel@tonic-gate else 509*0Sstevel@tonic-gate ch = ii; 510*0Sstevel@tonic-gate i = ckph(); 511*0Sstevel@tonic-gate if (nonumb) { 512*0Sstevel@tonic-gate acc = 0; 513*0Sstevel@tonic-gate break; 514*0Sstevel@tonic-gate } 515*0Sstevel@tonic-gate if (acc < (i + k)) 516*0Sstevel@tonic-gate acc = 1; 517*0Sstevel@tonic-gate else 518*0Sstevel@tonic-gate acc = 0; 519*0Sstevel@tonic-gate goto a0; 520*0Sstevel@tonic-gate case ')': 521*0Sstevel@tonic-gate break; 522*0Sstevel@tonic-gate case '(': 523*0Sstevel@tonic-gate acc = atoi0(); 524*0Sstevel@tonic-gate goto a0; 525*0Sstevel@tonic-gate } 526*0Sstevel@tonic-gate return(acc); 527*0Sstevel@tonic-gate } 528*0Sstevel@tonic-gate 529*0Sstevel@tonic-gate 530*0Sstevel@tonic-gate long ckph() 531*0Sstevel@tonic-gate { 532*0Sstevel@tonic-gate register tchar i; 533*0Sstevel@tonic-gate register long j; 534*0Sstevel@tonic-gate extern long atoi0(); 535*0Sstevel@tonic-gate extern long atoi1(); 536*0Sstevel@tonic-gate 537*0Sstevel@tonic-gate if (cbits(i = getch()) == '(') 538*0Sstevel@tonic-gate j = atoi0(); 539*0Sstevel@tonic-gate else { 540*0Sstevel@tonic-gate j = atoi1(i); 541*0Sstevel@tonic-gate } 542*0Sstevel@tonic-gate return(j); 543*0Sstevel@tonic-gate } 544*0Sstevel@tonic-gate 545*0Sstevel@tonic-gate 546*0Sstevel@tonic-gate long atoi1(ii) 547*0Sstevel@tonic-gate register tchar ii; 548*0Sstevel@tonic-gate { 549*0Sstevel@tonic-gate register i, j, digits; 550*0Sstevel@tonic-gate register long acc; 551*0Sstevel@tonic-gate int neg, abs, field; 552*0Sstevel@tonic-gate 553*0Sstevel@tonic-gate neg = abs = field = digits = 0; 554*0Sstevel@tonic-gate acc = 0; 555*0Sstevel@tonic-gate for (;;) { 556*0Sstevel@tonic-gate i = cbits(ii); 557*0Sstevel@tonic-gate switch (i) { 558*0Sstevel@tonic-gate default: 559*0Sstevel@tonic-gate break; 560*0Sstevel@tonic-gate case '+': 561*0Sstevel@tonic-gate ii = getch(); 562*0Sstevel@tonic-gate continue; 563*0Sstevel@tonic-gate case '-': 564*0Sstevel@tonic-gate neg = 1; 565*0Sstevel@tonic-gate ii = getch(); 566*0Sstevel@tonic-gate continue; 567*0Sstevel@tonic-gate case '|': 568*0Sstevel@tonic-gate abs = 1 + neg; 569*0Sstevel@tonic-gate neg = 0; 570*0Sstevel@tonic-gate ii = getch(); 571*0Sstevel@tonic-gate continue; 572*0Sstevel@tonic-gate } 573*0Sstevel@tonic-gate break; 574*0Sstevel@tonic-gate } 575*0Sstevel@tonic-gate a1: 576*0Sstevel@tonic-gate while (i >= '0' && i <= '9') { 577*0Sstevel@tonic-gate field++; 578*0Sstevel@tonic-gate digits++; 579*0Sstevel@tonic-gate acc = 10 * acc + i - '0'; 580*0Sstevel@tonic-gate ii = getch(); 581*0Sstevel@tonic-gate i = cbits(ii); 582*0Sstevel@tonic-gate } 583*0Sstevel@tonic-gate if (i == '.') { 584*0Sstevel@tonic-gate field++; 585*0Sstevel@tonic-gate digits = 0; 586*0Sstevel@tonic-gate ii = getch(); 587*0Sstevel@tonic-gate i = cbits(ii); 588*0Sstevel@tonic-gate goto a1; 589*0Sstevel@tonic-gate } 590*0Sstevel@tonic-gate if (!field) { 591*0Sstevel@tonic-gate ch = ii; 592*0Sstevel@tonic-gate goto a2; 593*0Sstevel@tonic-gate } 594*0Sstevel@tonic-gate switch (i) { 595*0Sstevel@tonic-gate case 'u': 596*0Sstevel@tonic-gate i = j = 1; /* should this be related to HOR?? */ 597*0Sstevel@tonic-gate break; 598*0Sstevel@tonic-gate case 'v': /*VSs - vert spacing*/ 599*0Sstevel@tonic-gate j = lss; 600*0Sstevel@tonic-gate i = 1; 601*0Sstevel@tonic-gate break; 602*0Sstevel@tonic-gate case 'm': /*Ems*/ 603*0Sstevel@tonic-gate j = EM; 604*0Sstevel@tonic-gate i = 1; 605*0Sstevel@tonic-gate break; 606*0Sstevel@tonic-gate case 'n': /*Ens*/ 607*0Sstevel@tonic-gate j = EM; 608*0Sstevel@tonic-gate #ifndef NROFF 609*0Sstevel@tonic-gate i = 2; 610*0Sstevel@tonic-gate #endif 611*0Sstevel@tonic-gate #ifdef NROFF 612*0Sstevel@tonic-gate i = 1; /*Same as Ems in NROFF*/ 613*0Sstevel@tonic-gate #endif 614*0Sstevel@tonic-gate break; 615*0Sstevel@tonic-gate case 'p': /*Points*/ 616*0Sstevel@tonic-gate j = INCH; 617*0Sstevel@tonic-gate i = 72; 618*0Sstevel@tonic-gate break; 619*0Sstevel@tonic-gate case 'i': /*Inches*/ 620*0Sstevel@tonic-gate j = INCH; 621*0Sstevel@tonic-gate i = 1; 622*0Sstevel@tonic-gate break; 623*0Sstevel@tonic-gate case 'c': /*Centimeters*/ 624*0Sstevel@tonic-gate /* if INCH is too big, this will overflow */ 625*0Sstevel@tonic-gate j = INCH * 50; 626*0Sstevel@tonic-gate i = 127; 627*0Sstevel@tonic-gate break; 628*0Sstevel@tonic-gate case 'P': /*Picas*/ 629*0Sstevel@tonic-gate j = INCH; 630*0Sstevel@tonic-gate i = 6; 631*0Sstevel@tonic-gate break; 632*0Sstevel@tonic-gate default: 633*0Sstevel@tonic-gate j = dfact; 634*0Sstevel@tonic-gate ch = ii; 635*0Sstevel@tonic-gate i = dfactd; 636*0Sstevel@tonic-gate } 637*0Sstevel@tonic-gate if (neg) 638*0Sstevel@tonic-gate acc = -acc; 639*0Sstevel@tonic-gate if (!noscale) { 640*0Sstevel@tonic-gate acc = (acc * j) / i; 641*0Sstevel@tonic-gate } 642*0Sstevel@tonic-gate if ((field != digits) && (digits > 0)) 643*0Sstevel@tonic-gate while (digits--) 644*0Sstevel@tonic-gate acc /= 10; 645*0Sstevel@tonic-gate if (abs) { 646*0Sstevel@tonic-gate if (dip != d) 647*0Sstevel@tonic-gate j = dip->dnl; 648*0Sstevel@tonic-gate else 649*0Sstevel@tonic-gate j = numtab[NL].val; 650*0Sstevel@tonic-gate if (!vflag) { 651*0Sstevel@tonic-gate j = numtab[HP].val; 652*0Sstevel@tonic-gate } 653*0Sstevel@tonic-gate if (abs == 2) 654*0Sstevel@tonic-gate j = -j; 655*0Sstevel@tonic-gate acc -= j; 656*0Sstevel@tonic-gate } 657*0Sstevel@tonic-gate a2: 658*0Sstevel@tonic-gate nonumb = !field; 659*0Sstevel@tonic-gate return(acc); 660*0Sstevel@tonic-gate } 661*0Sstevel@tonic-gate 662*0Sstevel@tonic-gate 663*0Sstevel@tonic-gate caserr() 664*0Sstevel@tonic-gate { 665*0Sstevel@tonic-gate register i, j; 666*0Sstevel@tonic-gate register struct numtab *p; 667*0Sstevel@tonic-gate 668*0Sstevel@tonic-gate lgf++; 669*0Sstevel@tonic-gate while (!skip() && (i = getrq()) ) { 670*0Sstevel@tonic-gate j = usedr(i); 671*0Sstevel@tonic-gate if (j < 0) 672*0Sstevel@tonic-gate continue; 673*0Sstevel@tonic-gate p = &numtab[j]; 674*0Sstevel@tonic-gate nunhash(p); 675*0Sstevel@tonic-gate p->r = p->val = p->inc = p->fmt = 0; 676*0Sstevel@tonic-gate regcnt--; 677*0Sstevel@tonic-gate } 678*0Sstevel@tonic-gate } 679*0Sstevel@tonic-gate 680*0Sstevel@tonic-gate 681*0Sstevel@tonic-gate casenr() 682*0Sstevel@tonic-gate { 683*0Sstevel@tonic-gate register i, j; 684*0Sstevel@tonic-gate 685*0Sstevel@tonic-gate lgf++; 686*0Sstevel@tonic-gate skip(); 687*0Sstevel@tonic-gate if ((i = findr(getrq())) == -1) 688*0Sstevel@tonic-gate goto rtn; 689*0Sstevel@tonic-gate skip(); 690*0Sstevel@tonic-gate j = inumb(&numtab[i].val); 691*0Sstevel@tonic-gate if (nonumb) 692*0Sstevel@tonic-gate goto rtn; 693*0Sstevel@tonic-gate numtab[i].val = j; 694*0Sstevel@tonic-gate skip(); 695*0Sstevel@tonic-gate j = atoi(); 696*0Sstevel@tonic-gate if (nonumb) 697*0Sstevel@tonic-gate goto rtn; 698*0Sstevel@tonic-gate numtab[i].inc = j; 699*0Sstevel@tonic-gate rtn: 700*0Sstevel@tonic-gate return; 701*0Sstevel@tonic-gate } 702*0Sstevel@tonic-gate 703*0Sstevel@tonic-gate 704*0Sstevel@tonic-gate caseaf() 705*0Sstevel@tonic-gate { 706*0Sstevel@tonic-gate register i, k; 707*0Sstevel@tonic-gate register tchar j, jj; 708*0Sstevel@tonic-gate 709*0Sstevel@tonic-gate lgf++; 710*0Sstevel@tonic-gate if (skip() || !(i = getrq()) || skip()) 711*0Sstevel@tonic-gate return; 712*0Sstevel@tonic-gate k = 0; 713*0Sstevel@tonic-gate j = getch(); 714*0Sstevel@tonic-gate if (!ischar(jj = cbits(j)) || !isalpha(jj)) { 715*0Sstevel@tonic-gate ch = j; 716*0Sstevel@tonic-gate while ((j = cbits(getch())) >= '0' && j <= '9') 717*0Sstevel@tonic-gate k++; 718*0Sstevel@tonic-gate } 719*0Sstevel@tonic-gate if (!k) 720*0Sstevel@tonic-gate k = j; 721*0Sstevel@tonic-gate numtab[findr(i)].fmt = k & BYTEMASK; 722*0Sstevel@tonic-gate } 723*0Sstevel@tonic-gate 724*0Sstevel@tonic-gate setaf() /* return format of number register */ 725*0Sstevel@tonic-gate { 726*0Sstevel@tonic-gate register int i, j; 727*0Sstevel@tonic-gate 728*0Sstevel@tonic-gate i = usedr(getsn()); 729*0Sstevel@tonic-gate if (i == -1) 730*0Sstevel@tonic-gate return; 731*0Sstevel@tonic-gate if (numtab[i].fmt > 20) /* it was probably a, A, i or I */ 732*0Sstevel@tonic-gate *pbp++ = numtab[i].fmt; 733*0Sstevel@tonic-gate else 734*0Sstevel@tonic-gate for (j = (numtab[i].fmt ? numtab[i].fmt : 1); j; j--) 735*0Sstevel@tonic-gate *pbp++ = '0'; 736*0Sstevel@tonic-gate } 737*0Sstevel@tonic-gate 738*0Sstevel@tonic-gate 739*0Sstevel@tonic-gate vnumb(i) 740*0Sstevel@tonic-gate int *i; 741*0Sstevel@tonic-gate { 742*0Sstevel@tonic-gate vflag++; 743*0Sstevel@tonic-gate dfact = lss; 744*0Sstevel@tonic-gate res = VERT; 745*0Sstevel@tonic-gate return(inumb(i)); 746*0Sstevel@tonic-gate } 747*0Sstevel@tonic-gate 748*0Sstevel@tonic-gate 749*0Sstevel@tonic-gate hnumb(i) 750*0Sstevel@tonic-gate int *i; 751*0Sstevel@tonic-gate { 752*0Sstevel@tonic-gate dfact = EM; 753*0Sstevel@tonic-gate res = HOR; 754*0Sstevel@tonic-gate return(inumb(i)); 755*0Sstevel@tonic-gate } 756*0Sstevel@tonic-gate 757*0Sstevel@tonic-gate 758*0Sstevel@tonic-gate inumb(n) 759*0Sstevel@tonic-gate int *n; 760*0Sstevel@tonic-gate { 761*0Sstevel@tonic-gate register i, j, f; 762*0Sstevel@tonic-gate register tchar ii; 763*0Sstevel@tonic-gate 764*0Sstevel@tonic-gate f = 0; 765*0Sstevel@tonic-gate if (n) { 766*0Sstevel@tonic-gate if ((j = cbits(ii = getch())) == '+') 767*0Sstevel@tonic-gate f = 1; 768*0Sstevel@tonic-gate else if (j == '-') 769*0Sstevel@tonic-gate f = -1; 770*0Sstevel@tonic-gate else 771*0Sstevel@tonic-gate ch = ii; 772*0Sstevel@tonic-gate } 773*0Sstevel@tonic-gate i = atoi(); 774*0Sstevel@tonic-gate if (n && f) 775*0Sstevel@tonic-gate i = *n + f * i; 776*0Sstevel@tonic-gate i = quant(i, res); 777*0Sstevel@tonic-gate vflag = 0; 778*0Sstevel@tonic-gate res = dfactd = dfact = 1; 779*0Sstevel@tonic-gate if (nonumb) 780*0Sstevel@tonic-gate i = 0; 781*0Sstevel@tonic-gate return(i); 782*0Sstevel@tonic-gate } 783*0Sstevel@tonic-gate 784*0Sstevel@tonic-gate 785*0Sstevel@tonic-gate quant(n, m) 786*0Sstevel@tonic-gate int n, m; 787*0Sstevel@tonic-gate { 788*0Sstevel@tonic-gate register i, neg; 789*0Sstevel@tonic-gate 790*0Sstevel@tonic-gate neg = 0; 791*0Sstevel@tonic-gate if (n < 0) { 792*0Sstevel@tonic-gate neg++; 793*0Sstevel@tonic-gate n = -n; 794*0Sstevel@tonic-gate } 795*0Sstevel@tonic-gate /* better as i = ((n + (m/2))/m)*m */ 796*0Sstevel@tonic-gate i = n / m; 797*0Sstevel@tonic-gate if ((n - m * i) > (m / 2)) 798*0Sstevel@tonic-gate i += 1; 799*0Sstevel@tonic-gate i *= m; 800*0Sstevel@tonic-gate if (neg) 801*0Sstevel@tonic-gate i = -i; 802*0Sstevel@tonic-gate return(i); 803*0Sstevel@tonic-gate } 804*0Sstevel@tonic-gate 805*0Sstevel@tonic-gate 806