VirtualBox

source: kBuild/trunk/src/kmk/function.c@ 2163

Last change on this file since 2163 was 2163, checked in by bird, 16 years ago

kmk: Added a $(select ) function for handling switch like stuff. Fixes #74.

  • Property svn:eol-style set to native
File size: 146.3 KB
Line 
1/* Builtin function expansion for GNU Make.
2Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
31998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software
4Foundation, Inc.
5This file is part of GNU Make.
6
7GNU Make is free software; you can redistribute it and/or modify it under the
8terms of the GNU General Public License as published by the Free Software
9Foundation; either version 3 of the License, or (at your option) any later
10version.
11
12GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License along with
17this program. If not, see <http://www.gnu.org/licenses/>. */
18
19#include "make.h"
20#include "filedef.h"
21#include "variable.h"
22#include "dep.h"
23#include "job.h"
24#include "commands.h"
25#include "debug.h"
26
27#ifdef _AMIGA
28#include "amiga.h"
29#endif
30
31#ifdef WINDOWS32 /* bird */
32# include "pathstuff.h"
33#endif
34
35#ifdef KMK_HELPERS
36# include "kbuild.h"
37#endif
38#ifdef CONFIG_WITH_PRINTF
39# include "kmkbuiltin.h"
40#endif
41#ifdef CONFIG_WITH_XARGS /* bird */
42# ifdef HAVE_LIMITS_H
43# include <limits.h>
44# endif
45#endif
46#include <assert.h> /* bird */
47
48#if defined (CONFIG_WITH_MATH) || defined (CONFIG_WITH_NANOTS) || defined (CONFIG_WITH_FILE_SIZE) /* bird */
49# include <ctype.h>
50typedef big_int math_int;
51static char *math_int_to_variable_buffer (char *, math_int);
52static math_int math_int_from_string (const char *str);
53#endif
54
55#ifdef CONFIG_WITH_NANOTS /* bird */
56# ifdef WINDOWS32
57# include <Windows.h>
58# endif
59#endif
60
61#ifdef __OS2__
62# define CONFIG_WITH_OS2_LIBPATH 1
63#endif
64#ifdef CONFIG_WITH_OS2_LIBPATH
65# define INCL_BASE
66# define INCL_ERRROS
67# include <os2.h>
68
69# define QHINF_EXEINFO 1 /* NE exeinfo. */
70# define QHINF_READRSRCTBL 2 /* Reads from the resource table. */
71# define QHINF_READFILE 3 /* Reads from the executable file. */
72# define QHINF_LIBPATHLENGTH 4 /* Gets the libpath length. */
73# define QHINF_LIBPATH 5 /* Gets the entire libpath. */
74# define QHINF_FIXENTRY 6 /* NE only */
75# define QHINF_STE 7 /* NE only */
76# define QHINF_MAPSEL 8 /* NE only */
77 extern APIRET APIENTRY DosQueryHeaderInfo(HMODULE hmod, ULONG ulIndex, PVOID pvBuffer, ULONG cbBuffer, ULONG ulSubFunction);
78#endif /* CONFIG_WITH_OS2_LIBPATH */
79
80
81struct function_table_entry
82 {
83 const char *name;
84 unsigned char len;
85 unsigned char minimum_args;
86 unsigned char maximum_args;
87 char expand_args;
88 char *(*func_ptr) (char *output, char **argv, const char *fname);
89 };
90
91static unsigned long
92function_table_entry_hash_1 (const void *keyv)
93{
94 const struct function_table_entry *key = keyv;
95 return_STRING_N_HASH_1 (key->name, key->len);
96}
97
98static unsigned long
99function_table_entry_hash_2 (const void *keyv)
100{
101 const struct function_table_entry *key = keyv;
102 return_STRING_N_HASH_2 (key->name, key->len);
103}
104
105static int
106function_table_entry_hash_cmp (const void *xv, const void *yv)
107{
108 const struct function_table_entry *x = xv;
109 const struct function_table_entry *y = yv;
110 int result = x->len - y->len;
111 if (result)
112 return result;
113 return_STRING_N_COMPARE (x->name, y->name, x->len);
114}
115
116static struct hash_table function_table;
117
118#ifdef CONFIG_WITH_MAKE_STATS
119long make_stats_allocations = 0;
120long make_stats_reallocations = 0;
121unsigned long make_stats_allocated = 0;
122unsigned long make_stats_ht_lookups = 0;
123unsigned long make_stats_ht_collisions = 0;
124#endif
125
126
127
128/* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing
129 each occurrence of SUBST with REPLACE. TEXT is null-terminated. SLEN is
130 the length of SUBST and RLEN is the length of REPLACE. If BY_WORD is
131 nonzero, substitutions are done only on matches which are complete
132 whitespace-delimited words. */
133
134char *
135subst_expand (char *o, const char *text, const char *subst, const char *replace,
136 unsigned int slen, unsigned int rlen, int by_word)
137{
138 const char *t = text;
139 const char *p;
140
141 if (slen == 0 && !by_word)
142 {
143 /* The first occurrence of "" in any string is its end. */
144 o = variable_buffer_output (o, t, strlen (t));
145 if (rlen > 0)
146 o = variable_buffer_output (o, replace, rlen);
147 return o;
148 }
149
150 do
151 {
152 if (by_word && slen == 0)
153 /* When matching by words, the empty string should match
154 the end of each word, rather than the end of the whole text. */
155 p = end_of_token (next_token (t));
156 else
157 {
158 p = strstr (t, subst);
159 if (p == 0)
160 {
161 /* No more matches. Output everything left on the end. */
162 o = variable_buffer_output (o, t, strlen (t));
163 return o;
164 }
165 }
166
167 /* Output everything before this occurrence of the string to replace. */
168 if (p > t)
169 o = variable_buffer_output (o, t, p - t);
170
171 /* If we're substituting only by fully matched words,
172 or only at the ends of words, check that this case qualifies. */
173 if (by_word
174 && ((p > text && !isblank ((unsigned char)p[-1]))
175 || (p[slen] != '\0' && !isblank ((unsigned char)p[slen]))))
176 /* Struck out. Output the rest of the string that is
177 no longer to be replaced. */
178 o = variable_buffer_output (o, subst, slen);
179 else if (rlen > 0)
180 /* Output the replacement string. */
181 o = variable_buffer_output (o, replace, rlen);
182
183 /* Advance T past the string to be replaced. */
184 t = p + slen;
185 } while (*t != '\0');
186
187 return o;
188}
189
190
191
192/* Store into VARIABLE_BUFFER at O the result of scanning TEXT
193 and replacing strings matching PATTERN with REPLACE.
194 If PATTERN_PERCENT is not nil, PATTERN has already been
195 run through find_percent, and PATTERN_PERCENT is the result.
196 If REPLACE_PERCENT is not nil, REPLACE has already been
197 run through find_percent, and REPLACE_PERCENT is the result.
198 Note that we expect PATTERN_PERCENT and REPLACE_PERCENT to point to the
199 character _AFTER_ the %, not to the % itself.
200*/
201
202char *
203patsubst_expand_pat (char *o, const char *text,
204 const char *pattern, const char *replace,
205 const char *pattern_percent, const char *replace_percent)
206{
207 unsigned int pattern_prepercent_len, pattern_postpercent_len;
208 unsigned int replace_prepercent_len, replace_postpercent_len;
209 const char *t;
210 unsigned int len;
211 int doneany = 0;
212
213 /* Record the length of REPLACE before and after the % so we don't have to
214 compute these lengths more than once. */
215 if (replace_percent)
216 {
217 replace_prepercent_len = replace_percent - replace - 1;
218 replace_postpercent_len = strlen (replace_percent);
219 }
220 else
221 {
222 replace_prepercent_len = strlen (replace);
223 replace_postpercent_len = 0;
224 }
225
226 if (!pattern_percent)
227 /* With no % in the pattern, this is just a simple substitution. */
228 return subst_expand (o, text, pattern, replace,
229 strlen (pattern), strlen (replace), 1);
230
231 /* Record the length of PATTERN before and after the %
232 so we don't have to compute it more than once. */
233 pattern_prepercent_len = pattern_percent - pattern - 1;
234 pattern_postpercent_len = strlen (pattern_percent);
235
236 while ((t = find_next_token (&text, &len)) != 0)
237 {
238 int fail = 0;
239
240 /* Is it big enough to match? */
241 if (len < pattern_prepercent_len + pattern_postpercent_len)
242 fail = 1;
243
244 /* Does the prefix match? */
245 if (!fail && pattern_prepercent_len > 0
246 && (*t != *pattern
247 || t[pattern_prepercent_len - 1] != pattern_percent[-2]
248 || !strneq (t + 1, pattern + 1, pattern_prepercent_len - 1)))
249 fail = 1;
250
251 /* Does the suffix match? */
252 if (!fail && pattern_postpercent_len > 0
253 && (t[len - 1] != pattern_percent[pattern_postpercent_len - 1]
254 || t[len - pattern_postpercent_len] != *pattern_percent
255 || !strneq (&t[len - pattern_postpercent_len],
256 pattern_percent, pattern_postpercent_len - 1)))
257 fail = 1;
258
259 if (fail)
260 /* It didn't match. Output the string. */
261 o = variable_buffer_output (o, t, len);
262 else
263 {
264 /* It matched. Output the replacement. */
265
266 /* Output the part of the replacement before the %. */
267 o = variable_buffer_output (o, replace, replace_prepercent_len);
268
269 if (replace_percent != 0)
270 {
271 /* Output the part of the matched string that
272 matched the % in the pattern. */
273 o = variable_buffer_output (o, t + pattern_prepercent_len,
274 len - (pattern_prepercent_len
275 + pattern_postpercent_len));
276 /* Output the part of the replacement after the %. */
277 o = variable_buffer_output (o, replace_percent,
278 replace_postpercent_len);
279 }
280 }
281
282 /* Output a space, but not if the replacement is "". */
283 if (fail || replace_prepercent_len > 0
284 || (replace_percent != 0 && len + replace_postpercent_len > 0))
285 {
286 o = variable_buffer_output (o, " ", 1);
287 doneany = 1;
288 }
289 }
290#ifndef CONFIG_WITH_VALUE_LENGTH
291 if (doneany)
292 /* Kill the last space. */
293 --o;
294#else
295 /* Kill the last space and make sure there is a terminator there
296 so that strcache_add_len doesn't have to do a lot of exacty work
297 when expand_deps sends the output its way. */
298 if (doneany)
299 *--o = '\0';
300 else
301 o = variable_buffer_output (o, "\0", 1) - 1;
302#endif
303
304 return o;
305}
306
307/* Store into VARIABLE_BUFFER at O the result of scanning TEXT
308 and replacing strings matching PATTERN with REPLACE.
309 If PATTERN_PERCENT is not nil, PATTERN has already been
310 run through find_percent, and PATTERN_PERCENT is the result.
311 If REPLACE_PERCENT is not nil, REPLACE has already been
312 run through find_percent, and REPLACE_PERCENT is the result.
313 Note that we expect PATTERN_PERCENT and REPLACE_PERCENT to point to the
314 character _AFTER_ the %, not to the % itself.
315*/
316
317char *
318patsubst_expand (char *o, const char *text, char *pattern, char *replace)
319{
320 const char *pattern_percent = find_percent (pattern);
321 const char *replace_percent = find_percent (replace);
322
323 /* If there's a percent in the pattern or replacement skip it. */
324 if (replace_percent)
325 ++replace_percent;
326 if (pattern_percent)
327 ++pattern_percent;
328
329 return patsubst_expand_pat (o, text, pattern, replace,
330 pattern_percent, replace_percent);
331}
332
333
334#if defined (CONFIG_WITH_OPTIMIZATION_HACKS) || defined (CONFIG_WITH_VALUE_LENGTH)
335
336/* Char map containing the valid function name characters. */
337char func_char_map[256];
338
339/* Do the hash table lookup. */
340
341MY_INLINE const struct function_table_entry *
342lookup_function_in_hash_tab (const char *s, unsigned char len)
343{
344 struct function_table_entry function_table_entry_key;
345 function_table_entry_key.name = s;
346 function_table_entry_key.len = len;
347
348 return hash_find_item (&function_table, &function_table_entry_key);
349}
350
351/* Look up a function by name. */
352
353MY_INLINE const struct function_table_entry *
354lookup_function (const char *s, unsigned int len)
355{
356 unsigned char ch;
357# if 0 /* insane loop unroll */
358
359 if (len > MAX_FUNCTION_LENGTH)
360 len = MAX_FUNCTION_LENGTH + 1;
361
362# define X(idx) \
363 if (!func_char_map[ch = s[idx]]) \
364 { \
365 if (isblank (ch)) \
366 return lookup_function_in_hash_tab (s, idx); \
367 return 0; \
368 }
369# define Z(idx) \
370 return lookup_function_in_hash_tab (s, idx);
371
372 switch (len)
373 {
374 default:
375 assert (0);
376 case 0: return 0;
377 case 1: return 0;
378 case 2: X(0); X(1); Z(2);
379 case 3: X(0); X(1); X(2); Z(3);
380 case 4: X(0); X(1); X(2); X(3); Z(4);
381 case 5: X(0); X(1); X(2); X(3); X(4); Z(5);
382 case 6: X(0); X(1); X(2); X(3); X(4); X(5); Z(6);
383 case 7: X(0); X(1); X(2); X(3); X(4); X(5); X(6); Z(7);
384 case 8: X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); Z(8);
385 case 9: X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); X(8); Z(9);
386 case 10: X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); X(8); X(9); Z(10);
387 case 11: X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); X(8); X(9); X(10); Z(11);
388 case 12: X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); X(8); X(9); X(10); X(11); Z(12);
389 case 13: X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); X(8); X(9); X(10); X(11); X(12);
390 if ((ch = s[12]) == '\0' || isblank (ch))
391 return lookup_function_in_hash_tab (s, 12);
392 return 0;
393 }
394# undef Z
395# undef X
396
397# else /* normal loop */
398 const char *e = s;
399 if (len > MAX_FUNCTION_LENGTH)
400 len = MAX_FUNCTION_LENGTH;
401 while (func_char_map[ch = *e])
402 {
403 if (!len--)
404 return 0;
405 e++;
406 }
407 if (ch == '\0' || isblank (ch))
408 return lookup_function_in_hash_tab (s, e - s);
409 return 0;
410# endif /* normal loop */
411}
412
413#else /* original code */
414/* Look up a function by name. */
415
416static const struct function_table_entry *
417lookup_function (const char *s)
418{
419 const char *e = s;
420 while (*e && ( (*e >= 'a' && *e <= 'z') || *e == '-'))
421 e++;
422 if (*e == '\0' || isblank ((unsigned char) *e))
423 {
424 struct function_table_entry function_table_entry_key;
425 function_table_entry_key.name = s;
426 function_table_entry_key.len = e - s;
427
428 return hash_find_item (&function_table, &function_table_entry_key);
429 }
430 return 0;
431}
432#endif /* original code */
433
434
435
436/* Return 1 if PATTERN matches STR, 0 if not. */
437
438int
439pattern_matches (const char *pattern, const char *percent, const char *str)
440{
441 unsigned int sfxlen, strlength;
442
443 if (percent == 0)
444 {
445 unsigned int len = strlen (pattern) + 1;
446 char *new_chars = alloca (len);
447 memcpy (new_chars, pattern, len);
448 percent = find_percent (new_chars);
449 if (percent == 0)
450 return streq (new_chars, str);
451 pattern = new_chars;
452 }
453
454 sfxlen = strlen (percent + 1);
455 strlength = strlen (str);
456
457 if (strlength < (percent - pattern) + sfxlen
458 || !strneq (pattern, str, percent - pattern))
459 return 0;
460
461 return !strcmp (percent + 1, str + (strlength - sfxlen));
462}
463
464
465
466/* Find the next comma or ENDPAREN (counting nested STARTPAREN and
467 ENDPARENtheses), starting at PTR before END. Return a pointer to
468 next character.
469
470 If no next argument is found, return NULL.
471*/
472
473static char *
474find_next_argument (char startparen, char endparen,
475 const char *ptr, const char *end)
476{
477 int count = 0;
478
479 for (; ptr < end; ++ptr)
480 if (*ptr == startparen)
481 ++count;
482
483 else if (*ptr == endparen)
484 {
485 --count;
486 if (count < 0)
487 return NULL;
488 }
489
490 else if (*ptr == ',' && !count)
491 return (char *)ptr;
492
493 /* We didn't find anything. */
494 return NULL;
495}
496
497
498
499/* Glob-expand LINE. The returned pointer is
500 only good until the next call to string_glob. */
501
502static char *
503string_glob (char *line)
504{
505 static char *result = 0;
506 static unsigned int length;
507 struct nameseq *chain;
508 unsigned int idx;
509
510#ifndef CONFIG_WITH_ALLOC_CACHES
511 chain = multi_glob (parse_file_seq
512 (&line, '\0', sizeof (struct nameseq),
513 /* We do not want parse_file_seq to strip `./'s.
514 That would break examples like:
515 $(patsubst ./%.c,obj/%.o,$(wildcard ./?*.c)). */
516 0),
517 sizeof (struct nameseq));
518#else /* CONFIG_WITH_ALLOC_CACHES */
519 chain = multi_glob (parse_file_seq
520 (&line, '\0', &nameseq_cache,
521 /* We do not want parse_file_seq to strip `./'s.
522 That would break examples like:
523 $(patsubst ./%.c,obj/%.o,$(wildcard ./?*.c)). */
524 0),
525 &nameseq_cache);
526#endif /* CONFIG_WITH_ALLOC_CACHES */
527
528 if (result == 0)
529 {
530 length = 100;
531 result = xmalloc (100);
532 }
533
534 idx = 0;
535 while (chain != 0)
536 {
537 const char *name = chain->name;
538 unsigned int len = strlen (name);
539
540 struct nameseq *next = chain->next;
541#ifndef CONFIG_WITH_ALLOC_CACHES
542 free (chain);
543#else
544 alloccache_free (&nameseq_cache, chain);
545#endif
546 chain = next;
547
548 /* multi_glob will pass names without globbing metacharacters
549 through as is, but we want only files that actually exist. */
550 if (file_exists_p (name))
551 {
552 if (idx + len + 1 > length)
553 {
554 length += (len + 1) * 2;
555 result = xrealloc (result, length);
556 }
557 memcpy (&result[idx], name, len);
558 idx += len;
559 result[idx++] = ' ';
560 }
561 }
562
563 /* Kill the last space and terminate the string. */
564 if (idx == 0)
565 result[0] = '\0';
566 else
567 result[idx - 1] = '\0';
568
569 return result;
570}
571
572
573/*
574 Builtin functions
575 */
576
577static char *
578func_patsubst (char *o, char **argv, const char *funcname UNUSED)
579{
580 o = patsubst_expand (o, argv[2], argv[0], argv[1]);
581 return o;
582}
583
584
585static char *
586func_join (char *o, char **argv, const char *funcname UNUSED)
587{
588 int doneany = 0;
589
590 /* Write each word of the first argument directly followed
591 by the corresponding word of the second argument.
592 If the two arguments have a different number of words,
593 the excess words are just output separated by blanks. */
594 const char *tp;
595 const char *pp;
596 const char *list1_iterator = argv[0];
597 const char *list2_iterator = argv[1];
598 do
599 {
600 unsigned int len1, len2;
601
602 tp = find_next_token (&list1_iterator, &len1);
603 if (tp != 0)
604 o = variable_buffer_output (o, tp, len1);
605
606 pp = find_next_token (&list2_iterator, &len2);
607 if (pp != 0)
608 o = variable_buffer_output (o, pp, len2);
609
610 if (tp != 0 || pp != 0)
611 {
612 o = variable_buffer_output (o, " ", 1);
613 doneany = 1;
614 }
615 }
616 while (tp != 0 || pp != 0);
617 if (doneany)
618 /* Kill the last blank. */
619 --o;
620
621 return o;
622}
623
624
625static char *
626func_origin (char *o, char **argv, const char *funcname UNUSED)
627{
628 /* Expand the argument. */
629 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
630 if (v == 0)
631 o = variable_buffer_output (o, "undefined", 9);
632 else
633 switch (v->origin)
634 {
635 default:
636 case o_invalid:
637 abort ();
638 break;
639 case o_default:
640 o = variable_buffer_output (o, "default", 7);
641 break;
642 case o_env:
643 o = variable_buffer_output (o, "environment", 11);
644 break;
645 case o_file:
646 o = variable_buffer_output (o, "file", 4);
647 break;
648 case o_env_override:
649 o = variable_buffer_output (o, "environment override", 20);
650 break;
651 case o_command:
652 o = variable_buffer_output (o, "command line", 12);
653 break;
654 case o_override:
655 o = variable_buffer_output (o, "override", 8);
656 break;
657 case o_automatic:
658 o = variable_buffer_output (o, "automatic", 9);
659 break;
660#ifdef CONFIG_WITH_LOCAL_VARIABLES
661 case o_local:
662 o = variable_buffer_output (o, "local", 5);
663 break;
664#endif
665 }
666
667 return o;
668}
669
670static char *
671func_flavor (char *o, char **argv, const char *funcname UNUSED)
672{
673 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
674
675 if (v == 0)
676 o = variable_buffer_output (o, "undefined", 9);
677 else
678 if (v->recursive)
679 o = variable_buffer_output (o, "recursive", 9);
680 else
681 o = variable_buffer_output (o, "simple", 6);
682
683 return o;
684}
685
686#ifdef VMS
687# define IS_PATHSEP(c) ((c) == ']')
688#else
689# ifdef HAVE_DOS_PATHS
690# define IS_PATHSEP(c) ((c) == '/' || (c) == '\\')
691# else
692# define IS_PATHSEP(c) ((c) == '/')
693# endif
694#endif
695
696
697static char *
698func_notdir_suffix (char *o, char **argv, const char *funcname)
699{
700 /* Expand the argument. */
701 const char *list_iterator = argv[0];
702 const char *p2;
703 int doneany =0;
704 unsigned int len=0;
705
706 int is_suffix = streq (funcname, "suffix");
707 int is_notdir = !is_suffix;
708 while ((p2 = find_next_token (&list_iterator, &len)) != 0)
709 {
710 const char *p = p2 + len;
711
712
713 while (p >= p2 && (!is_suffix || *p != '.'))
714 {
715 if (IS_PATHSEP (*p))
716 break;
717 --p;
718 }
719
720 if (p >= p2)
721 {
722 if (is_notdir)
723 ++p;
724 else if (*p != '.')
725 continue;
726 o = variable_buffer_output (o, p, len - (p - p2));
727 }
728#ifdef HAVE_DOS_PATHS
729 /* Handle the case of "d:foo/bar". */
730 else if (streq (funcname, "notdir") && p2[0] && p2[1] == ':')
731 {
732 p = p2 + 2;
733 o = variable_buffer_output (o, p, len - (p - p2));
734 }
735#endif
736 else if (is_notdir)
737 o = variable_buffer_output (o, p2, len);
738
739 if (is_notdir || p >= p2)
740 {
741 o = variable_buffer_output (o, " ", 1);
742 doneany = 1;
743 }
744 }
745
746 if (doneany)
747 /* Kill last space. */
748 --o;
749
750 return o;
751}
752
753
754static char *
755func_basename_dir (char *o, char **argv, const char *funcname)
756{
757 /* Expand the argument. */
758 const char *p3 = argv[0];
759 const char *p2;
760 int doneany=0;
761 unsigned int len=0;
762
763 int is_basename= streq (funcname, "basename");
764 int is_dir= !is_basename;
765
766 while ((p2 = find_next_token (&p3, &len)) != 0)
767 {
768 const char *p = p2 + len;
769 while (p >= p2 && (!is_basename || *p != '.'))
770 {
771 if (IS_PATHSEP (*p))
772 break;
773 --p;
774 }
775
776 if (p >= p2 && (is_dir))
777 o = variable_buffer_output (o, p2, ++p - p2);
778 else if (p >= p2 && (*p == '.'))
779 o = variable_buffer_output (o, p2, p - p2);
780#ifdef HAVE_DOS_PATHS
781 /* Handle the "d:foobar" case */
782 else if (p2[0] && p2[1] == ':' && is_dir)
783 o = variable_buffer_output (o, p2, 2);
784#endif
785 else if (is_dir)
786#ifdef VMS
787 o = variable_buffer_output (o, "[]", 2);
788#else
789#ifndef _AMIGA
790 o = variable_buffer_output (o, "./", 2);
791#else
792 ; /* Just a nop... */
793#endif /* AMIGA */
794#endif /* !VMS */
795 else
796 /* The entire name is the basename. */
797 o = variable_buffer_output (o, p2, len);
798
799 o = variable_buffer_output (o, " ", 1);
800 doneany = 1;
801 }
802
803 if (doneany)
804 /* Kill last space. */
805 --o;
806
807 return o;
808}
809
810static char *
811func_addsuffix_addprefix (char *o, char **argv, const char *funcname)
812{
813 int fixlen = strlen (argv[0]);
814 const char *list_iterator = argv[1];
815 int is_addprefix = streq (funcname, "addprefix");
816 int is_addsuffix = !is_addprefix;
817
818 int doneany = 0;
819 const char *p;
820 unsigned int len;
821
822 while ((p = find_next_token (&list_iterator, &len)) != 0)
823 {
824 if (is_addprefix)
825 o = variable_buffer_output (o, argv[0], fixlen);
826 o = variable_buffer_output (o, p, len);
827 if (is_addsuffix)
828 o = variable_buffer_output (o, argv[0], fixlen);
829 o = variable_buffer_output (o, " ", 1);
830 doneany = 1;
831 }
832
833 if (doneany)
834 /* Kill last space. */
835 --o;
836
837 return o;
838}
839
840static char *
841func_subst (char *o, char **argv, const char *funcname UNUSED)
842{
843 o = subst_expand (o, argv[2], argv[0], argv[1], strlen (argv[0]),
844 strlen (argv[1]), 0);
845
846 return o;
847}
848
849
850static char *
851func_firstword (char *o, char **argv, const char *funcname UNUSED)
852{
853 unsigned int i;
854 const char *words = argv[0]; /* Use a temp variable for find_next_token */
855 const char *p = find_next_token (&words, &i);
856
857 if (p != 0)
858 o = variable_buffer_output (o, p, i);
859
860 return o;
861}
862
863static char *
864func_lastword (char *o, char **argv, const char *funcname UNUSED)
865{
866 unsigned int i;
867 const char *words = argv[0]; /* Use a temp variable for find_next_token */
868 const char *p = NULL;
869 const char *t;
870
871 while ((t = find_next_token (&words, &i)))
872 p = t;
873
874 if (p != 0)
875 o = variable_buffer_output (o, p, i);
876
877 return o;
878}
879
880static char *
881func_words (char *o, char **argv, const char *funcname UNUSED)
882{
883 int i = 0;
884 const char *word_iterator = argv[0];
885 char buf[20];
886
887 while (find_next_token (&word_iterator, (unsigned int *) 0) != 0)
888 ++i;
889
890 sprintf (buf, "%d", i);
891 o = variable_buffer_output (o, buf, strlen (buf));
892
893 return o;
894}
895
896/* Set begpp to point to the first non-whitespace character of the string,
897 * and endpp to point to the last non-whitespace character of the string.
898 * If the string is empty or contains nothing but whitespace, endpp will be
899 * begpp-1.
900 */
901char *
902strip_whitespace (const char **begpp, const char **endpp)
903{
904 while (*begpp <= *endpp && isspace ((unsigned char)**begpp))
905 (*begpp) ++;
906 while (*endpp >= *begpp && isspace ((unsigned char)**endpp))
907 (*endpp) --;
908 return (char *)*begpp;
909}
910
911static void
912check_numeric (const char *s, const char *msg)
913{
914 const char *end = s + strlen (s) - 1;
915 const char *beg = s;
916 strip_whitespace (&s, &end);
917
918 for (; s <= end; ++s)
919 if (!ISDIGIT (*s)) /* ISDIGIT only evals its arg once: see make.h. */
920 break;
921
922 if (s <= end || end - beg < 0)
923 fatal (*expanding_var, "%s: '%s'", msg, beg);
924}
925
926
927
928static char *
929func_word (char *o, char **argv, const char *funcname UNUSED)
930{
931 const char *end_p;
932 const char *p;
933 int i;
934
935 /* Check the first argument. */
936 check_numeric (argv[0], _("non-numeric first argument to `word' function"));
937 i = atoi (argv[0]);
938
939 if (i == 0)
940 fatal (*expanding_var,
941 _("first argument to `word' function must be greater than 0"));
942
943 end_p = argv[1];
944 while ((p = find_next_token (&end_p, 0)) != 0)
945 if (--i == 0)
946 break;
947
948 if (i == 0)
949 o = variable_buffer_output (o, p, end_p - p);
950
951 return o;
952}
953
954static char *
955func_wordlist (char *o, char **argv, const char *funcname UNUSED)
956{
957 int start, count;
958
959 /* Check the arguments. */
960 check_numeric (argv[0],
961 _("non-numeric first argument to `wordlist' function"));
962 check_numeric (argv[1],
963 _("non-numeric second argument to `wordlist' function"));
964
965 start = atoi (argv[0]);
966 if (start < 1)
967 fatal (*expanding_var,
968 "invalid first argument to `wordlist' function: `%d'", start);
969
970 count = atoi (argv[1]) - start + 1;
971
972 if (count > 0)
973 {
974 const char *p;
975 const char *end_p = argv[2];
976
977 /* Find the beginning of the "start"th word. */
978 while (((p = find_next_token (&end_p, 0)) != 0) && --start)
979 ;
980
981 if (p)
982 {
983 /* Find the end of the "count"th word from start. */
984 while (--count && (find_next_token (&end_p, 0) != 0))
985 ;
986
987 /* Return the stuff in the middle. */
988 o = variable_buffer_output (o, p, end_p - p);
989 }
990 }
991
992 return o;
993}
994
995static char *
996func_findstring (char *o, char **argv, const char *funcname UNUSED)
997{
998 /* Find the first occurrence of the first string in the second. */
999 if (strstr (argv[1], argv[0]) != 0)
1000 o = variable_buffer_output (o, argv[0], strlen (argv[0]));
1001
1002 return o;
1003}
1004
1005static char *
1006func_foreach (char *o, char **argv, const char *funcname UNUSED)
1007{
1008 /* expand only the first two. */
1009 char *varname = expand_argument (argv[0], NULL);
1010 char *list = expand_argument (argv[1], NULL);
1011 const char *body = argv[2];
1012#ifdef CONFIG_WITH_VALUE_LENGTH
1013 long body_len = strlen (body);
1014#endif
1015
1016 int doneany = 0;
1017 const char *list_iterator = list;
1018 const char *p;
1019 unsigned int len;
1020 struct variable *var;
1021
1022 push_new_variable_scope ();
1023 var = define_variable (varname, strlen (varname), "", o_automatic, 0);
1024
1025 /* loop through LIST, put the value in VAR and expand BODY */
1026 while ((p = find_next_token (&list_iterator, &len)) != 0)
1027 {
1028#ifndef CONFIG_WITH_VALUE_LENGTH
1029 char *result = 0;
1030
1031 free (var->value);
1032 var->value = savestring (p, len);
1033
1034 result = allocated_variable_expand (body);
1035
1036 o = variable_buffer_output (o, result, strlen (result));
1037 o = variable_buffer_output (o, " ", 1);
1038 doneany = 1;
1039 free (result);
1040#else /* CONFIG_WITH_VALUE_LENGTH */
1041 if (len >= var->value_alloc_len)
1042 {
1043# ifdef CONFIG_WITH_RDONLY_VARIABLE_VALUE
1044 if (var->rdonly_val)
1045 var->rdonly_val = 0;
1046 else
1047# endif
1048 free (var->value);
1049 var->value_alloc_len = VAR_ALIGN_VALUE_ALLOC (len + 1);
1050 var->value = xmalloc (var->value_alloc_len);
1051 }
1052 memcpy (var->value, p, len);
1053 var->value[len] = '\0';
1054 var->value_length = len;
1055
1056 variable_expand_string_2 (o, body, body_len, &o);
1057 o = variable_buffer_output (o, " ", 1);
1058 doneany = 1;
1059#endif /* CONFIG_WITH_VALUE_LENGTH */
1060 }
1061
1062 if (doneany)
1063 /* Kill the last space. */
1064 --o;
1065
1066 pop_variable_scope ();
1067 free (varname);
1068 free (list);
1069
1070 return o;
1071}
1072
1073#ifdef CONFIG_WITH_LOOP_FUNCTIONS
1074
1075
1076/* Helper for func_for that evaluates the INIT and NEXT parts. */
1077static void
1078helper_eval (char *text, size_t text_len)
1079{
1080 unsigned int buf_len;
1081 char *buf;
1082
1083 install_variable_buffer (&buf, &buf_len);
1084 eval_buffer (text, text + text_len);
1085 restore_variable_buffer (buf, buf_len);
1086}
1087
1088/*
1089 $(for init,condition,next,body)
1090 */
1091static char *
1092func_for (char *o, char **argv, const char *funcname UNUSED)
1093{
1094 char *init = argv[0];
1095 const char *cond = argv[1];
1096 const char *next = argv[2];
1097 size_t next_len = strlen (next);
1098 char *next_buf = xmalloc (next_len + 1);
1099 const char *body = argv[3];
1100 size_t body_len = strlen (body);
1101 unsigned int doneany = 0;
1102
1103 push_new_variable_scope ();
1104
1105 /* Evaluate INIT. */
1106
1107 helper_eval (init, strlen (init));
1108
1109 /* Loop till COND is false. */
1110
1111 while (expr_eval_if_conditionals (cond, NULL) == 0 /* true */)
1112 {
1113 /* Expand BODY. */
1114
1115 if (!doneany)
1116 doneany = 1;
1117 else
1118 o = variable_buffer_output (o, " ", 1);
1119 variable_expand_string_2 (o, body, body_len, &o);
1120
1121 /* Evaluate NEXT. */
1122
1123 memcpy (next_buf, next, next_len + 1);
1124 helper_eval (next_buf, next_len);
1125 }
1126
1127 pop_variable_scope ();
1128 free (next_buf);
1129
1130 return o;
1131}
1132
1133/*
1134 $(while condition,body)
1135 */
1136static char *
1137func_while (char *o, char **argv, const char *funcname UNUSED)
1138{
1139 const char *cond = argv[0];
1140 const char *body = argv[1];
1141 size_t body_len = strlen (body);
1142 unsigned int doneany = 0;
1143
1144 push_new_variable_scope ();
1145
1146 while (expr_eval_if_conditionals (cond, NULL) == 0 /* true */)
1147 {
1148 if (!doneany)
1149 doneany = 1;
1150 else
1151 o = variable_buffer_output (o, " ", 1);
1152 variable_expand_string_2 (o, body, body_len, &o);
1153 }
1154
1155 pop_variable_scope ();
1156
1157 return o;
1158}
1159
1160
1161#endif /* CONFIG_WITH_LOOP_FUNCTIONS */
1162
1163struct a_word
1164{
1165 struct a_word *next;
1166 struct a_word *chain;
1167 char *str;
1168 int length;
1169 int matched;
1170};
1171
1172static unsigned long
1173a_word_hash_1 (const void *key)
1174{
1175 return_STRING_HASH_1 (((struct a_word const *) key)->str);
1176}
1177
1178static unsigned long
1179a_word_hash_2 (const void *key)
1180{
1181 return_STRING_HASH_2 (((struct a_word const *) key)->str);
1182}
1183
1184static int
1185a_word_hash_cmp (const void *x, const void *y)
1186{
1187 int result = ((struct a_word const *) x)->length - ((struct a_word const *) y)->length;
1188 if (result)
1189 return result;
1190 return_STRING_COMPARE (((struct a_word const *) x)->str,
1191 ((struct a_word const *) y)->str);
1192}
1193
1194struct a_pattern
1195{
1196 struct a_pattern *next;
1197 char *str;
1198 char *percent;
1199 int length;
1200 int save_c;
1201};
1202
1203static char *
1204func_filter_filterout (char *o, char **argv, const char *funcname)
1205{
1206 struct a_word *wordhead;
1207 struct a_word **wordtail;
1208 struct a_word *wp;
1209 struct a_pattern *pathead;
1210 struct a_pattern **pattail;
1211 struct a_pattern *pp;
1212
1213 struct hash_table a_word_table;
1214 int is_filter = streq (funcname, "filter");
1215 const char *pat_iterator = argv[0];
1216 const char *word_iterator = argv[1];
1217 int literals = 0;
1218 int words = 0;
1219 int hashing = 0;
1220 char *p;
1221 unsigned int len;
1222
1223 /* Chop ARGV[0] up into patterns to match against the words. */
1224
1225 pattail = &pathead;
1226 while ((p = find_next_token (&pat_iterator, &len)) != 0)
1227 {
1228 struct a_pattern *pat = alloca (sizeof (struct a_pattern));
1229
1230 *pattail = pat;
1231 pattail = &pat->next;
1232
1233 if (*pat_iterator != '\0')
1234 ++pat_iterator;
1235
1236 pat->str = p;
1237 pat->length = len;
1238 pat->save_c = p[len];
1239 p[len] = '\0';
1240 pat->percent = find_percent (p);
1241 if (pat->percent == 0)
1242 literals++;
1243 }
1244 *pattail = 0;
1245
1246 /* Chop ARGV[1] up into words to match against the patterns. */
1247
1248 wordtail = &wordhead;
1249 while ((p = find_next_token (&word_iterator, &len)) != 0)
1250 {
1251 struct a_word *word = alloca (sizeof (struct a_word));
1252
1253 *wordtail = word;
1254 wordtail = &word->next;
1255
1256 if (*word_iterator != '\0')
1257 ++word_iterator;
1258
1259 p[len] = '\0';
1260 word->str = p;
1261 word->length = len;
1262 word->matched = 0;
1263 word->chain = 0;
1264 words++;
1265 }
1266 *wordtail = 0;
1267
1268 /* Only use a hash table if arg list lengths justifies the cost. */
1269 hashing = (literals >= 2 && (literals * words) >= 10);
1270 if (hashing)
1271 {
1272 hash_init (&a_word_table, words, a_word_hash_1, a_word_hash_2,
1273 a_word_hash_cmp);
1274 for (wp = wordhead; wp != 0; wp = wp->next)
1275 {
1276 struct a_word *owp = hash_insert (&a_word_table, wp);
1277 if (owp)
1278 wp->chain = owp;
1279 }
1280 }
1281
1282 if (words)
1283 {
1284 int doneany = 0;
1285
1286 /* Run each pattern through the words, killing words. */
1287 for (pp = pathead; pp != 0; pp = pp->next)
1288 {
1289 if (pp->percent)
1290 for (wp = wordhead; wp != 0; wp = wp->next)
1291 wp->matched |= pattern_matches (pp->str, pp->percent, wp->str);
1292 else if (hashing)
1293 {
1294 struct a_word a_word_key;
1295 a_word_key.str = pp->str;
1296 a_word_key.length = pp->length;
1297 wp = hash_find_item (&a_word_table, &a_word_key);
1298 while (wp)
1299 {
1300 wp->matched |= 1;
1301 wp = wp->chain;
1302 }
1303 }
1304 else
1305 for (wp = wordhead; wp != 0; wp = wp->next)
1306 wp->matched |= (wp->length == pp->length
1307 && strneq (pp->str, wp->str, wp->length));
1308 }
1309
1310 /* Output the words that matched (or didn't, for filter-out). */
1311 for (wp = wordhead; wp != 0; wp = wp->next)
1312 if (is_filter ? wp->matched : !wp->matched)
1313 {
1314 o = variable_buffer_output (o, wp->str, strlen (wp->str));
1315 o = variable_buffer_output (o, " ", 1);
1316 doneany = 1;
1317 }
1318
1319 if (doneany)
1320 /* Kill the last space. */
1321 --o;
1322 }
1323
1324 for (pp = pathead; pp != 0; pp = pp->next)
1325 pp->str[pp->length] = pp->save_c;
1326
1327 if (hashing)
1328 hash_free (&a_word_table, 0);
1329
1330 return o;
1331}
1332
1333
1334static char *
1335func_strip (char *o, char **argv, const char *funcname UNUSED)
1336{
1337 const char *p = argv[0];
1338 int doneany = 0;
1339
1340 while (*p != '\0')
1341 {
1342 int i=0;
1343 const char *word_start;
1344
1345 while (isspace ((unsigned char)*p))
1346 ++p;
1347 word_start = p;
1348 for (i=0; *p != '\0' && !isspace ((unsigned char)*p); ++p, ++i)
1349 {}
1350 if (!i)
1351 break;
1352 o = variable_buffer_output (o, word_start, i);
1353 o = variable_buffer_output (o, " ", 1);
1354 doneany = 1;
1355 }
1356
1357 if (doneany)
1358 /* Kill the last space. */
1359 --o;
1360
1361 return o;
1362}
1363
1364/*
1365 Print a warning or fatal message.
1366*/
1367static char *
1368func_error (char *o, char **argv, const char *funcname)
1369{
1370 char **argvp;
1371 char *msg, *p;
1372 int len;
1373
1374 /* The arguments will be broken on commas. Rather than create yet
1375 another special case where function arguments aren't broken up,
1376 just create a format string that puts them back together. */
1377 for (len=0, argvp=argv; *argvp != 0; ++argvp)
1378 len += strlen (*argvp) + 2;
1379
1380 p = msg = alloca (len + 1);
1381
1382 for (argvp=argv; argvp[1] != 0; ++argvp)
1383 {
1384 strcpy (p, *argvp);
1385 p += strlen (*argvp);
1386 *(p++) = ',';
1387 *(p++) = ' ';
1388 }
1389 strcpy (p, *argvp);
1390
1391 switch (*funcname) {
1392 case 'e':
1393 fatal (reading_file, "%s", msg);
1394
1395 case 'w':
1396 error (reading_file, "%s", msg);
1397 break;
1398
1399 case 'i':
1400 printf ("%s\n", msg);
1401 fflush(stdout);
1402 break;
1403
1404 default:
1405 fatal (*expanding_var, "Internal error: func_error: '%s'", funcname);
1406 }
1407
1408 /* The warning function expands to the empty string. */
1409 return o;
1410}
1411
1412
1413/*
1414 chop argv[0] into words, and sort them.
1415 */
1416static char *
1417func_sort (char *o, char **argv, const char *funcname UNUSED)
1418{
1419 const char *t;
1420 char **words;
1421 int wordi;
1422 char *p;
1423 unsigned int len;
1424 int i;
1425
1426 /* Find the maximum number of words we'll have. */
1427 t = argv[0];
1428 wordi = 1;
1429 while (*t != '\0')
1430 {
1431 char c = *(t++);
1432
1433 if (! isspace ((unsigned char)c))
1434 continue;
1435
1436 ++wordi;
1437
1438 while (isspace ((unsigned char)*t))
1439 ++t;
1440 }
1441
1442 words = xmalloc (wordi * sizeof (char *));
1443
1444 /* Now assign pointers to each string in the array. */
1445 t = argv[0];
1446 wordi = 0;
1447 while ((p = find_next_token (&t, &len)) != 0)
1448 {
1449 ++t;
1450 p[len] = '\0';
1451 words[wordi++] = p;
1452 }
1453
1454 if (wordi)
1455 {
1456 /* Now sort the list of words. */
1457 qsort (words, wordi, sizeof (char *), alpha_compare);
1458
1459 /* Now write the sorted list, uniquified. */
1460#ifdef CONFIG_WITH_RSORT
1461 if (strcmp (funcname, "rsort"))
1462 {
1463 /* sort */
1464#endif
1465 for (i = 0; i < wordi; ++i)
1466 {
1467 len = strlen (words[i]);
1468 if (i == wordi - 1 || strlen (words[i + 1]) != len
1469 || strcmp (words[i], words[i + 1]))
1470 {
1471 o = variable_buffer_output (o, words[i], len);
1472 o = variable_buffer_output (o, " ", 1);
1473 }
1474 }
1475#ifdef CONFIG_WITH_RSORT
1476 }
1477 else
1478 {
1479 /* rsort - reverse the result */
1480 i = wordi;
1481 while (i-- > 0)
1482 {
1483 len = strlen (words[i]);
1484 if (i == 0 || strlen (words[i - 1]) != len
1485 || strcmp (words[i], words[i - 1]))
1486 {
1487 o = variable_buffer_output (o, words[i], len);
1488 o = variable_buffer_output (o, " ", 1);
1489 }
1490 }
1491 }
1492#endif
1493
1494 /* Kill the last space. */
1495 --o;
1496 }
1497
1498 free (words);
1499
1500 return o;
1501}
1502
1503/*
1504 $(if condition,true-part[,false-part])
1505
1506 CONDITION is false iff it evaluates to an empty string. White
1507 space before and after condition are stripped before evaluation.
1508
1509 If CONDITION is true, then TRUE-PART is evaluated, otherwise FALSE-PART is
1510 evaluated (if it exists). Because only one of the two PARTs is evaluated,
1511 you can use $(if ...) to create side-effects (with $(shell ...), for
1512 example).
1513*/
1514
1515static char *
1516func_if (char *o, char **argv, const char *funcname UNUSED)
1517{
1518 const char *begp = argv[0];
1519 const char *endp = begp + strlen (argv[0]) - 1;
1520 int result = 0;
1521
1522 /* Find the result of the condition: if we have a value, and it's not
1523 empty, the condition is true. If we don't have a value, or it's the
1524 empty string, then it's false. */
1525
1526 strip_whitespace (&begp, &endp);
1527
1528 if (begp <= endp)
1529 {
1530 char *expansion = expand_argument (begp, endp+1);
1531
1532 result = strlen (expansion);
1533 free (expansion);
1534 }
1535
1536 /* If the result is true (1) we want to eval the first argument, and if
1537 it's false (0) we want to eval the second. If the argument doesn't
1538 exist we do nothing, otherwise expand it and add to the buffer. */
1539
1540 argv += 1 + !result;
1541
1542 if (*argv)
1543 {
1544 char *expansion = expand_argument (*argv, NULL);
1545
1546 o = variable_buffer_output (o, expansion, strlen (expansion));
1547
1548 free (expansion);
1549 }
1550
1551 return o;
1552}
1553
1554/*
1555 $(or condition1[,condition2[,condition3[...]]])
1556
1557 A CONDITION is false iff it evaluates to an empty string. White
1558 space before and after CONDITION are stripped before evaluation.
1559
1560 CONDITION1 is evaluated. If it's true, then this is the result of
1561 expansion. If it's false, CONDITION2 is evaluated, and so on. If none of
1562 the conditions are true, the expansion is the empty string.
1563
1564 Once a CONDITION is true no further conditions are evaluated
1565 (short-circuiting).
1566*/
1567
1568static char *
1569func_or (char *o, char **argv, const char *funcname UNUSED)
1570{
1571 for ( ; *argv ; ++argv)
1572 {
1573 const char *begp = *argv;
1574 const char *endp = begp + strlen (*argv) - 1;
1575 char *expansion;
1576 int result = 0;
1577
1578 /* Find the result of the condition: if it's false keep going. */
1579
1580 strip_whitespace (&begp, &endp);
1581
1582 if (begp > endp)
1583 continue;
1584
1585 expansion = expand_argument (begp, endp+1);
1586 result = strlen (expansion);
1587
1588 /* If the result is false keep going. */
1589 if (!result)
1590 {
1591 free (expansion);
1592 continue;
1593 }
1594
1595 /* It's true! Keep this result and return. */
1596 o = variable_buffer_output (o, expansion, result);
1597 free (expansion);
1598 break;
1599 }
1600
1601 return o;
1602}
1603
1604/*
1605 $(and condition1[,condition2[,condition3[...]]])
1606
1607 A CONDITION is false iff it evaluates to an empty string. White
1608 space before and after CONDITION are stripped before evaluation.
1609
1610 CONDITION1 is evaluated. If it's false, then this is the result of
1611 expansion. If it's true, CONDITION2 is evaluated, and so on. If all of
1612 the conditions are true, the expansion is the result of the last condition.
1613
1614 Once a CONDITION is false no further conditions are evaluated
1615 (short-circuiting).
1616*/
1617
1618static char *
1619func_and (char *o, char **argv, const char *funcname UNUSED)
1620{
1621 char *expansion;
1622 int result;
1623
1624 while (1)
1625 {
1626 const char *begp = *argv;
1627 const char *endp = begp + strlen (*argv) - 1;
1628
1629 /* An empty condition is always false. */
1630 strip_whitespace (&begp, &endp);
1631 if (begp > endp)
1632 return o;
1633
1634 expansion = expand_argument (begp, endp+1);
1635 result = strlen (expansion);
1636
1637 /* If the result is false, stop here: we're done. */
1638 if (!result)
1639 break;
1640
1641 /* Otherwise the result is true. If this is the last one, keep this
1642 result and quit. Otherwise go on to the next one! */
1643
1644 if (*(++argv))
1645 free (expansion);
1646 else
1647 {
1648 o = variable_buffer_output (o, expansion, result);
1649 break;
1650 }
1651 }
1652
1653 free (expansion);
1654
1655 return o;
1656}
1657
1658static char *
1659func_wildcard (char *o, char **argv, const char *funcname UNUSED)
1660{
1661#ifdef _AMIGA
1662 o = wildcard_expansion (argv[0], o);
1663#else
1664 char *p = string_glob (argv[0]);
1665 o = variable_buffer_output (o, p, strlen (p));
1666#endif
1667 return o;
1668}
1669
1670/*
1671 $(eval <makefile string>)
1672
1673 Always resolves to the empty string.
1674
1675 Treat the arguments as a segment of makefile, and parse them.
1676*/
1677
1678static char *
1679func_eval (char *o, char **argv, const char *funcname UNUSED)
1680{
1681 char *buf;
1682 unsigned int len;
1683
1684 /* Eval the buffer. Pop the current variable buffer setting so that the
1685 eval'd code can use its own without conflicting. */
1686
1687 install_variable_buffer (&buf, &len);
1688
1689#ifndef CONFIG_WITH_VALUE_LENGTH
1690 eval_buffer (argv[0]);
1691#else
1692 eval_buffer (argv[0], strchr (argv[0], '\0'));
1693#endif
1694
1695 restore_variable_buffer (buf, len);
1696
1697 return o;
1698}
1699
1700
1701#ifdef CONFIG_WITH_EVALPLUS
1702/* Same as func_eval except that we push and pop the local variable
1703 context before evaluating the buffer. */
1704static char *
1705func_evalctx (char *o, char **argv, const char *funcname UNUSED)
1706{
1707 char *buf;
1708 unsigned int len;
1709
1710 /* Eval the buffer. Pop the current variable buffer setting so that the
1711 eval'd code can use its own without conflicting. */
1712
1713 install_variable_buffer (&buf, &len);
1714
1715 push_new_variable_scope ();
1716
1717 eval_buffer (argv[0], strchr (argv[0], '\0'));
1718
1719 pop_variable_scope ();
1720
1721 restore_variable_buffer (buf, len);
1722
1723 return o;
1724}
1725
1726/* A mix of func_eval and func_value, saves memory for the expansion.
1727 This implements both evalval and evalvalctx, the latter has its own
1728 variable context just like evalctx. */
1729static char *
1730func_evalval (char *o, char **argv, const char *funcname)
1731{
1732 /* Look up the variable. */
1733 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
1734 if (v)
1735 {
1736 char *buf;
1737 unsigned int len;
1738 int var_ctx;
1739 size_t off;
1740 const struct floc *reading_file_saved = reading_file;
1741
1742 /* Make a copy of the value to the variable buffer since
1743 eval_buffer will make changes to its input. */
1744
1745 off = o - variable_buffer;
1746 variable_buffer_output (o, v->value, v->value_length + 1);
1747 o = variable_buffer + off;
1748
1749 /* Eval the value. Pop the current variable buffer setting so that the
1750 eval'd code can use its own without conflicting. (really necessary?) */
1751
1752 install_variable_buffer (&buf, &len);
1753 var_ctx = !strcmp (funcname, "evalvalctx");
1754 if (var_ctx)
1755 push_new_variable_scope ();
1756 if (v->fileinfo.filenm)
1757 reading_file = &v->fileinfo;
1758
1759 assert (!o[v->value_length]);
1760 eval_buffer (o, o + v->value_length);
1761
1762 reading_file = reading_file_saved;
1763 if (var_ctx)
1764 pop_variable_scope ();
1765 restore_variable_buffer (buf, len);
1766 }
1767
1768 return o;
1769}
1770
1771/* Optimizes the content of one or more variables to save time in
1772 the eval functions. This function will collapse line continuations
1773 and remove comments. */
1774static char *
1775func_eval_optimize_variable (char *o, char **argv, const char *funcname)
1776{
1777 unsigned int i;
1778
1779 for (i = 0; argv[i]; i++)
1780 {
1781 struct variable *v = lookup_variable (argv[i], strlen (argv[i]));
1782# ifdef CONFIG_WITH_RDONLY_VARIABLE_VALUE
1783 if (v && !v->origin != o_automatic && !v->rdonly_val)
1784# else
1785 if (v && !v->origin != o_automatic)
1786# endif
1787 {
1788 char *eos, *src;
1789
1790 eos = collapse_continuations (v->value, v->value_length);
1791 v->value_length = eos - v->value;
1792
1793 /* remove comments */
1794
1795 src = memchr (v->value, '#', v->value_length);
1796 if (src)
1797 {
1798 unsigned char ch = '\0';
1799 char *dst = src;
1800 do
1801 {
1802 /* drop blanks preceeding the comment */
1803 while (dst > v->value)
1804 {
1805 ch = (unsigned char)dst[-1];
1806 if (!isblank (ch))
1807 break;
1808 dst--;
1809 }
1810
1811 /* advance SRC to eol / eos. */
1812 src = memchr (src, '\n', eos - src);
1813 if (!src)
1814 break;
1815
1816 /* drop a preceeding newline if possible (full line comment) */
1817 if (dst > v->value && dst[-1] == '\n')
1818 dst--;
1819
1820 /* copy till next comment or eol. */
1821 while (src < eos)
1822 {
1823 ch = *src++;
1824 if (ch == '#')
1825 break;
1826 *dst++ = ch;
1827 }
1828 }
1829 while (ch == '#' && src < eos);
1830
1831 *dst = '\0';
1832 v->value_length = dst - v->value;
1833 }
1834 }
1835 else if (v)
1836 error (NILF, _("$(%s ): variable `%s' is of the wrong type\n"), funcname, v->name);
1837 }
1838
1839 return o;
1840}
1841
1842#endif /* CONFIG_WITH_EVALPLUS */
1843
1844static char *
1845func_value (char *o, char **argv, const char *funcname UNUSED)
1846{
1847 /* Look up the variable. */
1848 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
1849
1850 /* Copy its value into the output buffer without expanding it. */
1851 if (v)
1852#ifdef CONFIG_WITH_VALUE_LENGTH
1853 {
1854 assert (v->value_length == strlen (v->value));
1855 o = variable_buffer_output (o, v->value, v->value_length);
1856 }
1857#else
1858 o = variable_buffer_output (o, v->value, strlen(v->value));
1859#endif
1860
1861 return o;
1862}
1863
1864/*
1865 \r is replaced on UNIX as well. Is this desirable?
1866 */
1867static void
1868fold_newlines (char *buffer, unsigned int *length)
1869{
1870 char *dst = buffer;
1871 char *src = buffer;
1872 char *last_nonnl = buffer -1;
1873 src[*length] = 0;
1874 for (; *src != '\0'; ++src)
1875 {
1876 if (src[0] == '\r' && src[1] == '\n')
1877 continue;
1878 if (*src == '\n')
1879 {
1880 *dst++ = ' ';
1881 }
1882 else
1883 {
1884 last_nonnl = dst;
1885 *dst++ = *src;
1886 }
1887 }
1888 *(++last_nonnl) = '\0';
1889 *length = last_nonnl - buffer;
1890}
1891
1892
1893
1894int shell_function_pid = 0, shell_function_completed;
1895
1896
1897#ifdef WINDOWS32
1898/*untested*/
1899
1900#include <windows.h>
1901#include <io.h>
1902#include "sub_proc.h"
1903
1904
1905void
1906windows32_openpipe (int *pipedes, int *pid_p, char **command_argv, char **envp)
1907{
1908 SECURITY_ATTRIBUTES saAttr;
1909 HANDLE hIn;
1910 HANDLE hErr;
1911 HANDLE hChildOutRd;
1912 HANDLE hChildOutWr;
1913 HANDLE hProcess;
1914
1915
1916 saAttr.nLength = sizeof (SECURITY_ATTRIBUTES);
1917 saAttr.bInheritHandle = TRUE;
1918 saAttr.lpSecurityDescriptor = NULL;
1919
1920 if (DuplicateHandle (GetCurrentProcess(),
1921 GetStdHandle(STD_INPUT_HANDLE),
1922 GetCurrentProcess(),
1923 &hIn,
1924 0,
1925 TRUE,
1926 DUPLICATE_SAME_ACCESS) == FALSE) {
1927 fatal (NILF, _("create_child_process: DuplicateHandle(In) failed (e=%ld)\n"),
1928 GetLastError());
1929
1930 }
1931 if (DuplicateHandle(GetCurrentProcess(),
1932 GetStdHandle(STD_ERROR_HANDLE),
1933 GetCurrentProcess(),
1934 &hErr,
1935 0,
1936 TRUE,
1937 DUPLICATE_SAME_ACCESS) == FALSE) {
1938 fatal (NILF, _("create_child_process: DuplicateHandle(Err) failed (e=%ld)\n"),
1939 GetLastError());
1940 }
1941
1942 if (!CreatePipe(&hChildOutRd, &hChildOutWr, &saAttr, 0))
1943 fatal (NILF, _("CreatePipe() failed (e=%ld)\n"), GetLastError());
1944
1945 hProcess = process_init_fd(hIn, hChildOutWr, hErr);
1946
1947 if (!hProcess)
1948 fatal (NILF, _("windows32_openpipe (): process_init_fd() failed\n"));
1949
1950 /* make sure that CreateProcess() has Path it needs */
1951 sync_Path_environment();
1952
1953 if (!process_begin(hProcess, command_argv, envp, command_argv[0], NULL)) {
1954 /* register process for wait */
1955 process_register(hProcess);
1956
1957 /* set the pid for returning to caller */
1958 *pid_p = (int) hProcess;
1959
1960 /* set up to read data from child */
1961 pipedes[0] = _open_osfhandle((long) hChildOutRd, O_RDONLY);
1962
1963 /* this will be closed almost right away */
1964 pipedes[1] = _open_osfhandle((long) hChildOutWr, O_APPEND);
1965 } else {
1966 /* reap/cleanup the failed process */
1967 process_cleanup(hProcess);
1968
1969 /* close handles which were duplicated, they weren't used */
1970 CloseHandle(hIn);
1971 CloseHandle(hErr);
1972
1973 /* close pipe handles, they won't be used */
1974 CloseHandle(hChildOutRd);
1975 CloseHandle(hChildOutWr);
1976
1977 /* set status for return */
1978 pipedes[0] = pipedes[1] = -1;
1979 *pid_p = -1;
1980 }
1981}
1982#endif
1983
1984
1985#ifdef __MSDOS__
1986FILE *
1987msdos_openpipe (int* pipedes, int *pidp, char *text)
1988{
1989 FILE *fpipe=0;
1990 /* MSDOS can't fork, but it has `popen'. */
1991 struct variable *sh = lookup_variable ("SHELL", 5);
1992 int e;
1993 extern int dos_command_running, dos_status;
1994
1995 /* Make sure not to bother processing an empty line. */
1996 while (isblank ((unsigned char)*text))
1997 ++text;
1998 if (*text == '\0')
1999 return 0;
2000
2001 if (sh)
2002 {
2003 char buf[PATH_MAX + 7];
2004 /* This makes sure $SHELL value is used by $(shell), even
2005 though the target environment is not passed to it. */
2006 sprintf (buf, "SHELL=%s", sh->value);
2007 putenv (buf);
2008 }
2009
2010 e = errno;
2011 errno = 0;
2012 dos_command_running = 1;
2013 dos_status = 0;
2014 /* If dos_status becomes non-zero, it means the child process
2015 was interrupted by a signal, like SIGINT or SIGQUIT. See
2016 fatal_error_signal in commands.c. */
2017 fpipe = popen (text, "rt");
2018 dos_command_running = 0;
2019 if (!fpipe || dos_status)
2020 {
2021 pipedes[0] = -1;
2022 *pidp = -1;
2023 if (dos_status)
2024 errno = EINTR;
2025 else if (errno == 0)
2026 errno = ENOMEM;
2027 shell_function_completed = -1;
2028 }
2029 else
2030 {
2031 pipedes[0] = fileno (fpipe);
2032 *pidp = 42; /* Yes, the Meaning of Life, the Universe, and Everything! */
2033 errno = e;
2034 shell_function_completed = 1;
2035 }
2036 return fpipe;
2037}
2038#endif
2039
2040/*
2041 Do shell spawning, with the naughty bits for different OSes.
2042 */
2043
2044#ifdef VMS
2045
2046/* VMS can't do $(shell ...) */
2047#define func_shell 0
2048
2049#else
2050#ifndef _AMIGA
2051static char *
2052func_shell (char *o, char **argv, const char *funcname UNUSED)
2053{
2054 char *batch_filename = NULL;
2055
2056#ifdef __MSDOS__
2057 FILE *fpipe;
2058#endif
2059 char **command_argv;
2060 const char *error_prefix;
2061 char **envp;
2062 int pipedes[2];
2063 int pid;
2064
2065#ifndef __MSDOS__
2066 /* Construct the argument list. */
2067 command_argv = construct_command_argv (argv[0], NULL, NULL, 0,
2068 &batch_filename);
2069 if (command_argv == 0)
2070 return o;
2071#endif
2072
2073 /* Using a target environment for `shell' loses in cases like:
2074 export var = $(shell echo foobie)
2075 because target_environment hits a loop trying to expand $(var)
2076 to put it in the environment. This is even more confusing when
2077 var was not explicitly exported, but just appeared in the
2078 calling environment.
2079
2080 See Savannah bug #10593.
2081
2082 envp = target_environment (NILF);
2083 */
2084
2085 envp = environ;
2086
2087 /* For error messages. */
2088 if (reading_file && reading_file->filenm)
2089 {
2090 char *p = alloca (strlen (reading_file->filenm)+11+4);
2091 sprintf (p, "%s:%lu: ", reading_file->filenm, reading_file->lineno);
2092 error_prefix = p;
2093 }
2094 else
2095 error_prefix = "";
2096
2097#if defined(__MSDOS__)
2098 fpipe = msdos_openpipe (pipedes, &pid, argv[0]);
2099 if (pipedes[0] < 0)
2100 {
2101 perror_with_name (error_prefix, "pipe");
2102 return o;
2103 }
2104#elif defined(WINDOWS32)
2105 windows32_openpipe (pipedes, &pid, command_argv, envp);
2106 if (pipedes[0] < 0)
2107 {
2108 /* open of the pipe failed, mark as failed execution */
2109 shell_function_completed = -1;
2110
2111 return o;
2112 }
2113 else
2114#else
2115 if (pipe (pipedes) < 0)
2116 {
2117 perror_with_name (error_prefix, "pipe");
2118 return o;
2119 }
2120
2121# ifdef __EMX__
2122 /* close some handles that are unnecessary for the child process */
2123 CLOSE_ON_EXEC(pipedes[1]);
2124 CLOSE_ON_EXEC(pipedes[0]);
2125 /* Never use fork()/exec() here! Use spawn() instead in exec_command() */
2126 pid = child_execute_job (0, pipedes[1], command_argv, envp);
2127 if (pid < 0)
2128 perror_with_name (error_prefix, "spawn");
2129# else /* ! __EMX__ */
2130 pid = vfork ();
2131 if (pid < 0)
2132 perror_with_name (error_prefix, "fork");
2133 else if (pid == 0)
2134 child_execute_job (0, pipedes[1], command_argv, envp);
2135 else
2136# endif
2137#endif
2138 {
2139 /* We are the parent. */
2140 char *buffer;
2141 unsigned int maxlen, i;
2142 int cc;
2143
2144 /* Record the PID for reap_children. */
2145 shell_function_pid = pid;
2146#ifndef __MSDOS__
2147 shell_function_completed = 0;
2148
2149 /* Free the storage only the child needed. */
2150 free (command_argv[0]);
2151 free (command_argv);
2152
2153 /* Close the write side of the pipe. */
2154# ifdef _MSC_VER /* Avoid annoying msvcrt when debugging. (bird) */
2155 if (pipedes[1] != -1)
2156# endif
2157 close (pipedes[1]);
2158#endif
2159
2160 /* Set up and read from the pipe. */
2161
2162 maxlen = 200;
2163 buffer = xmalloc (maxlen + 1);
2164
2165 /* Read from the pipe until it gets EOF. */
2166 for (i = 0; ; i += cc)
2167 {
2168 if (i == maxlen)
2169 {
2170 maxlen += 512;
2171 buffer = xrealloc (buffer, maxlen + 1);
2172 }
2173
2174 EINTRLOOP (cc, read (pipedes[0], &buffer[i], maxlen - i));
2175 if (cc <= 0)
2176 break;
2177 }
2178 buffer[i] = '\0';
2179
2180 /* Close the read side of the pipe. */
2181#ifdef __MSDOS__
2182 if (fpipe)
2183 (void) pclose (fpipe);
2184#else
2185# ifdef _MSC_VER /* Avoid annoying msvcrt when debugging. (bird) */
2186 if (pipedes[0] != -1)
2187# endif
2188 (void) close (pipedes[0]);
2189#endif
2190
2191 /* Loop until child_handler or reap_children() sets
2192 shell_function_completed to the status of our child shell. */
2193 while (shell_function_completed == 0)
2194 reap_children (1, 0);
2195
2196 if (batch_filename) {
2197 DB (DB_VERBOSE, (_("Cleaning up temporary batch file %s\n"),
2198 batch_filename));
2199 remove (batch_filename);
2200 free (batch_filename);
2201 }
2202 shell_function_pid = 0;
2203
2204 /* The child_handler function will set shell_function_completed
2205 to 1 when the child dies normally, or to -1 if it
2206 dies with status 127, which is most likely an exec fail. */
2207
2208 if (shell_function_completed == -1)
2209 {
2210 /* This likely means that the execvp failed, so we should just
2211 write the error message in the pipe from the child. */
2212 fputs (buffer, stderr);
2213 fflush (stderr);
2214 }
2215 else
2216 {
2217 /* The child finished normally. Replace all newlines in its output
2218 with spaces, and put that in the variable output buffer. */
2219 fold_newlines (buffer, &i);
2220 o = variable_buffer_output (o, buffer, i);
2221 }
2222
2223 free (buffer);
2224 }
2225
2226 return o;
2227}
2228
2229#else /* _AMIGA */
2230
2231/* Do the Amiga version of func_shell. */
2232
2233static char *
2234func_shell (char *o, char **argv, const char *funcname)
2235{
2236 /* Amiga can't fork nor spawn, but I can start a program with
2237 redirection of my choice. However, this means that we
2238 don't have an opportunity to reopen stdout to trap it. Thus,
2239 we save our own stdout onto a new descriptor and dup a temp
2240 file's descriptor onto our stdout temporarily. After we
2241 spawn the shell program, we dup our own stdout back to the
2242 stdout descriptor. The buffer reading is the same as above,
2243 except that we're now reading from a file. */
2244
2245#include <dos/dos.h>
2246#include <proto/dos.h>
2247
2248 BPTR child_stdout;
2249 char tmp_output[FILENAME_MAX];
2250 unsigned int maxlen = 200, i;
2251 int cc;
2252 char * buffer, * ptr;
2253 char ** aptr;
2254 int len = 0;
2255 char* batch_filename = NULL;
2256
2257 /* Construct the argument list. */
2258 command_argv = construct_command_argv (argv[0], NULL, NULL, 0,
2259 &batch_filename);
2260 if (command_argv == 0)
2261 return o;
2262
2263 /* Note the mktemp() is a security hole, but this only runs on Amiga.
2264 Ideally we would use main.c:open_tmpfile(), but this uses a special
2265 Open(), not fopen(), and I'm not familiar enough with the code to mess
2266 with it. */
2267 strcpy (tmp_output, "t:MakeshXXXXXXXX");
2268 mktemp (tmp_output);
2269 child_stdout = Open (tmp_output, MODE_NEWFILE);
2270
2271 for (aptr=command_argv; *aptr; aptr++)
2272 len += strlen (*aptr) + 1;
2273
2274 buffer = xmalloc (len + 1);
2275 ptr = buffer;
2276
2277 for (aptr=command_argv; *aptr; aptr++)
2278 {
2279 strcpy (ptr, *aptr);
2280 ptr += strlen (ptr) + 1;
2281 *ptr ++ = ' ';
2282 *ptr = 0;
2283 }
2284
2285 ptr[-1] = '\n';
2286
2287 Execute (buffer, NULL, child_stdout);
2288 free (buffer);
2289
2290 Close (child_stdout);
2291
2292 child_stdout = Open (tmp_output, MODE_OLDFILE);
2293
2294 buffer = xmalloc (maxlen);
2295 i = 0;
2296 do
2297 {
2298 if (i == maxlen)
2299 {
2300 maxlen += 512;
2301 buffer = xrealloc (buffer, maxlen + 1);
2302 }
2303
2304 cc = Read (child_stdout, &buffer[i], maxlen - i);
2305 if (cc > 0)
2306 i += cc;
2307 } while (cc > 0);
2308
2309 Close (child_stdout);
2310
2311 fold_newlines (buffer, &i);
2312 o = variable_buffer_output (o, buffer, i);
2313 free (buffer);
2314 return o;
2315}
2316#endif /* _AMIGA */
2317#endif /* !VMS */
2318
2319#ifdef EXPERIMENTAL
2320
2321/*
2322 equality. Return is string-boolean, ie, the empty string is false.
2323 */
2324static char *
2325func_eq (char *o, char **argv, const char *funcname UNUSED)
2326{
2327 int result = ! strcmp (argv[0], argv[1]);
2328 o = variable_buffer_output (o, result ? "1" : "", result);
2329 return o;
2330}
2331
2332
2333/*
2334 string-boolean not operator.
2335 */
2336static char *
2337func_not (char *o, char **argv, const char *funcname UNUSED)
2338{
2339 const char *s = argv[0];
2340 int result = 0;
2341 while (isspace ((unsigned char)*s))
2342 s++;
2343 result = ! (*s);
2344 o = variable_buffer_output (o, result ? "1" : "", result);
2345 return o;
2346}
2347#endif
2348
2349
2350#ifdef CONFIG_WITH_STRING_FUNCTIONS
2351/*
2352 $(length string)
2353
2354 XXX: This doesn't take multibyte locales into account.
2355 */
2356static char *
2357func_length (char *o, char **argv, const char *funcname UNUSED)
2358{
2359 size_t len = strlen (argv[0]);
2360 return math_int_to_variable_buffer (o, len);
2361}
2362
2363/*
2364 $(length-var var)
2365
2366 XXX: This doesn't take multibyte locales into account.
2367 */
2368static char *
2369func_length_var (char *o, char **argv, const char *funcname UNUSED)
2370{
2371 struct variable *var = lookup_variable (argv[0], strlen (argv[0]));
2372 return math_int_to_variable_buffer (o, var ? var->value_length : 0);
2373}
2374
2375
2376/* func_insert and func_substr helper. */
2377static char *
2378helper_pad (char *o, size_t to_add, const char *pad, size_t pad_len)
2379{
2380 while (to_add > 0)
2381 {
2382 size_t size = to_add > pad_len ? pad_len : to_add;
2383 o = variable_buffer_output (o, pad, size);
2384 to_add -= size;
2385 }
2386 return o;
2387}
2388
2389/*
2390 $(insert in, str[, n[, length[, pad]]])
2391
2392 XXX: This doesn't take multibyte locales into account.
2393 */
2394static char *
2395func_insert (char *o, char **argv, const char *funcname UNUSED)
2396{
2397 const char *in = argv[0];
2398 size_t in_len = strlen (in);
2399 const char *str = argv[1];
2400 size_t str_len = strlen (str);
2401 math_int n = 0;
2402 math_int length = str_len;
2403 const char *pad = " ";
2404 size_t pad_len = 16;
2405 size_t i;
2406
2407 if (argv[2] != NULL)
2408 {
2409 n = math_int_from_string (argv[2]);
2410 if (n > 0)
2411 n--; /* one-origin */
2412 else if (n == 0)
2413 n = str_len; /* append */
2414 else
2415 { /* n < 0: from the end */
2416 n = str_len + n;
2417 if (n < 0)
2418 n = 0;
2419 }
2420 if (n > 16*1024*1024) /* 16MB */
2421 fatal (NILF, _("$(insert ): n=%s is out of bounds\n"), argv[2]);
2422
2423 if (argv[3] != NULL)
2424 {
2425 length = math_int_from_string (argv[3]);
2426 if (length < 0 || length > 16*1024*1024 /* 16MB */)
2427 fatal (NILF, _("$(insert ): length=%s is out of bounds\n"), argv[3]);
2428
2429 if (argv[4] != NULL)
2430 {
2431 const char *tmp = argv[4];
2432 for (i = 0; tmp[i] == ' '; i++)
2433 /* nothing */;
2434 if (tmp[i] != '\0')
2435 {
2436 pad = argv[4];
2437 pad_len = strlen (pad);
2438 }
2439 /* else: it was all default spaces. */
2440 }
2441 }
2442 }
2443
2444 /* the head of the original string */
2445 if (n > 0)
2446 {
2447 if (n <= str_len)
2448 o = variable_buffer_output (o, str, n);
2449 else
2450 {
2451 o = variable_buffer_output (o, str, str_len);
2452 o = helper_pad (o, n - str_len, pad, pad_len);
2453 }
2454 }
2455
2456 /* insert the string */
2457 if (length <= in_len)
2458 o = variable_buffer_output (o, in, length);
2459 else
2460 {
2461 o = variable_buffer_output (o, in, in_len);
2462 o = helper_pad (o, length - in_len, pad, pad_len);
2463 }
2464
2465 /* the tail of the original string */
2466 if (n < str_len)
2467 o = variable_buffer_output (o, str + n, str_len - n);
2468
2469 return o;
2470}
2471
2472
2473/*
2474 $(pos needle, haystack[, start])
2475 $(lastpos needle, haystack[, start])
2476
2477 XXX: This doesn't take multibyte locales into account.
2478 */
2479static char *
2480func_pos (char *o, char **argv, const char *funcname UNUSED)
2481{
2482 const char *needle = *argv[0] ? argv[0] : " ";
2483 size_t needle_len = strlen (needle);
2484 const char *haystack = argv[1];
2485 size_t haystack_len = strlen (haystack);
2486 math_int start = 0;
2487 const char *hit;
2488
2489 if (argv[2] != NULL)
2490 {
2491 start = math_int_from_string (argv[2]);
2492 if (start > 0)
2493 start--; /* one-origin */
2494 else if (start < 0)
2495 start = haystack_len + start; /* from the end */
2496 if (start < 0 || start + needle_len > haystack_len)
2497 return math_int_to_variable_buffer (o, 0);
2498 }
2499 else if (funcname[0] == 'l')
2500 start = haystack_len - 1;
2501
2502 /* do the searching */
2503 if (funcname[0] != 'l')
2504 { /* pos */
2505 if (needle_len == 1)
2506 hit = strchr (haystack + start, *needle);
2507 else
2508 hit = strstr (haystack + start, needle);
2509 }
2510 else
2511 { /* last pos */
2512 int ch = *needle;
2513 size_t off = start + 1;
2514
2515 hit = NULL;
2516 while (off-- > 0)
2517 {
2518 if ( haystack[off] == ch
2519 && ( needle_len == 1
2520 || strncmp (&haystack[off], needle, needle_len) == 0))
2521 {
2522 hit = haystack + off;
2523 break;
2524 }
2525 }
2526 }
2527
2528 return math_int_to_variable_buffer (o, hit ? hit - haystack + 1 : 0);
2529}
2530
2531
2532/*
2533 $(substr str, start[, length[, pad]])
2534
2535 XXX: This doesn't take multibyte locales into account.
2536 */
2537static char *
2538func_substr (char *o, char **argv, const char *funcname UNUSED)
2539{
2540 const char *str = argv[0];
2541 size_t str_len = strlen (str);
2542 math_int start = math_int_from_string (argv[1]);
2543 math_int length = 0;
2544 const char *pad = NULL;
2545 size_t pad_len = 0;
2546
2547 if (argv[2] != NULL)
2548 {
2549 if (argv[3] != NULL)
2550 {
2551 pad = argv[3];
2552 for (pad_len = 0; pad[pad_len] == ' '; pad_len++)
2553 /* nothing */;
2554 if (pad[pad_len] != '\0')
2555 pad_len = strlen (pad);
2556 else
2557 {
2558 pad = " ";
2559 pad_len = 16;
2560 }
2561 }
2562 length = math_int_from_string (argv[2]);
2563 if (length < 0 || (pad != NULL && length > 16*1024*1024 /* 16MB */))
2564 fatal (NILF, _("$(substr ): length=%s is out of bounds\n"), argv[3]);
2565 if (length == 0)
2566 return o;
2567 }
2568
2569 /* adjust start and length. */
2570 if (pad == NULL)
2571 {
2572 if (start > 0)
2573 {
2574 start--; /* one-origin */
2575 if (start >= str_len)
2576 return o;
2577 if (length == 0 || start + length > str_len)
2578 length = str_len - start;
2579 }
2580 else
2581 {
2582 start = str_len + start;
2583 if (start <= 0)
2584 {
2585 start += length;
2586 if (start <= 0)
2587 return o;
2588 length = start;
2589 start = 0;
2590 }
2591 else if (length == 0 || start + length > str_len)
2592 length = str_len - start;
2593 }
2594
2595 o = variable_buffer_output (o, str + start, length);
2596 }
2597 else
2598 {
2599 if (start > 0)
2600 {
2601 start--; /* one-origin */
2602 if (start >= str_len)
2603 return length ? helper_pad (o, length, pad, pad_len) : o;
2604 if (length == 0)
2605 length = str_len - start;
2606 }
2607 else
2608 {
2609 start = str_len + start;
2610 if (start <= 0)
2611 {
2612 if (start + length <= 0)
2613 return length ? helper_pad (o, length, pad, pad_len) : o;
2614 o = helper_pad (o, -start, pad, pad_len);
2615 return variable_buffer_output (o, str, length + start);
2616 }
2617 if (length == 0)
2618 length = str_len - start;
2619 }
2620 if (start + length <= str_len)
2621 o = variable_buffer_output (o, str + start, length);
2622 else
2623 {
2624 o = variable_buffer_output (o, str + start, str_len - start);
2625 o = helper_pad (o, start + length - str_len, pad, pad_len);
2626 }
2627 }
2628
2629 return o;
2630}
2631
2632
2633/*
2634 $(translate string, from-set[, to-set[, pad-char]])
2635
2636 XXX: This doesn't take multibyte locales into account.
2637 */
2638static char *
2639func_translate (char *o, char **argv, const char *funcname UNUSED)
2640{
2641 const unsigned char *str = (const unsigned char *)argv[0];
2642 const unsigned char *from_set = (const unsigned char *)argv[1];
2643 const char *to_set = argv[2] != NULL ? argv[2] : "";
2644 char trans_tab[1 << CHAR_BIT];
2645 int i;
2646 char ch;
2647
2648 /* init the array. */
2649 for (i = 0; i < (1 << CHAR_BIT); i++)
2650 trans_tab[i] = i;
2651
2652 while ( (i = *from_set) != '\0'
2653 && (ch = *to_set) != '\0')
2654 {
2655 trans_tab[i] = ch;
2656 from_set++;
2657 to_set++;
2658 }
2659
2660 if (i != '\0')
2661 {
2662 ch = '\0'; /* no padding == remove char */
2663 if (argv[2] != NULL && argv[3] != NULL)
2664 {
2665 ch = argv[3][0];
2666 if (ch && argv[3][1])
2667 fatal (NILF, _("$(translate ): pad=`%s' expected a single char\n"), argv[3]);
2668 if (ch == '\0') /* no char == space */
2669 ch = ' ';
2670 }
2671 while ((i = *from_set++) != '\0')
2672 trans_tab[i] = ch;
2673 }
2674
2675 /* do the translation */
2676 while ((i = *str++) != '\0')
2677 {
2678 ch = trans_tab[i];
2679 if (ch)
2680 o = variable_buffer_output (o, &ch, 1);
2681 }
2682
2683 return o;
2684}
2685#endif /* CONFIG_WITH_STRING_FUNCTIONS */
2686
2687
2688#ifdef CONFIG_WITH_LAZY_DEPS_VARS
2689
2690/* This is also in file.c (bad). */
2691# if VMS
2692# define FILE_LIST_SEPARATOR ','
2693# else
2694# define FILE_LIST_SEPARATOR ' '
2695# endif
2696
2697/* Implements $^ and $+.
2698
2699 The first is somes with with FUNCNAME 'deps', the second as 'deps-all'.
2700
2701 If no second argument is given, or if it's empty, or if it's zero,
2702 all dependencies will be returned. If the second argument is non-zero
2703 the dependency at that position will be returned. If the argument is
2704 negative a fatal error is thrown. */
2705static char *
2706func_deps (char *o, char **argv, const char *funcname)
2707{
2708 unsigned int idx = 0;
2709 struct file *file;
2710
2711 /* Handle the argument if present. */
2712
2713 if (argv[1])
2714 {
2715 char *p = argv[1];
2716 while (isspace ((unsigned int)*p))
2717 p++;
2718 if (*p != '\0')
2719 {
2720 char *n;
2721 long l = strtol (p, &n, 0);
2722 while (isspace ((unsigned int)*n))
2723 n++;
2724 idx = l;
2725 if (*n != '\0' || l < 0 || (long)idx != l)
2726 fatal (NILF, _("%s: invalid index value: `%s'\n"), funcname, p);
2727 }
2728 }
2729
2730 /* Find the file and select the list corresponding to FUNCNAME. */
2731
2732 file = lookup_file (argv[0]);
2733 if (file)
2734 {
2735 struct dep *deps = funcname[4] != '\0' && file->org_deps
2736 ? file->org_deps : file->deps;
2737 struct dep *d;
2738
2739 if ( file->double_colon
2740 && ( file->double_colon != file
2741 || file->last != file))
2742 error (NILF, _("$(%s ) cannot be used on files with multiple double colon rules like `%s'\n"),
2743 funcname, file->name);
2744
2745 if (idx == 0 /* all */)
2746 {
2747 unsigned int total_len = 0;
2748
2749 /* calc the result length. */
2750
2751 for (d = deps; d; d = d->next)
2752 if (!d->ignore_mtime)
2753 {
2754 const char *c = dep_name (d);
2755
2756#ifndef NO_ARCHIVES
2757 if (ar_name (c))
2758 {
2759 c = strchr (c, '(') + 1;
2760 total_len += strlen (c);
2761 }
2762 else
2763#elif defined (CONFIG_WITH_STRCACHE2)
2764 total_len += strcache2_get_len (&file_strcache, c) + 1;
2765#else
2766 total_len += strlen (c) + 1;
2767#endif
2768 }
2769
2770 if (total_len)
2771 {
2772 /* prepare the variable buffer dude wrt to the output size and
2773 pass along the strings. */
2774
2775 o = variable_buffer_output (o + total_len, "", 0) - total_len; /* a hack */
2776
2777 for (d = deps; d; d = d->next)
2778 if (!d->ignore_mtime)
2779 {
2780 unsigned int len;
2781 const char *c = dep_name (d);
2782
2783#ifndef NO_ARCHIVES
2784 if (ar_name (c))
2785 {
2786 c = strchr (c, '(') + 1;
2787 len = strlen (c);
2788 }
2789 else
2790#elif defined (CONFIG_WITH_STRCACHE2)
2791 len = strcache2_get_len (&file_strcache, c) + 1;
2792#else
2793 len = strlen (c) + 1;
2794#endif
2795 o = variable_buffer_output (o, c, len);
2796 o[-1] = FILE_LIST_SEPARATOR;
2797 }
2798
2799 --o; /* nuke the last list separator */
2800 *o = '\0';
2801 }
2802 }
2803 else
2804 {
2805 /* Dependency given by index. */
2806
2807 for (d = deps; d; d = d->next)
2808 if (!d->ignore_mtime)
2809 {
2810 if (--idx == 0) /* 1 based indexing */
2811 {
2812 unsigned int len;
2813 const char *c = dep_name (d);
2814
2815#ifndef NO_ARCHIVES
2816 if (ar_name (c))
2817 {
2818 c = strchr (c, '(') + 1;
2819 len = strlen (c) - 1;
2820 }
2821 else
2822#elif defined (CONFIG_WITH_STRCACHE2)
2823 len = strcache2_get_len (&file_strcache, c);
2824#else
2825 len = strlen (c);
2826#endif
2827 o = variable_buffer_output (o, c, len);
2828 break;
2829 }
2830 }
2831 }
2832 }
2833
2834 return o;
2835}
2836
2837/* Implements $?.
2838
2839 If no second argument is given, or if it's empty, or if it's zero,
2840 all dependencies will be returned. If the second argument is non-zero
2841 the dependency at that position will be returned. If the argument is
2842 negative a fatal error is thrown. */
2843static char *
2844func_deps_newer (char *o, char **argv, const char *funcname)
2845{
2846 unsigned int idx = 0;
2847 struct file *file;
2848
2849 /* Handle the argument if present. */
2850
2851 if (argv[1])
2852 {
2853 char *p = argv[1];
2854 while (isspace ((unsigned int)*p))
2855 p++;
2856 if (*p != '\0')
2857 {
2858 char *n;
2859 long l = strtol (p, &n, 0);
2860 while (isspace ((unsigned int)*n))
2861 n++;
2862 idx = l;
2863 if (*n != '\0' || l < 0 || (long)idx != l)
2864 fatal (NILF, _("%s: invalid index value: `%s'\n"), funcname, p);
2865 }
2866 }
2867
2868 /* Find the file. */
2869
2870 file = lookup_file (argv[0]);
2871 if (file)
2872 {
2873 struct dep *deps = file->deps;
2874 struct dep *d;
2875
2876 if ( file->double_colon
2877 && ( file->double_colon != file
2878 || file->last != file))
2879 error (NILF, _("$(%s ) cannot be used on files with multiple double colon rules like `%s'\n"),
2880 funcname, file->name);
2881
2882 if (idx == 0 /* all */)
2883 {
2884 unsigned int total_len = 0;
2885
2886 /* calc the result length. */
2887
2888 for (d = deps; d; d = d->next)
2889 if (!d->ignore_mtime && d->changed)
2890 {
2891 const char *c = dep_name (d);
2892
2893#ifndef NO_ARCHIVES
2894 if (ar_name (c))
2895 {
2896 c = strchr (c, '(') + 1;
2897 total_len += strlen (c);
2898 }
2899 else
2900#elif defined (CONFIG_WITH_STRCACHE2)
2901 total_len += strcache2_get_len (&file_strcache, c) + 1;
2902#else
2903 total_len += strlen (c) + 1;
2904#endif
2905 }
2906
2907 if (total_len)
2908 {
2909 /* prepare the variable buffer dude wrt to the output size and
2910 pass along the strings. */
2911
2912 o = variable_buffer_output (o + total_len, "", 0) - total_len; /* a hack */
2913
2914 for (d = deps; d; d = d->next)
2915 if (!d->ignore_mtime && d->changed)
2916 {
2917 unsigned int len;
2918 const char *c = dep_name (d);
2919
2920#ifndef NO_ARCHIVES
2921 if (ar_name (c))
2922 {
2923 c = strchr (c, '(') + 1;
2924 len = strlen (c);
2925 }
2926 else
2927#elif defined (CONFIG_WITH_STRCACHE2)
2928 len = strcache2_get_len (&file_strcache, c) + 1;
2929#else
2930 len = strlen (c) + 1;
2931#endif
2932 o = variable_buffer_output (o, c, len);
2933 o[-1] = FILE_LIST_SEPARATOR;
2934 }
2935
2936 --o; /* nuke the last list separator */
2937 *o = '\0';
2938 }
2939 }
2940 else
2941 {
2942 /* Dependency given by index. */
2943
2944 for (d = deps; d; d = d->next)
2945 if (!d->ignore_mtime && d->changed)
2946 {
2947 if (--idx == 0) /* 1 based indexing */
2948 {
2949 unsigned int len;
2950 const char *c = dep_name (d);
2951
2952#ifndef NO_ARCHIVES
2953 if (ar_name (c))
2954 {
2955 c = strchr (c, '(') + 1;
2956 len = strlen (c) - 1;
2957 }
2958 else
2959#elif defined (CONFIG_WITH_STRCACHE2)
2960 len = strcache2_get_len (&file_strcache, c);
2961#else
2962 len = strlen (c);
2963#endif
2964 o = variable_buffer_output (o, c, len);
2965 break;
2966 }
2967 }
2968 }
2969 }
2970
2971 return o;
2972}
2973
2974/* Implements $|, the order only dependency list.
2975
2976 If no second argument is given, or if it's empty, or if it's zero,
2977 all dependencies will be returned. If the second argument is non-zero
2978 the dependency at that position will be returned. If the argument is
2979 negative a fatal error is thrown. */
2980static char *
2981func_deps_order_only (char *o, char **argv, const char *funcname)
2982{
2983 unsigned int idx = 0;
2984 struct file *file;
2985
2986 /* Handle the argument if present. */
2987
2988 if (argv[1])
2989 {
2990 char *p = argv[1];
2991 while (isspace ((unsigned int)*p))
2992 p++;
2993 if (*p != '\0')
2994 {
2995 char *n;
2996 long l = strtol (p, &n, 0);
2997 while (isspace ((unsigned int)*n))
2998 n++;
2999 idx = l;
3000 if (*n != '\0' || l < 0 || (long)idx != l)
3001 fatal (NILF, _("%s: invalid index value: `%s'\n"), funcname, p);
3002 }
3003 }
3004
3005 /* Find the file. */
3006
3007 file = lookup_file (argv[0]);
3008 if (file)
3009 {
3010 struct dep *deps = file->deps;
3011 struct dep *d;
3012
3013 if ( file->double_colon
3014 && ( file->double_colon != file
3015 || file->last != file))
3016 error (NILF, _("$(%s ) cannot be used on files with multiple double colon rules like `%s'\n"),
3017 funcname, file->name);
3018
3019 if (idx == 0 /* all */)
3020 {
3021 unsigned int total_len = 0;
3022
3023 /* calc the result length. */
3024
3025 for (d = deps; d; d = d->next)
3026 if (d->ignore_mtime)
3027 {
3028 const char *c = dep_name (d);
3029
3030#ifndef NO_ARCHIVES
3031 if (ar_name (c))
3032 {
3033 c = strchr (c, '(') + 1;
3034 total_len += strlen (c);
3035 }
3036 else
3037#elif defined (CONFIG_WITH_STRCACHE2)
3038 total_len += strcache2_get_len (&file_strcache, c) + 1;
3039#else
3040 total_len += strlen (c) + 1;
3041#endif
3042 }
3043
3044 if (total_len)
3045 {
3046 /* prepare the variable buffer dude wrt to the output size and
3047 pass along the strings. */
3048
3049 o = variable_buffer_output (o + total_len, "", 0) - total_len; /* a hack */
3050
3051 for (d = deps; d; d = d->next)
3052 if (d->ignore_mtime)
3053 {
3054 unsigned int len;
3055 const char *c = dep_name (d);
3056
3057#ifndef NO_ARCHIVES
3058 if (ar_name (c))
3059 {
3060 c = strchr (c, '(') + 1;
3061 len = strlen (c);
3062 }
3063 else
3064#elif defined (CONFIG_WITH_STRCACHE2)
3065 len = strcache2_get_len (&file_strcache, c) + 1;
3066#else
3067 len = strlen (c) + 1;
3068#endif
3069 o = variable_buffer_output (o, c, len);
3070 o[-1] = FILE_LIST_SEPARATOR;
3071 }
3072
3073 --o; /* nuke the last list separator */
3074 *o = '\0';
3075 }
3076 }
3077 else
3078 {
3079 /* Dependency given by index. */
3080
3081 for (d = deps; d; d = d->next)
3082 if (d->ignore_mtime)
3083 {
3084 if (--idx == 0) /* 1 based indexing */
3085 {
3086 unsigned int len;
3087 const char *c = dep_name (d);
3088
3089#ifndef NO_ARCHIVES
3090 if (ar_name (c))
3091 {
3092 c = strchr (c, '(') + 1;
3093 len = strlen (c) - 1;
3094 }
3095 else
3096#elif defined (CONFIG_WITH_STRCACHE2)
3097 len = strcache2_get_len (&file_strcache, c);
3098#else
3099 len = strlen (c);
3100#endif
3101 o = variable_buffer_output (o, c, len);
3102 break;
3103 }
3104 }
3105 }
3106 }
3107
3108 return o;
3109}
3110#endif /* CONFIG_WITH_LAZY_DEPS_VARS */
3111
3112
3113
3114#ifdef CONFIG_WITH_DEFINED
3115/* Similar to ifdef. */
3116static char *
3117func_defined (char *o, char **argv, const char *funcname UNUSED)
3118{
3119 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
3120 int result = v != NULL && *v->value != '\0';
3121 o = variable_buffer_output (o, result ? "1" : "", result);
3122 return o;
3123}
3124#endif /* CONFIG_WITH_DEFINED*/
3125
3126
3127
3128/* Return the absolute name of file NAME which does not contain any `.',
3129 `..' components nor any repeated path separators ('/'). */
3130#ifdef KMK
3131char *
3132#else
3133static char *
3134#endif
3135abspath (const char *name, char *apath)
3136{
3137 char *dest;
3138 const char *start, *end, *apath_limit;
3139
3140 if (name[0] == '\0' || apath == NULL)
3141 return NULL;
3142
3143#ifdef WINDOWS32 /* bird */
3144 dest = w32ify((char *)name, 1);
3145 if (!dest)
3146 return NULL;
3147 {
3148 size_t len = strlen(dest);
3149 memcpy(apath, dest, len);
3150 dest = apath + len;
3151 }
3152
3153 (void)end; (void)start; (void)apath_limit;
3154
3155#elif defined __OS2__ /* bird */
3156 if (_abspath(apath, name, GET_PATH_MAX))
3157 return NULL;
3158 dest = strchr(apath, '\0');
3159
3160 (void)end; (void)start; (void)apath_limit; (void)dest;
3161
3162#else /* !WINDOWS32 && !__OS2__ */
3163 apath_limit = apath + GET_PATH_MAX;
3164
3165#ifdef HAVE_DOS_PATHS /* bird added this */
3166 if (isalpha(name[0]) && name[1] == ':')
3167 {
3168 /* drive spec */
3169 apath[0] = toupper(name[0]);
3170 apath[1] = ':';
3171 apath[2] = '/';
3172 name += 2;
3173 }
3174 else
3175#endif /* HAVE_DOS_PATHS */
3176 if (name[0] != '/')
3177 {
3178 /* It is unlikely we would make it until here but just to make sure. */
3179 if (!starting_directory)
3180 return NULL;
3181
3182 strcpy (apath, starting_directory);
3183
3184 dest = strchr (apath, '\0');
3185 }
3186 else
3187 {
3188 apath[0] = '/';
3189 dest = apath + 1;
3190 }
3191
3192 for (start = end = name; *start != '\0'; start = end)
3193 {
3194 unsigned long len;
3195
3196 /* Skip sequence of multiple path-separators. */
3197 while (*start == '/')
3198 ++start;
3199
3200 /* Find end of path component. */
3201 for (end = start; *end != '\0' && *end != '/'; ++end)
3202 ;
3203
3204 len = end - start;
3205
3206 if (len == 0)
3207 break;
3208 else if (len == 1 && start[0] == '.')
3209 /* nothing */;
3210 else if (len == 2 && start[0] == '.' && start[1] == '.')
3211 {
3212 /* Back up to previous component, ignore if at root already. */
3213 if (dest > apath + 1)
3214 while ((--dest)[-1] != '/');
3215 }
3216 else
3217 {
3218 if (dest[-1] != '/')
3219 *dest++ = '/';
3220
3221 if (dest + len >= apath_limit)
3222 return NULL;
3223
3224 dest = memcpy (dest, start, len);
3225 dest += len;
3226 *dest = '\0';
3227 }
3228 }
3229#endif /* !WINDOWS32 && !__OS2__ */
3230
3231 /* Unless it is root strip trailing separator. */
3232#ifdef HAVE_DOS_PATHS /* bird (is this correct? what about UNC?) */
3233 if (dest > apath + 1 + (apath[0] != '/') && dest[-1] == '/')
3234#else
3235 if (dest > apath + 1 && dest[-1] == '/')
3236#endif
3237 --dest;
3238
3239 *dest = '\0';
3240
3241 return apath;
3242}
3243
3244
3245static char *
3246func_realpath (char *o, char **argv, const char *funcname UNUSED)
3247{
3248 /* Expand the argument. */
3249 const char *p = argv[0];
3250 const char *path = 0;
3251 int doneany = 0;
3252 unsigned int len = 0;
3253 PATH_VAR (in);
3254 PATH_VAR (out);
3255
3256 while ((path = find_next_token (&p, &len)) != 0)
3257 {
3258 if (len < GET_PATH_MAX)
3259 {
3260 strncpy (in, path, len);
3261 in[len] = '\0';
3262
3263 if (
3264#ifdef HAVE_REALPATH
3265 realpath (in, out)
3266#else
3267 abspath (in, out)
3268#endif
3269 )
3270 {
3271 o = variable_buffer_output (o, out, strlen (out));
3272 o = variable_buffer_output (o, " ", 1);
3273 doneany = 1;
3274 }
3275 }
3276 }
3277
3278 /* Kill last space. */
3279 if (doneany)
3280 --o;
3281
3282 return o;
3283}
3284
3285static char *
3286func_abspath (char *o, char **argv, const char *funcname UNUSED)
3287{
3288 /* Expand the argument. */
3289 const char *p = argv[0];
3290 const char *path = 0;
3291 int doneany = 0;
3292 unsigned int len = 0;
3293 PATH_VAR (in);
3294 PATH_VAR (out);
3295
3296 while ((path = find_next_token (&p, &len)) != 0)
3297 {
3298 if (len < GET_PATH_MAX)
3299 {
3300 strncpy (in, path, len);
3301 in[len] = '\0';
3302
3303 if (abspath (in, out))
3304 {
3305 o = variable_buffer_output (o, out, strlen (out));
3306 o = variable_buffer_output (o, " ", 1);
3307 doneany = 1;
3308 }
3309 }
3310 }
3311
3312 /* Kill last space. */
3313 if (doneany)
3314 --o;
3315
3316 return o;
3317}
3318
3319#ifdef CONFIG_WITH_ABSPATHEX
3320/* Same as abspath except that the current path may be given as the
3321 2nd argument. */
3322static char *
3323func_abspathex (char *o, char **argv, const char *funcname UNUSED)
3324{
3325 char *cwd = argv[1];
3326
3327 /* cwd needs leading spaces chopped and may be optional,
3328 in which case we're exactly like $(abspath ). */
3329 while (isblank(*cwd))
3330 cwd++;
3331 if (!*cwd)
3332 o = func_abspath (o, argv, funcname);
3333 else
3334 {
3335 /* Expand the argument. */
3336 const char *p = argv[0];
3337 unsigned int cwd_len = ~0U;
3338 char *path = 0;
3339 int doneany = 0;
3340 unsigned int len = 0;
3341 PATH_VAR (in);
3342 PATH_VAR (out);
3343
3344 while ((path = find_next_token (&p, &len)) != 0)
3345 {
3346 if (len < GET_PATH_MAX)
3347 {
3348#ifdef HAVE_DOS_PATHS
3349 if (path[0] != '/' && path[0] != '\\' && (len < 2 || path[1] != ':') && cwd)
3350#else
3351 if (path[0] != '/' && cwd)
3352#endif
3353 {
3354 /* relative path, prefix with cwd. */
3355 if (cwd_len == ~0U)
3356 cwd_len = strlen (cwd);
3357 if (cwd_len + len + 1 >= GET_PATH_MAX)
3358 continue;
3359 memcpy (in, cwd, cwd_len);
3360 in[cwd_len] = '/';
3361 memcpy (in + cwd_len + 1, path, len);
3362 in[cwd_len + len + 1] = '\0';
3363 }
3364 else
3365 {
3366 /* absolute path pass it as-is. */
3367 memcpy (in, path, len);
3368 in[len] = '\0';
3369 }
3370
3371 if (abspath (in, out))
3372 {
3373 o = variable_buffer_output (o, out, strlen (out));
3374 o = variable_buffer_output (o, " ", 1);
3375 doneany = 1;
3376 }
3377 }
3378 }
3379
3380 /* Kill last space. */
3381 if (doneany)
3382 --o;
3383 }
3384
3385 return o;
3386}
3387#endif
3388
3389#ifdef CONFIG_WITH_XARGS
3390/* Create one or more command lines avoiding the max argument
3391 length restriction of the host OS.
3392
3393 The last argument is the list of arguments that the normal
3394 xargs command would be fed from stdin.
3395
3396 The first argument is initial command and it's arguments.
3397
3398 If there are three or more arguments, the 2nd argument is
3399 the command and arguments to be used on subsequent
3400 command lines. Defaults to the initial command.
3401
3402 If there are four or more arguments, the 3rd argument is
3403 the command to be used at the final command line. Defaults
3404 to the sub sequent or initial command .
3405
3406 A future version of this function may define more arguments
3407 and therefor anyone specifying six or more arguments will
3408 cause fatal errors.
3409
3410 Typical usage is:
3411 $(xargs ar cas mylib.a,$(objects))
3412 or
3413 $(xargs ar cas mylib.a,ar as mylib.a,$(objects))
3414
3415 It will then create one or more "ar mylib.a ..." command
3416 lines with proper \n\t separation so it can be used when
3417 writing rules. */
3418static char *
3419func_xargs (char *o, char **argv, const char *funcname UNUSED)
3420{
3421 int argc;
3422 const char *initial_cmd;
3423 size_t initial_cmd_len;
3424 const char *subsequent_cmd;
3425 size_t subsequent_cmd_len;
3426 const char *final_cmd;
3427 size_t final_cmd_len;
3428 const char *args;
3429 size_t max_args;
3430 int i;
3431
3432#ifdef ARG_MAX
3433 /* ARG_MAX is a bit unreliable (environment), so drop 25% of the max. */
3434# define XARGS_MAX (ARG_MAX - (ARG_MAX / 4))
3435#else /* FIXME: update configure with a command line length test. */
3436# define XARGS_MAX 10240
3437#endif
3438
3439 argc = 0;
3440 while (argv[argc])
3441 argc++;
3442 if (argc > 4)
3443 fatal (NILF, _("Too many arguments for $(xargs)!\n"));
3444
3445 /* first: the initial / default command.*/
3446 initial_cmd = argv[0];
3447 while (isspace ((unsigned char)*initial_cmd))
3448 initial_cmd++;
3449 max_args = initial_cmd_len = strlen (initial_cmd);
3450
3451 /* second: the command for the subsequent command lines. defaults to the initial cmd. */
3452 subsequent_cmd = argc > 2 && argv[1][0] != '\0' ? argv[1] : "";
3453 while (isspace ((unsigned char)*subsequent_cmd))
3454 subsequent_cmd++;
3455 if (*subsequent_cmd)
3456 {
3457 subsequent_cmd_len = strlen (subsequent_cmd);
3458 if (subsequent_cmd_len > max_args)
3459 max_args = subsequent_cmd_len;
3460 }
3461 else
3462 {
3463 subsequent_cmd = initial_cmd;
3464 subsequent_cmd_len = initial_cmd_len;
3465 }
3466
3467 /* third: the final command. defaults to the subseq cmd. */
3468 final_cmd = argc > 3 && argv[2][0] != '\0' ? argv[2] : "";
3469 while (isspace ((unsigned char)*final_cmd))
3470 final_cmd++;
3471 if (*final_cmd)
3472 {
3473 final_cmd_len = strlen (final_cmd);
3474 if (final_cmd_len > max_args)
3475 max_args = final_cmd_len;
3476 }
3477 else
3478 {
3479 final_cmd = subsequent_cmd;
3480 final_cmd_len = subsequent_cmd_len;
3481 }
3482
3483 /* last: the arguments to split up into sensible portions. */
3484 args = argv[argc - 1];
3485
3486 /* calc the max argument length. */
3487 if (XARGS_MAX <= max_args + 2)
3488 fatal (NILF, _("$(xargs): the commands are longer than the max exec argument length. (%lu <= %lu)\n"),
3489 (unsigned long)XARGS_MAX, (unsigned long)max_args + 2);
3490 max_args = XARGS_MAX - max_args - 1;
3491
3492 /* generate the commands. */
3493 i = 0;
3494 for (i = 0; ; i++)
3495 {
3496 unsigned int len;
3497 const char *iterator = args;
3498 const char *end = args;
3499 const char *cur;
3500 const char *tmp;
3501
3502 /* scan the arguments till we reach the end or the max length. */
3503 while ((cur = find_next_token(&iterator, &len))
3504 && (size_t)((cur + len) - args) < max_args)
3505 end = cur + len;
3506 if (cur && end == args)
3507 fatal (NILF, _("$(xargs): command + one single arg is too much. giving up.\n"));
3508
3509 /* emit the command. */
3510 if (i == 0)
3511 {
3512 o = variable_buffer_output (o, (char *)initial_cmd, initial_cmd_len);
3513 o = variable_buffer_output (o, " ", 1);
3514 }
3515 else if (cur)
3516 {
3517 o = variable_buffer_output (o, "\n\t", 2);
3518 o = variable_buffer_output (o, (char *)subsequent_cmd, subsequent_cmd_len);
3519 o = variable_buffer_output (o, " ", 1);
3520 }
3521 else
3522 {
3523 o = variable_buffer_output (o, "\n\t", 2);
3524 o = variable_buffer_output (o, (char *)final_cmd, final_cmd_len);
3525 o = variable_buffer_output (o, " ", 1);
3526 }
3527
3528 tmp = end;
3529 while (tmp > args && isspace ((unsigned char)tmp[-1])) /* drop trailing spaces. */
3530 tmp--;
3531 o = variable_buffer_output (o, (char *)args, tmp - args);
3532
3533
3534 /* next */
3535 if (!cur)
3536 break;
3537 args = end;
3538 while (isspace ((unsigned char)*args))
3539 args++;
3540 }
3541
3542 return o;
3543}
3544#endif
3545
3546#ifdef CONFIG_WITH_TOUPPER_TOLOWER
3547static char *
3548func_toupper_tolower (char *o, char **argv, const char *funcname)
3549{
3550 /* Expand the argument. */
3551 const char *p = argv[0];
3552 while (*p)
3553 {
3554 /* convert to temporary buffer */
3555 char tmp[256];
3556 unsigned int i;
3557 if (!strcmp(funcname, "toupper"))
3558 for (i = 0; i < sizeof(tmp) && *p; i++, p++)
3559 tmp[i] = toupper(*p);
3560 else
3561 for (i = 0; i < sizeof(tmp) && *p; i++, p++)
3562 tmp[i] = tolower(*p);
3563 o = variable_buffer_output (o, tmp, i);
3564 }
3565
3566 return o;
3567}
3568#endif /* CONFIG_WITH_TOUPPER_TOLOWER */
3569
3570#if defined(CONFIG_WITH_VALUE_LENGTH) && defined(CONFIG_WITH_COMPARE)
3571
3572/* Strip leading spaces and other things off a command. */
3573static const char *
3574comp_cmds_strip_leading (const char *s, const char *e)
3575{
3576 while (s < e)
3577 {
3578 const char ch = *s;
3579 if (!isblank (ch)
3580 && ch != '@'
3581#ifdef CONFIG_WITH_COMMANDS_FUNC
3582 && ch != '%'
3583#endif
3584 && ch != '+'
3585 && ch != '-')
3586 break;
3587 s++;
3588 }
3589 return s;
3590}
3591
3592/* Worker for func_comp_vars() which is called if the comparision failed.
3593 It will do the slow command by command comparision of the commands
3594 when there invoked as comp-cmds. */
3595static char *
3596comp_vars_ne (char *o, const char *s1, const char *e1, const char *s2, const char *e2,
3597 char *ne_retval, const char *funcname)
3598{
3599 /* give up at once if not comp-cmds or comp-cmds-ex. */
3600 if (strcmp (funcname, "comp-cmds") != 0
3601 && strcmp (funcname, "comp-cmds-ex") != 0)
3602 o = variable_buffer_output (o, ne_retval, strlen (ne_retval));
3603 else
3604 {
3605 const char * const s1_start = s1;
3606 int new_cmd = 1;
3607 int diff;
3608 for (;;)
3609 {
3610 /* if it's a new command, strip leading stuff. */
3611 if (new_cmd)
3612 {
3613 s1 = comp_cmds_strip_leading (s1, e1);
3614 s2 = comp_cmds_strip_leading (s2, e2);
3615 new_cmd = 0;
3616 }
3617 if (s1 >= e1 || s2 >= e2)
3618 break;
3619
3620 /*
3621 * Inner compare loop which compares one line.
3622 * FIXME: parse quoting!
3623 */
3624 for (;;)
3625 {
3626 const char ch1 = *s1;
3627 const char ch2 = *s2;
3628 diff = ch1 - ch2;
3629 if (diff)
3630 break;
3631 if (ch1 == '\n')
3632 break;
3633 assert (ch1 != '\r');
3634
3635 /* next */
3636 s1++;
3637 s2++;
3638 if (s1 >= e1 || s2 >= e2)
3639 break;
3640 }
3641
3642 /*
3643 * If we exited because of a difference try to end-of-command
3644 * comparision, e.g. ignore trailing spaces.
3645 */
3646 if (diff)
3647 {
3648 /* strip */
3649 while (s1 < e1 && isblank (*s1))
3650 s1++;
3651 while (s2 < e2 && isblank (*s2))
3652 s2++;
3653 if (s1 >= e1 || s2 >= e2)
3654 break;
3655
3656 /* compare again and check that it's a newline. */
3657 if (*s2 != '\n' || *s1 != '\n')
3658 break;
3659 }
3660 /* Break out if we exited because of EOS. */
3661 else if (s1 >= e1 || s2 >= e2)
3662 break;
3663
3664 /*
3665 * Detect the end of command lines.
3666 */
3667 if (*s1 == '\n')
3668 new_cmd = s1 == s1_start || s1[-1] != '\\';
3669 s1++;
3670 s2++;
3671 }
3672
3673 /*
3674 * Ignore trailing empty lines.
3675 */
3676 if (s1 < e1 || s2 < e2)
3677 {
3678 while (s1 < e1 && (isblank (*s1) || *s1 == '\n'))
3679 if (*s1++ == '\n')
3680 s1 = comp_cmds_strip_leading (s1, e1);
3681 while (s2 < e2 && (isblank (*s2) || *s2 == '\n'))
3682 if (*s2++ == '\n')
3683 s2 = comp_cmds_strip_leading (s2, e2);
3684 }
3685
3686 /* emit the result. */
3687 if (s1 == e1 && s2 == e2)
3688 o = variable_buffer_output (o, "", 1) - 1; /** @todo check why this was necessary back the... */
3689 else
3690 o = variable_buffer_output (o, ne_retval, strlen (ne_retval));
3691 }
3692 return o;
3693}
3694
3695/*
3696 $(comp-vars var1,var2,not-equal-return)
3697 or
3698 $(comp-cmds cmd-var1,cmd-var2,not-equal-return)
3699
3700 Compares the two variables (that's given by name to avoid unnecessary
3701 expanding) and return the string in the third argument if not equal.
3702 If equal, nothing is returned.
3703
3704 comp-vars will to an exact comparision only stripping leading and
3705 trailing spaces.
3706
3707 comp-cmds will compare command by command, ignoring not only leading
3708 and trailing spaces on each line but also leading one leading '@',
3709 '-', '+' and '%'
3710*/
3711static char *
3712func_comp_vars (char *o, char **argv, const char *funcname)
3713{
3714 const char *s1, *e1, *x1, *s2, *e2, *x2;
3715 char *a1 = NULL, *a2 = NULL;
3716 size_t l, l1, l2;
3717 struct variable *var1 = lookup_variable (argv[0], strlen (argv[0]));
3718 struct variable *var2 = lookup_variable (argv[1], strlen (argv[1]));
3719
3720 /* the simple cases */
3721 if (var1 == var2)
3722 return variable_buffer_output (o, "", 0); /* eq */
3723 if (!var1 || !var2)
3724 return variable_buffer_output (o, argv[2], strlen(argv[2]));
3725 if (var1->value == var2->value)
3726 return variable_buffer_output (o, "", 0); /* eq */
3727 if (!var1->recursive && !var2->recursive)
3728 {
3729 if ( var1->value_length == var2->value_length
3730 && !memcmp (var1->value, var2->value, var1->value_length))
3731 return variable_buffer_output (o, "", 0); /* eq */
3732
3733 /* ignore trailing and leading blanks */
3734 s1 = var1->value;
3735 e1 = s1 + var1->value_length;
3736 while (isblank ((unsigned char) *s1))
3737 s1++;
3738 while (e1 > s1 && isblank ((unsigned char) e1[-1]))
3739 e1--;
3740
3741 s2 = var2->value;
3742 e2 = s2 + var2->value_length;
3743 while (isblank ((unsigned char) *s2))
3744 s2++;
3745 while (e2 > s2 && isblank ((unsigned char) e2[-1]))
3746 e2--;
3747
3748 if (e1 - s1 != e2 - s2)
3749 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
3750 if (!memcmp (s1, s2, e1 - s1))
3751 return variable_buffer_output (o, "", 0); /* eq */
3752 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
3753 }
3754
3755 /* ignore trailing and leading blanks */
3756 s1 = var1->value;
3757 e1 = s1 + var1->value_length;
3758 while (isblank ((unsigned char) *s1))
3759 s1++;
3760 while (e1 > s1 && isblank ((unsigned char) e1[-1]))
3761 e1--;
3762
3763 s2 = var2->value;
3764 e2 = s2 + var2->value_length;
3765 while (isblank((unsigned char)*s2))
3766 s2++;
3767 while (e2 > s2 && isblank ((unsigned char) e2[-1]))
3768 e2--;
3769
3770 /* both empty after stripping? */
3771 if (s1 == e1 && s2 == e2)
3772 return variable_buffer_output (o, "", 0); /* eq */
3773
3774 /* optimist. */
3775 if ( e1 - s1 == e2 - s2
3776 && !memcmp(s1, s2, e1 - s1))
3777 return variable_buffer_output (o, "", 0); /* eq */
3778
3779 /* compare up to the first '$' or the end. */
3780 x1 = var1->recursive ? memchr (s1, '$', e1 - s1) : NULL;
3781 x2 = var2->recursive ? memchr (s2, '$', e2 - s2) : NULL;
3782 if (!x1 && !x2)
3783 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
3784
3785 l1 = x1 ? x1 - s1 : e1 - s1;
3786 l2 = x2 ? x2 - s2 : e2 - s2;
3787 l = l1 <= l2 ? l1 : l2;
3788 if (l && memcmp (s1, s2, l))
3789 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
3790
3791 /* one or both buffers now require expanding. */
3792 if (!x1)
3793 s1 += l;
3794 else
3795 {
3796 s1 = a1 = allocated_variable_expand ((char *)s1 + l);
3797 if (!l)
3798 while (isblank ((unsigned char) *s1))
3799 s1++;
3800 e1 = strchr (s1, '\0');
3801 while (e1 > s1 && isblank ((unsigned char) e1[-1]))
3802 e1--;
3803 }
3804
3805 if (!x2)
3806 s2 += l;
3807 else
3808 {
3809 s2 = a2 = allocated_variable_expand ((char *)s2 + l);
3810 if (!l)
3811 while (isblank ((unsigned char) *s2))
3812 s2++;
3813 e2 = strchr (s2, '\0');
3814 while (e2 > s2 && isblank ((unsigned char) e2[-1]))
3815 e2--;
3816 }
3817
3818 /* the final compare */
3819 if ( e1 - s1 != e2 - s2
3820 || memcmp (s1, s2, e1 - s1))
3821 o = comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
3822 else
3823 o = variable_buffer_output (o, "", 1) - 1; /* eq */ /** @todo check why this was necessary back the... */
3824 if (a1)
3825 free (a1);
3826 if (a2)
3827 free (a2);
3828 return o;
3829}
3830
3831/*
3832 $(comp-cmds-ex cmds1,cmds2,not-equal-return)
3833
3834 Compares the two strings and return the string in the third argument
3835 if not equal. If equal, nothing is returned.
3836
3837 The comparision will be performed command by command, ignoring not
3838 only leading and trailing spaces on each line but also leading one
3839 leading '@', '-', '+' and '%'.
3840*/
3841static char *
3842func_comp_cmds_ex (char *o, char **argv, const char *funcname)
3843{
3844 const char *s1, *e1, *s2, *e2;
3845 size_t l1, l2;
3846
3847 /* the simple cases */
3848 s1 = argv[0];
3849 s2 = argv[1];
3850 if (s1 == s2)
3851 return variable_buffer_output (o, "", 0); /* eq */
3852 l1 = strlen (argv[0]);
3853 l2 = strlen (argv[1]);
3854
3855 if ( l1 == l2
3856 && !memcmp (s1, s2, l1))
3857 return variable_buffer_output (o, "", 0); /* eq */
3858
3859 /* ignore trailing and leading blanks */
3860 e1 = s1 + l1;
3861 s1 = comp_cmds_strip_leading (s1, e1);
3862
3863 e2 = s2 + l2;
3864 s2 = comp_cmds_strip_leading (s2, e2);
3865
3866 if (e1 - s1 != e2 - s2)
3867 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
3868 if (!memcmp (s1, s2, e1 - s1))
3869 return variable_buffer_output (o, "", 0); /* eq */
3870 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
3871}
3872#endif
3873
3874#ifdef CONFIG_WITH_DATE
3875# if defined (_MSC_VER) /* FIXME: !defined (HAVE_STRPTIME) */
3876char *strptime(const char *s, const char *format, struct tm *tm)
3877{
3878 return (char *)"strptime is not implemented";
3879}
3880# endif
3881/* Check if the string is all blanks or not. */
3882static int
3883all_blanks (const char *s)
3884{
3885 if (!s)
3886 return 1;
3887 while (isspace ((unsigned char)*s))
3888 s++;
3889 return *s == '\0';
3890}
3891
3892/* The first argument is the strftime format string, a iso
3893 timestamp is the default if nothing is given.
3894
3895 The second argument is a time value if given. The format
3896 is either the format from the first argument or given as
3897 an additional third argument. */
3898static char *
3899func_date (char *o, char **argv, const char *funcname)
3900{
3901 char *p;
3902 char *buf;
3903 size_t buf_size;
3904 struct tm t;
3905 const char *format;
3906
3907 /* determin the format - use a single word as the default. */
3908 format = !strcmp (funcname, "date-utc")
3909 ? "%Y-%m-%dT%H:%M:%SZ"
3910 : "%Y-%m-%dT%H:%M:%S";
3911 if (!all_blanks (argv[0]))
3912 format = argv[0];
3913
3914 /* get the time. */
3915 memset (&t, 0, sizeof(t));
3916 if (argv[0] && !all_blanks (argv[1]))
3917 {
3918 const char *input_format = !all_blanks (argv[2]) ? argv[2] : format;
3919 p = strptime (argv[1], input_format, &t);
3920 if (!p || *p != '\0')
3921 {
3922 error (NILF, _("$(%s): strptime(%s,%s,) -> %s\n"), funcname,
3923 argv[1], input_format, p ? p : "<null>");
3924 return variable_buffer_output (o, "", 0);
3925 }
3926 }
3927 else
3928 {
3929 time_t tval;
3930 time (&tval);
3931 if (!strcmp (funcname, "date-utc"))
3932 t = *gmtime (&tval);
3933 else
3934 t = *localtime (&tval);
3935 }
3936
3937 /* format it. note that zero isn't necessarily an error, so we'll
3938 have to keep shut about failures. */
3939 buf_size = 64;
3940 buf = xmalloc (buf_size);
3941 while (strftime (buf, buf_size, format, &t) == 0)
3942 {
3943 if (buf_size >= 4096)
3944 {
3945 *buf = '\0';
3946 break;
3947 }
3948 buf = xrealloc (buf, buf_size <<= 1);
3949 }
3950 o = variable_buffer_output (o, buf, strlen (buf));
3951 free (buf);
3952 return o;
3953}
3954#endif
3955
3956#ifdef CONFIG_WITH_FILE_SIZE
3957/* Prints the size of the specified file. Only one file is
3958 permitted, notthing is stripped. -1 is returned if stat
3959 fails. */
3960static char *
3961func_file_size (char *o, char **argv, const char *funcname UNUSED)
3962{
3963 struct stat st;
3964 if (stat (argv[0], &st))
3965 return variable_buffer_output (o, "-1", 2);
3966 return math_int_to_variable_buffer (o, st.st_size);
3967}
3968#endif
3969
3970#ifdef CONFIG_WITH_WHICH
3971/* Checks if the specified file exists an is executable.
3972 On systems employing executable extensions, the name may
3973 be modified to include the extension. */
3974static int func_which_test_x (char *file)
3975{
3976 struct stat st;
3977# if defined(WINDOWS32) || defined(__OS2__)
3978 char *ext;
3979 char *slash;
3980
3981 /* fix slashes first. */
3982 slash = file;
3983 while ((slash = strchr (slash, '\\')) != NULL)
3984 *slash++ = '/';
3985
3986 /* straight */
3987 if (stat (file, &st) == 0
3988 && S_ISREG (st.st_mode))
3989 return 1;
3990
3991 /* don't try add an extension if there already is one */
3992 ext = strchr (file, '\0');
3993 if (ext - file >= 4
3994 && ( !stricmp (ext - 4, ".exe")
3995 || !stricmp (ext - 4, ".cmd")
3996 || !stricmp (ext - 4, ".bat")
3997 || !stricmp (ext - 4, ".com")))
3998 return 0;
3999
4000 /* try the extensions. */
4001 strcpy (ext, ".exe");
4002 if (stat (file, &st) == 0
4003 && S_ISREG (st.st_mode))
4004 return 1;
4005
4006 strcpy (ext, ".cmd");
4007 if (stat (file, &st) == 0
4008 && S_ISREG (st.st_mode))
4009 return 1;
4010
4011 strcpy (ext, ".bat");
4012 if (stat (file, &st) == 0
4013 && S_ISREG (st.st_mode))
4014 return 1;
4015
4016 strcpy (ext, ".com");
4017 if (stat (file, &st) == 0
4018 && S_ISREG (st.st_mode))
4019 return 1;
4020
4021 return 0;
4022
4023# else
4024
4025 return access (file, X_OK) == 0
4026 && stat (file, &st) == 0
4027 && S_ISREG (st.st_mode);
4028# endif
4029}
4030
4031/* Searches for the specified programs in the PATH and print
4032 their full location if found. Prints nothing if not found. */
4033static char *
4034func_which (char *o, char **argv, const char *funcname UNUSED)
4035{
4036 const char *path;
4037 struct variable *path_var;
4038 unsigned i;
4039 int first = 1;
4040 PATH_VAR (buf);
4041
4042 path_var = lookup_variable ("PATH", 4);
4043 if (path_var)
4044 path = path_var->value;
4045 else
4046 path = ".";
4047
4048 /* iterate input */
4049 for (i = 0; argv[i]; i++)
4050 {
4051 unsigned int len;
4052 const char *iterator = argv[i];
4053 char *cur;
4054
4055 while ((cur = find_next_token (&iterator, &len)))
4056 {
4057 /* if there is a separator, don't walk the path. */
4058 if (memchr (cur, '/', len)
4059#ifdef HAVE_DOS_PATHS
4060 || memchr (cur, '\\', len)
4061 || memchr (cur, ':', len)
4062#endif
4063 )
4064 {
4065 if (len + 1 + 4 < GET_PATH_MAX) /* +4 for .exe */
4066 {
4067 memcpy (buf, cur, len);
4068 buf[len] = '\0';
4069 if (func_which_test_x (buf))
4070 o = variable_buffer_output (o, buf, strlen (buf));
4071 }
4072 }
4073 else
4074 {
4075 const char *comp = path;
4076 for (;;)
4077 {
4078 const char *src = comp;
4079 const char *end = strchr (comp, PATH_SEPARATOR_CHAR);
4080 size_t comp_len = end ? (size_t)(end - comp) : strlen (comp);
4081 if (!comp_len)
4082 {
4083 comp_len = 1;
4084 src = ".";
4085 }
4086 if (len + comp_len + 2 + 4 < GET_PATH_MAX) /* +4 for .exe */
4087 {
4088 memcpy (buf, comp, comp_len);
4089 buf [comp_len] = '/';
4090 memcpy (&buf[comp_len + 1], cur, len);
4091 buf[comp_len + 1 + len] = '\0';
4092
4093 if (func_which_test_x (buf))
4094 {
4095 if (!first)
4096 o = variable_buffer_output (o, " ", 1);
4097 o = variable_buffer_output (o, buf, strlen (buf));
4098 first = 0;
4099 break;
4100 }
4101 }
4102
4103 /* next */
4104 if (!end)
4105 break;
4106 comp = end + 1;
4107 }
4108 }
4109 }
4110 }
4111
4112 return variable_buffer_output (o, "", 0);
4113}
4114#endif /* CONFIG_WITH_WHICH */
4115
4116#ifdef CONFIG_WITH_IF_CONDITIONALS
4117
4118/* Evaluates the expression given in the argument using the
4119 same evaluator as for the new 'if' statements, except now
4120 we don't force the result into a boolean like for 'if' and
4121 '$(if-expr ,,)'. */
4122static char *
4123func_expr (char *o, char **argv, const char *funcname UNUSED)
4124{
4125 o = expr_eval_to_string (o, argv[0]);
4126 return o;
4127}
4128
4129/* Same as '$(if ,,)' except the first argument is evaluated
4130 using the same evaluator as for the new 'if' statements. */
4131static char *
4132func_if_expr (char *o, char **argv, const char *funcname UNUSED)
4133{
4134 int rc;
4135 char *to_expand;
4136
4137 /* Evaluate the condition in argv[0] and expand the 2nd or
4138 3rd argument according to the result. */
4139 rc = expr_eval_if_conditionals (argv[0], NULL);
4140 to_expand = rc == 0 ? argv[1] : argv[2];
4141 if (*to_expand)
4142 variable_expand_string_2 (o, to_expand, -1, &o);
4143
4144 return o;
4145}
4146
4147/*
4148 $(select when1-cond, when1-body[,whenN-cond, whenN-body]).
4149 */
4150static char *
4151func_select (char *o, char **argv, const char *funcname UNUSED)
4152{
4153 int i;
4154
4155 /* Test WHEN-CONDs until one matches. The check for 'otherwise[:]'
4156 and 'default[:]' make this a bit more fun... */
4157
4158 for (i = 0; argv[i] != NULL; i += 2)
4159 {
4160 const char *cond = argv[i];
4161 int is_otherwise = 0;
4162
4163 if (argv[i + 1] == NULL)
4164 fatal (NILF, _("$(select ): not an even argument count\n"));
4165
4166 while (isspace ((unsigned char)*cond))
4167 cond++;
4168 if ( (*cond == 'o' && strncmp (cond, "otherwise", 9) == 0)
4169 || (*cond == 'd' && strncmp (cond, "default", 7) == 0))
4170 {
4171 const char *end = cond + (*cond == 'o' ? 9 : 7);
4172 while (isspace ((unsigned char)*end))
4173 end++;
4174 if (*end == ':')
4175 do end++;
4176 while (isspace ((unsigned char)*end));
4177 is_otherwise = *end == '\0';
4178 }
4179
4180 if ( is_otherwise
4181 || expr_eval_if_conditionals (cond, NULL) == 0 /* true */)
4182 {
4183 variable_expand_string_2 (o, argv[i + 1], -1, &o);
4184 break;
4185 }
4186 }
4187
4188 return o;
4189}
4190
4191#endif /* CONFIG_WITH_IF_CONDITIONALS */
4192
4193#ifdef CONFIG_WITH_SET_CONDITIONALS
4194static char *
4195func_set_intersects (char *o, char **argv, const char *funcname UNUSED)
4196{
4197 const char *s1_cur;
4198 unsigned int s1_len;
4199 const char *s1_iterator = argv[0];
4200
4201 while ((s1_cur = find_next_token (&s1_iterator, &s1_len)) != 0)
4202 {
4203 const char *s2_cur;
4204 unsigned int s2_len;
4205 const char *s2_iterator = argv[1];
4206 while ((s2_cur = find_next_token (&s2_iterator, &s2_len)) != 0)
4207 if (s2_len == s1_len
4208 && strneq (s2_cur, s1_cur, s1_len) )
4209 return variable_buffer_output (o, "1", 1); /* found intersection */
4210 }
4211
4212 return o; /* no intersection */
4213}
4214#endif /* CONFIG_WITH_SET_CONDITIONALS */
4215
4216#ifdef CONFIG_WITH_STACK
4217
4218/* Push an item (string without spaces). */
4219static char *
4220func_stack_push (char *o, char **argv, const char *funcname UNUSED)
4221{
4222 do_variable_definition(NILF, argv[0], argv[1], o_file, f_append, 0 /* !target_var */);
4223 return o;
4224}
4225
4226/* Pops an item off the stack / get the top stack element.
4227 (This is what's tricky to do in pure GNU make syntax.) */
4228static char *
4229func_stack_pop_top (char *o, char **argv, const char *funcname)
4230{
4231 struct variable *stack_var;
4232 const char *stack = argv[0];
4233
4234 stack_var = lookup_variable (stack, strlen (stack) );
4235 if (stack_var)
4236 {
4237 unsigned int len;
4238 const char *iterator = stack_var->value;
4239 char *lastitem = NULL;
4240 char *cur;
4241
4242 while ((cur = find_next_token (&iterator, &len)))
4243 lastitem = cur;
4244
4245 if (lastitem != NULL)
4246 {
4247 if (strcmp (funcname, "stack-popv") != 0)
4248 o = variable_buffer_output (o, lastitem, len);
4249 if (strcmp (funcname, "stack-top") != 0)
4250 {
4251 *lastitem = '\0';
4252 while (lastitem > stack_var->value && isspace (lastitem[-1]))
4253 *--lastitem = '\0';
4254#ifdef CONFIG_WITH_VALUE_LENGTH
4255 stack_var->value_length = lastitem - stack_var->value;
4256#endif
4257 }
4258 }
4259 }
4260 return o;
4261}
4262#endif /* CONFIG_WITH_STACK */
4263
4264#if defined (CONFIG_WITH_MATH) || defined (CONFIG_WITH_NANOTS) || defined (CONFIG_WITH_FILE_SIZE)
4265/* outputs the number (as a string) into the variable buffer. */
4266static char *
4267math_int_to_variable_buffer (char *o, math_int num)
4268{
4269 static const char xdigits[17] = "0123456789abcdef";
4270 int negative;
4271 char strbuf[24]; /* 16 hex + 2 prefix + sign + term => 20
4272 or 20 dec + sign + term => 22 */
4273 char *str = &strbuf[sizeof (strbuf) - 1];
4274
4275 negative = num < 0;
4276 if (negative)
4277 num = -num;
4278
4279 *str = '\0';
4280
4281 do
4282 {
4283#ifdef HEX_MATH_NUMBERS
4284 *--str = xdigits[num & 0xf];
4285 num >>= 4;
4286#else
4287 *--str = xdigits[num % 10];
4288 num /= 10;
4289#endif
4290 }
4291 while (num);
4292
4293#ifdef HEX_MATH_NUMBERS
4294 *--str = 'x';
4295 *--str = '0';
4296#endif
4297
4298 if (negative)
4299 *--str = '-';
4300
4301 return variable_buffer_output (o, str, &strbuf[sizeof (strbuf) - 1] - str);
4302}
4303#endif /* CONFIG_WITH_MATH || CONFIG_WITH_NANOTS */
4304
4305#ifdef CONFIG_WITH_MATH
4306
4307/* Converts a string to an integer, causes an error if the format is invalid. */
4308static math_int
4309math_int_from_string (const char *str)
4310{
4311 const char *start;
4312 unsigned base = 0;
4313 int negative = 0;
4314 math_int num = 0;
4315
4316 /* strip spaces */
4317 while (isspace (*str))
4318 str++;
4319 if (!*str)
4320 {
4321 error (NILF, _("bad number: empty\n"));
4322 return 0;
4323 }
4324 start = str;
4325
4326 /* check for +/- */
4327 while (*str == '+' || *str == '-' || isspace (*str))
4328 if (*str++ == '-')
4329 negative = !negative;
4330
4331 /* check for prefix - we do not accept octal numbers, sorry. */
4332 if (*str == '0' && (str[1] == 'x' || str[1] == 'X'))
4333 {
4334 base = 16;
4335 str += 2;
4336 }
4337 else
4338 {
4339 /* look for a hex digit, if not found treat it as decimal */
4340 const char *p2 = str;
4341 for ( ; *p2; p2++)
4342 if (isxdigit (*p2) && !isdigit (*p2) && isascii (*p2) )
4343 {
4344 base = 16;
4345 break;
4346 }
4347 if (base == 0)
4348 base = 10;
4349 }
4350
4351 /* must have at least one digit! */
4352 if ( !isascii (*str)
4353 || !(base == 16 ? isxdigit (*str) : isdigit (*str)) )
4354 {
4355 error (NILF, _("bad number: '%s'\n"), start);
4356 return 0;
4357 }
4358
4359 /* convert it! */
4360 while (*str && !isspace (*str))
4361 {
4362 int ch = *str++;
4363 if (ch >= '0' && ch <= '9')
4364 ch -= '0';
4365 else if (base == 16 && ch >= 'a' && ch <= 'f')
4366 ch -= 'a' - 10;
4367 else if (base == 16 && ch >= 'A' && ch <= 'F')
4368 ch -= 'A' - 10;
4369 else
4370 {
4371 error (NILF, _("bad number: '%s' (base=%d, pos=%d)\n"), start, base, str - start);
4372 return 0;
4373 }
4374 num *= base;
4375 num += ch;
4376 }
4377
4378 /* check trailing spaces. */
4379 while (isspace (*str))
4380 str++;
4381 if (*str)
4382 {
4383 error (NILF, _("bad number: '%s'\n"), start);
4384 return 0;
4385 }
4386
4387 return negative ? -num : num;
4388}
4389
4390/* Add two or more integer numbers. */
4391static char *
4392func_int_add (char *o, char **argv, const char *funcname UNUSED)
4393{
4394 math_int num;
4395 int i;
4396
4397 num = math_int_from_string (argv[0]);
4398 for (i = 1; argv[i]; i++)
4399 num += math_int_from_string (argv[i]);
4400
4401 return math_int_to_variable_buffer (o, num);
4402}
4403
4404/* Subtract two or more integer numbers. */
4405static char *
4406func_int_sub (char *o, char **argv, const char *funcname UNUSED)
4407{
4408 math_int num;
4409 int i;
4410
4411 num = math_int_from_string (argv[0]);
4412 for (i = 1; argv[i]; i++)
4413 num -= math_int_from_string (argv[i]);
4414
4415 return math_int_to_variable_buffer (o, num);
4416}
4417
4418/* Multiply two or more integer numbers. */
4419static char *
4420func_int_mul (char *o, char **argv, const char *funcname UNUSED)
4421{
4422 math_int num;
4423 int i;
4424
4425 num = math_int_from_string (argv[0]);
4426 for (i = 1; argv[i]; i++)
4427 num *= math_int_from_string (argv[i]);
4428
4429 return math_int_to_variable_buffer (o, num);
4430}
4431
4432/* Divide an integer number by one or more divisors. */
4433static char *
4434func_int_div (char *o, char **argv, const char *funcname UNUSED)
4435{
4436 math_int num;
4437 math_int divisor;
4438 int i;
4439
4440 num = math_int_from_string (argv[0]);
4441 for (i = 1; argv[i]; i++)
4442 {
4443 divisor = math_int_from_string (argv[i]);
4444 if (!divisor)
4445 {
4446 error (NILF, _("divide by zero ('%s')\n"), argv[i]);
4447 return math_int_to_variable_buffer (o, 0);
4448 }
4449 num /= divisor;
4450 }
4451
4452 return math_int_to_variable_buffer (o, num);
4453}
4454
4455
4456/* Divide and return the remainder. */
4457static char *
4458func_int_mod (char *o, char **argv, const char *funcname UNUSED)
4459{
4460 math_int num;
4461 math_int divisor;
4462
4463 num = math_int_from_string (argv[0]);
4464 divisor = math_int_from_string (argv[1]);
4465 if (!divisor)
4466 {
4467 error (NILF, _("divide by zero ('%s')\n"), argv[1]);
4468 return math_int_to_variable_buffer (o, 0);
4469 }
4470 num %= divisor;
4471
4472 return math_int_to_variable_buffer (o, num);
4473}
4474
4475/* 2-complement. */
4476static char *
4477func_int_not (char *o, char **argv, const char *funcname UNUSED)
4478{
4479 math_int num;
4480
4481 num = math_int_from_string (argv[0]);
4482 num = ~num;
4483
4484 return math_int_to_variable_buffer (o, num);
4485}
4486
4487/* Bitwise AND (two or more numbers). */
4488static char *
4489func_int_and (char *o, char **argv, const char *funcname UNUSED)
4490{
4491 math_int num;
4492 int i;
4493
4494 num = math_int_from_string (argv[0]);
4495 for (i = 1; argv[i]; i++)
4496 num &= math_int_from_string (argv[i]);
4497
4498 return math_int_to_variable_buffer (o, num);
4499}
4500
4501/* Bitwise OR (two or more numbers). */
4502static char *
4503func_int_or (char *o, char **argv, const char *funcname UNUSED)
4504{
4505 math_int num;
4506 int i;
4507
4508 num = math_int_from_string (argv[0]);
4509 for (i = 1; argv[i]; i++)
4510 num |= math_int_from_string (argv[i]);
4511
4512 return math_int_to_variable_buffer (o, num);
4513}
4514
4515/* Bitwise XOR (two or more numbers). */
4516static char *
4517func_int_xor (char *o, char **argv, const char *funcname UNUSED)
4518{
4519 math_int num;
4520 int i;
4521
4522 num = math_int_from_string (argv[0]);
4523 for (i = 1; argv[i]; i++)
4524 num ^= math_int_from_string (argv[i]);
4525
4526 return math_int_to_variable_buffer (o, num);
4527}
4528
4529/* Compare two integer numbers. Returns make boolean (true="1"; false=""). */
4530static char *
4531func_int_cmp (char *o, char **argv, const char *funcname)
4532{
4533 math_int num1;
4534 math_int num2;
4535 int rc;
4536
4537 num1 = math_int_from_string (argv[0]);
4538 num2 = math_int_from_string (argv[1]);
4539
4540 funcname += sizeof ("int-") - 1;
4541 if (!strcmp (funcname, "eq"))
4542 rc = num1 == num2;
4543 else if (!strcmp (funcname, "ne"))
4544 rc = num1 != num2;
4545 else if (!strcmp (funcname, "gt"))
4546 rc = num1 > num2;
4547 else if (!strcmp (funcname, "ge"))
4548 rc = num1 >= num2;
4549 else if (!strcmp (funcname, "lt"))
4550 rc = num1 < num2;
4551 else /*if (!strcmp (funcname, "le"))*/
4552 rc = num1 <= num2;
4553
4554 return variable_buffer_output (o, rc ? "1" : "", rc);
4555}
4556
4557#endif /* CONFIG_WITH_MATH */
4558
4559#ifdef CONFIG_WITH_NANOTS
4560/* Returns the current timestamp as nano seconds. The time
4561 source is a high res monotone one if the platform provides
4562 this (and we know about it).
4563
4564 Tip. Use this with int-sub to profile makefile reading
4565 and similar. */
4566static char *
4567func_nanots (char *o, char **argv UNUSED, const char *funcname UNUSED)
4568{
4569 return math_int_to_variable_buffer (o, nano_timestamp ());
4570}
4571#endif
4572
4573#ifdef CONFIG_WITH_OS2_LIBPATH
4574/* Sets or gets the OS/2 libpath variables.
4575
4576 The first argument indicates which variable - BEGINLIBPATH,
4577 ENDLIBPATH, LIBPATHSTRICT or LIBPATH.
4578
4579 The second indicates whether this is a get (not present) or
4580 set (present) operation. When present it is the new value for
4581 the variable. */
4582static char *
4583func_os2_libpath (char *o, char **argv, const char *funcname UNUSED)
4584{
4585 char buf[4096];
4586 ULONG fVar;
4587 APIRET rc;
4588
4589 /* translate variable name (first arg) */
4590 if (!strcmp (argv[0], "BEGINLIBPATH"))
4591 fVar = BEGIN_LIBPATH;
4592 else if (!strcmp (argv[0], "ENDLIBPATH"))
4593 fVar = END_LIBPATH;
4594 else if (!strcmp (argv[0], "LIBPATHSTRICT"))
4595 fVar = LIBPATHSTRICT;
4596 else if (!strcmp (argv[0], "LIBPATH"))
4597 fVar = 0;
4598 else
4599 {
4600 error (NILF, _("$(libpath): unknown variable `%s'"), argv[0]);
4601 return variable_buffer_output (o, "", 0);
4602 }
4603
4604 if (!argv[1])
4605 {
4606 /* get the variable value. */
4607 if (fVar != 0)
4608 {
4609 buf[0] = buf[1] = buf[2] = buf[3] = '\0';
4610 rc = DosQueryExtLIBPATH (buf, fVar);
4611 }
4612 else
4613 rc = DosQueryHeaderInfo (NULLHANDLE, 0, buf, sizeof(buf), QHINF_LIBPATH);
4614 if (rc != NO_ERROR)
4615 {
4616 error (NILF, _("$(libpath): failed to query `%s', rc=%d"), argv[0], rc);
4617 return variable_buffer_output (o, "", 0);
4618 }
4619 o = variable_buffer_output (o, buf, strlen (buf));
4620 }
4621 else
4622 {
4623 /* set the variable value. */
4624 size_t len;
4625 size_t len_max = sizeof (buf) < 2048 ? sizeof (buf) : 2048;
4626 const char *val;
4627 const char *end;
4628
4629 if (fVar == 0)
4630 {
4631 error (NILF, _("$(libpath): LIBPATH is read-only"));
4632 return variable_buffer_output (o, "", 0);
4633 }
4634
4635 /* strip leading and trailing spaces and check for max length. */
4636 val = argv[1];
4637 while (isspace (*val))
4638 val++;
4639 end = strchr (val, '\0');
4640 while (end > val && isspace (end[-1]))
4641 end--;
4642
4643 len = end - val;
4644 if (len >= len_max)
4645 {
4646 error (NILF, _("$(libpath): The new `%s' value is too long (%d bytes, max %d)"),
4647 argv[0], len, len_max);
4648 return variable_buffer_output (o, "", 0);
4649 }
4650
4651 /* make a stripped copy in low memory and try set it. */
4652 memcpy (buf, val, len);
4653 buf[len] = '\0';
4654 rc = DosSetExtLIBPATH (buf, fVar);
4655 if (rc != NO_ERROR)
4656 {
4657 error (NILF, _("$(libpath): failed to set `%s' to `%s', rc=%d"), argv[0], buf, rc);
4658 return variable_buffer_output (o, "", 0);
4659 }
4660
4661 o = variable_buffer_output (o, "", 0);
4662 }
4663 return o;
4664}
4665#endif /* CONFIG_WITH_OS2_LIBPATH */
4666
4667#if defined (CONFIG_WITH_MAKE_STATS) || defined (CONFIG_WITH_MINIMAL_STATS)
4668/* Retrieve make statistics. */
4669static char *
4670func_make_stats (char *o, char **argv, const char *funcname UNUSED)
4671{
4672 char buf[512];
4673 int len;
4674
4675 if (!argv[0] || (!argv[0][0] && !argv[1]))
4676 {
4677# ifdef CONFIG_WITH_MAKE_STATS
4678 len = sprintf (buf, "alloc-cur: %5ld/%3ld %3luMB hash: %5lu %2lu%%",
4679 make_stats_allocations,
4680 make_stats_reallocations,
4681 make_stats_allocated / (1024*1024),
4682 make_stats_ht_lookups,
4683 (make_stats_ht_collisions * 100) / make_stats_ht_lookups);
4684 o = variable_buffer_output (o, buf, len);
4685#endif
4686 }
4687 else
4688 {
4689 /* selective */
4690 int i;
4691 for (i = 0; argv[i]; i++)
4692 {
4693 unsigned long val;
4694 if (i != 0)
4695 o = variable_buffer_output (o, " ", 1);
4696 if (0)
4697 continue;
4698# ifdef CONFIG_WITH_MAKE_STATS
4699 else if (!strcmp(argv[i], "allocations"))
4700 val = make_stats_allocations;
4701 else if (!strcmp(argv[i], "reallocations"))
4702 val = make_stats_reallocations;
4703 else if (!strcmp(argv[i], "allocated"))
4704 val = make_stats_allocated;
4705 else if (!strcmp(argv[i], "ht_lookups"))
4706 val = make_stats_ht_lookups;
4707 else if (!strcmp(argv[i], "ht_collisions"))
4708 val = make_stats_ht_collisions;
4709 else if (!strcmp(argv[i], "ht_collisions_pct"))
4710 val = (make_stats_ht_collisions * 100) / make_stats_ht_lookups;
4711#endif
4712 else
4713 {
4714 o = variable_buffer_output (o, argv[i], strlen (argv[i]));
4715 continue;
4716 }
4717
4718 len = sprintf (buf, "%ld", val);
4719 o = variable_buffer_output (o, buf, len);
4720 }
4721 }
4722
4723 return o;
4724}
4725#endif /* CONFIG_WITH_MAKE_STATS */
4726
4727#ifdef CONFIG_WITH_COMMANDS_FUNC
4728/* Gets all the commands for a target, separated by newlines.
4729
4730 This is useful when creating and checking target dependencies since
4731 it reduces the amount of work and the memory consuption. A new prefix
4732 character '%' has been introduced for skipping certain lines, like
4733 for instance the one calling this function and pushing to a dep file.
4734 Blank lines are also skipped.
4735
4736 The commands function takes exactly one argument, which is the name of
4737 the target which commands should be returned.
4738
4739 The commands-sc is identical to commands except that it uses a ';' to
4740 separate the commands.
4741
4742 The commands-usr is similar to commands except that it takes a 2nd
4743 argument that is used to separate the commands. */
4744char *
4745func_commands (char *o, char **argv, const char *funcname)
4746{
4747 struct file *file;
4748 static int recursive = 0;
4749
4750 if (recursive)
4751 {
4752 error (reading_file, _("$(%s ) was invoked recursivly"), funcname);
4753 return variable_buffer_output (o, "recursive", sizeof ("recursive") - 1);
4754 }
4755 if (*argv[0] == '\0')
4756 {
4757 error (reading_file, _("$(%s ) was invoked with an empty target name"), funcname);
4758 return o;
4759 }
4760 recursive = 1;
4761
4762 file = lookup_file (argv[0]);
4763 if (file && file->cmds)
4764 {
4765 unsigned int i;
4766 int cmd_sep_len;
4767 struct commands *cmds = file->cmds;
4768 const char *cmd_sep;
4769
4770 if (!strcmp (funcname, "commands"))
4771 {
4772 cmd_sep = "\n";
4773 cmd_sep_len = 1;
4774 }
4775 else if (!strcmp (funcname, "commands-sc"))
4776 {
4777 cmd_sep = ";";
4778 cmd_sep_len = 1;
4779 }
4780 else /*if (!strcmp (funcname, "commands-usr"))*/
4781 {
4782 cmd_sep = argv[1];
4783 cmd_sep_len = strlen (cmd_sep);
4784 }
4785
4786 initialize_file_variables (file, 1 /* don't search for pattern vars */);
4787 set_file_variables (file, 1 /* early call */);
4788 chop_commands (cmds);
4789
4790 for (i = 0; i < cmds->ncommand_lines; i++)
4791 {
4792 char *p;
4793 char *in, *out, *ref;
4794
4795 /* Skip it if it has a '%' prefix or is blank. */
4796 if (cmds->lines_flags[i] & COMMAND_GETTER_SKIP_IT)
4797 continue;
4798 p = cmds->command_lines[i];
4799 while (isblank ((unsigned char)*p))
4800 p++;
4801 if (*p == '\0')
4802 continue;
4803
4804 /* --- copied from new_job() in job.c --- */
4805
4806 /* Collapse backslash-newline combinations that are inside variable
4807 or function references. These are left alone by the parser so
4808 that they will appear in the echoing of commands (where they look
4809 nice); and collapsed by construct_command_argv when it tokenizes.
4810 But letting them survive inside function invocations loses because
4811 we don't want the functions to see them as part of the text. */
4812
4813 /* IN points to where in the line we are scanning.
4814 OUT points to where in the line we are writing.
4815 When we collapse a backslash-newline combination,
4816 IN gets ahead of OUT. */
4817
4818 in = out = p;
4819 while ((ref = strchr (in, '$')) != 0)
4820 {
4821 ++ref; /* Move past the $. */
4822
4823 if (out != in)
4824 /* Copy the text between the end of the last chunk
4825 we processed (where IN points) and the new chunk
4826 we are about to process (where REF points). */
4827 memmove (out, in, ref - in);
4828
4829 /* Move both pointers past the boring stuff. */
4830 out += ref - in;
4831 in = ref;
4832
4833 if (*ref == '(' || *ref == '{')
4834 {
4835 char openparen = *ref;
4836 char closeparen = openparen == '(' ? ')' : '}';
4837 int count;
4838 char *p2;
4839
4840 *out++ = *in++; /* Copy OPENPAREN. */
4841 /* IN now points past the opening paren or brace.
4842 Count parens or braces until it is matched. */
4843 count = 0;
4844 while (*in != '\0')
4845 {
4846 if (*in == closeparen && --count < 0)
4847 break;
4848 else if (*in == '\\' && in[1] == '\n')
4849 {
4850 /* We have found a backslash-newline inside a
4851 variable or function reference. Eat it and
4852 any following whitespace. */
4853
4854 int quoted = 0;
4855 for (p2 = in - 1; p2 > ref && *p2 == '\\'; --p2)
4856 quoted = !quoted;
4857
4858 if (quoted)
4859 /* There were two or more backslashes, so this is
4860 not really a continuation line. We don't collapse
4861 the quoting backslashes here as is done in
4862 collapse_continuations, because the line will
4863 be collapsed again after expansion. */
4864 *out++ = *in++;
4865 else
4866 {
4867 /* Skip the backslash, newline and
4868 any following whitespace. */
4869 in = next_token (in + 2);
4870
4871 /* Discard any preceding whitespace that has
4872 already been written to the output. */
4873 while (out > ref
4874 && isblank ((unsigned char)out[-1]))
4875 --out;
4876
4877 /* Replace it all with a single space. */
4878 *out++ = ' ';
4879 }
4880 }
4881 else
4882 {
4883 if (*in == openparen)
4884 ++count;
4885
4886 *out++ = *in++;
4887 }
4888 }
4889 }
4890 /* Some of these can be amended ($< perhaps), but we're likely to be called while the
4891 dep expansion happens, so it would have to be on a hackish basis. sad... */
4892 else if (*ref == '<' || *ref == '*' || *ref == '%' || *ref == '^' || *ref == '+')
4893 error (reading_file, _("$(%s ) does not work reliably with $%c in all cases"), funcname, *ref);
4894 }
4895
4896 /* There are no more references in this line to worry about.
4897 Copy the remaining uninteresting text to the output. */
4898 if (out != in)
4899 strcpy (out, in);
4900
4901 /* --- copied from new_job() in job.c --- */
4902
4903 /* Finally, expand the line. */
4904 if (i)
4905 o = variable_buffer_output (o, cmd_sep, cmd_sep_len);
4906 o = variable_expand_for_file_2 (o, cmds->command_lines[i], ~0U, file, NULL);
4907
4908 /* Skip it if it has a '%' prefix or is blank. */
4909 p = o;
4910 while (isblank ((unsigned char)*o)
4911 || *o == '@'
4912 || *o == '-'
4913 || *o == '+')
4914 o++;
4915 if (*o != '\0' && *o != '%')
4916 o = strchr (o, '\0');
4917 else if (i)
4918 o = p - cmd_sep_len;
4919 else
4920 o = p;
4921 } /* for each command line */
4922 }
4923 /* else FIXME: bitch about it? */
4924
4925 recursive = 0;
4926 return o;
4927}
4928#endif /* CONFIG_WITH_COMMANDS_FUNC */
4929
4930#ifdef KMK
4931/* Useful when debugging kmk and/or makefiles. */
4932char *
4933func_breakpoint (char *o, char **argv UNUSED, const char *funcname UNUSED)
4934{
4935#ifdef _MSC_VER
4936 __debugbreak();
4937#elif defined(__i386__) || defined(__x86__) || defined(__X86__) || defined(_M_IX86) || defined(__i386) \
4938 || defined(__amd64__) || defined(__x86_64__) || defined(__AMD64__) || defined(_M_X64) || defined(__amd64)
4939 __asm__ __volatile__ ("int3\n\t");
4940#else
4941 char *p = (char *)0;
4942 *p = '\0';
4943#endif
4944 return o;
4945}
4946#endif /* KMK */
4947
4948
4949/* Lookup table for builtin functions.
4950
4951 This doesn't have to be sorted; we use a straight lookup. We might gain
4952 some efficiency by moving most often used functions to the start of the
4953 table.
4954
4955 If MAXIMUM_ARGS is 0, that means there is no maximum and all
4956 comma-separated values are treated as arguments.
4957
4958 EXPAND_ARGS means that all arguments should be expanded before invocation.
4959 Functions that do namespace tricks (foreach) don't automatically expand. */
4960
4961static char *func_call (char *o, char **argv, const char *funcname);
4962
4963
4964static struct function_table_entry function_table_init[] =
4965{
4966 /* Name/size */ /* MIN MAX EXP? Function */
4967 { STRING_SIZE_TUPLE("abspath"), 0, 1, 1, func_abspath},
4968 { STRING_SIZE_TUPLE("addprefix"), 2, 2, 1, func_addsuffix_addprefix},
4969 { STRING_SIZE_TUPLE("addsuffix"), 2, 2, 1, func_addsuffix_addprefix},
4970 { STRING_SIZE_TUPLE("basename"), 0, 1, 1, func_basename_dir},
4971 { STRING_SIZE_TUPLE("dir"), 0, 1, 1, func_basename_dir},
4972 { STRING_SIZE_TUPLE("notdir"), 0, 1, 1, func_notdir_suffix},
4973 { STRING_SIZE_TUPLE("subst"), 3, 3, 1, func_subst},
4974 { STRING_SIZE_TUPLE("suffix"), 0, 1, 1, func_notdir_suffix},
4975 { STRING_SIZE_TUPLE("filter"), 2, 2, 1, func_filter_filterout},
4976 { STRING_SIZE_TUPLE("filter-out"), 2, 2, 1, func_filter_filterout},
4977 { STRING_SIZE_TUPLE("findstring"), 2, 2, 1, func_findstring},
4978 { STRING_SIZE_TUPLE("firstword"), 0, 1, 1, func_firstword},
4979 { STRING_SIZE_TUPLE("flavor"), 0, 1, 1, func_flavor},
4980 { STRING_SIZE_TUPLE("join"), 2, 2, 1, func_join},
4981 { STRING_SIZE_TUPLE("lastword"), 0, 1, 1, func_lastword},
4982 { STRING_SIZE_TUPLE("patsubst"), 3, 3, 1, func_patsubst},
4983 { STRING_SIZE_TUPLE("realpath"), 0, 1, 1, func_realpath},
4984#ifdef CONFIG_WITH_RSORT
4985 { STRING_SIZE_TUPLE("rsort"), 0, 1, 1, func_sort},
4986#endif
4987 { STRING_SIZE_TUPLE("shell"), 0, 1, 1, func_shell},
4988 { STRING_SIZE_TUPLE("sort"), 0, 1, 1, func_sort},
4989 { STRING_SIZE_TUPLE("strip"), 0, 1, 1, func_strip},
4990 { STRING_SIZE_TUPLE("wildcard"), 0, 1, 1, func_wildcard},
4991 { STRING_SIZE_TUPLE("word"), 2, 2, 1, func_word},
4992 { STRING_SIZE_TUPLE("wordlist"), 3, 3, 1, func_wordlist},
4993 { STRING_SIZE_TUPLE("words"), 0, 1, 1, func_words},
4994 { STRING_SIZE_TUPLE("origin"), 0, 1, 1, func_origin},
4995 { STRING_SIZE_TUPLE("foreach"), 3, 3, 0, func_foreach},
4996#ifdef CONFIG_WITH_LOOP_FUNCTIONS
4997 { STRING_SIZE_TUPLE("for"), 4, 4, 0, func_for},
4998 { STRING_SIZE_TUPLE("while"), 2, 2, 0, func_while},
4999#endif
5000 { STRING_SIZE_TUPLE("call"), 1, 0, 1, func_call},
5001 { STRING_SIZE_TUPLE("info"), 0, 1, 1, func_error},
5002 { STRING_SIZE_TUPLE("error"), 0, 1, 1, func_error},
5003 { STRING_SIZE_TUPLE("warning"), 0, 1, 1, func_error},
5004 { STRING_SIZE_TUPLE("if"), 2, 3, 0, func_if},
5005 { STRING_SIZE_TUPLE("or"), 1, 0, 0, func_or},
5006 { STRING_SIZE_TUPLE("and"), 1, 0, 0, func_and},
5007 { STRING_SIZE_TUPLE("value"), 0, 1, 1, func_value},
5008 { STRING_SIZE_TUPLE("eval"), 0, 1, 1, func_eval},
5009#ifdef CONFIG_WITH_EVALPLUS
5010 { STRING_SIZE_TUPLE("evalctx"), 0, 1, 1, func_evalctx},
5011 { STRING_SIZE_TUPLE("evalval"), 1, 1, 1, func_evalval},
5012 { STRING_SIZE_TUPLE("evalvalctx"), 1, 1, 1, func_evalval},
5013 { STRING_SIZE_TUPLE("evalcall"), 1, 0, 1, func_call},
5014 { STRING_SIZE_TUPLE("evalcall2"), 1, 0, 1, func_call},
5015 { STRING_SIZE_TUPLE("eval-opt-var"), 1, 0, 1, func_eval_optimize_variable},
5016#endif
5017#ifdef EXPERIMENTAL
5018 { STRING_SIZE_TUPLE("eq"), 2, 2, 1, func_eq},
5019 { STRING_SIZE_TUPLE("not"), 0, 1, 1, func_not},
5020#endif
5021#ifdef CONFIG_WITH_STRING_FUNCTIONS
5022 { STRING_SIZE_TUPLE("length"), 1, 1, 1, func_length},
5023 { STRING_SIZE_TUPLE("length-var"), 1, 1, 1, func_length_var},
5024 { STRING_SIZE_TUPLE("insert"), 2, 5, 1, func_insert},
5025 { STRING_SIZE_TUPLE("pos"), 2, 3, 1, func_pos},
5026 { STRING_SIZE_TUPLE("lastpos"), 2, 3, 1, func_pos},
5027 { STRING_SIZE_TUPLE("substr"), 2, 4, 1, func_substr},
5028 { STRING_SIZE_TUPLE("translate"), 2, 4, 1, func_translate},
5029#endif
5030#ifdef CONFIG_WITH_PRINTF
5031 { STRING_SIZE_TUPLE("printf"), 1, 0, 1, kmk_builtin_func_printf},
5032#endif
5033#ifdef CONFIG_WITH_LAZY_DEPS_VARS
5034 { STRING_SIZE_TUPLE("deps"), 1, 2, 1, func_deps},
5035 { STRING_SIZE_TUPLE("deps-all"), 1, 2, 1, func_deps},
5036 { STRING_SIZE_TUPLE("deps-newer"), 1, 2, 1, func_deps_newer},
5037 { STRING_SIZE_TUPLE("deps-oo"), 1, 2, 1, func_deps_order_only},
5038#endif
5039#ifdef CONFIG_WITH_DEFINED
5040 { STRING_SIZE_TUPLE("defined"), 1, 1, 1, func_defined},
5041#endif
5042#ifdef CONFIG_WITH_TOUPPER_TOLOWER
5043 { STRING_SIZE_TUPLE("toupper"), 0, 1, 1, func_toupper_tolower},
5044 { STRING_SIZE_TUPLE("tolower"), 0, 1, 1, func_toupper_tolower},
5045#endif
5046#ifdef CONFIG_WITH_ABSPATHEX
5047 { STRING_SIZE_TUPLE("abspathex"), 0, 2, 1, func_abspathex},
5048#endif
5049#ifdef CONFIG_WITH_XARGS
5050 { STRING_SIZE_TUPLE("xargs"), 2, 0, 1, func_xargs},
5051#endif
5052#if defined(CONFIG_WITH_VALUE_LENGTH) && defined(CONFIG_WITH_COMPARE)
5053 { STRING_SIZE_TUPLE("comp-vars"), 3, 3, 1, func_comp_vars},
5054 { STRING_SIZE_TUPLE("comp-cmds"), 3, 3, 1, func_comp_vars},
5055 { STRING_SIZE_TUPLE("comp-cmds-ex"), 3, 3, 1, func_comp_cmds_ex},
5056#endif
5057#ifdef CONFIG_WITH_DATE
5058 { STRING_SIZE_TUPLE("date"), 0, 1, 1, func_date},
5059 { STRING_SIZE_TUPLE("date-utc"), 0, 3, 1, func_date},
5060#endif
5061#ifdef CONFIG_WITH_FILE_SIZE
5062 { STRING_SIZE_TUPLE("file-size"), 1, 1, 1, func_file_size},
5063#endif
5064#ifdef CONFIG_WITH_WHICH
5065 { STRING_SIZE_TUPLE("which"), 0, 0, 1, func_which},
5066#endif
5067#ifdef CONFIG_WITH_IF_CONDITIONALS
5068 { STRING_SIZE_TUPLE("expr"), 1, 1, 0, func_expr},
5069 { STRING_SIZE_TUPLE("if-expr"), 2, 3, 0, func_if_expr},
5070 { STRING_SIZE_TUPLE("select"), 2, 0, 0, func_select},
5071#endif
5072#ifdef CONFIG_WITH_SET_CONDITIONALS
5073 { STRING_SIZE_TUPLE("intersects"), 2, 2, 1, func_set_intersects},
5074#endif
5075#ifdef CONFIG_WITH_STACK
5076 { STRING_SIZE_TUPLE("stack-push"), 2, 2, 1, func_stack_push},
5077 { STRING_SIZE_TUPLE("stack-pop"), 1, 1, 1, func_stack_pop_top},
5078 { STRING_SIZE_TUPLE("stack-popv"), 1, 1, 1, func_stack_pop_top},
5079 { STRING_SIZE_TUPLE("stack-top"), 1, 1, 1, func_stack_pop_top},
5080#endif
5081#ifdef CONFIG_WITH_MATH
5082 { STRING_SIZE_TUPLE("int-add"), 2, 0, 1, func_int_add},
5083 { STRING_SIZE_TUPLE("int-sub"), 2, 0, 1, func_int_sub},
5084 { STRING_SIZE_TUPLE("int-mul"), 2, 0, 1, func_int_mul},
5085 { STRING_SIZE_TUPLE("int-div"), 2, 0, 1, func_int_div},
5086 { STRING_SIZE_TUPLE("int-mod"), 2, 2, 1, func_int_mod},
5087 { STRING_SIZE_TUPLE("int-not"), 1, 1, 1, func_int_not},
5088 { STRING_SIZE_TUPLE("int-and"), 2, 0, 1, func_int_and},
5089 { STRING_SIZE_TUPLE("int-or"), 2, 0, 1, func_int_or},
5090 { STRING_SIZE_TUPLE("int-xor"), 2, 0, 1, func_int_xor},
5091 { STRING_SIZE_TUPLE("int-eq"), 2, 2, 1, func_int_cmp},
5092 { STRING_SIZE_TUPLE("int-ne"), 2, 2, 1, func_int_cmp},
5093 { STRING_SIZE_TUPLE("int-gt"), 2, 2, 1, func_int_cmp},
5094 { STRING_SIZE_TUPLE("int-ge"), 2, 2, 1, func_int_cmp},
5095 { STRING_SIZE_TUPLE("int-lt"), 2, 2, 1, func_int_cmp},
5096 { STRING_SIZE_TUPLE("int-le"), 2, 2, 1, func_int_cmp},
5097#endif
5098#ifdef CONFIG_WITH_NANOTS
5099 { STRING_SIZE_TUPLE("nanots"), 0, 0, 0, func_nanots},
5100#endif
5101#ifdef CONFIG_WITH_OS2_LIBPATH
5102 { STRING_SIZE_TUPLE("libpath"), 1, 2, 1, func_os2_libpath},
5103#endif
5104#if defined (CONFIG_WITH_MAKE_STATS) || defined (CONFIG_WITH_MINIMAL_STATS)
5105 { STRING_SIZE_TUPLE("make-stats"), 0, 0, 0, func_make_stats},
5106#endif
5107#ifdef CONFIG_WITH_COMMANDS_FUNC
5108 { STRING_SIZE_TUPLE("commands"), 1, 1, 1, func_commands},
5109 { STRING_SIZE_TUPLE("commands-sc"), 1, 1, 1, func_commands},
5110 { STRING_SIZE_TUPLE("commands-usr"), 2, 2, 1, func_commands},
5111#endif
5112#ifdef KMK_HELPERS
5113 { STRING_SIZE_TUPLE("kb-src-tool"), 1, 1, 0, func_kbuild_source_tool},
5114 { STRING_SIZE_TUPLE("kb-obj-base"), 1, 1, 0, func_kbuild_object_base},
5115 { STRING_SIZE_TUPLE("kb-obj-suff"), 1, 1, 0, func_kbuild_object_suffix},
5116 { STRING_SIZE_TUPLE("kb-src-prop"), 3, 4, 0, func_kbuild_source_prop},
5117 { STRING_SIZE_TUPLE("kb-src-one"), 0, 1, 0, func_kbuild_source_one},
5118 { STRING_SIZE_TUPLE("kb-exp-tmpl"), 6, 6, 1, func_kbuild_expand_template},
5119#endif
5120#ifdef KMK
5121 { STRING_SIZE_TUPLE("breakpoint"), 0, 0, 0, func_breakpoint},
5122#endif
5123};
5124
5125#define FUNCTION_TABLE_ENTRIES (sizeof (function_table_init) / sizeof (struct function_table_entry))
5126
5127
5128
5129/* These must come after the definition of function_table. */
5130
5131static char *
5132expand_builtin_function (char *o, int argc, char **argv,
5133 const struct function_table_entry *entry_p)
5134{
5135 if (argc < (int)entry_p->minimum_args)
5136 fatal (*expanding_var,
5137 _("insufficient number of arguments (%d) to function `%s'"),
5138 argc, entry_p->name);
5139
5140 /* I suppose technically some function could do something with no
5141 arguments, but so far none do, so just test it for all functions here
5142 rather than in each one. We can change it later if necessary. */
5143
5144 if (!argc)
5145 return o;
5146
5147 if (!entry_p->func_ptr)
5148 fatal (*expanding_var,
5149 _("unimplemented on this platform: function `%s'"), entry_p->name);
5150
5151 return entry_p->func_ptr (o, argv, entry_p->name);
5152}
5153
5154/* Check for a function invocation in *STRINGP. *STRINGP points at the
5155 opening ( or { and is not null-terminated. If a function invocation
5156 is found, expand it into the buffer at *OP, updating *OP, incrementing
5157 *STRINGP past the reference and returning nonzero. If not, return zero. */
5158
5159static int
5160handle_function2 (const struct function_table_entry *entry_p, char **op, const char **stringp) /* bird split it up. */
5161{
5162 char openparen = (*stringp)[0];
5163 char closeparen = openparen == '(' ? ')' : '}';
5164 const char *beg;
5165 const char *end;
5166 int count = 0;
5167 char *abeg = NULL;
5168 char **argv, **argvp;
5169 int nargs;
5170
5171 beg = *stringp + 1;
5172
5173 /* We found a builtin function. Find the beginning of its arguments (skip
5174 whitespace after the name). */
5175
5176 beg = next_token (beg + entry_p->len);
5177
5178 /* Find the end of the function invocation, counting nested use of
5179 whichever kind of parens we use. Since we're looking, count commas
5180 to get a rough estimate of how many arguments we might have. The
5181 count might be high, but it'll never be low. */
5182
5183 for (nargs=1, end=beg; *end != '\0'; ++end)
5184 if (*end == ',')
5185 ++nargs;
5186 else if (*end == openparen)
5187 ++count;
5188 else if (*end == closeparen && --count < 0)
5189 break;
5190
5191 if (count >= 0)
5192 fatal (*expanding_var,
5193 _("unterminated call to function `%s': missing `%c'"),
5194 entry_p->name, closeparen);
5195
5196 *stringp = end;
5197
5198 /* Get some memory to store the arg pointers. */
5199 argvp = argv = alloca (sizeof (char *) * (nargs + 2));
5200
5201 /* Chop the string into arguments, then a nul. As soon as we hit
5202 MAXIMUM_ARGS (if it's >0) assume the rest of the string is part of the
5203 last argument.
5204
5205 If we're expanding, store pointers to the expansion of each one. If
5206 not, make a duplicate of the string and point into that, nul-terminating
5207 each argument. */
5208
5209 if (entry_p->expand_args)
5210 {
5211 const char *p;
5212 for (p=beg, nargs=0; p <= end; ++argvp)
5213 {
5214 const char *next;
5215
5216 ++nargs;
5217
5218 if (nargs == entry_p->maximum_args
5219 || (! (next = find_next_argument (openparen, closeparen, p, end))))
5220 next = end;
5221
5222 *argvp = expand_argument (p, next);
5223 p = next + 1;
5224 }
5225 }
5226 else
5227 {
5228 int len = end - beg;
5229 char *p, *aend;
5230
5231 abeg = xmalloc (len+1);
5232 memcpy (abeg, beg, len);
5233 abeg[len] = '\0';
5234 aend = abeg + len;
5235
5236 for (p=abeg, nargs=0; p <= aend; ++argvp)
5237 {
5238 char *next;
5239
5240 ++nargs;
5241
5242 if (nargs == entry_p->maximum_args
5243 || (! (next = find_next_argument (openparen, closeparen, p, aend))))
5244 next = aend;
5245
5246 *argvp = p;
5247 *next = '\0';
5248 p = next + 1;
5249 }
5250 }
5251 *argvp = NULL;
5252
5253 /* Finally! Run the function... */
5254 *op = expand_builtin_function (*op, nargs, argv, entry_p);
5255
5256 /* Free memory. */
5257 if (entry_p->expand_args)
5258 for (argvp=argv; *argvp != 0; ++argvp)
5259 free (*argvp);
5260 if (abeg)
5261 free (abeg);
5262
5263 return 1;
5264}
5265
5266
5267int /* bird split it up and hacked it. */
5268#ifndef CONFIG_WITH_VALUE_LENGTH
5269handle_function (char **op, const char **stringp)
5270{
5271 const struct function_table_entry *entry_p = lookup_function (*stringp + 1);
5272 if (!entry_p)
5273 return 0;
5274 return handle_function2 (entry_p, op, stringp);
5275}
5276#else /* CONFIG_WITH_VALUE_LENGTH */
5277handle_function (char **op, const char **stringp, const char *nameend, const char *eol UNUSED)
5278{
5279 const char *fname = *stringp + 1;
5280 const struct function_table_entry *entry_p =
5281 lookup_function_in_hash_tab (fname, nameend - fname);
5282 if (!entry_p)
5283 return 0;
5284 return handle_function2 (entry_p, op, stringp);
5285}
5286#endif /* CONFIG_WITH_VALUE_LENGTH */
5287
5288
5289
5290/* User-defined functions. Expand the first argument as either a builtin
5291 function or a make variable, in the context of the rest of the arguments
5292 assigned to $1, $2, ... $N. $0 is the name of the function. */
5293
5294static char *
5295func_call (char *o, char **argv, const char *funcname UNUSED)
5296{
5297 static int max_args = 0;
5298 char *fname;
5299 char *cp;
5300 char *body;
5301 int flen;
5302 int i;
5303 int saved_args;
5304 const struct function_table_entry *entry_p;
5305 struct variable *v;
5306#ifdef CONFIG_WITH_EVALPLUS
5307 char *buf;
5308 unsigned int len;
5309#endif
5310#if defined (CONFIG_WITH_EVALPLUS) || defined (CONFIG_WITH_VALUE_LENGTH)
5311 char num[11];
5312#endif
5313
5314 /* There is no way to define a variable with a space in the name, so strip
5315 leading and trailing whitespace as a favor to the user. */
5316 fname = argv[0];
5317 while (*fname != '\0' && isspace ((unsigned char)*fname))
5318 ++fname;
5319
5320 cp = fname + strlen (fname) - 1;
5321 while (cp > fname && isspace ((unsigned char)*cp))
5322 --cp;
5323 cp[1] = '\0';
5324
5325 /* Calling nothing is a no-op */
5326 if (*fname == '\0')
5327 return o;
5328
5329 /* Are we invoking a builtin function? */
5330
5331#ifndef CONFIG_WITH_VALUE_LENGTH
5332 entry_p = lookup_function (fname);
5333#else
5334 entry_p = lookup_function (fname, cp - fname + 1);
5335#endif
5336 if (entry_p)
5337 {
5338 /* How many arguments do we have? */
5339 for (i=0; argv[i+1]; ++i)
5340 ;
5341 return expand_builtin_function (o, i, argv+1, entry_p);
5342 }
5343
5344 /* Not a builtin, so the first argument is the name of a variable to be
5345 expanded and interpreted as a function. Find it. */
5346 flen = strlen (fname);
5347
5348 v = lookup_variable (fname, flen);
5349
5350 if (v == 0)
5351 warn_undefined (fname, flen);
5352
5353 if (v == 0 || *v->value == '\0')
5354 return o;
5355
5356 body = alloca (flen + 4);
5357 body[0] = '$';
5358 body[1] = '(';
5359 memcpy (body + 2, fname, flen);
5360 body[flen+2] = ')';
5361 body[flen+3] = '\0';
5362
5363 /* Set up arguments $(1) .. $(N). $(0) is the function name. */
5364
5365 push_new_variable_scope ();
5366
5367 for (i=0; *argv; ++i, ++argv)
5368#ifdef CONFIG_WITH_VALUE_LENGTH
5369 define_variable (num, sprintf (num, "%d", i), *argv, o_automatic, 0);
5370#else
5371 {
5372 char num[11];
5373
5374 sprintf (num, "%d", i);
5375 define_variable (num, strlen (num), *argv, o_automatic, 0);
5376 }
5377#endif
5378
5379#ifdef CONFIG_WITH_EVALPLUS
5380 /* $(.ARGC) is the argument count. */
5381
5382 len = sprintf (num, "%d", i - 1);
5383 define_variable_vl (".ARGC", sizeof (".ARGC") - 1, num, len,
5384 1 /* dup val */, o_automatic, 0);
5385#endif
5386
5387 /* If the number of arguments we have is < max_args, it means we're inside
5388 a recursive invocation of $(call ...). Fill in the remaining arguments
5389 in the new scope with the empty value, to hide them from this
5390 invocation. */
5391
5392 for (; i < max_args; ++i)
5393#ifdef CONFIG_WITH_VALUE_LENGTH
5394 define_variable (num, sprintf (num, "%d", i), "", o_automatic, 0);
5395#else
5396 {
5397 char num[11];
5398
5399 sprintf (num, "%d", i);
5400 define_variable (num, strlen (num), "", o_automatic, 0);
5401 }
5402#endif
5403
5404 saved_args = max_args;
5405 max_args = i;
5406
5407#ifdef CONFIG_WITH_EVALPLUS
5408 if (!strcmp (funcname, "call"))
5409 {
5410#endif
5411 /* Expand the body in the context of the arguments, adding the result to
5412 the variable buffer. */
5413
5414 v->exp_count = EXP_COUNT_MAX;
5415#ifndef CONFIG_WITH_VALUE_LENGTH
5416 o = variable_expand_string (o, body, flen+3);
5417 v->exp_count = 0;
5418
5419 o += strlen (o);
5420#else /* CONFIG_WITH_VALUE_LENGTH */
5421 variable_expand_string_2 (o, body, flen+3, &o);
5422 v->exp_count = 0;
5423#endif /* CONFIG_WITH_VALUE_LENGTH */
5424#ifdef CONFIG_WITH_EVALPLUS
5425 }
5426 else
5427 {
5428 const struct floc *reading_file_saved = reading_file;
5429 char *eos;
5430
5431 if (!strcmp (funcname, "evalcall"))
5432 {
5433 /* Evaluate the variable value without expanding it. We
5434 need a copy since eval_buffer is destructive. */
5435
5436 size_t off = o - variable_buffer;
5437 eos = variable_buffer_output (o, v->value, v->value_length + 1) - 1;
5438 o = variable_buffer + off;
5439 if (v->fileinfo.filenm)
5440 reading_file = &v->fileinfo;
5441 }
5442 else
5443 {
5444 /* Expand the body first and then evaluate the output. */
5445
5446 v->exp_count = EXP_COUNT_MAX;
5447 o = variable_expand_string_2 (o, body, flen+3, &eos);
5448 v->exp_count = 0;
5449 }
5450
5451 install_variable_buffer (&buf, &len);
5452 eval_buffer (o, eos);
5453 restore_variable_buffer (buf, len);
5454 reading_file = reading_file_saved;
5455
5456 /* Deal with the .RETURN value if present. */
5457
5458 v = lookup_variable_in_set (".RETURN", sizeof (".RETURN") - 1,
5459 current_variable_set_list->set);
5460 if (v && v->value_length)
5461 {
5462 if (v->recursive)
5463 {
5464 v->exp_count = EXP_COUNT_MAX;
5465 variable_expand_string_2 (o, v->value, v->value_length, &o);
5466 v->exp_count = 0;
5467 }
5468 else
5469 o = variable_buffer_output (o, v->value, v->value_length);
5470 }
5471 }
5472#endif /* CONFIG_WITH_EVALPLUS */
5473
5474 max_args = saved_args;
5475
5476 pop_variable_scope ();
5477
5478 return o;
5479}
5480
5481void
5482hash_init_function_table (void)
5483{
5484 hash_init (&function_table, FUNCTION_TABLE_ENTRIES * 2,
5485 function_table_entry_hash_1, function_table_entry_hash_2,
5486 function_table_entry_hash_cmp);
5487 hash_load (&function_table, function_table_init,
5488 FUNCTION_TABLE_ENTRIES, sizeof (struct function_table_entry));
5489#if defined (CONFIG_WITH_OPTIMIZATION_HACKS) || defined (CONFIG_WITH_VALUE_LENGTH)
5490 {
5491 unsigned int i;
5492 for (i = 0; i < FUNCTION_TABLE_ENTRIES; i++)
5493 {
5494 const char *fn = function_table_init[i].name;
5495 while (*fn)
5496 {
5497 func_char_map[(int)*fn] = 1;
5498 fn++;
5499 }
5500 assert (function_table_init[i].len <= MAX_FUNCTION_LENGTH);
5501 assert (function_table_init[i].len >= MIN_FUNCTION_LENGTH);
5502 }
5503 }
5504#endif
5505}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette