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 static char sccsid[] = "@(#)n5.c 4.4 (Berkeley) 05/02/91";
10 #endif /* not lint */
11
12 #include "tdef.h"
13 #include <sgtty.h>
14 extern
15 #include "d.h"
16 extern
17 #include "v.h"
18 #include "sdef.h"
19
20 /*
21 troff5.c
22
23 misc processing requests
24 */
25
26 extern int inchar[LNSIZE], *pinchar; /* XXX */
27 extern struct s *frame;
28 extern struct s *litlev;
29 extern filep ip;
30 extern filep offset;
31
32 extern int ascii;
33 extern int nonumb;
34 extern int admod;
35 extern int ad;
36 extern int fi;
37 extern int cc;
38 extern int c2;
39 extern int ohc;
40 extern int tabc;
41 extern int dotc;
42 extern int pendnf;
43 extern int hyf;
44 extern int ce;
45 extern int po;
46 extern int po1;
47 extern int nc;
48 extern int in;
49 extern int un;
50 extern int un1;
51 extern int in1;
52 extern int ll;
53 extern int ll1;
54 extern int lt;
55 extern int lt1;
56 extern int nlistx[NTRAP];
57 extern int mlist[NTRAP];
58 extern int lgf;
59 extern int pl;
60 extern int npn;
61 extern int npnflg;
62 extern int copyf;
63 extern char nextf[];
64 extern int trap;
65 extern int lss;
66 extern int em;
67 extern int evlist[EVLSZ];
68 extern int evi;
69 extern int ibf;
70 extern int ev;
71 extern int ch;
72 extern int nflush;
73 extern int tty;
74 extern struct sgttyb ttys;
75 extern int quiet;
76 extern int iflg;
77 extern int eschar;
78 extern int lit;
79 extern int ls;
80 extern int ls1;
81 extern int tabtab[];
82 extern char trtab[];
83 extern int ul;
84 extern int cu;
85 extern int sfont;
86 extern int font;
87 extern int fontlab[];
88 extern int it;
89 extern int itmac;
90 extern int noscale;
91 extern int ic;
92 extern int icf;
93 extern int ics;
94 extern int *vlist;
95 extern int sv;
96 extern int esc;
97 extern int nn;
98 extern int nms;
99 extern int ndf;
100 extern int lnmod;
101 extern int ni;
102 extern int lnsize;
103 extern int nb;
104 extern int nlflg;
105 extern int apts, apts1, pts, pts1, font, font1;
106 extern int ulfont;
107 extern int ulbit;
108 extern int error;
109 extern int nmbits;
110 extern int chbits;
111 extern int tdelim;
112 extern int xxx;
113 int iflist[NIF];
114 int ifx;
115
casead()116 casead(){
117 register i;
118
119 ad = 1;
120 /*leave admod alone*/
121 if(skip())return;
122 switch(i = getch() & CMASK){
123 case 'r': /*right adj, left ragged*/
124 admod = 2;
125 break;
126 case 'l': /*left adj, right ragged*/
127 admod = ad = 0; /*same as casena*/
128 break;
129 case 'c': /*centered adj*/
130 admod = 1;
131 break;
132 case 'b': case 'n':
133 admod = 0;
134 break;
135 case '0': case '2': case '4':
136 ad = 0;
137 case '1': case '3': case '5':
138 admod = (i - '0')/2;
139 }
140 }
casena()141 casena(){
142 ad = 0;
143 }
casefi()144 casefi(){
145 tbreak();
146 fi++;
147 pendnf = 0;
148 lnsize = LNSIZE;
149 }
casenf()150 casenf(){
151 tbreak();
152 fi = 0;
153 /* can't do while oline is only LNSIZE
154 lnsize = LNSIZE + WDSIZE;
155 */
156 }
casers()157 casers(){
158 dip->nls = 0;
159 }
casens()160 casens(){
161 dip->nls++;
162 }
chget(c)163 chget(c)
164 int c;
165 {
166 register i;
167
168 if(skip() ||
169 ((i = getch()) & MOT) ||
170 ((i&CMASK) == ' ') ||
171 ((i&CMASK) == '\n')){
172 ch = i;
173 return(c);
174 }else return(i & BMASK);
175 }
casecc()176 casecc(){
177 cc = chget('.');
178 }
casec2()179 casec2(){
180 c2 = chget('\'');
181 }
casehc()182 casehc(){
183 ohc = chget(OHC);
184 }
casetc()185 casetc(){
186 tabc = chget(0);
187 }
caselc()188 caselc(){
189 dotc = chget(0);
190 }
casehy()191 casehy(){
192 register i;
193
194 hyf = 1;
195 if(skip())return;
196 noscale++;
197 i = atoi();
198 noscale = 0;
199 if(nonumb)return;
200 hyf = max(i,0);
201 }
casenh()202 casenh(){
203 hyf = 0;
204 }
max(aa,bb)205 max(aa,bb)
206 int aa,bb;
207 {
208 if(aa>bb)return(aa);
209 else return(bb);
210 }
casece()211 casece(){
212 register i;
213
214 noscale++;
215 skip();
216 i = max(atoi(),0);
217 if(nonumb)i = 1;
218 tbreak();
219 ce = i;
220 noscale = 0;
221 }
casein()222 casein(){
223 register i;
224
225 if(skip())i = in1;
226 else i = max(hnumb(&in),0);
227 tbreak();
228 in1 = in;
229 in = i;
230 if(!nc){
231 un = in;
232 setnel();
233 }
234 }
casell()235 casell(){
236 register i;
237
238 if(skip())i = ll1;
239 else i = max(hnumb(&ll),INCH/10);
240 ll1 = ll;
241 ll = i;
242 setnel();
243 }
caselt()244 caselt(){
245 register i;
246
247 if(skip())i = lt1;
248 else i = max(hnumb(<),0);
249 lt1 = lt;
250 lt = i;
251 }
caseti()252 caseti(){
253 register i;
254
255 if(skip())return;
256 i = max(hnumb(&in),0);
257 tbreak();
258 un1 = i;
259 setnel();
260 }
casels()261 casels(){
262 register i;
263
264 noscale++;
265 if(skip())i = ls1;
266 else i = max(inumb(&ls),1);
267 ls1 = ls;
268 ls = i;
269 noscale = 0;
270 }
casepo()271 casepo(){
272 register i;
273
274 if(skip())i = po1;
275 else i = max(hnumb(&po),0);
276 po1 = po;
277 po = i;
278 #ifndef NROFF
279 if(!ascii)esc += po - po1;
280 #endif
281 }
casepl()282 casepl(){
283 register i;
284
285 skip();
286 if((i = vnumb(&pl)) == 0)pl = 11 * INCH; /*11in*/
287 else pl = i;
288 if(v.nl > pl)v.nl = pl;
289 }
casewh()290 casewh(){
291 register i, j, k;
292
293 lgf++;
294 skip();
295 i = vnumb((int *)0);
296 if(nonumb)return;
297 skip();
298 j = getrq();
299 if((k=findn(i)) != NTRAP){
300 mlist[k] = j;
301 return;
302 }
303 for(k=0; k<NTRAP; k++)if(mlist[k] == 0)break;
304 if(k == NTRAP){
305 prstrfl("Cannot plant trap.\n");
306 return;
307 }
308 mlist[k] = j;
309 nlistx[k] = i;
310 }
casech()311 casech(){
312 register i, j, k;
313
314 lgf++;
315 skip();
316 if(!(j=getrq()))return;
317 else for(k=0; k<NTRAP; k++)if(mlist[k] == j)break;
318 if(k == NTRAP)return;
319 skip();
320 i = vnumb((int *)0);
321 if(nonumb)mlist[k] = 0;
322 nlistx[k] = i;
323 }
findn(i)324 findn(i)
325 int i;
326 {
327 register k;
328
329 for(k=0; k<NTRAP; k++)
330 if((nlistx[k] == i) && (mlist[k] != 0))break;
331 return(k);
332 }
casepn()333 casepn(){
334 register i;
335
336 skip();
337 noscale++;
338 i = max(inumb(&v.pn),0);
339 noscale = 0;
340 if(!nonumb){
341 npn = i;
342 npnflg++;
343 }
344 }
casebp()345 casebp(){
346 register i;
347 register struct s *savframe;
348
349 if(dip != d)return;
350 savframe = frame;
351 skip();
352 if((i = inumb(&v.pn)) < 0)i = 0;
353 tbreak();
354 if(!nonumb){
355 npn = i;
356 npnflg++;
357 }else if(dip->nls)return;
358 eject(savframe);
359 }
casetm(x)360 casetm(x) int x;{
361 register i;
362 char tmbuf[NTM];
363
364 lgf++;
365 copyf++;
366 if(skip() && x)prstrfl("User Abort.");
367 for(i=0; i<NTM-2;)if((tmbuf[i++]=getch()) == '\n')break;
368 if(i == NTM-2)tmbuf[i++] = '\n';
369 tmbuf[i] = 0;
370 prstrfl(tmbuf);
371 copyf--;
372 }
casesp(a)373 casesp(a)
374 int a;
375 {
376 register i, j, savlss;
377
378 tbreak();
379 if(dip->nls || trap)return;
380 i = findt1();
381 if(!a){
382 skip();
383 j = vnumb((int *)0);
384 if(nonumb)j = lss;
385 }else j = a;
386 if(j == 0)return;
387 if(i < j)j = i;
388 savlss = lss;
389 if(dip != d)i = dip->dnl; else i = v.nl;
390 if((i + j) < 0)j = -i;
391 lss = j;
392 newline(0);
393 lss = savlss;
394 }
casert()395 casert(){
396 register a, *p;
397
398 skip();
399 if(dip != d)p = &dip->dnl; else p = &v.nl;
400 a = vnumb(p);
401 if(nonumb)a = dip->mkline;
402 if((a < 0) || (a >= *p))return;
403 nb++;
404 casesp(a - *p);
405 }
caseem()406 caseem(){
407 lgf++;
408 skip();
409 em = getrq();
410 }
casefl()411 casefl(){
412 tbreak();
413 flusho();
414 }
caseev()415 caseev(){
416 register nxev;
417 extern int block;
418
419 if(skip()){
420 e0:
421 if(evi == 0)return;
422 nxev = evlist[--evi];
423 goto e1;
424 }
425 noscale++;
426 nxev = atoi();
427 noscale = 0;
428 if(nonumb)goto e0;
429 flushi();
430 if((nxev >= NEV) || (nxev < 0) || (evi >= EVLSZ)){
431 prstrfl("Cannot do ev.\n");
432 if(error)done2(040);else edone(040);
433 return;
434 }
435 evlist[evi++] = ev;
436 e1:
437 if(ev == nxev)return;
438 lseek(ibf, (long)(ev*EVS*sizeof(int)), 0);
439 write(ibf,(char *)&block, EVS*sizeof(int));
440 lseek(ibf, (long)(nxev*EVS*sizeof(int)), 0);
441 read(ibf,(char *)&block, EVS*sizeof(int));
442 ev = nxev;
443 }
caseel()444 caseel(){
445 if(--ifx < 0){
446 ifx = 0;
447 iflist[0] = 0;
448 }
449 caseif(2);
450 }
caseie()451 caseie(){
452 if(ifx >= NIF){
453 prstr("if-else overflow.\n");
454 ifx = 0;
455 edone(040);
456 }
457 caseif(1);
458 ifx++;
459 }
caseif(x)460 caseif(x)
461 int x;
462 {
463 register i, notflag, true;
464
465 if(x == 2){
466 notflag = 0;
467 true = iflist[ifx];
468 goto i1;
469 }
470 true = 0;
471 skip();
472 if(((i = getch()) & CMASK) == '!'){
473 notflag = 1;
474 }else{
475 notflag = 0;
476 ch = i;
477 }
478 i = atoi();
479 if(!nonumb){
480 if(i > 0)true++;
481 goto i1;
482 }
483 switch((i = getch()) & CMASK){
484 case 'e':
485 if(!(v.pn & 01))true++;
486 break;
487 case 'o':
488 if(v.pn & 01)true++;
489 break;
490 #ifdef NROFF
491 case 'n':
492 true++;
493 case 't':
494 #endif
495 #ifndef NROFF
496 case 't':
497 true++;
498 case 'n':
499 #endif
500 case ' ':
501 break;
502 default:
503 true = cmpstr(i);
504 }
505 i1:
506 true ^= notflag;
507 if(x == 1)iflist[ifx] = !true;
508 if(true){
509 i2:
510 do{
511 v.hp = 0;
512 pinchar = inchar; /* XXX */
513 }
514 while(((i = getch()) & CMASK) == ' ');
515 if((i & CMASK) == LEFT)goto i2;
516 ch = i;
517 nflush++;
518 }else{
519 copyf++;
520 if(eat(LEFT) == LEFT){
521 while(eatblk(RIGHT,LEFT) != RIGHT)nlflg = 0;
522 }
523 copyf--;
524 }
525 }
eatblk(right,left)526 eatblk(right,left)
527 int right,left;
528 {
529 register i;
530
531 e0:
532 while(((i = getch() & CMASK) != right) &&
533 (i != left) &&
534 (i != '\n'));
535 if(i == left){
536 while((i=eatblk(right,left)) != right)nlflg = 0;
537 goto e0;
538 }
539 return(i);
540 }
cmpstr(delim)541 cmpstr(delim)
542 int delim;
543 {
544 register i, j;
545 register filep p;
546 extern filep alloc();
547 extern filep incoff();
548 filep begin;
549 int cnt, k;
550 int savapts, savapts1, savfont, savfont1,
551 savpts, savpts1;
552
553 if(delim & MOT)return(0);
554 delim &= CMASK;
555 if(dip != d)wbfl();
556 if((offset = begin = alloc()) == (filep)0)return(0);
557 cnt = 0;
558 v.hp = 0;
559 pinchar = inchar; /* XXX */
560 savapts = apts;
561 savapts1 = apts1;
562 savfont = font;
563 savfont1 = font1;
564 savpts = pts;
565 savpts1 = pts1;
566 while(((j = (i=getch()) & CMASK) != delim) && (j != '\n')){
567 wbf(i);
568 cnt++;
569 }
570 wbt(0);
571 k = !cnt;
572 if(nlflg)goto rtn;
573 p = begin;
574 apts = savapts;
575 apts1 = savapts1;
576 font = savfont;
577 font1 = savfont1;
578 pts = savpts;
579 pts1 = savpts1;
580 mchbits();
581 v.hp = 0;
582 pinchar = inchar; /* XXX */
583 while(((j = (i=getch()) & CMASK) != delim) && (j != '\n')){
584 if(rbf0(p) != i){
585 eat(delim);
586 k = 0;
587 break;
588 }
589 p = incoff(p);
590 k = !(--cnt);
591 }
592 rtn:
593 apts = savapts;
594 apts1 = savapts1;
595 font = savfont;
596 font1 = savfont1;
597 pts = savpts;
598 pts1 = savpts1;
599 mchbits();
600 offset = dip->op;
601 ffree(begin);
602 return(k);
603 }
caserd()604 caserd(){
605
606 lgf++;
607 skip();
608 getname();
609 if(!iflg){
610 if(quiet){
611 ttys.sg_flags &= ~ECHO;
612 stty(0, &ttys);
613 prstrfl(""); /*bell*/
614 }else{
615 if(nextf[0]){
616 prstr(nextf);
617 prstr(":");
618 }else{
619 prstr(""); /*bell*/
620 }
621 }
622 }
623 collect();
624 tty++;
625 pushi((filep)-1);
626 }
rdtty()627 rdtty(){
628 char onechar;
629
630 onechar = 0;
631 if(read(0, &onechar, 1) == 1){
632 if(onechar == '\n')tty++;
633 else tty = 1;
634 if(tty != 3)return(onechar);
635 }
636 popi();
637 tty = 0;
638 if(quiet){
639 ttys.sg_flags |= ECHO;
640 stty(0, &ttys);
641 }
642 return(0);
643 }
caseec()644 caseec(){
645 eschar = chget('\\');
646 }
caseeo()647 caseeo(){
648 eschar = 0;
649 }
caseli()650 caseli(){
651
652 skip();
653 lit = max(inumb((int *)0),1);
654 litlev = frame;
655 if((dip == d) && (v.nl == -1))newline(1);
656 }
caseta()657 caseta(){
658 register i;
659
660 tabtab[0] = nonumb = 0;
661 for(i=0; ((i < (NTAB-1)) && !nonumb); i++){
662 if(skip())break;
663 tabtab[i] = tabtab[max(i-1,0)] & TMASK;
664 tabtab[i] = max(hnumb(&tabtab[i]),0) & TMASK;
665 if(!nonumb) switch(ch & CMASK){
666 case 'C':
667 tabtab[i] |= CTAB;
668 break;
669 case 'R':
670 tabtab[i] |= RTAB;
671 break;
672 default: /*includes L*/
673 break;
674 }
675 nonumb = ch = 0;
676 }
677 tabtab[i] = 0;
678 }
casene()679 casene(){
680 register i, j;
681
682 skip();
683 i = vnumb((int *)0);
684 if(nonumb)i = lss;
685 if(i > (j = findt1())){
686 i = lss;
687 lss = j;
688 dip->nls = 0;
689 newline(0);
690 lss = i;
691 }
692 }
casetr()693 casetr(){
694 register i, j;
695
696 lgf++;
697 skip();
698 while((i = getch() & CMASK) != '\n'){
699 if((i & MOT) || ((j = getch()) & MOT))return;
700 if((j &= CMASK) == '\n')j = ' ';
701 trtab[i] = j;
702 }
703 }
casecu()704 casecu(){
705 cu++;
706 caseul();
707 }
caseul()708 caseul(){
709 register i;
710
711 noscale++;
712 if(skip())i = 1;
713 else i = atoi();
714 if(ul && (i == 0)){
715 font = sfont;
716 ul = cu = 0;
717 }
718 if(i){
719 if(!ul){
720 sfont = font;
721 font = ulfont;
722 }
723 ul = i;
724 }
725 noscale = 0;
726 mchbits();
727 }
caseuf()728 caseuf(){
729 register i, j;
730
731 if(skip() || !(i = getrq()) || (i == 'S') ||
732 ((j = find(i,fontlab)) == -1))
733 ulfont = 1; /*default position 2*/
734 else ulfont = j;
735 #ifdef NROFF
736 if(ulfont == 0)ulfont = 1;
737 #endif
738 ulbit = ulfont<<9;
739 }
caseit()740 caseit(){
741 register i;
742
743 lgf++;
744 it = itmac = 0;
745 noscale++;
746 skip();
747 i = atoi();
748 skip();
749 if(!nonumb && (itmac = getrq()))it = i;
750 noscale = 0;
751 }
casemc()752 casemc(){
753 register i;
754
755 if(icf > 1)ic = 0;
756 icf = 0;
757 if(skip())return;
758 ic = getch();
759 icf = 1;
760 skip();
761 i = max(hnumb((int *)0),0);
762 if(!nonumb)ics = i;
763 }
casemk()764 casemk(){
765 register i, j;
766
767 if(dip != d)j = dip->dnl; else j = v.nl;
768 if(skip()){
769 dip->mkline = j;
770 return;
771 }
772 if((i = getrq()) == 0)return;
773 vlist[findr(i)] = j;
774 }
casesv()775 casesv(){
776 register i;
777
778 skip();
779 if((i = vnumb((int *)0)) < 0)return;
780 if(nonumb)i = 1;
781 sv += i;
782 caseos();
783 }
caseos()784 caseos(){
785 register savlss;
786
787 if(sv <= findt1()){
788 savlss = lss;
789 lss = sv;
790 newline(0);
791 lss = savlss;
792 sv = 0;
793 }
794 }
casenm()795 casenm(){
796 register i;
797
798 lnmod = nn = 0;
799 if(skip())return;
800 lnmod++;
801 noscale++;
802 i = inumb(&v.ln);
803 if(!nonumb)v.ln = max(i,0);
804 getnm(&ndf,1);
805 getnm(&nms,0);
806 getnm(&ni,0);
807 noscale = 0;
808 nmbits = chbits;
809 }
getnm(p,min)810 getnm(p,min)
811 int *p, min;
812 {
813 register i;
814
815 eat(' ');
816 if(skip())return;
817 i = atoi();
818 if(nonumb)return;
819 *p = max(i,min);
820 }
casenn()821 casenn(){
822 noscale++;
823 skip();
824 nn = max(atoi(),1);
825 noscale = 0;
826 }
caseab()827 caseab(){
828 dummy();
829 casetm(1);
830 done2(0);
831 }
832