VirtualBox

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

Last change on this file since 2444 was 2276, checked in by bird, 16 years ago

kmk: Do not crash if $(if-expr ) is missing the 3rd argument, it is supposed to be optional... Fixes #85

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