Remove building with NOCRYPTO option
[minix.git] / minix / commands / cawf / expand.c
blobfc4dad502c03dbbfe9fab53dfe604a4172783a61
1 /*
2 * expand.c - macro expansion functions for cawf(1)
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"
34 * Expand(line) - expand macro or if/ie/el line
37 void Expand(unsigned char *line) {
39 unsigned char buf[2*MAXLINE]; /* line buffer */
40 unsigned char cmd[4]; /* nroff command */
41 int cmdl; /* command length */
42 int cmdx; /* cmd index in Macrotab[] */
43 int cond = 0; /* conditional statuses */
44 int i, j; /* temporary indexes */
45 int iflen; /* if statement length */
46 int invert; /* inversion status */
47 unsigned char *lp; /* line pointer */
48 int mx = -1; /* Macrotab[] index */
49 int n1, n2; /* temporary numbers */
50 int nargs = 0; /* number of arguments */
51 int nleft = 0; /* number of macro lines left */
52 char op; /* comparison operator */
53 int prevcond; /* previous condition (for else's) */
54 int ptr = -1; /* Macrotxt[] index */
55 int quote; /* quoted string status */
56 unsigned char *s1, *s2; /* temporary string pointers */
59 (void) sprintf((char *)buf, ".^= %d %s", NR, (char *)Inname);
60 Pass2(buf);
62 for (lp = line; *lp; ) {
63 invert = regexec(Pat[1].pat, lp);
64 prevcond = cond;
65 cond = 0;
66 if (regexec(Pat[0].pat, lp) == 0) {
68 * Not conditional: - ! "^[.'](i[ef]|el)"
70 cond = 1;
71 iflen = 0;
74 else if (regexec(Pat[2].pat, lp)) {
76 * Argument count comparison: -
77 * "^[.']i[ef] !?\\n\(\.\$(>|>=|=|<|<=)[0-9] "
79 iflen = strlen(".if \\n(.$=n ") + invert;
80 s1 = lp + iflen - 3;
81 op = *s1++;
82 if (*s1 == '=' && (op == '>' || op == '<')) {
83 s1++;
84 op = (op == '>') ? 'G' : 'L';
86 n1 = (int)(*s1 - '0');
87 switch (op) {
88 case '=':
89 if ((nargs - 1) == n1)
90 cond = 1;
91 break;
92 case '<':
93 if ((nargs - 1) < n1)
94 cond = 1;
95 break;
96 case '>':
97 if ((nargs - 1) > n1)
98 cond = 1;
99 break;
100 case 'G': /* >= */
101 if ((nargs - 1) >= n1)
102 cond = 1;
103 break;
104 case 'L': /* <= */
105 if ((nargs - 1) <= n1)
106 cond = 1;
110 else if (regexec(Pat[3].pat, lp)) {
112 * Argument string comparison: - "^[.']i[ef] !?'\\\$[0-9]'[^']*' "
114 iflen = strlen(".if '\\$n'") + invert;
115 n1 = (int)(*(lp + iflen - 2) - '0');
116 if (n1 >= 0 && n1 < nargs)
117 s1 = Args[n1];
118 else
119 s1 = (unsigned char *)"";
120 if ((s2 = (unsigned char *)strchr((char *)lp
121 + iflen, '\''))
122 != NULL) {
123 n2 = s2 - lp - iflen;
124 if (strncmp((char *)s1, (char *)lp + iflen, n2)
125 == 0)
126 cond = 1;
127 iflen += n2 + 2;
131 else if (regexec(Pat[4].pat, lp)) {
133 * Nroff or troff: - "^[.']i[ef] !?[nt] "
135 iflen = strlen(".if n ") + invert;
136 if (*(lp + iflen - 2) == 'n')
137 cond = 1;
140 else if ((*lp == '.' || *lp == '\'')
141 && strncmp((char *)lp+1, "el ", 3) == 0) {
143 * Else clause: - "^[.']el "
145 cond = 1 - prevcond;
146 iflen = 4;
149 else {
151 * Unknown conditional:
153 cond = 1;
154 iflen = 0;
155 (void) sprintf((char *)buf,
156 ".tm unknown .if/.ie form: %s", (char *)lp);
157 lp = buf;
160 * Handle conditional. If case is true, locate predicate.
161 * If predicate is an .i[ef], process it.
163 if (invert)
164 cond = 1 - cond;
165 if (cond && iflen > 0) {
166 lp += iflen;
167 if (regexec(Pat[15].pat, lp))
168 continue;
171 * Do argument substitution, as necessary.
173 if (cond && regexec(Pat[5].pat, lp)) { /* "\$[0-9]" ??? */
174 for (s1 = buf;;) {
175 if ((n1 = Pat[5].pat->startp[0] - lp) > 0) {
176 (void) strncpy((char *)s1, (char *)lp,
177 n1);
178 s1 += n1;
180 *s1 = '\0';
181 lp = Pat[5].pat->endp[0];
182 n1 = (int)(*(lp-1) - '0');
183 if (n1 >= 0 && n1 < nargs) {
184 (void) strcpy((char *)s1,
185 (char *)Args[n1]);
186 s1 += strlen((char *)Args[n1]);
188 if (*lp == '\0')
189 break;
190 if (regexec(Pat[5].pat, lp) == 0) {
191 (void) strcpy((char *)s1, (char *)lp);
192 break;
195 lp = buf;
198 * Check for nroff command.
200 if (cond) {
201 cmdl = 0;
202 if (cond && (*lp == '.' || *lp == '\'')) {
203 if ((*cmd = *(lp+1)) != '\0') {
204 cmdl++;
205 if ((*(cmd+1) = *(lp+2)) == ' ')
206 *(cmd+1) = '\0';
207 else
208 cmdl++;
211 cmd[cmdl] = '\0';
213 if (cond == 0)
214 i = i; /* do nothing if condition is false */
215 else if (cmdl == 0 || ((cmdx = Findmacro(cmd, 0)) < 0))
216 Pass2(lp);
217 else if (Sp >= MAXSP) {
218 (void) sprintf((char *)buf, " macro nesting > %d",
219 MAXSP);
220 Error(WARN, LINE, (char *)buf, NULL);
221 } else {
223 * Stack macros.
226 * Push stack.
228 Sp++;
229 Nleftstack[Sp] = nleft;
230 Ptrstack[Sp] = ptr;
231 Mxstack[Sp] = mx;
232 Condstack[Sp] = cond;
233 for (i = 10*Sp, j = 0; j < 10; i++, j++) {
234 Argstack[i] = Args[j];
235 Args[j] = NULL;
238 * Start new stack entry.
240 mx = cmdx;
241 ptr = Macrotab[mx].bx;
242 cond = 0;
243 nleft = Macrotab[mx].ct;
244 Args[0] = Newstr(cmd);
246 * Parse arguments.
248 for (s1 = lp + cmdl + 1, nargs = 1; nargs < 10;) {
249 while (*s1 && (*s1 == ' ' || *s1 == '\t'))
250 s1++;
251 if (*s1 == '\0')
252 break;
253 if (*s1 == '"') {
254 s1++;
255 quote = 1;
256 } else
257 quote = 0;
258 for (s2 = buf;;) {
259 if (!quote && (*s1 == ' ' || *s1 == '\t')) {
260 *s2 = '\0';
261 break;
263 if ((*s2 = *s1) == '\0')
264 break;
265 s1++;
266 if (quote && *s2 == '"') {
267 *s2 = '\0';
268 break;
270 s2++;
272 if (buf[0])
273 Args[nargs++] = Newstr(buf);
275 for (i = nargs; i < 10; i++) {
276 Args[i] = NULL;
280 * Unstack completed macros.
282 while (nleft <= 0 && Sp >= 0) {
283 nleft = Nleftstack[Sp];
284 mx = Mxstack[Sp];
285 ptr = Ptrstack[Sp];
286 cond = Condstack[Sp];
287 for (i = 10*Sp, j = 0, nargs = -1; j < 10; i++, j++) {
288 Free(&Args[j]);
289 if ((Args[j] = Argstack[i]) != NULL)
290 nargs = j;
292 Sp--;
293 nargs++;
296 * Get next line.
298 if (nleft > 0) {
299 lp = Macrotxt[ptr++];
300 nleft--;
301 } else
302 lp = (unsigned char *)"";
304 (void) sprintf((char *)buf, ".^# %d %s", NR, (char *)Inname);
305 Pass2(buf);