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