1 | /* Builtin function expansion for GNU Make. |
---|
2 | Copyright (C) 1988,1989,1991-1997,1999 Free Software Foundation, Inc. |
---|
3 | This file is part of GNU Make. |
---|
4 | |
---|
5 | GNU Make is free software; you can redistribute it and/or modify |
---|
6 | it under the terms of the GNU General Public License as published by |
---|
7 | the Free Software Foundation; either version 2, or (at your option) |
---|
8 | any later version. |
---|
9 | |
---|
10 | GNU Make is distributed in the hope that it will be useful, |
---|
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
13 | GNU General Public License for more details. |
---|
14 | |
---|
15 | You should have received a copy of the GNU General Public License |
---|
16 | along with GNU Make; see the file COPYING. If not, write to |
---|
17 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
---|
18 | Boston, MA 02111-1307, USA. */ |
---|
19 | |
---|
20 | #include "make.h" |
---|
21 | #include "filedef.h" |
---|
22 | #include "variable.h" |
---|
23 | #include "dep.h" |
---|
24 | #include "job.h" |
---|
25 | #include "commands.h" |
---|
26 | #include "debug.h" |
---|
27 | |
---|
28 | #ifdef _AMIGA |
---|
29 | #include "amiga.h" |
---|
30 | #endif |
---|
31 | |
---|
32 | |
---|
33 | struct function_table_entry |
---|
34 | { |
---|
35 | const char *name; |
---|
36 | unsigned char len; |
---|
37 | unsigned char minimum_args; |
---|
38 | unsigned char maximum_args; |
---|
39 | char expand_args; |
---|
40 | char *(*func_ptr) PARAMS ((char *output, char **argv, const char *fname)); |
---|
41 | }; |
---|
42 | |
---|
43 | |
---|
44 | /* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing |
---|
45 | each occurrence of SUBST with REPLACE. TEXT is null-terminated. SLEN is |
---|
46 | the length of SUBST and RLEN is the length of REPLACE. If BY_WORD is |
---|
47 | nonzero, substitutions are done only on matches which are complete |
---|
48 | whitespace-delimited words. If SUFFIX_ONLY is nonzero, substitutions are |
---|
49 | done only at the ends of whitespace-delimited words. */ |
---|
50 | |
---|
51 | char * |
---|
52 | subst_expand (o, text, subst, replace, slen, rlen, by_word, suffix_only) |
---|
53 | char *o; |
---|
54 | char *text; |
---|
55 | char *subst, *replace; |
---|
56 | unsigned int slen, rlen; |
---|
57 | int by_word, suffix_only; |
---|
58 | { |
---|
59 | register char *t = text; |
---|
60 | register char *p; |
---|
61 | |
---|
62 | if (slen == 0 && !by_word && !suffix_only) |
---|
63 | { |
---|
64 | /* The first occurrence of "" in any string is its end. */ |
---|
65 | o = variable_buffer_output (o, t, strlen (t)); |
---|
66 | if (rlen > 0) |
---|
67 | o = variable_buffer_output (o, replace, rlen); |
---|
68 | return o; |
---|
69 | } |
---|
70 | |
---|
71 | do |
---|
72 | { |
---|
73 | if ((by_word | suffix_only) && slen == 0) |
---|
74 | /* When matching by words, the empty string should match |
---|
75 | the end of each word, rather than the end of the whole text. */ |
---|
76 | p = end_of_token (next_token (t)); |
---|
77 | else |
---|
78 | { |
---|
79 | p = sindex (t, 0, subst, slen); |
---|
80 | if (p == 0) |
---|
81 | { |
---|
82 | /* No more matches. Output everything left on the end. */ |
---|
83 | o = variable_buffer_output (o, t, strlen (t)); |
---|
84 | return o; |
---|
85 | } |
---|
86 | } |
---|
87 | |
---|
88 | /* Output everything before this occurrence of the string to replace. */ |
---|
89 | if (p > t) |
---|
90 | o = variable_buffer_output (o, t, p - t); |
---|
91 | |
---|
92 | /* If we're substituting only by fully matched words, |
---|
93 | or only at the ends of words, check that this case qualifies. */ |
---|
94 | if ((by_word |
---|
95 | && ((p > t && !isblank ((unsigned char)p[-1])) |
---|
96 | || (p[slen] != '\0' && !isblank ((unsigned char)p[slen])))) |
---|
97 | || (suffix_only |
---|
98 | && (p[slen] != '\0' && !isblank ((unsigned char)p[slen])))) |
---|
99 | /* Struck out. Output the rest of the string that is |
---|
100 | no longer to be replaced. */ |
---|
101 | o = variable_buffer_output (o, subst, slen); |
---|
102 | else if (rlen > 0) |
---|
103 | /* Output the replacement string. */ |
---|
104 | o = variable_buffer_output (o, replace, rlen); |
---|
105 | |
---|
106 | /* Advance T past the string to be replaced. */ |
---|
107 | t = p + slen; |
---|
108 | } while (*t != '\0'); |
---|
109 | |
---|
110 | return o; |
---|
111 | } |
---|
112 | |
---|
113 | |
---|
114 | /* Store into VARIABLE_BUFFER at O the result of scanning TEXT |
---|
115 | and replacing strings matching PATTERN with REPLACE. |
---|
116 | If PATTERN_PERCENT is not nil, PATTERN has already been |
---|
117 | run through find_percent, and PATTERN_PERCENT is the result. |
---|
118 | If REPLACE_PERCENT is not nil, REPLACE has already been |
---|
119 | run through find_percent, and REPLACE_PERCENT is the result. */ |
---|
120 | |
---|
121 | char * |
---|
122 | patsubst_expand (o, text, pattern, replace, pattern_percent, replace_percent) |
---|
123 | char *o; |
---|
124 | char *text; |
---|
125 | register char *pattern, *replace; |
---|
126 | register char *pattern_percent, *replace_percent; |
---|
127 | { |
---|
128 | unsigned int pattern_prepercent_len, pattern_postpercent_len; |
---|
129 | unsigned int replace_prepercent_len, replace_postpercent_len = 0; |
---|
130 | char *t; |
---|
131 | int len; |
---|
132 | int doneany = 0; |
---|
133 | |
---|
134 | /* We call find_percent on REPLACE before checking PATTERN so that REPLACE |
---|
135 | will be collapsed before we call subst_expand if PATTERN has no %. */ |
---|
136 | if (replace_percent == 0) |
---|
137 | replace_percent = find_percent (replace); |
---|
138 | if (replace_percent != 0) |
---|
139 | { |
---|
140 | /* Record the length of REPLACE before and after the % so |
---|
141 | we don't have to compute these lengths more than once. */ |
---|
142 | replace_prepercent_len = replace_percent - replace; |
---|
143 | replace_postpercent_len = strlen (replace_percent + 1); |
---|
144 | } |
---|
145 | else |
---|
146 | /* We store the length of the replacement |
---|
147 | so we only need to compute it once. */ |
---|
148 | replace_prepercent_len = strlen (replace); |
---|
149 | |
---|
150 | if (pattern_percent == 0) |
---|
151 | pattern_percent = find_percent (pattern); |
---|
152 | if (pattern_percent == 0) |
---|
153 | /* With no % in the pattern, this is just a simple substitution. */ |
---|
154 | return subst_expand (o, text, pattern, replace, |
---|
155 | strlen (pattern), strlen (replace), 1, 0); |
---|
156 | |
---|
157 | /* Record the length of PATTERN before and after the % |
---|
158 | so we don't have to compute it more than once. */ |
---|
159 | pattern_prepercent_len = pattern_percent - pattern; |
---|
160 | pattern_postpercent_len = strlen (pattern_percent + 1); |
---|
161 | |
---|
162 | while ((t = find_next_token (&text, &len)) != 0) |
---|
163 | { |
---|
164 | int fail = 0; |
---|
165 | |
---|
166 | /* Is it big enough to match? */ |
---|
167 | if (len < pattern_prepercent_len + pattern_postpercent_len) |
---|
168 | fail = 1; |
---|
169 | |
---|
170 | /* Does the prefix match? */ |
---|
171 | if (!fail && pattern_prepercent_len > 0 |
---|
172 | && (*t != *pattern |
---|
173 | || t[pattern_prepercent_len - 1] != pattern_percent[-1] |
---|
174 | || !strneq (t + 1, pattern + 1, pattern_prepercent_len - 1))) |
---|
175 | fail = 1; |
---|
176 | |
---|
177 | /* Does the suffix match? */ |
---|
178 | if (!fail && pattern_postpercent_len > 0 |
---|
179 | && (t[len - 1] != pattern_percent[pattern_postpercent_len] |
---|
180 | || t[len - pattern_postpercent_len] != pattern_percent[1] |
---|
181 | || !strneq (&t[len - pattern_postpercent_len], |
---|
182 | &pattern_percent[1], pattern_postpercent_len - 1))) |
---|
183 | fail = 1; |
---|
184 | |
---|
185 | if (fail) |
---|
186 | /* It didn't match. Output the string. */ |
---|
187 | o = variable_buffer_output (o, t, len); |
---|
188 | else |
---|
189 | { |
---|
190 | /* It matched. Output the replacement. */ |
---|
191 | |
---|
192 | /* Output the part of the replacement before the %. */ |
---|
193 | o = variable_buffer_output (o, replace, replace_prepercent_len); |
---|
194 | |
---|
195 | if (replace_percent != 0) |
---|
196 | { |
---|
197 | /* Output the part of the matched string that |
---|
198 | matched the % in the pattern. */ |
---|
199 | o = variable_buffer_output (o, t + pattern_prepercent_len, |
---|
200 | len - (pattern_prepercent_len |
---|
201 | + pattern_postpercent_len)); |
---|
202 | /* Output the part of the replacement after the %. */ |
---|
203 | o = variable_buffer_output (o, replace_percent + 1, |
---|
204 | replace_postpercent_len); |
---|
205 | } |
---|
206 | } |
---|
207 | |
---|
208 | /* Output a space, but not if the replacement is "". */ |
---|
209 | if (fail || replace_prepercent_len > 0 |
---|
210 | || (replace_percent != 0 && len + replace_postpercent_len > 0)) |
---|
211 | { |
---|
212 | o = variable_buffer_output (o, " ", 1); |
---|
213 | doneany = 1; |
---|
214 | } |
---|
215 | } |
---|
216 | if (doneany) |
---|
217 | /* Kill the last space. */ |
---|
218 | --o; |
---|
219 | |
---|
220 | return o; |
---|
221 | } |
---|
222 | |
---|
223 | |
---|
224 | /* Look up a function by name. |
---|
225 | The table is currently small enough that it's not really worthwhile to use |
---|
226 | a fancier lookup algorithm. If it gets larger, maybe... |
---|
227 | */ |
---|
228 | |
---|
229 | static const struct function_table_entry * |
---|
230 | lookup_function (table, s) |
---|
231 | const struct function_table_entry *table; |
---|
232 | const char *s; |
---|
233 | { |
---|
234 | int len = strlen (s); |
---|
235 | |
---|
236 | for (; table->name != NULL; ++table) |
---|
237 | if (table->len <= len |
---|
238 | && (isblank ((unsigned char)s[table->len]) || s[table->len] == '\0') |
---|
239 | && strneq (s, table->name, table->len)) |
---|
240 | return table; |
---|
241 | |
---|
242 | return NULL; |
---|
243 | } |
---|
244 | |
---|
245 | |
---|
246 | /* Return 1 if PATTERN matches STR, 0 if not. */ |
---|
247 | |
---|
248 | int |
---|
249 | pattern_matches (pattern, percent, str) |
---|
250 | register char *pattern, *percent, *str; |
---|
251 | { |
---|
252 | unsigned int sfxlen, strlength; |
---|
253 | |
---|
254 | if (percent == 0) |
---|
255 | { |
---|
256 | unsigned int len = strlen (pattern) + 1; |
---|
257 | char *new_chars = (char *) alloca (len); |
---|
258 | bcopy (pattern, new_chars, len); |
---|
259 | pattern = new_chars; |
---|
260 | percent = find_percent (pattern); |
---|
261 | if (percent == 0) |
---|
262 | return streq (pattern, str); |
---|
263 | } |
---|
264 | |
---|
265 | sfxlen = strlen (percent + 1); |
---|
266 | strlength = strlen (str); |
---|
267 | |
---|
268 | if (strlength < (percent - pattern) + sfxlen |
---|
269 | || !strneq (pattern, str, percent - pattern)) |
---|
270 | return 0; |
---|
271 | |
---|
272 | return !strcmp (percent + 1, str + (strlength - sfxlen)); |
---|
273 | } |
---|
274 | |
---|
275 | |
---|
276 | /* Find the next comma or ENDPAREN (counting nested STARTPAREN and |
---|
277 | ENDPARENtheses), starting at PTR before END. Return a pointer to |
---|
278 | next character. |
---|
279 | |
---|
280 | If no next argument is found, return NULL. |
---|
281 | */ |
---|
282 | |
---|
283 | static char * |
---|
284 | find_next_argument (startparen, endparen, ptr, end) |
---|
285 | char startparen; |
---|
286 | char endparen; |
---|
287 | const char *ptr; |
---|
288 | const char *end; |
---|
289 | { |
---|
290 | int count = 0; |
---|
291 | |
---|
292 | for (; ptr < end; ++ptr) |
---|
293 | if (*ptr == startparen) |
---|
294 | ++count; |
---|
295 | |
---|
296 | else if (*ptr == endparen) |
---|
297 | { |
---|
298 | --count; |
---|
299 | if (count < 0) |
---|
300 | return NULL; |
---|
301 | } |
---|
302 | |
---|
303 | else if (*ptr == ',' && !count) |
---|
304 | return (char *)ptr; |
---|
305 | |
---|
306 | /* We didn't find anything. */ |
---|
307 | return NULL; |
---|
308 | } |
---|
309 | |
---|
310 | |
---|
311 | /* Glob-expand LINE. The returned pointer is |
---|
312 | only good until the next call to string_glob. */ |
---|
313 | |
---|
314 | static char * |
---|
315 | string_glob (line) |
---|
316 | char *line; |
---|
317 | { |
---|
318 | static char *result = 0; |
---|
319 | static unsigned int length; |
---|
320 | register struct nameseq *chain; |
---|
321 | register unsigned int idx; |
---|
322 | |
---|
323 | chain = multi_glob (parse_file_seq |
---|
324 | (&line, '\0', sizeof (struct nameseq), |
---|
325 | /* We do not want parse_file_seq to strip `./'s. |
---|
326 | That would break examples like: |
---|
327 | $(patsubst ./%.c,obj/%.o,$(wildcard ./?*.c)). */ |
---|
328 | 0), |
---|
329 | sizeof (struct nameseq)); |
---|
330 | |
---|
331 | if (result == 0) |
---|
332 | { |
---|
333 | length = 100; |
---|
334 | result = (char *) xmalloc (100); |
---|
335 | } |
---|
336 | |
---|
337 | idx = 0; |
---|
338 | while (chain != 0) |
---|
339 | { |
---|
340 | register char *name = chain->name; |
---|
341 | unsigned int len = strlen (name); |
---|
342 | |
---|
343 | struct nameseq *next = chain->next; |
---|
344 | free ((char *) chain); |
---|
345 | chain = next; |
---|
346 | |
---|
347 | /* multi_glob will pass names without globbing metacharacters |
---|
348 | through as is, but we want only files that actually exist. */ |
---|
349 | if (file_exists_p (name)) |
---|
350 | { |
---|
351 | if (idx + len + 1 > length) |
---|
352 | { |
---|
353 | length += (len + 1) * 2; |
---|
354 | result = (char *) xrealloc (result, length); |
---|
355 | } |
---|
356 | bcopy (name, &result[idx], len); |
---|
357 | idx += len; |
---|
358 | result[idx++] = ' '; |
---|
359 | } |
---|
360 | |
---|
361 | free (name); |
---|
362 | } |
---|
363 | |
---|
364 | /* Kill the last space and terminate the string. */ |
---|
365 | if (idx == 0) |
---|
366 | result[0] = '\0'; |
---|
367 | else |
---|
368 | result[idx - 1] = '\0'; |
---|
369 | |
---|
370 | return result; |
---|
371 | } |
---|
372 | |
---|
373 | /* |
---|
374 | Builtin functions |
---|
375 | */ |
---|
376 | |
---|
377 | static char * |
---|
378 | func_patsubst (o, argv, funcname) |
---|
379 | char *o; |
---|
380 | char **argv; |
---|
381 | const char *funcname; |
---|
382 | { |
---|
383 | o = patsubst_expand (o, argv[2], argv[0], argv[1], (char *) 0, (char *) 0); |
---|
384 | return o; |
---|
385 | } |
---|
386 | |
---|
387 | |
---|
388 | static char * |
---|
389 | func_join (o, argv, funcname) |
---|
390 | char *o; |
---|
391 | char **argv; |
---|
392 | const char *funcname; |
---|
393 | { |
---|
394 | int doneany = 0; |
---|
395 | |
---|
396 | /* Write each word of the first argument directly followed |
---|
397 | by the corresponding word of the second argument. |
---|
398 | If the two arguments have a different number of words, |
---|
399 | the excess words are just output separated by blanks. */ |
---|
400 | register char *tp; |
---|
401 | register char *pp; |
---|
402 | char *list1_iterator = argv[0]; |
---|
403 | char *list2_iterator = argv[1]; |
---|
404 | do |
---|
405 | { |
---|
406 | unsigned int len1, len2; |
---|
407 | |
---|
408 | tp = find_next_token (&list1_iterator, &len1); |
---|
409 | if (tp != 0) |
---|
410 | o = variable_buffer_output (o, tp, len1); |
---|
411 | |
---|
412 | pp = find_next_token (&list2_iterator, &len2); |
---|
413 | if (pp != 0) |
---|
414 | o = variable_buffer_output (o, pp, len2); |
---|
415 | |
---|
416 | if (tp != 0 || pp != 0) |
---|
417 | { |
---|
418 | o = variable_buffer_output (o, " ", 1); |
---|
419 | doneany = 1; |
---|
420 | } |
---|
421 | } |
---|
422 | while (tp != 0 || pp != 0); |
---|
423 | if (doneany) |
---|
424 | /* Kill the last blank. */ |
---|
425 | --o; |
---|
426 | |
---|
427 | return o; |
---|
428 | } |
---|
429 | |
---|
430 | |
---|
431 | static char * |
---|
432 | func_origin (o, argv, funcname) |
---|
433 | char *o; |
---|
434 | char **argv; |
---|
435 | const char *funcname; |
---|
436 | { |
---|
437 | /* Expand the argument. */ |
---|
438 | register struct variable *v = lookup_variable (argv[0], strlen (argv[0])); |
---|
439 | if (v == 0) |
---|
440 | o = variable_buffer_output (o, "undefined", 9); |
---|
441 | else |
---|
442 | switch (v->origin) |
---|
443 | { |
---|
444 | default: |
---|
445 | case o_invalid: |
---|
446 | abort (); |
---|
447 | break; |
---|
448 | case o_default: |
---|
449 | o = variable_buffer_output (o, "default", 7); |
---|
450 | break; |
---|
451 | case o_env: |
---|
452 | o = variable_buffer_output (o, "environment", 11); |
---|
453 | break; |
---|
454 | case o_file: |
---|
455 | o = variable_buffer_output (o, "file", 4); |
---|
456 | break; |
---|
457 | case o_env_override: |
---|
458 | o = variable_buffer_output (o, "environment override", 20); |
---|
459 | break; |
---|
460 | case o_command: |
---|
461 | o = variable_buffer_output (o, "command line", 12); |
---|
462 | break; |
---|
463 | case o_override: |
---|
464 | o = variable_buffer_output (o, "override", 8); |
---|
465 | break; |
---|
466 | case o_automatic: |
---|
467 | o = variable_buffer_output (o, "automatic", 9); |
---|
468 | break; |
---|
469 | } |
---|
470 | |
---|
471 | return o; |
---|
472 | } |
---|
473 | |
---|
474 | #ifdef VMS |
---|
475 | #define IS_PATHSEP(c) ((c) == ']') |
---|
476 | #else |
---|
477 | #if defined(__MSDOS__) || defined(WINDOWS32) |
---|
478 | #define IS_PATHSEP(c) ((c) == '/' || (c) == '\\') |
---|
479 | #else |
---|
480 | #define IS_PATHSEP(c) ((c) == '/') |
---|
481 | #endif |
---|
482 | #endif |
---|
483 | |
---|
484 | |
---|
485 | static char * |
---|
486 | func_notdir_suffix (o, argv, funcname) |
---|
487 | char *o; |
---|
488 | char **argv; |
---|
489 | const char *funcname; |
---|
490 | { |
---|
491 | /* Expand the argument. */ |
---|
492 | char *list_iterator = argv[0]; |
---|
493 | char *p2 =0; |
---|
494 | int doneany =0; |
---|
495 | unsigned int len=0; |
---|
496 | |
---|
497 | int is_suffix = streq (funcname, "suffix"); |
---|
498 | int is_notdir = !is_suffix; |
---|
499 | while ((p2 = find_next_token (&list_iterator, &len)) != 0) |
---|
500 | { |
---|
501 | char *p = p2 + len; |
---|
502 | |
---|
503 | |
---|
504 | while (p >= p2 && (!is_suffix || *p != '.')) |
---|
505 | { |
---|
506 | if (IS_PATHSEP (*p)) |
---|
507 | break; |
---|
508 | --p; |
---|
509 | } |
---|
510 | |
---|
511 | if (p >= p2) |
---|
512 | { |
---|
513 | if (is_notdir) |
---|
514 | ++p; |
---|
515 | else if (*p != '.') |
---|
516 | continue; |
---|
517 | o = variable_buffer_output (o, p, len - (p - p2)); |
---|
518 | } |
---|
519 | #if defined(WINDOWS32) || defined(__MSDOS__) |
---|
520 | /* Handle the case of "d:foo/bar". */ |
---|
521 | else if (streq (funcname, "notdir") && p2[0] && p2[1] == ':') |
---|
522 | { |
---|
523 | p = p2 + 2; |
---|
524 | o = variable_buffer_output (o, p, len - (p - p2)); |
---|
525 | } |
---|
526 | #endif |
---|
527 | else if (is_notdir) |
---|
528 | o = variable_buffer_output (o, p2, len); |
---|
529 | |
---|
530 | if (is_notdir || p >= p2) |
---|
531 | { |
---|
532 | o = variable_buffer_output (o, " ", 1); |
---|
533 | doneany = 1; |
---|
534 | } |
---|
535 | } |
---|
536 | if (doneany) |
---|
537 | /* Kill last space. */ |
---|
538 | --o; |
---|
539 | |
---|
540 | |
---|
541 | return o; |
---|
542 | |
---|
543 | } |
---|
544 | |
---|
545 | |
---|
546 | static char * |
---|
547 | func_basename_dir (o, argv, funcname) |
---|
548 | char *o; |
---|
549 | char **argv; |
---|
550 | const char *funcname; |
---|
551 | { |
---|
552 | /* Expand the argument. */ |
---|
553 | char *p3 = argv[0]; |
---|
554 | char *p2=0; |
---|
555 | int doneany=0; |
---|
556 | unsigned int len=0; |
---|
557 | char *p=0; |
---|
558 | int is_basename= streq (funcname, "basename"); |
---|
559 | int is_dir= !is_basename; |
---|
560 | |
---|
561 | while ((p2 = find_next_token (&p3, &len)) != 0) |
---|
562 | { |
---|
563 | p = p2 + len; |
---|
564 | while (p >= p2 && (!is_basename || *p != '.')) |
---|
565 | { |
---|
566 | if (IS_PATHSEP (*p)) |
---|
567 | break; |
---|
568 | --p; |
---|
569 | } |
---|
570 | |
---|
571 | if (p >= p2 && (is_dir)) |
---|
572 | o = variable_buffer_output (o, p2, ++p - p2); |
---|
573 | else if (p >= p2 && (*p == '.')) |
---|
574 | o = variable_buffer_output (o, p2, p - p2); |
---|
575 | #if defined(WINDOWS32) || defined(__MSDOS__) |
---|
576 | /* Handle the "d:foobar" case */ |
---|
577 | else if (p2[0] && p2[1] == ':' && is_dir) |
---|
578 | o = variable_buffer_output (o, p2, 2); |
---|
579 | #endif |
---|
580 | else if (is_dir) |
---|
581 | #ifdef VMS |
---|
582 | o = variable_buffer_output (o, "[]", 2); |
---|
583 | #else |
---|
584 | #ifndef _AMIGA |
---|
585 | o = variable_buffer_output (o, "./", 2); |
---|
586 | #else |
---|
587 | ; /* Just a nop... */ |
---|
588 | #endif /* AMIGA */ |
---|
589 | #endif /* !VMS */ |
---|
590 | else |
---|
591 | /* The entire name is the basename. */ |
---|
592 | o = variable_buffer_output (o, p2, len); |
---|
593 | |
---|
594 | o = variable_buffer_output (o, " ", 1); |
---|
595 | doneany = 1; |
---|
596 | } |
---|
597 | if (doneany) |
---|
598 | /* Kill last space. */ |
---|
599 | --o; |
---|
600 | |
---|
601 | |
---|
602 | return o; |
---|
603 | } |
---|
604 | |
---|
605 | static char * |
---|
606 | func_addsuffix_addprefix (o, argv, funcname) |
---|
607 | char *o; |
---|
608 | char **argv; |
---|
609 | const char *funcname; |
---|
610 | { |
---|
611 | int fixlen = strlen (argv[0]); |
---|
612 | char *list_iterator = argv[1]; |
---|
613 | int is_addprefix = streq (funcname, "addprefix"); |
---|
614 | int is_addsuffix = !is_addprefix; |
---|
615 | |
---|
616 | int doneany = 0; |
---|
617 | char *p; |
---|
618 | unsigned int len; |
---|
619 | |
---|
620 | while ((p = find_next_token (&list_iterator, &len)) != 0) |
---|
621 | { |
---|
622 | if (is_addprefix) |
---|
623 | o = variable_buffer_output (o, argv[0], fixlen); |
---|
624 | o = variable_buffer_output (o, p, len); |
---|
625 | if (is_addsuffix) |
---|
626 | o = variable_buffer_output (o, argv[0], fixlen); |
---|
627 | o = variable_buffer_output (o, " ", 1); |
---|
628 | doneany = 1; |
---|
629 | } |
---|
630 | |
---|
631 | if (doneany) |
---|
632 | /* Kill last space. */ |
---|
633 | --o; |
---|
634 | |
---|
635 | return o; |
---|
636 | } |
---|
637 | |
---|
638 | static char * |
---|
639 | func_subst (o, argv, funcname) |
---|
640 | char *o; |
---|
641 | char **argv; |
---|
642 | const char *funcname; |
---|
643 | { |
---|
644 | o = subst_expand (o, argv[2], argv[0], argv[1], strlen (argv[0]), |
---|
645 | strlen (argv[1]), 0, 0); |
---|
646 | |
---|
647 | return o; |
---|
648 | } |
---|
649 | |
---|
650 | |
---|
651 | static char * |
---|
652 | func_firstword (o, argv, funcname) |
---|
653 | char *o; |
---|
654 | char **argv; |
---|
655 | const char *funcname; |
---|
656 | { |
---|
657 | unsigned int i; |
---|
658 | char *words = argv[0]; /* Use a temp variable for find_next_token */ |
---|
659 | char *p = find_next_token (&words, &i); |
---|
660 | |
---|
661 | if (p != 0) |
---|
662 | o = variable_buffer_output (o, p, i); |
---|
663 | |
---|
664 | return o; |
---|
665 | } |
---|
666 | |
---|
667 | |
---|
668 | static char * |
---|
669 | func_words (o, argv, funcname) |
---|
670 | char *o; |
---|
671 | char **argv; |
---|
672 | const char *funcname; |
---|
673 | { |
---|
674 | int i = 0; |
---|
675 | char *word_iterator = argv[0]; |
---|
676 | char buf[20]; |
---|
677 | |
---|
678 | while (find_next_token (&word_iterator, (unsigned int *) 0) != 0) |
---|
679 | ++i; |
---|
680 | |
---|
681 | sprintf (buf, "%d", i); |
---|
682 | o = variable_buffer_output (o, buf, strlen (buf)); |
---|
683 | |
---|
684 | |
---|
685 | return o; |
---|
686 | } |
---|
687 | |
---|
688 | char * |
---|
689 | strip_whitespace (begpp, endpp) |
---|
690 | char **begpp; |
---|
691 | char **endpp; |
---|
692 | { |
---|
693 | while (isspace ((unsigned char)**begpp) && *begpp <= *endpp) |
---|
694 | (*begpp) ++; |
---|
695 | while (isspace ((unsigned char)**endpp) && *endpp >= *begpp) |
---|
696 | (*endpp) --; |
---|
697 | return *begpp; |
---|
698 | } |
---|
699 | |
---|
700 | int |
---|
701 | is_numeric (p) |
---|
702 | char *p; |
---|
703 | { |
---|
704 | char *end = p + strlen (p) - 1; |
---|
705 | char *beg = p; |
---|
706 | strip_whitespace (&p, &end); |
---|
707 | |
---|
708 | while (p <= end) |
---|
709 | if (!ISDIGIT (*(p++))) /* ISDIGIT only evals its arg once: see make.h. */ |
---|
710 | return 0; |
---|
711 | |
---|
712 | return (end - beg >= 0); |
---|
713 | } |
---|
714 | |
---|
715 | void |
---|
716 | check_numeric (s, message) |
---|
717 | char *s; |
---|
718 | char *message; |
---|
719 | { |
---|
720 | if (!is_numeric (s)) |
---|
721 | fatal (reading_file, message); |
---|
722 | } |
---|
723 | |
---|
724 | |
---|
725 | |
---|
726 | static char * |
---|
727 | func_word (o, argv, funcname) |
---|
728 | char *o; |
---|
729 | char **argv; |
---|
730 | const char *funcname; |
---|
731 | { |
---|
732 | char *end_p=0; |
---|
733 | int i=0; |
---|
734 | char *p=0; |
---|
735 | |
---|
736 | /* Check the first argument. */ |
---|
737 | check_numeric (argv[0], _("non-numeric first argument to `word' function")); |
---|
738 | i = atoi (argv[0]); |
---|
739 | |
---|
740 | if (i == 0) |
---|
741 | fatal (reading_file, _("first argument to `word' function must be greater than 0")); |
---|
742 | |
---|
743 | |
---|
744 | end_p = argv[1]; |
---|
745 | while ((p = find_next_token (&end_p, 0)) != 0) |
---|
746 | if (--i == 0) |
---|
747 | break; |
---|
748 | |
---|
749 | if (i == 0) |
---|
750 | o = variable_buffer_output (o, p, end_p - p); |
---|
751 | |
---|
752 | return o; |
---|
753 | } |
---|
754 | |
---|
755 | static char * |
---|
756 | func_wordlist (o, argv, funcname) |
---|
757 | char *o; |
---|
758 | char **argv; |
---|
759 | const char *funcname; |
---|
760 | { |
---|
761 | int start, count; |
---|
762 | |
---|
763 | /* Check the arguments. */ |
---|
764 | check_numeric (argv[0], |
---|
765 | _("non-numeric first argument to `wordlist' function")); |
---|
766 | check_numeric (argv[1], |
---|
767 | _("non-numeric second argument to `wordlist' function")); |
---|
768 | |
---|
769 | start = atoi (argv[0]); |
---|
770 | count = atoi (argv[1]) - start + 1; |
---|
771 | |
---|
772 | if (count > 0) |
---|
773 | { |
---|
774 | char *p; |
---|
775 | char *end_p = argv[2]; |
---|
776 | |
---|
777 | /* Find the beginning of the "start"th word. */ |
---|
778 | while (((p = find_next_token (&end_p, 0)) != 0) && --start) |
---|
779 | ; |
---|
780 | |
---|
781 | if (p) |
---|
782 | { |
---|
783 | /* Find the end of the "count"th word from start. */ |
---|
784 | while (--count && (find_next_token (&end_p, 0) != 0)) |
---|
785 | ; |
---|
786 | |
---|
787 | /* Return the stuff in the middle. */ |
---|
788 | o = variable_buffer_output (o, p, end_p - p); |
---|
789 | } |
---|
790 | } |
---|
791 | |
---|
792 | return o; |
---|
793 | } |
---|
794 | |
---|
795 | static char* |
---|
796 | func_findstring (o, argv, funcname) |
---|
797 | char *o; |
---|
798 | char **argv; |
---|
799 | const char *funcname; |
---|
800 | { |
---|
801 | /* Find the first occurrence of the first string in the second. */ |
---|
802 | int i = strlen (argv[0]); |
---|
803 | if (sindex (argv[1], 0, argv[0], i) != 0) |
---|
804 | o = variable_buffer_output (o, argv[0], i); |
---|
805 | |
---|
806 | return o; |
---|
807 | } |
---|
808 | |
---|
809 | static char * |
---|
810 | func_foreach (o, argv, funcname) |
---|
811 | char *o; |
---|
812 | char **argv; |
---|
813 | const char *funcname; |
---|
814 | { |
---|
815 | /* expand only the first two. */ |
---|
816 | char *varname = expand_argument (argv[0], NULL); |
---|
817 | char *list = expand_argument (argv[1], NULL); |
---|
818 | char *body = argv[2]; |
---|
819 | |
---|
820 | int doneany = 0; |
---|
821 | char *list_iterator = list; |
---|
822 | char *p; |
---|
823 | unsigned int len; |
---|
824 | register struct variable *var; |
---|
825 | |
---|
826 | push_new_variable_scope (); |
---|
827 | var = define_variable (varname, strlen (varname), "", o_automatic, 0); |
---|
828 | |
---|
829 | /* loop through LIST, put the value in VAR and expand BODY */ |
---|
830 | while ((p = find_next_token (&list_iterator, &len)) != 0) |
---|
831 | { |
---|
832 | char *result = 0; |
---|
833 | |
---|
834 | { |
---|
835 | char save = p[len]; |
---|
836 | |
---|
837 | p[len] = '\0'; |
---|
838 | free (var->value); |
---|
839 | var->value = (char *) xstrdup ((char*) p); |
---|
840 | p[len] = save; |
---|
841 | } |
---|
842 | |
---|
843 | result = allocated_variable_expand (body); |
---|
844 | |
---|
845 | o = variable_buffer_output (o, result, strlen (result)); |
---|
846 | o = variable_buffer_output (o, " ", 1); |
---|
847 | doneany = 1; |
---|
848 | free (result); |
---|
849 | } |
---|
850 | |
---|
851 | if (doneany) |
---|
852 | /* Kill the last space. */ |
---|
853 | --o; |
---|
854 | |
---|
855 | pop_variable_scope (); |
---|
856 | free (varname); |
---|
857 | free (list); |
---|
858 | |
---|
859 | return o; |
---|
860 | } |
---|
861 | |
---|
862 | struct a_word |
---|
863 | { |
---|
864 | struct a_word *next; |
---|
865 | char *str; |
---|
866 | int matched; |
---|
867 | }; |
---|
868 | |
---|
869 | static char * |
---|
870 | func_filter_filterout (o, argv, funcname) |
---|
871 | char *o; |
---|
872 | char **argv; |
---|
873 | const char *funcname; |
---|
874 | { |
---|
875 | struct a_word *wordhead = 0; |
---|
876 | struct a_word *wordtail = 0; |
---|
877 | |
---|
878 | int is_filter = streq (funcname, "filter"); |
---|
879 | char *patterns = argv[0]; |
---|
880 | char *word_iterator = argv[1]; |
---|
881 | |
---|
882 | char *p; |
---|
883 | unsigned int len; |
---|
884 | |
---|
885 | /* Chop ARGV[1] up into words and then run each pattern through. */ |
---|
886 | while ((p = find_next_token (&word_iterator, &len)) != 0) |
---|
887 | { |
---|
888 | struct a_word *w = (struct a_word *)alloca (sizeof (struct a_word)); |
---|
889 | if (wordhead == 0) |
---|
890 | wordhead = w; |
---|
891 | else |
---|
892 | wordtail->next = w; |
---|
893 | wordtail = w; |
---|
894 | |
---|
895 | if (*word_iterator != '\0') |
---|
896 | ++word_iterator; |
---|
897 | p[len] = '\0'; |
---|
898 | w->str = p; |
---|
899 | w->matched = 0; |
---|
900 | } |
---|
901 | |
---|
902 | if (wordhead != 0) |
---|
903 | { |
---|
904 | char *pat_iterator = patterns; |
---|
905 | int doneany = 0; |
---|
906 | struct a_word *wp; |
---|
907 | |
---|
908 | wordtail->next = 0; |
---|
909 | |
---|
910 | /* Run each pattern through the words, killing words. */ |
---|
911 | while ((p = find_next_token (&pat_iterator, &len)) != 0) |
---|
912 | { |
---|
913 | char *percent; |
---|
914 | char save = p[len]; |
---|
915 | p[len] = '\0'; |
---|
916 | |
---|
917 | percent = find_percent (p); |
---|
918 | for (wp = wordhead; wp != 0; wp = wp->next) |
---|
919 | wp->matched |= (percent == 0 ? streq (p, wp->str) |
---|
920 | : pattern_matches (p, percent, wp->str)); |
---|
921 | |
---|
922 | p[len] = save; |
---|
923 | } |
---|
924 | |
---|
925 | /* Output the words that matched (or didn't, for filter-out). */ |
---|
926 | for (wp = wordhead; wp != 0; wp = wp->next) |
---|
927 | if (is_filter ? wp->matched : !wp->matched) |
---|
928 | { |
---|
929 | o = variable_buffer_output (o, wp->str, strlen (wp->str)); |
---|
930 | o = variable_buffer_output (o, " ", 1); |
---|
931 | doneany = 1; |
---|
932 | } |
---|
933 | |
---|
934 | if (doneany) |
---|
935 | /* Kill the last space. */ |
---|
936 | --o; |
---|
937 | } |
---|
938 | |
---|
939 | return o; |
---|
940 | } |
---|
941 | |
---|
942 | |
---|
943 | static char * |
---|
944 | func_strip (o, argv, funcname) |
---|
945 | char *o; |
---|
946 | char **argv; |
---|
947 | const char *funcname; |
---|
948 | { |
---|
949 | char *p = argv[0]; |
---|
950 | int doneany =0; |
---|
951 | |
---|
952 | while (*p != '\0') |
---|
953 | { |
---|
954 | int i=0; |
---|
955 | char *word_start=0; |
---|
956 | |
---|
957 | while (isspace ((unsigned char)*p)) |
---|
958 | ++p; |
---|
959 | word_start = p; |
---|
960 | for (i=0; *p != '\0' && !isspace ((unsigned char)*p); ++p, ++i) |
---|
961 | {} |
---|
962 | if (!i) |
---|
963 | break; |
---|
964 | o = variable_buffer_output (o, word_start, i); |
---|
965 | o = variable_buffer_output (o, " ", 1); |
---|
966 | doneany = 1; |
---|
967 | } |
---|
968 | |
---|
969 | if (doneany) |
---|
970 | /* Kill the last space. */ |
---|
971 | --o; |
---|
972 | return o; |
---|
973 | } |
---|
974 | |
---|
975 | /* |
---|
976 | Print a warning or fatal message. |
---|
977 | */ |
---|
978 | static char * |
---|
979 | func_error (o, argv, funcname) |
---|
980 | char *o; |
---|
981 | char **argv; |
---|
982 | const char *funcname; |
---|
983 | { |
---|
984 | char **argvp; |
---|
985 | char *msg, *p; |
---|
986 | int len; |
---|
987 | |
---|
988 | /* The arguments will be broken on commas. Rather than create yet |
---|
989 | another special case where function arguments aren't broken up, |
---|
990 | just create a format string that puts them back together. */ |
---|
991 | for (len=0, argvp=argv; *argvp != 0; ++argvp) |
---|
992 | len += strlen (*argvp) + 2; |
---|
993 | |
---|
994 | p = msg = alloca (len + 1); |
---|
995 | |
---|
996 | for (argvp=argv; argvp[1] != 0; ++argvp) |
---|
997 | { |
---|
998 | strcpy (p, *argvp); |
---|
999 | p += strlen (*argvp); |
---|
1000 | *(p++) = ','; |
---|
1001 | *(p++) = ' '; |
---|
1002 | } |
---|
1003 | strcpy (p, *argvp); |
---|
1004 | |
---|
1005 | if (*funcname == 'e') |
---|
1006 | fatal (reading_file, "%s", msg); |
---|
1007 | |
---|
1008 | /* The warning function expands to the empty string. */ |
---|
1009 | error (reading_file, "%s", msg); |
---|
1010 | |
---|
1011 | return o; |
---|
1012 | } |
---|
1013 | |
---|
1014 | |
---|
1015 | /* |
---|
1016 | chop argv[0] into words, and sort them. |
---|
1017 | */ |
---|
1018 | static char * |
---|
1019 | func_sort (o, argv, funcname) |
---|
1020 | char *o; |
---|
1021 | char **argv; |
---|
1022 | const char *funcname; |
---|
1023 | { |
---|
1024 | char **words = 0; |
---|
1025 | int nwords = 0; |
---|
1026 | register int wordi = 0; |
---|
1027 | |
---|
1028 | /* Chop ARGV[0] into words and put them in WORDS. */ |
---|
1029 | char *t = argv[0]; |
---|
1030 | char *p; |
---|
1031 | unsigned int len; |
---|
1032 | int i; |
---|
1033 | |
---|
1034 | while ((p = find_next_token (&t, &len)) != 0) |
---|
1035 | { |
---|
1036 | if (wordi >= nwords - 1) |
---|
1037 | { |
---|
1038 | nwords = (2 * nwords) + 5; |
---|
1039 | words = (char **) xrealloc ((char *) words, |
---|
1040 | nwords * sizeof (char *)); |
---|
1041 | } |
---|
1042 | words[wordi++] = savestring (p, len); |
---|
1043 | } |
---|
1044 | |
---|
1045 | if (!wordi) |
---|
1046 | return o; |
---|
1047 | |
---|
1048 | /* Now sort the list of words. */ |
---|
1049 | qsort ((char *) words, wordi, sizeof (char *), alpha_compare); |
---|
1050 | |
---|
1051 | /* Now write the sorted list. */ |
---|
1052 | for (i = 0; i < wordi; ++i) |
---|
1053 | { |
---|
1054 | len = strlen (words[i]); |
---|
1055 | if (i == wordi - 1 || strlen (words[i + 1]) != len |
---|
1056 | || strcmp (words[i], words[i + 1])) |
---|
1057 | { |
---|
1058 | o = variable_buffer_output (o, words[i], len); |
---|
1059 | o = variable_buffer_output (o, " ", 1); |
---|
1060 | } |
---|
1061 | free (words[i]); |
---|
1062 | } |
---|
1063 | /* Kill the last space. */ |
---|
1064 | --o; |
---|
1065 | |
---|
1066 | free (words); |
---|
1067 | |
---|
1068 | return o; |
---|
1069 | } |
---|
1070 | |
---|
1071 | /* |
---|
1072 | $(if condition,true-part[,false-part]) |
---|
1073 | |
---|
1074 | CONDITION is false iff it evaluates to an empty string. White |
---|
1075 | space before and after condition are stripped before evaluation. |
---|
1076 | |
---|
1077 | If CONDITION is true, then TRUE-PART is evaluated, otherwise FALSE-PART is |
---|
1078 | evaluated (if it exists). Because only one of the two PARTs is evaluated, |
---|
1079 | you can use $(if ...) to create side-effects (with $(shell ...), for |
---|
1080 | example). |
---|
1081 | */ |
---|
1082 | |
---|
1083 | static char * |
---|
1084 | func_if (o, argv, funcname) |
---|
1085 | char *o; |
---|
1086 | char **argv; |
---|
1087 | const char *funcname; |
---|
1088 | { |
---|
1089 | char *begp = argv[0]; |
---|
1090 | char *endp = begp + strlen (argv[0]); |
---|
1091 | int result = 0; |
---|
1092 | |
---|
1093 | /* Find the result of the condition: if we have a value, and it's not |
---|
1094 | empty, the condition is true. If we don't have a value, or it's the |
---|
1095 | empty string, then it's false. */ |
---|
1096 | |
---|
1097 | strip_whitespace (&begp, &endp); |
---|
1098 | |
---|
1099 | if (begp < endp) |
---|
1100 | { |
---|
1101 | char *expansion = expand_argument (begp, NULL); |
---|
1102 | |
---|
1103 | result = strlen (expansion); |
---|
1104 | free (expansion); |
---|
1105 | } |
---|
1106 | |
---|
1107 | /* If the result is true (1) we want to eval the first argument, and if |
---|
1108 | it's false (0) we want to eval the second. If the argument doesn't |
---|
1109 | exist we do nothing, otherwise expand it and add to the buffer. */ |
---|
1110 | |
---|
1111 | argv += 1 + !result; |
---|
1112 | |
---|
1113 | if (argv[0]) |
---|
1114 | { |
---|
1115 | char *expansion; |
---|
1116 | |
---|
1117 | expansion = expand_argument (argv[0], NULL); |
---|
1118 | |
---|
1119 | o = variable_buffer_output (o, expansion, strlen (expansion)); |
---|
1120 | |
---|
1121 | free (expansion); |
---|
1122 | } |
---|
1123 | |
---|
1124 | return o; |
---|
1125 | } |
---|
1126 | |
---|
1127 | static char * |
---|
1128 | func_wildcard (o, argv, funcname) |
---|
1129 | char *o; |
---|
1130 | char **argv; |
---|
1131 | const char *funcname; |
---|
1132 | { |
---|
1133 | |
---|
1134 | #ifdef _AMIGA |
---|
1135 | o = wildcard_expansion (argv[0], o); |
---|
1136 | #else |
---|
1137 | char *p = string_glob (argv[0]); |
---|
1138 | o = variable_buffer_output (o, p, strlen (p)); |
---|
1139 | #endif |
---|
1140 | return o; |
---|
1141 | } |
---|
1142 | |
---|
1143 | /* |
---|
1144 | \r is replaced on UNIX as well. Is this desirable? |
---|
1145 | */ |
---|
1146 | void |
---|
1147 | fold_newlines (buffer, length) |
---|
1148 | char *buffer; |
---|
1149 | int *length; |
---|
1150 | { |
---|
1151 | char *dst = buffer; |
---|
1152 | char *src = buffer; |
---|
1153 | char *last_nonnl = buffer -1; |
---|
1154 | src[*length] = 0; |
---|
1155 | for (; *src != '\0'; ++src) |
---|
1156 | { |
---|
1157 | if (src[0] == '\r' && src[1] == '\n') |
---|
1158 | continue; |
---|
1159 | if (*src == '\n') |
---|
1160 | { |
---|
1161 | *dst++ = ' '; |
---|
1162 | } |
---|
1163 | else |
---|
1164 | { |
---|
1165 | last_nonnl = dst; |
---|
1166 | *dst++ = *src; |
---|
1167 | } |
---|
1168 | } |
---|
1169 | *(++last_nonnl) = '\0'; |
---|
1170 | *length = last_nonnl - buffer; |
---|
1171 | } |
---|
1172 | |
---|
1173 | |
---|
1174 | |
---|
1175 | int shell_function_pid = 0, shell_function_completed; |
---|
1176 | |
---|
1177 | |
---|
1178 | #ifdef WINDOWS32 |
---|
1179 | /*untested*/ |
---|
1180 | |
---|
1181 | #include <windows.h> |
---|
1182 | #include <io.h> |
---|
1183 | #include "sub_proc.h" |
---|
1184 | |
---|
1185 | |
---|
1186 | void |
---|
1187 | windows32_openpipe (int *pipedes, int *pid_p, char **command_argv, char **envp) |
---|
1188 | { |
---|
1189 | SECURITY_ATTRIBUTES saAttr; |
---|
1190 | HANDLE hIn; |
---|
1191 | HANDLE hErr; |
---|
1192 | HANDLE hChildOutRd; |
---|
1193 | HANDLE hChildOutWr; |
---|
1194 | HANDLE hProcess; |
---|
1195 | |
---|
1196 | |
---|
1197 | saAttr.nLength = sizeof (SECURITY_ATTRIBUTES); |
---|
1198 | saAttr.bInheritHandle = TRUE; |
---|
1199 | saAttr.lpSecurityDescriptor = NULL; |
---|
1200 | |
---|
1201 | if (DuplicateHandle (GetCurrentProcess(), |
---|
1202 | GetStdHandle(STD_INPUT_HANDLE), |
---|
1203 | GetCurrentProcess(), |
---|
1204 | &hIn, |
---|
1205 | 0, |
---|
1206 | TRUE, |
---|
1207 | DUPLICATE_SAME_ACCESS) == FALSE) { |
---|
1208 | fatal (NILF, _("create_child_process: DuplicateHandle(In) failed (e=%d)\n"), |
---|
1209 | GetLastError()); |
---|
1210 | |
---|
1211 | } |
---|
1212 | if (DuplicateHandle(GetCurrentProcess(), |
---|
1213 | GetStdHandle(STD_ERROR_HANDLE), |
---|
1214 | GetCurrentProcess(), |
---|
1215 | &hErr, |
---|
1216 | 0, |
---|
1217 | TRUE, |
---|
1218 | DUPLICATE_SAME_ACCESS) == FALSE) { |
---|
1219 | fatal (NILF, _("create_child_process: DuplicateHandle(Err) failed (e=%d)\n"), |
---|
1220 | GetLastError()); |
---|
1221 | } |
---|
1222 | |
---|
1223 | if (!CreatePipe(&hChildOutRd, &hChildOutWr, &saAttr, 0)) |
---|
1224 | fatal (NILF, _("CreatePipe() failed (e=%d)\n"), GetLastError()); |
---|
1225 | |
---|
1226 | hProcess = process_init_fd(hIn, hChildOutWr, hErr); |
---|
1227 | |
---|
1228 | if (!hProcess) |
---|
1229 | fatal (NILF, _("windows32_openpipe (): process_init_fd() failed\n")); |
---|
1230 | |
---|
1231 | /* make sure that CreateProcess() has Path it needs */ |
---|
1232 | sync_Path_environment(); |
---|
1233 | |
---|
1234 | if (!process_begin(hProcess, command_argv, envp, command_argv[0], NULL)) { |
---|
1235 | /* register process for wait */ |
---|
1236 | process_register(hProcess); |
---|
1237 | |
---|
1238 | /* set the pid for returning to caller */ |
---|
1239 | *pid_p = (int) hProcess; |
---|
1240 | |
---|
1241 | /* set up to read data from child */ |
---|
1242 | pipedes[0] = _open_osfhandle((long) hChildOutRd, O_RDONLY); |
---|
1243 | |
---|
1244 | /* this will be closed almost right away */ |
---|
1245 | pipedes[1] = _open_osfhandle((long) hChildOutWr, O_APPEND); |
---|
1246 | } else { |
---|
1247 | /* reap/cleanup the failed process */ |
---|
1248 | process_cleanup(hProcess); |
---|
1249 | |
---|
1250 | /* close handles which were duplicated, they weren't used */ |
---|
1251 | CloseHandle(hIn); |
---|
1252 | CloseHandle(hErr); |
---|
1253 | |
---|
1254 | /* close pipe handles, they won't be used */ |
---|
1255 | CloseHandle(hChildOutRd); |
---|
1256 | CloseHandle(hChildOutWr); |
---|
1257 | |
---|
1258 | /* set status for return */ |
---|
1259 | pipedes[0] = pipedes[1] = -1; |
---|
1260 | *pid_p = -1; |
---|
1261 | } |
---|
1262 | } |
---|
1263 | #endif |
---|
1264 | |
---|
1265 | |
---|
1266 | #ifdef __MSDOS__ |
---|
1267 | FILE * |
---|
1268 | msdos_openpipe (int* pipedes, int *pidp, char *text) |
---|
1269 | { |
---|
1270 | FILE *fpipe=0; |
---|
1271 | /* MSDOS can't fork, but it has `popen'. */ |
---|
1272 | struct variable *sh = lookup_variable ("SHELL", 5); |
---|
1273 | int e; |
---|
1274 | extern int dos_command_running, dos_status; |
---|
1275 | |
---|
1276 | /* Make sure not to bother processing an empty line. */ |
---|
1277 | while (isblank ((unsigned char)*text)) |
---|
1278 | ++text; |
---|
1279 | if (*text == '\0') |
---|
1280 | return 0; |
---|
1281 | |
---|
1282 | if (sh) |
---|
1283 | { |
---|
1284 | char buf[PATH_MAX + 7]; |
---|
1285 | /* This makes sure $SHELL value is used by $(shell), even |
---|
1286 | though the target environment is not passed to it. */ |
---|
1287 | sprintf (buf, "SHELL=%s", sh->value); |
---|
1288 | putenv (buf); |
---|
1289 | } |
---|
1290 | |
---|
1291 | e = errno; |
---|
1292 | errno = 0; |
---|
1293 | dos_command_running = 1; |
---|
1294 | dos_status = 0; |
---|
1295 | /* If dos_status becomes non-zero, it means the child process |
---|
1296 | was interrupted by a signal, like SIGINT or SIGQUIT. See |
---|
1297 | fatal_error_signal in commands.c. */ |
---|
1298 | fpipe = popen (text, "rt"); |
---|
1299 | dos_command_running = 0; |
---|
1300 | if (!fpipe || dos_status) |
---|
1301 | { |
---|
1302 | pipedes[0] = -1; |
---|
1303 | *pidp = -1; |
---|
1304 | if (dos_status) |
---|
1305 | errno = EINTR; |
---|
1306 | else if (errno == 0) |
---|
1307 | errno = ENOMEM; |
---|
1308 | shell_function_completed = -1; |
---|
1309 | } |
---|
1310 | else |
---|
1311 | { |
---|
1312 | pipedes[0] = fileno (fpipe); |
---|
1313 | *pidp = 42; /* Yes, the Meaning of Life, the Universe, and Everything! */ |
---|
1314 | errno = e; |
---|
1315 | shell_function_completed = 1; |
---|
1316 | } |
---|
1317 | return fpipe; |
---|
1318 | } |
---|
1319 | #endif |
---|
1320 | |
---|
1321 | /* |
---|
1322 | Do shell spawning, with the naughty bits for different OSes. |
---|
1323 | */ |
---|
1324 | |
---|
1325 | #ifdef VMS |
---|
1326 | |
---|
1327 | /* VMS can't do $(shell ...) */ |
---|
1328 | #define func_shell 0 |
---|
1329 | |
---|
1330 | #else |
---|
1331 | #ifndef _AMIGA |
---|
1332 | static char * |
---|
1333 | func_shell (o, argv, funcname) |
---|
1334 | char *o; |
---|
1335 | char **argv; |
---|
1336 | const char *funcname; |
---|
1337 | { |
---|
1338 | char* batch_filename = NULL; |
---|
1339 | int i; |
---|
1340 | |
---|
1341 | #ifdef __MSDOS__ |
---|
1342 | FILE *fpipe; |
---|
1343 | #endif |
---|
1344 | char **command_argv; |
---|
1345 | char *error_prefix; |
---|
1346 | char **envp; |
---|
1347 | int pipedes[2]; |
---|
1348 | int pid; |
---|
1349 | |
---|
1350 | #ifndef __MSDOS__ |
---|
1351 | /* Construct the argument list. */ |
---|
1352 | command_argv = construct_command_argv (argv[0], |
---|
1353 | (char **) NULL, (struct file *) 0, |
---|
1354 | &batch_filename); |
---|
1355 | if (command_argv == 0) |
---|
1356 | return o; |
---|
1357 | #endif |
---|
1358 | |
---|
1359 | /* Using a target environment for `shell' loses in cases like: |
---|
1360 | export var = $(shell echo foobie) |
---|
1361 | because target_environment hits a loop trying to expand $(var) |
---|
1362 | to put it in the environment. This is even more confusing when |
---|
1363 | var was not explicitly exported, but just appeared in the |
---|
1364 | calling environment. */ |
---|
1365 | |
---|
1366 | envp = environ; |
---|
1367 | |
---|
1368 | /* For error messages. */ |
---|
1369 | if (reading_file != 0) |
---|
1370 | { |
---|
1371 | error_prefix = (char *) alloca (strlen (reading_file->filenm)+11+4); |
---|
1372 | sprintf (error_prefix, |
---|
1373 | "%s:%lu: ", reading_file->filenm, reading_file->lineno); |
---|
1374 | } |
---|
1375 | else |
---|
1376 | error_prefix = ""; |
---|
1377 | |
---|
1378 | #ifdef WINDOWS32 |
---|
1379 | windows32_openpipe (pipedes, &pid, command_argv, envp); |
---|
1380 | |
---|
1381 | if (pipedes[0] < 0) { |
---|
1382 | /* open of the pipe failed, mark as failed execution */ |
---|
1383 | shell_function_completed = -1; |
---|
1384 | |
---|
1385 | return o; |
---|
1386 | } else |
---|
1387 | #else /* WINDOWS32 */ |
---|
1388 | |
---|
1389 | # ifdef __MSDOS__ |
---|
1390 | fpipe = msdos_openpipe (pipedes, &pid, argv[0]); |
---|
1391 | if (pipedes[0] < 0) |
---|
1392 | { |
---|
1393 | perror_with_name (error_prefix, "pipe"); |
---|
1394 | return o; |
---|
1395 | } |
---|
1396 | # else |
---|
1397 | if (pipe (pipedes) < 0) |
---|
1398 | { |
---|
1399 | perror_with_name (error_prefix, "pipe"); |
---|
1400 | return o; |
---|
1401 | } |
---|
1402 | |
---|
1403 | pid = vfork (); |
---|
1404 | if (pid < 0) |
---|
1405 | perror_with_name (error_prefix, "fork"); |
---|
1406 | else if (pid == 0) |
---|
1407 | child_execute_job (0, pipedes[1], command_argv, envp); |
---|
1408 | else |
---|
1409 | # endif /* ! __MSDOS__ */ |
---|
1410 | |
---|
1411 | #endif /* WINDOWS32 */ |
---|
1412 | { |
---|
1413 | /* We are the parent. */ |
---|
1414 | |
---|
1415 | char *buffer; |
---|
1416 | unsigned int maxlen; |
---|
1417 | int cc; |
---|
1418 | |
---|
1419 | /* Record the PID for reap_children. */ |
---|
1420 | shell_function_pid = pid; |
---|
1421 | #ifndef __MSDOS__ |
---|
1422 | shell_function_completed = 0; |
---|
1423 | |
---|
1424 | /* Free the storage only the child needed. */ |
---|
1425 | free (command_argv[0]); |
---|
1426 | free ((char *) command_argv); |
---|
1427 | |
---|
1428 | /* Close the write side of the pipe. */ |
---|
1429 | (void) close (pipedes[1]); |
---|
1430 | #endif |
---|
1431 | |
---|
1432 | /* Set up and read from the pipe. */ |
---|
1433 | |
---|
1434 | maxlen = 200; |
---|
1435 | buffer = (char *) xmalloc (maxlen + 1); |
---|
1436 | |
---|
1437 | /* Read from the pipe until it gets EOF. */ |
---|
1438 | i = 0; |
---|
1439 | do |
---|
1440 | { |
---|
1441 | if (i == maxlen) |
---|
1442 | { |
---|
1443 | maxlen += 512; |
---|
1444 | buffer = (char *) xrealloc (buffer, maxlen + 1); |
---|
1445 | } |
---|
1446 | |
---|
1447 | errno = 0; |
---|
1448 | cc = read (pipedes[0], &buffer[i], maxlen - i); |
---|
1449 | if (cc > 0) |
---|
1450 | i += cc; |
---|
1451 | } |
---|
1452 | while (cc > 0 || EINTR_SET); |
---|
1453 | |
---|
1454 | /* Close the read side of the pipe. */ |
---|
1455 | #ifdef __MSDOS__ |
---|
1456 | if (fpipe) |
---|
1457 | (void) pclose (fpipe); |
---|
1458 | #else |
---|
1459 | (void) close (pipedes[0]); |
---|
1460 | #endif |
---|
1461 | |
---|
1462 | /* Loop until child_handler sets shell_function_completed |
---|
1463 | to the status of our child shell. */ |
---|
1464 | while (shell_function_completed == 0) |
---|
1465 | reap_children (1, 0); |
---|
1466 | |
---|
1467 | if (batch_filename) { |
---|
1468 | DB (DB_VERBOSE, (_("Cleaning up temporary batch file %s\n"), |
---|
1469 | batch_filename)); |
---|
1470 | remove (batch_filename); |
---|
1471 | free (batch_filename); |
---|
1472 | } |
---|
1473 | shell_function_pid = 0; |
---|
1474 | |
---|
1475 | /* The child_handler function will set shell_function_completed |
---|
1476 | to 1 when the child dies normally, or to -1 if it |
---|
1477 | dies with status 127, which is most likely an exec fail. */ |
---|
1478 | |
---|
1479 | if (shell_function_completed == -1) |
---|
1480 | { |
---|
1481 | /* This most likely means that the execvp failed, |
---|
1482 | so we should just write out the error message |
---|
1483 | that came in over the pipe from the child. */ |
---|
1484 | fputs (buffer, stderr); |
---|
1485 | fflush (stderr); |
---|
1486 | } |
---|
1487 | else |
---|
1488 | { |
---|
1489 | /* The child finished normally. Replace all |
---|
1490 | newlines in its output with spaces, and put |
---|
1491 | that in the variable output buffer. */ |
---|
1492 | fold_newlines (buffer, &i); |
---|
1493 | o = variable_buffer_output (o, buffer, i); |
---|
1494 | } |
---|
1495 | |
---|
1496 | free (buffer); |
---|
1497 | } |
---|
1498 | |
---|
1499 | return o; |
---|
1500 | } |
---|
1501 | |
---|
1502 | #else /* _AMIGA */ |
---|
1503 | |
---|
1504 | /* Do the Amiga version of func_shell. */ |
---|
1505 | |
---|
1506 | static char * |
---|
1507 | func_shell (char *o, char **argv, const char *funcname) |
---|
1508 | { |
---|
1509 | /* Amiga can't fork nor spawn, but I can start a program with |
---|
1510 | redirection of my choice. However, this means that we |
---|
1511 | don't have an opportunity to reopen stdout to trap it. Thus, |
---|
1512 | we save our own stdout onto a new descriptor and dup a temp |
---|
1513 | file's descriptor onto our stdout temporarily. After we |
---|
1514 | spawn the shell program, we dup our own stdout back to the |
---|
1515 | stdout descriptor. The buffer reading is the same as above, |
---|
1516 | except that we're now reading from a file. */ |
---|
1517 | |
---|
1518 | #include <dos/dos.h> |
---|
1519 | #include <proto/dos.h> |
---|
1520 | |
---|
1521 | BPTR child_stdout; |
---|
1522 | char tmp_output[FILENAME_MAX]; |
---|
1523 | unsigned int maxlen = 200; |
---|
1524 | int cc, i; |
---|
1525 | char * buffer, * ptr; |
---|
1526 | char ** aptr; |
---|
1527 | int len = 0; |
---|
1528 | char* batch_filename = NULL; |
---|
1529 | |
---|
1530 | /* Construct the argument list. */ |
---|
1531 | command_argv = construct_command_argv (argv[0], (char **) NULL, |
---|
1532 | (struct file *) 0, &batch_filename); |
---|
1533 | if (command_argv == 0) |
---|
1534 | return o; |
---|
1535 | |
---|
1536 | /* Note the mktemp() is a security hole, but this only runs on Amiga. |
---|
1537 | Ideally we would use main.c:open_tmpfile(), but this uses a special |
---|
1538 | Open(), not fopen(), and I'm not familiar enough with the code to mess |
---|
1539 | with it. */ |
---|
1540 | strcpy (tmp_output, "t:MakeshXXXXXXXX"); |
---|
1541 | mktemp (tmp_output); |
---|
1542 | child_stdout = Open (tmp_output, MODE_NEWFILE); |
---|
1543 | |
---|
1544 | for (aptr=command_argv; *aptr; aptr++) |
---|
1545 | len += strlen (*aptr) + 1; |
---|
1546 | |
---|
1547 | buffer = xmalloc (len + 1); |
---|
1548 | ptr = buffer; |
---|
1549 | |
---|
1550 | for (aptr=command_argv; *aptr; aptr++) |
---|
1551 | { |
---|
1552 | strcpy (ptr, *aptr); |
---|
1553 | ptr += strlen (ptr) + 1; |
---|
1554 | *ptr ++ = ' '; |
---|
1555 | *ptr = 0; |
---|
1556 | } |
---|
1557 | |
---|
1558 | ptr[-1] = '\n'; |
---|
1559 | |
---|
1560 | Execute (buffer, NULL, child_stdout); |
---|
1561 | free (buffer); |
---|
1562 | |
---|
1563 | Close (child_stdout); |
---|
1564 | |
---|
1565 | child_stdout = Open (tmp_output, MODE_OLDFILE); |
---|
1566 | |
---|
1567 | buffer = xmalloc (maxlen); |
---|
1568 | i = 0; |
---|
1569 | do |
---|
1570 | { |
---|
1571 | if (i == maxlen) |
---|
1572 | { |
---|
1573 | maxlen += 512; |
---|
1574 | buffer = (char *) xrealloc (buffer, maxlen + 1); |
---|
1575 | } |
---|
1576 | |
---|
1577 | cc = Read (child_stdout, &buffer[i], maxlen - i); |
---|
1578 | if (cc > 0) |
---|
1579 | i += cc; |
---|
1580 | } while (cc > 0); |
---|
1581 | |
---|
1582 | Close (child_stdout); |
---|
1583 | |
---|
1584 | fold_newlines (buffer, &i); |
---|
1585 | o = variable_buffer_output (o, buffer, i); |
---|
1586 | free (buffer); |
---|
1587 | return o; |
---|
1588 | } |
---|
1589 | #endif /* _AMIGA */ |
---|
1590 | #endif /* !VMS */ |
---|
1591 | |
---|
1592 | #ifdef EXPERIMENTAL |
---|
1593 | |
---|
1594 | /* |
---|
1595 | equality. Return is string-boolean, ie, the empty string is false. |
---|
1596 | */ |
---|
1597 | static char * |
---|
1598 | func_eq (char* o, char **argv, char *funcname) |
---|
1599 | { |
---|
1600 | int result = ! strcmp (argv[0], argv[1]); |
---|
1601 | o = variable_buffer_output (o, result ? "1" : "", result); |
---|
1602 | return o; |
---|
1603 | } |
---|
1604 | |
---|
1605 | |
---|
1606 | /* |
---|
1607 | string-boolean not operator. |
---|
1608 | */ |
---|
1609 | static char * |
---|
1610 | func_not (char* o, char **argv, char *funcname) |
---|
1611 | { |
---|
1612 | char * s = argv[0]; |
---|
1613 | int result = 0; |
---|
1614 | while (isspace ((unsigned char)*s)) |
---|
1615 | s++; |
---|
1616 | result = ! (*s); |
---|
1617 | o = variable_buffer_output (o, result ? "1" : "", result); |
---|
1618 | return o; |
---|
1619 | } |
---|
1620 | #endif |
---|
1621 | |
---|
1622 | |
---|
1623 | #define STRING_SIZE_TUPLE(_s) (_s), (sizeof (_s)-1) |
---|
1624 | |
---|
1625 | /* Lookup table for builtin functions. |
---|
1626 | |
---|
1627 | This doesn't have to be sorted; we use a straight lookup. We might gain |
---|
1628 | some efficiency by moving most often used functions to the start of the |
---|
1629 | table. |
---|
1630 | |
---|
1631 | If MAXIMUM_ARGS is 0, that means there is no maximum and all |
---|
1632 | comma-separated values are treated as arguments. |
---|
1633 | |
---|
1634 | EXPAND_ARGS means that all arguments should be expanded before invocation. |
---|
1635 | Functions that do namespace tricks (foreach) don't automatically expand. */ |
---|
1636 | |
---|
1637 | static char *func_call PARAMS ((char *o, char **argv, const char *funcname)); |
---|
1638 | |
---|
1639 | |
---|
1640 | static struct function_table_entry function_table[] = |
---|
1641 | { |
---|
1642 | /* Name/size */ /* MIN MAX EXP? Function */ |
---|
1643 | { STRING_SIZE_TUPLE("addprefix"), 2, 2, 1, func_addsuffix_addprefix}, |
---|
1644 | { STRING_SIZE_TUPLE("addsuffix"), 2, 2, 1, func_addsuffix_addprefix}, |
---|
1645 | { STRING_SIZE_TUPLE("basename"), 0, 1, 1, func_basename_dir}, |
---|
1646 | { STRING_SIZE_TUPLE("dir"), 0, 1, 1, func_basename_dir}, |
---|
1647 | { STRING_SIZE_TUPLE("notdir"), 0, 1, 1, func_notdir_suffix}, |
---|
1648 | { STRING_SIZE_TUPLE("subst"), 3, 3, 1, func_subst}, |
---|
1649 | { STRING_SIZE_TUPLE("suffix"), 0, 1, 1, func_notdir_suffix}, |
---|
1650 | { STRING_SIZE_TUPLE("filter"), 2, 2, 1, func_filter_filterout}, |
---|
1651 | { STRING_SIZE_TUPLE("filter-out"), 2, 2, 1, func_filter_filterout}, |
---|
1652 | { STRING_SIZE_TUPLE("findstring"), 2, 2, 1, func_findstring}, |
---|
1653 | { STRING_SIZE_TUPLE("firstword"), 0, 1, 1, func_firstword}, |
---|
1654 | { STRING_SIZE_TUPLE("join"), 2, 2, 1, func_join}, |
---|
1655 | { STRING_SIZE_TUPLE("patsubst"), 3, 3, 1, func_patsubst}, |
---|
1656 | { STRING_SIZE_TUPLE("shell"), 0, 1, 1, func_shell}, |
---|
1657 | { STRING_SIZE_TUPLE("sort"), 0, 1, 1, func_sort}, |
---|
1658 | { STRING_SIZE_TUPLE("strip"), 0, 1, 1, func_strip}, |
---|
1659 | { STRING_SIZE_TUPLE("wildcard"), 0, 1, 1, func_wildcard}, |
---|
1660 | { STRING_SIZE_TUPLE("word"), 2, 2, 1, func_word}, |
---|
1661 | { STRING_SIZE_TUPLE("wordlist"), 3, 3, 1, func_wordlist}, |
---|
1662 | { STRING_SIZE_TUPLE("words"), 0, 1, 1, func_words}, |
---|
1663 | { STRING_SIZE_TUPLE("origin"), 0, 1, 1, func_origin}, |
---|
1664 | { STRING_SIZE_TUPLE("foreach"), 3, 3, 0, func_foreach}, |
---|
1665 | { STRING_SIZE_TUPLE("call"), 1, 0, 1, func_call}, |
---|
1666 | { STRING_SIZE_TUPLE("error"), 0, 1, 1, func_error}, |
---|
1667 | { STRING_SIZE_TUPLE("warning"), 0, 1, 1, func_error}, |
---|
1668 | { STRING_SIZE_TUPLE("if"), 2, 3, 0, func_if}, |
---|
1669 | #ifdef EXPERIMENTAL |
---|
1670 | { STRING_SIZE_TUPLE("eq"), 2, 2, 1, func_eq}, |
---|
1671 | { STRING_SIZE_TUPLE("not"), 0, 1, 1, func_not}, |
---|
1672 | #endif |
---|
1673 | { 0 } |
---|
1674 | }; |
---|
1675 | |
---|
1676 | |
---|
1677 | /* These must come after the definition of function_table[]. */ |
---|
1678 | |
---|
1679 | static char * |
---|
1680 | expand_builtin_function (o, argc, argv, entry_p) |
---|
1681 | char *o; |
---|
1682 | int argc; |
---|
1683 | char **argv; |
---|
1684 | struct function_table_entry *entry_p; |
---|
1685 | { |
---|
1686 | if (argc < entry_p->minimum_args) |
---|
1687 | fatal (reading_file, |
---|
1688 | _("Insufficient number of arguments (%d) to function `%s'"), |
---|
1689 | argc, entry_p->name); |
---|
1690 | |
---|
1691 | /* I suppose technically some function could do something with no |
---|
1692 | arguments, but so far none do, so just test it for all functions here |
---|
1693 | rather than in each one. We can change it later if necessary. */ |
---|
1694 | |
---|
1695 | if (!argc) |
---|
1696 | return o; |
---|
1697 | |
---|
1698 | if (!entry_p->func_ptr) |
---|
1699 | fatal (reading_file, _("Unimplemented on this platform: function `%s'"), |
---|
1700 | entry_p->name); |
---|
1701 | |
---|
1702 | return entry_p->func_ptr (o, argv, entry_p->name); |
---|
1703 | } |
---|
1704 | |
---|
1705 | /* Check for a function invocation in *STRINGP. *STRINGP points at the |
---|
1706 | opening ( or { and is not null-terminated. If a function invocation |
---|
1707 | is found, expand it into the buffer at *OP, updating *OP, incrementing |
---|
1708 | *STRINGP past the reference and returning nonzero. If not, return zero. */ |
---|
1709 | |
---|
1710 | int |
---|
1711 | handle_function (op, stringp) |
---|
1712 | char **op; |
---|
1713 | char **stringp; |
---|
1714 | { |
---|
1715 | const struct function_table_entry *entry_p; |
---|
1716 | char openparen = (*stringp)[0]; |
---|
1717 | char closeparen = openparen == '(' ? ')' : '}'; |
---|
1718 | char *beg; |
---|
1719 | char *end; |
---|
1720 | int count = 0; |
---|
1721 | register char *p; |
---|
1722 | char **argv, **argvp; |
---|
1723 | int nargs; |
---|
1724 | |
---|
1725 | beg = *stringp + 1; |
---|
1726 | |
---|
1727 | entry_p = lookup_function (function_table, beg); |
---|
1728 | |
---|
1729 | if (!entry_p) |
---|
1730 | return 0; |
---|
1731 | |
---|
1732 | /* We found a builtin function. Find the beginning of its arguments (skip |
---|
1733 | whitespace after the name). */ |
---|
1734 | |
---|
1735 | beg = next_token (beg + entry_p->len); |
---|
1736 | |
---|
1737 | /* Find the end of the function invocation, counting nested use of |
---|
1738 | whichever kind of parens we use. Since we're looking, count commas |
---|
1739 | to get a rough estimate of how many arguments we might have. The |
---|
1740 | count might be high, but it'll never be low. */ |
---|
1741 | |
---|
1742 | for (nargs=1, end=beg; *end != '\0'; ++end) |
---|
1743 | if (*end == ',') |
---|
1744 | ++nargs; |
---|
1745 | else if (*end == openparen) |
---|
1746 | ++count; |
---|
1747 | else if (*end == closeparen && --count < 0) |
---|
1748 | break; |
---|
1749 | |
---|
1750 | if (count >= 0) |
---|
1751 | fatal (reading_file, |
---|
1752 | _("unterminated call to function `%s': missing `%c'"), |
---|
1753 | entry_p->name, closeparen); |
---|
1754 | |
---|
1755 | *stringp = end; |
---|
1756 | |
---|
1757 | /* Get some memory to store the arg pointers. */ |
---|
1758 | argvp = argv = (char **) alloca (sizeof (char *) * (nargs + 2)); |
---|
1759 | |
---|
1760 | /* Chop the string into arguments, then a nul. As soon as we hit |
---|
1761 | MAXIMUM_ARGS (if it's >0) assume the rest of the string is part of the |
---|
1762 | last argument. |
---|
1763 | |
---|
1764 | If we're expanding, store pointers to the expansion of each one. If |
---|
1765 | not, make a duplicate of the string and point into that, nul-terminating |
---|
1766 | each argument. */ |
---|
1767 | |
---|
1768 | if (!entry_p->expand_args) |
---|
1769 | { |
---|
1770 | int len = end - beg; |
---|
1771 | |
---|
1772 | p = xmalloc (len+1); |
---|
1773 | memcpy (p, beg, len); |
---|
1774 | p[len] = '\0'; |
---|
1775 | beg = p; |
---|
1776 | end = beg + len; |
---|
1777 | } |
---|
1778 | |
---|
1779 | for (p=beg, nargs=0; p <= end; ++argvp) |
---|
1780 | { |
---|
1781 | char *next; |
---|
1782 | |
---|
1783 | ++nargs; |
---|
1784 | |
---|
1785 | if (nargs == entry_p->maximum_args |
---|
1786 | || (! (next = find_next_argument (openparen, closeparen, p, end)))) |
---|
1787 | next = end; |
---|
1788 | |
---|
1789 | if (entry_p->expand_args) |
---|
1790 | *argvp = expand_argument (p, next); |
---|
1791 | else |
---|
1792 | { |
---|
1793 | *argvp = p; |
---|
1794 | *next = '\0'; |
---|
1795 | } |
---|
1796 | |
---|
1797 | p = next + 1; |
---|
1798 | } |
---|
1799 | *argvp = NULL; |
---|
1800 | |
---|
1801 | /* Finally! Run the function... */ |
---|
1802 | *op = expand_builtin_function (*op, nargs, argv, entry_p); |
---|
1803 | |
---|
1804 | /* Free memory. */ |
---|
1805 | if (entry_p->expand_args) |
---|
1806 | for (argvp=argv; *argvp != 0; ++argvp) |
---|
1807 | free (*argvp); |
---|
1808 | else |
---|
1809 | free (beg); |
---|
1810 | |
---|
1811 | return 1; |
---|
1812 | } |
---|
1813 | |
---|
1814 | |
---|
1815 | /* User-defined functions. Expand the first argument as either a builtin |
---|
1816 | function or a make variable, in the context of the rest of the arguments |
---|
1817 | assigned to $1, $2, ... $N. $0 is the name of the function. */ |
---|
1818 | |
---|
1819 | static char * |
---|
1820 | func_call (o, argv, funcname) |
---|
1821 | char *o; |
---|
1822 | char **argv; |
---|
1823 | const char *funcname; |
---|
1824 | { |
---|
1825 | char *fname; |
---|
1826 | char *cp; |
---|
1827 | int flen; |
---|
1828 | char *body; |
---|
1829 | int i; |
---|
1830 | const struct function_table_entry *entry_p; |
---|
1831 | |
---|
1832 | /* There is no way to define a variable with a space in the name, so strip |
---|
1833 | leading and trailing whitespace as a favor to the user. */ |
---|
1834 | fname = argv[0]; |
---|
1835 | while (*fname != '\0' && isspace ((unsigned char)*fname)) |
---|
1836 | ++fname; |
---|
1837 | |
---|
1838 | cp = fname + strlen (fname) - 1; |
---|
1839 | while (cp > fname && isspace ((unsigned char)*cp)) |
---|
1840 | --cp; |
---|
1841 | cp[1] = '\0'; |
---|
1842 | |
---|
1843 | /* Calling nothing is a no-op */ |
---|
1844 | if (*fname == '\0') |
---|
1845 | return o; |
---|
1846 | |
---|
1847 | /* Are we invoking a builtin function? */ |
---|
1848 | |
---|
1849 | entry_p = lookup_function (function_table, fname); |
---|
1850 | |
---|
1851 | if (entry_p) |
---|
1852 | { |
---|
1853 | /* How many arguments do we have? */ |
---|
1854 | for (i=0; argv[i+1]; ++i) |
---|
1855 | ; |
---|
1856 | |
---|
1857 | return expand_builtin_function (o, i, argv+1, entry_p); |
---|
1858 | } |
---|
1859 | |
---|
1860 | /* Not a builtin, so the first argument is the name of a variable to be |
---|
1861 | expanded and interpreted as a function. Create the variable |
---|
1862 | reference. */ |
---|
1863 | flen = strlen (fname); |
---|
1864 | |
---|
1865 | body = alloca (flen + 4); |
---|
1866 | body[0] = '$'; |
---|
1867 | body[1] = '('; |
---|
1868 | memcpy (body + 2, fname, flen); |
---|
1869 | body[flen+2] = ')'; |
---|
1870 | body[flen+3] = '\0'; |
---|
1871 | |
---|
1872 | /* Set up arguments $(1) .. $(N). $(0) is the function name. */ |
---|
1873 | |
---|
1874 | push_new_variable_scope (); |
---|
1875 | |
---|
1876 | for (i=0; *argv; ++i, ++argv) |
---|
1877 | { |
---|
1878 | char num[11]; |
---|
1879 | |
---|
1880 | sprintf (num, "%d", i); |
---|
1881 | define_variable (num, strlen (num), *argv, o_automatic, 1); |
---|
1882 | } |
---|
1883 | |
---|
1884 | /* Expand the body in the context of the arguments, adding the result to |
---|
1885 | the variable buffer. */ |
---|
1886 | |
---|
1887 | o = variable_expand_string (o, body, flen+3); |
---|
1888 | |
---|
1889 | pop_variable_scope (); |
---|
1890 | |
---|
1891 | return o + strlen (o); |
---|
1892 | } |
---|