VirtualBox

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

最後變更 在這個檔案從2516是 2516,由 bird 提交於 14 年 前

func_abspathex: Don't crash when no cwd is given. Addressed gcc warnings.

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

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