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