4 * number registers, conversion, arithmetic
13 int falsef
= 0; /* on if inside false branch of if */
15 #define NHASHSIZE 128 /* must be 2**n */
16 #define NHASH(i) ((i>>6)^i) & (NHASHSIZE-1)
17 Numtab
*nhash
[NHASHSIZE
];
19 Numtab
*numtabp
= NULL
;
28 char buf
[NTM
]; /* for \n(.S */
31 if ((i
= cbits(ii
= getach())) == '+')
35 else if (ii
) /* don't put it back if it's already back (thanks to jaap) */
39 if ((i
= getsn()) == 0)
109 break; /* -Tterm used in nroff */
125 case 'R': /* maximal # of regs that can be addressed */
126 i
= 255*256 - regcnt
;
129 p
= unpair(dip
->curd
);
130 *pbp
++ = p
[1]; /* watch order */
137 cpushback(cfname
[ifi
]);
141 for( i
= 0; tabtab
[i
] != 0 && i
< NTAB
; i
++) {
144 sprintf(&buf
[j
], "%d", tabtab
[i
] & TABMASK
);
146 if ( tabtab
[i
] & RTAB
)
147 sprintf(&buf
[j
], "uR");
148 else if (tabtab
[i
] & CTAB
)
149 sprintf(&buf
[j
], "uC");
151 sprintf(&buf
[j
], "uL");
161 if ((j
= findr(i
)) == -1)
164 i
= numtabp
[j
].val
= numtabp
[j
].val
+ numtabp
[j
].inc
* f
;
165 nform
= numtabp
[j
].fmt
;
168 setn1(i
, nform
, (Tchar
) 0);
176 if (numbufp
>= &numbuf
[24])
184 /* insert into input number i, in format form, with size-font bits bits */
185 void setn1(int i
, int form
, Tchar bits
)
195 void prnumtab(Numtab
*p
)
198 for (i
= 0; i
< ncnt
; i
++)
201 fprintf(stderr
, "slot %d, %s, val %d\n", i
, unpair(p
[i
].r
), p
[i
].val
);
203 fprintf(stderr
, "slot %d empty\n", i
);
205 fprintf(stderr
, "slot %d empty\n", i
);
210 ncnt
= sizeof(numtab
)/sizeof(Numtab
) + NDELTA
;
211 numtabp
= (Numtab
*) grow((char *)numtabp
, ncnt
, sizeof(Numtab
));
212 if (numtabp
== NULL
) {
213 ERROR
"not enough memory for registers (%d)", ncnt WARN
;
216 numtabp
= (Numtab
*) memcpy((char *)numtabp
, (char *)numtab
,
218 if (numtabp
== NULL
) {
219 ERROR
"Cannot initialize registers" WARN
;
224 void grownumtab(void)
227 numtabp
= (Numtab
*) grow((char *) numtabp
, ncnt
, sizeof(Numtab
));
228 if (numtabp
== NULL
) {
229 ERROR
"Too many number registers (%d)", ncnt WARN
;
232 memset((char *)(numtabp
) + (ncnt
- NDELTA
) * sizeof(Numtab
),
233 0, NDELTA
* sizeof(Numtab
));
243 for (i
=0; i
<NHASHSIZE
; i
++)
245 for (p
=numtabp
; p
< &numtabp
[ncnt
]; p
++)
247 for (p
=numtabp
; p
< &numtabp
[ncnt
]; p
++) {
256 void nunhash(Numtab
*rp
)
263 lp
= &nhash
[NHASH(rp
->r
)];
284 for (p
= nhash
[h
]; p
; p
= p
->link
)
287 for (p
= numtabp
; p
< &numtabp
[ncnt
]; p
++) {
300 int usedr(int i
) /* returns -1 if nr i has never been used */
306 for (p
= nhash
[NHASH(i
)]; p
; p
= p
->link
)
313 int fnumb(int i
, int (*f
)(Tchar
))
319 j
= (*f
)('-' | nrbits
);
326 return decml(i
, f
) + j
;
329 return roman(i
, f
) + j
;
332 return abc(i
, f
) + j
;
337 int decml(int i
, int (*f
)(Tchar
))
343 if ((j
= i
/ 10) || (nform
> 0))
345 return(k
+ (*f
)((i
% 10 + '0') | nrbits
));
349 int roman(int i
, int (*f
)(Tchar
))
353 return((*f
)('0' | nrbits
));
355 return(roman0(i
, f
, "ixcmz", "vldw"));
357 return(roman0(i
, f
, "IXCMZ", "VLDW"));
361 int roman0(int i
, int (*f
)(Tchar
), char *onesp
, char *fivesp
)
367 k
= roman0(i
/ 10, f
, onesp
+ 1, fivesp
+ 1);
368 q
= (i
= i
% 10) / 5;
371 k
+= (*f
)(*onesp
| nrbits
);
376 return(k
+= (*f
)(i
| nrbits
));
379 k
+= (*f
)(*fivesp
| nrbits
);
381 k
+= (*f
)(*onesp
| nrbits
);
386 int abc(int i
, int (*f
)(Tchar
))
389 return((*f
)('0' | nrbits
));
391 return(abc0(i
- 1, f
));
395 int abc0(int i
, int (*f
)(Tchar
))
402 return(k
+ (*f
)((i
% 26 + nform
) | nrbits
));
447 ERROR
"divide by zero." WARN
;
462 if ((acc
> 0) && (i
> 0))
471 if ((acc
> 0) || (i
> 0))
477 if (cbits(ii
= getch()) != '=')
491 if (cbits(ii
= getch()) == '=')
507 if (cbits(ii
= getch()) == '=')
536 if (cbits(i
= getch()) == '(')
545 * print error about illegal numeric argument;
550 static char warn
[] = "Numeric argument expected";
551 int savcd
= numtabp
[CD
].val
;
553 if (numerr
.type
== RQERR
)
554 sprintf(err_buf
, "%c%s: %s", nb
? cbits(c2
) : cbits(cc
),
555 unpair(numerr
.req
), warn
);
557 sprintf(err_buf
, "\\%c'%s': %s", numerr
.esc
, &numerr
.escarg
,
559 if (frame
!= stk
) /* uncertainty correction */
562 numtabp
[CD
].val
= savcd
;
569 double acc
; /* this is the only double in troff! */
570 int neg
, abs
, field
, decpnt
;
574 neg
= abs
= field
= decpnt
= digits
= 0;
597 while (i
>= '0' && i
<= '9') {
600 acc
= 10 * acc
+ i
- '0';
604 if (i
== '.' && !decpnt
++) {
617 i
= j
= 1; /* should this be related to HOR?? */
619 case 'v': /*VSs - vert spacing*/
632 i
= 1; /*Same as Ems in NROFF*/
642 case 'c': /*Centimeters*/
643 /* if INCH is too big, this will overflow */
660 if (field
!= digits
&& digits
> 0)
676 nonumb
= (!field
|| field
== decpnt
);
677 if (nonumb
&& (trace
& TRNARGS
) && !ismot(ii
) && !nlflg
&& !ifnum
) {
678 if (cbits(ii
) != RIGHT
) /* Too painful to do right */
691 while (!skip() && (i
= getrq()) ) {
697 p
->r
= p
->val
= p
->inc
= p
->fmt
= 0;
703 * .nr request; if tracing, don't check optional
704 * 2nd argument because tbl generates .in 1.5n
713 if ((i
= findr(getrq())) == -1)
716 j
= inumb(&numtabp
[i
].val
);
722 j
= atoi0(); /* BUG??? */
737 if (skip() || !(i
= getrq()) || skip())
741 if (!isalpha(cbits(j
))) {
743 while ((j
= cbits(getch())) >= '0' && j
<= '9')
748 numtabp
[findr(i
)].fmt
= k
; /* was k & BYTEMASK */
751 void setaf(void) /* return format of number register */
758 if (numtabp
[i
].fmt
> 20) /* it was probably a, A, i or I */
759 *pbp
++ = numtabp
[i
].fmt
;
761 for (j
= (numtabp
[i
].fmt
? numtabp
[i
].fmt
: 1); j
; j
--)
790 if ((j
= cbits(ii
= getch())) == '+')
802 res
= dfactd
= dfact
= 1;
809 int quant(int n
, int m
)
818 /* better as i = ((n + m/2)/m)*m */
820 if (n
- m
* i
> m
/ 2)