|
|
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: #include <sgtty.h>
19: #include "ext.h"
20: #define blisti(i) (((i)-NEV*EVS)/BLK)
21: filep blist[NBLIST];
22: tchar *argtop;
23: int pagech = '%';
24: int strflg;
25: extern struct contab {
26: int rq;
27: union {
28: int (*f)();
29: unsigned mx;
30: } x;
31: } contab[NM];
32:
33: #ifdef INCORE
34: tchar *wbuf;
35: tchar *rbuf;
36: tchar corebuf[NBLIST*BLK];
37: #else
38: tchar wbuf[BLK];
39: tchar rbuf[BLK];
40: #endif
41:
42: caseig()
43: {
44: register i;
45:
46: offset = 0;
47: if ((i = copyb()) != '.')
48: control(i, 1);
49: }
50:
51:
52: casern()
53: {
54: register i, j;
55:
56: lgf++;
57: skip();
58: if ((i = getrq()) == 0 || (oldmn = findmn(i)) < 0)
59: return;
60: skip();
61: clrmn(findmn(j = getrq()));
62: if (j)
63: contab[oldmn].rq = (contab[oldmn].rq & MMASK) | j;
64: }
65:
66:
67: caserm()
68: {
69: lgf++;
70: while (!skip()) {
71: clrmn(findmn(getrq()));
72: }
73: }
74:
75:
76: caseas()
77: {
78: app++;
79: caseds();
80: }
81:
82:
83: caseds()
84: {
85: ds++;
86: casede();
87: }
88:
89:
90: caseam()
91: {
92: app++;
93: casede();
94: }
95:
96:
97: casede()
98: {
99: register i, req;
100: register filep savoff;
101: extern filep finds();
102:
103: if (dip != d)
104: wbfl();
105: req = '.';
106: lgf++;
107: skip();
108: if ((i = getrq()) == 0)
109: goto de1;
110: if ((offset = finds(i)) == 0)
111: goto de1;
112: if (ds)
113: copys();
114: else
115: req = copyb();
116: wbfl();
117: clrmn(oldmn);
118: if (newmn)
119: contab[newmn].rq = i | MMASK;
120: if (apptr) {
121: savoff = offset;
122: offset = apptr;
123: wbt((tchar) IMP);
124: offset = savoff;
125: }
126: offset = dip->op;
127: if (req != '.')
128: control(req, 1);
129: de1:
130: ds = app = 0;
131: return;
132: }
133:
134:
135: findmn(i)
136: register int i;
137: {
138: register j;
139: register struct contab *p;
140:
141: for (p = contab; p < &contab[NM]; p++) {
142: if (i == (p->rq & ~MMASK))
143: break;
144: }
145: j = p - contab;
146: if (j == NM)
147: j = -1;
148: return(j);
149: }
150:
151:
152: clrmn(i)
153: register int i;
154: {
155: if (i >= 0) {
156: if (contab[i].rq & MMASK)
157: ffree((filep)contab[i].x.mx);
158: contab[i].rq = 0;
159: contab[i].x.mx = 0;
160: }
161: }
162:
163:
164: filep finds(mn)
165: register int mn;
166: {
167: register i;
168: register filep savip;
169: extern filep alloc();
170: extern filep incoff();
171:
172: oldmn = findmn(mn);
173: newmn = 0;
174: apptr = (filep)0;
175: if (app && oldmn >= 0 && (contab[oldmn].rq & MMASK)) {
176: savip = ip;
177: ip = (filep)contab[oldmn].x.mx;
178: oldmn = -1;
179: while ((i = rbf()) != 0)
180: ;
181: apptr = ip;
182: if (!diflg)
183: ip = incoff(ip);
184: nextb = ip;
185: ip = savip;
186: } else {
187: for (i = 0; i < NM; i++) {
188: if (contab[i].rq == 0)
189: break;
190: }
191: if (i == NM || (nextb = alloc()) == 0) {
192: app = 0;
193: if (macerr++ > 1)
194: done2(02);
195: fprintf(stderr, "troff: Too many (%d) string/macro names.\n", NM);
196: edone(04);
197: return(offset = 0);
198: }
199: contab[i].x.mx = (unsigned) nextb;
200: if (!diflg) {
201: newmn = i;
202: if (oldmn == -1)
203: contab[i].rq = -1;
204: } else {
205: contab[i].rq = mn | MMASK;
206: }
207: }
208: app = 0;
209: return(offset = nextb);
210: }
211:
212:
213: skip()
214: {
215: tchar i;
216:
217: while (cbits(i = getch()) == ' ')
218: ;
219: ch = i;
220: return(nlflg);
221: }
222:
223:
224: copyb()
225: {
226: register i, j, k;
227: int req, state;
228: tchar ii;
229: filep savoff;
230:
231: if (skip() || !(j = getrq()))
232: j = '.';
233: req = j;
234: k = j >> BYTE;
235: j &= BMASK;
236: copyf++;
237: flushi();
238: nlflg = 0;
239: state = 1;
240: while (1) {
241: i = cbits(ii = getch());
242: if (state == 3) {
243: if (i == k)
244: break;
245: if (!k) {
246: ch = ii;
247: i = getach();
248: ch = ii;
249: if (!i)
250: break;
251: }
252: state = 0;
253: goto c0;
254: }
255: if (i == '\n') {
256: state = 1;
257: nlflg = 0;
258: goto c0;
259: }
260: if (state == 1 && i == '.') {
261: state++;
262: savoff = offset;
263: goto c0;
264: }
265: if ((state == 2) && (i == j)) {
266: state++;
267: goto c0;
268: }
269: state = 0;
270: c0:
271: if (offset)
272: wbf(ii);
273: }
274: if (offset) {
275: wbfl();
276: offset = savoff;
277: wbt((tchar)0);
278: }
279: copyf--;
280: return(req);
281: }
282:
283:
284: copys()
285: {
286: tchar i;
287:
288: copyf++;
289: if (skip())
290: goto c0;
291: if (cbits(i = getch()) != '"')
292: wbf(i);
293: while (cbits(i = getch()) != '\n')
294: wbf(i);
295: c0:
296: wbt((tchar)0);
297: copyf--;
298: }
299:
300:
301: filep alloc()
302: {
303: register i;
304: filep j;
305:
306: for (i = 0; i < NBLIST; i++) {
307: if (blist[i] == 0)
308: break;
309: }
310: if (i == NBLIST) {
311: j = 0;
312: } else {
313: blist[i] = -1;
314: if ((j = ((filep)i * BLK + NEV * EVS)) < NEV * EVS)
315: j = 0;
316: }
317: return(nextb = j);
318: }
319:
320:
321: ffree(i)
322: filep i;
323: {
324: register j;
325:
326: while ((blist[j = blisti(i)]) != -1) {
327: i = ((filep)blist[j]);
328: blist[j] = 0;
329: }
330: blist[j] = 0;
331: }
332:
333:
334: wbt(i)
335: tchar i;
336: {
337: wbf(i);
338: wbfl();
339: }
340:
341:
342: wbf(i)
343: tchar i;
344: {
345: register j;
346:
347: if (!offset)
348: return;
349: if (!woff) {
350: woff = offset;
351: #ifdef INCORE
352: wbuf = &corebuf[woff]; /* INCORE only */
353: #endif
354: wbfi = 0;
355: }
356: wbuf[wbfi++] = i;
357: if (!((++offset) & (BLK - 1))) {
358: wbfl();
359: if (blist[j = blisti(--offset)] == -1) {
360: if (alloc() == 0) {
361: fprintf(stderr, "troff: Out of temp file space at %d.\n", v.cd);
362: done2(01);
363: }
364: blist[j] = (unsigned)(nextb);
365: }
366: offset = ((filep)blist[j]);
367: }
368: if (wbfi >= BLK)
369: wbfl();
370: }
371:
372:
373: wbfl()
374: {
375: if (woff == 0)
376: return;
377: #ifndef INCORE
378: lseek(ibf, ((long)woff) * sizeof(tchar), 0);
379: write(ibf, (char *)wbuf, wbfi * sizeof(tchar));
380: #endif
381: if ((woff & (~(BLK - 1))) == (roff & (~(BLK - 1))))
382: roff = -1;
383: woff = 0;
384: }
385:
386:
387: tchar rbf()
388: {
389: tchar i;
390: register filep j, p;
391: extern filep incoff();
392:
393: /* this is an inline expansion of rbf0: dirty! */
394: if ((j = ip & ~(BLK - 1)) != roff) {
395: roff = j;
396: #ifndef INCORE
397: lseek(ibf, (long)roff * sizeof(tchar), 0);
398: if (read(ibf, (char *)rbuf, BLK * sizeof(tchar)) == 0)
399: i = 0;
400: else
401: i = rbuf[ip & (BLK-1)];
402: #else
403: rbuf = &corebuf[roff];
404: i = rbuf[ip & (BLK-1)];
405: #endif
406: } else
407: i = rbuf[ip & (BLK-1)];
408: /* end of rbf0 */
409: if (i == 0) {
410: if (!app)
411: i = popi();
412: } else {
413: /* this is an inline expansion of incoff: also dirty */
414: int i;
415: p = ip;
416: if (!((j = ++p) & (BLK - 1))) {
417: if ((i = blist[blisti(--p)]) == -1) {
418: fprintf(stderr, "troff: Bad storage allocation.\n");
419: done2(-5);
420: }
421: j = ((filep)i);
422: }
423: ip = j;
424: }
425: return(i);
426: }
427:
428:
429: tchar rbf0(p)
430: register filep p;
431: {
432: register filep i;
433:
434: if ((i = p & ~(BLK - 1)) != roff) {
435: roff = i;
436: #ifndef INCORE
437: lseek(ibf, (long)roff * sizeof(tchar), 0);
438: if (read(ibf, (char *)rbuf, BLK * sizeof(tchar)) == 0)
439: return(0);
440: #else
441: rbuf = &corebuf[roff];
442: #endif
443: }
444: return(rbuf[p & (BLK-1)]);
445: }
446:
447:
448: filep incoff(p)
449: register filep p;
450: {
451: register i;
452: register filep j;
453:
454: if (!((j = ++p) & (BLK - 1))) {
455: if ((i = blist[blisti(--p)]) == -1) {
456: fprintf(stderr, "troff: Bad storage allocation.\n");
457: done2(-5);
458: }
459: j = (filep) i;
460: }
461: return(j);
462: }
463:
464:
465: tchar popi()
466: {
467: register struct s *p;
468:
469: if (frame == stk)
470: return(0);
471: if (strflg)
472: strflg--;
473: p = nxf = frame;
474: p->nargs = 0;
475: frame = p->pframe;
476: ip = p->pip;
477: nchar = p->pnchar;
478: rchar = p->prchar;
479: pendt = p->ppendt;
480: ap = p->pap;
481: cp = p->pcp;
482: ch0 = p->pch0;
483: return(p->pch);
484: }
485:
486: /*
487: * test that the end of the allocation is above a certain location
488: * in memory
489: */
490: #define SPACETEST(base, size) while ((enda - (size)) <= (char *)(base)){setbrk(DELTA);}
491:
492: pushi(newip)
493: filep newip;
494: {
495: register struct s *p;
496: extern char *setbrk();
497:
498: SPACETEST(nxf, sizeof(struct s));
499: p = nxf;
500: p->pframe = frame;
501: p->pip = ip;
502: p->pnchar = nchar;
503: p->prchar = rchar;
504: p->ppendt = pendt;
505: p->pap = ap;
506: p->pcp = cp;
507: p->pch0 = ch0;
508: p->pch = ch;
509: cp = ap = 0;
510: nchar = rchar = pendt = ch0 = ch = 0;
511: frame = nxf;
512: if (nxf->nargs == 0)
513: nxf += 1;
514: else
515: nxf = (struct s *)argtop;
516: return(ip = newip);
517: }
518:
519:
520: char *setbrk(x)
521: int x;
522: {
523: register char *i;
524: char *sbrk();
525:
526: if (x % 2 == 1)
527: x++;
528: if ((i = sbrk(x)) == MAXPTR) {
529: fprintf(stderr, "troff: Core limit reached.\n");
530: edone(0100);
531: } else {
532: enda = i + x;
533: }
534: return(i);
535: }
536:
537:
538: getsn()
539: {
540: register i;
541:
542: if ((i = getach()) == 0)
543: return(0);
544: if (i == '(')
545: return(getrq());
546: else
547: return(i);
548: }
549:
550:
551: setstr()
552: {
553: register i;
554:
555: lgf++;
556: if (((i = getsn()) == 0) || ((i = findmn(i)) == -1) || !(contab[i].rq & MMASK)) {
557: lgf--;
558: return(0);
559: } else {
560: SPACETEST(nxf, sizeof(struct s));
561: nxf->nargs = 0;
562: strflg++;
563: lgf--;
564: return(pushi(((filep)contab[i].x.mx)));
565: }
566: }
567:
568:
569:
570: collect()
571: {
572: register j;
573: tchar i;
574: register tchar *strp;
575: tchar * lim;
576: tchar * *argpp, **argppend;
577: int quote;
578: struct s *savnxf;
579:
580: copyf++;
581: nxf->nargs = 0;
582: savnxf = nxf;
583: if (skip())
584: goto rtn;
585:
586: {
587: char *memp;
588: memp = (char *)savnxf;
589: /*
590: * 1 s structure for the macro descriptor
591: * APERMAC tchar *'s for pointers into the strings
592: * space for the tchar's themselves
593: */
594: memp += sizeof(struct s);
595: /*
596: * CPERMAC (the total # of characters for ALL arguments)
597: * to a macros, has been carefully chosen
598: * so that the distance between stack frames is < DELTA
599: */
600: #define CPERMAC 200
601: #define APERMAC 9
602: memp += APERMAC * sizeof(tchar *);
603: memp += CPERMAC * sizeof(tchar);
604: nxf = (struct s*)memp;
605: }
606: lim = (tchar *)nxf;
607: argpp = (tchar **)(savnxf + 1);
608: argppend = &argpp[APERMAC];
609: SPACETEST(argppend, sizeof(tchar *));
610: strp = (tchar *)argppend;
611: /*
612: * Zero out all the string pointers before filling them in.
613: */
614: for (j = 0; j < APERMAC; j++){
615: argpp[j] = (tchar *)0;
616: }
617: #if 0
618: fprintf(stderr, "savnxf=0x%x,nxf=0x%x,argpp=0x%x,strp=argppend=0x%x,lim=0x%x,enda=0x%x\n",
619: savnxf, nxf, argpp, strp, lim, enda);
620: #endif 0
621: strflg = 0;
622: while ((argpp != argppend) && (!skip())) {
623: *argpp++ = strp;
624: quote = 0;
625: if (cbits(i = getch()) == '"')
626: quote++;
627: else
628: ch = i;
629: while (1) {
630: i = getch();
631: if ( nlflg || (!quote && cbits(i) == ' '))
632: break;
633: if ( quote
634: && (cbits(i) == '"')
635: && (cbits(i = getch()) != '"')) {
636: ch = i;
637: break;
638: }
639: *strp++ = i;
640: if (strflg && (strp >= lim)) {
641: #if 0
642: fprintf(stderr, "strp=0x%x, lim = 0x%x\n",
643: strp, lim);
644: #endif 0
645: fprintf(stderr,
646: "troff: Macro argument too long.\n");
647: copyf--;
648: edone(004);
649: }
650: SPACETEST(strp, 3 * sizeof(tchar));
651: }
652: *strp++ = 0;
653: }
654: nxf = savnxf;
655: nxf->nargs = argpp - (tchar **)(savnxf + 1);
656: argtop = strp;
657: rtn:
658: copyf--;
659: }
660:
661:
662: seta()
663: {
664: register i;
665:
666: i = cbits(getch()) - '0';
667: if ( (i > 0)
668: && (i <= APERMAC)
669: && (i <= frame->nargs)){
670: ap = *(((tchar **)(frame + 1)) + i - 1);
671: }
672: }
673:
674:
675: caseda()
676: {
677: app++;
678: casedi();
679: }
680:
681:
682: casedi()
683: {
684: register i, j;
685: register *k;
686:
687: lgf++;
688: if (skip() || ((i = getrq()) == 0)) {
689: if (dip != d)
690: wbt((tchar)0);
691: if (dilev > 0) {
692: v.dn = dip->dnl;
693: v.dl = dip->maxl;
694: dip = &d[--dilev];
695: offset = dip->op;
696: }
697: goto rtn;
698: }
699: if (++dilev == NDI) {
700: --dilev;
701: fprintf(stderr, "troff: Diversions nested too deep.\n");
702: edone(02);
703: }
704: if (dip != d)
705: wbt((tchar)0);
706: diflg++;
707: dip = &d[dilev];
708: dip->op = finds(i);
709: dip->curd = i;
710: clrmn(oldmn);
711: k = (int *) & dip->dnl;
712: for (j = 0; j < 10; j++)
713: k[j] = 0; /*not op and curd*/
714: rtn:
715: app = 0;
716: diflg = 0;
717: }
718:
719:
720: casedt()
721: {
722: lgf++;
723: dip->dimac = dip->ditrap = dip->ditf = 0;
724: skip();
725: dip->ditrap = vnumb((int *)0);
726: if (nonumb)
727: return;
728: skip();
729: dip->dimac = getrq();
730: }
731:
732:
733: casetl()
734: {
735: register j;
736: int w1, w2, w3;
737: tchar i, delim;
738: filep begin;
739: extern width(), pchar();
740:
741: dip->nls = 0;
742: skip();
743: if (dip != d)
744: wbfl();
745: if ((offset = begin = alloc()) == 0)
746: return;
747: if (ismot(delim = getch())) {
748: ch = delim;
749: delim = '\'';
750: } else
751: delim = cbits(delim);
752: if (!nlflg)
753: while (cbits(i = getch()) != '\n') {
754: if (cbits(i) == cbits(delim))
755: i = IMP;
756: wbf(i);
757: }
758: wbf((tchar)IMP);
759: wbf((tchar)IMP);
760: wbt((tchar)0);
761:
762: w1 = hseg(width, begin);
763: w2 = hseg(width, (filep)0);
764: w3 = hseg(width, (filep)0);
765: offset = dip->op;
766: #ifdef NROFF
767: if (!offset)
768: horiz(po);
769: #endif
770: hseg(pchar, begin);
771: if (w2 || w3)
772: horiz(j = quant((lt - w2) / 2 - w1, HOR));
773: hseg(pchar, (filep)0);
774: if (w3) {
775: horiz(lt - w1 - w2 - w3 - j);
776: hseg(pchar, (filep)0);
777: }
778: newline(0);
779: if (dip != d) {
780: if (dip->dnl > dip->hnl)
781: dip->hnl = dip->dnl;
782: } else {
783: if (v.nl > dip->hnl)
784: dip->hnl = v.nl;
785: }
786: ffree(begin);
787: }
788:
789:
790: casepc()
791: {
792: pagech = chget(IMP);
793: }
794:
795:
796: hseg(f, p)
797: int (*f)();
798: filep p;
799: {
800: register acc;
801: tchar i;
802: static filep q;
803:
804: acc = 0;
805: if (p)
806: q = p;
807: while (1) {
808: i = rbf0(q);
809: q = incoff(q);
810: if (!i || i == IMP)
811: return(acc);
812: if (cbits(i) == pagech) {
813: nrbits = i & SFMASK;
814: nform = fmt[findr('%')];
815: acc += fnumb(v.pn, f);
816: } else
817: acc += (*f)(i);
818: }
819: }
820:
821:
822: casepm()
823: {
824: register i, k;
825: register char *p;
826: int xx, cnt, tcnt, kk, tot;
827: filep j;
828: char pmline[10];
829:
830: kk = cnt = tcnt = 0;
831: tot = !skip();
832: for (i = 0; i < NM; i++) {
833: if (contab[i].rq)
834: tcnt++;
835: if (!((xx = contab[i].rq) & MMASK))
836: continue;
837: p = pmline;
838: j = (filep) contab[i].x.mx;
839: k = 1;
840: while ((j = blist[blisti(j)]) != -1) {
841: k++;
842: }
843: cnt++;
844: kk += k;
845: if (!tot) {
846: *p++ = xx & 0177;
847: if (!(*p++ = (xx >> BYTE) & 0177))
848: *(p - 1) = ' ';
849: *p++ = 0;
850: fprintf(stderr, "%s %d\n", pmline, k);
851: }
852: }
853: fprintf(stderr, "pm: total %d, macros %d, space %d\n", tcnt, cnt, kk);
854: }
855:
856:
857: dummy()
858: {
859: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.