VirtualBox

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

Last change on this file since 2962 was 2912, checked in by bird, 8 years ago

rewrote kmk_redirect to skip the separate process. Added chache invalidation after directory deletion for addressing kmk rebuild and fetching.

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