VirtualBox

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

Last change on this file since 2016 was 2011, checked in by bird, 16 years ago

kmk,footer.kmk: New helper function 'kb-exp-tmpl', 10x faster than the gnu make script.

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

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