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

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

function.c: func_eval_optimize_variable - display error if the variable is of the wrong kind.

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