|
|
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: /*
13: troff3.c
14:
15: macro and string routines, storage allocation
16: */
17:
18: unsigned blist[NBLIST];
19: extern struct s *frame, *stk, *nxf;
20: extern filep ip;
21: extern filep offset;
22: extern filep nextb;
23: extern char *enda;
24:
25: extern int ch;
26: extern int ibf;
27: extern int lgf;
28: extern int copyf;
29: extern int ch0;
30: extern int app;
31: extern int ds;
32: extern int nlflg;
33: extern int *argtop;
34: extern int *ap;
35: extern int nchar;
36: extern int pendt;
37: extern int rchar;
38: extern int dilev;
39: extern int nonumb;
40: extern int lt;
41: extern int nrbits;
42: extern int nform;
43: extern int fmt[];
44: extern int oldmn;
45: extern int newmn;
46: extern int macerr;
47: extern filep apptr;
48: extern int diflg;
49: extern filep woff;
50: extern filep roff;
51: extern int wbfi;
52: extern int po;
53: extern int *cp;
54: extern int xxx;
55: int pagech = '%';
56: int strflg;
57: extern struct contab {
58: int rq;
59: union {
60: int (*f)();
61: unsigned mx;
62: }x;
63: }contab[NM];
64: #ifndef VMUNIX
65: int wbuf[BLK];
66: int rbuf[BLK];
67: #else
68: int *wbuf;
69: int *rbuf;
70: int Buf[NBLIST*BLK + NEV*EVS];
71: #endif
72:
73: caseig(){
74: register i;
75:
76: offset = 0;
77: if((i = copyb()) != '.')control(i,1);
78: }
79: casern(){
80: register i,j;
81:
82: lgf++;
83: skip();
84: if(((i=getrq())==0) || ((oldmn=findmn(i)) < 0))return;
85: skip();
86: clrmn(findmn(j=getrq()));
87: if(j)contab[oldmn].rq = (contab[oldmn].rq & MMASK) | j;
88: }
89: caserm(){
90: lgf++;
91: while(!skip()){
92: clrmn(findmn(getrq()));
93: }
94: }
95: caseas(){
96: app++;
97: caseds();
98: }
99: caseds(){
100: ds++;
101: casede();
102: }
103: caseam(){
104: app++;
105: casede();
106: }
107: casede(){
108: register i, req;
109: register filep savoff;
110: extern filep finds();
111:
112: if(dip != d)wbfl();
113: req = '.';
114: lgf++;
115: skip();
116: if((i=getrq())==0)goto de1;
117: if((offset=finds(i)) == 0)goto de1;
118: if(ds)copys();
119: else req = copyb();
120: wbfl();
121: clrmn(oldmn);
122: if(newmn)contab[newmn].rq = i | MMASK;
123: if(apptr){
124: savoff = offset;
125: offset = apptr;
126: wbt(IMP);
127: offset = savoff;
128: }
129: offset = dip->op;
130: if(req != '.')control(req,1);
131: de1:
132: ds = app = 0;
133: return;
134: }
135: findmn(i)
136: int i;
137: {
138: register j;
139:
140: for(j=0;j<NM;j++){
141: if(i == (contab[j].rq & ~MMASK))break;
142: }
143: if(j==NM)j = -1;
144: return(j);
145: }
146: clrmn(i)
147: int i;
148: {
149: extern filep boff();
150: if(i >= 0){
151: if(contab[i].rq & MMASK)ffree(((filep)contab[i].x.mx)<<BLKBITS);
152: contab[i].rq = 0;
153: contab[i].x.mx = 0;
154: }
155: }
156: filep finds(mn)
157: int mn;
158: {
159: register i;
160: extern filep boff();
161: register filep savip;
162: extern filep alloc();
163: extern filep incoff();
164:
165: oldmn = findmn(mn);
166: newmn = 0;
167: apptr = (filep)0;
168: if(app && (oldmn >= 0) && (contab[oldmn].rq & MMASK)){
169: savip = ip;
170: ip = (((filep)contab[oldmn].x.mx)<<BLKBITS);
171: oldmn = -1;
172: while((i=rbf()) != 0);
173: apptr = ip;
174: if(!diflg)ip = incoff(ip);
175: nextb = ip;
176: ip = savip;
177: }else{
178: for(i=0;i<NM;i++){
179: if(contab[i].rq == 0)break;
180: }
181: if((i==NM) ||
182: (nextb = alloc()) == 0){
183: app = 0;
184: if(macerr++ > 1)done2(02);
185: prstr("Too many string/macro names.\n");
186: edone(04);
187: return(offset = 0);
188: }
189: contab[i].x.mx = (unsigned)(nextb>>BLKBITS);
190: if(!diflg){
191: newmn = i;
192: if(oldmn == -1)contab[i].rq = -1;
193: }else{
194: contab[i].rq = mn | MMASK;
195: }
196: }
197:
198: app = 0;
199: return(offset = nextb);
200: }
201: skip(){
202: register i;
203:
204: while(((i=getch()) & CMASK) == ' ');
205: ch=i;
206: return(nlflg);
207: }
208: copyb()
209: {
210: register i, j, k;
211: int ii, req, state;
212: filep savoff;
213:
214: if(skip() || !(j=getrq()))j = '.';
215: req = j;
216: k = j>>BYTE;
217: j &= BMASK;
218: copyf++;
219: flushi();
220: nlflg = 0;
221: state = 1;
222: while(1){
223: i = (ii = getch()) & CMASK;
224: if(state == 3){
225: if(i == k)break;
226: if(!k){
227: ch = ii;
228: i = getach();
229: ch = ii;
230: if(!i)break;
231: }
232: state = 0;
233: goto c0;
234: }
235: if(i == '\n'){
236: state = 1;
237: nlflg = 0;
238: goto c0;
239: }
240: if((state == 1) && (i == '.')){
241: state++;
242: savoff = offset;
243: goto c0;
244: }
245: if((state == 2) && (i == j)){
246: state++;
247: goto c0;
248: }
249: state = 0;
250: c0:
251: if(offset)wbf(ii);
252: }
253: if(offset){
254: wbfl();
255: offset = savoff;
256: wbt(0);
257: }
258: copyf--;
259: return(req);
260: }
261: copys()
262: {
263: register i;
264:
265: copyf++;
266: if(skip())goto c0;
267: if(((i=getch()) & CMASK) != '"')wbf(i);
268: while(((i=getch()) & CMASK) != '\n')wbf(i);
269: c0:
270: wbt(0);
271: copyf--;
272: }
273: filep alloc()
274: {
275: register i;
276: extern filep boff();
277: filep j;
278:
279: for(i=0;i<NBLIST;i++){
280: if(blist[i] == 0)break;
281: }
282: if(i==NBLIST){
283: j = 0;
284: }else{
285: blist[i] = -1;
286: if((j = boff(i)) < NEV*EVS)j = 0;
287: }
288: return(nextb = j);
289: }
290: ffree(i)
291: filep i;
292: {
293: register j;
294:
295: while((blist[j = blisti(i)]) != -1){
296: i = ((filep)blist[j])<<BLKBITS;
297: blist[j] = 0;
298: }
299: blist[j] = 0;
300: }
301: filep boff(i)
302: int i;
303: {
304: return(((filep)i)*BLK + NEV*EVS);
305: }
306: wbt(i)
307: int i;
308: {
309: wbf(i);
310: wbfl();
311: }
312: wbf(i)
313: int i;
314: {
315: register j;
316:
317: if(!offset)return;
318: if(!woff){
319: woff = offset;
320: #ifdef VMUNIX
321: wbuf = &Buf[woff];
322: #endif
323: wbfi = 0;
324: }
325: wbuf[wbfi++] = i;
326: if(!((++offset) & (BLK-1))){
327: wbfl();
328: if(blist[j = blisti(--offset)] == -1){
329: if(alloc() == 0){
330: prstr("Out of temp file space.\n");
331: done2(01);
332: }
333: blist[j] = (unsigned)(nextb>>BLKBITS);
334: }
335: offset = ((filep)blist[j])<<BLKBITS;
336: }
337: if(wbfi >= BLK)wbfl();
338: }
339: wbfl(){
340: if(woff == 0)return;
341: #ifndef VMUNIX
342: lseek(ibf, ((long)woff) * sizeof(int), 0);
343: write(ibf, (char *)wbuf, wbfi * sizeof(int));
344: #endif
345: if((woff & (~(BLK-1))) == (roff & (~(BLK-1))))roff = -1;
346: woff = 0;
347: }
348: blisti(i)
349: filep i;
350: {
351: return((i-NEV*EVS)/(BLK));
352: }
353: rbf(){
354: register i;
355: extern filep incoff();
356:
357: if((i=rbf0(ip)) == 0){
358: if(!app)i = popi();
359: }else{
360: ip = incoff(ip);
361: }
362: return(i);
363: }
364: rbf0(p)
365: filep p;
366: {
367: register filep i;
368:
369: if((i = (p & (~(BLK-1)))) != roff){
370: roff = i;
371: #ifndef VMUNIX
372: lseek(ibf, ((long)roff) * sizeof(int), 0);
373: if(read(ibf, (char *)rbuf, BLK * sizeof(int)) == 0)return(0);
374: #else
375: rbuf = &Buf[roff];
376: #endif
377: }
378: return(rbuf[p & (BLK-1)]);
379: }
380: filep incoff(p)
381: filep p;
382: {
383: register i;
384: register filep j;
385: if(!((j = (++p)) & (BLK-1))){
386: if((i = blist[blisti(--p)]) == -1){
387: prstr("Bad storage allocation.\n");
388: done2(-5);
389: }
390: j = ((filep)i)<<BLKBITS;
391: }
392: return(j);
393: }
394: popi(){
395: register struct s *p;
396:
397: if(frame == stk)return(0);
398: if(strflg)strflg--;
399: p = nxf = frame;
400: p->nargs = 0;
401: frame = p->pframe;
402: ip = p->pip;
403: nchar = p->pnchar;
404: rchar = p->prchar;
405: pendt = p->ppendt;
406: ap = p->pap;
407: cp = p->pcp;
408: ch0 = p->pch0;
409: return(p->pch);
410: }
411: pushi(newip)
412: filep newip;
413: {
414: register struct s *p;
415: extern char *setbrk();
416:
417: if((enda - sizeof(struct s)) < (char *)nxf)setbrk(DELTA);
418: p = nxf;
419: p->pframe = frame;
420: p->pip = ip;
421: p->pnchar = nchar;
422: p->prchar = rchar;
423: p->ppendt = pendt;
424: p->pap = ap;
425: p->pcp = cp;
426: p->pch0 = ch0;
427: p->pch = ch;
428: cp = ap = 0;
429: nchar = rchar = pendt = ch0 = ch = 0;
430: frame = nxf;
431: if(nxf->nargs == 0) nxf += 1;
432: else nxf = (struct s *)argtop;
433: return(ip = newip);
434: }
435: char *setbrk(x)
436: int x;
437: {
438: register char *i;
439: char *sbrk();
440:
441: if((i = sbrk(x)) == MAXPTR){
442: prstrfl("Core limit reached.\n");
443: edone(0100);
444: }else{
445: enda = i + x;
446: }
447: return(i);
448: }
449: getsn(){
450: register i;
451:
452: if((i=getach()) == 0)return(0);
453: if(i == '(')return(getrq());
454: else return(i);
455: }
456: setstr(){
457: register i;
458:
459: lgf++;
460: if(((i=getsn()) == 0) ||
461: ((i=findmn(i)) == -1) ||
462: !(contab[i].rq & MMASK)){
463: lgf--;
464: return(0);
465: }else{
466: if((enda-2) < (char *)nxf)setbrk(DELTA);
467: nxf->nargs = 0;
468: strflg++;
469: lgf--;
470: return(pushi(((filep)contab[i].x.mx)<<BLKBITS));
471: }
472: }
473: collect()
474: {
475: register i;
476: register int *strp;
477: int *lim;
478: int **argpp, **argppend;
479: int quote;
480: struct s *savnxf;
481:
482: copyf++;
483: nxf->nargs = 0;
484: savnxf = nxf;
485: if(skip())goto rtn;
486: lim = (int *)(nxf = savnxf + sizeof(struct s)/sizeof(savnxf));
487: strflg = 0;
488: if((argppend =
489: (argpp = (int **)savnxf+(sizeof(struct s)/sizeof(int **))) + 9)
490: > (int **)enda)setbrk(DELTA);
491: strp = (int *)argppend;
492: for(i=8; i>=0; i--)argpp[i] = 0;
493: while((argpp != argppend) && (!skip())){
494: *argpp++ = strp;
495: quote = 0;
496: if(((i = getch()) & CMASK) == '"')quote++;
497: else ch = i;
498: while(1){
499: i = getch();
500: if( nlflg ||
501: ((!quote) && ((i & CMASK) == ' ')))break;
502: if(quote && ((i & CMASK) == '"') &&
503: (((i=getch()) & CMASK) != '"')){
504: ch = i;
505: break;
506: }
507: *strp++ = i;
508: if(strflg && (strp >= lim)){
509: prstrfl("Macro argument too long.\n");
510: copyf--;
511: edone(004);
512: }
513: if((enda-4) <= (char *)strp)setbrk(DELTA);
514: }
515: *strp++ = 0;
516: }
517: nxf = savnxf;
518: nxf->nargs = argpp -(int **)(nxf + 1);
519: argtop = strp;
520: rtn:
521: copyf--;
522: }
523: seta()
524: {
525: register i;
526:
527: if(((i = (getch() & CMASK) - '0') > 0) &&
528: (i <= 9) && (i <= frame->nargs))ap = *((int **)frame + i-1 + (sizeof(struct s)/sizeof(int **)));
529: }
530: caseda(){
531: app++;
532: casedi();
533: }
534: casedi(){
535: register i, j;
536: register *k;
537:
538: lgf++;
539: if(skip() || ((i=getrq()) == 0)){
540: if(dip != d)wbt(0);
541: if(dilev > 0){
542: v.dn = dip->dnl;
543: v.dl = dip->maxl;
544: dip = &d[--dilev];
545: offset = dip->op;
546: }
547: goto rtn;
548: }
549: if(++dilev == NDI){
550: --dilev;
551: prstr("Cannot divert.\n");
552: edone(02);
553: }
554: if(dip != d)wbt(0);
555: diflg++;
556: dip = &d[dilev];
557: dip->op = finds(i);
558: dip->curd = i;
559: clrmn(oldmn);
560: k = (int *)&dip->dnl;
561: for(j=0; j<10; j++)k[j] = 0; /*not op and curd*/
562: rtn:
563: app = 0;
564: diflg = 0;
565: }
566: casedt(){
567: lgf++;
568: dip->dimac = dip->ditrap = dip->ditf = 0;
569: skip();
570: dip->ditrap = vnumb((int *)0);
571: if(nonumb)return;
572: skip();
573: dip->dimac = getrq();
574: }
575: casetl(){
576: register i, j;
577: int w1, w2, w3, delim;
578: filep begin;
579: extern width(), pchar();
580:
581: dip->nls = 0;
582: skip();
583: if(dip != d)wbfl();
584: if((offset = begin = alloc()) == 0)return;
585: if((delim = getch()) & MOT){
586: ch = delim;
587: delim = '\'';
588: }else delim &= CMASK;
589: if(!nlflg)
590: while(((i = getch()) & CMASK) != '\n'){
591: if((i & CMASK) == delim)i = IMP;
592: wbf(i);
593: }
594: wbf(IMP);wbf(IMP);wbt(0);
595:
596: w1 = hseg(width,begin);
597: w2 = hseg(width,(filep)0);
598: w3 = hseg(width,(filep)0);
599: offset = dip->op;
600: #ifdef NROFF
601: if(!offset)horiz(po);
602: #endif
603: hseg(pchar,begin);
604: if(w2 || w3)horiz(j=quant((lt - w2)/2-w1,HOR));
605: hseg(pchar,(filep)0);
606: if(w3){
607: horiz(lt-w1-w2-w3-j);
608: hseg(pchar,(filep)0);
609: }
610: newline(0);
611: if(dip != d){if(dip->dnl > dip->hnl)dip->hnl = dip->dnl;}
612: else{if(v.nl > dip->hnl)dip->hnl = v.nl;}
613: ffree(begin);
614: }
615: casepc(){
616: pagech = chget(IMP);
617: }
618: hseg(f,p)
619: int (*f)();
620: filep p;
621: {
622: register acc, i;
623: static filep q;
624:
625: acc = 0;
626: if(p)q = p;
627: while(1){
628: i = rbf0(q);
629: q = incoff(q);
630: if(!i || (i == IMP))return(acc);
631: if((i & CMASK) == pagech){
632: nrbits = i & ~CMASK;
633: nform = fmt[findr('%')];
634: acc += fnumb(v.pn,f);
635: }else acc += (*f)(i);
636: }
637: }
638: casepm(){
639: register i, k;
640: register char *p;
641: int xx, cnt, kk, tot;
642: filep j;
643: char *kvt();
644: char pmline[10];
645:
646: kk = cnt = 0;
647: tot = !skip();
648: for(i = 0; i<NM; i++){
649: if(!((xx = contab[i].rq) & MMASK))continue;
650: p = pmline;
651: j = (((filep)contab[i].x.mx)<<BLKBITS);
652: k = 1;
653: while((j = blist[blisti(j)]) != -1){k++; j <<= BLKBITS;}
654: cnt++;
655: kk += k;
656: if(!tot){
657: *p++ = xx & 0177;
658: if(!(*p++ = (xx >> BYTE) & 0177))*(p-1) = ' ';
659: *p++ = ' ';
660: kvt(k,p);
661: prstr(pmline);
662: }
663: }
664: if(tot || (cnt > 1)){
665: kvt(kk,pmline);
666: prstr(pmline);
667: }
668: }
669: char *kvt(k,p)
670: int k;
671: char *p;
672: {
673: if(k>=100)*p++ = k/100 + '0';
674: if(k>=10)*p++ = (k%100)/10 + '0';
675: *p++ = k%10 + '0';
676: *p++ = '\n';
677: *p = 0;
678: return(p);
679: }
680: dummy(){}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.