VirtualBox

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

Last change on this file since 1947 was 1935, checked in by bird, 16 years ago

kmk: new function - eval-opt-var

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

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