Improve the process for GNU tools
[minix3.git] / minix / commands / cawf / nreq.c
blob1bc9030716d86c0488e54cbe8caa2ad4b155af6a
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 Nreq(unsigned char *line, int brk) {
120 unsigned char c[3]; /* command buffer */
121 int cmp, hi, low, mid; /* binary search indixes */
123 c[0] = c[1] = c[2] = '\0';
124 if ((c[0] = line[1]) != '\0')
125 c[1] = line[2];
127 low = mid = 0;
128 hi = sizeof(NrReqt) / sizeof(struct nr_req);
129 while (low <= hi) {
130 mid = (low + hi) / 2;
131 if ((cmp = strcmp((char *)c, NrReqt[mid].nm)) < 0)
132 hi = mid - 1;
133 else if (cmp > 0)
134 low = mid + 1;
135 else {
136 (void) (*NrReqt[mid].fun)(line, brk);
137 return;
141 * Unknown request starting with a '.' or '\''..
143 Error(WARN, LINE, " unknown request", NULL);
148 * Adjust - "^[.']ad"
151 static void nr_ad(unsigned char *line, int brk) {
152 Pass3(NOBREAK, (unsigned char *)"both", NULL, 0);
157 * Begin new page - "^[.']bp"
160 static void nr_bp(unsigned char *line, int brk) {
161 Pass3(brk, (unsigned char *)"need", NULL, 999);
166 * Break - "^[.']br"
169 static void nr_br(unsigned char *line, int brk) {
170 Pass3(brk, (unsigned char *)"flush", NULL, 0);
175 * Center - "^[.']ce"
178 static void nr_ce(unsigned char *line, int brk) {
179 unsigned char *s; /* string poiner */
181 if ((s = Field(2, line, 0)) != NULL)
182 Centering = atoi((char *)s);
183 else
184 Centering = 1;
189 * Diversion on and off - "^[.']di"
192 static void nr_di(unsigned char *line, int brk) {
193 Pass3(DOBREAK, (unsigned char *)"flush", NULL, 0);
194 Divert ^= 1;
199 * Define string - "^[.']ds"
202 static void nr_ds(unsigned char *line, int brk) {
203 unsigned char buf[MAXLINE]; /* temporary buffer */
204 unsigned char nm[4], nm1[4]; /* name buffers */
205 unsigned char *s1, *s2, *s3, /* temporary string pointers */
206 *s4;
208 if (Asmname(&line[3], nm) == 0) {
209 Error(WARN, LINE, " no name", NULL);
210 return;
212 s1 = Field(3, line, 0);
213 s2 = Findstr(nm, s1, 1);
214 while (*s2 == '\\' && *(s2 + 1) == '*') {
215 s2++;
216 s3 = Asmcode(&s2, nm1);
217 s2 = Findstr(nm1, NULL, 0);
219 if (Hdft) {
222 * Look for names LH, LF, CH, CF, RH, RF.
224 if ((nm[0]=='L' || nm[0]=='C' || nm[0]=='R')
225 && (nm[1]=='F' || nm[1]=='H')) {
226 (void) sprintf((char *)buf, "%s", (char *)nm);
227 Pass3(NOBREAK, buf, s2, 0);
235 * Fill - "^[.']fi"
238 static void nr_fi(unsigned char *line, int brk) {
239 Fill = 1;
240 Pass3(brk, (unsigned char *)"flush", NULL, 0);
245 * Flush - "^[.']fl"
248 static void nr_fl(unsigned char *line, int brk) {
249 Pass3(brk, (unsigned char *)"flush", NULL, 0);
254 * Font - "^[.']ft <font_name>"
257 static void nr_ft(unsigned char *line, int brk) {
258 int i; /* temporary index */
260 if (line[3] == '\0' || line[4] == '\0')
261 line[4] = 'P';
262 if (line[4] == 'P') {
263 Font[0] = Prevfont;
264 return;
266 for (i = 0; Fcode[i].nm; i++) {
267 if (Fcode[i].nm == line[4])
268 break;
270 if (Fcode[i].status == '\0') {
271 Error(WARN, LINE, " bad font code", NULL);
272 return;
274 Prevfont = Font[0];
275 Font[0] = line[4];
280 * Input trap - "^[.']it [1 <request>]"
283 static void nr_it(unsigned char *line, int brk) {
284 unsigned char buf[MAXLINE]; /* temporary buffer */
285 int i; /* temporary index */
286 unsigned char *s1, *s2; /* temporary string pointers */
288 if ((s1 = Field(2, line, 0)) == NULL) {
289 Free(&Aftnxt);
290 return;
292 if ((i = atoi((char *)s1)) != 1) {
293 Error(WARN, LINE, " first .it arg must be 1", NULL);
294 return;
296 if ((s2 = Field(3, line, 0)) == NULL)
297 Free(&Aftnxt);
298 else {
299 (void) sprintf((char *)buf, "%s,%s",
300 (Aftnxt == NULL) ? "" : (char *)Aftnxt,
301 (char *)s2);
302 Free(&Aftnxt);
303 Aftnxt = Newstr(buf);
309 * Comment - "^[.']\\" - do nothing
311 * Debug - "^[.']\^d" - do nothing
313 * Finalization - "[.']\^e" - do nothing
315 * Error file - "^[.']\^x <name>" - do nothing
317 * "^[.']i0", "^[.']lg" and "^[.']li" - do nothing
319 * Point size - "^[.']ps" - do nothing
321 * Vertical spacing - "^[.']vs" - do nothing
325 static void nr_nil(unsigned char *line, int brk) {
330 * No adjust "^[.']na"
333 static void nr_na(unsigned char *line, int brk) {
334 Pass3(NOBREAK, (unsigned char *)"left", NULL, 0);
339 * No fill - "^[.']nf"
342 static void nr_nf(unsigned char *line, int brk) {
343 Fill = 0;
344 Pass3(brk, (unsigned char *)"flush", NULL, 0);
349 * No space - "^[.']ns"
352 static void nr_ns(unsigned char *line, int brk) {
353 Pass3(NOBREAK, (unsigned char *)"nospace", NULL, 0);
358 * Remove macro or string - "^[.']rm"
361 static void nr_rm(unsigned char *line, int brk) {
362 int i; /* temporary index */
363 unsigned char nm[4]; /* name buffer */
365 if (Asmname(&line[3], nm) == 0) {
366 Error(WARN, LINE, " no name", NULL);
367 return;
369 if ((i = Findmacro(nm, 0)) >= 0) {
370 Delmacro(i);
371 return;
373 (void) Findstr(nm, NULL, 0);
374 if (Sx >= 0) {
375 Delstr(Sx);
376 return;
378 Error(WARN, LINE, " no macro/string", NULL);
383 * Rename macro or string - "^[.']rn"
386 static void nr_rn(unsigned char *line, int brk) {
387 int i, j; /* temporary indexes */
388 unsigned char nm[4], nm1[4]; /* name buffers */
389 unsigned char *s1; /* temporary string pointer */
391 if ((s1 = Field(2, line, 0)) == NULL || Asmname(s1, nm) == 0) {
392 Error(WARN, LINE, " no name", NULL);
393 return;
395 if ((s1 = Field(3, line, 0)) == NULL || Asmname(s1, nm1) == 0) {
396 Error(WARN, LINE, " no new name", NULL);
397 return;
399 if ((i = Findmacro(nm, 0)) >= 0) {
400 if ((j = Findmacro(nm1, 0)) >= 0)
401 Delmacro(j);
402 j = Findmacro(nm1, 1);
403 Macrotab[j].bx = Macrotab[i].bx;
404 Macrotab[i].bx = -1;
405 Macrotab[j].ct = Macrotab[i].ct;
406 Macrotab[i].ct = 0;
407 Delmacro(i);
408 return;
410 (void) Findstr(nm, NULL, 0);
411 if ((i = Sx) >= 0) {
412 (void) Findstr(nm1, Str[i].str, 1);
413 Delstr(i);
414 return;
416 if (Findmacro(nm1, 0) < 0)
417 (void) Findmacro(nm1, 1);
422 * Remove register - "^[.']rr"
425 static void nr_rr(unsigned char *line, int brk) {
426 int i; /* temporary index */
427 unsigned char nm[4]; /* name buffer */
429 if (Asmname(&line[3], nm) == 0) {
430 Error(WARN, LINE, " no name", NULL);
431 return;
433 if ((i = Findnum(nm, 0, 0)) < 0) {
434 Error(WARN, LINE, " no register", NULL);
435 return;
437 Delnum(i);
442 * Resume space - "^[.']rs"
445 static void nr_rs(unsigned char *line, int brk) {
446 Pass3(NOBREAK, (unsigned char *)"yesspace", NULL, 0);
451 * Message - "^[.']tm"
454 static void nr_tm(unsigned char *line, int brk) {
455 Pass3(MESSAGE, Inname, (line[3] == ' ') ? &line[4] : &line[3], NR);
460 * Translate - "^[.']tr abcd..."
463 static void nr_tr(unsigned char *line, int brk) {
464 unsigned char buf[MAXLINE]; /* temporary buffer */
465 int i, j; /* temporary indexes */
466 unsigned char nm[4], nm1[4]; /* name buffers */
467 unsigned char *s1, *s2; /* temporary string pointers */
468 int trin, trout; /* types: 0 = char; 1 = named char */
469 unsigned char xbuf[MAXLINE]; /* temporary buffer */
471 if (line[3] != ' ') {
472 Error(WARN, LINE, " unknown translation", NULL);
473 return;
475 for (s1 = &line[4]; *s1;) {
476 nm[1] = nm[2] = '\0';
477 s2 = s1 + 1;
479 * Assemble the input value.
481 if (*s1 == '\\' && (*s2 == '*' || *s2 == '(')) {
482 if (*s2 == '(') {
484 * Input is named character -- "\(xx".
486 trin = 1;
487 s1 = s2 + 1;
488 if ((nm[0] = *s1) != '\0') {
489 s1++;
490 if ((nm[1] = *s1) != '\0')
491 s1++;
493 } else {
495 * Input is interpolated string -- "\*x" or "\*(xx".
497 s1 = Asmcode(&s2, nm);
498 if (*s1)
499 s1++;
500 s2 = Findstr(nm, NULL, 0);
501 if (*s2 != '\0') {
502 if ((strlen((char *)s2) + strlen((char *)s1) + 1)
503 >= MAXLINE)
504 Error(WARN, LINE, " string too long: ", (char *)nm);
505 else {
506 (void) sprintf((char *)buf, "%s%s",
507 (char *)s2, (char *)s1);
508 (void) strcpy((char *)xbuf, (char *)buf);
509 s1 = xbuf;
512 continue;
514 } else {
517 * Input is a simple character.
519 trin = 0;
520 if ((nm[0] = *s1) != '\0')
521 s1++;
524 * Assemble the output value.
527 assemble_output:
528 nm1[1] = nm1[2] = '\0';
529 if (*s1 == '\0') {
532 * Supply a space if there is no output character.
534 trout = 0;
535 nm1[0] = ' ';
536 } else {
537 s2 = s1 + 1;
538 if (*s1 == '\\' && (*s2 == '(' || *s2 == '*')) {
539 if (*s2 == '(') {
541 * The output is a named character -- "\(xx".
543 trout = 1;
544 s1 = s2 + 1;
545 if ((nm1[0] = *s1) != '\0') {
546 s1++;
547 if ((nm1[1] = *s1) != '\0')
548 s1++;
550 } else {
552 * The output is an interpolated string -- * "\*x" or "\*(xx".
554 s1 = Asmcode(&s2, nm1);
555 if (*s1)
556 s1++;
557 s2 = Findstr(nm1, NULL, 0);
558 if (*s2 != '\0') {
560 * Interpolate a string value.
562 if ((strlen((char *)s2) + strlen((char *)s1) + 1)
563 >= MAXLINE)
564 Error(WARN, LINE, " string too long: ",
565 (char *)nm);
566 else {
567 (void) sprintf((char *)buf, "%s%s", (char *)s2,
568 (char *)s1);
569 (void) strcpy((char *)xbuf, (char *)buf);
570 s1 = xbuf;
573 goto assemble_output;
575 } else {
576 trout = 0;
577 if ((nm1[0] = *s1) != '0')
578 s1++;
579 else
580 nm1[0] = ' ';
584 * Do the translation.
586 switch (trin) {
588 case 0: /* simple char */
589 switch (trout) {
591 case 0: /* to simple char */
592 Trtbl[(int)nm[0]] = nm1[0];
593 break;
594 case 1: /* to named char */
595 if ((i = Findchar(nm1, 0, NULL, 0)) < 0
596 || strlen((char *)Schar[i].str) != 1)
597 Error(WARN, LINE, " bad named character: ",
598 (char *)nm1);
599 else
600 Trtbl[(int)nm[0]] = *(Schar[i].str);
601 break;
603 break;
604 case 1: /* named char */
605 if ((i = Findchar(nm, 0, NULL, 0)) < 0)
606 Error(WARN, LINE, " unknown named character: ", (char *)nm);
607 else {
608 switch (trout) {
610 case 0: /* to simple char */
611 Free(&Schar[i].str);
612 Schar[i].str = Newstr(nm1);
613 Schar[i].len = 1;
614 break;
615 case 1: /* to named char */
616 if ((j = Findchar(nm1, 0, NULL, 0)) < 0)
617 Error(WARN, LINE, " unknown named character: ",
618 (char *)nm1);
619 else
620 (void) Findchar(nm, Schar[j].len, Schar[j].str, 1);
621 break;
624 break;
631 * Initialization - "^[.']\^b (fh|HF|NH) [01]"
633 * fh = first page header status
634 * HF = header/footer status
635 * NH = initialize number headers
638 static void nr_Ub(unsigned char *line, int brk) {
639 int i; /* temporary index */
640 unsigned char *s1, *s2; /* temporary string pointers */
642 if ((s1 = Field(2, line, 0)) == NULL)
643 return;
644 if ((s2 = Field(3, line, 0)) == NULL)
645 i = 0;
646 else
647 i = atoi((char *)s2);
648 if (s1[0] == 'f' && s1[1] == 'h')
649 Pass3(NOBREAK, (unsigned char *)"fph", NULL, i);
650 else if (s1[0] == 'H' && s1[1] == 'F')
651 Hdft = i;
652 else if (s1[0] == 'N' && s1[1] == 'H') {
653 for (i = 0; i < MAXNHNR; i++)
654 Nhnr[i] = 0;
655 } else
656 Error(WARN, LINE, " unknown initialization", NULL);
661 * Character definitions - "^[.']\^c"
664 static void nr_Uc(unsigned char *line, int brk) {
665 unsigned char buf[MAXLINE]; /* temporary buffer */
666 int i; /* temporary index */
667 unsigned char *s1, *s2, *s3, /* temporary string pointers */
668 *s4, *s5;
670 s2 = Field(2, line, 0);
671 i = atoi((char *)Field(3, line, 0));
672 s4 = Field(4, line, 0);
673 if (i < 0 || i > MAXLINE/2 || *s2 == '\0') {
674 Error(WARN, LINE, " bad character definition", NULL);
675 return;
677 if (s4 == NULL)
678 s4 = (unsigned char *)"";
679 else if (*s4 == '"')
680 s4++;
681 s1 = buf;
682 while ((s5 = (unsigned char *)strchr((char *)s4, '\\')) != NULL) {
683 while (s5 > s4)
684 *s1++ = *s4++;
685 s4 = ++s5;
686 if (*s5 == '\\')
687 *s1++ = '\\';
688 else if (*s5 == 'b')
689 *s1++ = '\b';
690 if (*s4)
691 s4++;
693 while ((*s1++ = *s4++))
695 if (*s2 == 'h' && *(s2+1) == 'y')
696 (void) Findhy(buf, i, 1);
697 else
698 (void) Findchar(s2, i, buf, 1);
703 * Font is OK - "[.']\^f <font_name_character>"
706 static void nr_Uf(unsigned char *line, int brk) {
707 int i; /* temporary index */
709 if (line[3] != '\0' && line[4] != '\0') {
710 for (i = 0; Fcode[i].nm; i++) {
711 if (line[4] == Fcode[i].nm) {
712 Fcode[i].status = '1';
713 return;
717 Error(WARN, LINE, " unknown font", NULL);
722 * Resolutions - "[.']\^r cpi horizontal vertical"
725 static void nr_Ur(unsigned char *line, int brk) {
726 unsigned char buf[MAXLINE]; /* temporary buffer */
727 int i, j; /* temporary indexes */
728 double tval; /* temporary value */
730 if ((i = atoi((char *)Field(3, line, 0))) <= 0
731 || (j = atoi((char *)Field(4, line, 0))) <= 0) {
732 Error(WARN, LINE, " bad cpi resolutions", NULL);
733 return;
735 tval = (double) (240.0 / (double) i);
736 if (Findscale((int)'m', tval, 1) < 0)
737 Error(FATAL, LINE, " missing Scal['m']", NULL);
738 Scalen = tval;
739 if (Scalen <= 0.0) {
740 (void) sprintf((char *)buf, " bad Scale['n'] (%f)", Scalen);
741 Error(FATAL, LINE, (char *)buf, NULL);
743 if (Findscale((int)'n', tval, 1) < 0)
744 Error(FATAL, LINE, " missing Scale['n']", NULL);
745 Scalev = (double) (240.0 / (double) j);
746 if (Scalev <= 0.0) {
747 (void) sprintf((char *)buf, " bad Scale['v'] (%f)", Scalen);
748 Error(FATAL, LINE, (char *)buf, NULL);
750 if (Findscale((int)'v', Scalev, 1) < 0)
751 Error(FATAL, LINE, " missing Scale['v']", NULL);
756 * Set line number and file name - "^[.']\^# <number> <file>"
758 * Lock line number and file name - "^[.']\^= <number> <file>"
761 static void nr_UL(unsigned char *line, int brk) {
762 unsigned char *s1; /* temporary string pointer */
764 if ((s1 = Field(2, line, 0)) != NULL)
765 P2il = atoi((char *)s1) - 1;
766 else
767 P2il = 0;
768 Lockil = (line[2] == '#') ? 0 : 1;
769 Free(&P2name);
770 if (Field(3, line, 1) != NULL) {
771 P2name = F;
772 F = NULL;
773 } else
774 P2name = NULL;