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