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