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

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

function.c: func_eval_optimize_variable - made it build without rdonly_val, and also to refuse automatic variables.

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