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