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