VirtualBox

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

Last change on this file since 2125 was 2118, checked in by bird, 16 years ago

function.c: warnings.

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

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