VirtualBox

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

最後變更 在這個檔案從2462是 2462,由 bird 提交於 14 年 前

kmk: Implemented . Fixes #81.

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

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