|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)n4.c 4.1 6/7/82";
3: #endif lint
4:
5: #include "tdef.h"
6: extern
7: #include "d.h"
8: extern
9: #include "v.h"
10: #ifdef NROFF
11: extern
12: #include "tw.h"
13: #endif
14: #include "sdef.h"
15: /*
16: troff4.c
17:
18: number registers, conversion, arithmetic
19: */
20:
21: extern int inchar[LNSIZE], *pinchar; /* XXX */
22: extern struct s *frame;
23:
24: extern int ascii;
25: extern int cbuf[NC];
26: extern int *cp;
27: extern int r[NN];
28: extern int *vlist;
29: extern int inc[NN];
30: extern int fmt[NN];
31: extern int ch;
32: extern int lgf;
33: extern int pl;
34: extern int lastl;
35: extern int ralss;
36: extern int totout;
37: extern int nrbits;
38: extern int nonumb;
39: extern int vflag;
40: extern int noscale;
41: extern int dfact;
42: extern int dfactd;
43: extern int po;
44: extern int nform;
45: extern int ll;
46: extern int in;
47: extern int font;
48: extern int bdtab[];
49: extern int lss;
50: extern int pts;
51: extern int fi;
52: extern int res;
53: extern int cwidth;
54: extern int dotT;
55: extern int ev;
56: extern int ne;
57: extern int ad, admod;
58: extern int print;
59: extern int ls;
60: extern int nel, un;
61: extern int xxx;
62: int regcnt = NNAMES;
63:
64: setn()
65: {
66: register i,j;
67: int f;
68:
69: f = nform = 0;
70: if((i=getch() & CMASK) == '+')f = 1;
71: else if(i == '-')f = -1;
72: else ch = i;
73: if((i=getsn()) == 0)return;
74: if((i & 0177) == '.')switch(i>>BYTE){
75: case 's': i = pts & 077; break;
76: case 'v': i = lss; break;
77: case 'f': i = font + 1; break;
78: case 'p': i = pl; break;
79: case 't': i = findt1(); break;
80: case 'o': i = po; break;
81: case 'l': i = ll; break;
82: case 'i': i = in; break;
83: case '$': i = frame->nargs; break;
84: case 'A': i = ascii; break;
85: case 'c': i = v.cd; break;
86: case 'n': i = lastl; break;
87: case 'a': i = ralss; break;
88: case 'h': i = dip->hnl; break;
89: case 'd':
90: if(dip != d)i = dip->dnl; else i = v.nl;
91: break;
92: case 'u': i = fi; break;
93: case 'j': i = ad + 2*admod; break;
94: case 'w': i = width(*(pinchar-1)); break; /* XXX */
95: case 'x': i = nel; break;
96: case 'y': i = un; break;
97: case 'T': i = dotT; break; /*-Tterm used in nroff*/
98: case 'V': i = VERT; break;
99: case 'H': i = HOR; break;
100: case 'k': i = ne; break;
101: case 'P': i = print; break;
102: case 'L': i = ls; break;
103: case 'R': i = NN - regcnt; break;
104: case 'z': i = dip->curd;
105: cbuf[0] = i & BMASK;
106: cbuf[1] = (i >> BYTE) & BMASK;
107: cbuf[2] = 0;
108: cp = cbuf;
109: return;
110: #ifndef NROFF
111: case 'b': i = bdtab[font]; break;
112: #endif
113:
114: default:
115: goto s0;
116: }
117: else{
118: s0:
119: if((j=findr(i)) == -1)i = 0;
120: else{
121: i = (vlist[j] = (vlist[j] + inc[j]*f));
122: nform = fmt[j];
123: }
124: }
125: setn1(i);
126: cp = cbuf;
127: }
128: setn1(i)
129: int i;
130: {
131: extern int wrc();
132:
133: cp = cbuf;
134: nrbits = 0;
135: fnumb(i,wrc);
136: *cp = 0;
137: cp = cbuf;
138: }
139: findr(i)
140: int i;
141: {
142: register j;
143: static int numerr;
144:
145: if(i == 0)return(-1);
146: for(j=0;j<NN;j++){
147: if(i == r[j])break;
148: }
149: if(j != NN)return(j);
150: for(j=0; j<NN; j++){
151: if(r[j] == 0){
152: r[j] = i;
153: regcnt++;
154: break;
155: }
156: }
157: if(j==NN){
158: if(!numerr)prstrfl("Too many number registers.\n");
159: if(++numerr > 1)done2(04); else edone(04);
160: }
161: return(j);
162: }
163: fnumb(i,f)
164: int i, (*f)();
165: {
166: register j;
167:
168: j = 0;
169: if(i < 0){
170: j = (*f)('-' | nrbits);
171: i = -i;
172: }
173: switch(nform){
174: default:
175: case '1':
176: case 0: return(decml(i,f) + j);
177: case 'i':
178: case 'I': return(roman(i,f) + j);
179: case 'a':
180: case 'A': return(abc(i,f) + j);
181: }
182: }
183: decml(i,f)
184: int i, (*f)();
185: {
186: register j,k;
187:
188: k = 0;
189: nform--;
190: if((j=i/10) || (nform > 0))k = decml(j,f);
191: return(k + (*f)((i%10 + '0') | nrbits));
192: }
193: roman(i,f)
194: int i, (*f)();
195: {
196:
197: if(!i)return((*f)('0' | nrbits));
198: if(nform == 'i')return(roman0(i,f,"ixcmz","vldw"));
199: else return(roman0(i,f,"IXCMZ","VLDW"));
200: }
201: roman0(i,f,onesp,fivesp)
202: int i, (*f)();
203: char *onesp, *fivesp;
204: {
205: register q, rem, k;
206:
207: k = 0;
208: if(!i)return(0);
209: k = roman0(i/10,f,onesp+1,fivesp+1);
210: q = (i=i%10)/5;
211: rem = i%5;
212: if(rem == 4){
213: k += (*f)(*onesp | nrbits);
214: if(q)i = *(onesp+1);
215: else i = *fivesp;
216: return(k += (*f)(i | nrbits));
217: }
218: if(q)k += (*f)(*fivesp | nrbits);
219: while(--rem >= 0)
220: k += (*f)(*onesp | nrbits);
221: return(k);
222: }
223: abc(i,f)
224: int i, (*f)();
225: {
226: if(!i)return((*f)('0' | nrbits));
227: else return(abc0(i-1,f));
228: }
229: abc0(i,f)
230: int i, (*f)();
231: {
232: register j, k;
233:
234: k = 0;
235: if(j=i/26)k = abc0(j-1,f);
236: return(k + (*f)((i%26 + nform) | nrbits));
237: }
238: wrc(i)
239: int i;
240: {
241: if(cp >= &cbuf[NC])return(0);
242: *cp++ = i;
243: return(1);
244: }
245: atoi(){
246: extern long atoi0();
247:
248: return((int)atoi0());
249: }
250: long atoi0()
251: {
252: register ii, k, cnt;
253: long i, acc;
254: extern long ckph();
255:
256: i = 0; acc = 0;
257: nonumb = 0;
258: cnt = -1;
259: a0:
260: cnt++;
261: switch((ii=getch()) & CMASK){
262: default:
263: ch = ii;
264: if(cnt)break;
265: case '+':
266: i = ckph();
267: if(nonumb)break;
268: acc += i;
269: goto a0;
270: case '-':
271: i = ckph();
272: if(nonumb)break;
273: acc -= i;
274: goto a0;
275: case '*':
276: i = ckph();
277: if(nonumb)break;
278: acc *= i;
279: goto a0;
280: case '/':
281: i = ckph();
282: if(nonumb)break;
283: if(i == 0){
284: prstrfl("Divide by zero.\n");
285: acc = 0;
286: }else acc /= i;
287: goto a0;
288: case '%':
289: i = ckph();
290: if(nonumb)break;
291: acc %= i;
292: goto a0;
293: case '&': /*and*/
294: i = ckph();
295: if(nonumb)break;
296: if((acc > 0) && (i > 0))acc = 1; else acc = 0;
297: goto a0;
298: case ':': /*or*/
299: i = ckph();
300: if(nonumb)break;
301: if((acc > 0) || (i > 0))acc = 1; else acc = 0;
302: goto a0;
303: case '=':
304: if(((ii=getch()) & CMASK) != '=')ch = ii;
305: i = ckph();
306: if(nonumb){acc = 0; break;}
307: if(i == acc)acc = 1;
308: else acc = 0;
309: goto a0;
310: case '>':
311: k = 0;
312: if(((ii=getch()) & CMASK) == '=')k++; else ch =ii;
313: i = ckph();
314: if(nonumb){acc = 0; break;}
315: if(acc > (i - k))acc = 1; else acc = 0;
316: goto a0;
317: case '<':
318: k = 0;
319: if(((ii=getch()) & CMASK) == '=')k++; else ch =ii;
320: i = ckph();
321: if(nonumb){acc = 0; break;}
322: if(acc < (i + k))acc = 1; else acc = 0;
323: goto a0;
324: case ')': break;
325: case '(':
326: acc = atoi0();
327: goto a0;
328: }
329: return(acc);
330: }
331: long ckph(){
332: register i;
333: long j;
334: extern long atoi0();
335: extern long atoi1();
336:
337: if(((i = getch()) & CMASK) == '(')j = atoi0();
338: else{
339: ch = i;
340: j = atoi1();
341: }
342: return(j);
343: }
344: long atoi1()
345: {
346: register i, j, digits;
347: long acc;
348: int neg, abs, field;
349:
350: neg = abs = field = digits = 0;
351: acc = 0;
352: a0:
353: switch((i = getch()) & CMASK){
354: default:
355: ch = i;
356: break;
357: case '+':
358: goto a0;
359: case '-':
360: neg = 1;
361: goto a0;
362: case '|':
363: abs = 1 + neg;
364: neg = 0;
365: goto a0;
366: }
367: a1:
368: while(((j = ((i = getch()) & CMASK) - '0') >= 0) && (j <= 9)){
369: field++;
370: digits++;
371: acc = 10*acc + j;
372: }
373: if((i & CMASK) == '.'){
374: field++;
375: digits = 0;
376: goto a1;
377: }
378: ch = i;
379: if(!field)goto a2;
380: switch((i = getch()) & CMASK){
381: case 'u':
382: i = j = 1;
383: break;
384: case 'v': /*VSs - vert spacing*/
385: j = lss;
386: i = 1;
387: break;
388: case 'm': /*Ems*/
389: j = EM;
390: i = 1;
391: break;
392: case 'n': /*Ens*/
393: j = EM;
394: #ifndef NROFF
395: i = 2;
396: #endif
397: #ifdef NROFF
398: i = 1; /*Same as Ems in NROFF*/
399: #endif
400: break;
401: case 'p': /*Points*/
402: j = INCH;
403: i = 72;
404: break;
405: case 'i': /*Inches*/
406: j = INCH;
407: i = 1;
408: break;
409: case 'c': /*Centimeters*/
410: j = INCH*50;
411: i = 127;
412: break;
413: case 'P': /*Picas*/
414: j = INCH;
415: i = 6;
416: break;
417: default:
418: j = dfact;
419: ch = i;
420: i = dfactd;
421: }
422: if(neg) acc = -acc;
423: if(!noscale){
424: acc = (acc*j)/i;
425: }
426: if((field != digits) && (digits > 0))while(digits--)acc /= 10;
427: if(abs){
428: if(dip != d)j = dip->dnl; else j = v.nl;
429: if(!vflag)j = v.hp = sumhp(); /* XXX */
430: if(abs == 2)j = -j;
431: acc -= j;
432: }
433: a2:
434: nonumb = !field;
435: return(acc);
436: }
437: caserr(){
438: register i,j;
439:
440: lgf++;
441: while(!skip() && (i=getrq()) ){
442: for(j=NNAMES; j<NN; j++){ /*NNAMES predefined names*/
443: if(i == r[j])break;
444: }
445: if(j!=NN){
446: r[j]=vlist[j]=inc[j]=fmt[j]=0;
447: regcnt--;
448: }
449: }
450: }
451: casenr(){
452: register i, j;
453:
454: lgf++;
455: skip();
456: if((i = findr(getrq())) == -1)goto rtn;
457: skip();
458: j = inumb(&vlist[i]);
459: if(nonumb)goto rtn;
460: vlist[i] = j;
461: skip();
462: j = atoi();
463: if(nonumb)goto rtn;
464: inc[i] = j;
465: rtn:
466: return;
467: }
468: caseaf(){
469: register i, j, k;
470:
471: lgf++;
472: if(skip() || !(i = getrq()) || skip())return;
473: k = 0;
474: if(!alph(j=getch())){
475: ch = j;
476: while(((j = getch() & CMASK) >= '0') &&
477: (j <= '9'))k++;
478: }
479: if(!k)k=j;
480: fmt[findr(i)] = k & BMASK;
481: }
482: vnumb(i)
483: int *i;
484: {
485: vflag++;
486: dfact = lss;
487: res = VERT;
488: return(inumb(i));
489: }
490: hnumb(i)
491: int *i;
492: {
493: dfact = EM;
494: res = HOR;
495: return(inumb(i));
496: }
497: inumb(n)
498: int *n;
499: {
500: register i, j, f;
501:
502: f = 0;
503: if(n){
504: if((j = (i = getch()) & CMASK) == '+')f = 1;
505: else if(j == '-')f = -1;
506: else ch = i;
507: }
508: i = atoi();
509: if(n && f)i = *n + f*i;
510: i = quant(i,res);
511: vflag = 0;
512: res = dfactd = dfact = 1;
513: if(nonumb)i = 0;
514: return(i);
515: }
516: quant(n,m)
517: int n, m;
518: {
519: register i, neg;
520:
521: neg = 0;
522: if(n<0){
523: neg++;
524: n = -n;
525: }
526: i = n/m;
527: if((n - m*i) > (m/2))i += 1;
528: i *= m;
529: if(neg)i = -i;
530: return(i);
531: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.