source: trunk/src/kmk/function.c@ 2564

Last change on this file since 2564 was 2556, checked in by bird, 14 years ago

umask fixes.

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