VirtualBox

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

Last change on this file since 1956 was 1948, checked in by bird, 17 years ago

kmk: Fixed CONFIG_WITH_LAZY_DEPS_VARS bug. Files with multiple double colon rules cannot be handled lazily in any easy way.

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

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