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