SYSENTER/SYSCALL support
[minix.git] / commands / cawf / nreq.c
blobce64842c77a37c3bfbab3eb3438e1349104cfe5b
1 /*
2 * nreq.c - cawf(1) processing of nroff requests
3 */
5 /*
6 * Copyright (c) 1991 Purdue University Research Foundation,
7 * West Lafayette, Indiana 47907. All rights reserved.
9 * Written by Victor A. Abell <abe@mace.cc.purdue.edu>, Purdue
10 * University Computing Center. Not derived from licensed software;
11 * derived from awf(1) by Henry Spencer of the University of Toronto.
13 * Permission is granted to anyone to use this software for any
14 * purpose on any computer system, and to alter it and redistribute
15 * it freely, subject to the following restrictions:
17 * 1. The author is not responsible for any consequences of use of
18 * this software, even if they arise from flaws in it.
20 * 2. The origin of this software must not be misrepresented, either
21 * by explicit claim or by omission. Credits must appear in the
22 * documentation.
24 * 3. Altered versions must be plainly marked as such, and must not
25 * be misrepresented as being the original software. Credits must
26 * appear in the documentation.
28 * 4. This notice may not be removed or altered.
31 #include "cawf.h"
32 #include <ctype.h>
36 * Prototypes for request processing functions.
39 static void nr_UL(unsigned char *line, int brk);
40 static void nr_Ub(unsigned char *line, int brk);
41 static void nr_Uc(unsigned char *line, int brk);
42 static void nr_Uf(unsigned char *line, int brk);
43 static void nr_Ur(unsigned char *line, int brk);
44 static void nr_ad(unsigned char *line, int brk);
45 static void nr_bp(unsigned char *line, int brk);
46 static void nr_br(unsigned char *line, int brk);
47 static void nr_ce(unsigned char *line, int brk);
48 static void nr_di(unsigned char *line, int brk);
49 static void nr_ds(unsigned char *line, int brk);
50 static void nr_fi(unsigned char *line, int brk);
51 static void nr_fl(unsigned char *line, int brk);
52 static void nr_ft(unsigned char *line, int brk);
53 static void nr_it(unsigned char *line, int brk);
54 static void nr_na(unsigned char *line, int brk);
55 static void nr_nf(unsigned char *line, int brk);
56 static void nr_ns(unsigned char *line, int brk);
57 static void nr_rm(unsigned char *line, int brk);
58 static void nr_rn(unsigned char *line, int brk);
59 static void nr_rr(unsigned char *line, int brk);
60 static void nr_rs(unsigned char *line, int brk);
61 static void nr_tm(unsigned char *line, int brk);
62 static void nr_tr(unsigned char *line, int brk);
64 static void nr_nil(unsigned char *line, int brk);
68 * NrReqt[] - nroff request processing table
70 * CAUTION: place new entries in their proper alphabetical order, since
71 * this table is processed with a binary search.
74 static struct nr_req {
75 char *nm; /* nroff request */
76 void (*fun)(); /* processing function */
77 } NrReqt[] = {
78 { "\\\"", nr_nil }, /* backslash-quote */
79 { "^#", nr_UL },
80 { "^=", nr_UL },
81 { "^b", nr_Ub },
82 { "^c", nr_Uc },
83 { "^d", nr_nil },
84 { "^e", nr_nil },
85 { "^f", nr_Uf },
86 { "^r", nr_Ur },
87 { "^x", nr_nil },
88 { "ad", nr_ad },
89 { "bp", nr_bp },
90 { "br", nr_br },
91 { "ce", nr_ce },
92 { "di", nr_di },
93 { "ds", nr_ds },
94 { "fi", nr_fi },
95 { "fl", nr_fl },
96 { "ft", nr_ft },
97 { "hy", nr_nil },
98 { "i0", nr_nil },
99 { "it", nr_it },
100 { "lg", nr_nil },
101 { "li", nr_nil },
102 { "na", nr_na },
103 { "nf", nr_nf },
104 { "ns", nr_ns },
105 { "ps", nr_nil },
106 { "rm", nr_rm },
107 { "rn", nr_rn },
108 { "rr", nr_rr },
109 { "rs", nr_rs },
110 { "tm", nr_tm },
111 { "tr", nr_tr },
112 { "vs", nr_nil },
115 * Nreq(line, brk) - process miscellaneous nroff requests from line
116 * buffer with request status of (brk)
119 void
120 Nreq(line, brk)
121 unsigned char *line;
122 int brk;
124 unsigned char c[3]; /* command buffer */
125 int cmp, hi, low, mid; /* binary search indixes */
127 c[0] = c[1] = c[2] = '\0';
128 if ((c[0] = line[1]) != '\0')
129 c[1] = line[2];
131 low = mid = 0;
132 hi = sizeof(NrReqt) / sizeof(struct nr_req);
133 while (low <= hi) {
134 mid = (low + hi) / 2;
135 if ((cmp = strcmp((char *)c, NrReqt[mid].nm)) < 0)
136 hi = mid - 1;
137 else if (cmp > 0)
138 low = mid + 1;
139 else {
140 (void) (*NrReqt[mid].fun)(line, brk);
141 return;
145 * Unknown request starting with a '.' or '\''..
147 Error(WARN, LINE, " unknown request", NULL);
152 * Adjust - "^[.']ad"
155 static void
156 nr_ad(line, brk)
157 unsigned char *line;
158 int brk;
160 Pass3(NOBREAK, (unsigned char *)"both", NULL, 0);
165 * Begin new page - "^[.']bp"
168 static void
169 nr_bp(line, brk)
170 unsigned char *line;
171 int brk;
173 Pass3(brk, (unsigned char *)"need", NULL, 999);
178 * Break - "^[.']br"
181 static void
182 nr_br(line, brk)
183 unsigned char *line;
184 int brk;
186 Pass3(brk, (unsigned char *)"flush", NULL, 0);
191 * Center - "^[.']ce"
194 static void
195 nr_ce(line, brk)
196 unsigned char *line;
197 int brk;
199 unsigned char *s; /* string poiner */
201 if ((s = Field(2, line, 0)) != NULL)
202 Centering = atoi((char *)s);
203 else
204 Centering = 1;
209 * Diversion on and off - "^[.']di"
212 static void
213 nr_di(line, brk)
214 unsigned char *line;
215 int brk;
217 Pass3(DOBREAK, (unsigned char *)"flush", NULL, 0);
218 Divert ^= 1;
223 * Define string - "^[.']ds"
226 static void
227 nr_ds(line, brk)
228 unsigned char *line;
229 int brk;
231 unsigned char buf[MAXLINE]; /* temporary buffer */
232 unsigned char nm[4], nm1[4]; /* name buffers */
233 unsigned char *s1, *s2, *s3, /* temporary string pointers */
234 *s4;
236 if (Asmname(&line[3], nm) == 0) {
237 Error(WARN, LINE, " no name", NULL);
238 return;
240 s1 = Field(3, line, 0);
241 s2 = Findstr(nm, s1, 1);
242 while (*s2 == '\\' && *(s2 + 1) == '*') {
243 s2++;
244 s3 = Asmcode(&s2, nm1);
245 s2 = Findstr(nm1, NULL, 0);
247 if (Hdft) {
250 * Look for names LH, LF, CH, CF, RH, RF.
252 if ((nm[0]=='L' || nm[0]=='C' || nm[0]=='R')
253 && (nm[1]=='F' || nm[1]=='H')) {
254 (void) sprintf((char *)buf, "%s", (char *)nm);
255 Pass3(NOBREAK, buf, s2, 0);
263 * Fill - "^[.']fi"
266 static void
267 nr_fi(line, brk)
268 unsigned char *line;
269 int brk;
271 Fill = 1;
272 Pass3(brk, (unsigned char *)"flush", NULL, 0);
277 * Flush - "^[.']fl"
280 static void
281 nr_fl(line, brk)
282 unsigned char *line;
283 int brk;
285 Pass3(brk, (unsigned char *)"flush", NULL, 0);
290 * Font - "^[.']ft <font_name>"
293 static void
294 nr_ft(line, brk)
295 unsigned char *line;
296 int brk;
298 int i; /* temporary index */
300 if (line[3] == '\0' || line[4] == '\0')
301 line[4] = 'P';
302 if (line[4] == 'P') {
303 Font[0] = Prevfont;
304 return;
306 for (i = 0; Fcode[i].nm; i++) {
307 if (Fcode[i].nm == line[4])
308 break;
310 if (Fcode[i].status == '\0') {
311 Error(WARN, LINE, " bad font code", NULL);
312 return;
314 Prevfont = Font[0];
315 Font[0] = line[4];
320 * Input trap - "^[.']it [1 <request>]"
323 static void
324 nr_it(line, brk)
325 unsigned char *line;
326 int brk;
329 unsigned char buf[MAXLINE]; /* temporary buffer */
330 int i; /* temporary index */
331 unsigned char *s1, *s2; /* temporary string pointers */
333 if ((s1 = Field(2, line, 0)) == NULL) {
334 Free(&Aftnxt);
335 return;
337 if ((i = atoi((char *)s1)) != 1) {
338 Error(WARN, LINE, " first .it arg must be 1", NULL);
339 return;
341 if ((s2 = Field(3, line, 0)) == NULL)
342 Free(&Aftnxt);
343 else {
344 (void) sprintf((char *)buf, "%s,%s",
345 (Aftnxt == NULL) ? "" : (char *)Aftnxt,
346 (char *)s2);
347 Free(&Aftnxt);
348 Aftnxt = Newstr(buf);
354 * Comment - "^[.']\\" - do nothing
356 * Debug - "^[.']\^d" - do nothing
358 * Finalization - "[.']\^e" - do nothing
360 * Error file - "^[.']\^x <name>" - do nothing
362 * "^[.']i0", "^[.']lg" and "^[.']li" - do nothing
364 * Point size - "^[.']ps" - do nothing
366 * Vertical spacing - "^[.']vs" - do nothing
370 static void
371 nr_nil(line, brk)
372 unsigned char *line;
373 int brk;
379 * No adjust "^[.']na"
382 static void
383 nr_na(line, brk)
384 unsigned char *line;
385 int brk;
387 Pass3(NOBREAK, (unsigned char *)"left", NULL, 0);
392 * No fill - "^[.']nf"
395 static void
396 nr_nf(line, brk)
397 unsigned char *line;
398 int brk;
400 Fill = 0;
401 Pass3(brk, (unsigned char *)"flush", NULL, 0);
406 * No space - "^[.']ns"
409 static void
410 nr_ns(line, brk)
411 unsigned char *line;
412 int brk;
414 Pass3(NOBREAK, (unsigned char *)"nospace", NULL, 0);
419 * Remove macro or string - "^[.']rm"
422 static void
423 nr_rm(line, brk)
424 unsigned char *line;
425 int brk;
427 int i; /* temporary index */
428 unsigned char nm[4]; /* name buffer */
430 if (Asmname(&line[3], nm) == 0) {
431 Error(WARN, LINE, " no name", NULL);
432 return;
434 if ((i = Findmacro(nm, 0)) >= 0) {
435 Delmacro(i);
436 return;
438 (void) Findstr(nm, NULL, 0);
439 if (Sx >= 0) {
440 Delstr(Sx);
441 return;
443 Error(WARN, LINE, " no macro/string", NULL);
448 * Rename macro or string - "^[.']rn"
451 static void
452 nr_rn(line, brk)
453 unsigned char *line;
454 int brk;
456 int i, j; /* temporary indexes */
457 unsigned char nm[4], nm1[4]; /* name buffers */
458 unsigned char *s1; /* temporary string pointer */
460 if ((s1 = Field(2, line, 0)) == NULL || Asmname(s1, nm) == 0) {
461 Error(WARN, LINE, " no name", NULL);
462 return;
464 if ((s1 = Field(3, line, 0)) == NULL || Asmname(s1, nm1) == 0) {
465 Error(WARN, LINE, " no new name", NULL);
466 return;
468 if ((i = Findmacro(nm, 0)) >= 0) {
469 if ((j = Findmacro(nm1, 0)) >= 0)
470 Delmacro(j);
471 j = Findmacro(nm1, 1);
472 Macrotab[j].bx = Macrotab[i].bx;
473 Macrotab[i].bx = -1;
474 Macrotab[j].ct = Macrotab[i].ct;
475 Macrotab[i].ct = 0;
476 Delmacro(i);
477 return;
479 (void) Findstr(nm, NULL, 0);
480 if ((i = Sx) >= 0) {
481 (void) Findstr(nm1, Str[i].str, 1);
482 Delstr(i);
483 return;
485 if (Findmacro(nm1, 0) < 0)
486 (void) Findmacro(nm1, 1);
491 * Remove register - "^[.']rr"
494 static void
495 nr_rr(line, brk)
496 unsigned char *line;
497 int brk;
499 int i; /* temporary index */
500 unsigned char nm[4]; /* name buffer */
502 if (Asmname(&line[3], nm) == 0) {
503 Error(WARN, LINE, " no name", NULL);
504 return;
506 if ((i = Findnum(nm, 0, 0)) < 0) {
507 Error(WARN, LINE, " no register", NULL);
508 return;
510 Delnum(i);
515 * Resume space - "^[.']rs"
518 static void
519 nr_rs(line, brk)
520 unsigned char *line;
521 int brk;
523 Pass3(NOBREAK, (unsigned char *)"yesspace", NULL, 0);
528 * Message - "^[.']tm"
531 static void
532 nr_tm(line, brk)
533 unsigned char *line;
534 int brk;
536 Pass3(MESSAGE, Inname, (line[3] == ' ') ? &line[4] : &line[3], NR);
541 * Translate - "^[.']tr abcd..."
544 static void
545 nr_tr(line, brk)
546 unsigned char *line;
547 int brk;
549 unsigned char buf[MAXLINE]; /* temporary buffer */
550 int i, j; /* temporary indexes */
551 unsigned char nm[4], nm1[4]; /* name buffers */
552 unsigned char *s1, *s2; /* temporary string pointers */
553 int trin, trout; /* types: 0 = char; 1 = named char */
554 unsigned char xbuf[MAXLINE]; /* temporary buffer */
556 if (line[3] != ' ') {
557 Error(WARN, LINE, " unknown translation", NULL);
558 return;
560 for (s1 = &line[4]; *s1;) {
561 nm[1] = nm[2] = '\0';
562 s2 = s1 + 1;
564 * Assemble the input value.
566 if (*s1 == '\\' && (*s2 == '*' || *s2 == '(')) {
567 if (*s2 == '(') {
569 * Input is named character -- "\(xx".
571 trin = 1;
572 s1 = s2 + 1;
573 if ((nm[0] = *s1) != '\0') {
574 s1++;
575 if ((nm[1] = *s1) != '\0')
576 s1++;
578 } else {
580 * Input is interpolated string -- "\*x" or "\*(xx".
582 s1 = Asmcode(&s2, nm);
583 if (*s1)
584 s1++;
585 s2 = Findstr(nm, NULL, 0);
586 if (*s2 != '\0') {
587 if ((strlen((char *)s2) + strlen((char *)s1) + 1)
588 >= MAXLINE)
589 Error(WARN, LINE, " string too long: ", (char *)nm);
590 else {
591 (void) sprintf((char *)buf, "%s%s",
592 (char *)s2, (char *)s1);
593 (void) strcpy((char *)xbuf, (char *)buf);
594 s1 = xbuf;
597 continue;
599 } else {
602 * Input is a simple character.
604 trin = 0;
605 if ((nm[0] = *s1) != '\0')
606 s1++;
609 * Assemble the output value.
612 assemble_output:
613 nm1[1] = nm1[2] = '\0';
614 if (*s1 == '\0') {
617 * Supply a space if there is no output character.
619 trout = 0;
620 nm1[0] = ' ';
621 } else {
622 s2 = s1 + 1;
623 if (*s1 == '\\' && (*s2 == '(' || *s2 == '*')) {
624 if (*s2 == '(') {
626 * The output is a named character -- "\(xx".
628 trout = 1;
629 s1 = s2 + 1;
630 if ((nm1[0] = *s1) != '\0') {
631 s1++;
632 if ((nm1[1] = *s1) != '\0')
633 s1++;
635 } else {
637 * The output is an interpolated string -- * "\*x" or "\*(xx".
639 s1 = Asmcode(&s2, nm1);
640 if (*s1)
641 s1++;
642 s2 = Findstr(nm1, NULL, 0);
643 if (*s2 != '\0') {
645 * Interpolate a string value.
647 if ((strlen((char *)s2) + strlen((char *)s1) + 1)
648 >= MAXLINE)
649 Error(WARN, LINE, " string too long: ",
650 (char *)nm);
651 else {
652 (void) sprintf((char *)buf, "%s%s", (char *)s2,
653 (char *)s1);
654 (void) strcpy((char *)xbuf, (char *)buf);
655 s1 = xbuf;
658 goto assemble_output;
660 } else {
661 trout = 0;
662 if ((nm1[0] = *s1) != '0')
663 s1++;
664 else
665 nm1[0] = ' ';
669 * Do the translation.
671 switch (trin) {
673 case 0: /* simple char */
674 switch (trout) {
676 case 0: /* to simple char */
677 Trtbl[(int)nm[0]] = nm1[0];
678 break;
679 case 1: /* to named char */
680 if ((i = Findchar(nm1, 0, NULL, 0)) < 0
681 || strlen((char *)Schar[i].str) != 1)
682 Error(WARN, LINE, " bad named character: ",
683 (char *)nm1);
684 else
685 Trtbl[(int)nm[0]] = *(Schar[i].str);
686 break;
688 break;
689 case 1: /* named char */
690 if ((i = Findchar(nm, 0, NULL, 0)) < 0)
691 Error(WARN, LINE, " unknown named character: ", (char *)nm);
692 else {
693 switch (trout) {
695 case 0: /* to simple char */
696 Free(&Schar[i].str);
697 Schar[i].str = Newstr(nm1);
698 Schar[i].len = 1;
699 break;
700 case 1: /* to named char */
701 if ((j = Findchar(nm1, 0, NULL, 0)) < 0)
702 Error(WARN, LINE, " unknown named character: ",
703 (char *)nm1);
704 else
705 (void) Findchar(nm, Schar[j].len, Schar[j].str, 1);
706 break;
709 break;
716 * Initialization - "^[.']\^b (fh|HF|NH) [01]"
718 * fh = first page header status
719 * HF = header/footer status
720 * NH = initialize number headers
723 static void
724 nr_Ub(line, brk)
725 unsigned char *line;
726 int brk;
728 int i; /* temporary index */
729 unsigned char *s1, *s2; /* temporary string pointers */
731 if ((s1 = Field(2, line, 0)) == NULL)
732 return;
733 if ((s2 = Field(3, line, 0)) == NULL)
734 i = 0;
735 else
736 i = atoi((char *)s2);
737 if (s1[0] == 'f' && s1[1] == 'h')
738 Pass3(NOBREAK, (unsigned char *)"fph", NULL, i);
739 else if (s1[0] == 'H' && s1[1] == 'F')
740 Hdft = i;
741 else if (s1[0] == 'N' && s1[1] == 'H') {
742 for (i = 0; i < MAXNHNR; i++)
743 Nhnr[i] = 0;
744 } else
745 Error(WARN, LINE, " unknown initialization", NULL);
750 * Character definitions - "^[.']\^c"
753 static void
754 nr_Uc(line, brk)
755 unsigned char *line;
756 int brk;
758 unsigned char buf[MAXLINE]; /* temporary buffer */
759 int i; /* temporary index */
760 unsigned char *s1, *s2, *s3, /* temporary string pointers */
761 *s4, *s5;
763 s2 = Field(2, line, 0);
764 i = atoi((char *)Field(3, line, 0));
765 s4 = Field(4, line, 0);
766 if (i < 0 || i > MAXLINE/2 || *s2 == '\0') {
767 Error(WARN, LINE, " bad character definition", NULL);
768 return;
770 if (s4 == NULL)
771 s4 = (unsigned char *)"";
772 else if (*s4 == '"')
773 s4++;
774 s1 = buf;
775 while ((s5 = (unsigned char *)strchr((char *)s4, '\\')) != NULL) {
776 while (s5 > s4)
777 *s1++ = *s4++;
778 s4 = ++s5;
779 if (*s5 == '\\')
780 *s1++ = '\\';
781 else if (*s5 == 'b')
782 *s1++ = '\b';
783 if (*s4)
784 s4++;
786 while (*s1++ = *s4++)
788 if (*s2 == 'h' && *(s2+1) == 'y')
789 (void) Findhy(buf, i, 1);
790 else
791 (void) Findchar(s2, i, buf, 1);
796 * Font is OK - "[.']\^f <font_name_character>"
799 static void
800 nr_Uf(line, brk)
801 unsigned char *line;
802 int brk;
804 int i; /* temporary index */
806 if (line[3] != '\0' && line[4] != '\0') {
807 for (i = 0; Fcode[i].nm; i++) {
808 if (line[4] == Fcode[i].nm) {
809 Fcode[i].status = '1';
810 return;
814 Error(WARN, LINE, " unknown font", NULL);
819 * Resolutions - "[.']\^r cpi horizontal vertical"
822 static void
823 nr_Ur(line, brk)
824 unsigned char *line;
825 int brk;
827 unsigned char buf[MAXLINE]; /* temporary buffer */
828 int i, j; /* temporary indexes */
829 double tval; /* temporary value */
831 if ((i = atoi((char *)Field(3, line, 0))) <= 0
832 || (j = atoi((char *)Field(4, line, 0))) <= 0) {
833 Error(WARN, LINE, " bad cpi resolutions", NULL);
834 return;
836 tval = (double) (240.0 / (double) i);
837 if (Findscale((int)'m', tval, 1) < 0)
838 Error(FATAL, LINE, " missing Scal['m']", NULL);
839 Scalen = tval;
840 if (Scalen <= 0.0) {
841 (void) sprintf((char *)buf, " bad Scale['n'] (%f)", Scalen);
842 Error(FATAL, LINE, (char *)buf, NULL);
844 if (Findscale((int)'n', tval, 1) < 0)
845 Error(FATAL, LINE, " missing Scale['n']", NULL);
846 Scalev = (double) (240.0 / (double) j);
847 if (Scalev <= 0.0) {
848 (void) sprintf((char *)buf, " bad Scale['v'] (%f)", Scalen);
849 Error(FATAL, LINE, (char *)buf, NULL);
851 if (Findscale((int)'v', Scalev, 1) < 0)
852 Error(FATAL, LINE, " missing Scale['v']", NULL);
857 * Set line number and file name - "^[.']\^# <number> <file>"
859 * Lock line number and file name - "^[.']\^= <number> <file>"
862 static void
863 nr_UL(line, brk)
864 unsigned char *line;
865 int brk;
867 unsigned char *s1; /* temporary string pointer */
869 if ((s1 = Field(2, line, 0)) != NULL)
870 P2il = atoi((char *)s1) - 1;
871 else
872 P2il = 0;
873 Lockil = (line[2] == '#') ? 0 : 1;
874 Free(&P2name);
875 if (Field(3, line, 1) != NULL) {
876 P2name = F;
877 F = NULL;
878 } else
879 P2name = NULL;