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