|
|
1.1 root 1: /*
2: * roff.src - v 1.123 of 12/5/80
3: *
4: * This is the first file of the nroff/troff program (n1.c).
5: *
6: */
7:
8:
9:
10:
11: #ifdef NROFF
12: char ntversion[] = "@(#)nroff: 1.123";
13: #else
14: char ntversion[] = "@(#)troff: 1.123";
15: #endif
16:
17: #ifndef unix
18: char ntNunix[] = "@(#) non-unix";
19: #define INCORE
20: #define SMALL
21: #define tso
22: #endif
23:
24: #ifdef SMALL
25: char ntSMALL[] = "@(#) SMALL";
26: #define NDIAGS
27: #define NOCOMPACT
28: #endif
29:
30: #ifdef INCORE
31: char ntINC[] = "@(#) incore";
32: #define NOCOMPACT
33: #endif
34:
35: #ifdef NDIAGS
36: char ntDIAGS[] = "@(#) NDIAGS";
37: #endif
38:
39: #ifdef NOCOMPACT
40: char ntNOCOMPACT[] = "@(#) NOCOMPACT";
41: #endif
42:
43:
44:
45: int version = 1123; /* nroff/troff version tag */
46:
47: #ifdef unix
48: #include <sys/types.h>
49: #include <sys/stat.h>
50: #endif
51: #include "tdef.hd"
52: #include "strs.hd"
53: #ifndef INCORE
54: #include "uns.hd"
55: #endif
56: #ifdef NROFF
57: #include "tw.hd"
58: extern struct ttable t;
59: #endif
60: #ifdef unix
61: #include <setjmp.h>
62: jmp_buf sjbuf;
63: #include <sgtty.h>
64: #endif
65: /*
66: troff1.c
67:
68: consume options, initialization, main loop,
69: input routines, escape function calling
70: */
71:
72: extern struct s *frame, *stk, *nxf;
73: extern struct s *ejl;
74: extern struct tmpfaddr ip;
75: #ifndef INCORE
76: extern struct envblock eblock; /* environment block */
77: #else
78: extern struct envblock eblock[NEV]; /* incore environments */
79: extern char *malloc();
80: extern int *argsp;
81: extern int maclev;
82: #endif
83: extern struct d d[NDI], *dip;
84: extern struct datablock dblock; /* compactable data area */
85:
86:
87: #ifndef SMALL
88: extern int fork(), pipe(), dup2();
89: extern int **argpp; /* pointers to request arguments */
90: #endif
91:
92: #ifdef ebcdic
93: extern char atoe[], etoa[]; /* ascii to ebcdic and vice versa */
94: extern char *fname();
95: #endif
96: #ifdef tso
97: char hibuf[NSO][IBUFSZ]; /* input buffers during .so */
98: int heibuf[NSO]; /* end pointers for hibuf */
99: int hibufp[NSO]; /* current pos pointers for hibuf */
100: #endif
101: extern int ev;
102: extern int bdtab[];
103: extern getfont();
104: extern char *mktemp();
105: extern char *ttyname();
106: #ifndef INCORE
107: extern char *setbrk();
108: #endif
109: extern char *ttyname();
110: extern catch(), fpecatch(), kcatch();
111: extern int cd;
112: extern int vflag;
113: extern int dfact;
114: extern int tch[];
115: extern int *cstk[], cstkl;
116: extern int ch_CMASK;
117: extern long atoi0();
118: extern int ndone;
119: extern int stdi;
120: extern int waitf;
121: extern int nofeed;
122: extern int quiet;
123: extern filedes ptid;
124: extern int ascii;
125: extern int npn;
126: extern int xflg;
127: extern int stop;
128: extern char ibuf[IBUFSZ];
129: extern char xbuf[IBUFSZ];
130: extern char *ibufp;
131: extern char *xbufp;
132: extern char *eibuf;
133: extern char *xeibuf;
134: extern int cbuf[NC];
135: extern int nx;
136: extern int mflg;
137: extern int ch;
138: extern int pto;
139: extern int pfrom;
140: extern int cps;
141: extern int suffid;
142: extern char suftab[];
143: extern int ibf;
144: extern filedes ttyod;
145: #ifdef unix
146: extern struct sgttyb ttys;
147: #endif
148: extern int iflg;
149: extern int init;
150: extern int rargc;
151: extern char **argp;
152: extern int lgf;
153: extern int copyf;
154: extern int eschar;
155: extern int cwidth;
156: extern int nlflg;
157: extern int donef;
158: extern int nflush;
159: extern int nfo;
160: extern filedes ifile;
161: extern int fc;
162: extern int padc;
163: extern int raw;
164: extern struct {
165: char buf[NS];
166: } nextf[NSN];
167: char cfname[NSO][NS] = "<standard input"; /* file name stack */
168: extern char newf[];
169: extern int nfi;
170: #ifdef NROFF
171: extern char termtab[];
172: extern int tti;
173: #endif
174: extern filedes ifl[NSO];
175: extern int ifi;
176: extern int flss;
177: extern char ptname[];
178: extern int print;
179: extern int nonumb;
180: extern int pnlist[];
181: extern int *pnp;
182: extern int trap;
183: extern int tflg;
184: extern int ejf;
185: extern int gflag;
186: extern int oline[];
187: extern int *olinep;
188: extern int dpn;
189: extern int noscale;
190: extern char *unlkp;
191: extern int level;
192: extern int ttysave;
193: extern int dotT;
194: extern int tabch, ldrch;
195: extern no_out;
196: #ifndef NROFF
197: extern char codetab[];
198: extern int lg;
199: extern char fontfile[];
200: extern int ffi; /* index into fontfile string (see t6.c) */
201: #else
202: extern int eqflg;
203: extern int hflg;
204: #endif
205: int nnextf = 0; /* index into nextf */
206: struct tmpfaddr ipl[NSO];
207: long offl[NSO];
208: long ioff;
209: char *ttyp;
210: int ms[] = {31,28,31,30,31,30,31,31,30,31,30,31};
211:
212: #ifndef SMALL
213: int unixp; /* pointer into unix call buffer */
214: int unixpt=0; /* top of unix buffer */
215: int unixch=0; /* channel for unix reads */
216: #endif
217:
218: #ifndef NROFF
219: int acctf;
220: #endif
221: int did_mesg = 0;
222:
223: /* definitions for compacted macros */
224:
225: #ifndef NOCOMPACT
226:
227: extern char cmpctf[], cmpctuf[];
228:
229: int cmpcti; /* pointer into cmpctt string */
230: int compact; /* compact flag */
231: char cname[10] = "x."; /* string name for compacted output */
232: int cnamei = 2; /* pointer to end of cname string */
233:
234: #endif
235: main(argc, argv, envp)
236: int argc;
237: char **argv, **envp;
238: {
239: register char *p, *q;
240: register i;
241: #ifndef NOCOMPACT
242: int sargc; /* hold argc, argv for -c */
243: char **sargv;
244: int tversion;
245:
246: sargc = argc;
247: sargv = argv;
248: #endif
249:
250: #ifdef ebcdic
251: cargs(argc, argv); /* convert args to ascii */
252: #endif
253: setsignals();
254: init1(argv[0][0]);
255:
256: #ifdef NROFF
257: for (tti = -1; termtab[++tti]; ) ; /* find end of string */
258: termtab[tti] = '3';
259: termtab[tti+1] = '7'; /* tab37 is default terminal table */
260: #ifdef tso
261: termtab[tti+2] = '.'; /* fudge name (to tabnn.t) */
262: termtab[tti+3] = 't';
263: #endif
264: #else
265: for (ffi = -1; fontfile[++ffi]; ) ; /* find end of string */
266: #endif
267:
268: #ifndef NOCOMPACT
269: for (cmpcti = -1; cmpctf[++cmpcti]; ) ; /* end of comp. macr. names */
270: #endif
271:
272: for (nfi = -1; nextf[0].buf[++nfi]; ) ; /* find end of string */
273:
274: while(--argc > 0 && (++argv)[0][0]=='-')
275: switch(argv[0][1]){
276:
277: case 0:
278: goto start;
279: case 'i':
280: stdi++;
281: continue;
282: case 'q':
283: quiet++;
284: #ifdef unix
285: if(gtty(0, &ttys) >= 0)
286: ttysave = ttys.sg_flags;
287: #endif
288: continue;
289: case 'n':
290: npn = cnum(&argv[0][2]);
291: continue;
292: case 'p':
293: xflg = 0;
294: cps = cnum(&argv[0][2]);
295: continue;
296: case 's':
297: if(!(stop = cnum(&argv[0][2])))stop++;
298: continue;
299: case 'r':
300: vlist[findr(argv[0][2])] = cnum(&argv[0][3]);
301: continue;
302: case 'c': /* read compacted macros */
303: #ifndef NOCOMPACT
304: if (mflg) goto regmac; /* use -m if not first package */
305: else mflg++;
306: p = &cmpctf[cmpcti];
307: q = &argv[0][2];
308: while (*p++ = *q++) ; /* make compacted file name */
309:
310: if ((i = open(cmpctf,0)) < 0)
311: goto regless; /* data area */
312: if ((read(i,&tversion,sizeof(version)) != sizeof(version)) ||
313: (tversion != version ))
314: goto regless; /* wrong version of macros */
315: if ((read(i,&dblock,sizeof(struct datablock))) <
316: sizeof(struct datablock)) {
317: prstr("error reading data area\n");
318: exit(1); }
319:
320: cmpctf[cmpcti-2] = 't'; /* now tmp file */
321: if ((i = open(cmpctf,0)) < 0) {
322: prstr("can't find compacted tmp file\n");
323: exit(1); }
324: Mcp(i, ibf); /* copy tmp file */
325: close(i);
326:
327: p = nextf[nnextf++].buf; /* save name of uncomp. area */
328: q = cmpctuf;
329: while (*p++ = *q++) ;
330: p--; /* point to uncompacted segment */
331: q = &argv[0][2]; /* package name */
332: while (*p++ = *q++) ; /* stow it */
333:
334: for (sargc-=argc; ((--sargc>0)&&((++sargv)[0][0])); )
335: if (sargv[0][1] == 'r') /* re-eval nr settings */
336: vlist[findr(sargv[0][2])] = cnum(&sargv[0][3]);
337:
338: continue;
339:
340: case 'k':
341: p = &cname[cnamei]; /* save name to compact into */
342: q = &argv[0][2];
343: while (*p++ = *q++) ;
344: compact++;
345: continue;
346:
347: regless: mflg--; /* fall into -m */
348: #endif
349: case 'm':
350: regmac:
351: if (mflg++ >= NSN) ertoomp();
352: p = &nextf[nnextf++].buf[nfi];
353: q = &argv[0][2];
354: while((*p++ = *q++) != 0);
355: continue;
356: case 'o':
357: getpn(&argv[0][2]);
358: continue;
359: #ifdef NROFF
360: case 'h':
361: hflg++;
362: continue;
363: case 'z':
364: no_out++;
365: continue;
366: case 'e':
367: eqflg++;
368: continue;
369: case 'T':
370: p = &termtab[tti];
371: q = &argv[0][2];
372: if(!((*q) & 0177))continue;
373: while((*p++ = *q++) != 0);
374: #ifdef tso
375: *p++ = '.'; /* fudge name on tso */
376: *p++ = 't';
377: #endif
378: dotT++;
379: continue;
380: case 'u':
381: bdtab[2] = cnum(&argv[0][2]); /* set emboldening */
382: if ((bdtab[2]<0) || (bdtab[2]>50)) bdtab[2]=0;
383: continue;
384: #endif
385: #ifndef NROFF
386: case 'z':
387: no_out++;
388: case 'a':
389: ascii = 1;
390: nofeed++;
391: case 't':
392: #ifndef tso
393: ptid = 1;
394: #endif
395: continue;
396: case 'w':
397: waitf = 1;
398: continue;
399: case 'f':
400: nofeed++;
401: continue;
402: case 'x':
403: xflg = 0;
404: continue;
405: case 'b':
406: #ifdef unix
407: if(open(ptname,1) < 0)prstr("Busy.\n");
408: else
409: #endif
410: prstr("Available.\n");
411: done3(0);
412: case 'g':
413: stop = gflag = 1;
414: #ifdef unix
415: ptid = 1;
416: #endif
417: dpn = 0;
418: continue;
419: case 'T':
420: ffi -= 2; /* overwrite 'ft' */
421: for (p = &argv[0][2]; (fontfile[ffi] = *p++); ffi++);
422: fontfile[ffi++] = '/'; /* build new path */
423: fontfile[ffi++] = 'f';
424: fontfile[ffi++] = 't';
425: #ifdef tso
426: fontfile[ffi+1] = '.'; /* fudge name on tso */
427: fontfile[ffi+2] = 'f';
428: #endif
429: fontfile[ffi] = 'R'; getfont(0,1); /* get default fonts */
430: fontfile[ffi] = 'I'; getfont(1,1);
431: fontfile[ffi] = 'B'; getfont(2,1);
432: fontfile[ffi] = 'S'; getfont(3,1);
433: continue;
434: #endif
435: default:
436: prstr("Unknown option: ");
437: aprstr(argv[0]);
438: prstr("\n");
439: ferrex();
440: }
441: start:
442: argp = argv;
443: rargc = argc;
444: nnextf = 0;
445: init2();
446: #ifdef unix
447: setjmp(sjbuf);
448: #endif
449: #ifdef tso
450: setexit();
451: #endif
452: loop:
453: copyf = lgf = nb = nflush = nlflg = 0;
454: if(ip.b && (rbf0(&ip)==0) && ejf
455: #ifndef INCORE
456: && (frame->pframe <= ejl)
457: #else
458: && ((maclev-1) <= (int)ejl)
459: #endif
460: ) {
461: nflush++;
462: trap = 0;
463: eject((struct s *)0);
464: goto loop;
465: }
466: i = getch();
467: if(pendt)goto lablt;
468: if(ch_CMASK == XPAR){
469: copyf++;
470: tflg++;
471: for(;ch_CMASK != '\n';)pchar(getch());
472: tflg = 0;
473: copyf--;
474: goto loop;
475: }
476: if((ch_CMASK == cc) || (ch_CMASK == c2)){
477: if(ch_CMASK == c2)nb++;
478: copyf++;
479: do i = getch();
480: while ((ch_CMASK == ' ') || (ch_CMASK == '\t'));
481: ch = i;
482: copyf--;
483: control(getrq(),1);
484: flushi();
485: goto loop;
486: }
487: lablt:
488: ch = i;
489: text();
490: goto loop;
491: }
492: setsignals()
493: {
494: #ifdef unix
495: signal(SIGHUP,catch);
496: if (signal(SIGINT,SIG_IGN) == SIG_IGN){
497: signal(SIGHUP,SIG_IGN);
498: signal(SIGINT,SIG_IGN);
499: signal(SIGQUIT,SIG_IGN); }
500: else signal(SIGINT,catch);
501: signal(SIGFPE,fpecatch);
502: signal(SIGPIPE,catch);
503: signal(SIGTERM,kcatch);
504: #endif
505: }
506: catch(){
507: /*
508: prstr("Interrupt\n");
509: */
510: done3(01);
511: }
512: fpecatch(){
513: prstrfl("Floating Exception.\n");
514: #ifdef unix
515: signal(SIGFPE,fpecatch);
516: #endif
517: }
518: kcatch(){
519: #ifdef unix
520: signal(SIGTERM,SIG_IGN);
521: #endif
522: done3(01);
523: }
524: #ifndef NROFF
525: #ifndef SMALL
526: acctg() {
527: static char *acct_file = "/usr/adm/tracct";
528: acctf = open(acct_file,1);
529: setuid(getuid());
530: }
531: #endif
532: #endif
533: init1(a)
534: char a;
535: {
536: register char *p;
537: register i;
538:
539: #ifndef NROFF
540: #ifndef SMALL
541: acctg();/*open troff actg file while mode 4755*/
542: #endif
543: #endif
544: #ifndef INCORE
545: if((suffid=open(suftab,0)) < 0) errcos();
546: read(suffid, sufind.chr, sizeof(sufind));
547:
548: p = mktemp("/tmp/taXXXXX");
549: if(a == 'a')p = &p[5];
550: if((close(creat(p, 0600))) < 0){
551: prstr("Cannot create temp file.\n");
552: exit(-1);
553: }
554: ibf = open(p, 2);
555: #endif
556: for(i=256; --i;)trtab[i]=i;
557: trtab[UNPAD] = ' ';
558: mchbits();
559: #ifndef INCORE
560: if(a != 'a')unlkp = p;
561: #endif
562: }
563: init2()
564: {
565: register i,j;
566:
567: #ifdef unix
568: ttyod = 2;
569: if(((ttyp=ttyname(j=0)) != (char *)0) ||
570: ((ttyp=ttyname(j=1)) != (char *)0) ||
571: ((ttyp=ttyname(j=2)) != (char *)0)
572: );else
573: #endif
574: ttyp = "notty";
575: #ifdef tso
576: ttyod = stdout;
577: #endif
578: iflg = j;
579: if(ascii)mesg(0);
580:
581: #ifdef unix
582: if (!ptid && !waitf
583: #ifndef NOCOMPACT
584: && !compact
585: #endif
586: ) {
587: if((ptid = open(ptname,1)) < 0){
588: prstr("Typesetter busy.\n");
589: done3(-2);
590: }
591: }
592: #endif
593: #ifdef tso
594: if ((ptid = fopen("OUTPUT", "w,BINARY")) == (FILE *)-1) {
595: prstr("can't create OUTPUT");
596: exit(1); }
597: #endif
598: ptinit();
599: for(i=NEV; i--;)
600: #ifndef INCORE
601: write(ibf, (char *)&eblock, sizeof(struct envblock));
602: #else
603: if (i)
604: { char *p, *q;
605: for (p=(char *)&eblock[i],q=(char *)&eblock[0],j=0; (j<sizeof(struct envblock)); j++)
606: *p++ = *q++; }
607: #endif
608: olinep = oline;
609: ibufp = eibuf = ibuf;
610: v_hp = init = 0;
611: ioff = 0;
612: v_nl = -1;
613: cvtime();
614: #ifndef INCORE
615: frame = stk = (struct s *)setbrk(DELTA);
616: #else
617: frame = stk = (struct s *)malloc(sizeof(struct s));
618: /* incore version */
619: #endif
620: dip = &d[0];
621: #ifndef INCORE
622: nxf = frame + 1;
623: #else
624: nxf = (struct s *)malloc(sizeof(struct s));
625: #endif
626: nx = mflg;
627: }
628: cvtime(){
629:
630: long tt;
631: register i;
632:
633: time(&tt);
634: tt -= 3600*ZONE; /*5hrs for EST*/
635: v_dy = (tt/86400L) + 1;
636: v_dw = (v_dy + 3)%7 + 1;
637: for(v_yr=70;; v_yr++){
638: if((v_yr)%4)ms[1]=28;else ms[1]=29;
639: for(i=0;i<12;){
640: if(v_dy<=ms[i]){
641: v_mo = i+1;
642: return;
643: }
644: v_dy -= ms[i++];
645: }
646: }
647: }
648: cnum(a)
649: char *a;
650: {
651: register i;
652:
653: ibufp = a;
654: for (eibuf = a; *eibuf++; ) ;
655: i = atoi();
656: ch = 0;
657: return(i);
658: }
659: mesg(f)
660: int f;
661: {
662: #ifdef unix
663: static int mode;
664: struct stat statb;
665:
666: if(!f){
667: stat(ttyp,&statb);
668: mode = statb.st_mode;
669: chmod(ttyp,mode & ~0122);
670: did_mesg = 1;
671: }else{
672: if (did_mesg) chmod(ttyp,mode);
673: }
674: #endif
675: }
676: prstrfl(s)
677: char *s;
678: {
679: flusho();
680: prstr(s);
681: }
682: prstr(s)
683: char *s;
684: {
685: register i;
686: register char *j;
687:
688: #ifdef unix
689: j = s;
690: for(i=0;*s;i++)s++;
691: write(ttyod,j,i);
692: #endif
693: #ifdef ebcdic
694: while (i = *s++) {
695: if (putc(i, ttyod) == EOF)
696: exit(1);
697: if (etoa[i] == '\n')
698: fflush(ttyod); }
699: #endif
700: }
701: #ifdef ebcdic
702: aprstrfl(s)
703: char *s;
704: {
705: flusho();
706: aprstr(s);
707: }
708: aprstr(s)
709: char *s;
710: { register i;
711: register char *j;
712:
713: while (i = *s++) {
714: if (putc(atoe[i], ttyod) == EOF)
715: exit(1);
716: if (i == '\n')
717: fflush(ttyod); }
718: }
719: #endif
720: control(a,b)
721: int a,b;
722: {
723: register i,j;
724:
725: i = a;
726: if((i == 0) || ((j = frmname(i)) == -1))return(0);
727: if (nametab[j].ename & MMASK) {
728: nxf->nargs = 0;
729: if(b)collect();
730: flushi();
731: return(pushi((filep)nametab[j].vv.val)); }
732: else {
733: if(!b)return(0);
734: return ((*nametab[j].vv.f)(0)); }
735: }
736:
737: getrq(){
738: register i,j;
739:
740: if(((i=getach()) == 0) ||
741: ((j=getach()) == 0))goto rtn;
742: i = PAIR(i,j);
743: rtn:
744: return(i);
745: }
746: getch(){
747: register int i, j, k;
748:
749: level++;
750: g0:
751: if(ch){
752: if (((ch_CMASK = (i = ch) & CMASK)) == '\n')nlflg++;
753: ch = 0;
754: level--;
755: return(i);
756: }
757:
758: if(nlflg){
759: level--;
760: return(ch_CMASK = '\n');
761: }
762:
763: if((k = (i = getch0()) & CMASK) != ESC){
764: if(i & MOT)goto g2;
765: if(k == FLSS){
766: copyf++; raw++;
767: i = getch0();
768: /* sign extend */
769: if (i & 0100000) i |= (int)~0177777;
770: if(!fi)flss = i;
771: copyf--; raw--;
772: goto g0;
773: }
774: if(!copyf){
775: #ifndef NROFF
776: if((k == 'f') && lg && !lgf){
777: i = getlg(i);
778: goto g2;
779: }
780: #endif
781: if((k == fc) || (k == tabch) || (k == ldrch)){
782: if((i=setfield(k)) == 0)goto g0; else goto g2;
783: }
784: if(k == 010){
785: i = makem(-width(' ' | chbits));
786: goto g2;
787: }
788: }
789: goto g2;
790: }
791: k = (j = getch0()) & CMASK;
792: if(j & MOT){
793: i = j;
794: goto g2;
795: }
796: switch(k){
797:
798: case '\n': /*concealed newline*/
799: goto g0;
800: case 'n': /*number register*/
801: setn();
802: goto g0;
803: case '*': /*string indicator*/
804: setstr();
805: goto g0;
806: case '$': /*argument indicator*/
807: getch();
808: if (((i = ch_CMASK - '0') > 0) && (i <= 9) && (i <= frame->nargs))
809: #ifndef INCORE
810: setap(*((int **)frame + i-1 + (sizeof(struct s)/sizeof(int **))));
811: #else
812: setap((int *)*(argsp + i - 1));
813: #endif
814: goto g0;
815: case '{': /*LEFT*/
816: i = LEFT;
817: goto gx;
818: case '}': /*RIGHT*/
819: i = RIGHT;
820: goto gx;
821: case '"': /*comment*/
822: while(((i=getch0()) & CMASK ) != '\n');
823: goto g2;
824: case ESC: /*double backslash*/
825: i = eschar;
826: goto gx;
827: case 'e': /*printable version of current eschar*/
828: i = PRESC;
829: goto gx;
830: case ' ': /*unpaddable space*/
831: i = UNPAD;
832: goto gx;
833: case '|': /*narrow space*/
834: i = NARSP;
835: goto gx;
836: case '^': /*half of narrow space*/
837: i = HNSP;
838: goto gx;
839: case '\'': /*\(aa*/
840: i = 0222;
841: goto gx;
842: case '`': /*\(ga*/
843: i = 0223;
844: goto gx;
845: case '_': /*\(ul*/
846: i = 0224;
847: goto gx;
848: case '-': /*current font minus*/
849: i = 0210;
850: goto gx;
851: case '&': /*filler*/
852: i = FILLER;
853: goto gx;
854: case 'c': /*to be continued*/
855: i = CONT;
856: goto gx;
857: case ':': /* lem's character */
858: i = COLON;
859: goto gx;
860: case '!': /*transparent indicator*/
861: i = XPAR;
862: goto gx;
863: case 't': /*tab*/
864: i = '\t';
865: goto g2;
866: case 'a': /*leader (SOH)*/
867: i = LEADER;
868: goto g2;
869: case '%': /*ohc*/
870: i = OHC;
871: goto g2;
872: case 'g': /* return format of a number reg */
873: setaf();
874: goto g0;
875: case '.': /*.*/
876: i = '.';
877: gx:
878: i = (j & ~CMASK) | i;
879: goto g2;
880: }
881: if(!copyf)
882: switch(k){
883:
884: case 'p': /*spread*/
885: spread++;
886: goto g0;
887: case '(': /*special char name*/
888: if((i=setch()) == 0)goto g0;
889: break;
890: case 's': /*size indicator*/
891: setps();
892: goto g0;
893: case 'f': /*font indicator*/
894: setfont(0);
895: goto g0;
896: case 'w': /*width function*/
897: setwd();
898: goto g0;
899: case 'v': /*vert mot*/
900: dfact = lss;
901: vflag++;
902: if (i = mot()) break;
903: goto g0;
904: case 'h': /*horiz mot*/
905: #ifdef NROFF
906: dfact = EM;
907: #endif
908: #ifndef NROFF
909: dfact = 6 * (pts & 077);
910: #endif
911: if (i = mot()) break;
912: goto g0;
913: case 'z': /*zero with char*/
914: if (!((i = getch()) & MOT)) i |= ZBIT;
915: break;
916: case 'l': /*hor line*/
917: setline();
918: goto g0;
919: case 'L': /*vert line*/
920: setvline();
921: goto g0;
922: case 'b': /*bracket*/
923: setbra();
924: goto g0;
925: case 'o': /*overstrike*/
926: setov();
927: goto g0;
928: case 'k': /*mark hor place*/
929: if((i=findr(getsn())) == -1)goto g0;
930: vlist[i] = v_hp;
931: goto g0;
932: case 'j': /*mark output hor place*/
933: if(!(i=getach()))goto g0;
934: i = (i<<BYTE) | JREG;
935: break;
936: case '0': /*number space*/
937: i = makem(width('0' | chbits));
938: break;
939: case 'x': /*extra line space*/
940: if(i = xlss())break;
941: goto g0;
942: case 'u': /*half em up*/
943: case 'r': /*full em up*/
944: case 'd': /*half em down*/
945: i = sethl(k);
946: break;
947: default:
948: i = j;
949: }
950: else{
951: setch0(j);
952: i = eschar;
953: }
954: g2:
955: if((ch_CMASK = (i & CMASK)) == '\n'){
956: nlflg++;
957: v_hp = 0;
958: if (!ip.b) cd++;
959: }
960: if(!--level){
961: j = width(i);
962: v_hp += j;
963: cwidth = j;
964: }
965: return(i);
966: }
967: char ifilt[32] = {0,001,002,003,0,005,006,007,010,
968: 011,012,0,0,0,016,017,0,
969: 0,0,0,0,0,0,0,0,
970: 0,0,033};
971: getch0(){
972: register int i, j;
973:
974: again:
975: if (cstkl) { /* characters in stack? */
976: while ((i = *cstk[cstkl]++) == 0) {
977: cstk[cstkl--] = 0; /* that string is depleted */
978: while (cstkl && !cstk[cstkl])
979: cstkl--; /* find next in stack */
980: if (!cstkl) break; } /* out if stack empty */
981: if (cstkl >= RP) return (i);
982: else if (i) goto g5; }
983: ipagain:
984: if (ip.b) /* input from tty or tmp file */
985: i =
986: #ifndef SMALL
987: (ip.b == (filep)-2) ? rdunix() : /* read from unix */
988: #endif
989: (ip.b == (filep)-1) ? rdtty() : /* read from tty */
990: rbf(); /* read from tmp */
991: else {
992: if(donef || ndone)done(0);
993: if(nx || (ibufp >= eibuf)){
994: if(nfo)goto g1;
995: g0:
996: if (nextfile(0)) {
997: if (ip.b) goto ipagain;
998: if (ibufp < eibuf) goto g2; }
999: g1:
1000: nx = 0;
1001: #ifdef unix
1002: if((j=read(ifile,ibuf,IBUFSZ)) <= 0)goto g0;
1003: #endif
1004: #ifdef tso
1005: if ((j=fread(ibuf,1,IBUFSZ,ifile))<=0) goto g0;
1006: #endif
1007: ibufp = ibuf;
1008: eibuf = ibuf + j; }
1009: g2:
1010: #ifndef ebcdic
1011: i = *ibufp++ & 0177;
1012: #else
1013: i = etoa[*ibufp++] & 0177;
1014: #endif
1015: ioff++;
1016: if(i >= 040)goto g4; else i = ifilt[i]; }
1017: g5:
1018: if(raw)return(i);
1019: if((i & CMASK) == IMP)goto again;
1020: if((i == 0) && !init)goto again;
1021: g4:
1022: if((copyf == 0) && ((i & ~BMASK) == 0) && ((i & CMASK) < 0370))
1023: #ifndef NROFF
1024: if(spbits && (i>31) && ((codetab[i-32] & 0200))) i |= spbits;
1025: else
1026: #endif
1027: i |= chbits;
1028: if((i & CMASK) == eschar)i = (i & ~CMASK) | ESC;
1029: return(i);
1030: }
1031: nextfile(nxtog)
1032: int nxtog;
1033: {
1034: register char *p;
1035: register int i;
1036:
1037: n0:
1038: #ifdef unix
1039: if(ifile)close(ifile);
1040: #endif
1041: #ifdef tso
1042: if (ifile) fclose(ifile);
1043: #endif
1044: if(nnextf < mflg){
1045: p = nextf[nnextf++].buf;
1046: goto n1; }
1047: else
1048: if (mflg == nnextf) nnextf++;
1049: if(ifi > 0){
1050: if(popf())goto n0; /*popf error*/
1051: return(1); /*popf ok*/
1052: }
1053: if(rargc-- <= 0) {
1054: if((nfo -= mflg) && !stdi)done(0);
1055: nfo++;
1056: cd = stdi = mflg = 0;
1057: for (i=0,p="<standard input>"; cfname[ifi][i] = p[i]; i++) ;
1058: ifile = (filedes)0;
1059: ioff = 0;
1060: return(0); }
1061: p = (argp++)[0];
1062: n1:
1063: if((p[0] == '-') && (p[1] == 0)){
1064: for (i=0,p="<standard input>"; cfname[ifi][i] = p[i]; i++) ;
1065: ifile = (filedes)0;
1066: }else
1067: #ifdef unix
1068: if((ifile=open(p,0)) >= 0)
1069: #endif
1070: #ifdef tso
1071: if ((ifile=fopen(fname(p),"r")) != NULL)
1072: #endif
1073: for (i=0; cfname[ifi][i] = p[i]; i++) ;
1074: else {
1075: if ((nnextf <= mflg) && !nxtog) {
1076: prstr("Non-existent macro file (");
1077: aprstr(&nextf[nnextf-1].buf[nfi]);
1078: prstr(")"); }
1079: else {
1080: prstr("cannot open file ");
1081: aprstr(p); }
1082: prstr("\n");
1083: nfo -= mflg;
1084: nx = nnextf;
1085: done(02);
1086: }
1087: nfo++;
1088: cd = 0;
1089: ioff = 0;
1090: return(0);
1091: }
1092: popf(){
1093: register i;
1094: register char *p, *q;
1095:
1096: ioff = offl[--ifi];
1097: cptmpfaddr(ip,ipl[ifi]);
1098: if((ifile = ifl[ifi]) == (filedes)0){
1099: p = xbuf;
1100: q = ibuf;
1101: ibufp = xbufp;
1102: eibuf = xeibuf;
1103: while(q < eibuf)*q++ = *p++;
1104: return(0);
1105: }
1106: #ifdef unix
1107: if((lseek(ifile,(long)(ioff & ~(IBUFSZ-1)),0) < (long)0) ||
1108: ((i = read(ifile,ibuf,IBUFSZ)) < 0))return(1);
1109: eibuf = ibuf + i;
1110: ibufp = ibuf;
1111: if(ttyname(ifile) == (char *)0)
1112: ibufp = ibuf + (int)(ioff & (IBUFSZ-1));
1113: #endif
1114: #ifdef tso
1115: eibuf = heibuf[ifi]; /* restore buffers and pointers */
1116: ibufp = hibufp[ifi];
1117: if (ibufp >= eibuf) return (1);
1118: for (p=ibuf,q=hibuf[ifi]; p<=eibuf; )
1119: *p++ = *q++;
1120: #endif
1121: return(0);
1122: }
1123: flushi(){
1124: if(nflush)return;
1125: ch = 0;
1126: if (cstkl == CH0) {
1127: if (tch[0] == '\n') nlflg++;
1128: do cstkl--;
1129: while (cstkl && !cstk[cstkl]); }
1130: copyf++;
1131: while(!nlflg){
1132: if(donef && (frame == stk))break;
1133: getch();
1134: }
1135: copyf--;
1136: v_hp = 0;
1137: }
1138: getach(){
1139: register i;
1140:
1141: lgf++;
1142: if(((i = getch()) & (MOT | 0200)) ||
1143: (ch_CMASK == ' ') ||
1144: (ch_CMASK == '\n')) {
1145: ch = i;
1146: i = 0;
1147: }
1148: lgf--;
1149: return(i & 0177);
1150: }
1151: getname(){
1152: register int i, k;
1153:
1154: lgf++;
1155: for(k=0; k < (NS-1); k++){
1156: i = getch();
1157: if ((ch_CMASK <= ' ') || (ch_CMASK > 0176)) break;
1158: newf[k] = ch_CMASK;
1159: }
1160: newf[k] = 0;
1161: ch = i;
1162: lgf--;
1163: return(newf[0]);
1164: }
1165: casenx(){
1166: register int i;
1167:
1168: lgf++;
1169: skip();
1170: getname();
1171: nx++;
1172: nnextf--;
1173: for (i=0; (nextf[nnextf].buf[i] = newf[i]); i++) ;
1174: i = mflg;
1175: if (mflg <= nnextf) mflg = nnextf + 1;
1176: nextfile(1);
1177: mflg = i;
1178: nlflg++;
1179: cstkl = pendt = ip.b = 0;
1180: cstk[CH0] = cstk[AP] = (int *)0;
1181: frame = stk;
1182: #ifndef INCORE
1183: nxf = frame + 1;
1184: #else
1185: nxf = (struct s *)malloc(sizeof(struct s));
1186: #endif
1187: }
1188: caseso()
1189: {
1190: register filedes i;
1191: register char *p, *q;
1192:
1193: lgf++;
1194: newf[0] = 0;
1195: if(skip() || !getname()
1196: #ifdef unix
1197: || ((i=open(newf,0)) <0)
1198: #endif
1199: #ifdef tso
1200: || ((i=fopen(fname(newf),"r")) == NULL)
1201: #endif
1202: || (ifi >= NSO)) {
1203: prstr("can't open file ");
1204: aprstr(newf);
1205: prstr("\n");
1206: done(02);
1207: }
1208: for (p=cfname[ifi+1],q=newf; *p = *q; p++,q++) ;
1209: flushi();
1210: #ifdef tso
1211: for (p=ibuf,q=hibuf[ifi]; p<eibuf; )
1212: *q++ = *p++;
1213: heibuf[ifi] = eibuf; /* save buffer and pointers */
1214: hibufp[ifi] = ibufp;
1215: #endif
1216: ifl[ifi] = ifile;
1217: ifile = i;
1218: offl[ifi] = ioff;
1219: ioff = 0;
1220: cptmpfaddr(ipl[ifi],ip);
1221: ip.b = 0;
1222: nx++;
1223: nflush++;
1224: if(!ifl[ifi++]){
1225: p = ibuf;
1226: q = xbuf;
1227: xbufp = ibufp;
1228: xeibuf = eibuf;
1229: while(p < eibuf)*q++ = *p++;
1230: }
1231: }
1232: getpn(a)
1233: char *a;
1234: {
1235: register i, neg;
1236: long atoi1();
1237:
1238: if((*a & 0177) == 0)return;
1239: neg = 0;
1240: ibufp = a;
1241: for (eibuf = a; *eibuf++; ) ;
1242: noscale++;
1243: while((i = getch() & CMASK) != 0)switch(i){
1244: case '+':
1245: case ',':
1246: continue;
1247: case '-':
1248: neg = MOT;
1249: goto d2;
1250: default:
1251: ch = i;
1252: d2:
1253: i = atoi1();
1254: if(nonumb)goto fini;
1255: else{
1256: *pnp++ = i | neg;
1257: neg = 0;
1258: if(pnp >= &pnlist[NPN-2]){
1259: prstr("Too many page numbers\n");
1260: done3(-3);
1261: }
1262: }
1263: }
1264: fini:
1265: if(neg)*pnp++ = -2;
1266: *pnp = -1;
1267: ch = noscale = print = 0;
1268: pnp = pnlist;
1269: if(*pnp != -1)chkpn();
1270: }
1271:
1272: /* compacted macros support routines. */
1273:
1274:
1275: #ifndef NOCOMPACT
1276:
1277: Mcp(oldp, newp) /* copy file on oldp to file on newp */
1278: int oldp, newp;
1279: { int n;
1280: char BUF[BSIZE]; /* copy buffer */
1281:
1282: while ((n = read(oldp, BUF, BSIZE)) > 0)
1283:
1284: if (write(newp, BUF, n) != n) {
1285:
1286: prstr("tmp file write error\n");
1287: exit(1); }
1288: }
1289:
1290: #endif
1291:
1292: caseco() /* perform .co request */
1293: {
1294: #ifndef NOCOMPACT
1295: int i;
1296:
1297: if (!compact) return(0);
1298: cname[0] = 'd'; /* data file first */
1299: if ((i = creat(cname, 0666)) < 0) {
1300: prstr("can't create data file\n");
1301: exit(1); }
1302:
1303: write(i, &version, sizeof(version)); /* write current version tag */
1304: write(i, &dblock, sizeof(struct datablock)); /* write data area */
1305: close(i); /* done with data area */
1306:
1307: cname[0] = 't'; /* now the tmp file */
1308: lseek(ibf, (long)(ev*sizeof(struct envblock)), 0); /* write curr env */
1309: write(ibf, (char *)&eblock, sizeof(struct envblock));
1310: lseek(ibf, (long)0, 0); /* rewind */
1311: if ((i = creat(cname, 0666)) < 0) {
1312: prstr("can't create tmp file\n");
1313: exit(1); }
1314: Mcp(ibf, i); /* copy tmp file */
1315: unlink(unlkp); /* remove old tmp file */
1316:
1317: prstr("Compaction completed\n");
1318: exit(1);
1319: #endif
1320: }
1321:
1322: /* error message routines */
1323:
1324: ertoomp() {prstr("Too many macro packages.\n"); exit(-1); }
1325:
1326: #ifndef INCORE
1327: errcos() {prstr("Cannot open suftab.\n"); exit(-1); }
1328: #endif
1329:
1330: ferrex() {
1331: #ifdef unix
1332: #ifndef INCORE
1333: unlink(unlkp);
1334: #endif
1335: #endif
1336: exit(1); }
1337: caseunix() /* read output of command sent to unix */
1338: {
1339: #ifndef SMALL
1340: int fildes[2]; /* file pointers for pipe */
1341: register int i, j;
1342: char argbuf[15*ARGLEN]; /* hold arguments sent to unix */
1343: char *argp[20]; /* pointers to arguments */
1344: register int *p;
1345:
1346: nxf->nargs = 0;
1347: collect(); /* get request arguments */
1348: flushi(); /* flush input */
1349: pipe(fildes); /* open pipe */
1350:
1351: if (fork() == 0) { /* child only code */
1352:
1353: close(1); /* close standard output */
1354: if (dup2(fildes[1], 1) != 1) {
1355: prstr("can't setup command env\n");
1356: exit(1); }
1357: close(fildes[1]); /* close old pipe channel */
1358:
1359: j = 0;
1360: argpp -= nxf->nargs; /* point to args */
1361:
1362: for (i=0; i < nxf->nargs; i++) {
1363: argp[i] = &argbuf[j]; /* point to next string */
1364: for (p = *argpp++; argbuf[j++] = (char)*p++; ) ; }
1365:
1366: argp[nxf->nargs] = 0; /* null after last pointer */
1367: close(0); /* close standard input */
1368: execvp(argp[0], argp); /* call unix program */
1369: prstr("Can't execute ");
1370: prstr(argp[0]);
1371: prstr("\n");
1372: exit(1); }
1373:
1374: else { /* parent only code */
1375:
1376: close(fildes[1]); /* close write side */
1377: unixch = fildes[0]; /* channel for unix reads */
1378: pushi((filep)-2); } /* mark unix read */
1379: }
1380:
1381: rdunix()
1382: {
1383: static char unixb[BSIZE]; /* unix read buffer */
1384:
1385: if (unixp >= unixpt) { /* read a buffer */
1386:
1387: if ((unixpt = read(unixch,unixb,BSIZE)) <= 0) {
1388: close(unixch);
1389: popi(); /* end of file - terminate unix read */
1390: unixch = 0;
1391: return getch0(); }
1392:
1393: else unixp = 0; }
1394:
1395: return unixb[unixp++];
1396: #endif
1397: }
1398:
1399: #ifdef ebcdic
1400:
1401: char *fname(s)
1402: char *s;
1403: { static char fnamebuf[NS];
1404: register char *p;
1405:
1406: for (p = fnamebuf; *s; s++)
1407: if (*s == '/')
1408: p = fnamebuf;
1409: else
1410: *p++ = atoe[*s];
1411: *p++ = 0;
1412: return (fnamebuf);
1413: }
1414:
1415: cargs(rgc, rgv)
1416: int rgc;
1417: char **rgv;
1418: { char *trgv;
1419:
1420: for ( ; (rgc-- > 0); rgv++)
1421:
1422: for (trgv = *rgv; (*trgv); trgv++)
1423:
1424: *trgv = etoa[*trgv];
1425: }
1426:
1427: #endif
1428:
1429: #ifdef tso
1430: abs(i)
1431: int i;
1432: {
1433: if (i >= 0) return i;
1434: else return -i;
1435: }
1436: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.