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