VirtualBox

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

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

kmk: Implemented the where function. Fixes #108.

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

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