xref: /csrg-svn/old/roff/common_source/n1.c (revision 17673)
1 #ifndef lint
2 static char sccsid[] = "@(#)n1.c	4.6 01/09/85";
3 #endif lint
4 
5 #include "tdef.h"
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <sys/time.h>
9 extern
10 #include "d.h"
11 extern
12 #include "v.h"
13 #ifdef NROFF
14 extern
15 #include "tw.h"
16 #endif
17 #include "sdef.h"
18 #include <setjmp.h>
19 jmp_buf sjbuf;
20 #include	<sgtty.h>
21 /*
22 troff1.c
23 
24 consume options, initialization, main loop,
25 input routines, escape function calling
26 */
27 
28 int	inchar[LNSIZE], *pinchar = inchar;	/* XXX */
29 extern struct s *frame, *stk, *nxf;
30 extern struct s *ejl, *litlev;
31 extern filep ip;
32 extern filep offset;
33 extern filep nextb;
34 
35 
36 extern int stdi;
37 extern int waitf;
38 extern int nofeed;
39 extern int quiet;
40 extern int ptid;
41 extern int ascii;
42 extern int npn;
43 extern int xflg;
44 extern int stop;
45 extern char ibuf[IBUFSZ];
46 extern char xbuf[IBUFSZ];
47 extern char *ibufp;
48 extern char *xbufp;
49 extern char *eibuf;
50 extern char *xeibuf;
51 extern int cbuf[NC];
52 extern int *cp;
53 extern int *vlist;
54 extern int nx;
55 extern int mflg;
56 extern int ch;
57 extern int pto;
58 extern int pfrom;
59 extern int cps;
60 extern int chbits;
61 extern int ibf;
62 extern int ttyod;
63 extern struct sgttyb ttys;
64 extern int iflg;
65 extern int init;
66 extern int rargc;
67 extern char **argp;
68 extern char trtab[256];
69 extern int lgf;
70 extern int copyf;
71 extern int eschar;
72 extern int ch0;
73 extern int cwidth;
74 extern int nlflg;
75 extern int *ap;
76 extern int donef;
77 extern int nflush;
78 extern int nchar;
79 extern int rchar;
80 extern int nfo;
81 extern int ifile;
82 extern int fc;
83 extern int padc;
84 extern int tabc;
85 extern int dotc;
86 extern int raw;
87 extern int tabtab[NTAB];
88 extern char nextf[];
89 extern int nfi;
90 #ifdef NROFF
91 extern char termtab[];
92 extern int tti;
93 #endif
94 extern int ifl[NSO];
95 extern int ifi;
96 extern int pendt;
97 extern int flss;
98 extern int fi;
99 extern int lg;
100 extern char ptname[];
101 extern int print;
102 extern int nonumb;
103 extern int pnlist[];
104 extern int *pnp;
105 extern int nb;
106 extern int trap;
107 extern int tflg;
108 extern int ejf;
109 extern int lit;
110 extern int cc;
111 extern int c2;
112 extern int spread;
113 extern int gflag;
114 extern int oline[];
115 extern int *olinep;
116 extern int dpn;
117 extern int noscale;
118 extern char *unlkp;
119 extern int pts;
120 extern int level;
121 extern int ttysave;
122 extern int tdelim;
123 extern int dotT;
124 extern int tabch, ldrch;
125 extern int eqflg;
126 extern no_out;
127 extern int hflg;
128 #ifndef NROFF
129 extern char codetab[];
130 extern int spbits;
131 #endif
132 extern int xxx;
133 int stopmesg;
134 filep ipl[NSO];
135 long offl[NSO];
136 long ioff;
137 char *ttyp;
138 extern struct contab {
139 	int rq;
140 	union {
141 		int (*f)();
142 		unsigned mx;
143 	}x;
144 }contab[NM];
145 int ms[] = {31,28,31,30,31,30,31,31,30,31,30,31};
146 #ifndef NROFF
147 int acctf;
148 #endif
149 
150 main(argc,argv)
151 int argc;
152 char **argv;
153 {
154 	char *p, *q;
155 	register i, j;
156 	extern catch(), fpecatch(), kcatch();
157 
158 	signal(SIGHUP,catch);
159 	if(signal(SIGINT,catch) == SIG_IGN){
160 		signal(SIGHUP,SIG_IGN);
161 		signal(SIGINT,SIG_IGN);
162 		signal(SIGQUIT,SIG_IGN);
163 	}
164 	signal(SIGFPE,fpecatch);
165 	signal(SIGPIPE,catch);
166 	signal(SIGTERM,kcatch);
167 	init1(argv[0][0]);
168 options:
169 	while(--argc > 0 && (++argv)[0][0]=='-')
170 		switch(argv[0][1]){
171 
172 		case 0:
173 			goto start;
174 		case 'i':
175 			stdi++;
176 			continue;
177 		case 'q':
178 			quiet++;
179 			if(gtty(0, &ttys) >= 0)
180 				ttysave = ttys.sg_flags;
181 			continue;
182 		case 'n':
183 			npn = cnum(&argv[0][2]);
184 			continue;
185 		case 'p':
186 			xflg = 0;
187 			cps = cnum(&argv[0][2]);
188 			continue;
189 		case 'S':
190 			stopmesg++;
191 			continue;
192 		case 's':
193 			if(!(stop = cnum(&argv[0][2])))stop++;
194 			continue;
195 		case 'r':
196 			vlist[findr(argv[0][2])] = cnum(&argv[0][3]);
197 			continue;
198 		case 'm':
199 			p = &nextf[nfi];
200 			q = &argv[0][2];
201 			while((*p++ = *q++) != 0);
202 			if (access(nextf, 4) < 0) {
203 char *local = "/usr/local/lib/tmac/tmac.\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
204 				strcat(local, &argv[0][2]);
205 				if (access(local, 4) == 0)
206 					strcpy(nextf, local);
207 			}
208 			mflg++;
209 			continue;
210 		case 'o':
211 			getpn(&argv[0][2]);
212 			continue;
213 #ifdef NROFF
214 		case 'h':
215 			hflg++;
216 			continue;
217 		case 'z':
218 			no_out++;
219 			continue;
220 		case 'e':
221 			eqflg++;
222 			continue;
223 		case 'T':
224 			p = &termtab[tti];
225 			q = &argv[0][2];
226 			if(!((*q) & 0177))continue;
227 			while((*p++ = *q++) != 0);
228 			dotT++;
229 			continue;
230 #endif
231 #ifndef NROFF
232 		case 'z':
233 			no_out++;
234 		case 'a':
235 			ascii = 1;
236 			nofeed++;
237 		case 't':
238 			ptid = 1;
239 			continue;
240 		case 'w':
241 			waitf = 1;
242 			continue;
243 		case 'f':
244 			nofeed++;
245 			continue;
246 		case 'x':
247 			xflg = 0;
248 			continue;
249 		case 'b':
250 			if(open(ptname,1) < 0)prstr("Busy.\n");
251 			else prstr("Available.\n");
252 			done3(0);
253 		case 'g':
254 			stop = ptid = gflag = 1;
255 			dpn = 0;
256 			continue;
257 		case 'F':
258 			{
259 			  extern char *fontfile;
260 			  fontfile = &argv[0][2];
261 			}
262 			continue;
263 #endif
264 		default:
265 			pto = cnum(&argv[0][1]);
266 			continue;
267 		}
268 
269 	if(argv[0][0] == '+'){
270 		pfrom = cnum(&argv[0][1]);
271 		print = 0;
272 		if(argc > 0)goto options;
273 	}
274 
275 start:
276 	argp = argv;
277 	rargc = argc;
278 	init2();
279 	setjmp(sjbuf);
280 loop:
281 	copyf = lgf = nb = nflush = nlflg = 0;
282 	if(ip && (rbf0(ip)==0) && ejf && (frame->pframe <= ejl)){
283 		nflush++;
284 		trap = 0;
285 		eject((struct s *)0);
286 		goto loop;
287 	}
288 	i = getch();
289 	if(pendt)goto lt;
290 	if(lit && (frame <= litlev)){
291 		lit--;
292 		goto lt;
293 	}
294 	if((j = (i & CMASK)) == XPAR){
295 		copyf++;
296 		tflg++;
297 		for(;(i & CMASK) != '\n';)pchar(i = getch());
298 		tflg = 0;
299 		copyf--;
300 		goto loop;
301 	}
302 	if((j == cc) || (j == c2)){
303 		if(j == c2)nb++;
304 		copyf++;
305 		while(((j=((i=getch()) & CMASK)) == ' ') ||
306 			(j == '\t'));
307 		ch = i;
308 		copyf--;
309 		control(getrq(),1);
310 		flushi();
311 		goto loop;
312 	}
313 lt:
314 	ch = i;
315 	text();
316 	goto loop;
317 }
318 catch(){
319 /*
320 	prstr("Interrupt\n");
321 */
322 	done3(01);
323 }
324 fpecatch(){
325 	prstrfl("Floating Exception.\n");
326 	signal(SIGFPE,fpecatch);
327 }
328 kcatch(){
329 	signal(SIGTERM,SIG_IGN);
330 	done3(01);
331 }
332 #ifndef NROFF
333 acctg() {
334 	static char *acct_file = "/usr/adm/tracct";
335 	acctf = open(acct_file,1);
336 	setuid(getuid());
337 }
338 #endif
339 init1(a)
340 char a;
341 {
342 	register char *p;
343 	char *mktemp();
344 	register i;
345 
346 #ifndef NROFF
347 	acctg();/*open troff actg file while mode 4755*/
348 #endif
349 	p = mktemp("/tmp/taXXXXX");
350 	if(a == 'a')p = &p[5];
351 	if((close(creat(p, 0600))) < 0){
352 		prstr("Cannot create temp file.\n");
353 		exit(-1);
354 	}
355 	ibf = open(p, 2);
356 	for(i=256; --i;)trtab[i]=i;
357 	trtab[UNPAD] = ' ';
358 	mchbits();
359 	if(a != 'a')unlkp = p;
360 }
361 init2()
362 {
363 	register i,j;
364 	extern int block;
365 	extern char *setbrk();
366 	extern char *ttyname();
367 
368 	ttyod = 2;
369 	if(((ttyp=ttyname(j=0)) != (char *)0) ||
370 	   ((ttyp=ttyname(j=1)) != (char *)0) ||
371 	   ((ttyp=ttyname(j=2)) != (char *)0)
372 	  );else ttyp = "notty";
373 	iflg = j;
374 	if(ascii)mesg(0);
375 
376 	if((!ptid) && (!waitf)){
377 		if((ptid = open(ptname,1)) < 0){
378 			prstr("Typesetter busy.\n");
379 			done3(-2);
380 		}
381 	}
382 	ptinit();
383 	for(i=NEV; i--;)write(ibf, (char *)&block, EVS*sizeof(int));
384 	olinep = oline;
385 	ibufp = eibuf = ibuf;
386 	v.hp = init = 0;
387 	pinchar = inchar;	/* XXX */
388 	ioff = 0;
389 	v.nl = -1;
390 	cvtime();
391 	frame = stk = (struct s *)setbrk(DELTA);
392 	dip = &d[0];
393 	nxf = frame + 1;
394 	nx = mflg;
395 }
396 cvtime(){
397 
398 	register i;
399 	struct timeval t;
400 	struct timezone tz;
401 
402 	gettimeofday(&t, &tz);
403 	t.tv_sec -= 60*tz.tz_minuteswest;	/* 5hrs for EST */
404 	v.dy = (t.tv_sec/86400L) + 1;
405 	v.dw = (v.dy + 3)%7 + 1;
406 	for(v.yr=70;; v.yr++){
407 		if((v.yr)%4)ms[1]=28;else ms[1]=29;
408 		for(i=0;i<12;){
409 			if(v.dy<=ms[i]){
410 				v.mo = i+1;
411 				return;
412 			}
413 			v.dy -= ms[i++];
414 		}
415 	}
416 }
417 cnum(a)
418 char *a;
419 {
420 	register i;
421 
422 	ibufp = a;
423 	eibuf = (char *) MAXPTR;
424 	i = atoi();
425 	ch = 0;
426 	return(i);
427 }
428 mesg(f)
429 int f;
430 {
431 	static int mode;
432 
433 	if (ttyp==0)
434 		return;
435 	if(!f){
436 		stat(ttyp,cbuf);
437 		mode = ((struct stat *)(cbuf))->st_mode;
438 		chmod(ttyp,mode & ~022);
439 	}else{
440 		chmod(ttyp,mode);
441 	}
442 }
443 prstrfl(s)
444 char *s;
445 {
446 	flusho();
447 	prstr(s);
448 }
449 prstr(s)
450 char *s;
451 {
452 	register i;
453 	register char *j;
454 
455 	j = s;
456 	for(i=0;*s;i++)s++;
457 	write(ttyod,j,i);
458 }
459 control(a,b)
460 int a,b;
461 {
462 	register i,j;
463 	extern filep boff();
464 
465 	i = a;
466 	if((i == 0) || ((j = findmn(i)) == -1))return(0);
467 	if(contab[j].rq & MMASK){
468 		nxf->nargs = 0;
469 		if(b)collect();
470 		flushi();
471 		return(pushi(((filep)contab[j].x.mx)<<BLKBITS));
472 	}else{
473 		if(!b)return(0);
474 		return((*contab[j].x.f)(0));
475 	}
476 }
477 
478 getrq(){
479 	register i,j;
480 
481 	if(((i=getach()) == 0) ||
482 	   ((j=getach()) == 0))goto rtn;
483 	i = PAIR(i,j);
484 rtn:
485 	return(i);
486 }
487 getch(){
488 	register int i, j, k;
489 
490 	level++;
491 g0:
492 	if(ch){
493 		if(((i = ch) & CMASK) == '\n')nlflg++;
494 		ch = 0;
495 		level--;
496 		return(i);
497 	}
498 
499 	if(nlflg){
500 		level--;
501 		return('\n');
502 	}
503 
504 	if((k = (i = getch0()) & CMASK) != ESC){
505 		if(i & MOT)goto g2;
506 		if(k == FLSS){
507 			copyf++; raw++;
508 			i = getch0();
509 			if(!fi)flss = i;
510 			copyf--; raw--;
511 			goto g0;
512 		}
513 		if(k == RPT){
514 			setrpt();
515 			goto g0;
516 		}
517 		if(!copyf){
518 			if((k == 'f') && lg && !lgf){
519 				i = getlg(i);
520 				goto g2;
521 			}
522 			if((k == fc) || (k == tabch) || (k == ldrch)){
523 				if((i=setfield(k)) == 0)goto g0; else goto g2;
524 			}
525 			if(k == 010){
526 				i = makem(-width(' ' | chbits));
527 				goto g2;
528 			}
529 		}
530 		goto g2;
531 	}
532 	k = (j = getch0()) & CMASK;
533 	if(j & MOT){
534 		i = j;
535 		goto g2;
536 	}
537 /*
538 	if(k == tdelim){
539 		i = TDELIM;
540 		tdelim = IMP;
541 		goto g2;
542 	}
543 */
544 	switch(k){
545 
546 		case '\n':	/*concealed newline*/
547 			goto g0;
548 		case 'n':	/*number register*/
549 			setn();
550 			goto g0;
551 		case '*':	/*string indicator*/
552 			setstr();
553 			goto g0;
554 		case '$':	/*argument indicator*/
555 			seta();
556 			goto g0;
557 		case '{':	/*LEFT*/
558 			i = LEFT;
559 			goto gx;
560 		case '}':	/*RIGHT*/
561 			i = RIGHT;
562 			goto gx;
563 		case '"':	/*comment*/
564 			while(((i=getch0()) & CMASK ) != '\n');
565 			goto g2;
566 		case ESC:	/*double backslash*/
567 			i = eschar;
568 			goto gx;
569 		case 'e':	/*printable version of current eschar*/
570 			i = PRESC;
571 			goto gx;
572 		case ' ':	/*unpaddable space*/
573 			i = UNPAD;
574 			goto gx;
575 		case '|':	/*narrow space*/
576 			i = NARSP;
577 			goto gx;
578 		case '^':	/*half of narrow space*/
579 			i = HNSP;
580 			goto gx;
581 		case '\'':	/*\(aa*/
582 			i = 0222;
583 			goto gx;
584 		case '`':	/*\(ga*/
585 			i = 0223;
586 			goto gx;
587 		case '_':	/*\(ul*/
588 			i = 0224;
589 			goto gx;
590 		case '-':	/*current font minus*/
591 			i = 0210;
592 			goto gx;
593 		case '&':	/*filler*/
594 			i = FILLER;
595 			goto gx;
596 		case 'c':	/*to be continued*/
597 			i = CONT;
598 			goto gx;
599 		case ':':	/*lem's char*/
600 			i = COLON;
601 			goto gx;
602 		case '!':	/*transparent indicator*/
603 			i = XPAR;
604 			goto gx;
605 		case 't':	/*tab*/
606 			i = '\t';
607 			goto g2;
608 		case 'a':	/*leader (SOH)*/
609 			i = LEADER;
610 			goto g2;
611 		case '%':	/*ohc*/
612 			i = OHC;
613 			goto g2;
614 		case '.':	/*.*/
615 			i = '.';
616 		gx:
617 			i = (j & ~CMASK) | i;
618 			goto g2;
619 	}
620 	if(!copyf)
621 		switch(k){
622 
623 			case 'p':	/*spread*/
624 				spread++;
625 				goto g0;
626 			case '(':	/*special char name*/
627 				if((i=setch()) == 0)goto g0;
628 				break;
629 			case 's':	/*size indicator*/
630 				setps();
631 				goto g0;
632 			case 'f':	/*font indicator*/
633 				setfont(0);
634 				goto g0;
635 			case 'w':	/*width function*/
636 				setwd();
637 				goto g0;
638 			case 'v':	/*vert mot*/
639 				if(i = vmot())break;
640 				goto g0;
641 			case 'h': 	/*horiz mot*/
642 				if(i = hmot())break;
643 				goto g0;
644 			case 'z':	/*zero with char*/
645 				i = setz();
646 				break;
647 			case 'l':	/*hor line*/
648 				setline();
649 				goto g0;
650 			case 'L':	/*vert line*/
651 				setvline();
652 				goto g0;
653 			case 'b':	/*bracket*/
654 				setbra();
655 				goto g0;
656 			case 'o':	/*overstrike*/
657 				setov();
658 				goto g0;
659 			case 'k':	/*mark hor place*/
660 				if((i=findr(getsn())) == -1)goto g0;
661 				vlist[i] = v.hp = sumhp();	/* XXX */
662 				goto g0;
663 			case 'j':	/*mark output hor place*/
664 				if(!(i=getach()))goto g0;
665 				i = (i<<BYTE) | JREG;
666 				break;
667 			case '0':	/*number space*/
668 				i = makem(width('0' | chbits));
669 				break;
670 			case 'x':	/*extra line space*/
671 				if(i = xlss())break;
672 				goto g0;
673 			case 'u':	/*half em up*/
674 			case 'r':	/*full em up*/
675 			case 'd':	/*half em down*/
676 				i = sethl(k);
677 				break;
678 			default:
679 				i = j;
680 		}
681 	else{
682 		ch0 = j;
683 		i = eschar;
684 	}
685 g2:
686 	if((i & CMASK) == '\n'){
687 		nlflg++;
688 		v.hp = 0;
689 		pinchar = inchar;	/* XXX */
690 		if(ip == 0)v.cd++;
691 	}
692 	if(!--level){
693 		/* j = width(i); */
694 		/* v.hp += j; */
695 		/* cwidth = j; */
696 		if (pinchar >= inchar + LNSIZE) {	/* XXX */
697 			inchar[0] = makem(sumhp());
698 			pinchar = &inchar[1];
699 		}
700 		*pinchar++ = i;	/* XXX */
701 	}
702 	return(i);
703 }
704 
705 sumhp()	/* XXX - add up widths in inchar array */
706 {
707 	register int n;
708 	register int *p;
709 
710 	n = 0;
711 	for (p = inchar; p < pinchar; p++)
712 		n += width(*p);
713 	return(n);
714 }
715 char ifilt[32] = {0,001,002,003,0,005,006,007,010,011,012};
716 getch0(){
717 	register int i, j;
718 
719 	if(ch0){i=ch0; ch0=0; return(i);}
720 	if(nchar){nchar--; return(rchar);}
721 
722 again:
723 	if(cp){
724 		if((i = *cp++) == 0){
725 			cp = 0;
726 			goto again;
727 		}
728 	}else if(ap){
729 		if((i = *ap++) == 0){
730 			ap = 0;
731 			goto again;
732 		}
733 	}else if(ip){
734 		if(ip == -1)i = rdtty();
735 		else i = rbf();
736 	}else{
737 		if(donef)done(0);
738 		if(nx || ((ibufp >= eibuf) && (ibufp != (char *) MAXPTR))){
739 			if(nfo)goto g1;
740 		g0:
741 			if(nextfile()){
742 				if(ip)goto again;
743 				if(ibufp < eibuf)goto g2;
744 			}
745 		g1:
746 			nx = 0;
747 			if((j=read(ifile,ibuf,IBUFSZ)) <= 0)goto g0;
748 			ibufp = ibuf;
749 			eibuf = ibuf + j;
750 			if(ip)goto again;
751 		}
752 	g2:
753 		i = *ibufp++ & 0177;
754 		ioff++;
755 		if(i >= 040)goto g4; else i = ifilt[i];
756 	}
757 	if(raw)return(i);
758 	if((j = i & CMASK) == IMP)goto again;
759 	if((i == 0) && !init)goto again;
760 g4:
761 	if((copyf == 0) && ((i & ~BMASK) == 0) && ((i & CMASK) < 0370))
762 #ifndef NROFF
763 		if(spbits && (i>31) && ((codetab[i-32] & 0200))) i |= spbits;
764 		else
765 #endif
766 		i |= chbits;
767 	if((i & CMASK) == eschar)i = (i & ~CMASK) | ESC;
768 	return(i);
769 }
770 nextfile(){
771 	register char *p;
772 
773 n0:
774 	if(ifile)close(ifile);
775 	if(nx){
776 		p = nextf;
777 		if(*p != 0)goto n1;
778 	}
779 	if(ifi > 0){
780 		if(popf())goto n0; /*popf error*/
781 		return(1); /*popf ok*/
782 	}
783 	if(rargc-- <= 0)goto n2;
784 	p = (argp++)[0];
785 n1:
786 	if((p[0] == '-') && (p[1] == 0)){
787 		ifile = 0;
788 	}else if((ifile=open(p,0)) < 0){
789 		prstr("Cannot open ");
790 		prstr(p);
791 		prstr("\n");
792 		nfo -= mflg;
793 		done(02);
794 	}
795 	nfo++;
796 	v.cd = 0;
797 	ioff = 0;
798 	return(0);
799 n2:
800 	if((nfo -= mflg) && !stdi)done(0);
801 	nfo++;
802 	v.cd = ifile =  stdi = mflg = 0;
803 	ioff = 0;
804 	return(0);
805 }
806 popf(){
807 	register i;
808 	register char *p, *q;
809 	extern char *ttyname();
810 
811 	ioff = offl[--ifi];
812 	ip = ipl[ifi];
813 	if((ifile = ifl[ifi]) == 0){
814 		p = xbuf;
815 		q = ibuf;
816 		ibufp = xbufp;
817 		eibuf = xeibuf;
818 		while(q < eibuf)*q++ = *p++;
819 		return(0);
820 	}
821 	if((lseek(ifile,(long)(ioff & ~(IBUFSZ-1)),0) < 0) ||
822 	   ((i = read(ifile,ibuf,IBUFSZ)) < 0))return(1);
823 	eibuf = ibuf + i;
824 	ibufp = ibuf;
825 	if(ttyname(ifile) == (char *)0)
826 		if((ibufp = ibuf + (int)(ioff & (IBUFSZ-1)))  >= eibuf)return(1);
827 	return(0);
828 }
829 flushi(){
830 	if(nflush)return;
831 	ch = 0;
832 	if((ch0 & CMASK) == '\n')nlflg++;
833 	ch0 = 0;
834 	copyf++;
835 	while(!nlflg){
836 		if(donef && (frame == stk))break;
837 		getch();
838 	}
839 	copyf--;
840 	v.hp = 0;
841 	pinchar = inchar;	/* XXX */
842 }
843 getach(){
844 	register i;
845 
846 	lgf++;
847 	if(((i = getch()) & MOT) ||
848 	    ((i&CMASK) == ' ') ||
849 	    ((i&CMASK) == '\n')||
850 	    (i & 0200)){
851 			ch = i;
852 			i = 0;
853 	}
854 	lgf--;
855 	return(i & 0177);
856 }
857 casenx(){
858 	lgf++;
859 	skip();
860 	getname();
861 	nx++;
862 	nextfile();
863 	nlflg++;
864 	ip = 0;
865 	ap = 0;
866 	nchar = pendt = 0;
867 	frame = stk;
868 	nxf = frame + 1;
869 }
870 getname(){
871 	register int i, j, k;
872 
873 	lgf++;
874 	for(k=0; k < (NS-1); k++){
875 		if(((j=(i=getch()) & CMASK) <= ' ') ||
876 			(j > 0176))break;
877 		nextf[k] = j;
878 	}
879 	nextf[k] = 0;
880 	ch = i;
881 	lgf--;
882 	return(nextf[0]);
883 }
884 caseso(){
885 	register i;
886 	register char *p, *q;
887 
888 	lgf++;
889 	nextf[0] = 0;
890 	if(skip() || !getname() || ((i=open(nextf,0)) <0) || (ifi >= NSO)) {
891 		prstr("can't open file ");
892 		prstr(nextf);
893 		prstr("\n");
894 		done(02);
895 	}
896 	flushi();
897 	ifl[ifi] = ifile;
898 	ifile = i;
899 	offl[ifi] = ioff;
900 	ioff = 0;
901 	ipl[ifi] = ip;
902 	ip = 0;
903 	nx++;
904 	nflush++;
905 	if(!ifl[ifi++]){
906 		p = ibuf;
907 		q = xbuf;
908 		xbufp = ibufp;
909 		xeibuf = eibuf;
910 		while(p < eibuf)*q++ = *p++;
911 	}
912 }
913 
914 casecf(){	/* copy file without change */
915 	int fd, i, n;
916 	char buf[OBUFSZ];
917 
918 	flusho();
919 	lgf++;
920 	nextf[0] = 0;
921 	if(skip() || !getname() || ((fd=open(nextf,0)) <0) || (ifi >= NSO)) {
922 		prstr("can't open file ");
923 		prstr(nextf);
924 		prstr("\n");
925 		done(02);
926 	}
927 	while ((n = read(fd, buf, OBUFSZ)) > 0)
928 		for (i = 0; i < n; i++)
929 			oput(buf[i]);
930 	flusho();
931 	close(fd);
932 }
933 getpn(a)
934 char *a;
935 {
936 	register i, neg;
937 	long atoi1();
938 
939 	if((*a & 0177) == 0)return;
940 	neg = 0;
941 	ibufp = a;
942 	eibuf = (char *) MAXPTR;
943 	noscale++;
944 	while((i = getch() & CMASK) != 0)switch(i){
945 		case '+':
946 		case ',':
947 			continue;
948 		case '-':
949 			neg = MOT;
950 			goto d2;
951 		default:
952 			ch = i;
953 		d2:
954 			i = atoi1();
955 			if(nonumb)goto fini;
956 			else{
957 				*pnp++ = i | neg;
958 				neg = 0;
959 				if(pnp >= &pnlist[NPN-2]){
960 					prstr("Too many page numbers\n");
961 					done3(-3);
962 				}
963 			}
964 		}
965 fini:
966 	if(neg)*pnp++ = -2;
967 	*pnp = -1;
968 	ch = noscale = print = 0;
969 	pnp = pnlist;
970 	if(*pnp != -1)chkpn();
971 }
972 setrpt(){
973 	register i, j;
974 
975 	copyf++;raw++;
976 	i = getch0();
977 	copyf--;raw--;
978 	if((i < 0) ||
979 	   (((j = getch0()) & CMASK) == RPT))return;
980 	rchar = j;
981 	nchar = i & BMASK;
982 }
983