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

Last change on this file since 2500 was 2495, checked in by bird, 14 years ago

function.c: bugfix in new code.

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