VirtualBox

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

Last change on this file since 3432 was 3415, checked in by bird, 5 years ago

kmk: Fixed mixup from r2433 where _TARGET_TOOL was extended but the builtin source handling functions wasn't. For instance, using _TOOLS, _TOOLS.amd64 and _TOOLS.x86, we would end up with the first when compiling and one of the latter two when linking. Also replaced a few legacy BUILD_PLATFORM* with KBUILD_HOST* variable names in the footers.

  • Property svn:eol-style set to native
File size: 225.3 KB
Line 
1/* Builtin function expansion for GNU Make.
2Copyright (C) 1988-2016 Free Software Foundation, Inc.
3This file is part of GNU Make.
4
5GNU Make is free software; you can redistribute it and/or modify it under the
6terms of the GNU General Public License as published by the Free Software
7Foundation; either version 3 of the License, or (at your option) any later
8version.
9
10GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
11WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License along with
15this program. If not, see <http://www.gnu.org/licenses/>. */
16
17#include "makeint.h"
18#include "filedef.h"
19#include "variable.h"
20#include "dep.h"
21#include "job.h"
22#include "commands.h"
23#include "debug.h"
24
25#ifdef _AMIGA
26#include "amiga.h"
27#endif
28
29#ifdef WINDOWS32 /* bird */
30# include "pathstuff.h"
31# ifdef CONFIG_NEW_WIN_CHILDREN
32# include "w32/winchildren.h"
33# endif
34#endif
35
36#ifdef KMK_HELPERS
37# include "kbuild.h"
38#endif
39#ifdef CONFIG_WITH_PRINTF
40# include "kmkbuiltin.h"
41#endif
42#ifdef CONFIG_WITH_XARGS /* bird */
43# ifdef HAVE_LIMITS_H
44# include <limits.h>
45# endif
46#endif
47#ifdef CONFIG_WITH_COMPILER
48# include "kmk_cc_exec.h"
49#endif
50#include <assert.h> /* bird */
51
52#if defined (CONFIG_WITH_MATH) || defined (CONFIG_WITH_NANOTS) || defined (CONFIG_WITH_FILE_SIZE) /* bird */
53# include <ctype.h>
54typedef big_int math_int;
55static char *math_int_to_variable_buffer (char *, math_int);
56static math_int math_int_from_string (const char *str);
57#endif
58
59#ifdef CONFIG_WITH_NANOTS /* bird */
60# ifdef WINDOWS32
61# include <Windows.h>
62# endif
63#endif
64
65#ifdef __OS2__
66# define CONFIG_WITH_OS2_LIBPATH 1
67#endif
68#ifdef CONFIG_WITH_OS2_LIBPATH
69# define INCL_BASE
70# define INCL_ERRROS
71# include <os2.h>
72
73# define QHINF_EXEINFO 1 /* NE exeinfo. */
74# define QHINF_READRSRCTBL 2 /* Reads from the resource table. */
75# define QHINF_READFILE 3 /* Reads from the executable file. */
76# define QHINF_LIBPATHLENGTH 4 /* Gets the libpath length. */
77# define QHINF_LIBPATH 5 /* Gets the entire libpath. */
78# define QHINF_FIXENTRY 6 /* NE only */
79# define QHINF_STE 7 /* NE only */
80# define QHINF_MAPSEL 8 /* NE only */
81 extern APIRET APIENTRY DosQueryHeaderInfo(HMODULE hmod, ULONG ulIndex, PVOID pvBuffer, ULONG cbBuffer, ULONG ulSubFunction);
82#endif /* CONFIG_WITH_OS2_LIBPATH */
83
84#ifdef KMK
85/** Checks if the @a_cch characters (bytes) in @a a_psz equals @a a_szConst. */
86# define STR_N_EQUALS(a_psz, a_cch, a_szConst) \
87 ( (a_cch) == sizeof (a_szConst) - 1 && !strncmp ((a_psz), (a_szConst), sizeof (a_szConst) - 1) )
88
89# ifdef _MSC_VER
90# include "kmkbuiltin/mscfakes.h"
91# endif
92# include "version_compare.h"
93#endif
94
95
96struct function_table_entry
97 {
98 union {
99 char *(*func_ptr) (char *output, char **argv, const char *fname);
100 gmk_func_ptr alloc_func_ptr;
101 } fptr;
102 const char *name;
103 unsigned char len;
104 unsigned char minimum_args;
105 unsigned char maximum_args;
106 unsigned char expand_args:1;
107 unsigned char alloc_fn:1;
108 };
109
110static unsigned long
111function_table_entry_hash_1 (const void *keyv)
112{
113 const struct function_table_entry *key = keyv;
114 return_STRING_N_HASH_1 (key->name, key->len);
115}
116
117static unsigned long
118function_table_entry_hash_2 (const void *keyv)
119{
120 const struct function_table_entry *key = keyv;
121 return_STRING_N_HASH_2 (key->name, key->len);
122}
123
124static int
125function_table_entry_hash_cmp (const void *xv, const void *yv)
126{
127 const struct function_table_entry *x = xv;
128 const struct function_table_entry *y = yv;
129 int result = x->len - y->len;
130 if (result)
131 return result;
132 return_STRING_N_COMPARE (x->name, y->name, x->len);
133}
134
135static struct hash_table function_table;
136
137#ifdef CONFIG_WITH_MAKE_STATS
138long make_stats_allocations = 0;
139long make_stats_reallocations = 0;
140unsigned long make_stats_allocated = 0;
141unsigned long make_stats_ht_lookups = 0;
142unsigned long make_stats_ht_collisions = 0;
143#endif
144
145
146
147/* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing
148 each occurrence of SUBST with REPLACE. TEXT is null-terminated. SLEN is
149 the length of SUBST and RLEN is the length of REPLACE. If BY_WORD is
150 nonzero, substitutions are done only on matches which are complete
151 whitespace-delimited words. */
152
153char *
154subst_expand (char *o, const char *text, const char *subst, const char *replace,
155 unsigned int slen, unsigned int rlen, int by_word)
156{
157 const char *t = text;
158 const char *p;
159
160 if (slen == 0 && !by_word)
161 {
162 /* The first occurrence of "" in any string is its end. */
163 o = variable_buffer_output (o, t, strlen (t));
164 if (rlen > 0)
165 o = variable_buffer_output (o, replace, rlen);
166 return o;
167 }
168
169 do
170 {
171 if (by_word && slen == 0)
172 /* When matching by words, the empty string should match
173 the end of each word, rather than the end of the whole text. */
174 p = end_of_token (next_token (t));
175 else
176 {
177 p = strstr (t, subst);
178 if (p == 0)
179 {
180 /* No more matches. Output everything left on the end. */
181 o = variable_buffer_output (o, t, strlen (t));
182 return o;
183 }
184 }
185
186 /* Output everything before this occurrence of the string to replace. */
187 if (p > t)
188 o = variable_buffer_output (o, t, p - t);
189
190 /* If we're substituting only by fully matched words,
191 or only at the ends of words, check that this case qualifies. */
192 if (by_word
193 && ((p > text && !ISSPACE (p[-1]))
194 || ! STOP_SET (p[slen], MAP_SPACE|MAP_NUL)))
195 /* Struck out. Output the rest of the string that is
196 no longer to be replaced. */
197 o = variable_buffer_output (o, subst, slen);
198 else if (rlen > 0)
199 /* Output the replacement string. */
200 o = variable_buffer_output (o, replace, rlen);
201
202 /* Advance T past the string to be replaced. */
203 t = p + slen;
204 } while (*t != '\0');
205
206 return o;
207}
208
209
210
211/* Store into VARIABLE_BUFFER at O the result of scanning TEXT
212 and replacing strings matching PATTERN with REPLACE.
213 If PATTERN_PERCENT is not nil, PATTERN has already been
214 run through find_percent, and PATTERN_PERCENT is the result.
215 If REPLACE_PERCENT is not nil, REPLACE has already been
216 run through find_percent, and REPLACE_PERCENT is the result.
217 Note that we expect PATTERN_PERCENT and REPLACE_PERCENT to point to the
218 character _AFTER_ the %, not to the % itself.
219*/
220
221char *
222patsubst_expand_pat (char *o, const char *text,
223 const char *pattern, const char *replace,
224 const char *pattern_percent, const char *replace_percent)
225{
226 unsigned int pattern_prepercent_len, pattern_postpercent_len;
227 unsigned int replace_prepercent_len, replace_postpercent_len;
228 const char *t;
229 unsigned int len;
230 int doneany = 0;
231
232 /* Record the length of REPLACE before and after the % so we don't have to
233 compute these lengths more than once. */
234 if (replace_percent)
235 {
236 replace_prepercent_len = replace_percent - replace - 1;
237 replace_postpercent_len = strlen (replace_percent);
238 }
239 else
240 {
241 replace_prepercent_len = strlen (replace);
242 replace_postpercent_len = 0;
243 }
244
245 if (!pattern_percent)
246 /* With no % in the pattern, this is just a simple substitution. */
247 return subst_expand (o, text, pattern, replace,
248 strlen (pattern), strlen (replace), 1);
249
250 /* Record the length of PATTERN before and after the %
251 so we don't have to compute it more than once. */
252 pattern_prepercent_len = pattern_percent - pattern - 1;
253 pattern_postpercent_len = strlen (pattern_percent);
254
255 while ((t = find_next_token (&text, &len)) != 0)
256 {
257 int fail = 0;
258
259 /* Is it big enough to match? */
260 if (len < pattern_prepercent_len + pattern_postpercent_len)
261 fail = 1;
262
263 /* Does the prefix match? */
264 if (!fail && pattern_prepercent_len > 0
265 && (*t != *pattern
266 || t[pattern_prepercent_len - 1] != pattern_percent[-2]
267 || !strneq (t + 1, pattern + 1, pattern_prepercent_len - 1)))
268 fail = 1;
269
270 /* Does the suffix match? */
271 if (!fail && pattern_postpercent_len > 0
272 && (t[len - 1] != pattern_percent[pattern_postpercent_len - 1]
273 || t[len - pattern_postpercent_len] != *pattern_percent
274 || !strneq (&t[len - pattern_postpercent_len],
275 pattern_percent, pattern_postpercent_len - 1)))
276 fail = 1;
277
278 if (fail)
279 /* It didn't match. Output the string. */
280 o = variable_buffer_output (o, t, len);
281 else
282 {
283 /* It matched. Output the replacement. */
284
285 /* Output the part of the replacement before the %. */
286 o = variable_buffer_output (o, replace, replace_prepercent_len);
287
288 if (replace_percent != 0)
289 {
290 /* Output the part of the matched string that
291 matched the % in the pattern. */
292 o = variable_buffer_output (o, t + pattern_prepercent_len,
293 len - (pattern_prepercent_len
294 + pattern_postpercent_len));
295 /* Output the part of the replacement after the %. */
296 o = variable_buffer_output (o, replace_percent,
297 replace_postpercent_len);
298 }
299 }
300
301 /* Output a space, but not if the replacement is "". */
302 if (fail || replace_prepercent_len > 0
303 || (replace_percent != 0 && len + replace_postpercent_len > 0))
304 {
305 o = variable_buffer_output (o, " ", 1);
306 doneany = 1;
307 }
308 }
309#ifndef CONFIG_WITH_VALUE_LENGTH
310 if (doneany)
311 /* Kill the last space. */
312 --o;
313#else
314 /* Kill the last space and make sure there is a terminator there
315 so that strcache_add_len doesn't have to do a lot of exacty work
316 when expand_deps sends the output its way. */
317 if (doneany)
318 *--o = '\0';
319 else
320 o = variable_buffer_output (o, "\0", 1) - 1;
321#endif
322
323 return o;
324}
325
326/* Store into VARIABLE_BUFFER at O the result of scanning TEXT
327 and replacing strings matching PATTERN with REPLACE.
328 If PATTERN_PERCENT is not nil, PATTERN has already been
329 run through find_percent, and PATTERN_PERCENT is the result.
330 If REPLACE_PERCENT is not nil, REPLACE has already been
331 run through find_percent, and REPLACE_PERCENT is the result.
332 Note that we expect PATTERN_PERCENT and REPLACE_PERCENT to point to the
333 character _AFTER_ the %, not to the % itself.
334*/
335
336char *
337patsubst_expand (char *o, const char *text, char *pattern, char *replace)
338{
339 const char *pattern_percent = find_percent (pattern);
340 const char *replace_percent = find_percent (replace);
341
342 /* If there's a percent in the pattern or replacement skip it. */
343 if (replace_percent)
344 ++replace_percent;
345 if (pattern_percent)
346 ++pattern_percent;
347
348 return patsubst_expand_pat (o, text, pattern, replace,
349 pattern_percent, replace_percent);
350}
351
352
353#if defined (CONFIG_WITH_OPTIMIZATION_HACKS) || defined (CONFIG_WITH_VALUE_LENGTH)
354
355/* Char map containing the valid function name characters. */
356char func_char_map[256];
357
358/* Do the hash table lookup. */
359
360MY_INLINE const struct function_table_entry *
361lookup_function_in_hash_tab (const char *s, unsigned char len)
362{
363 struct function_table_entry function_table_entry_key;
364 function_table_entry_key.name = s;
365 function_table_entry_key.len = len;
366
367 return hash_find_item (&function_table, &function_table_entry_key);
368}
369
370/* Look up a function by name. */
371
372MY_INLINE const struct function_table_entry *
373lookup_function (const char *s, unsigned int len)
374{
375 unsigned char ch;
376# if 0 /* insane loop unroll */
377
378 if (len > MAX_FUNCTION_LENGTH)
379 len = MAX_FUNCTION_LENGTH + 1;
380
381# define X(idx) \
382 if (!func_char_map[ch = s[idx]]) \
383 { \
384 if (ISBLANK (ch)) \
385 return lookup_function_in_hash_tab (s, idx); \
386 return 0; \
387 }
388# define Z(idx) \
389 return lookup_function_in_hash_tab (s, idx);
390
391 switch (len)
392 {
393 default:
394 assert (0);
395 case 0: return 0;
396 case 1: return 0;
397 case 2: X(0); X(1); Z(2);
398 case 3: X(0); X(1); X(2); Z(3);
399 case 4: X(0); X(1); X(2); X(3); Z(4);
400 case 5: X(0); X(1); X(2); X(3); X(4); Z(5);
401 case 6: X(0); X(1); X(2); X(3); X(4); X(5); Z(6);
402 case 7: X(0); X(1); X(2); X(3); X(4); X(5); X(6); Z(7);
403 case 8: X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); Z(8);
404 case 9: X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); X(8); Z(9);
405 case 10: X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); X(8); X(9); Z(10);
406 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);
407 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);
408 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);
409 if ((ch = s[12]) == '\0' || ISBLANK (ch))
410 return lookup_function_in_hash_tab (s, 12);
411 return 0;
412 }
413# undef Z
414# undef X
415
416# else /* normal loop */
417 const char *e = s;
418 if (len > MAX_FUNCTION_LENGTH)
419 len = MAX_FUNCTION_LENGTH;
420 while (func_char_map[ch = *e])
421 {
422 if (!len--)
423 return 0;
424 e++;
425 }
426 if (ch == '\0' || ISBLANK (ch))
427 return lookup_function_in_hash_tab (s, e - s);
428 return 0;
429# endif /* normal loop */
430}
431
432#else /* original code */
433/* Look up a function by name. */
434
435static const struct function_table_entry *
436lookup_function (const char *s)
437{
438 struct function_table_entry function_table_entry_key;
439 const char *e = s;
440 while (STOP_SET (*e, MAP_USERFUNC))
441 e++;
442
443 if (e == s || !STOP_SET(*e, MAP_NUL|MAP_SPACE))
444 return NULL;
445
446 function_table_entry_key.name = s;
447 function_table_entry_key.len = e - s;
448
449 return hash_find_item (&function_table, &function_table_entry_key);
450}
451#endif /* original code */
452
453
454
455/* Return 1 if PATTERN matches STR, 0 if not. */
456
457int
458pattern_matches (const char *pattern, const char *percent, const char *str)
459{
460 unsigned int sfxlen, strlength;
461
462 if (percent == 0)
463 {
464 unsigned int len = strlen (pattern) + 1;
465 char *new_chars = alloca (len);
466 memcpy (new_chars, pattern, len);
467 percent = find_percent (new_chars);
468 if (percent == 0)
469 return streq (new_chars, str);
470 pattern = new_chars;
471 }
472
473 sfxlen = strlen (percent + 1);
474 strlength = strlen (str);
475
476 if (strlength < (percent - pattern) + sfxlen
477 || !strneq (pattern, str, percent - pattern))
478 return 0;
479
480 return !strcmp (percent + 1, str + (strlength - sfxlen));
481}
482
483
484
485/* Find the next comma or ENDPAREN (counting nested STARTPAREN and
486 ENDPARENtheses), starting at PTR before END. Return a pointer to
487 next character.
488
489 If no next argument is found, return NULL.
490*/
491
492static char *
493find_next_argument (char startparen, char endparen,
494 const char *ptr, const char *end)
495{
496 int count = 0;
497
498 for (; ptr < end; ++ptr)
499 if (*ptr == startparen)
500 ++count;
501
502 else if (*ptr == endparen)
503 {
504 --count;
505 if (count < 0)
506 return NULL;
507 }
508
509 else if (*ptr == ',' && !count)
510 return (char *)ptr;
511
512 /* We didn't find anything. */
513 return NULL;
514}
515
516
517
518/* Glob-expand LINE. The returned pointer is
519 only good until the next call to string_glob. */
520
521static char *
522string_glob (char *line)
523{
524 static char *result = 0;
525 static unsigned int length;
526 struct nameseq *chain;
527 unsigned int idx;
528
529 chain = PARSE_FILE_SEQ (&line, struct nameseq, MAP_NUL, NULL,
530 /* We do not want parse_file_seq to strip './'s.
531 That would break examples like:
532 $(patsubst ./%.c,obj/%.o,$(wildcard ./?*.c)). */
533 PARSEFS_NOSTRIP|PARSEFS_NOCACHE|PARSEFS_EXISTS);
534
535 if (result == 0)
536 {
537 length = 100;
538 result = xmalloc (100);
539 }
540
541 idx = 0;
542 while (chain != 0)
543 {
544 struct nameseq *next = chain->next;
545 unsigned int len = strlen (chain->name);
546
547 if (idx + len + 1 > length)
548 {
549 length += (len + 1) * 2;
550 result = xrealloc (result, length);
551 }
552 memcpy (&result[idx], chain->name, len);
553 idx += len;
554 result[idx++] = ' ';
555
556 /* Because we used PARSEFS_NOCACHE above, we have to free() NAME. */
557 free ((char *)chain->name);
558#ifndef CONFIG_WITH_ALLOC_CACHES
559 free (chain);
560#else
561 alloccache_free (&nameseq_cache, chain);
562#endif
563 chain = next;
564 }
565
566 /* Kill the last space and terminate the string. */
567 if (idx == 0)
568 result[0] = '\0';
569 else
570 result[idx - 1] = '\0';
571
572 return result;
573}
574
575
576/*
577 Builtin functions
578 */
579
580static char *
581func_patsubst (char *o, char **argv, const char *funcname UNUSED)
582{
583 o = patsubst_expand (o, argv[2], argv[0], argv[1]);
584 return o;
585}
586
587
588static char *
589func_join (char *o, char **argv, const char *funcname UNUSED)
590{
591 int doneany = 0;
592
593 /* Write each word of the first argument directly followed
594 by the corresponding word of the second argument.
595 If the two arguments have a different number of words,
596 the excess words are just output separated by blanks. */
597 const char *tp;
598 const char *pp;
599 const char *list1_iterator = argv[0];
600 const char *list2_iterator = argv[1];
601 do
602 {
603 unsigned int len1, len2;
604
605 tp = find_next_token (&list1_iterator, &len1);
606 if (tp != 0)
607 o = variable_buffer_output (o, tp, len1);
608
609 pp = find_next_token (&list2_iterator, &len2);
610 if (pp != 0)
611 o = variable_buffer_output (o, pp, len2);
612
613 if (tp != 0 || pp != 0)
614 {
615 o = variable_buffer_output (o, " ", 1);
616 doneany = 1;
617 }
618 }
619 while (tp != 0 || pp != 0);
620 if (doneany)
621 /* Kill the last blank. */
622 --o;
623
624 return o;
625}
626
627
628static char *
629func_origin (char *o, char **argv, const char *funcname UNUSED)
630{
631 /* Expand the argument. */
632 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
633 if (v == 0)
634 o = variable_buffer_output (o, "undefined", 9);
635 else
636 switch (v->origin)
637 {
638 default:
639 case o_invalid:
640 abort ();
641 break;
642 case o_default:
643 o = variable_buffer_output (o, "default", 7);
644 break;
645 case o_env:
646 o = variable_buffer_output (o, "environment", 11);
647 break;
648 case o_file:
649 o = variable_buffer_output (o, "file", 4);
650 break;
651 case o_env_override:
652 o = variable_buffer_output (o, "environment override", 20);
653 break;
654 case o_command:
655 o = variable_buffer_output (o, "command line", 12);
656 break;
657 case o_override:
658 o = variable_buffer_output (o, "override", 8);
659 break;
660 case o_automatic:
661 o = variable_buffer_output (o, "automatic", 9);
662 break;
663#ifdef CONFIG_WITH_LOCAL_VARIABLES
664 case o_local:
665 o = variable_buffer_output (o, "local", 5);
666 break;
667#endif
668 }
669
670 return o;
671}
672
673static char *
674func_flavor (char *o, char **argv, const char *funcname UNUSED)
675{
676 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
677
678 if (v == 0)
679 o = variable_buffer_output (o, "undefined", 9);
680 else
681 if (v->recursive)
682 o = variable_buffer_output (o, "recursive", 9);
683 else
684 o = variable_buffer_output (o, "simple", 6);
685
686 return o;
687}
688
689#ifdef CONFIG_WITH_WHERE_FUNCTION
690static char *
691func_where (char *o, char **argv, const char *funcname UNUSED)
692{
693 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
694 char buf[64];
695
696 if (v == 0)
697 o = variable_buffer_output (o, "undefined", 9);
698 else
699 if (v->fileinfo.filenm)
700 {
701 o = variable_buffer_output (o, v->fileinfo.filenm, strlen(v->fileinfo.filenm));
702 sprintf (buf, ":%lu", v->fileinfo.lineno);
703 o = variable_buffer_output (o, buf, strlen(buf));
704 }
705 else
706 o = variable_buffer_output (o, "no-location", 11);
707
708 return o;
709}
710#endif /* CONFIG_WITH_WHERE_FUNCTION */
711
712static char *
713func_notdir_suffix (char *o, char **argv, const char *funcname)
714{
715 /* Expand the argument. */
716 const char *list_iterator = argv[0];
717 const char *p2;
718 int doneany =0;
719 unsigned int len=0;
720
721 int is_suffix = funcname[0] == 's';
722 int is_notdir = !is_suffix;
723 int stop = MAP_DIRSEP | (is_suffix ? MAP_DOT : 0);
724#ifdef VMS
725 /* For VMS list_iterator points to a comma separated list. To use the common
726 [find_]next_token, create a local copy and replace the commas with
727 spaces. Obviously, there is a problem if there is a ',' in the VMS filename
728 (can only happen on ODS5), the same problem as with spaces in filenames,
729 which seems to be present in make on all platforms. */
730 char *vms_list_iterator = alloca(strlen(list_iterator) + 1);
731 int i;
732 for (i = 0; list_iterator[i]; i++)
733 if (list_iterator[i] == ',')
734 vms_list_iterator[i] = ' ';
735 else
736 vms_list_iterator[i] = list_iterator[i];
737 vms_list_iterator[i] = list_iterator[i];
738 while ((p2 = find_next_token((const char**) &vms_list_iterator, &len)) != 0)
739#else
740 while ((p2 = find_next_token (&list_iterator, &len)) != 0)
741#endif
742 {
743 const char *p = p2 + len - 1;
744
745 while (p >= p2 && ! STOP_SET (*p, stop))
746 --p;
747
748 if (p >= p2)
749 {
750 if (is_notdir)
751 ++p;
752 else if (*p != '.')
753 continue;
754 o = variable_buffer_output (o, p, len - (p - p2));
755 }
756#ifdef HAVE_DOS_PATHS
757 /* Handle the case of "d:foo/bar". */
758 else if (is_notdir && p2[0] && p2[1] == ':')
759 {
760 p = p2 + 2;
761 o = variable_buffer_output (o, p, len - (p - p2));
762 }
763#endif
764 else if (is_notdir)
765 o = variable_buffer_output (o, p2, len);
766
767 if (is_notdir || p >= p2)
768 {
769#ifdef VMS
770 if (vms_comma_separator)
771 o = variable_buffer_output (o, ",", 1);
772 else
773#endif
774 o = variable_buffer_output (o, " ", 1);
775
776 doneany = 1;
777 }
778 }
779
780 if (doneany)
781 /* Kill last space. */
782 --o;
783
784 return o;
785}
786
787
788static char *
789func_basename_dir (char *o, char **argv, const char *funcname)
790{
791 /* Expand the argument. */
792 const char *p3 = argv[0];
793 const char *p2;
794 int doneany = 0;
795 unsigned int len = 0;
796
797 int is_basename = funcname[0] == 'b';
798 int is_dir = !is_basename;
799 int stop = MAP_DIRSEP | (is_basename ? MAP_DOT : 0) | MAP_NUL;
800#ifdef VMS
801 /* As in func_notdir_suffix ... */
802 char *vms_p3 = alloca (strlen(p3) + 1);
803 int i;
804 for (i = 0; p3[i]; i++)
805 if (p3[i] == ',')
806 vms_p3[i] = ' ';
807 else
808 vms_p3[i] = p3[i];
809 vms_p3[i] = p3[i];
810 while ((p2 = find_next_token((const char**) &vms_p3, &len)) != 0)
811#else
812 while ((p2 = find_next_token (&p3, &len)) != 0)
813#endif
814 {
815 const char *p = p2 + len - 1;
816 while (p >= p2 && ! STOP_SET (*p, stop))
817 --p;
818
819 if (p >= p2 && (is_dir))
820 o = variable_buffer_output (o, p2, ++p - p2);
821 else if (p >= p2 && (*p == '.'))
822 o = variable_buffer_output (o, p2, p - p2);
823#ifdef HAVE_DOS_PATHS
824 /* Handle the "d:foobar" case */
825 else if (p2[0] && p2[1] == ':' && is_dir)
826 o = variable_buffer_output (o, p2, 2);
827#endif
828 else if (is_dir)
829#ifdef VMS
830 {
831 extern int vms_report_unix_paths;
832 if (vms_report_unix_paths)
833 o = variable_buffer_output (o, "./", 2);
834 else
835 o = variable_buffer_output (o, "[]", 2);
836 }
837#else
838#ifndef _AMIGA
839 o = variable_buffer_output (o, "./", 2);
840#else
841 ; /* Just a nop... */
842#endif /* AMIGA */
843#endif /* !VMS */
844 else
845 /* The entire name is the basename. */
846 o = variable_buffer_output (o, p2, len);
847
848#ifdef VMS
849 if (vms_comma_separator)
850 o = variable_buffer_output (o, ",", 1);
851 else
852#endif
853 o = variable_buffer_output (o, " ", 1);
854 doneany = 1;
855 }
856
857 if (doneany)
858 /* Kill last space. */
859 --o;
860
861 return o;
862}
863
864#if 1 /* rewrite to new MAP stuff? */
865# ifdef VMS
866# define IS_PATHSEP(c) ((c) == ']')
867# else
868# ifdef HAVE_DOS_PATHS
869# define IS_PATHSEP(c) ((c) == '/' || (c) == '\\')
870# else
871# define IS_PATHSEP(c) ((c) == '/')
872# endif
873# endif
874#endif
875
876#ifdef CONFIG_WITH_ROOT_FUNC
877
878/*
879 $(root path)
880
881 This is mainly for dealing with drive letters and UNC paths on Windows
882 and OS/2.
883 */
884static char *
885func_root (char *o, char **argv, const char *funcname UNUSED)
886{
887 const char *paths = argv[0] ? argv[0] : "";
888 int doneany = 0;
889 const char *p;
890 unsigned int len;
891
892 while ((p = find_next_token (&paths, &len)) != 0)
893 {
894 const char *p2 = p;
895
896# ifdef HAVE_DOS_PATHS
897 if ( len >= 2
898 && p2[1] == ':'
899 && ( (p2[0] >= 'A' && p2[0] <= 'Z')
900 || (p2[0] >= 'a' && p2[0] <= 'z')))
901 {
902 p2 += 2;
903 len -= 2;
904 }
905 else if (len >= 4 && IS_PATHSEP(p2[0]) && IS_PATHSEP(p2[1])
906 && !IS_PATHSEP(p2[2]))
907 {
908 /* Min recognized UNC: "//./" - find the next slash
909 Typical root: "//srv/shr/" */
910 /* XXX: Check if //./ needs special handling. */
911
912 p2 += 3;
913 len -= 3;
914 while (len > 0 && !IS_PATHSEP(*p2))
915 p2++, len--;
916
917 if (len && IS_PATHSEP(p2[0]) && (len == 1 || !IS_PATHSEP(p2[1])))
918 {
919 p2++;
920 len--;
921
922 if (len) /* optional share */
923 while (len > 0 && !IS_PATHSEP(*p2))
924 p2++, len--;
925 }
926 else
927 p2 = NULL;
928 }
929 else if (IS_PATHSEP(*p2))
930 {
931 p2++;
932 len--;
933 }
934 else
935 p2 = NULL;
936
937# elif defined (VMS) || defined (AMGIA)
938 /* XXX: VMS and AMGIA */
939 O (fatal, NILF, _("$(root ) is not implemented on this platform"));
940# else
941 if (IS_PATHSEP(*p2))
942 {
943 p2++;
944 len--;
945 }
946 else
947 p2 = NULL;
948# endif
949 if (p2 != NULL)
950 {
951 /* Include all subsequent path separators. */
952
953 while (len > 0 && IS_PATHSEP(*p2))
954 p2++, len--;
955 o = variable_buffer_output (o, p, p2 - p);
956 o = variable_buffer_output (o, " ", 1);
957 doneany = 1;
958 }
959 }
960
961 if (doneany)
962 /* Kill last space. */
963 --o;
964
965 return o;
966}
967
968/*
969 $(notroot path)
970
971 This is mainly for dealing with drive letters and UNC paths on Windows
972 and OS/2.
973 */
974static char *
975func_notroot (char *o, char **argv, const char *funcname UNUSED)
976{
977 const char *paths = argv[0] ? argv[0] : "";
978 int doneany = 0;
979 const char *p;
980 unsigned int len;
981
982 while ((p = find_next_token (&paths, &len)) != 0)
983 {
984 const char *p2 = p;
985
986# ifdef HAVE_DOS_PATHS
987 if ( len >= 2
988 && p2[1] == ':'
989 && ( (p2[0] >= 'A' && p2[0] <= 'Z')
990 || (p2[0] >= 'a' && p2[0] <= 'z')))
991 {
992 p2 += 2;
993 len -= 2;
994 }
995 else if (len >= 4 && IS_PATHSEP(p2[0]) && IS_PATHSEP(p2[1])
996 && !IS_PATHSEP(p2[2]))
997 {
998 /* Min recognized UNC: "//./" - find the next slash
999 Typical root: "//srv/shr/" */
1000 /* XXX: Check if //./ needs special handling. */
1001 unsigned int saved_len = len;
1002
1003 p2 += 3;
1004 len -= 3;
1005 while (len > 0 && !IS_PATHSEP(*p2))
1006 p2++, len--;
1007
1008 if (len && IS_PATHSEP(p2[0]) && (len == 1 || !IS_PATHSEP(p2[1])))
1009 {
1010 p2++;
1011 len--;
1012
1013 if (len) /* optional share */
1014 while (len > 0 && !IS_PATHSEP(*p2))
1015 p2++, len--;
1016 }
1017 else
1018 {
1019 p2 = p;
1020 len = saved_len;
1021 }
1022 }
1023
1024# elif defined (VMS) || defined (AMGIA)
1025 /* XXX: VMS and AMGIA */
1026 O (fatal, NILF, _("$(root ) is not implemented on this platform"));
1027# endif
1028
1029 /* Exclude all subsequent / leading path separators. */
1030
1031 while (len > 0 && IS_PATHSEP(*p2))
1032 p2++, len--;
1033 if (len > 0)
1034 o = variable_buffer_output (o, p2, len);
1035 else
1036 o = variable_buffer_output (o, ".", 1);
1037 o = variable_buffer_output (o, " ", 1);
1038 doneany = 1;
1039 }
1040
1041 if (doneany)
1042 /* Kill last space. */
1043 --o;
1044
1045 return o;
1046}
1047
1048#endif /* CONFIG_WITH_ROOT_FUNC */
1049
1050static char *
1051func_addsuffix_addprefix (char *o, char **argv, const char *funcname)
1052{
1053 int fixlen = strlen (argv[0]);
1054 const char *list_iterator = argv[1];
1055 int is_addprefix = funcname[3] == 'p';
1056 int is_addsuffix = !is_addprefix;
1057
1058 int doneany = 0;
1059 const char *p;
1060 unsigned int len;
1061
1062 while ((p = find_next_token (&list_iterator, &len)) != 0)
1063 {
1064 if (is_addprefix)
1065 o = variable_buffer_output (o, argv[0], fixlen);
1066 o = variable_buffer_output (o, p, len);
1067 if (is_addsuffix)
1068 o = variable_buffer_output (o, argv[0], fixlen);
1069 o = variable_buffer_output (o, " ", 1);
1070 doneany = 1;
1071 }
1072
1073 if (doneany)
1074 /* Kill last space. */
1075 --o;
1076
1077 return o;
1078}
1079
1080static char *
1081func_subst (char *o, char **argv, const char *funcname UNUSED)
1082{
1083 o = subst_expand (o, argv[2], argv[0], argv[1], strlen (argv[0]),
1084 strlen (argv[1]), 0);
1085
1086 return o;
1087}
1088
1089#ifdef CONFIG_WITH_DEFINED_FUNCTIONS
1090
1091/* Used by func_firstdefined and func_lastdefined to parse the optional last
1092 argument. Returns 0 if the variable name is to be returned and 1 if it's
1093 the variable value value. */
1094static int
1095parse_value_name_argument (const char *arg1, const char *funcname)
1096{
1097 const char *end;
1098 int rc;
1099
1100 if (arg1 == NULL)
1101 return 0;
1102
1103 end = strchr (arg1, '\0');
1104 strip_whitespace (&arg1, &end);
1105
1106 if (!strncmp (arg1, "name", end - arg1))
1107 rc = 0;
1108 else if (!strncmp (arg1, "value", end - arg1))
1109 rc = 1;
1110 else
1111# if 1 /* FIXME: later */
1112 OSS (fatal, *expanding_var,
1113 _("second argument to `%s' function must be `name' or `value', not `%s'"),
1114 funcname, arg1);
1115# else
1116 {
1117 /* check the expanded form */
1118 char *exp = expand_argument (arg1, strchr (arg1, '\0'));
1119 arg1 = exp;
1120 end = strchr (arg1, '\0');
1121 strip_whitespace (&arg1, &end);
1122
1123 if (!strncmp (arg1, "name", end - arg1))
1124 rc = 0;
1125 else if (!strncmp (arg1, "value", end - arg1))
1126 rc = 1;
1127 else
1128 OSS (fatal, *expanding_var,
1129 _("second argument to `%s' function must be `name' or `value', not `%s'"),
1130 funcname, exp);
1131 free (exp);
1132 }
1133# endif
1134
1135 return rc;
1136}
1137
1138/* Given a list of variable names (ARGV[0]), returned the first variable which
1139 is defined (i.e. value is not empty). ARGV[1] indicates whether to return
1140 the variable name or its value. */
1141static char *
1142func_firstdefined (char *o, char **argv, const char *funcname)
1143{
1144 unsigned int i;
1145 const char *words = argv[0]; /* Use a temp variable for find_next_token */
1146 const char *p;
1147 int ret_value = parse_value_name_argument (argv[1], funcname);
1148
1149 /* FIXME: Optimize by not expanding the arguments, but instead expand them
1150 one by one here. This will require a find_next_token variant which
1151 takes `$(' and `)' into account. */
1152 while ((p = find_next_token (&words, &i)) != NULL)
1153 {
1154 struct variable *v = lookup_variable (p, i);
1155 if (v && v->value_length)
1156 {
1157 if (ret_value)
1158 variable_expand_string_2 (o, v->value, v->value_length, &o);
1159 else
1160 o = variable_buffer_output (o, p, i);
1161 break;
1162 }
1163 }
1164
1165 return o;
1166}
1167
1168/* Given a list of variable names (ARGV[0]), returned the last variable which
1169 is defined (i.e. value is not empty). ARGV[1] indicates whether to return
1170 the variable name or its value. */
1171static char *
1172func_lastdefined (char *o, char **argv, const char *funcname)
1173{
1174 struct variable *last_v = NULL;
1175 unsigned int i;
1176 const char *words = argv[0]; /* Use a temp variable for find_next_token */
1177 const char *p;
1178 int ret_value = parse_value_name_argument (argv[1], funcname);
1179
1180 /* FIXME: Optimize this. Walk from the end on unexpanded arguments. */
1181 while ((p = find_next_token (&words, &i)) != NULL)
1182 {
1183 struct variable *v = lookup_variable (p, i);
1184 if (v && v->value_length)
1185 {
1186 last_v = v;
1187 break;
1188 }
1189 }
1190
1191 if (last_v != NULL)
1192 {
1193 if (ret_value)
1194 variable_expand_string_2 (o, last_v->value, last_v->value_length, &o);
1195 else
1196 o = variable_buffer_output (o, last_v->name, last_v->length);
1197 }
1198 return o;
1199}
1200
1201#endif /* CONFIG_WITH_DEFINED_FUNCTIONS */
1202
1203static char *
1204func_firstword (char *o, char **argv, const char *funcname UNUSED)
1205{
1206 unsigned int i;
1207 const char *words = argv[0]; /* Use a temp variable for find_next_token */
1208 const char *p = find_next_token (&words, &i);
1209
1210 if (p != 0)
1211 o = variable_buffer_output (o, p, i);
1212
1213 return o;
1214}
1215
1216static char *
1217func_lastword (char *o, char **argv, const char *funcname UNUSED)
1218{
1219 unsigned int i;
1220 const char *words = argv[0]; /* Use a temp variable for find_next_token */
1221 const char *p = NULL;
1222 const char *t;
1223
1224 while ((t = find_next_token (&words, &i)))
1225 p = t;
1226
1227 if (p != 0)
1228 o = variable_buffer_output (o, p, i);
1229
1230 return o;
1231}
1232
1233static char *
1234func_words (char *o, char **argv, const char *funcname UNUSED)
1235{
1236 int i = 0;
1237 const char *word_iterator = argv[0];
1238 char buf[20];
1239
1240 while (find_next_token (&word_iterator, NULL) != 0)
1241 ++i;
1242
1243 sprintf (buf, "%d", i);
1244 o = variable_buffer_output (o, buf, strlen (buf));
1245
1246 return o;
1247}
1248
1249/* Set begpp to point to the first non-whitespace character of the string,
1250 * and endpp to point to the last non-whitespace character of the string.
1251 * If the string is empty or contains nothing but whitespace, endpp will be
1252 * begpp-1.
1253 */
1254char *
1255strip_whitespace (const char **begpp, const char **endpp)
1256{
1257 while (*begpp <= *endpp && ISSPACE (**begpp))
1258 (*begpp) ++;
1259 while (*endpp >= *begpp && ISSPACE (**endpp))
1260 (*endpp) --;
1261 return (char *)*begpp;
1262}
1263
1264static void
1265check_numeric (const char *s, const char *msg)
1266{
1267 const char *end = s + strlen (s) - 1;
1268 const char *beg = s;
1269 strip_whitespace (&s, &end);
1270
1271 for (; s <= end; ++s)
1272 if (!ISDIGIT (*s)) /* ISDIGIT only evals its arg once: see makeint.h. */
1273 break;
1274
1275 if (s <= end || end - beg < 0)
1276 OSS (fatal, *expanding_var, "%s: '%s'", msg, beg);
1277}
1278
1279
1280
1281static char *
1282func_word (char *o, char **argv, const char *funcname UNUSED)
1283{
1284 const char *end_p;
1285 const char *p;
1286 int i;
1287
1288 /* Check the first argument. */
1289 check_numeric (argv[0], _("non-numeric first argument to 'word' function"));
1290 i = atoi (argv[0]);
1291
1292 if (i == 0)
1293 O (fatal, *expanding_var,
1294 _("first argument to 'word' function must be greater than 0"));
1295
1296 end_p = argv[1];
1297 while ((p = find_next_token (&end_p, 0)) != 0)
1298 if (--i == 0)
1299 break;
1300
1301 if (i == 0)
1302 o = variable_buffer_output (o, p, end_p - p);
1303
1304 return o;
1305}
1306
1307static char *
1308func_wordlist (char *o, char **argv, const char *funcname UNUSED)
1309{
1310 int start, count;
1311
1312 /* Check the arguments. */
1313 check_numeric (argv[0],
1314 _("non-numeric first argument to 'wordlist' function"));
1315 check_numeric (argv[1],
1316 _("non-numeric second argument to 'wordlist' function"));
1317
1318 start = atoi (argv[0]);
1319 if (start < 1)
1320 ON (fatal, *expanding_var,
1321 "invalid first argument to 'wordlist' function: '%d'", start);
1322
1323 count = atoi (argv[1]) - start + 1;
1324
1325 if (count > 0)
1326 {
1327 const char *p;
1328 const char *end_p = argv[2];
1329
1330 /* Find the beginning of the "start"th word. */
1331 while (((p = find_next_token (&end_p, 0)) != 0) && --start)
1332 ;
1333
1334 if (p)
1335 {
1336 /* Find the end of the "count"th word from start. */
1337 while (--count && (find_next_token (&end_p, 0) != 0))
1338 ;
1339
1340 /* Return the stuff in the middle. */
1341 o = variable_buffer_output (o, p, end_p - p);
1342 }
1343 }
1344
1345 return o;
1346}
1347
1348static char *
1349func_findstring (char *o, char **argv, const char *funcname UNUSED)
1350{
1351 /* Find the first occurrence of the first string in the second. */
1352 if (strstr (argv[1], argv[0]) != 0)
1353 o = variable_buffer_output (o, argv[0], strlen (argv[0]));
1354
1355 return o;
1356}
1357
1358static char *
1359func_foreach (char *o, char **argv, const char *funcname UNUSED)
1360{
1361 /* expand only the first two. */
1362 char *varname = expand_argument (argv[0], NULL);
1363 char *list = expand_argument (argv[1], NULL);
1364 const char *body = argv[2];
1365#ifdef CONFIG_WITH_VALUE_LENGTH
1366 long body_len = strlen (body);
1367#endif
1368
1369 int doneany = 0;
1370 const char *list_iterator = list;
1371 const char *p;
1372 unsigned int len;
1373 struct variable *var;
1374
1375 /* Clean up the variable name by removing whitespace. */
1376 char *vp = next_token (varname);
1377 end_of_token (vp)[0] = '\0';
1378
1379 push_new_variable_scope ();
1380 var = define_variable (vp, strlen (vp), "", o_automatic, 0);
1381
1382 /* loop through LIST, put the value in VAR and expand BODY */
1383 while ((p = find_next_token (&list_iterator, &len)) != 0)
1384 {
1385#ifndef CONFIG_WITH_VALUE_LENGTH
1386 char *result = 0;
1387
1388 free (var->value);
1389 var->value = xstrndup (p, len);
1390
1391 result = allocated_variable_expand (body);
1392
1393 o = variable_buffer_output (o, result, strlen (result));
1394 o = variable_buffer_output (o, " ", 1);
1395 doneany = 1;
1396 free (result);
1397#else /* CONFIG_WITH_VALUE_LENGTH */
1398 if (len >= var->value_alloc_len)
1399 {
1400# ifdef CONFIG_WITH_RDONLY_VARIABLE_VALUE
1401 if (var->rdonly_val)
1402 var->rdonly_val = 0;
1403 else
1404# endif
1405 free (var->value);
1406 var->value_alloc_len = VAR_ALIGN_VALUE_ALLOC (len + 1);
1407 var->value = xmalloc (var->value_alloc_len);
1408 }
1409 memcpy (var->value, p, len);
1410 var->value[len] = '\0';
1411 var->value_length = len;
1412 VARIABLE_CHANGED (var);
1413
1414 variable_expand_string_2 (o, body, body_len, &o);
1415 o = variable_buffer_output (o, " ", 1);
1416 doneany = 1;
1417#endif /* CONFIG_WITH_VALUE_LENGTH */
1418 }
1419
1420 if (doneany)
1421 /* Kill the last space. */
1422 --o;
1423
1424 pop_variable_scope ();
1425 free (varname);
1426 free (list);
1427
1428 return o;
1429}
1430
1431#ifdef CONFIG_WITH_LOOP_FUNCTIONS
1432
1433
1434/* Helper for func_for that evaluates the INIT and NEXT parts. */
1435static void
1436helper_eval (char *text, size_t text_len)
1437{
1438 unsigned int buf_len;
1439 char *buf;
1440
1441 install_variable_buffer (&buf, &buf_len);
1442 eval_buffer (text, NULL, text + text_len);
1443 restore_variable_buffer (buf, buf_len);
1444}
1445
1446/*
1447 $(for init,condition,next,body)
1448 */
1449static char *
1450func_for (char *o, char **argv, const char *funcname UNUSED)
1451{
1452 char *init = argv[0];
1453 const char *cond = argv[1];
1454 const char *next = argv[2];
1455 size_t next_len = strlen (next);
1456 char *next_buf = xmalloc (next_len + 1);
1457 const char *body = argv[3];
1458 size_t body_len = strlen (body);
1459 unsigned int doneany = 0;
1460
1461 push_new_variable_scope ();
1462
1463 /* Evaluate INIT. */
1464
1465 helper_eval (init, strlen (init));
1466
1467 /* Loop till COND is false. */
1468
1469 while (expr_eval_if_conditionals (cond, NULL) == 0 /* true */)
1470 {
1471 /* Expand BODY. */
1472
1473 if (!doneany)
1474 doneany = 1;
1475 else
1476 o = variable_buffer_output (o, " ", 1);
1477 variable_expand_string_2 (o, body, body_len, &o);
1478
1479 /* Evaluate NEXT. */
1480
1481 memcpy (next_buf, next, next_len + 1);
1482 helper_eval (next_buf, next_len);
1483 }
1484
1485 pop_variable_scope ();
1486 free (next_buf);
1487
1488 return o;
1489}
1490
1491/*
1492 $(while condition,body)
1493 */
1494static char *
1495func_while (char *o, char **argv, const char *funcname UNUSED)
1496{
1497 const char *cond = argv[0];
1498 const char *body = argv[1];
1499 size_t body_len = strlen (body);
1500 unsigned int doneany = 0;
1501
1502 push_new_variable_scope ();
1503
1504 while (expr_eval_if_conditionals (cond, NULL) == 0 /* true */)
1505 {
1506 if (!doneany)
1507 doneany = 1;
1508 else
1509 o = variable_buffer_output (o, " ", 1);
1510 variable_expand_string_2 (o, body, body_len, &o);
1511 }
1512
1513 pop_variable_scope ();
1514
1515 return o;
1516}
1517
1518
1519#endif /* CONFIG_WITH_LOOP_FUNCTIONS */
1520
1521struct a_word
1522{
1523 struct a_word *next;
1524 struct a_word *chain;
1525 char *str;
1526 int length;
1527 int matched;
1528};
1529
1530static unsigned long
1531a_word_hash_1 (const void *key)
1532{
1533 return_STRING_HASH_1 (((struct a_word const *) key)->str);
1534}
1535
1536static unsigned long
1537a_word_hash_2 (const void *key)
1538{
1539 return_STRING_HASH_2 (((struct a_word const *) key)->str);
1540}
1541
1542static int
1543a_word_hash_cmp (const void *x, const void *y)
1544{
1545 int result = ((struct a_word const *) x)->length - ((struct a_word const *) y)->length;
1546 if (result)
1547 return result;
1548 return_STRING_COMPARE (((struct a_word const *) x)->str,
1549 ((struct a_word const *) y)->str);
1550}
1551
1552struct a_pattern
1553{
1554 struct a_pattern *next;
1555 char *str;
1556 char *percent;
1557 int length;
1558};
1559
1560static char *
1561func_filter_filterout (char *o, char **argv, const char *funcname)
1562{
1563 struct a_word *wordhead;
1564 struct a_word **wordtail;
1565 struct a_word *wp;
1566 struct a_pattern *pathead;
1567 struct a_pattern **pattail;
1568 struct a_pattern *pp;
1569
1570 struct hash_table a_word_table;
1571 int is_filter = funcname[CSTRLEN ("filter")] == '\0';
1572 const char *pat_iterator = argv[0];
1573 const char *word_iterator = argv[1];
1574 int literals = 0;
1575 int words = 0;
1576 int hashing = 0;
1577 char *p;
1578 unsigned int len;
1579
1580 /* Chop ARGV[0] up into patterns to match against the words.
1581 We don't need to preserve it because our caller frees all the
1582 argument memory anyway. */
1583
1584 pattail = &pathead;
1585 while ((p = find_next_token (&pat_iterator, &len)) != 0)
1586 {
1587 struct a_pattern *pat = alloca (sizeof (struct a_pattern));
1588
1589 *pattail = pat;
1590 pattail = &pat->next;
1591
1592 if (*pat_iterator != '\0')
1593 ++pat_iterator;
1594
1595 pat->str = p;
1596 p[len] = '\0';
1597 pat->percent = find_percent (p);
1598 if (pat->percent == 0)
1599 literals++;
1600
1601 /* find_percent() might shorten the string so LEN is wrong. */
1602 pat->length = strlen (pat->str);
1603 }
1604 *pattail = 0;
1605
1606 /* Chop ARGV[1] up into words to match against the patterns. */
1607
1608 wordtail = &wordhead;
1609 while ((p = find_next_token (&word_iterator, &len)) != 0)
1610 {
1611 struct a_word *word = alloca (sizeof (struct a_word));
1612
1613 *wordtail = word;
1614 wordtail = &word->next;
1615
1616 if (*word_iterator != '\0')
1617 ++word_iterator;
1618
1619 p[len] = '\0';
1620 word->str = p;
1621 word->length = len;
1622 word->matched = 0;
1623 word->chain = 0;
1624 words++;
1625 }
1626 *wordtail = 0;
1627
1628 /* Only use a hash table if arg list lengths justifies the cost. */
1629 hashing = (literals >= 2 && (literals * words) >= 10);
1630 if (hashing)
1631 {
1632 hash_init (&a_word_table, words, a_word_hash_1, a_word_hash_2,
1633 a_word_hash_cmp);
1634 for (wp = wordhead; wp != 0; wp = wp->next)
1635 {
1636 struct a_word *owp = hash_insert (&a_word_table, wp);
1637 if (owp)
1638 wp->chain = owp;
1639 }
1640 }
1641
1642 if (words)
1643 {
1644 int doneany = 0;
1645
1646 /* Run each pattern through the words, killing words. */
1647 for (pp = pathead; pp != 0; pp = pp->next)
1648 {
1649 if (pp->percent)
1650 for (wp = wordhead; wp != 0; wp = wp->next)
1651 wp->matched |= pattern_matches (pp->str, pp->percent, wp->str);
1652 else if (hashing)
1653 {
1654 struct a_word a_word_key;
1655 a_word_key.str = pp->str;
1656 a_word_key.length = pp->length;
1657 wp = hash_find_item (&a_word_table, &a_word_key);
1658 while (wp)
1659 {
1660 wp->matched |= 1;
1661 wp = wp->chain;
1662 }
1663 }
1664 else
1665 for (wp = wordhead; wp != 0; wp = wp->next)
1666 wp->matched |= (wp->length == pp->length
1667 && strneq (pp->str, wp->str, wp->length));
1668 }
1669
1670 /* Output the words that matched (or didn't, for filter-out). */
1671 for (wp = wordhead; wp != 0; wp = wp->next)
1672 if (is_filter ? wp->matched : !wp->matched)
1673 {
1674 o = variable_buffer_output (o, wp->str, strlen (wp->str));
1675 o = variable_buffer_output (o, " ", 1);
1676 doneany = 1;
1677 }
1678
1679 if (doneany)
1680 /* Kill the last space. */
1681 --o;
1682 }
1683
1684 if (hashing)
1685 hash_free (&a_word_table, 0);
1686
1687 return o;
1688}
1689
1690
1691static char *
1692func_strip (char *o, char **argv, const char *funcname UNUSED)
1693{
1694 const char *p = argv[0];
1695 int doneany = 0;
1696
1697 while (*p != '\0')
1698 {
1699 int i=0;
1700 const char *word_start;
1701
1702 NEXT_TOKEN (p);
1703 word_start = p;
1704 for (i=0; *p != '\0' && !ISSPACE (*p); ++p, ++i)
1705 {}
1706 if (!i)
1707 break;
1708 o = variable_buffer_output (o, word_start, i);
1709 o = variable_buffer_output (o, " ", 1);
1710 doneany = 1;
1711 }
1712
1713 if (doneany)
1714 /* Kill the last space. */
1715 --o;
1716
1717 return o;
1718}
1719
1720/*
1721 Print a warning or fatal message.
1722*/
1723static char *
1724func_error (char *o, char **argv, const char *funcname)
1725{
1726 char **argvp;
1727 char *msg, *p;
1728 int len;
1729
1730 /* The arguments will be broken on commas. Rather than create yet
1731 another special case where function arguments aren't broken up,
1732 just create a format string that puts them back together. */
1733 for (len=0, argvp=argv; *argvp != 0; ++argvp)
1734 len += strlen (*argvp) + 2;
1735
1736 p = msg = alloca (len + 1);
1737
1738 for (argvp=argv; argvp[1] != 0; ++argvp)
1739 {
1740 strcpy (p, *argvp);
1741 p += strlen (*argvp);
1742 *(p++) = ',';
1743 *(p++) = ' ';
1744 }
1745 strcpy (p, *argvp);
1746
1747 switch (*funcname)
1748 {
1749 case 'e':
1750 OS (fatal, reading_file, "%s", msg);
1751
1752 case 'w':
1753 OS (error, reading_file, "%s", msg);
1754 break;
1755
1756 case 'i':
1757 outputs (0, msg);
1758 outputs (0, "\n");
1759 break;
1760
1761 default:
1762 OS (fatal, *expanding_var, "Internal error: func_error: '%s'", funcname);
1763 }
1764
1765 /* The warning function expands to the empty string. */
1766 return o;
1767}
1768
1769#ifdef KMK
1770/* Compare strings *S1 and *S2.
1771 Return negative if the first is less, positive if it is greater,
1772 zero if they are equal. */
1773
1774static int
1775version_compare_wrapper (const void *v1, const void *v2)
1776{
1777 const char *s1 = *((char **)v1);
1778 const char *s2 = *((char **)v2);
1779 return version_compare (s1, s2);
1780}
1781#endif /* KMK */
1782
1783/*
1784 chop argv[0] into words, and sort them.
1785 */
1786static char *
1787func_sort (char *o, char **argv, const char *funcname UNUSED)
1788{
1789 const char *t;
1790 char **words;
1791 int wordi;
1792 char *p;
1793 unsigned int len;
1794
1795 /* Find the maximum number of words we'll have. */
1796 t = argv[0];
1797 wordi = 0;
1798 while ((p = find_next_token (&t, NULL)) != 0)
1799 {
1800 ++t;
1801 ++wordi;
1802 }
1803
1804 words = xmalloc ((wordi == 0 ? 1 : wordi) * sizeof (char *));
1805
1806 /* Now assign pointers to each string in the array. */
1807 t = argv[0];
1808 wordi = 0;
1809 while ((p = find_next_token (&t, &len)) != 0)
1810 {
1811 if (*t != '\0') /* bird: Fixes access beyond end of string and overflowing words array. */
1812 ++t;
1813 p[len] = '\0';
1814 words[wordi++] = p;
1815 }
1816
1817 if (wordi)
1818 {
1819 int i;
1820
1821 /* Now sort the list of words. */
1822#ifdef KMK
1823 if (funcname[0] == 'v' || funcname[1] == 'v')
1824 qsort (words, wordi, sizeof (char *), version_compare_wrapper);
1825 else
1826 qsort (words, wordi, sizeof (char *), alpha_compare);
1827#else
1828 qsort (words, wordi, sizeof (char *), alpha_compare);
1829#endif
1830
1831 /* Now write the sorted list, uniquified. */
1832#ifdef CONFIG_WITH_RSORT
1833 if (*funcname != 'r')
1834 {
1835 /* sort */
1836#endif
1837 for (i = 0; i < wordi; ++i)
1838 {
1839 len = strlen (words[i]);
1840 if (i == wordi - 1 || strlen (words[i + 1]) != len
1841 || strcmp (words[i], words[i + 1]))
1842 {
1843 o = variable_buffer_output (o, words[i], len);
1844 o = variable_buffer_output (o, " ", 1);
1845 }
1846 }
1847#ifdef CONFIG_WITH_RSORT
1848 }
1849 else
1850 {
1851 /* rsort - reverse the result */
1852 i = wordi;
1853 while (i-- > 0)
1854 {
1855 len = strlen (words[i]);
1856 if (i == 0 || strlen (words[i - 1]) != len
1857 || strcmp (words[i], words[i - 1]))
1858 {
1859 o = variable_buffer_output (o, words[i], len);
1860 o = variable_buffer_output (o, " ", 1);
1861 }
1862 }
1863 }
1864#endif
1865
1866 /* Kill the last space. */
1867 --o;
1868 }
1869
1870 free (words);
1871
1872 return o;
1873}
1874
1875/*
1876 $(if condition,true-part[,false-part])
1877
1878 CONDITION is false iff it evaluates to an empty string. White
1879 space before and after condition are stripped before evaluation.
1880
1881 If CONDITION is true, then TRUE-PART is evaluated, otherwise FALSE-PART is
1882 evaluated (if it exists). Because only one of the two PARTs is evaluated,
1883 you can use $(if ...) to create side-effects (with $(shell ...), for
1884 example).
1885*/
1886
1887static char *
1888func_if (char *o, char **argv, const char *funcname UNUSED)
1889{
1890 const char *begp = argv[0];
1891 const char *endp = begp + strlen (argv[0]) - 1;
1892 int result = 0;
1893
1894 /* Find the result of the condition: if we have a value, and it's not
1895 empty, the condition is true. If we don't have a value, or it's the
1896 empty string, then it's false. */
1897
1898 strip_whitespace (&begp, &endp);
1899
1900 if (begp <= endp)
1901 {
1902 char *expansion = expand_argument (begp, endp+1);
1903
1904 result = strlen (expansion);
1905 free (expansion);
1906 }
1907
1908 /* If the result is true (1) we want to eval the first argument, and if
1909 it's false (0) we want to eval the second. If the argument doesn't
1910 exist we do nothing, otherwise expand it and add to the buffer. */
1911
1912 argv += 1 + !result;
1913
1914 if (*argv)
1915 {
1916 char *expansion = expand_argument (*argv, NULL);
1917
1918 o = variable_buffer_output (o, expansion, strlen (expansion));
1919
1920 free (expansion);
1921 }
1922
1923 return o;
1924}
1925
1926/*
1927 $(or condition1[,condition2[,condition3[...]]])
1928
1929 A CONDITION is false iff it evaluates to an empty string. White
1930 space before and after CONDITION are stripped before evaluation.
1931
1932 CONDITION1 is evaluated. If it's true, then this is the result of
1933 expansion. If it's false, CONDITION2 is evaluated, and so on. If none of
1934 the conditions are true, the expansion is the empty string.
1935
1936 Once a CONDITION is true no further conditions are evaluated
1937 (short-circuiting).
1938*/
1939
1940static char *
1941func_or (char *o, char **argv, const char *funcname UNUSED)
1942{
1943 for ( ; *argv ; ++argv)
1944 {
1945 const char *begp = *argv;
1946 const char *endp = begp + strlen (*argv) - 1;
1947 char *expansion;
1948 int result = 0;
1949
1950 /* Find the result of the condition: if it's false keep going. */
1951
1952 strip_whitespace (&begp, &endp);
1953
1954 if (begp > endp)
1955 continue;
1956
1957 expansion = expand_argument (begp, endp+1);
1958 result = strlen (expansion);
1959
1960 /* If the result is false keep going. */
1961 if (!result)
1962 {
1963 free (expansion);
1964 continue;
1965 }
1966
1967 /* It's true! Keep this result and return. */
1968 o = variable_buffer_output (o, expansion, result);
1969 free (expansion);
1970 break;
1971 }
1972
1973 return o;
1974}
1975
1976/*
1977 $(and condition1[,condition2[,condition3[...]]])
1978
1979 A CONDITION is false iff it evaluates to an empty string. White
1980 space before and after CONDITION are stripped before evaluation.
1981
1982 CONDITION1 is evaluated. If it's false, then this is the result of
1983 expansion. If it's true, CONDITION2 is evaluated, and so on. If all of
1984 the conditions are true, the expansion is the result of the last condition.
1985
1986 Once a CONDITION is false no further conditions are evaluated
1987 (short-circuiting).
1988*/
1989
1990static char *
1991func_and (char *o, char **argv, const char *funcname UNUSED)
1992{
1993 char *expansion;
1994
1995 while (1)
1996 {
1997 const char *begp = *argv;
1998 const char *endp = begp + strlen (*argv) - 1;
1999 int result;
2000
2001 /* An empty condition is always false. */
2002 strip_whitespace (&begp, &endp);
2003 if (begp > endp)
2004 return o;
2005
2006 expansion = expand_argument (begp, endp+1);
2007 result = strlen (expansion);
2008
2009 /* If the result is false, stop here: we're done. */
2010 if (!result)
2011 break;
2012
2013 /* Otherwise the result is true. If this is the last one, keep this
2014 result and quit. Otherwise go on to the next one! */
2015
2016 if (*(++argv))
2017 free (expansion);
2018 else
2019 {
2020 o = variable_buffer_output (o, expansion, result);
2021 break;
2022 }
2023 }
2024
2025 free (expansion);
2026
2027 return o;
2028}
2029
2030static char *
2031func_wildcard (char *o, char **argv, const char *funcname UNUSED)
2032{
2033#ifdef _AMIGA
2034 o = wildcard_expansion (argv[0], o);
2035#else
2036 char *p = string_glob (argv[0]);
2037 o = variable_buffer_output (o, p, strlen (p));
2038#endif
2039 return o;
2040}
2041
2042/*
2043 $(eval <makefile string>)
2044
2045 Always resolves to the empty string.
2046
2047 Treat the arguments as a segment of makefile, and parse them.
2048*/
2049
2050static char *
2051func_eval (char *o, char **argv, const char *funcname UNUSED)
2052{
2053 char *buf;
2054 unsigned int len;
2055
2056 /* Eval the buffer. Pop the current variable buffer setting so that the
2057 eval'd code can use its own without conflicting. */
2058
2059 install_variable_buffer (&buf, &len);
2060
2061#ifndef CONFIG_WITH_VALUE_LENGTH
2062 eval_buffer (argv[0], NULL);
2063#else
2064 eval_buffer (argv[0], NULL, strchr (argv[0], '\0'));
2065#endif
2066
2067 restore_variable_buffer (buf, len);
2068
2069 return o;
2070}
2071
2072
2073#ifdef CONFIG_WITH_EVALPLUS
2074/* Same as func_eval except that we push and pop the local variable
2075 context before evaluating the buffer. */
2076static char *
2077func_evalctx (char *o, char **argv, const char *funcname UNUSED)
2078{
2079 char *buf;
2080 unsigned int len;
2081
2082 /* Eval the buffer. Pop the current variable buffer setting so that the
2083 eval'd code can use its own without conflicting. */
2084
2085 install_variable_buffer (&buf, &len);
2086
2087 push_new_variable_scope ();
2088
2089 eval_buffer (argv[0], NULL, strchr (argv[0], '\0'));
2090
2091 pop_variable_scope ();
2092
2093 restore_variable_buffer (buf, len);
2094
2095 return o;
2096}
2097
2098/* A mix of func_eval and func_value, saves memory for the expansion.
2099 This implements both evalval and evalvalctx, the latter has its own
2100 variable context just like evalctx. */
2101static char *
2102func_evalval (char *o, char **argv, const char *funcname)
2103{
2104 /* Look up the variable. */
2105 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
2106 if (v)
2107 {
2108 char *buf;
2109 unsigned int len;
2110 int var_ctx;
2111 size_t off;
2112 const floc *reading_file_saved = reading_file;
2113# ifdef CONFIG_WITH_MAKE_STATS
2114 unsigned long long uStartTick = CURRENT_CLOCK_TICK();
2115# ifndef CONFIG_WITH_COMPILER
2116 MAKE_STATS_2(v->evalval_count++);
2117# endif
2118# endif
2119
2120 var_ctx = !strcmp (funcname, "evalvalctx");
2121 if (var_ctx)
2122 push_new_variable_scope ();
2123 if (v->fileinfo.filenm)
2124 reading_file = &v->fileinfo;
2125
2126# ifdef CONFIG_WITH_COMPILER
2127 /* If this variable has been evaluated more than a few times, it make
2128 sense to compile it to speed up the processing. */
2129
2130 v->evalval_count++;
2131 if ( v->evalprog
2132 || (v->evalval_count == 3 && kmk_cc_compile_variable_for_eval (v)))
2133 {
2134 install_variable_buffer (&buf, &len); /* Really necessary? */
2135 kmk_exec_eval_variable (v);
2136 restore_variable_buffer (buf, len);
2137 }
2138 else
2139# endif
2140 {
2141 /* Make a copy of the value to the variable buffer first since
2142 eval_buffer will make changes to its input. */
2143
2144 off = o - variable_buffer;
2145 variable_buffer_output (o, v->value, v->value_length + 1);
2146 o = variable_buffer + off;
2147 assert (!o[v->value_length]);
2148
2149 install_variable_buffer (&buf, &len); /* Really necessary? */
2150 eval_buffer (o, NULL, o + v->value_length);
2151 restore_variable_buffer (buf, len);
2152 }
2153
2154 reading_file = reading_file_saved;
2155 if (var_ctx)
2156 pop_variable_scope ();
2157
2158 MAKE_STATS_2(v->cTicksEvalVal += CURRENT_CLOCK_TICK() - uStartTick);
2159 }
2160
2161 return o;
2162}
2163
2164/* Optimizes the content of one or more variables to save time in
2165 the eval functions. This function will collapse line continuations
2166 and remove comments. */
2167static char *
2168func_eval_optimize_variable (char *o, char **argv, const char *funcname)
2169{
2170 unsigned int i;
2171
2172 for (i = 0; argv[i]; i++)
2173 {
2174 struct variable *v = lookup_variable (argv[i], strlen (argv[i]));
2175# ifdef CONFIG_WITH_RDONLY_VARIABLE_VALUE
2176 if (v && v->origin != o_automatic && !v->rdonly_val)
2177# else
2178 if (v && v->origin != o_automatic)
2179# endif
2180 {
2181 char *eos, *src;
2182
2183 eos = collapse_continuations (v->value, v->value_length);
2184 v->value_length = eos - v->value;
2185
2186 /* remove comments */
2187
2188 src = memchr (v->value, '#', v->value_length);
2189 if (src)
2190 {
2191 unsigned char ch = '\0';
2192 char *dst = src;
2193 do
2194 {
2195 /* drop blanks preceeding the comment */
2196 while (dst > v->value)
2197 {
2198 ch = (unsigned char)dst[-1];
2199 if (!ISBLANK (ch))
2200 break;
2201 dst--;
2202 }
2203
2204 /* advance SRC to eol / eos. */
2205 src = memchr (src, '\n', eos - src);
2206 if (!src)
2207 break;
2208
2209 /* drop a preceeding newline if possible (full line comment) */
2210 if (dst > v->value && dst[-1] == '\n')
2211 dst--;
2212
2213 /* copy till next comment or eol. */
2214 while (src < eos)
2215 {
2216 ch = *src++;
2217 if (ch == '#')
2218 break;
2219 *dst++ = ch;
2220 }
2221 }
2222 while (ch == '#' && src < eos);
2223
2224 *dst = '\0';
2225 v->value_length = dst - v->value;
2226 }
2227
2228 VARIABLE_CHANGED (v);
2229
2230# ifdef CONFIG_WITH_COMPILER
2231 /* Compile the variable for evalval, evalctx and expansion. */
2232
2233 if ( v->recursive
2234 && !IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR (v))
2235 kmk_cc_compile_variable_for_expand (v);
2236 kmk_cc_compile_variable_for_eval (v);
2237# endif
2238 }
2239 else if (v)
2240 OSS (error, NILF, _("$(%s ): variable `%s' is of the wrong type\n"), funcname, v->name);
2241 }
2242
2243 return o;
2244}
2245
2246#endif /* CONFIG_WITH_EVALPLUS */
2247
2248static char *
2249func_value (char *o, char **argv, const char *funcname UNUSED)
2250{
2251 /* Look up the variable. */
2252 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
2253
2254 /* Copy its value into the output buffer without expanding it. */
2255 if (v)
2256#ifdef CONFIG_WITH_VALUE_LENGTH
2257 {
2258 assert (v->value_length == strlen (v->value));
2259 o = variable_buffer_output (o, v->value, v->value_length);
2260 }
2261#else
2262 o = variable_buffer_output (o, v->value, strlen (v->value));
2263#endif
2264
2265 return o;
2266}
2267
2268/*
2269 \r is replaced on UNIX as well. Is this desirable?
2270 */
2271static void
2272fold_newlines (char *buffer, unsigned int *length, int trim_newlines)
2273{
2274 char *dst = buffer;
2275 char *src = buffer;
2276 char *last_nonnl = buffer - 1;
2277 src[*length] = 0;
2278 for (; *src != '\0'; ++src)
2279 {
2280 if (src[0] == '\r' && src[1] == '\n')
2281 continue;
2282 if (*src == '\n')
2283 {
2284 *dst++ = ' ';
2285 }
2286 else
2287 {
2288 last_nonnl = dst;
2289 *dst++ = *src;
2290 }
2291 }
2292
2293 if (!trim_newlines && (last_nonnl < (dst - 2)))
2294 last_nonnl = dst - 2;
2295
2296 *(++last_nonnl) = '\0';
2297 *length = last_nonnl - buffer;
2298}
2299
2300pid_t shell_function_pid = 0;
2301static int shell_function_completed;
2302
2303void
2304shell_completed (int exit_code, int exit_sig)
2305{
2306 char buf[256];
2307
2308 shell_function_pid = 0;
2309 if (exit_sig == 0 && exit_code == 127)
2310 shell_function_completed = -1;
2311 else
2312 shell_function_completed = 1;
2313
2314 sprintf (buf, "%d", exit_code);
2315 define_variable_cname (".SHELLSTATUS", buf, o_override, 0);
2316}
2317
2318#ifdef WINDOWS32
2319/*untested*/
2320
2321# ifndef CONFIG_NEW_WIN_CHILDREN
2322#include <windows.h>
2323#include <io.h>
2324#include "sub_proc.h"
2325
2326int
2327windows32_openpipe (int *pipedes, int errfd, pid_t *pid_p, char **command_argv, char **envp)
2328{
2329 SECURITY_ATTRIBUTES saAttr;
2330 HANDLE hIn = INVALID_HANDLE_VALUE;
2331 HANDLE hErr = INVALID_HANDLE_VALUE;
2332 HANDLE hChildOutRd;
2333 HANDLE hChildOutWr;
2334 HANDLE hProcess, tmpIn, tmpErr;
2335 DWORD e;
2336
2337 /* Set status for return. */
2338 pipedes[0] = pipedes[1] = -1;
2339 *pid_p = (pid_t)-1;
2340
2341 saAttr.nLength = sizeof (SECURITY_ATTRIBUTES);
2342 saAttr.bInheritHandle = TRUE;
2343 saAttr.lpSecurityDescriptor = NULL;
2344
2345 /* Standard handles returned by GetStdHandle can be NULL or
2346 INVALID_HANDLE_VALUE if the parent process closed them. If that
2347 happens, we open the null device and pass its handle to
2348 process_begin below as the corresponding handle to inherit. */
2349 tmpIn = GetStdHandle (STD_INPUT_HANDLE);
2350 if (DuplicateHandle (GetCurrentProcess (), tmpIn,
2351 GetCurrentProcess (), &hIn,
2352 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE)
2353 {
2354 e = GetLastError ();
2355 if (e == ERROR_INVALID_HANDLE)
2356 {
2357 tmpIn = CreateFile ("NUL", GENERIC_READ,
2358 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
2359 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2360 if (tmpIn != INVALID_HANDLE_VALUE
2361 && DuplicateHandle (GetCurrentProcess (), tmpIn,
2362 GetCurrentProcess (), &hIn,
2363 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE)
2364 CloseHandle (tmpIn);
2365 }
2366 if (hIn == INVALID_HANDLE_VALUE)
2367 {
2368 ON (error, NILF,
2369 _("windows32_openpipe: DuplicateHandle(In) failed (e=%ld)\n"), e);
2370 return -1;
2371 }
2372 }
2373 tmpErr = (HANDLE)_get_osfhandle (errfd);
2374 if (DuplicateHandle (GetCurrentProcess (), tmpErr,
2375 GetCurrentProcess (), &hErr,
2376 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE)
2377 {
2378 e = GetLastError ();
2379 if (e == ERROR_INVALID_HANDLE)
2380 {
2381 tmpErr = CreateFile ("NUL", GENERIC_WRITE,
2382 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
2383 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2384 if (tmpErr != INVALID_HANDLE_VALUE
2385 && DuplicateHandle (GetCurrentProcess (), tmpErr,
2386 GetCurrentProcess (), &hErr,
2387 0, TRUE, DUPLICATE_SAME_ACCESS) == FALSE)
2388 CloseHandle (tmpErr);
2389 }
2390 if (hErr == INVALID_HANDLE_VALUE)
2391 {
2392 ON (error, NILF,
2393 _("windows32_openpipe: DuplicateHandle(Err) failed (e=%ld)\n"), e);
2394 return -1;
2395 }
2396 }
2397
2398 if (! CreatePipe (&hChildOutRd, &hChildOutWr, &saAttr, 0))
2399 {
2400 ON (error, NILF, _("CreatePipe() failed (e=%ld)\n"), GetLastError());
2401 return -1;
2402 }
2403
2404 hProcess = process_init_fd (hIn, hChildOutWr, hErr);
2405
2406 if (!hProcess)
2407 {
2408 O (error, NILF, _("windows32_openpipe(): process_init_fd() failed\n"));
2409 return -1;
2410 }
2411
2412 /* make sure that CreateProcess() has Path it needs */
2413 sync_Path_environment ();
2414 /* 'sync_Path_environment' may realloc 'environ', so take note of
2415 the new value. */
2416 envp = environ;
2417
2418 if (! process_begin (hProcess, command_argv, envp, command_argv[0], NULL))
2419 {
2420 /* register process for wait */
2421 process_register (hProcess);
2422
2423 /* set the pid for returning to caller */
2424 *pid_p = (pid_t) hProcess;
2425
2426 /* set up to read data from child */
2427 pipedes[0] = _open_osfhandle ((intptr_t) hChildOutRd, O_RDONLY);
2428
2429 /* this will be closed almost right away */
2430 pipedes[1] = _open_osfhandle ((intptr_t) hChildOutWr, O_APPEND);
2431 return 0;
2432 }
2433 else
2434 {
2435 /* reap/cleanup the failed process */
2436 process_cleanup (hProcess);
2437
2438 /* close handles which were duplicated, they weren't used */
2439 if (hIn != INVALID_HANDLE_VALUE)
2440 CloseHandle (hIn);
2441 if (hErr != INVALID_HANDLE_VALUE)
2442 CloseHandle (hErr);
2443
2444 /* close pipe handles, they won't be used */
2445 CloseHandle (hChildOutRd);
2446 CloseHandle (hChildOutWr);
2447
2448 return -1;
2449 }
2450}
2451# endif /* !CONFIG_NEW_WIN_CHILDREN */
2452#endif
2453
2454
2455#ifdef __MSDOS__
2456FILE *
2457msdos_openpipe (int* pipedes, int *pidp, char *text)
2458{
2459 FILE *fpipe=0;
2460 /* MSDOS can't fork, but it has 'popen'. */
2461 struct variable *sh = lookup_variable ("SHELL", 5);
2462 int e;
2463 extern int dos_command_running, dos_status;
2464
2465 /* Make sure not to bother processing an empty line. */
2466 NEXT_TOKEN (text);
2467 if (*text == '\0')
2468 return 0;
2469
2470 if (sh)
2471 {
2472 char buf[PATH_MAX + 7];
2473 /* This makes sure $SHELL value is used by $(shell), even
2474 though the target environment is not passed to it. */
2475 sprintf (buf, "SHELL=%s", sh->value);
2476 putenv (buf);
2477 }
2478
2479 e = errno;
2480 errno = 0;
2481 dos_command_running = 1;
2482 dos_status = 0;
2483 /* If dos_status becomes non-zero, it means the child process
2484 was interrupted by a signal, like SIGINT or SIGQUIT. See
2485 fatal_error_signal in commands.c. */
2486 fpipe = popen (text, "rt");
2487 dos_command_running = 0;
2488 if (!fpipe || dos_status)
2489 {
2490 pipedes[0] = -1;
2491 *pidp = -1;
2492 if (dos_status)
2493 errno = EINTR;
2494 else if (errno == 0)
2495 errno = ENOMEM;
2496 if (fpipe)
2497 pclose (fpipe);
2498 shell_completed (127, 0);
2499 }
2500 else
2501 {
2502 pipedes[0] = fileno (fpipe);
2503 *pidp = 42; /* Yes, the Meaning of Life, the Universe, and Everything! */
2504 errno = e;
2505 }
2506 return fpipe;
2507}
2508#endif
2509
2510/*
2511 Do shell spawning, with the naughty bits for different OSes.
2512 */
2513
2514#ifdef VMS
2515
2516/* VMS can't do $(shell ...) */
2517
2518char *
2519func_shell_base (char *o, char **argv, int trim_newlines)
2520{
2521 fprintf (stderr, "This platform does not support shell\n");
2522 die (MAKE_TROUBLE);
2523 return NULL;
2524}
2525
2526#define func_shell 0
2527
2528#else
2529#ifndef _AMIGA
2530char *
2531func_shell_base (char *o, char **argv, int trim_newlines)
2532{
2533 char *batch_filename = NULL;
2534 int errfd;
2535#ifdef __MSDOS__
2536 FILE *fpipe;
2537#endif
2538 char **command_argv;
2539 const char * volatile error_prefix; /* bird: this volatile ~~and the 'o' one~~, is for shutting up gcc warnings */
2540 char **envp;
2541 int pipedes[2];
2542 pid_t pid;
2543
2544#ifndef __MSDOS__
2545#ifdef WINDOWS32
2546 /* Reset just_print_flag. This is needed on Windows when batch files
2547 are used to run the commands, because we normally refrain from
2548 creating batch files under -n. */
2549 int j_p_f = just_print_flag;
2550 just_print_flag = 0;
2551#endif
2552
2553 /* Construct the argument list. */
2554 command_argv = construct_command_argv (argv[0], NULL, NULL, 0,
2555 &batch_filename);
2556 if (command_argv == 0)
2557 {
2558#ifdef WINDOWS32
2559 just_print_flag = j_p_f;
2560#endif
2561 return o;
2562 }
2563#endif /* !__MSDOS__ */
2564
2565 /* Using a target environment for 'shell' loses in cases like:
2566 export var = $(shell echo foobie)
2567 bad := $(var)
2568 because target_environment hits a loop trying to expand $(var) to put it
2569 in the environment. This is even more confusing when 'var' was not
2570 explicitly exported, but just appeared in the calling environment.
2571
2572 See Savannah bug #10593.
2573
2574 envp = target_environment (NULL);
2575 */
2576
2577 envp = environ;
2578
2579 /* For error messages. */
2580 if (reading_file && reading_file->filenm)
2581 {
2582 char *p = alloca (strlen (reading_file->filenm)+11+4);
2583 sprintf (p, "%s:%lu: ", reading_file->filenm,
2584 reading_file->lineno + reading_file->offset);
2585 error_prefix = p;
2586 }
2587 else
2588 error_prefix = "";
2589
2590 /* Set up the output in case the shell writes something. */
2591 output_start ();
2592
2593#ifdef CONFIG_WITH_OUTPUT_IN_MEMORY
2594 errfd = -1; /** @todo fixme */
2595#else
2596 errfd = (output_context && output_context->err >= 0
2597 ? output_context->err : FD_STDERR);
2598#endif
2599
2600#if defined(__MSDOS__)
2601 fpipe = msdos_openpipe (pipedes, &pid, argv[0]);
2602 if (pipedes[0] < 0)
2603 {
2604 perror_with_name (error_prefix, "pipe");
2605 return o;
2606 }
2607
2608#elif defined(WINDOWS32)
2609# ifdef CONFIG_NEW_WIN_CHILDREN
2610 pipedes[1] = -1;
2611 MkWinChildCreateWithStdOutPipe (command_argv, envp, errfd, &pid, &pipedes[0]);
2612# else
2613 windows32_openpipe (pipedes, errfd, &pid, command_argv, envp);
2614# endif
2615 /* Restore the value of just_print_flag. */
2616 just_print_flag = j_p_f;
2617
2618 if (pipedes[0] < 0)
2619 {
2620 /* Open of the pipe failed, mark as failed execution. */
2621 shell_completed (127, 0);
2622 perror_with_name (error_prefix, "pipe");
2623 return o;
2624 }
2625
2626#else
2627 if (pipe (pipedes) < 0)
2628 {
2629 perror_with_name (error_prefix, "pipe");
2630 return o;
2631 }
2632
2633 /* Close handles that are unnecessary for the child process. */
2634 CLOSE_ON_EXEC(pipedes[1]);
2635 CLOSE_ON_EXEC(pipedes[0]);
2636
2637 {
2638 struct output out;
2639 out.syncout = 1;
2640 out.out = pipedes[1];
2641 out.err = errfd;
2642
2643 pid = child_execute_job (&out, 1, command_argv, envp);
2644 }
2645
2646 if (pid < 0)
2647 {
2648 perror_with_name (error_prefix, "fork");
2649 return o;
2650 }
2651#endif
2652
2653 {
2654 char *buffer;
2655 unsigned int maxlen, i;
2656 int cc;
2657
2658 /* Record the PID for reap_children. */
2659 shell_function_pid = pid;
2660#ifndef __MSDOS__
2661 shell_function_completed = 0;
2662
2663 /* Free the storage only the child needed. */
2664 free (command_argv[0]);
2665 free (command_argv);
2666
2667 /* Close the write side of the pipe. We test for -1, since
2668 pipedes[1] is -1 on MS-Windows, and some versions of MS
2669 libraries barf when 'close' is called with -1. */
2670 if (pipedes[1] >= 0)
2671 close (pipedes[1]);
2672#endif
2673
2674 /* Set up and read from the pipe. */
2675
2676 maxlen = 200;
2677 buffer = xmalloc (maxlen + 1);
2678
2679 /* Read from the pipe until it gets EOF. */
2680 for (i = 0; ; i += cc)
2681 {
2682 if (i == maxlen)
2683 {
2684 maxlen += 512;
2685 buffer = xrealloc (buffer, maxlen + 1);
2686 }
2687
2688 EINTRLOOP (cc, read (pipedes[0], &buffer[i], maxlen - i));
2689 if (cc <= 0)
2690 break;
2691 }
2692 buffer[i] = '\0';
2693
2694 /* Close the read side of the pipe. */
2695#ifdef __MSDOS__
2696 if (fpipe)
2697 {
2698 int st = pclose (fpipe);
2699 shell_completed (st, 0);
2700 }
2701#else
2702# ifdef _MSC_VER /* Avoid annoying msvcrt when debugging. (bird) */
2703 if (pipedes[0] != -1)
2704# endif
2705 (void) close (pipedes[0]);
2706#endif
2707
2708 /* Loop until child_handler or reap_children() sets
2709 shell_function_completed to the status of our child shell. */
2710 while (shell_function_completed == 0)
2711 reap_children (1, 0);
2712
2713 if (batch_filename)
2714 {
2715 DB (DB_VERBOSE, (_("Cleaning up temporary batch file %s\n"),
2716 batch_filename));
2717 remove (batch_filename);
2718 free (batch_filename);
2719 }
2720 shell_function_pid = 0;
2721
2722 /* shell_completed() will set shell_function_completed to 1 when the
2723 child dies normally, or to -1 if it dies with status 127, which is
2724 most likely an exec fail. */
2725
2726 if (shell_function_completed == -1)
2727 {
2728 /* This likely means that the execvp failed, so we should just
2729 write the error message in the pipe from the child. */
2730 fputs (buffer, stderr);
2731 fflush (stderr);
2732 }
2733 else
2734 {
2735 /* The child finished normally. Replace all newlines in its output
2736 with spaces, and put that in the variable output buffer. */
2737 fold_newlines (buffer, &i, trim_newlines);
2738 o = variable_buffer_output (o, buffer, i);
2739 }
2740
2741 free (buffer);
2742 }
2743
2744 return o;
2745}
2746
2747#else /* _AMIGA */
2748
2749/* Do the Amiga version of func_shell. */
2750
2751char *
2752func_shell_base (char *o, char **argv, int trim_newlines)
2753{
2754 /* Amiga can't fork nor spawn, but I can start a program with
2755 redirection of my choice. However, this means that we
2756 don't have an opportunity to reopen stdout to trap it. Thus,
2757 we save our own stdout onto a new descriptor and dup a temp
2758 file's descriptor onto our stdout temporarily. After we
2759 spawn the shell program, we dup our own stdout back to the
2760 stdout descriptor. The buffer reading is the same as above,
2761 except that we're now reading from a file. */
2762
2763#include <dos/dos.h>
2764#include <proto/dos.h>
2765
2766 BPTR child_stdout;
2767 char tmp_output[FILENAME_MAX];
2768 unsigned int maxlen = 200, i;
2769 int cc;
2770 char * buffer, * ptr;
2771 char ** aptr;
2772 int len = 0;
2773 char* batch_filename = NULL;
2774
2775 /* Construct the argument list. */
2776 command_argv = construct_command_argv (argv[0], NULL, NULL, 0,
2777 &batch_filename);
2778 if (command_argv == 0)
2779 return o;
2780
2781 /* Note the mktemp() is a security hole, but this only runs on Amiga.
2782 Ideally we would use output_tmpfile(), but this uses a special
2783 Open(), not fopen(), and I'm not familiar enough with the code to mess
2784 with it. */
2785 strcpy (tmp_output, "t:MakeshXXXXXXXX");
2786 mktemp (tmp_output);
2787 child_stdout = Open (tmp_output, MODE_NEWFILE);
2788
2789 for (aptr=command_argv; *aptr; aptr++)
2790 len += strlen (*aptr) + 1;
2791
2792 buffer = xmalloc (len + 1);
2793 ptr = buffer;
2794
2795 for (aptr=command_argv; *aptr; aptr++)
2796 {
2797 strcpy (ptr, *aptr);
2798 ptr += strlen (ptr) + 1;
2799 *ptr ++ = ' ';
2800 *ptr = 0;
2801 }
2802
2803 ptr[-1] = '\n';
2804
2805 Execute (buffer, NULL, child_stdout);
2806 free (buffer);
2807
2808 Close (child_stdout);
2809
2810 child_stdout = Open (tmp_output, MODE_OLDFILE);
2811
2812 buffer = xmalloc (maxlen);
2813 i = 0;
2814 do
2815 {
2816 if (i == maxlen)
2817 {
2818 maxlen += 512;
2819 buffer = xrealloc (buffer, maxlen + 1);
2820 }
2821
2822 cc = Read (child_stdout, &buffer[i], maxlen - i);
2823 if (cc > 0)
2824 i += cc;
2825 } while (cc > 0);
2826
2827 Close (child_stdout);
2828
2829 fold_newlines (buffer, &i, trim_newlines);
2830 o = variable_buffer_output (o, buffer, i);
2831 free (buffer);
2832 return o;
2833}
2834#endif /* _AMIGA */
2835
2836static char *
2837func_shell (char *o, char **argv, const char *funcname UNUSED)
2838{
2839 return func_shell_base (o, argv, 1);
2840}
2841#endif /* !VMS */
2842
2843#ifdef EXPERIMENTAL
2844
2845/*
2846 equality. Return is string-boolean, i.e., the empty string is false.
2847 */
2848static char *
2849func_eq (char *o, char **argv, const char *funcname UNUSED)
2850{
2851 int result = ! strcmp (argv[0], argv[1]);
2852 o = variable_buffer_output (o, result ? "1" : "", result);
2853 return o;
2854}
2855
2856
2857/*
2858 string-boolean not operator.
2859 */
2860static char *
2861func_not (char *o, char **argv, const char *funcname UNUSED)
2862{
2863 const char *s = argv[0];
2864 int result = 0;
2865 NEXT_TOKEN (s);
2866 result = ! (*s);
2867 o = variable_buffer_output (o, result ? "1" : "", result);
2868 return o;
2869}
2870#endif
2871
2872
2873
2874#ifdef HAVE_DOS_PATHS
2875# ifdef __CYGWIN__
2876# define IS_ABSOLUTE(n) ((n[0] && n[1] == ':') || STOP_SET (n[0], MAP_DIRSEP))
2877# else
2878# define IS_ABSOLUTE(n) (n[0] && n[1] == ':')
2879# endif
2880# define ROOT_LEN 3
2881#else
2882#define IS_ABSOLUTE(n) (n[0] == '/')
2883#define ROOT_LEN 1
2884#endif
2885
2886/* Return the absolute name of file NAME which does not contain any '.',
2887 '..' components nor any repeated path separators ('/'). */
2888#ifdef KMK
2889char *
2890#else
2891static char *
2892#endif
2893abspath (const char *name, char *apath)
2894{
2895 char *dest;
2896 const char *start, *end, *apath_limit;
2897 unsigned long root_len = ROOT_LEN;
2898
2899 if (name[0] == '\0' || apath == NULL)
2900 return NULL;
2901
2902#ifdef WINDOWS32 /* bird */
2903 dest = unix_slashes_resolved (name, apath, GET_PATH_MAX);
2904 if (!dest)
2905 return NULL;
2906 dest = strchr(apath, '\0');
2907
2908 (void)end; (void)start; (void)apath_limit;
2909
2910#elif defined __OS2__ /* bird */
2911 if (_abspath(apath, name, GET_PATH_MAX))
2912 return NULL;
2913 dest = strchr(apath, '\0');
2914
2915 (void)end; (void)start; (void)apath_limit; (void)dest;
2916
2917#else /* !WINDOWS32 && !__OS2__ */
2918 apath_limit = apath + GET_PATH_MAX;
2919
2920 if (!IS_ABSOLUTE(name))
2921 {
2922 /* It is unlikely we would make it until here but just to make sure. */
2923 if (!starting_directory)
2924 return NULL;
2925
2926 strcpy (apath, starting_directory);
2927
2928#ifdef HAVE_DOS_PATHS
2929 if (STOP_SET (name[0], MAP_DIRSEP))
2930 {
2931 if (STOP_SET (name[1], MAP_DIRSEP))
2932 {
2933 /* A UNC. Don't prepend a drive letter. */
2934 apath[0] = name[0];
2935 apath[1] = name[1];
2936 root_len = 2;
2937 }
2938 /* We have /foo, an absolute file name except for the drive
2939 letter. Assume the missing drive letter is the current
2940 drive, which we can get if we remove from starting_directory
2941 everything past the root directory. */
2942 apath[root_len] = '\0';
2943 }
2944#endif
2945
2946 dest = strchr (apath, '\0');
2947 }
2948 else
2949 {
2950#if defined(__CYGWIN__) && defined(HAVE_DOS_PATHS)
2951 if (STOP_SET (name[0], MAP_DIRSEP))
2952 root_len = 1;
2953#endif
2954#ifdef KMK
2955 memcpy (apath, name, root_len);
2956 apath[root_len] = '\0';
2957 assert (strlen (apath) == root_len);
2958#else
2959 strncpy (apath, name, root_len);
2960 apath[root_len] = '\0';
2961#endif
2962 dest = apath + root_len;
2963 /* Get past the root, since we already copied it. */
2964 name += root_len;
2965#ifdef HAVE_DOS_PATHS
2966 if (! STOP_SET (apath[root_len - 1], MAP_DIRSEP))
2967 {
2968 /* Convert d:foo into d:./foo and increase root_len. */
2969 apath[2] = '.';
2970 apath[3] = '/';
2971 dest++;
2972 root_len++;
2973 /* strncpy above copied one character too many. */
2974 name--;
2975 }
2976 else
2977 apath[root_len - 1] = '/'; /* make sure it's a forward slash */
2978#endif
2979 }
2980
2981 for (start = end = name; *start != '\0'; start = end)
2982 {
2983 unsigned long len;
2984
2985 /* Skip sequence of multiple path-separators. */
2986 while (STOP_SET (*start, MAP_DIRSEP))
2987 ++start;
2988
2989 /* Find end of path component. */
2990 for (end = start; ! STOP_SET (*end, MAP_DIRSEP|MAP_NUL); ++end)
2991 ;
2992
2993 len = end - start;
2994
2995 if (len == 0)
2996 break;
2997 else if (len == 1 && start[0] == '.')
2998 /* nothing */;
2999 else if (len == 2 && start[0] == '.' && start[1] == '.')
3000 {
3001 /* Back up to previous component, ignore if at root already. */
3002 if (dest > apath + root_len)
3003 for (--dest; ! STOP_SET (dest[-1], MAP_DIRSEP); --dest)
3004 ;
3005 }
3006 else
3007 {
3008 if (! STOP_SET (dest[-1], MAP_DIRSEP))
3009 *dest++ = '/';
3010
3011 if (dest + len >= apath_limit)
3012 return NULL;
3013
3014 dest = memcpy (dest, start, len);
3015 dest += len;
3016 *dest = '\0';
3017 }
3018 }
3019#endif /* !WINDOWS32 && !__OS2__ */
3020
3021 /* Unless it is root strip trailing separator. */
3022 if (dest > apath + root_len && STOP_SET (dest[-1], MAP_DIRSEP))
3023 --dest;
3024
3025 *dest = '\0';
3026
3027 return apath;
3028}
3029
3030
3031static char *
3032func_realpath (char *o, char **argv, const char *funcname UNUSED)
3033{
3034 /* Expand the argument. */
3035 const char *p = argv[0];
3036 const char *path = 0;
3037 int doneany = 0;
3038 unsigned int len = 0;
3039
3040 while ((path = find_next_token (&p, &len)) != 0)
3041 {
3042 if (len < GET_PATH_MAX)
3043 {
3044 char *rp;
3045 struct stat st;
3046 PATH_VAR (in);
3047 PATH_VAR (out);
3048
3049 strncpy (in, path, len);
3050 in[len] = '\0';
3051
3052#ifdef HAVE_REALPATH
3053 ENULLLOOP (rp, realpath (in, out));
3054#else
3055 rp = abspath (in, out);
3056#endif
3057
3058 if (rp)
3059 {
3060 int r;
3061 EINTRLOOP (r, stat (out, &st));
3062 if (r == 0)
3063 {
3064 o = variable_buffer_output (o, out, strlen (out));
3065 o = variable_buffer_output (o, " ", 1);
3066 doneany = 1;
3067 }
3068 }
3069 }
3070 }
3071
3072 /* Kill last space. */
3073 if (doneany)
3074 --o;
3075
3076 return o;
3077}
3078
3079static char *
3080func_file (char *o, char **argv, const char *funcname UNUSED)
3081{
3082 char *fn = argv[0];
3083
3084 if (fn[0] == '>')
3085 {
3086 FILE *fp;
3087#ifdef KMK_FOPEN_NO_INHERIT_MODE
3088 const char *mode = "w" KMK_FOPEN_NO_INHERIT_MODE;
3089#else
3090 const char *mode = "w";
3091#endif
3092
3093 /* We are writing a file. */
3094 ++fn;
3095 if (fn[0] == '>')
3096 {
3097#ifdef KMK_FOPEN_NO_INHERIT_MODE
3098 mode = "a" KMK_FOPEN_NO_INHERIT_MODE;
3099#else
3100 mode = "a";
3101#endif
3102 ++fn;
3103 }
3104 NEXT_TOKEN (fn);
3105
3106 if (fn[0] == '\0')
3107 O (fatal, *expanding_var, _("file: missing filename"));
3108
3109 ENULLLOOP (fp, fopen (fn, mode));
3110 if (fp == NULL)
3111 OSS (fatal, reading_file, _("open: %s: %s"), fn, strerror (errno));
3112
3113 if (argv[1])
3114 {
3115 int l = strlen (argv[1]);
3116 int nl = l == 0 || argv[1][l-1] != '\n';
3117
3118 if (fputs (argv[1], fp) == EOF || (nl && fputc ('\n', fp) == EOF))
3119 OSS (fatal, reading_file, _("write: %s: %s"), fn, strerror (errno));
3120 }
3121 if (fclose (fp))
3122 OSS (fatal, reading_file, _("close: %s: %s"), fn, strerror (errno));
3123 }
3124 else if (fn[0] == '<')
3125 {
3126 char *preo = o;
3127 FILE *fp;
3128
3129 ++fn;
3130 NEXT_TOKEN (fn);
3131 if (fn[0] == '\0')
3132 O (fatal, *expanding_var, _("file: missing filename"));
3133
3134 if (argv[1])
3135 O (fatal, *expanding_var, _("file: too many arguments"));
3136
3137#ifdef KMK_FOPEN_NO_INHERIT_MODE
3138 ENULLLOOP (fp, fopen (fn, "r" KMK_FOPEN_NO_INHERIT_MODE));
3139#else
3140 ENULLLOOP (fp, fopen (fn, "r"));
3141#endif
3142 if (fp == NULL)
3143 {
3144 if (errno == ENOENT)
3145 return o;
3146 OSS (fatal, reading_file, _("open: %s: %s"), fn, strerror (errno));
3147 }
3148
3149 while (1)
3150 {
3151 char buf[1024];
3152 size_t l = fread (buf, 1, sizeof (buf), fp);
3153 if (l > 0)
3154 o = variable_buffer_output (o, buf, l);
3155
3156 if (ferror (fp))
3157 if (errno != EINTR)
3158 OSS (fatal, reading_file, _("read: %s: %s"), fn, strerror (errno));
3159 if (feof (fp))
3160 break;
3161 }
3162 if (fclose (fp))
3163 OSS (fatal, reading_file, _("close: %s: %s"), fn, strerror (errno));
3164
3165 /* Remove trailing newline. */
3166 if (o > preo && o[-1] == '\n')
3167 if (--o > preo && o[-1] == '\r')
3168 --o;
3169 }
3170 else
3171 OS (fatal, *expanding_var, _("file: invalid file operation: %s"), fn);
3172
3173 return o;
3174}
3175
3176static char *
3177func_abspath (char *o, char **argv, const char *funcname UNUSED)
3178{
3179 /* Expand the argument. */
3180 const char *p = argv[0];
3181 const char *path = 0;
3182 int doneany = 0;
3183 unsigned int len = 0;
3184
3185 while ((path = find_next_token (&p, &len)) != 0)
3186 {
3187 if (len < GET_PATH_MAX)
3188 {
3189 PATH_VAR (in);
3190 PATH_VAR (out);
3191
3192 strncpy (in, path, len);
3193 in[len] = '\0';
3194
3195 if (abspath (in, out))
3196 {
3197 o = variable_buffer_output (o, out, strlen (out));
3198 o = variable_buffer_output (o, " ", 1);
3199 doneany = 1;
3200 }
3201 }
3202 }
3203
3204 /* Kill last space. */
3205 if (doneany)
3206 --o;
3207
3208 return o;
3209}
3210
3211#ifdef CONFIG_WITH_ABSPATHEX
3212/* Same as abspath except that the current path may be given as the
3213 2nd argument. */
3214static char *
3215func_abspathex (char *o, char **argv, const char *funcname UNUSED)
3216{
3217 char *cwd = argv[1];
3218
3219 /* cwd needs leading spaces chopped and may be optional,
3220 in which case we're exactly like $(abspath ). */
3221 if (cwd)
3222 while (ISBLANK (*cwd))
3223 cwd++;
3224 if (!cwd || !*cwd)
3225 o = func_abspath (o, argv, funcname);
3226 else
3227 {
3228 /* Expand the argument. */
3229 const char *p = argv[0];
3230 unsigned int cwd_len = ~0U;
3231 char *path = 0;
3232 int doneany = 0;
3233 unsigned int len = 0;
3234 PATH_VAR (in);
3235 PATH_VAR (out);
3236
3237 while ((path = find_next_token (&p, &len)) != 0)
3238 {
3239 if (len < GET_PATH_MAX)
3240 {
3241#ifdef HAVE_DOS_PATHS
3242 if (path[0] != '/' && path[0] != '\\' && (len < 2 || path[1] != ':') && cwd)
3243#else
3244 if (path[0] != '/' && cwd)
3245#endif
3246 {
3247 /* relative path, prefix with cwd. */
3248 if (cwd_len == ~0U)
3249 cwd_len = strlen (cwd);
3250 if (cwd_len + len + 1 >= GET_PATH_MAX)
3251 continue;
3252 memcpy (in, cwd, cwd_len);
3253 in[cwd_len] = '/';
3254 memcpy (in + cwd_len + 1, path, len);
3255 in[cwd_len + len + 1] = '\0';
3256 }
3257 else
3258 {
3259 /* absolute path pass it as-is. */
3260 memcpy (in, path, len);
3261 in[len] = '\0';
3262 }
3263
3264 if (abspath (in, out))
3265 {
3266 o = variable_buffer_output (o, out, strlen (out));
3267 o = variable_buffer_output (o, " ", 1);
3268 doneany = 1;
3269 }
3270 }
3271 }
3272
3273 /* Kill last space. */
3274 if (doneany)
3275 --o;
3276 }
3277
3278 return o;
3279}
3280#endif
3281
3282#ifdef CONFIG_WITH_XARGS
3283/* Create one or more command lines avoiding the max argument
3284 length restriction of the host OS.
3285
3286 The last argument is the list of arguments that the normal
3287 xargs command would be fed from stdin.
3288
3289 The first argument is initial command and it's arguments.
3290
3291 If there are three or more arguments, the 2nd argument is
3292 the command and arguments to be used on subsequent
3293 command lines. Defaults to the initial command.
3294
3295 If there are four or more arguments, the 3rd argument is
3296 the command to be used at the final command line. Defaults
3297 to the sub sequent or initial command .
3298
3299 A future version of this function may define more arguments
3300 and therefor anyone specifying six or more arguments will
3301 cause fatal errors.
3302
3303 Typical usage is:
3304 $(xargs ar cas mylib.a,$(objects))
3305 or
3306 $(xargs ar cas mylib.a,ar as mylib.a,$(objects))
3307
3308 It will then create one or more "ar mylib.a ..." command
3309 lines with proper \n\t separation so it can be used when
3310 writing rules. */
3311static char *
3312func_xargs (char *o, char **argv, const char *funcname UNUSED)
3313{
3314 int argc;
3315 const char *initial_cmd;
3316 size_t initial_cmd_len;
3317 const char *subsequent_cmd;
3318 size_t subsequent_cmd_len;
3319 const char *final_cmd;
3320 size_t final_cmd_len;
3321 const char *args;
3322 size_t max_args;
3323 int i;
3324
3325#ifdef ARG_MAX
3326 /* ARG_MAX is a bit unreliable (environment), so drop 25% of the max. */
3327# define XARGS_MAX (ARG_MAX - (ARG_MAX / 4))
3328#else /* FIXME: update configure with a command line length test. */
3329# define XARGS_MAX 10240
3330#endif
3331
3332 argc = 0;
3333 while (argv[argc])
3334 argc++;
3335 if (argc > 4)
3336 O (fatal, NILF, _("Too many arguments for $(xargs)!\n"));
3337
3338 /* first: the initial / default command.*/
3339 initial_cmd = argv[0];
3340 while (ISSPACE (*initial_cmd))
3341 initial_cmd++;
3342 max_args = initial_cmd_len = strlen (initial_cmd);
3343
3344 /* second: the command for the subsequent command lines. defaults to the initial cmd. */
3345 subsequent_cmd = argc > 2 && argv[1][0] != '\0' ? argv[1] : "\0";
3346 while (ISSPACE (*subsequent_cmd))
3347 subsequent_cmd++; /* gcc 7.3.0 complains "offset ‘1’ outside bounds of constant string" if constant is "" rather than "\0". */
3348 if (*subsequent_cmd)
3349 {
3350 subsequent_cmd_len = strlen (subsequent_cmd);
3351 if (subsequent_cmd_len > max_args)
3352 max_args = subsequent_cmd_len;
3353 }
3354 else
3355 {
3356 subsequent_cmd = initial_cmd;
3357 subsequent_cmd_len = initial_cmd_len;
3358 }
3359
3360 /* third: the final command. defaults to the subseq cmd. */
3361 final_cmd = argc > 3 && argv[2][0] != '\0' ? argv[2] : "\0";
3362 while (ISSPACE (*final_cmd))
3363 final_cmd++; /* gcc 7.3.0: same complaint as for subsequent_cmd++ */
3364 if (*final_cmd)
3365 {
3366 final_cmd_len = strlen (final_cmd);
3367 if (final_cmd_len > max_args)
3368 max_args = final_cmd_len;
3369 }
3370 else
3371 {
3372 final_cmd = subsequent_cmd;
3373 final_cmd_len = subsequent_cmd_len;
3374 }
3375
3376 /* last: the arguments to split up into sensible portions. */
3377 args = argv[argc - 1];
3378
3379 /* calc the max argument length. */
3380 if (XARGS_MAX <= max_args + 2)
3381 ONN (fatal, NILF, _("$(xargs): the commands are longer than the max exec argument length. (%lu <= %lu)\n"),
3382 (unsigned long)XARGS_MAX, (unsigned long)max_args + 2);
3383 max_args = XARGS_MAX - max_args - 1;
3384
3385 /* generate the commands. */
3386 i = 0;
3387 for (i = 0; ; i++)
3388 {
3389 unsigned int len;
3390 const char *iterator = args;
3391 const char *end = args;
3392 const char *cur;
3393 const char *tmp;
3394
3395 /* scan the arguments till we reach the end or the max length. */
3396 while ((cur = find_next_token(&iterator, &len))
3397 && (size_t)((cur + len) - args) < max_args)
3398 end = cur + len;
3399 if (cur && end == args)
3400 O (fatal, NILF, _("$(xargs): command + one single arg is too much. giving up.\n"));
3401
3402 /* emit the command. */
3403 if (i == 0)
3404 {
3405 o = variable_buffer_output (o, (char *)initial_cmd, initial_cmd_len);
3406 o = variable_buffer_output (o, " ", 1);
3407 }
3408 else if (cur)
3409 {
3410 o = variable_buffer_output (o, "\n\t", 2);
3411 o = variable_buffer_output (o, (char *)subsequent_cmd, subsequent_cmd_len);
3412 o = variable_buffer_output (o, " ", 1);
3413 }
3414 else
3415 {
3416 o = variable_buffer_output (o, "\n\t", 2);
3417 o = variable_buffer_output (o, (char *)final_cmd, final_cmd_len);
3418 o = variable_buffer_output (o, " ", 1);
3419 }
3420
3421 tmp = end;
3422 while (tmp > args && ISSPACE (tmp[-1])) /* drop trailing spaces. */
3423 tmp--;
3424 o = variable_buffer_output (o, (char *)args, tmp - args);
3425
3426
3427 /* next */
3428 if (!cur)
3429 break;
3430 args = end;
3431 while (ISSPACE (*args))
3432 args++;
3433 }
3434
3435 return o;
3436}
3437#endif
3438
3439
3440#ifdef CONFIG_WITH_STRING_FUNCTIONS
3441/*
3442 $(length string)
3443
3444 XXX: This doesn't take multibyte locales into account.
3445 */
3446static char *
3447func_length (char *o, char **argv, const char *funcname UNUSED)
3448{
3449 size_t len = strlen (argv[0]);
3450 return math_int_to_variable_buffer (o, len);
3451}
3452
3453/*
3454 $(length-var var)
3455
3456 XXX: This doesn't take multibyte locales into account.
3457 */
3458static char *
3459func_length_var (char *o, char **argv, const char *funcname UNUSED)
3460{
3461 struct variable *var = lookup_variable (argv[0], strlen (argv[0]));
3462 return math_int_to_variable_buffer (o, var ? var->value_length : 0);
3463}
3464
3465
3466/* func_insert and func_substr helper. */
3467static char *
3468helper_pad (char *o, size_t to_add, const char *pad, size_t pad_len)
3469{
3470 while (to_add > 0)
3471 {
3472 size_t size = to_add > pad_len ? pad_len : to_add;
3473 o = variable_buffer_output (o, pad, size);
3474 to_add -= size;
3475 }
3476 return o;
3477}
3478
3479/*
3480 $(insert in, str[, n[, length[, pad]]])
3481
3482 XXX: This doesn't take multibyte locales into account.
3483 */
3484static char *
3485func_insert (char *o, char **argv, const char *funcname UNUSED)
3486{
3487 const char *in = argv[0];
3488 math_int in_len = (math_int)strlen (in);
3489 const char *str = argv[1];
3490 math_int str_len = (math_int)strlen (str);
3491 math_int n = 0;
3492 math_int length = str_len;
3493 const char *pad = " ";
3494 size_t pad_len = 16;
3495 size_t i;
3496
3497 if (argv[2] != NULL)
3498 {
3499 n = math_int_from_string (argv[2]);
3500 if (n > 0)
3501 n--; /* one-origin */
3502 else if (n == 0)
3503 n = str_len; /* append */
3504 else
3505 { /* n < 0: from the end */
3506 n = str_len + n;
3507 if (n < 0)
3508 n = 0;
3509 }
3510 if (n > 16*1024*1024) /* 16MB */
3511 OS (fatal, NILF, _("$(insert ): n=%s is out of bounds\n"), argv[2]);
3512
3513 if (argv[3] != NULL)
3514 {
3515 length = math_int_from_string (argv[3]);
3516 if (length < 0 || length > 16*1024*1024 /* 16MB */)
3517 OS (fatal, NILF, _("$(insert ): length=%s is out of bounds\n"), argv[3]);
3518
3519 if (argv[4] != NULL)
3520 {
3521 const char *tmp = argv[4];
3522 for (i = 0; tmp[i] == ' '; i++)
3523 /* nothing */;
3524 if (tmp[i] != '\0')
3525 {
3526 pad = argv[4];
3527 pad_len = strlen (pad);
3528 }
3529 /* else: it was all default spaces. */
3530 }
3531 }
3532 }
3533
3534 /* the head of the original string */
3535 if (n > 0)
3536 {
3537 if (n <= str_len)
3538 o = variable_buffer_output (o, str, n);
3539 else
3540 {
3541 o = variable_buffer_output (o, str, str_len);
3542 o = helper_pad (o, n - str_len, pad, pad_len);
3543 }
3544 }
3545
3546 /* insert the string */
3547 if (length <= in_len)
3548 o = variable_buffer_output (o, in, length);
3549 else
3550 {
3551 o = variable_buffer_output (o, in, in_len);
3552 o = helper_pad (o, length - in_len, pad, pad_len);
3553 }
3554
3555 /* the tail of the original string */
3556 if (n < str_len)
3557 o = variable_buffer_output (o, str + n, str_len - n);
3558
3559 return o;
3560}
3561
3562
3563/*
3564 $(pos needle, haystack[, start])
3565 $(lastpos needle, haystack[, start])
3566
3567 XXX: This doesn't take multibyte locales into account.
3568 */
3569static char *
3570func_pos (char *o, char **argv, const char *funcname UNUSED)
3571{
3572 const char *needle = *argv[0] ? argv[0] : " ";
3573 size_t needle_len = strlen (needle);
3574 const char *haystack = argv[1];
3575 size_t haystack_len = strlen (haystack);
3576 math_int start = 0;
3577 const char *hit;
3578
3579 if (argv[2] != NULL)
3580 {
3581 start = math_int_from_string (argv[2]);
3582 if (start > 0)
3583 start--; /* one-origin */
3584 else if (start < 0)
3585 start = haystack_len + start; /* from the end */
3586 if (start < 0 || start + needle_len > haystack_len)
3587 return math_int_to_variable_buffer (o, 0);
3588 }
3589 else if (funcname[0] == 'l')
3590 start = haystack_len - 1;
3591
3592 /* do the searching */
3593 if (funcname[0] != 'l')
3594 { /* pos */
3595 if (needle_len == 1)
3596 hit = strchr (haystack + start, *needle);
3597 else
3598 hit = strstr (haystack + start, needle);
3599 }
3600 else
3601 { /* last pos */
3602 int ch = *needle;
3603 size_t off = start + 1;
3604
3605 hit = NULL;
3606 while (off-- > 0)
3607 {
3608 if ( haystack[off] == ch
3609 && ( needle_len == 1
3610 || strncmp (&haystack[off], needle, needle_len) == 0))
3611 {
3612 hit = haystack + off;
3613 break;
3614 }
3615 }
3616 }
3617
3618 return math_int_to_variable_buffer (o, hit ? hit - haystack + 1 : 0);
3619}
3620
3621
3622/*
3623 $(substr str, start[, length[, pad]])
3624
3625 XXX: This doesn't take multibyte locales into account.
3626 */
3627static char *
3628func_substr (char *o, char **argv, const char *funcname UNUSED)
3629{
3630 const char *str = argv[0];
3631 math_int str_len = (math_int)strlen (str);
3632 math_int start = math_int_from_string (argv[1]);
3633 math_int length = 0;
3634 const char *pad = NULL;
3635 size_t pad_len = 0;
3636
3637 if (argv[2] != NULL)
3638 {
3639 if (argv[3] != NULL)
3640 {
3641 pad = argv[3];
3642 for (pad_len = 0; pad[pad_len] == ' '; pad_len++)
3643 /* nothing */;
3644 if (pad[pad_len] != '\0')
3645 pad_len = strlen (pad);
3646 else
3647 {
3648 pad = " ";
3649 pad_len = 16;
3650 }
3651 }
3652 length = math_int_from_string (argv[2]);
3653 if (pad != NULL && length > 16*1024*1024 /* 16MB */)
3654 OS (fatal, NILF, _("$(substr ): length=%s is out of bounds\n"), argv[2]);
3655 if (pad != NULL && length < 0)
3656 OS (fatal, NILF, _("$(substr ): negative length (%s) and padding doesn't mix.\n"), argv[2]);
3657 if (length == 0)
3658 return o;
3659 }
3660
3661 /* Note that negative start and length are used for referencing from the
3662 end of the string. */
3663 if (pad == NULL)
3664 {
3665 if (start > 0)
3666 start--; /* one-origin */
3667 else
3668 {
3669 start = str_len + start;
3670 if (start <= 0)
3671 {
3672 if (length < 0)
3673 return o;
3674 start += length;
3675 if (start <= 0)
3676 return o;
3677 length = start;
3678 start = 0;
3679 }
3680 }
3681
3682 if (start >= str_len)
3683 return o;
3684 if (length == 0)
3685 length = str_len - start;
3686 else if (length < 0)
3687 {
3688 if (str_len <= -length)
3689 return o;
3690 length += str_len;
3691 if (length <= start)
3692 return o;
3693 length -= start;
3694 }
3695 else if (start + length > str_len)
3696 length = str_len - start;
3697
3698 o = variable_buffer_output (o, str + start, length);
3699 }
3700 else
3701 {
3702 if (start > 0)
3703 {
3704 start--; /* one-origin */
3705 if (start >= str_len)
3706 return length ? helper_pad (o, length, pad, pad_len) : o;
3707 if (length == 0)
3708 length = str_len - start;
3709 }
3710 else
3711 {
3712 start = str_len + start;
3713 if (start <= 0)
3714 {
3715 if (start + length <= 0)
3716 return length ? helper_pad (o, length, pad, pad_len) : o;
3717 o = helper_pad (o, -start, pad, pad_len);
3718 return variable_buffer_output (o, str, length + start);
3719 }
3720 if (length == 0)
3721 length = str_len - start;
3722 }
3723 if (start + length <= str_len)
3724 o = variable_buffer_output (o, str + start, length);
3725 else
3726 {
3727 o = variable_buffer_output (o, str + start, str_len - start);
3728 o = helper_pad (o, start + length - str_len, pad, pad_len);
3729 }
3730 }
3731
3732 return o;
3733}
3734
3735
3736/*
3737 $(translate string, from-set[, to-set[, pad-char]])
3738
3739 XXX: This doesn't take multibyte locales into account.
3740 */
3741static char *
3742func_translate (char *o, char **argv, const char *funcname UNUSED)
3743{
3744 const unsigned char *str = (const unsigned char *)argv[0];
3745 const unsigned char *from_set = (const unsigned char *)argv[1];
3746 const char *to_set = argv[2] != NULL ? argv[2] : "";
3747 char trans_tab[1 << CHAR_BIT];
3748 int i;
3749 char ch;
3750
3751 /* init the array. */
3752 for (i = 0; i < (1 << CHAR_BIT); i++)
3753 trans_tab[i] = i;
3754
3755 while ( (i = *from_set) != '\0'
3756 && (ch = *to_set) != '\0')
3757 {
3758 trans_tab[i] = ch;
3759 from_set++;
3760 to_set++;
3761 }
3762
3763 if (i != '\0')
3764 {
3765 ch = '\0'; /* no padding == remove char */
3766 if (argv[2] != NULL && argv[3] != NULL)
3767 {
3768 ch = argv[3][0];
3769 if (ch && argv[3][1])
3770 OS (fatal, NILF, _("$(translate ): pad=`%s' expected a single char\n"), argv[3]);
3771 if (ch == '\0') /* no char == space */
3772 ch = ' ';
3773 }
3774 while ((i = *from_set++) != '\0')
3775 trans_tab[i] = ch;
3776 }
3777
3778 /* do the translation */
3779 while ((i = *str++) != '\0')
3780 {
3781 ch = trans_tab[i];
3782 if (ch)
3783 o = variable_buffer_output (o, &ch, 1);
3784 }
3785
3786 return o;
3787}
3788#endif /* CONFIG_WITH_STRING_FUNCTIONS */
3789
3790
3791#ifdef CONFIG_WITH_LAZY_DEPS_VARS
3792
3793/* This is also in file.c (bad). */
3794# if VMS
3795# define FILE_LIST_SEPARATOR ','
3796# else
3797# define FILE_LIST_SEPARATOR ' '
3798# endif
3799
3800/* Implements $^ and $+.
3801
3802 The first comes with FUNCNAME 'deps', the second as 'deps-all'.
3803
3804 If no second argument is given, or if it's empty, or if it's zero,
3805 all dependencies will be returned. If the second argument is non-zero
3806 the dependency at that position will be returned. If the argument is
3807 negative a fatal error is thrown. */
3808static char *
3809func_deps (char *o, char **argv, const char *funcname)
3810{
3811 unsigned int idx = 0;
3812 struct file *file;
3813
3814 /* Handle the argument if present. */
3815
3816 if (argv[1])
3817 {
3818 char *p = argv[1];
3819 while (ISSPACE (*p))
3820 p++;
3821 if (*p != '\0')
3822 {
3823 char *n;
3824 long l = strtol (p, &n, 0);
3825 while (ISSPACE (*n))
3826 n++;
3827 idx = l;
3828 if (*n != '\0' || l < 0 || (long)idx != l)
3829 OSS (fatal, NILF, _("%s: invalid index value: `%s'\n"), funcname, p);
3830 }
3831 }
3832
3833 /* Find the file and select the list corresponding to FUNCNAME. */
3834
3835 file = lookup_file (argv[0]);
3836 if (file)
3837 {
3838 struct dep *deps;
3839 struct dep *d;
3840 if (funcname[4] == '\0')
3841 {
3842 deps = file->deps_no_dupes;
3843 if (!deps && file->deps)
3844 deps = file->deps = create_uniqute_deps_chain (file->deps);
3845 }
3846 else
3847 deps = file->deps;
3848
3849 if ( file->double_colon
3850 && ( file->double_colon != file
3851 || file->last != file))
3852 OSS (error, NILF, _("$(%s ) cannot be used on files with multiple double colon rules like `%s'\n"),
3853 funcname, file->name);
3854
3855 if (idx == 0 /* all */)
3856 {
3857 unsigned int total_len = 0;
3858
3859 /* calc the result length. */
3860
3861 for (d = deps; d; d = d->next)
3862 if (!d->ignore_mtime)
3863 {
3864 const char *c = dep_name (d);
3865
3866#ifndef NO_ARCHIVES
3867 if (ar_name (c))
3868 {
3869 c = strchr (c, '(') + 1;
3870 total_len += strlen (c);
3871 }
3872 else
3873#endif
3874#ifdef CONFIG_WITH_STRCACHE2
3875 if (!d->need_2nd_expansion)
3876 total_len += strcache2_get_len (&file_strcache, c) + 1;
3877 else
3878#endif
3879 total_len += strlen (c) + 1;
3880 }
3881
3882 if (total_len)
3883 {
3884 /* prepare the variable buffer dude wrt to the output size and
3885 pass along the strings. */
3886
3887 o = variable_buffer_output (o + total_len, "", 0) - total_len; /* a hack */
3888
3889 for (d = deps; d; d = d->next)
3890 if (!d->ignore_mtime)
3891 {
3892 unsigned int len;
3893 const char *c = dep_name (d);
3894
3895#ifndef NO_ARCHIVES
3896 if (ar_name (c))
3897 {
3898 c = strchr (c, '(') + 1;
3899 len = strlen (c);
3900 }
3901 else
3902#endif
3903#ifdef CONFIG_WITH_STRCACHE2
3904 if (!d->need_2nd_expansion)
3905 len = strcache2_get_len (&file_strcache, c) + 1;
3906 else
3907#endif
3908 len = strlen (c) + 1;
3909 o = variable_buffer_output (o, c, len);
3910 o[-1] = FILE_LIST_SEPARATOR;
3911 }
3912
3913 --o; /* nuke the last list separator */
3914 *o = '\0';
3915 }
3916 }
3917 else
3918 {
3919 /* Dependency given by index. */
3920
3921 for (d = deps; d; d = d->next)
3922 if (!d->ignore_mtime)
3923 {
3924 if (--idx == 0) /* 1 based indexing */
3925 {
3926 unsigned int len;
3927 const char *c = dep_name (d);
3928
3929#ifndef NO_ARCHIVES
3930 if (ar_name (c))
3931 {
3932 c = strchr (c, '(') + 1;
3933 len = strlen (c) - 1;
3934 }
3935 else
3936#endif
3937#ifdef CONFIG_WITH_STRCACHE2
3938 if (!d->need_2nd_expansion)
3939 len = strcache2_get_len (&file_strcache, c);
3940 else
3941#endif
3942 len = strlen (c);
3943 o = variable_buffer_output (o, c, len);
3944 break;
3945 }
3946 }
3947 }
3948 }
3949
3950 return o;
3951}
3952
3953/* Implements $?.
3954
3955 If no second argument is given, or if it's empty, or if it's zero,
3956 all dependencies will be returned. If the second argument is non-zero
3957 the dependency at that position will be returned. If the argument is
3958 negative a fatal error is thrown. */
3959static char *
3960func_deps_newer (char *o, char **argv, const char *funcname)
3961{
3962 unsigned int idx = 0;
3963 struct file *file;
3964
3965 /* Handle the argument if present. */
3966
3967 if (argv[1])
3968 {
3969 char *p = argv[1];
3970 while (ISSPACE (*p))
3971 p++;
3972 if (*p != '\0')
3973 {
3974 char *n;
3975 long l = strtol (p, &n, 0);
3976 while (ISSPACE (*n))
3977 n++;
3978 idx = l;
3979 if (*n != '\0' || l < 0 || (long)idx != l)
3980 OSS (fatal, NILF, _("%s: invalid index value: `%s'\n"), funcname, p);
3981 }
3982 }
3983
3984 /* Find the file. */
3985
3986 file = lookup_file (argv[0]);
3987 if (file)
3988 {
3989 struct dep *deps = file->deps;
3990 struct dep *d;
3991
3992 if ( file->double_colon
3993 && ( file->double_colon != file
3994 || file->last != file))
3995 OSS (error, NILF, _("$(%s ) cannot be used on files with multiple double colon rules like `%s'\n"),
3996 funcname, file->name);
3997
3998 if (idx == 0 /* all */)
3999 {
4000 unsigned int total_len = 0;
4001
4002 /* calc the result length. */
4003
4004 for (d = deps; d; d = d->next)
4005 if (!d->ignore_mtime && d->changed)
4006 {
4007 const char *c = dep_name (d);
4008
4009#ifndef NO_ARCHIVES
4010 if (ar_name (c))
4011 {
4012 c = strchr (c, '(') + 1;
4013 total_len += strlen (c);
4014 }
4015 else
4016#endif
4017#ifdef CONFIG_WITH_STRCACHE2
4018 if (!d->need_2nd_expansion)
4019 total_len += strcache2_get_len (&file_strcache, c) + 1;
4020 else
4021#endif
4022 total_len += strlen (c) + 1;
4023 }
4024
4025 if (total_len)
4026 {
4027 /* prepare the variable buffer dude wrt to the output size and
4028 pass along the strings. */
4029
4030 o = variable_buffer_output (o + total_len, "", 0) - total_len; /* a hack */
4031
4032 for (d = deps; d; d = d->next)
4033 if (!d->ignore_mtime && d->changed)
4034 {
4035 unsigned int len;
4036 const char *c = dep_name (d);
4037
4038#ifndef NO_ARCHIVES
4039 if (ar_name (c))
4040 {
4041 c = strchr (c, '(') + 1;
4042 len = strlen (c);
4043 }
4044 else
4045#endif
4046#ifdef CONFIG_WITH_STRCACHE2
4047 if (!d->need_2nd_expansion)
4048 len = strcache2_get_len (&file_strcache, c) + 1;
4049 else
4050#endif
4051 len = strlen (c) + 1;
4052 o = variable_buffer_output (o, c, len);
4053 o[-1] = FILE_LIST_SEPARATOR;
4054 }
4055
4056 --o; /* nuke the last list separator */
4057 *o = '\0';
4058 }
4059 }
4060 else
4061 {
4062 /* Dependency given by index. */
4063
4064 for (d = deps; d; d = d->next)
4065 if (!d->ignore_mtime && d->changed)
4066 {
4067 if (--idx == 0) /* 1 based indexing */
4068 {
4069 unsigned int len;
4070 const char *c = dep_name (d);
4071
4072#ifndef NO_ARCHIVES
4073 if (ar_name (c))
4074 {
4075 c = strchr (c, '(') + 1;
4076 len = strlen (c) - 1;
4077 }
4078 else
4079#endif
4080#ifdef CONFIG_WITH_STRCACHE2
4081 if (!d->need_2nd_expansion)
4082 len = strcache2_get_len (&file_strcache, c);
4083 else
4084#endif
4085 len = strlen (c);
4086 o = variable_buffer_output (o, c, len);
4087 break;
4088 }
4089 }
4090 }
4091 }
4092
4093 return o;
4094}
4095
4096/* Implements $|, the order only dependency list.
4097
4098 If no second argument is given, or if it's empty, or if it's zero,
4099 all dependencies will be returned. If the second argument is non-zero
4100 the dependency at that position will be returned. If the argument is
4101 negative a fatal error is thrown. */
4102static char *
4103func_deps_order_only (char *o, char **argv, const char *funcname)
4104{
4105 unsigned int idx = 0;
4106 struct file *file;
4107
4108 /* Handle the argument if present. */
4109
4110 if (argv[1])
4111 {
4112 char *p = argv[1];
4113 while (ISSPACE (*p))
4114 p++;
4115 if (*p != '\0')
4116 {
4117 char *n;
4118 long l = strtol (p, &n, 0);
4119 while (ISSPACE (*n))
4120 n++;
4121 idx = l;
4122 if (*n != '\0' || l < 0 || (long)idx != l)
4123 OSS (fatal, NILF, _("%s: invalid index value: `%s'\n"), funcname, p);
4124 }
4125 }
4126
4127 /* Find the file. */
4128
4129 file = lookup_file (argv[0]);
4130 if (file)
4131 {
4132 struct dep *deps = file->deps;
4133 struct dep *d;
4134
4135 if ( file->double_colon
4136 && ( file->double_colon != file
4137 || file->last != file))
4138 OSS (error, NILF, _("$(%s ) cannot be used on files with multiple double colon rules like `%s'\n"),
4139 funcname, file->name);
4140
4141 if (idx == 0 /* all */)
4142 {
4143 unsigned int total_len = 0;
4144
4145 /* calc the result length. */
4146
4147 for (d = deps; d; d = d->next)
4148 if (d->ignore_mtime)
4149 {
4150 const char *c = dep_name (d);
4151
4152#ifndef NO_ARCHIVES
4153 if (ar_name (c))
4154 {
4155 c = strchr (c, '(') + 1;
4156 total_len += strlen (c);
4157 }
4158 else
4159#endif
4160#ifdef CONFIG_WITH_STRCACHE2
4161 if (!d->need_2nd_expansion)
4162 total_len += strcache2_get_len (&file_strcache, c) + 1;
4163 else
4164#endif
4165 total_len += strlen (c) + 1;
4166 }
4167
4168 if (total_len)
4169 {
4170 /* prepare the variable buffer dude wrt to the output size and
4171 pass along the strings. */
4172
4173 o = variable_buffer_output (o + total_len, "", 0) - total_len; /* a hack */
4174
4175 for (d = deps; d; d = d->next)
4176 if (d->ignore_mtime)
4177 {
4178 unsigned int len;
4179 const char *c = dep_name (d);
4180
4181#ifndef NO_ARCHIVES
4182 if (ar_name (c))
4183 {
4184 c = strchr (c, '(') + 1;
4185 len = strlen (c);
4186 }
4187 else
4188#endif
4189#ifdef CONFIG_WITH_STRCACHE2
4190 if (!d->need_2nd_expansion)
4191 len = strcache2_get_len (&file_strcache, c) + 1;
4192 else
4193#endif
4194 len = strlen (c) + 1;
4195 o = variable_buffer_output (o, c, len);
4196 o[-1] = FILE_LIST_SEPARATOR;
4197 }
4198
4199 --o; /* nuke the last list separator */
4200 *o = '\0';
4201 }
4202 }
4203 else
4204 {
4205 /* Dependency given by index. */
4206
4207 for (d = deps; d; d = d->next)
4208 if (d->ignore_mtime)
4209 {
4210 if (--idx == 0) /* 1 based indexing */
4211 {
4212 unsigned int len;
4213 const char *c = dep_name (d);
4214
4215#ifndef NO_ARCHIVES
4216 if (ar_name (c))
4217 {
4218 c = strchr (c, '(') + 1;
4219 len = strlen (c) - 1;
4220 }
4221 else
4222#endif
4223#ifdef CONFIG_WITH_STRCACHE2
4224 if (!d->need_2nd_expansion)
4225 len = strcache2_get_len (&file_strcache, c);
4226 else
4227#endif
4228 len = strlen (c);
4229 o = variable_buffer_output (o, c, len);
4230 break;
4231 }
4232 }
4233 }
4234 }
4235
4236 return o;
4237}
4238#endif /* CONFIG_WITH_LAZY_DEPS_VARS */
4239
4240
4241
4242#ifdef CONFIG_WITH_DEFINED
4243/* Similar to ifdef. */
4244static char *
4245func_defined (char *o, char **argv, const char *funcname UNUSED)
4246{
4247 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
4248 int result = v != NULL && *v->value != '\0';
4249 o = variable_buffer_output (o, result ? "1" : "", result);
4250 return o;
4251}
4252#endif /* CONFIG_WITH_DEFINED*/
4253
4254#ifdef CONFIG_WITH_TOUPPER_TOLOWER
4255static char *
4256func_toupper_tolower (char *o, char **argv, const char *funcname)
4257{
4258 /* Expand the argument. */
4259 const char *p = argv[0];
4260 while (*p)
4261 {
4262 /* convert to temporary buffer */
4263 char tmp[256];
4264 unsigned int i;
4265 if (!strcmp(funcname, "toupper"))
4266 for (i = 0; i < sizeof(tmp) && *p; i++, p++)
4267 tmp[i] = toupper(*p);
4268 else
4269 for (i = 0; i < sizeof(tmp) && *p; i++, p++)
4270 tmp[i] = tolower(*p);
4271 o = variable_buffer_output (o, tmp, i);
4272 }
4273
4274 return o;
4275}
4276#endif /* CONFIG_WITH_TOUPPER_TOLOWER */
4277
4278#if defined(CONFIG_WITH_VALUE_LENGTH) && defined(CONFIG_WITH_COMPARE)
4279
4280/* Strip leading spaces and other things off a command. */
4281static const char *
4282comp_cmds_strip_leading (const char *s, const char *e)
4283{
4284 while (s < e)
4285 {
4286 const char ch = *s;
4287 if (!ISBLANK (ch)
4288 && ch != '@'
4289#ifdef CONFIG_WITH_COMMANDS_FUNC
4290 && ch != '%'
4291#endif
4292 && ch != '+'
4293 && ch != '-')
4294 break;
4295 s++;
4296 }
4297 return s;
4298}
4299
4300/* Worker for func_comp_vars() which is called if the comparision failed.
4301 It will do the slow command by command comparision of the commands
4302 when there invoked as comp-cmds. */
4303static char *
4304comp_vars_ne (char *o, const char *s1, const char *e1, const char *s2, const char *e2,
4305 char *ne_retval, const char *funcname)
4306{
4307 /* give up at once if not comp-cmds or comp-cmds-ex. */
4308 if (strcmp (funcname, "comp-cmds") != 0
4309 && strcmp (funcname, "comp-cmds-ex") != 0)
4310 o = variable_buffer_output (o, ne_retval, strlen (ne_retval));
4311 else
4312 {
4313 const char * const s1_start = s1;
4314 int new_cmd = 1;
4315 int diff;
4316 for (;;)
4317 {
4318 /* if it's a new command, strip leading stuff. */
4319 if (new_cmd)
4320 {
4321 s1 = comp_cmds_strip_leading (s1, e1);
4322 s2 = comp_cmds_strip_leading (s2, e2);
4323 new_cmd = 0;
4324 }
4325 if (s1 >= e1 || s2 >= e2)
4326 break;
4327
4328 /*
4329 * Inner compare loop which compares one line.
4330 * FIXME: parse quoting!
4331 */
4332 for (;;)
4333 {
4334 const char ch1 = *s1;
4335 const char ch2 = *s2;
4336 diff = ch1 - ch2;
4337 if (diff)
4338 break;
4339 if (ch1 == '\n')
4340 break;
4341 assert (ch1 != '\r');
4342
4343 /* next */
4344 s1++;
4345 s2++;
4346 if (s1 >= e1 || s2 >= e2)
4347 break;
4348 }
4349
4350 /*
4351 * If we exited because of a difference try to end-of-command
4352 * comparision, e.g. ignore trailing spaces.
4353 */
4354 if (diff)
4355 {
4356 /* strip */
4357 while (s1 < e1 && ISBLANK (*s1))
4358 s1++;
4359 while (s2 < e2 && ISBLANK (*s2))
4360 s2++;
4361 if (s1 >= e1 || s2 >= e2)
4362 break;
4363
4364 /* compare again and check that it's a newline. */
4365 if (*s2 != '\n' || *s1 != '\n')
4366 break;
4367 }
4368 /* Break out if we exited because of EOS. */
4369 else if (s1 >= e1 || s2 >= e2)
4370 break;
4371
4372 /*
4373 * Detect the end of command lines.
4374 */
4375 if (*s1 == '\n')
4376 new_cmd = s1 == s1_start || s1[-1] != '\\';
4377 s1++;
4378 s2++;
4379 }
4380
4381 /*
4382 * Ignore trailing empty lines.
4383 */
4384 if (s1 < e1 || s2 < e2)
4385 {
4386 while (s1 < e1 && (ISBLANK (*s1) || *s1 == '\n'))
4387 if (*s1++ == '\n')
4388 s1 = comp_cmds_strip_leading (s1, e1);
4389 while (s2 < e2 && (ISBLANK (*s2) || *s2 == '\n'))
4390 if (*s2++ == '\n')
4391 s2 = comp_cmds_strip_leading (s2, e2);
4392 }
4393
4394 /* emit the result. */
4395 if (s1 == e1 && s2 == e2)
4396 o = variable_buffer_output (o, "", 1) - 1; /** @todo check why this was necessary back the... */
4397 else
4398 o = variable_buffer_output (o, ne_retval, strlen (ne_retval));
4399 }
4400 return o;
4401}
4402
4403/*
4404 $(comp-vars var1,var2,not-equal-return)
4405 or
4406 $(comp-cmds cmd-var1,cmd-var2,not-equal-return)
4407
4408 Compares the two variables (that's given by name to avoid unnecessary
4409 expanding) and return the string in the third argument if not equal.
4410 If equal, nothing is returned.
4411
4412 comp-vars will to an exact comparision only stripping leading and
4413 trailing spaces.
4414
4415 comp-cmds will compare command by command, ignoring not only leading
4416 and trailing spaces on each line but also leading one leading '@',
4417 '-', '+' and '%'
4418*/
4419static char *
4420func_comp_vars (char *o, char **argv, const char *funcname)
4421{
4422 const char *s1, *e1, *x1, *s2, *e2, *x2;
4423 char *a1 = NULL, *a2 = NULL;
4424 size_t l, l1, l2;
4425 struct variable *var1 = lookup_variable (argv[0], strlen (argv[0]));
4426 struct variable *var2 = lookup_variable (argv[1], strlen (argv[1]));
4427
4428 /* the simple cases */
4429 if (var1 == var2)
4430 return variable_buffer_output (o, "", 0); /* eq */
4431 if (!var1 || !var2)
4432 return variable_buffer_output (o, argv[2], strlen(argv[2]));
4433 if (var1->value == var2->value)
4434 return variable_buffer_output (o, "", 0); /* eq */
4435 if ( (!var1->recursive || IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR (var1))
4436 && (!var2->recursive || IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR (var2)) )
4437 {
4438 if ( var1->value_length == var2->value_length
4439 && !memcmp (var1->value, var2->value, var1->value_length))
4440 return variable_buffer_output (o, "", 0); /* eq */
4441
4442 /* ignore trailing and leading blanks */
4443 s1 = var1->value;
4444 e1 = s1 + var1->value_length;
4445 while (ISBLANK (*s1))
4446 s1++;
4447 while (e1 > s1 && ISBLANK (e1[-1]))
4448 e1--;
4449
4450 s2 = var2->value;
4451 e2 = s2 + var2->value_length;
4452 while (ISBLANK (*s2))
4453 s2++;
4454 while (e2 > s2 && ISBLANK (e2[-1]))
4455 e2--;
4456
4457 if (e1 - s1 != e2 - s2)
4458 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4459 if (!memcmp (s1, s2, e1 - s1))
4460 return variable_buffer_output (o, "", 0); /* eq */
4461 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4462 }
4463
4464 /* ignore trailing and leading blanks */
4465 s1 = var1->value;
4466 e1 = s1 + var1->value_length;
4467 while (ISBLANK (*s1))
4468 s1++;
4469 while (e1 > s1 && ISBLANK (e1[-1]))
4470 e1--;
4471
4472 s2 = var2->value;
4473 e2 = s2 + var2->value_length;
4474 while (ISBLANK (*s2))
4475 s2++;
4476 while (e2 > s2 && ISBLANK (e2[-1]))
4477 e2--;
4478
4479 /* both empty after stripping? */
4480 if (s1 == e1 && s2 == e2)
4481 return variable_buffer_output (o, "", 0); /* eq */
4482
4483 /* optimist. */
4484 if ( e1 - s1 == e2 - s2
4485 && !memcmp(s1, s2, e1 - s1))
4486 return variable_buffer_output (o, "", 0); /* eq */
4487
4488 /* compare up to the first '$' or the end. */
4489 x1 = var1->recursive ? memchr (s1, '$', e1 - s1) : NULL;
4490 x2 = var2->recursive ? memchr (s2, '$', e2 - s2) : NULL;
4491 if (!x1 && !x2)
4492 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4493
4494 l1 = x1 ? x1 - s1 : e1 - s1;
4495 l2 = x2 ? x2 - s2 : e2 - s2;
4496 l = l1 <= l2 ? l1 : l2;
4497 if (l && memcmp (s1, s2, l))
4498 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4499
4500 /* one or both buffers now require expanding. */
4501 if (!x1)
4502 s1 += l;
4503 else
4504 {
4505 s1 = a1 = allocated_variable_expand ((char *)s1 + l);
4506 if (!l)
4507 while (ISBLANK (*s1))
4508 s1++;
4509 e1 = strchr (s1, '\0');
4510 while (e1 > s1 && ISBLANK (e1[-1]))
4511 e1--;
4512 }
4513
4514 if (!x2)
4515 s2 += l;
4516 else
4517 {
4518 s2 = a2 = allocated_variable_expand ((char *)s2 + l);
4519 if (!l)
4520 while (ISBLANK (*s2))
4521 s2++;
4522 e2 = strchr (s2, '\0');
4523 while (e2 > s2 && ISBLANK (e2[-1]))
4524 e2--;
4525 }
4526
4527 /* the final compare */
4528 if ( e1 - s1 != e2 - s2
4529 || memcmp (s1, s2, e1 - s1))
4530 o = comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4531 else
4532 o = variable_buffer_output (o, "", 1) - 1; /* eq */ /** @todo check why this was necessary back the... */
4533 if (a1)
4534 free (a1);
4535 if (a2)
4536 free (a2);
4537 return o;
4538}
4539
4540/*
4541 $(comp-cmds-ex cmds1,cmds2,not-equal-return)
4542
4543 Compares the two strings and return the string in the third argument
4544 if not equal. If equal, nothing is returned.
4545
4546 The comparision will be performed command by command, ignoring not
4547 only leading and trailing spaces on each line but also leading one
4548 leading '@', '-', '+' and '%'.
4549*/
4550static char *
4551func_comp_cmds_ex (char *o, char **argv, const char *funcname)
4552{
4553 const char *s1, *e1, *s2, *e2;
4554 size_t l1, l2;
4555
4556 /* the simple cases */
4557 s1 = argv[0];
4558 s2 = argv[1];
4559 if (s1 == s2)
4560 return variable_buffer_output (o, "", 0); /* eq */
4561 l1 = strlen (argv[0]);
4562 l2 = strlen (argv[1]);
4563
4564 if ( l1 == l2
4565 && !memcmp (s1, s2, l1))
4566 return variable_buffer_output (o, "", 0); /* eq */
4567
4568 /* ignore trailing and leading blanks */
4569 e1 = s1 + l1;
4570 s1 = comp_cmds_strip_leading (s1, e1);
4571
4572 e2 = s2 + l2;
4573 s2 = comp_cmds_strip_leading (s2, e2);
4574
4575 if (e1 - s1 != e2 - s2)
4576 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4577 if (!memcmp (s1, s2, e1 - s1))
4578 return variable_buffer_output (o, "", 0); /* eq */
4579 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4580}
4581#endif
4582
4583#ifdef CONFIG_WITH_DATE
4584# if defined (_MSC_VER) /* FIXME: !defined (HAVE_STRPTIME) */
4585char *strptime(const char *s, const char *format, struct tm *tm)
4586{
4587 return (char *)"strptime is not implemented";
4588}
4589# endif
4590/* Check if the string is all blanks or not. */
4591static int
4592all_blanks (const char *s)
4593{
4594 if (!s)
4595 return 1;
4596 while (ISSPACE (*s))
4597 s++;
4598 return *s == '\0';
4599}
4600
4601/* The first argument is the strftime format string, a iso
4602 timestamp is the default if nothing is given.
4603
4604 The second argument is a time value if given. The format
4605 is either the format from the first argument or given as
4606 an additional third argument. */
4607static char *
4608func_date (char *o, char **argv, const char *funcname)
4609{
4610 char *p;
4611 char *buf;
4612 size_t buf_size;
4613 struct tm t;
4614 const char *format;
4615
4616 /* determin the format - use a single word as the default. */
4617 format = !strcmp (funcname, "date-utc")
4618 ? "%Y-%m-%dT%H:%M:%SZ"
4619 : "%Y-%m-%dT%H:%M:%S";
4620 if (!all_blanks (argv[0]))
4621 format = argv[0];
4622
4623 /* get the time. */
4624 memset (&t, 0, sizeof(t));
4625 if (argv[0] && !all_blanks (argv[1]))
4626 {
4627 const char *input_format = !all_blanks (argv[2]) ? argv[2] : format;
4628 p = strptime (argv[1], input_format, &t);
4629 if (!p || *p != '\0')
4630 {
4631 OSSSS (error, NILF, _("$(%s): strptime(%s,%s,) -> %s\n"), funcname,
4632 argv[1], input_format, p ? p : "<null>");
4633 return variable_buffer_output (o, "", 0);
4634 }
4635 }
4636 else
4637 {
4638 time_t tval;
4639 time (&tval);
4640 if (!strcmp (funcname, "date-utc"))
4641 t = *gmtime (&tval);
4642 else
4643 t = *localtime (&tval);
4644 }
4645
4646 /* format it. note that zero isn't necessarily an error, so we'll
4647 have to keep shut about failures. */
4648 buf_size = 64;
4649 buf = xmalloc (buf_size);
4650 while (strftime (buf, buf_size, format, &t) == 0)
4651 {
4652 if (buf_size >= 4096)
4653 {
4654 *buf = '\0';
4655 break;
4656 }
4657 buf = xrealloc (buf, buf_size <<= 1);
4658 }
4659 o = variable_buffer_output (o, buf, strlen (buf));
4660 free (buf);
4661 return o;
4662}
4663#endif
4664
4665#ifdef CONFIG_WITH_FILE_SIZE
4666/* Prints the size of the specified file. Only one file is
4667 permitted, notthing is stripped. -1 is returned if stat
4668 fails. */
4669static char *
4670func_file_size (char *o, char **argv, const char *funcname UNUSED)
4671{
4672 struct stat st;
4673 if (stat (argv[0], &st))
4674 return variable_buffer_output (o, "-1", 2);
4675 return math_int_to_variable_buffer (o, st.st_size);
4676}
4677#endif
4678
4679#ifdef CONFIG_WITH_WHICH
4680/* Checks if the specified file exists an is executable.
4681 On systems employing executable extensions, the name may
4682 be modified to include the extension. */
4683static int func_which_test_x (char *file)
4684{
4685 struct stat st;
4686# if defined(WINDOWS32) || defined(__OS2__)
4687 char *ext;
4688 char *slash;
4689
4690 /* fix slashes first. */
4691 slash = file;
4692 while ((slash = strchr (slash, '\\')) != NULL)
4693 *slash++ = '/';
4694
4695 /* straight */
4696 if (stat (file, &st) == 0
4697 && S_ISREG (st.st_mode))
4698 return 1;
4699
4700 /* don't try add an extension if there already is one */
4701 ext = strchr (file, '\0');
4702 if (ext - file >= 4
4703 && ( !stricmp (ext - 4, ".exe")
4704 || !stricmp (ext - 4, ".cmd")
4705 || !stricmp (ext - 4, ".bat")
4706 || !stricmp (ext - 4, ".com")))
4707 return 0;
4708
4709 /* try the extensions. */
4710 strcpy (ext, ".exe");
4711 if (stat (file, &st) == 0
4712 && S_ISREG (st.st_mode))
4713 return 1;
4714
4715 strcpy (ext, ".cmd");
4716 if (stat (file, &st) == 0
4717 && S_ISREG (st.st_mode))
4718 return 1;
4719
4720 strcpy (ext, ".bat");
4721 if (stat (file, &st) == 0
4722 && S_ISREG (st.st_mode))
4723 return 1;
4724
4725 strcpy (ext, ".com");
4726 if (stat (file, &st) == 0
4727 && S_ISREG (st.st_mode))
4728 return 1;
4729
4730 return 0;
4731
4732# else
4733
4734 return access (file, X_OK) == 0
4735 && stat (file, &st) == 0
4736 && S_ISREG (st.st_mode);
4737# endif
4738}
4739
4740/* Searches for the specified programs in the PATH and print
4741 their full location if found. Prints nothing if not found. */
4742static char *
4743func_which (char *o, char **argv, const char *funcname UNUSED)
4744{
4745 const char *path;
4746 struct variable *path_var;
4747 unsigned i;
4748 int first = 1;
4749 PATH_VAR (buf);
4750
4751 path_var = lookup_variable ("PATH", 4);
4752 if (path_var)
4753 path = path_var->value;
4754 else
4755 path = ".";
4756
4757 /* iterate input */
4758 for (i = 0; argv[i]; i++)
4759 {
4760 unsigned int len;
4761 const char *iterator = argv[i];
4762 char *cur;
4763
4764 while ((cur = find_next_token (&iterator, &len)))
4765 {
4766 /* if there is a separator, don't walk the path. */
4767 if (memchr (cur, '/', len)
4768#ifdef HAVE_DOS_PATHS
4769 || memchr (cur, '\\', len)
4770 || memchr (cur, ':', len)
4771#endif
4772 )
4773 {
4774 if (len + 1 + 4 < GET_PATH_MAX) /* +4 for .exe */
4775 {
4776 memcpy (buf, cur, len);
4777 buf[len] = '\0';
4778 if (func_which_test_x (buf))
4779 o = variable_buffer_output (o, buf, strlen (buf));
4780 }
4781 }
4782 else
4783 {
4784 const char *comp = path;
4785 for (;;)
4786 {
4787 const char *src = comp;
4788 const char *end = strchr (comp, PATH_SEPARATOR_CHAR);
4789 size_t src_len = end ? (size_t)(end - comp) : strlen (comp);
4790 if (!src_len)
4791 {
4792 src_len = 1;
4793 src = ".";
4794 }
4795 if (len + src_len + 2 + 4 < GET_PATH_MAX) /* +4 for .exe */
4796 {
4797 memcpy (buf, src, src_len);
4798 buf [src_len] = '/';
4799 memcpy (&buf[src_len + 1], cur, len);
4800 buf[src_len + 1 + len] = '\0';
4801
4802 if (func_which_test_x (buf))
4803 {
4804 if (!first)
4805 o = variable_buffer_output (o, " ", 1);
4806 o = variable_buffer_output (o, buf, strlen (buf));
4807 first = 0;
4808 break;
4809 }
4810 }
4811
4812 /* next */
4813 if (!end)
4814 break;
4815 comp = end + 1;
4816 }
4817 }
4818 }
4819 }
4820
4821 return variable_buffer_output (o, "", 0);
4822}
4823#endif /* CONFIG_WITH_WHICH */
4824
4825#ifdef CONFIG_WITH_IF_CONDITIONALS
4826
4827/* Evaluates the expression given in the argument using the
4828 same evaluator as for the new 'if' statements, except now
4829 we don't force the result into a boolean like for 'if' and
4830 '$(if-expr ,,)'. */
4831static char *
4832func_expr (char *o, char **argv, const char *funcname UNUSED)
4833{
4834 o = expr_eval_to_string (o, argv[0]);
4835 return o;
4836}
4837
4838/* Same as '$(if ,,)' except the first argument is evaluated
4839 using the same evaluator as for the new 'if' statements. */
4840static char *
4841func_if_expr (char *o, char **argv, const char *funcname UNUSED)
4842{
4843 int rc;
4844 char *to_expand;
4845
4846 /* Evaluate the condition in argv[0] and expand the 2nd or
4847 3rd (optional) argument according to the result. */
4848 rc = expr_eval_if_conditionals (argv[0], NULL);
4849 to_expand = rc == 0 ? argv[1] : argv[2];
4850 if (to_expand && *to_expand)
4851 variable_expand_string_2 (o, to_expand, -1, &o);
4852
4853 return o;
4854}
4855
4856/*
4857 $(select when1-cond, when1-body[,whenN-cond, whenN-body]).
4858 */
4859static char *
4860func_select (char *o, char **argv, const char *funcname UNUSED)
4861{
4862 int i;
4863
4864 /* Test WHEN-CONDs until one matches. The check for 'otherwise[:]'
4865 and 'default[:]' make this a bit more fun... */
4866
4867 for (i = 0; argv[i] != NULL; i += 2)
4868 {
4869 const char *cond = argv[i];
4870 int is_otherwise = 0;
4871
4872 if (argv[i + 1] == NULL)
4873 O (fatal, NILF, _("$(select ): not an even argument count\n"));
4874
4875 while (ISSPACE (*cond))
4876 cond++;
4877 if ( (*cond == 'o' && strncmp (cond, "otherwise", 9) == 0)
4878 || (*cond == 'd' && strncmp (cond, "default", 7) == 0))
4879 {
4880 const char *end = cond + (*cond == 'o' ? 9 : 7);
4881 while (ISSPACE (*end))
4882 end++;
4883 if (*end == ':')
4884 do end++;
4885 while (ISSPACE (*end));
4886 is_otherwise = *end == '\0';
4887 }
4888
4889 if ( is_otherwise
4890 || expr_eval_if_conditionals (cond, NULL) == 0 /* true */)
4891 {
4892 variable_expand_string_2 (o, argv[i + 1], -1, &o);
4893 break;
4894 }
4895 }
4896
4897 return o;
4898}
4899
4900#endif /* CONFIG_WITH_IF_CONDITIONALS */
4901
4902#ifdef CONFIG_WITH_SET_CONDITIONALS
4903static char *
4904func_set_intersects (char *o, char **argv, const char *funcname UNUSED)
4905{
4906 const char *s1_cur;
4907 unsigned int s1_len;
4908 const char *s1_iterator = argv[0];
4909
4910 while ((s1_cur = find_next_token (&s1_iterator, &s1_len)) != 0)
4911 {
4912 const char *s2_cur;
4913 unsigned int s2_len;
4914 const char *s2_iterator = argv[1];
4915 while ((s2_cur = find_next_token (&s2_iterator, &s2_len)) != 0)
4916 if (s2_len == s1_len
4917 && strneq (s2_cur, s1_cur, s1_len) )
4918 return variable_buffer_output (o, "1", 1); /* found intersection */
4919 }
4920
4921 return o; /* no intersection */
4922}
4923#endif /* CONFIG_WITH_SET_CONDITIONALS */
4924
4925#ifdef CONFIG_WITH_STACK
4926
4927/* Push an item (string without spaces). */
4928static char *
4929func_stack_push (char *o, char **argv, const char *funcname UNUSED)
4930{
4931 do_variable_definition(NILF, argv[0], argv[1], o_file, f_append, 0 /* !target_var */);
4932 return o;
4933}
4934
4935/* Pops an item off the stack / get the top stack element.
4936 (This is what's tricky to do in pure GNU make syntax.) */
4937static char *
4938func_stack_pop_top (char *o, char **argv, const char *funcname)
4939{
4940 struct variable *stack_var;
4941 const char *stack = argv[0];
4942
4943 stack_var = lookup_variable (stack, strlen (stack) );
4944 if (stack_var)
4945 {
4946 unsigned int len;
4947 const char *iterator = stack_var->value;
4948 char *lastitem = NULL;
4949 char *cur;
4950
4951 while ((cur = find_next_token (&iterator, &len)))
4952 lastitem = cur;
4953
4954 if (lastitem != NULL)
4955 {
4956 if (strcmp (funcname, "stack-popv") != 0)
4957 o = variable_buffer_output (o, lastitem, len);
4958 if (strcmp (funcname, "stack-top") != 0)
4959 {
4960 *lastitem = '\0';
4961 while (lastitem > stack_var->value && ISSPACE (lastitem[-1]))
4962 *--lastitem = '\0';
4963#ifdef CONFIG_WITH_VALUE_LENGTH
4964 stack_var->value_length = lastitem - stack_var->value;
4965#endif
4966 VARIABLE_CHANGED (stack_var);
4967 }
4968 }
4969 }
4970 return o;
4971}
4972#endif /* CONFIG_WITH_STACK */
4973
4974#if defined (CONFIG_WITH_MATH) || defined (CONFIG_WITH_NANOTS) || defined (CONFIG_WITH_FILE_SIZE)
4975/* outputs the number (as a string) into the variable buffer. */
4976static char *
4977math_int_to_variable_buffer (char *o, math_int num)
4978{
4979 static const char xdigits[17] = "0123456789abcdef";
4980 int negative;
4981 char strbuf[24]; /* 16 hex + 2 prefix + sign + term => 20
4982 or 20 dec + sign + term => 22 */
4983 char *str = &strbuf[sizeof (strbuf) - 1];
4984
4985 negative = num < 0;
4986 if (negative)
4987 num = -num;
4988
4989 *str = '\0';
4990
4991 do
4992 {
4993#ifdef HEX_MATH_NUMBERS
4994 *--str = xdigits[num & 0xf];
4995 num >>= 4;
4996#else
4997 *--str = xdigits[num % 10];
4998 num /= 10;
4999#endif
5000 }
5001 while (num);
5002
5003#ifdef HEX_MATH_NUMBERS
5004 *--str = 'x';
5005 *--str = '0';
5006#endif
5007
5008 if (negative)
5009 *--str = '-';
5010
5011 return variable_buffer_output (o, str, &strbuf[sizeof (strbuf) - 1] - str);
5012}
5013#endif /* CONFIG_WITH_MATH || CONFIG_WITH_NANOTS */
5014
5015#ifdef CONFIG_WITH_MATH
5016
5017/* Converts a string to an integer, causes an error if the format is invalid. */
5018static math_int
5019math_int_from_string (const char *str)
5020{
5021 const char *start;
5022 unsigned base = 0;
5023 int negative = 0;
5024 math_int num = 0;
5025
5026 /* strip spaces */
5027 while (ISSPACE (*str))
5028 str++;
5029 if (!*str)
5030 {
5031 O (error, NILF, _("bad number: empty\n"));
5032 return 0;
5033 }
5034 start = str;
5035
5036 /* check for +/- */
5037 while (*str == '+' || *str == '-' || ISSPACE (*str))
5038 if (*str++ == '-')
5039 negative = !negative;
5040
5041 /* check for prefix - we do not accept octal numbers, sorry. */
5042 if (*str == '0' && (str[1] == 'x' || str[1] == 'X'))
5043 {
5044 base = 16;
5045 str += 2;
5046 }
5047 else
5048 {
5049 /* look for a hex digit, if not found treat it as decimal */
5050 const char *p2 = str;
5051 for ( ; *p2; p2++)
5052 if (isxdigit (*p2) && !isdigit (*p2) && isascii (*p2) )
5053 {
5054 base = 16;
5055 break;
5056 }
5057 if (base == 0)
5058 base = 10;
5059 }
5060
5061 /* must have at least one digit! */
5062 if ( !isascii (*str)
5063 || !(base == 16 ? isxdigit (*str) : isdigit (*str)) )
5064 {
5065 OS (error, NILF, _("bad number: '%s'\n"), start);
5066 return 0;
5067 }
5068
5069 /* convert it! */
5070 while (*str && !ISSPACE (*str))
5071 {
5072 int ch = *str++;
5073 if (ch >= '0' && ch <= '9')
5074 ch -= '0';
5075 else if (base == 16 && ch >= 'a' && ch <= 'f')
5076 ch -= 'a' - 10;
5077 else if (base == 16 && ch >= 'A' && ch <= 'F')
5078 ch -= 'A' - 10;
5079 else
5080 {
5081 OSNN (error, NILF, _("bad number: '%s' (base=%u, pos=%lu)\n"), start, base, (unsigned long)(str - start));
5082 return 0;
5083 }
5084 num *= base;
5085 num += ch;
5086 }
5087
5088 /* check trailing spaces. */
5089 while (ISSPACE (*str))
5090 str++;
5091 if (*str)
5092 {
5093 OS (error, NILF, _("bad number: '%s'\n"), start);
5094 return 0;
5095 }
5096
5097 return negative ? -num : num;
5098}
5099
5100/* Add two or more integer numbers. */
5101static char *
5102func_int_add (char *o, char **argv, const char *funcname UNUSED)
5103{
5104 math_int num;
5105 int i;
5106
5107 num = math_int_from_string (argv[0]);
5108 for (i = 1; argv[i]; i++)
5109 num += math_int_from_string (argv[i]);
5110
5111 return math_int_to_variable_buffer (o, num);
5112}
5113
5114/* Subtract two or more integer numbers. */
5115static char *
5116func_int_sub (char *o, char **argv, const char *funcname UNUSED)
5117{
5118 math_int num;
5119 int i;
5120
5121 num = math_int_from_string (argv[0]);
5122 for (i = 1; argv[i]; i++)
5123 num -= math_int_from_string (argv[i]);
5124
5125 return math_int_to_variable_buffer (o, num);
5126}
5127
5128/* Multiply two or more integer numbers. */
5129static char *
5130func_int_mul (char *o, char **argv, const char *funcname UNUSED)
5131{
5132 math_int num;
5133 int i;
5134
5135 num = math_int_from_string (argv[0]);
5136 for (i = 1; argv[i]; i++)
5137 num *= math_int_from_string (argv[i]);
5138
5139 return math_int_to_variable_buffer (o, num);
5140}
5141
5142/* Divide an integer number by one or more divisors. */
5143static char *
5144func_int_div (char *o, char **argv, const char *funcname UNUSED)
5145{
5146 math_int num;
5147 math_int divisor;
5148 int i;
5149
5150 num = math_int_from_string (argv[0]);
5151 for (i = 1; argv[i]; i++)
5152 {
5153 divisor = math_int_from_string (argv[i]);
5154 if (!divisor)
5155 {
5156 OS (error, NILF, _("divide by zero ('%s')\n"), argv[i]);
5157 return math_int_to_variable_buffer (o, 0);
5158 }
5159 num /= divisor;
5160 }
5161
5162 return math_int_to_variable_buffer (o, num);
5163}
5164
5165
5166/* Divide and return the remainder. */
5167static char *
5168func_int_mod (char *o, char **argv, const char *funcname UNUSED)
5169{
5170 math_int num;
5171 math_int divisor;
5172
5173 num = math_int_from_string (argv[0]);
5174 divisor = math_int_from_string (argv[1]);
5175 if (!divisor)
5176 {
5177 OS (error, NILF, _("divide by zero ('%s')\n"), argv[1]);
5178 return math_int_to_variable_buffer (o, 0);
5179 }
5180 num %= divisor;
5181
5182 return math_int_to_variable_buffer (o, num);
5183}
5184
5185/* 2-complement. */
5186static char *
5187func_int_not (char *o, char **argv, const char *funcname UNUSED)
5188{
5189 math_int num;
5190
5191 num = math_int_from_string (argv[0]);
5192 num = ~num;
5193
5194 return math_int_to_variable_buffer (o, num);
5195}
5196
5197/* Bitwise AND (two or more numbers). */
5198static char *
5199func_int_and (char *o, char **argv, const char *funcname UNUSED)
5200{
5201 math_int num;
5202 int i;
5203
5204 num = math_int_from_string (argv[0]);
5205 for (i = 1; argv[i]; i++)
5206 num &= math_int_from_string (argv[i]);
5207
5208 return math_int_to_variable_buffer (o, num);
5209}
5210
5211/* Bitwise OR (two or more numbers). */
5212static char *
5213func_int_or (char *o, char **argv, const char *funcname UNUSED)
5214{
5215 math_int num;
5216 int i;
5217
5218 num = math_int_from_string (argv[0]);
5219 for (i = 1; argv[i]; i++)
5220 num |= math_int_from_string (argv[i]);
5221
5222 return math_int_to_variable_buffer (o, num);
5223}
5224
5225/* Bitwise XOR (two or more numbers). */
5226static char *
5227func_int_xor (char *o, char **argv, const char *funcname UNUSED)
5228{
5229 math_int num;
5230 int i;
5231
5232 num = math_int_from_string (argv[0]);
5233 for (i = 1; argv[i]; i++)
5234 num ^= math_int_from_string (argv[i]);
5235
5236 return math_int_to_variable_buffer (o, num);
5237}
5238
5239/* Compare two integer numbers. Returns make boolean (true="1"; false=""). */
5240static char *
5241func_int_cmp (char *o, char **argv, const char *funcname)
5242{
5243 math_int num1;
5244 math_int num2;
5245 int rc;
5246
5247 num1 = math_int_from_string (argv[0]);
5248 num2 = math_int_from_string (argv[1]);
5249
5250 funcname += sizeof ("int-") - 1;
5251 if (!strcmp (funcname, "eq"))
5252 rc = num1 == num2;
5253 else if (!strcmp (funcname, "ne"))
5254 rc = num1 != num2;
5255 else if (!strcmp (funcname, "gt"))
5256 rc = num1 > num2;
5257 else if (!strcmp (funcname, "ge"))
5258 rc = num1 >= num2;
5259 else if (!strcmp (funcname, "lt"))
5260 rc = num1 < num2;
5261 else /*if (!strcmp (funcname, "le"))*/
5262 rc = num1 <= num2;
5263
5264 return variable_buffer_output (o, rc ? "1" : "", rc);
5265}
5266
5267#endif /* CONFIG_WITH_MATH */
5268
5269#ifdef CONFIG_WITH_NANOTS
5270/* Returns the current timestamp as nano seconds. The time
5271 source is a high res monotone one if the platform provides
5272 this (and we know about it).
5273
5274 Tip. Use this with int-sub to profile makefile reading
5275 and similar. */
5276static char *
5277func_nanots (char *o, char **argv UNUSED, const char *funcname UNUSED)
5278{
5279 return math_int_to_variable_buffer (o, nano_timestamp ());
5280}
5281#endif
5282
5283#ifdef CONFIG_WITH_OS2_LIBPATH
5284/* Sets or gets the OS/2 libpath variables.
5285
5286 The first argument indicates which variable - BEGINLIBPATH,
5287 ENDLIBPATH, LIBPATHSTRICT or LIBPATH.
5288
5289 The second indicates whether this is a get (not present) or
5290 set (present) operation. When present it is the new value for
5291 the variable. */
5292static char *
5293func_os2_libpath (char *o, char **argv, const char *funcname UNUSED)
5294{
5295 char buf[4096];
5296 ULONG fVar;
5297 APIRET rc;
5298
5299 /* translate variable name (first arg) */
5300 if (!strcmp (argv[0], "BEGINLIBPATH"))
5301 fVar = BEGIN_LIBPATH;
5302 else if (!strcmp (argv[0], "ENDLIBPATH"))
5303 fVar = END_LIBPATH;
5304 else if (!strcmp (argv[0], "LIBPATHSTRICT"))
5305 fVar = LIBPATHSTRICT;
5306 else if (!strcmp (argv[0], "LIBPATH"))
5307 fVar = 0;
5308 else
5309 {
5310 OS (error, NILF, _("$(libpath): unknown variable `%s'"), argv[0]);
5311 return variable_buffer_output (o, "", 0);
5312 }
5313
5314 if (!argv[1])
5315 {
5316 /* get the variable value. */
5317 if (fVar != 0)
5318 {
5319 buf[0] = buf[1] = buf[2] = buf[3] = '\0';
5320 rc = DosQueryExtLIBPATH (buf, fVar);
5321 }
5322 else
5323 rc = DosQueryHeaderInfo (NULLHANDLE, 0, buf, sizeof(buf), QHINF_LIBPATH);
5324 if (rc != NO_ERROR)
5325 {
5326 OSN (error, NILF, _("$(libpath): failed to query `%s', rc=%d"), argv[0], rc);
5327 return variable_buffer_output (o, "", 0);
5328 }
5329 o = variable_buffer_output (o, buf, strlen (buf));
5330 }
5331 else
5332 {
5333 /* set the variable value. */
5334 size_t len;
5335 size_t len_max = sizeof (buf) < 2048 ? sizeof (buf) : 2048;
5336 const char *val;
5337 const char *end;
5338
5339 if (fVar == 0)
5340 {
5341 O (error, NILF, _("$(libpath): LIBPATH is read-only"));
5342 return variable_buffer_output (o, "", 0);
5343 }
5344
5345 /* strip leading and trailing spaces and check for max length. */
5346 val = argv[1];
5347 while (ISSPACE (*val))
5348 val++;
5349 end = strchr (val, '\0');
5350 while (end > val && ISSPACE (end[-1]))
5351 end--;
5352
5353 len = end - val;
5354 if (len >= len_max)
5355 {
5356 OSNN (error, NILF, _("$(libpath): The new `%s' value is too long (%d bytes, max %d)"),
5357 argv[0], len, len_max);
5358 return variable_buffer_output (o, "", 0);
5359 }
5360
5361 /* make a stripped copy in low memory and try set it. */
5362 memcpy (buf, val, len);
5363 buf[len] = '\0';
5364 rc = DosSetExtLIBPATH (buf, fVar);
5365 if (rc != NO_ERROR)
5366 {
5367 OSSN (error, NILF, _("$(libpath): failed to set `%s' to `%s', rc=%d"), argv[0], buf, rc);
5368 return variable_buffer_output (o, "", 0);
5369 }
5370
5371 o = variable_buffer_output (o, "", 0);
5372 }
5373 return o;
5374}
5375#endif /* CONFIG_WITH_OS2_LIBPATH */
5376
5377#if defined (CONFIG_WITH_MAKE_STATS) || defined (CONFIG_WITH_MINIMAL_STATS)
5378/* Retrieve make statistics. */
5379static char *
5380func_make_stats (char *o, char **argv, const char *funcname UNUSED)
5381{
5382 char buf[512];
5383 int len;
5384
5385 if (!argv[0] || (!argv[0][0] && !argv[1]))
5386 {
5387# ifdef CONFIG_WITH_MAKE_STATS
5388 len = sprintf (buf, "alloc-cur: %5ld/%3ld %3luMB hash: %5lu %2lu%%",
5389 make_stats_allocations,
5390 make_stats_reallocations,
5391 make_stats_allocated / (1024*1024),
5392 make_stats_ht_lookups,
5393 (make_stats_ht_collisions * 100) / make_stats_ht_lookups);
5394 o = variable_buffer_output (o, buf, len);
5395#endif
5396 }
5397 else
5398 {
5399 /* selective */
5400 int i;
5401 for (i = 0; argv[i]; i++)
5402 {
5403 unsigned long val;
5404 if (i != 0)
5405 o = variable_buffer_output (o, " ", 1);
5406 if (0)
5407 continue;
5408# ifdef CONFIG_WITH_MAKE_STATS
5409 else if (!strcmp(argv[i], "allocations"))
5410 val = make_stats_allocations;
5411 else if (!strcmp(argv[i], "reallocations"))
5412 val = make_stats_reallocations;
5413 else if (!strcmp(argv[i], "allocated"))
5414 val = make_stats_allocated;
5415 else if (!strcmp(argv[i], "ht_lookups"))
5416 val = make_stats_ht_lookups;
5417 else if (!strcmp(argv[i], "ht_collisions"))
5418 val = make_stats_ht_collisions;
5419 else if (!strcmp(argv[i], "ht_collisions_pct"))
5420 val = (make_stats_ht_collisions * 100) / make_stats_ht_lookups;
5421#endif
5422 else
5423 {
5424 o = variable_buffer_output (o, argv[i], strlen (argv[i]));
5425 continue;
5426 }
5427
5428 len = sprintf (buf, "%ld", val);
5429 o = variable_buffer_output (o, buf, len);
5430 }
5431 }
5432
5433 return o;
5434}
5435#endif /* CONFIG_WITH_MAKE_STATS */
5436
5437#ifdef CONFIG_WITH_COMMANDS_FUNC
5438/* Gets all the commands for a target, separated by newlines.
5439
5440 This is useful when creating and checking target dependencies since
5441 it reduces the amount of work and the memory consuption. A new prefix
5442 character '%' has been introduced for skipping certain lines, like
5443 for instance the one calling this function and pushing to a dep file.
5444 Blank lines are also skipped.
5445
5446 The commands function takes exactly one argument, which is the name of
5447 the target which commands should be returned.
5448
5449 The commands-sc is identical to commands except that it uses a ';' to
5450 separate the commands.
5451
5452 The commands-usr is similar to commands except that it takes a 2nd
5453 argument that is used to separate the commands. */
5454char *
5455func_commands (char *o, char **argv, const char *funcname)
5456{
5457 struct file *file;
5458 static int recursive = 0;
5459
5460 if (recursive)
5461 {
5462 OS (error, reading_file, _("$(%s ) was invoked recursivly"), funcname);
5463 return variable_buffer_output (o, "recursive", sizeof ("recursive") - 1);
5464 }
5465 if (*argv[0] == '\0')
5466 {
5467 OS (error, reading_file, _("$(%s ) was invoked with an empty target name"), funcname);
5468 return o;
5469 }
5470 recursive = 1;
5471
5472 file = lookup_file (argv[0]);
5473 if (file && file->cmds)
5474 {
5475 unsigned int i;
5476 int cmd_sep_len;
5477 struct commands *cmds = file->cmds;
5478 const char *cmd_sep;
5479
5480 if (!strcmp (funcname, "commands"))
5481 {
5482 cmd_sep = "\n";
5483 cmd_sep_len = 1;
5484 }
5485 else if (!strcmp (funcname, "commands-sc"))
5486 {
5487 cmd_sep = ";";
5488 cmd_sep_len = 1;
5489 }
5490 else /*if (!strcmp (funcname, "commands-usr"))*/
5491 {
5492 cmd_sep = argv[1];
5493 cmd_sep_len = strlen (cmd_sep);
5494 }
5495
5496 initialize_file_variables (file, 1 /* don't search for pattern vars */);
5497 set_file_variables (file, 1 /* early call */);
5498 chop_commands (cmds);
5499
5500 for (i = 0; i < cmds->ncommand_lines; i++)
5501 {
5502 char *p;
5503 char *in, *out, *ref;
5504
5505 /* Skip it if it has a '%' prefix or is blank. */
5506 if (cmds->lines_flags[i] & COMMAND_GETTER_SKIP_IT)
5507 continue;
5508 p = cmds->command_lines[i];
5509 while (ISBLANK (*p))
5510 p++;
5511 if (*p == '\0')
5512 continue;
5513
5514 /* --- copied from new_job() in job.c --- */
5515
5516 /* Collapse backslash-newline combinations that are inside variable
5517 or function references. These are left alone by the parser so
5518 that they will appear in the echoing of commands (where they look
5519 nice); and collapsed by construct_command_argv when it tokenizes.
5520 But letting them survive inside function invocations loses because
5521 we don't want the functions to see them as part of the text. */
5522
5523 /* IN points to where in the line we are scanning.
5524 OUT points to where in the line we are writing.
5525 When we collapse a backslash-newline combination,
5526 IN gets ahead of OUT. */
5527
5528 in = out = p;
5529 while ((ref = strchr (in, '$')) != 0)
5530 {
5531 ++ref; /* Move past the $. */
5532
5533 if (out != in)
5534 /* Copy the text between the end of the last chunk
5535 we processed (where IN points) and the new chunk
5536 we are about to process (where REF points). */
5537 memmove (out, in, ref - in);
5538
5539 /* Move both pointers past the boring stuff. */
5540 out += ref - in;
5541 in = ref;
5542
5543 if (*ref == '(' || *ref == '{')
5544 {
5545 char openparen = *ref;
5546 char closeparen = openparen == '(' ? ')' : '}';
5547 int count;
5548 char *p2;
5549
5550 *out++ = *in++; /* Copy OPENPAREN. */
5551 /* IN now points past the opening paren or brace.
5552 Count parens or braces until it is matched. */
5553 count = 0;
5554 while (*in != '\0')
5555 {
5556 if (*in == closeparen && --count < 0)
5557 break;
5558 else if (*in == '\\' && in[1] == '\n')
5559 {
5560 /* We have found a backslash-newline inside a
5561 variable or function reference. Eat it and
5562 any following whitespace. */
5563
5564 int quoted = 0;
5565 for (p2 = in - 1; p2 > ref && *p2 == '\\'; --p2)
5566 quoted = !quoted;
5567
5568 if (quoted)
5569 /* There were two or more backslashes, so this is
5570 not really a continuation line. We don't collapse
5571 the quoting backslashes here as is done in
5572 collapse_continuations, because the line will
5573 be collapsed again after expansion. */
5574 *out++ = *in++;
5575 else
5576 {
5577 /* Skip the backslash, newline and
5578 any following whitespace. */
5579 in = next_token (in + 2);
5580
5581 /* Discard any preceding whitespace that has
5582 already been written to the output. */
5583 while (out > ref
5584 && ISBLANK (out[-1]))
5585 --out;
5586
5587 /* Replace it all with a single space. */
5588 *out++ = ' ';
5589 }
5590 }
5591 else
5592 {
5593 if (*in == openparen)
5594 ++count;
5595
5596 *out++ = *in++;
5597 }
5598 }
5599 }
5600 /* Some of these can be amended ($< perhaps), but we're likely to be called while the
5601 dep expansion happens, so it would have to be on a hackish basis. sad... */
5602 else if (*ref == '<' || *ref == '*' || *ref == '%' || *ref == '^' || *ref == '+')
5603 OSN (error, reading_file, _("$(%s ) does not work reliably with $%c in all cases"), funcname, *ref);
5604 }
5605
5606 /* There are no more references in this line to worry about.
5607 Copy the remaining uninteresting text to the output. */
5608 if (out != in)
5609 strcpy (out, in);
5610
5611 /* --- copied from new_job() in job.c --- */
5612
5613 /* Finally, expand the line. */
5614 if (i)
5615 o = variable_buffer_output (o, cmd_sep, cmd_sep_len);
5616 o = variable_expand_for_file_2 (o, cmds->command_lines[i], ~0U, file, NULL);
5617
5618 /* Skip it if it has a '%' prefix or is blank. */
5619 p = o;
5620 while (ISBLANK (*o)
5621 || *o == '@'
5622 || *o == '-'
5623 || *o == '+')
5624 o++;
5625 if (*o != '\0' && *o != '%')
5626 o = strchr (o, '\0');
5627 else if (i)
5628 o = p - cmd_sep_len;
5629 else
5630 o = p;
5631 } /* for each command line */
5632 }
5633 /* else FIXME: bitch about it? */
5634
5635 recursive = 0;
5636 return o;
5637}
5638#endif /* CONFIG_WITH_COMMANDS_FUNC */
5639#ifdef KMK
5640
5641/* Useful when debugging kmk and/or makefiles. */
5642char *
5643func_breakpoint (char *o, char **argv UNUSED, const char *funcname UNUSED)
5644{
5645#ifdef _MSC_VER
5646 __debugbreak();
5647#elif defined(__i386__) || defined(__x86__) || defined(__X86__) || defined(_M_IX86) || defined(__i386) \
5648 || defined(__amd64__) || defined(__x86_64__) || defined(__AMD64__) || defined(_M_X64) || defined(__amd64)
5649# ifdef __sun__
5650 __asm__ __volatile__ ("int $3\n\t");
5651# else
5652 __asm__ __volatile__ ("int3\n\t");
5653# endif
5654#else
5655 char *p = (char *)0;
5656 *p = '\0';
5657#endif
5658 return o;
5659}
5660
5661/* umask | umask -S. */
5662char *
5663func_get_umask (char *o, char **argv UNUSED, const char *funcname UNUSED)
5664{
5665 char sz[80];
5666 int off;
5667 mode_t u;
5668 int symbolic = 0;
5669 const char *psz = argv[0];
5670
5671 if (psz)
5672 {
5673 const char *pszEnd = strchr (psz, '\0');
5674 strip_whitespace (&psz, &pszEnd);
5675
5676 if (pszEnd != psz)
5677 {
5678 if ( STR_N_EQUALS (psz, pszEnd - pszEnd, "S")
5679 || STR_N_EQUALS (psz, pszEnd - pszEnd, "-S")
5680 || STR_N_EQUALS (psz, pszEnd - pszEnd, "symbolic") )
5681 symbolic = 1;
5682 else
5683 OSS (error, reading_file, _("$(%s ) invalid argument `%s'"),
5684 funcname, argv[0]);
5685 }
5686 }
5687
5688 u = g_fUMask;
5689 assert (u == umask (g_fUMask));
5690
5691 if (symbolic)
5692 {
5693 off = 0;
5694 sz[off++] = 'u';
5695 sz[off++] = '=';
5696 if ((u & S_IRUSR) == 0)
5697 sz[off++] = 'r';
5698 if ((u & S_IWUSR) == 0)
5699 sz[off++] = 'w';
5700 if ((u & S_IXUSR) == 0)
5701 sz[off++] = 'x';
5702 sz[off++] = ',';
5703 sz[off++] = 'g';
5704 sz[off++] = '=';
5705 if ((u & S_IRGRP) == 0)
5706 sz[off++] = 'r';
5707 if ((u & S_IWGRP) == 0)
5708 sz[off++] = 'w';
5709 if ((u & S_IXGRP) == 0)
5710 sz[off++] = 'x';
5711 sz[off++] = ',';
5712 sz[off++] = 'o';
5713 sz[off++] = '=';
5714 if ((u & S_IROTH) == 0)
5715 sz[off++] = 'r';
5716 if ((u & S_IWOTH) == 0)
5717 sz[off++] = 'w';
5718 if ((u & S_IXOTH) == 0)
5719 sz[off++] = 'x';
5720 }
5721 else
5722 off = sprintf (sz, "%.4o", u);
5723
5724 return variable_buffer_output (o, sz, off);
5725}
5726
5727
5728/* umask 0002 | umask u=rwx,g=rwx,o=rx. */
5729char *
5730func_set_umask (char *o, char **argv UNUSED, const char *funcname UNUSED)
5731{
5732 mode_t u;
5733 const char *psz;
5734
5735 /* Figure what kind of input this is. */
5736 psz = argv[0];
5737 while (ISBLANK (*psz))
5738 psz++;
5739
5740 if (isdigit ((unsigned char)*psz))
5741 {
5742 u = 0;
5743 while (*psz)
5744 {
5745 u <<= 3;
5746 if (*psz < '0' || *psz >= '8')
5747 {
5748 OSS (error, reading_file, _("$(%s ) illegal number `%s'"), funcname, argv[0]);
5749 break;
5750 }
5751 u += *psz - '0';
5752 psz++;
5753 }
5754
5755 if (argv[1] != NULL)
5756 OS (error, reading_file, _("$(%s ) too many arguments for octal mode"), funcname);
5757
5758 umask (u);
5759 g_fUMask = u;
5760 }
5761 else
5762 {
5763 OS (error, reading_file, _("$(%s ) symbol mode is not implemented"), funcname);
5764 }
5765
5766 return o;
5767}
5768
5769
5770/* Controls the cache in dir-bird-nt.c. */
5771
5772char *
5773func_dircache_ctl (char *o, char **argv UNUSED, const char *funcname UNUSED)
5774{
5775# ifdef KBUILD_OS_WINDOWS
5776 const char *cmd = argv[0];
5777 while (ISBLANK (*cmd))
5778 cmd++;
5779 if (strcmp (cmd, "invalidate") == 0)
5780 {
5781 if (argv[1] != NULL)
5782 O (error, reading_file, "$(dircache-ctl invalidate) takes no parameters");
5783 dir_cache_invalid_all ();
5784 }
5785 else if (strcmp (cmd, "invalidate-and-close-dirs") == 0)
5786 {
5787 if (argv[1] != NULL)
5788 O (error, reading_file, "$(dircache-ctl invalidate) takes no parameters");
5789 dir_cache_invalid_all_and_close_dirs (0 /*including_root*/);
5790 }
5791 else if (strcmp (cmd, "invalidate-missing") == 0)
5792 {
5793 if (argv[1] != NULL)
5794 O (error, reading_file, "$(dircache-ctl invalidate-missing) takes no parameters");
5795 dir_cache_invalid_missing ();
5796 }
5797 else if (strcmp (cmd, "volatile") == 0)
5798 {
5799 size_t i;
5800 for (i = 1; argv[i] != NULL; i++)
5801 {
5802 const char *dir = argv[i];
5803 while (ISBLANK (*dir))
5804 dir++;
5805 if (*dir)
5806 dir_cache_volatile_dir (dir);
5807 }
5808 }
5809 else if (strcmp (cmd, "deleted") == 0)
5810 {
5811 size_t i;
5812 for (i = 1; argv[i] != NULL; i++)
5813 {
5814 const char *dir = argv[i];
5815 while (ISBLANK (*dir))
5816 dir++;
5817 if (*dir)
5818 dir_cache_deleted_directory (dir);
5819 }
5820 }
5821 else
5822 OS (error, reading_file, "Unknown $(dircache-ctl ) command: '%s'", cmd);
5823# endif
5824 return o;
5825}
5826
5827/* Helper for performer GNU make style quoting of one filename. */
5828
5829static char *
5830helper_quote_make (char *o, const char *name, size_t len, int is_dep,
5831 int is_tgt, int quote_trailing_slashes,
5832 const char *funcname)
5833{
5834 unsigned const map_flags = MAP_BLANK
5835 | MAP_NEWLINE
5836 | MAP_COMMENT
5837 | MAP_VARIABLE
5838 | MAP_SEMI
5839 | MAP_EQUALS
5840 | (is_dep ? MAP_PIPE :
5841 is_tgt ? MAP_COLON : 0);
5842 const char *cur = name;
5843 assert (memchr (name, '\0', len) == NULL);
5844 if (len > 0)
5845 {
5846 const char * const end = &name[len];
5847 unsigned long len_out = 0;
5848 const char *prev = cur;
5849 do
5850 {
5851 char ch = *cur;
5852 unsigned int flags = stopchar_map[(unsigned int)ch] & map_flags;
5853 if (!flags)
5854 cur++; /* likely */
5855 else
5856 {
5857 /* Flush pending output. */
5858 if (prev != cur)
5859 {
5860 o = variable_buffer_output (o, prev, cur - prev);
5861 len_out += cur - prev;
5862 }
5863
5864 /* Dollar is quoted by duplicating the dollar: */
5865 if (flags & MAP_VARIABLE)
5866 {
5867 o = variable_buffer_output (o, "$", 1);
5868 prev = cur++;
5869 }
5870 /* The rest is quoted by '\': */
5871 else
5872 {
5873 size_t const max_slashes = cur - prev;
5874 size_t slashes = 0;
5875 while (slashes < max_slashes && cur[1 - slashes] == '\\')
5876 slashes++;
5877 if (slashes)
5878 {
5879 o = variable_buffer_output (o, &cur[0 - slashes], slashes);
5880 len_out += slashes;
5881 }
5882 o = variable_buffer_output (o, "\\", 1);
5883 prev = cur++;
5884 }
5885 }
5886 }
5887 while ((uintptr_t)cur < (uintptr_t)end);
5888
5889 /* Flush pending output. */
5890 if (prev != cur)
5891 {
5892 o = variable_buffer_output (o, prev, cur - prev);
5893 len_out += cur - prev;
5894 }
5895
5896 /* Escape trailing slashes when needed. */
5897 if ( o[-1] == '\\'
5898 && quote_trailing_slashes)
5899 {
5900 size_t slashes = 1;
5901 while (slashes < len_out && o[-1 - slashes] == '\\')
5902 slashes++;
5903 while (slashes-- > 0)
5904 o = variable_buffer_output (o, "\\", 1);
5905 }
5906 }
5907 else
5908 OS (message, 0, "%s: cannot quote empty string", funcname);
5909 return o;
5910}
5911
5912/* Helper for func_quote_make that checks if there are more arguments
5913 that produces output or not. */
5914
5915static int func_quote_make_has_more_non_empty_args (char **argv)
5916{
5917 for (;;)
5918 {
5919 char *arg = *argv;
5920 if (!arg)
5921 return 0;
5922 if (*arg)
5923 return 1;
5924 argv++;
5925 }
5926}
5927
5928/* Takes zero or more plain strings and escapes (quotes) spaces and other
5929 problematic characters, GNU make style.
5930
5931 There is one slightly problematic aspect of using this, if the input ends
5932 with backslashes whether or not they will be reduced or taken as-is depends
5933 on whether they appear at the end of a line or not. They are taken as-is
5934 when at the end of a line, otherwise they'll be subject to unescaping
5935 (unquoting) and reduced by half.
5936
5937 In addition, the quoting style differs for files on the left side and
5938 right side of the recipe colon. Colons aren't escaped are only escaped
5939 on the left side (target), and the pipe character is only escaped on the
5940 right side (deps).
5941
5942 For this reason there are four variants of this function. */
5943
5944static char *func_quote_make (char *o, char **argv, const char *funcname)
5945{
5946 int const is_dep = funcname[5] == '-' && funcname[6] == 'd';
5947 int const is_tgt = funcname[5] == '-' && funcname[6] == 't';
5948 int const quote_trailing_slashes = funcname[5] == '\0' || funcname[9] == '\0';
5949 char * const o_initial = o;
5950 int i;
5951
5952 assert ( quote_trailing_slashes
5953 == (!strcmp (funcname, "quote") || !strcmp (funcname, "quote-dep") || !strcmp (funcname, "quote-tgt")));
5954 assert (is_dep == !strncmp (funcname, "quote-dep", sizeof ("quote-dep") - 1));
5955 assert (is_tgt == !strncmp (funcname, "quote-tgt", sizeof ("quote-tgt") - 1));
5956
5957 for (i = 0; argv[i]; i++)
5958 {
5959 char *arg = argv[i];
5960 if (*arg)
5961 {
5962 /* Add space separator. */
5963 if (o != o_initial)
5964 o = variable_buffer_output (o, " ", 1);
5965
5966 /* Output the quoted argument: */
5967 if (quote_trailing_slashes)
5968 o = helper_quote_make (o, arg, strlen (arg), is_dep, is_tgt,
5969 quote_trailing_slashes, funcname);
5970 else
5971 {
5972 char *end = strchr (arg, '\0');
5973 int qts = end != arg && end[-1] == '\\'
5974 && func_quote_make_has_more_non_empty_args (&argv[i + 1]);
5975 o = helper_quote_make (o, arg, strlen (arg), is_dep, is_tgt,
5976 qts, funcname);
5977 }
5978 }
5979 else
5980 OS (message, 0, "%s: cannot munge empty string", funcname);
5981 }
5982
5983 return o;
5984}
5985
5986/* Worker for func_quote_shell() for escaping a string that's inside
5987 double quotes. */
5988
5989static char *func_escape_shell_in_dq (char *o, const char *arg, size_t len)
5990{
5991 const char *prev = arg;
5992 while (len-- > 0)
5993 {
5994 char const ch = *arg;
5995 switch (ch)
5996 {
5997 default:
5998 arg++;
5999 break;
6000 case '!':
6001 case '$':
6002 case '`':
6003 case '"':
6004 case '\\':
6005 case '\n':
6006 if (prev != arg)
6007 o = variable_buffer_output (o, prev, arg - prev);
6008 o = variable_buffer_output (o, "\\", 1);
6009 prev = arg;
6010 arg++;
6011 break;
6012 }
6013 }
6014 if (prev != arg)
6015 o = variable_buffer_output (o, prev, arg - prev);
6016 return o;
6017}
6018
6019/* quote-sh-dq */
6020
6021static char *func_quote_shell_dq (char *o, char **argv, const char *funcname UNUSED)
6022{
6023 return func_escape_shell_in_dq (o, argv[0], strlen (argv[0]));
6024}
6025
6026
6027/* Worker for func_quote_shell() for escaping a string that's inside
6028 single quotes. */
6029
6030static char *func_escape_shell_in_sq (char *o, const char *arg, size_t len)
6031{
6032 while (len > 0)
6033 {
6034 char *sq = memchr (arg, '\'', len);
6035 if (!sq)
6036 return variable_buffer_output (o, arg, len);
6037 if (sq != arg)
6038 o = variable_buffer_output (o, arg, sq - arg);
6039 o = variable_buffer_output (o, "'\\''", 4);
6040
6041 /* advance */
6042 sq++;
6043 len -= sq - arg;
6044 arg = sq;
6045 }
6046 return o;
6047}
6048
6049/* quote-sh-dq */
6050
6051static char *func_quote_shell_sq (char *o, char **argv, const char *funcname UNUSED)
6052{
6053 return func_escape_shell_in_sq (o, argv[0], strlen (argv[0]));
6054}
6055
6056/* Output a shell argument with quoting as needed. */
6057static char *helper_quote_shell (char *o, const char *arg, size_t len,
6058 int leading_space)
6059{
6060 if ( memchr (arg, '$', len) != NULL
6061 || memchr (arg, '*', len) != NULL
6062 || memchr (arg, '?', len) != NULL
6063 || memchr (arg, '[', len) != NULL)
6064 {
6065 if (leading_space)
6066 o = variable_buffer_output (o, " '", 2);
6067 else
6068 o = variable_buffer_output (o, "'", 1);
6069 o = func_escape_shell_in_sq (o, arg, len);
6070 o = variable_buffer_output (o, "'", 1);
6071 }
6072 else if ( memchr (arg, ' ', len) != NULL
6073 || memchr (arg, '\t', len) != NULL
6074 || memchr (arg, '\\', len) != NULL
6075 || memchr (arg, '"', len) != NULL
6076 || memchr (arg, '`', len) != NULL
6077 || memchr (arg, '!', len) != NULL
6078 || memchr (arg, '|', len) != NULL
6079 || memchr (arg, '<', len) != NULL
6080 || memchr (arg, '>', len) != NULL
6081 || memchr (arg, '&', len) != NULL
6082 || memchr (arg, ';', len) != NULL
6083 || memchr (arg, '(', len) != NULL
6084 || memchr (arg, ')', len) != NULL
6085 || memchr (arg, '\n', len) != NULL)
6086 {
6087 if (leading_space)
6088 o = variable_buffer_output (o, " \"", 2);
6089 else
6090 o = variable_buffer_output (o, "\"", 1);
6091 o = func_escape_shell_in_dq (o, arg, len);
6092 o = variable_buffer_output (o, "\"", 1);
6093 }
6094 else
6095 {
6096 if (leading_space)
6097 o = variable_buffer_output (o, " ", 1);
6098 o = variable_buffer_output (o, arg, len);
6099 }
6100 return o;
6101}
6102
6103/* Takes zero or more plain strings and escapes/quotes spaces and other
6104 problematic characters, bourne make style.
6105
6106 The quote-sh-dq and quote-sh-sq variants is for escaping strings that
6107 going to be put into double quotes and single quotes respectively.
6108
6109 The normal quote-sh variant assumes it's free to do open and close
6110 quotes as it pleases. */
6111
6112static char *func_quote_shell (char *o, char **argv, const char *funcname UNUSED)
6113{
6114 int i;
6115 for (i = 0; argv[i]; i++)
6116 o = helper_quote_shell (o, argv[i], strlen (argv[i]),
6117 i > 0 /*need_leading_space*/);
6118 return o;
6119}
6120
6121/* Unlinks CUR from *CHAINP and frees it, returning the next element. */
6122
6123static struct nameseq *
6124helper_unlink_and_free_ns (struct nameseq *cur, struct nameseq *prev,
6125 struct nameseq **chainp)
6126{
6127 struct nameseq *freeit = cur; \
6128 free ((char *)cur->name);
6129 if (prev)
6130 prev->next = cur = cur->next;
6131 else
6132 *chainp = cur = cur->next;
6133 free_ns (freeit);
6134 return cur;
6135}
6136
6137/* Frees a chain returned by helper_parse_file_list. */
6138
6139static void free_ns_chain_no_strcache (struct nameseq *ns)
6140{
6141 while (ns != 0)
6142 {
6143 struct nameseq *t = ns;
6144 free ((char *)ns->name);
6145 ns = ns->next;
6146 free_ns (t);
6147 }
6148}
6149
6150/* Decoded style options for the $(q* ) and $(*file* ) functions. */
6151#define Q_RET_MASK 0x000f
6152#define Q_RET_QUOTED 0x0000
6153#define Q_RET_QUOTED_DEP 0x0001
6154#define Q_RET_QUOTED_DEP_END 0x0002
6155#define Q_RET_QUOTED_TGT 0x0003
6156#define Q_RET_QUOTED_TGT_END 0x0004
6157#define Q_RET_UNQUOTED 0x0005
6158#define Q_RET_SHELL 0x0006
6159#define Q_RET_SHELL_IN_DQ 0x0007
6160#define Q_RET_SHELL_IN_SQ 0x0008
6161
6162#define Q_IN_MASK 0x0030
6163#define Q_IN_QUOTED 0x0000
6164#define Q_IN_UNQUOTED 0x0010
6165#define Q_IN_QUOTED_DEP 0x0020 /** @todo needed? */
6166#define Q_IN_QUOTED_TGT 0x0030 /** @todo needed? */
6167#define Q_IN_SEP_COMMA 0x0040 /* for VMS hacks, file lists only */
6168
6169#define Q_SEP_MASK 0x0700
6170#define Q_SEP_SHIFT 8
6171#define Q_SEP_SPACE 0x0000
6172#define Q_SEP_TAB 0x0100
6173#define Q_SEP_NL 0x0200
6174#define Q_SEP_NL_TAB 0x0300
6175#define Q_SEP_COMMA 0x0400 /* for VMS, output only */
6176
6177#define Q_QDEFAULT (Q_IN_QUOTED | Q_RET_QUOTED | Q_SEP_SPACE)
6178#ifndef VMS
6179# define Q_QDEFAULT_VMS_TRICKS Q_QDEFAULT
6180#else /* VMS: Treat ',' as file separators in input, maybe output too. */
6181# define Q_QDEFAULT_VMS_TRICKS (Q_IN_SEP_COMMA | \
6182 (!vms_comma_separator ? Q_QDEFAULT \
6183 : (Q_QDEFAULT & ~Q_SEP_MASK) | Q_SEP_COMMA)
6184#endif
6185
6186
6187/* Decodes the optional style argument. This is chiefly for the return
6188 style, but can also pick the input and space styles (just because we can). */
6189
6190static unsigned int helper_file_quoting_style (char *style, unsigned int intstyle)
6191{
6192 if (style != NULL)
6193 {
6194 for (;;)
6195 {
6196 /* Skip blanks: */
6197 while (ISBLANK(*style))
6198 style++;
6199 if (*style != '\0')
6200 {
6201 /* Find the end of the current word: */
6202 char * const start = style;
6203 size_t len;
6204 char ch;
6205 while (!ISBLANK((ch = *style)) && ch != '\0')
6206 style++;
6207 len = style - start;
6208
6209 /* String "switch" to decode the word: */
6210
6211#define MATCH(a_str) (len == sizeof (a_str) - 1 && memcmp (start, a_str, sizeof (a_str)) == 0)
6212 /* return styles: */
6213 if (MATCH ("quoted") || MATCH ("q"))
6214 intstyle = (intstyle & ~Q_RET_MASK) | Q_RET_QUOTED;
6215 else if (MATCH ("unquoted") || MATCH ("unq") || MATCH ("u"))
6216 intstyle = (intstyle & ~Q_RET_MASK) | Q_RET_UNQUOTED;
6217 else if (MATCH ("quoted-dep") || MATCH ("q-dep") || MATCH ("q-d"))
6218 intstyle = (intstyle & ~Q_RET_MASK) | Q_RET_QUOTED_DEP;
6219 else if (MATCH ("quoted-dep-end") || MATCH ("q-dep-end") || MATCH ("q-d-e"))
6220 intstyle = (intstyle & ~Q_RET_MASK) | Q_RET_QUOTED_DEP_END;
6221 else if (MATCH ("quoted-tgt") || MATCH ("q-tgt") || MATCH ("q-t"))
6222 intstyle = (intstyle & ~Q_RET_MASK) | Q_RET_QUOTED_TGT;
6223 else if (MATCH ("quoted-tgt-end") || MATCH ("q-tgt-end") || MATCH ("q-t-e"))
6224 intstyle = (intstyle & ~Q_RET_MASK) | Q_RET_QUOTED_TGT_END;
6225 else if (MATCH ("shell") || MATCH ("sh"))
6226 intstyle = (intstyle & ~Q_RET_MASK) | Q_RET_SHELL;
6227 else if (MATCH ("shell-in-dq") || MATCH ("sh-i-d"))
6228 intstyle = (intstyle & ~Q_RET_MASK) | Q_RET_SHELL_IN_DQ;
6229 else if (MATCH ("shell-in-sq") || MATCH ("sh-i-s"))
6230 intstyle = (intstyle & ~Q_RET_MASK) | Q_RET_SHELL_IN_SQ;
6231 /* input styles: */
6232 else if (MATCH ("in-quoted") || MATCH ("i-q"))
6233 intstyle = (intstyle & ~Q_IN_MASK) | Q_IN_QUOTED;
6234 else if (MATCH ("in-unquoted") || MATCH ("i-unq") || MATCH ("i-u"))
6235 intstyle = (intstyle & ~Q_IN_MASK) | Q_IN_UNQUOTED;
6236 else if (MATCH ("in-quoted-dep") || MATCH ("i-q-dep") || MATCH ("i-q-d"))
6237 intstyle = (intstyle & ~Q_IN_MASK) | Q_IN_QUOTED_DEP;
6238 else if (MATCH ("in-quoted-tgt") || MATCH ("i-q-tgt") || MATCH ("i-q-t"))
6239 intstyle = (intstyle & ~Q_IN_MASK) | Q_IN_QUOTED_TGT;
6240 else if (MATCH ("in-sep-comma") || MATCH ("i-s-com") || MATCH ("i-s-c"))
6241 intstyle = (intstyle & ~Q_SEP_MASK) | Q_IN_SEP_COMMA;
6242 /* separator styles (output): */
6243 else if (MATCH ("sep-space") || MATCH ("s-space") || MATCH ("s-s"))
6244 intstyle = (intstyle & ~Q_SEP_MASK) | Q_SEP_SPACE;
6245 else if (MATCH ("sep-tab") || MATCH ("s-tab") || MATCH ("s-t"))
6246 intstyle = (intstyle & ~Q_SEP_MASK) | Q_SEP_TAB;
6247 else if (MATCH ("sep-nl") || MATCH ("s-nl") || MATCH ("s-n"))
6248 intstyle = (intstyle & ~Q_SEP_MASK) | Q_SEP_NL;
6249 else if (MATCH ("sep-nl-tab") || MATCH ("s-nl-tab") || MATCH ("s-n-t"))
6250 intstyle = (intstyle & ~Q_SEP_MASK) | Q_SEP_NL_TAB;
6251 else if (MATCH ("sep-comma") || MATCH ("s-comma") || MATCH ("s-c"))
6252 intstyle = (intstyle & ~Q_SEP_MASK) | Q_SEP_COMMA;
6253 else
6254 {
6255 char savedch = *style;
6256 *style = '\0';
6257 OS (error, reading_file, "Unknown file return style: %s", start);
6258 *style = savedch;
6259 }
6260#undef MATCH
6261 }
6262 else
6263 break;
6264 }
6265 }
6266 return intstyle;
6267}
6268
6269/* Output (returns) a separator according to STYLE. */
6270
6271static char *helper_return_sep (char *o, unsigned int style)
6272{
6273 /* Note! Must match Q_SEP_MASK! */
6274 static struct
6275 {
6276 const char *sep;
6277 size_t len;
6278 } const seps[8] =
6279 {
6280 { " ", 1 },
6281 { "\t", 1 },
6282 { "\n", 1 },
6283 { "\n\t", 2 },
6284 { ",", 1 },
6285 { " ", 1 },
6286 { " ", 1 },
6287 { " ", 1 }
6288 };
6289
6290 return variable_buffer_output(o,
6291 seps[(style & Q_SEP_MASK) >> Q_SEP_SHIFT].sep,
6292 seps[(style & Q_SEP_MASK) >> Q_SEP_SHIFT].len);
6293}
6294
6295/* Outputs (returns) the given file. */
6296
6297static char *helper_return_file_len (char *o, const char *file, size_t len,
6298 unsigned int style, int is_last)
6299{
6300 assert (memchr (file, '\0', len) == NULL);
6301 switch (style & Q_RET_MASK)
6302 {
6303 case Q_RET_UNQUOTED:
6304 o = variable_buffer_output (o, file, len);
6305 break;
6306 case Q_RET_QUOTED:
6307 o = helper_quote_make (o, file, len, 0 /*is_dep*/, 0 /*is_tgt*/,
6308 !is_last /*quote_trailing_slashes*/, NULL);
6309 break;
6310 case Q_RET_QUOTED_DEP:
6311 o = helper_quote_make (o, file, len, 1 /*is_dep*/, 0 /*is_tgt*/,
6312 !is_last /*quote_trailing_slashes*/, NULL);
6313 break;
6314 case Q_RET_QUOTED_DEP_END:
6315 o = helper_quote_make (o, file, len, 1 /*is_dep*/, 0 /*is_tgt*/,
6316 0 /*quote_trailing_slashes*/, NULL);
6317 break;
6318 case Q_RET_QUOTED_TGT:
6319 o = helper_quote_make (o, file, len, 0 /*is_dep*/, 1 /*is_tgt*/,
6320 !is_last /*quote_trailing_slashes*/, NULL);
6321 break;
6322 case Q_RET_QUOTED_TGT_END:
6323 o = helper_quote_make (o, file, len, 0 /*is_dep*/, 1 /*is_tgt*/,
6324 0 /*quote_trailing_slashes*/, NULL);
6325 break;
6326 case Q_RET_SHELL:
6327 o = helper_quote_shell (o, file, len, 0 /*need_leading_space*/);
6328 break;
6329 case Q_RET_SHELL_IN_DQ:
6330 o = func_escape_shell_in_dq (o, file, len);
6331 break;
6332 case Q_RET_SHELL_IN_SQ:
6333 o = func_escape_shell_in_sq (o, file, len);
6334 break;
6335 default:
6336 assert (0);
6337 }
6338
6339 /* Add separator space if not last. */
6340 if (!is_last)
6341 o = helper_return_sep (o, style);
6342 return o;
6343}
6344
6345/* Outputs (returns) the given file. */
6346
6347static char *helper_return_file (char *o, const char *file, unsigned int style, int is_last)
6348{
6349 return helper_return_file_len (o,file, strlen (file), style, is_last);
6350}
6351
6352/* Outputs (returns) the given CHAIN and frees it. */
6353
6354static char *helper_return_and_free_chain (char *o, struct nameseq *chain, unsigned int style)
6355{
6356 struct nameseq *cur;
6357 for (cur = chain; cur; cur = cur->next)
6358 o = helper_return_file (o, cur->name, style, cur->next == NULL);
6359 free_ns_chain_no_strcache (chain);
6360 return o;
6361}
6362
6363
6364/* Helper for helper_parse_file_list that globs a name sequence. */
6365static struct nameseq *
6366helper_glob_chain (struct nameseq *chain)
6367{
6368 struct nameseq *prev = NULL;
6369 struct nameseq *cur = chain;
6370 glob_t gl;
6371 dir_setup_glob (&gl);
6372
6373 /** @todo XXX: !NO_ARCHIVES */
6374 while (cur)
6375 {
6376 switch (glob (cur->name, GLOB_NOSORT | GLOB_ALTDIRFUNC, NULL, &gl))
6377 {
6378 case 0: /* Replace CUR with the names found. */
6379 {
6380 struct nameseq *subchain = NULL;
6381 struct nameseq **ppnext = &subchain;
6382 const char ** const names = (const char **)gl.gl_pathv;
6383 size_t const num_names = gl.gl_pathc;
6384 size_t idx;
6385
6386 cur = helper_unlink_and_free_ns (cur, prev, &chain);
6387
6388 for (idx = 0; idx < num_names; idx++)
6389 {
6390#ifndef CONFIG_WITH_ALLOC_CACHES
6391 struct nameseq *newp = xcalloc (sizeof (*newp));
6392#else
6393 struct nameseq *newp = alloccache_calloc (&nameseq_cache);
6394#endif
6395 newp->name = xstrdup (names[idx]);
6396 newp->next = NULL;
6397 *ppnext = newp;
6398 ppnext = &newp->next;
6399 }
6400
6401 if (subchain) /* parnaoia */
6402 {
6403 *ppnext = cur;
6404 if (prev)
6405 prev->next = subchain;
6406 else
6407 chain = subchain;
6408 }
6409 break;
6410 }
6411
6412 case GLOB_NOMATCH: /* doesn't exist, remove */
6413 cur = helper_unlink_and_free_ns (cur, prev, &chain);
6414 break;
6415
6416 default: /* Keep it. */
6417 prev = cur;
6418 cur = cur->next;
6419 break;
6420
6421 case GLOB_NOSPACE:
6422 OUT_OF_MEM();
6423 }
6424 globfree (&gl);
6425 }
6426 return chain;
6427}
6428
6429/* Parses a file/word list according to STYLE and returns a name list.
6430
6431 Note! The FILELIST parameter may be modified.
6432
6433 TODO/XXX: Unquote and split up the FILELIST directly. All function
6434 arguments are heap copies already, so we are free to modify
6435 them. Would be nice to ditch the nameseq in favor of something
6436 which also includes the length. */
6437
6438static struct nameseq *
6439helper_parse_file_list (char *filelist, unsigned int style, int glob)
6440{
6441 if (filelist && *filelist != '\0')
6442 {
6443 /* Q_IN_SEP_COMMA: VMS tricks for qbasename, qdir, qnotdir and qsuffix
6444 where commas are treated as separtors in FILELIST. We simply
6445 replace commas in the FILELIST before doing the regular parsing. */
6446 if (!(style & Q_IN_SEP_COMMA))
6447 { /* typical */ }
6448 else
6449 {
6450 size_t len = strlen (filelist);
6451 char *start = filelist;
6452 char *comma = (char *)memchr (filelist, ',', len);
6453 while (comma)
6454 {
6455 *comma = ' ';
6456 len -= comma - start - 1;
6457 if (len)
6458 {
6459 start = comma + 1;
6460 comma = (char *)memchr (start, ',', len);
6461 }
6462 else
6463 break;
6464 }
6465 }
6466
6467 switch (style & Q_IN_MASK)
6468 {
6469 case Q_IN_QUOTED:
6470 case Q_IN_QUOTED_DEP: /** @todo ?? */
6471 case Q_IN_QUOTED_TGT: /** @todo ?? */
6472 return PARSE_FILE_SEQ(&filelist, struct nameseq, MAP_NUL, NULL,
6473 !glob
6474 ? PARSEFS_NOGLOB | PARSEFS_NOSTRIP | PARSEFS_NOCACHE
6475 : PARSEFS_NOSTRIP | PARSEFS_NOCACHE | PARSEFS_EXISTS);
6476
6477 case Q_IN_UNQUOTED:
6478 {
6479 struct nameseq *chain = NULL;
6480 struct nameseq **ppnext = &chain;
6481 const char *it = filelist;
6482 const char *cur;
6483 unsigned int curlen;
6484 while ((cur = find_next_token (&it, &curlen)) != NULL)
6485 {
6486#ifndef CONFIG_WITH_ALLOC_CACHES
6487 struct nameseq *newp = xcalloc (sizeof (*newp));
6488#else
6489 struct nameseq *newp = alloccache_calloc (&nameseq_cache);
6490#endif
6491 newp->name = xstrndup (cur, curlen);
6492 newp->next = NULL;
6493 *ppnext = newp;
6494 ppnext = &newp->next;
6495 }
6496 if (!glob)
6497 return chain;
6498 return helper_glob_chain (chain);
6499 }
6500
6501 default:
6502 assert (0);
6503 return NULL;
6504 }
6505 }
6506 return NULL;
6507}
6508
6509/* $(requote style, file1 file2 ... fileN). */
6510
6511static char *func_requote (char *o, char **argv, const char *funcname UNUSED)
6512{
6513 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT);
6514 struct nameseq *chain = helper_parse_file_list (argv[1], style, 0);
6515 return helper_return_and_free_chain (o, chain, style);
6516}
6517
6518
6519/* Common worker for func_firstfile() and func_qfirstfile(). */
6520
6521static char *common_firstfile (char *o, char **argv, unsigned int style)
6522{
6523 struct nameseq *chain = helper_parse_file_list (argv[0], style, 0);
6524 if (chain)
6525 {
6526 o = helper_return_file (o, chain->name, style, 1);
6527 free_ns_chain_no_strcache (chain);
6528 }
6529 return o;
6530}
6531
6532/* $(firstfile file1 file2 ... fileN) - same as $(firstfile ), except
6533 for files rather than word tokens. See func_firstword(). */
6534
6535static char *func_firstfile (char *o, char **argv, const char *funcname UNUSED)
6536{
6537 return common_firstfile(o, argv, Q_IN_QUOTED | Q_RET_QUOTED | Q_SEP_SPACE);
6538}
6539
6540/* $(qfirstfile style, file1 file2 ... fileN) - same as $(firstfile ), except
6541 for files rather than word tokens. See func_firstword(). */
6542
6543static char *func_q_firstfile (char *o, char **argv, const char *funcname UNUSED)
6544{
6545 unsigned int style = helper_file_quoting_style (argv[0], Q_QDEFAULT);
6546 return common_firstfile(o, &argv[1], style);
6547}
6548
6549
6550/* Common worker for func_lastfile() and func_q_lastfile(). */
6551
6552static char *common_lastfile (char *o, char **argv, unsigned int style)
6553{
6554 struct nameseq *chain = helper_parse_file_list (argv[0], style, 0);
6555 if (chain)
6556 {
6557 struct nameseq *last = chain;
6558 while (last->next)
6559 last = last->next;
6560 o = helper_return_file (o, last->name, style, 1);
6561 free_ns_chain_no_strcache (chain);
6562 }
6563 return o;
6564}
6565
6566/* $(lastfile file1 file2 ... fileN) - same as $(lastfile ), except
6567 for files rather than word tokens. See func_lastword(). */
6568
6569static char *func_lastfile (char *o, char **argv, const char *funcname UNUSED)
6570{
6571 return common_lastfile (o, argv, Q_IN_QUOTED | Q_RET_QUOTED | Q_SEP_SPACE);
6572}
6573
6574/* $(qlastfile style, file1 file2 ... fileN) - same as $(lastfile ), except
6575 for files rather than word tokens. See func_lastword(). */
6576
6577static char *func_q_lastfile (char *o, char **argv, const char *funcname UNUSED)
6578{
6579 unsigned int style = helper_file_quoting_style (argv[0], Q_QDEFAULT);
6580 return common_lastfile (o, &argv[1], style);
6581}
6582
6583
6584/* Common worker for func_filelist() and func_q_filelist(). */
6585
6586static char *common_filelist (char *o, char **argv, unsigned int style)
6587{
6588 int start;
6589 int count;
6590
6591 /* Check the arguments. */
6592 check_numeric (argv[0],
6593 _("non-numeric first argument to 'filelist' function"));
6594 check_numeric (argv[1],
6595 _("non-numeric second argument to 'filelist' function"));
6596
6597 start = atoi (argv[0]);
6598 if (start < 1)
6599 ON (fatal, *expanding_var,
6600 "invalid first argument to 'filelist' function: '%d'", start);
6601 start--; /* make zero based */
6602
6603 count = atoi (argv[1]) - start;
6604
6605 if (count > 0)
6606 {
6607 char *line = argv[2];
6608 struct nameseq *cur;
6609 struct nameseq *chain;
6610 chain = helper_parse_file_list (line, style, 0);
6611
6612 /* Find the beginning of the "start"th word (1-based). */
6613 for (cur = chain; cur && start > 1; cur = cur->next)
6614 start--;
6615
6616 /* Output the requested count */
6617 while (cur && count-- > 0)
6618 o = helper_return_file (o, cur->name, style, count > 0 && cur->next);
6619
6620 free_ns_chain_no_strcache (chain);
6621 }
6622
6623 return o;
6624}
6625
6626/* $(filelist start, end, file1..fileN) - same as $(wordlist),
6627 except for files rather than word tokens. See func_wordlist(). */
6628
6629static char *func_filelist (char *o, char **argv, const char *funcname UNUSED)
6630{
6631 return common_filelist (o, argv, Q_IN_QUOTED | Q_RET_QUOTED | Q_SEP_SPACE);
6632}
6633
6634/* $(qfilelist style, start, end, file1..fileN) - same as $(wordlist),
6635 except for files rather than word tokens. See func_wordlist(). */
6636
6637static char *func_q_filelist (char *o, char **argv, const char *funcname UNUSED)
6638{
6639 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT);
6640 return common_filelist (o, &argv[1], style);
6641}
6642
6643
6644/* Common worker for func_countfiles() and func_q_countfiles(). */
6645
6646static char *common_countfiles (char *o, char **argv, unsigned int style)
6647{
6648 struct nameseq *chain = helper_parse_file_list (argv[0], style, 0);
6649 struct nameseq *cur;
6650 unsigned int files = 0;
6651 char retval[32];
6652
6653 for (cur = chain; cur; cur = cur->next)
6654 files++;
6655 free_ns_chain_no_strcache (chain);
6656
6657 return variable_buffer_output (o, retval, sprintf (retval, "%u", files));
6658}
6659
6660/* $(countfiles file1 file2 ... fileN) - same as $(words ), except for
6661 files rather than word tokens. See func_words(). */
6662
6663static char *func_countfiles (char *o, char **argv, const char *funcname UNUSED)
6664{
6665 return common_countfiles (o, argv, Q_IN_QUOTED | Q_RET_QUOTED | Q_SEP_SPACE);
6666}
6667
6668/* $(qcountfiles style, file1 file2 ... fileN) - same as $(words ), except for
6669 files rather than word tokens and the STYLE argument. See func_words(). */
6670
6671static char *func_q_countfiles (char *o, char **argv, const char *funcname UNUSED)
6672{
6673 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT);
6674 return common_countfiles (o, &argv[1], style);
6675}
6676
6677
6678/* Helper that sets the variable value. */
6679
6680static void
6681helper_set_var_value (struct variable *var, const char *value, size_t len)
6682{
6683#ifndef CONFIG_WITH_VALUE_LENGTH
6684 free (var->value);
6685 var->value = xstrndup (value, len);
6686#else
6687 if (len >= var->value_alloc_len)
6688 {
6689# ifdef CONFIG_WITH_RDONLY_VARIABLE_VALUE
6690 if (var->rdonly_val)
6691 var->rdonly_val = 0;
6692 else
6693# endif
6694 free (var->value);
6695 var->value_alloc_len = VAR_ALIGN_VALUE_ALLOC (len + 1);
6696 var->value = xmalloc (var->value_alloc_len);
6697 }
6698 memcpy (var->value, value, len);
6699 var->value[len] = '\0';
6700 var->value_length = len;
6701 VARIABLE_CHANGED (var);
6702#endif
6703}
6704
6705/* Common worker for func_foreachfile and func_qforeachfile. */
6706
6707static char *
6708common_foreachfile (char *o, char **argv, unsigned int style)
6709{
6710 /* expand only the first two. */
6711 char *varname = expand_argument (argv[0], NULL);
6712 char *list = expand_argument (argv[1], NULL);
6713 const char *body = argv[2];
6714#ifdef CONFIG_WITH_VALUE_LENGTH
6715 long body_len = strlen (body);
6716#endif
6717
6718 struct nameseq *chain = helper_parse_file_list (list, style, 0);
6719 struct nameseq *cur;
6720
6721 /* Clean up the variable name by removing whitespace. */
6722 struct variable *var;
6723 char *vp = next_token (varname);
6724 char *vp_end = end_of_token (vp);
6725 vp_end[0] = '\0';
6726
6727 push_new_variable_scope ();
6728 var = define_variable (vp, vp_end - vp, "", o_automatic, 0);
6729
6730 /* Don't need the list any more. */
6731 free (list);
6732 list = NULL;
6733
6734 /* Loop through the chain. */
6735 for (cur = chain; cur; cur = cur->next)
6736 {
6737 /* Update the variable value: */
6738 unsigned int const len = strlen (cur->name);
6739 switch (style & Q_RET_MASK)
6740 {
6741 case Q_RET_UNQUOTED:
6742 helper_set_var_value (var, cur->name, len);
6743 break;
6744 default:
6745 { /* Use the output buffer as temporary storage. */
6746 size_t const saved_off = o - variable_buffer;
6747 size_t quoted_len;
6748 char *quoted;
6749 o = helper_return_file_len (o, cur->name, len, style, 1 /*is_last*/);
6750 quoted = &variable_buffer[saved_off];
6751 quoted_len = o - quoted;
6752 helper_set_var_value (var, quoted, quoted_len);
6753 o = quoted;
6754 break;
6755 }
6756 }
6757
6758 /* Expand the body: */
6759#ifndef CONFIG_WITH_VALUE_LENGTH
6760 {
6761 char *result = allocated_variable_expand (body);
6762 o = variable_buffer_output (o, result, strlen (result));
6763 free (result);
6764 }
6765#else
6766 variable_expand_string_2 (o, body, body_len, &o);
6767#endif
6768
6769 /* Add separator: */
6770 if (cur->next)
6771 o = helper_return_sep (o, style);
6772 }
6773
6774 pop_variable_scope ();
6775 free (varname);
6776
6777 return o;
6778}
6779
6780/* $(foreachfile var, filelist, body) - same as $(foreach ), except
6781 for file rather than word tokens.
6782 See also func_foreach(). */
6783
6784static char *
6785func_foreachfile (char *o, char **argv, const char *funcname UNUSED)
6786{
6787 return common_foreachfile (o, argv, Q_IN_QUOTED | Q_RET_QUOTED | Q_SEP_SPACE);
6788}
6789
6790/* $(qforeachfile style, var, filelist, body) - same as $(foreach ), except
6791 for file rather than word tokens and flexible variable value encoding.
6792 See also func_foreach(). */
6793
6794static char *
6795func_q_foreachfile (char *o, char **argv, const char *funcname UNUSED)
6796{
6797 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT);
6798 return common_foreachfile (o, &argv[1], style);
6799}
6800
6801
6802/* Common worker for func_sortfiles() and func_q_sortfiles(). */
6803
6804static char *common_sortfiles (char *o, char **argv, unsigned int style,
6805 int ascending, int version)
6806{
6807 struct nameseq *chain = helper_parse_file_list (argv[0], style, 0);
6808
6809 /* Count the number of files to determin the array size and whether we've
6810 got anything to sort. */
6811 struct nameseq *cur;
6812 unsigned int num_files = 0;
6813 for (cur = chain; cur; cur = cur->next)
6814 num_files++;
6815
6816 if (num_files <= 1)
6817 o = helper_return_and_free_chain (o, chain, style);
6818 else
6819 {
6820 /* Create array of string pointers from the chain. */
6821 char **files = (char **)xmalloc (num_files * sizeof (char *));
6822 unsigned int idx = 0;
6823 for (cur = chain; cur; cur = cur->next)
6824 files[idx++] = (char *)cur->name;
6825
6826 /* Sort it. */
6827 if (version)
6828 qsort(files, num_files, sizeof(files[0]), version_compare_wrapper);
6829 else
6830 qsort(files, num_files, sizeof(files[0]), alpha_compare);
6831
6832 /* Output. We skip equal files. */
6833 if (ascending)
6834 for (idx = 0; idx < num_files; idx++)
6835 {
6836 const char *curfile = files[idx];
6837 while (idx + 1 < num_files && strcmp(files[idx + 1], curfile) == 0)
6838 idx++;
6839 o = helper_return_file(o, files[idx], style, idx + 1 >= num_files);
6840 }
6841 else
6842 {
6843 idx = num_files;
6844 while (idx-- > 0)
6845 {
6846 const char *curfile = files[idx];
6847 while (idx > 0 && strcmp(files[idx - 1], curfile) == 0)
6848 idx--;
6849 o = helper_return_file (o, curfile, style, idx == 0);
6850 }
6851 }
6852
6853 free (files);
6854 free_ns_chain_no_strcache (chain);
6855 }
6856 return o;
6857}
6858
6859/* $(sortfiles file1 ... fileN) and
6860 $(rsortfiles file1 ... fileN) - same as $(sort ) and $(rsort ),
6861 except for files rather than word tokens. See func_sort(). */
6862
6863static char *func_sortfiles (char *o, char **argv, const char *funcname)
6864{
6865 return common_sortfiles (o, argv, Q_IN_QUOTED | Q_RET_QUOTED | Q_SEP_SPACE,
6866 funcname[0] != 'r',
6867 funcname[0] == 'v' || funcname[1] == 'v');
6868}
6869
6870/* $(qsortfiles style, file1 ... fileN) and
6871 $(qrsortfiles style, file1 ... fileN) - same as $(sort ) and $(rsort ),
6872 except for files rather than word tokens and the flexible style.
6873 See func_sort(). */
6874
6875static char *func_q_sortfiles (char *o, char **argv, const char *funcname)
6876{
6877 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT);
6878 return common_sortfiles (o, &argv[1], style, funcname[1] != 'r',
6879 funcname[1] == 'v' || funcname[2] == 'v');
6880}
6881
6882
6883/* Helper for determining whether the given path is absolute or not. */
6884
6885static int helper_is_abs (const char *path)
6886{
6887#ifdef HAVE_DOS_PATHS
6888 return path[0] == '/'
6889 || path[0] == '\\'
6890 || (isalpha(path[0]) && path[1] == ':');
6891#else
6892 return path[0] == '/';
6893#endif
6894}
6895
6896/* Worker for func_q_abspath and func_q_abspath_ex. */
6897
6898static char *worker_abspath (char *o, char *line, const char *cwd,
6899 size_t cwd_len, unsigned int style)
6900{
6901 if (line && *line != '\0')
6902 {
6903 PATH_VAR (outbuf);
6904 struct nameseq *chain = helper_parse_file_list (line, style, 0);
6905
6906 /* Special case: single path, no cwd - no is_last path trouble */
6907 if (chain && !chain->next && !cwd)
6908 {
6909 if (abspath (chain->name, outbuf))
6910 o = helper_return_file(o, outbuf, style, 1);
6911 free_ns_chain_no_strcache (chain);
6912 }
6913 else if (chain)
6914 {
6915 /* Pass one: replace names by absolute names */
6916 struct nameseq *prev = NULL;
6917 struct nameseq *cur = chain;
6918 while (cur)
6919 {
6920 /* If relative path and we've got cwd, join cwd and it. */
6921 if (cwd && !helper_is_abs (cur->name))
6922 {
6923 size_t len_name = strlen (cur->name);
6924 char *name = xrealloc ((char *)cur->name, cwd_len + 1 + len_name + 1);
6925 memmove (&name[cwd_len + 1], &name[0], len_name);
6926 memcpy (name, cwd, cwd_len);
6927 name[cwd_len] = '/';
6928 name[cwd_len + 1 + len_name] = '\0';
6929 cur->name = name;
6930 }
6931
6932 if (abspath (cur->name, outbuf))
6933 {
6934 free ((char *)cur->name);
6935 cur->name = xstrdup (outbuf);
6936 prev = cur;
6937 cur = cur->next;
6938 }
6939 else /* remove it */
6940 cur = helper_unlink_and_free_ns (cur, prev, &chain);
6941 }
6942
6943 /* Pass two: output */
6944 o = helper_return_and_free_chain (o, chain, style);
6945 }
6946 }
6947 return o;
6948}
6949
6950/* $(qabspath style, file1 file2 ... fileN) - same as $(abspath ), except
6951 for files rather than word tokens. See func_abspath(). */
6952
6953static char *func_q_abspath (char *o, char **argv, const char *funcname UNUSED)
6954{
6955 return worker_abspath (o, argv[1], NULL, 0,
6956 helper_file_quoting_style (argv[0], Q_QDEFAULT));
6957}
6958
6959# ifdef CONFIG_WITH_ABSPATHEX
6960/* $(qabspathex style, file1 file2 ... fileN [,cwd]) - same as $(abspathex ),
6961 except for files rather than word tokens. See func_abspath_ex(). */
6962
6963static char *
6964func_q_abspathex (char *o, char **argv, const char *funcname UNUSED)
6965{
6966 /* cwd needs leading spaces chopped and may be optional,
6967 in which case we're exactly like $(abspath ). */
6968 char *cwd = argv[2];
6969 if (cwd)
6970 {
6971 while (ISBLANK (*cwd))
6972 cwd++;
6973 if (*cwd == '\0')
6974 cwd = NULL;
6975 }
6976
6977 return worker_abspath (o, argv[1], cwd, cwd ? strlen (cwd) : 0,
6978 helper_file_quoting_style (argv[0], Q_QDEFAULT));
6979}
6980# endif
6981
6982/* $(qaddprefix style, prefix, file1 ... fileN) and
6983 $(qaddsuffix style, prefix, file1 ... fileN) - same as $(addprefix )
6984 and $(addsuffix ) except for files rather than word tokens.
6985 The suffix/prefix is unquoted on input and subjected to the same quoting
6986 styling as the file names.
6987 See func_addsuffix_addprefix(). */
6988
6989static char *func_q_addsuffix_addprefix (char *o, char **argv, const char *funcname UNUSED)
6990{
6991 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT);
6992 const char * const fix = argv[1];
6993 size_t const fixlen = strlen (fix);
6994 struct nameseq *chain = helper_parse_file_list (argv[2], style, 0);
6995 if (chain)
6996 {
6997 size_t tmpsize = (fixlen + 512) & ~(size_t)63;
6998 char *tmp = (char *)xmalloc (tmpsize);
6999 struct nameseq *cur;
7000
7001 if (funcname[4] == 'p')
7002 {
7003 memcpy (tmp, fix, fixlen);
7004 for (cur = chain; cur; cur = cur->next)
7005 {
7006 size_t curlen = strlen (cur->name);
7007 if (fixlen + curlen + 1 <= tmpsize)
7008 { /* likely */ }
7009 else
7010 {
7011 tmpsize = (fixlen + curlen + 63) & ~(size_t)63;
7012 tmp = (char *)xrealloc (tmp, tmpsize);
7013 }
7014 memcpy (&tmp[fixlen], cur->name, curlen + 1);
7015 o = helper_return_file_len (o, tmp, fixlen + curlen,
7016 style, cur->next == NULL);
7017 }
7018 }
7019 else
7020 for (cur = chain; cur; cur = cur->next)
7021 {
7022 size_t curlen = strlen (cur->name);
7023 if (fixlen + curlen + 1 <= tmpsize)
7024 { /* likely */ }
7025 else
7026 {
7027 tmpsize = (fixlen + curlen + 63) & ~(size_t)63;
7028 tmp = (char *)xrealloc (tmp, tmpsize);
7029 }
7030 memcpy (tmp, cur->name, curlen);
7031 memcpy (&tmp[curlen], fix, fixlen + 1);
7032
7033 o = helper_return_file_len (o, tmp, fixlen + curlen,
7034 style, cur->next == NULL);
7035 }
7036 free_ns_chain_no_strcache (chain);
7037 }
7038 return o;
7039}
7040
7041/* $(qbasename style, path1 .. pathN) and $(qdir style, path1 .. pathN)
7042 - same as $(basename ) and $(dir ), except for files rather than word tokens.
7043 See func_basename_dir(). */
7044
7045static char *
7046func_q_basename_dir (char *o, char **argv, const char *funcname)
7047{
7048 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT_VMS_TRICKS);
7049 struct nameseq *chain = helper_parse_file_list (argv[1], style, 0);
7050 struct nameseq *cur;
7051
7052 int const is_basename = funcname[1] == 'b';
7053 int const is_dir = !is_basename;
7054 int const stop = MAP_DIRSEP | (is_basename ? MAP_DOT : 0) | MAP_NUL;
7055
7056 for (cur = chain; cur; cur = cur->next)
7057 {
7058 int const is_last = cur->next == NULL;
7059 const char * const path = cur->name;
7060 const char * const end = strchr (path, '\0');
7061
7062 /* Locate the last dot or path separator (P): */
7063 const char *p = path != end ? end - 1 : end;
7064 while (p >= path && !STOP_SET (*p, stop))
7065 --p;
7066
7067 /* Do the outputting: */
7068 if (p >= path && (is_dir))
7069 o = helper_return_file_len (o, path, ++p - path, style, is_last);
7070 else if (p >= path && *p == '.')
7071 o = helper_return_file_len (o, path, p - path, style, is_last);
7072#ifdef HAVE_DOS_PATHS
7073 /* Handle the "d:foobar" case */
7074 else if (path[0] && path[1] == ':' && is_dir)
7075 o = helper_return_file_len (o, path, 2, style, is_last);
7076#endif
7077 else if (is_dir)
7078#ifdef VMS
7079 {
7080 extern int vms_report_unix_paths;
7081 o = helper_return_file_len (o, vms_report_unix_paths ? "./" : "[]",
7082 2, style, is_last);
7083 }
7084#else
7085# ifndef _AMIGA
7086 o = helper_return_file_len (o, "./", 2, style, is_last);
7087# else
7088 ; /* Just a nop... */
7089# endif /* AMIGA */
7090#endif /* !VMS */
7091 else
7092 /* The entire name is the basename. */
7093 o = helper_return_file_len (o, path, end - path, style, is_last);
7094 }
7095
7096 free_ns_chain_no_strcache (chain);
7097 return o;
7098}
7099
7100/* $(qnotdir style, path1 ... pathN) - same as $(notdir ), except for
7101 files rather than word tokens. See func_notdir_suffix(). */
7102
7103static char *
7104func_q_notdir (char *o, char **argv, const char *funcname)
7105{
7106 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT_VMS_TRICKS);
7107 struct nameseq *chain = helper_parse_file_list (argv[1], style, 0);
7108 struct nameseq *cur;
7109 int const stop = MAP_DIRSEP;
7110
7111 for (cur = chain; cur; cur = cur->next)
7112 {
7113 int const is_last = cur->next == NULL;
7114 const char * const path = cur->name;
7115 const char * const end = strchr(path, '\0');
7116
7117 /* Locate the last dot or path separator (P): */
7118 const char *p = path != end ? end - 1 : end;
7119 while (p >= path && ! STOP_SET (*p, stop))
7120 --p;
7121
7122 if ((uintptr_t)p >= (uintptr_t)path)
7123 o = helper_return_file_len (o, p + 1, end - p - 1, style, is_last);
7124#ifdef HAVE_DOS_PATHS
7125 else if (path[0] && path[1] == ':') /* "d:foo/bar" -> "foo/bar" */
7126 o = helper_return_file_len (o, path + 2, end - path - 2, style, is_last);
7127#endif
7128 else
7129 o = helper_return_file_len (o, path, end - path, style, is_last);
7130 }
7131
7132 free_ns_chain_no_strcache (chain);
7133 return o;
7134}
7135
7136/* $(qsuffix style, path1 ... pathN) - same as $(suffix ), except for
7137 files rather than word tokens. See func_notdir_suffix(). */
7138
7139static char *
7140func_q_suffix (char *o, char **argv, const char *funcname)
7141{
7142 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT_VMS_TRICKS);
7143 struct nameseq *chain = helper_parse_file_list (argv[1], style, 0);
7144 struct nameseq *prev;
7145 struct nameseq *cur;
7146 int const stop = MAP_DIRSEP | MAP_DOT;
7147
7148 /* For suffixes we do a pre-pass that removes elements without suffixes.
7149 This simplifies the handling of end-quoting. */
7150 prev = NULL;
7151 cur = chain;
7152 while (cur)
7153 {
7154 const char * const path = cur->name;
7155 if (strchr (path, '.') != NULL)
7156 {
7157 const char * const end = strchr (path, '\0');
7158 const char *p = end - 1;
7159 while ((uintptr_t)p >= (uintptr_t)path && ! STOP_SET (*p, stop))
7160 --p;
7161 if ((uintptr_t)p >= (uintptr_t)path && *p == '.')
7162 {
7163 if (p != path)
7164 memmove ((char *)path, p, end - p + 1);
7165 prev = cur;
7166 cur = cur->next;
7167 }
7168 else /* remove it */
7169 cur = helper_unlink_and_free_ns (cur, prev, &chain);
7170 }
7171 else /* remove it */
7172 cur = helper_unlink_and_free_ns (cur, prev, &chain);
7173 }
7174
7175 /* Output pass: */
7176 return helper_return_and_free_chain (o, chain, style);
7177}
7178
7179# ifdef CONFIG_WITH_ROOT_FUNC
7180/*
7181 $(qroot style, path...pathN) - same as $(root ), except files rather
7182 than space delimited word tokens. See func_root().
7183
7184 This is mainly for dealing with drive letters and UNC paths on Windows
7185 and OS/2.
7186 */
7187static char *
7188func_q_root (char *o, char **argv, const char *funcname UNUSED)
7189{
7190 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT);
7191 struct nameseq *chain = helper_parse_file_list (argv[1], style, 0);
7192 struct nameseq *prev;
7193 struct nameseq *cur;
7194
7195 /* First pass: Strip non-root components and remove rootless elements. */
7196 prev = NULL;
7197 cur = chain;
7198 while (cur)
7199 {
7200 const char *path = cur->name;
7201 const char *end = NULL;
7202 char ch;
7203
7204# ifdef HAVE_DOS_PATHS
7205 if (isalpha(path[0]) && path[1] == ':')
7206 end = path + 2;
7207 else if ( IS_PATHSEP(path[0])
7208 && IS_PATHSEP(path[1])
7209 && !IS_PATHSEP(path[2]) && path[2]
7210 && path[3])
7211 {
7212 /* Min recognized UNC: "//./" - find the next slash
7213 Typical root: "//srv/shr/" */
7214 /* XXX: Check if //./ needs special handling. */
7215 end = path + 3;
7216 while ((ch = *end) != '\0' && !IS_PATHSEP(ch))
7217 end++;
7218
7219 if (IS_PATHSEP(ch) && !IS_PATHSEP(end[1]))
7220 {
7221 end++;
7222 while ((ch = *end) != '\0' && !IS_PATHSEP(ch))
7223 end++;
7224 }
7225 else
7226 end = NULL; /* invalid */
7227 }
7228 else if (IS_PATHSEP(*end))
7229 end = path + 1;
7230 else
7231 end = NULL;
7232
7233# elif defined (VMS) || defined (AMGIA)
7234 /* XXX: VMS and AMGIA */
7235 OS (fatal, NILF, _("$(%s ) is not implemented on this platform"), funcname);
7236# else
7237 if (IS_PATHSEP(*path))
7238 end = path + 1;
7239# endif
7240 if (end != NULL)
7241 {
7242 /* Include all subsequent path separators. */
7243
7244 while ((ch = *end) != '\0' && IS_PATHSEP(ch))
7245 end++;
7246 *(char *)end = '\0';
7247
7248 prev = cur;
7249 cur = cur->next;
7250 }
7251 else
7252 cur = helper_unlink_and_free_ns(cur, prev, &chain);
7253 }
7254
7255 /* Second pass: Output */
7256 return helper_return_and_free_chain (o, chain, style);
7257}
7258
7259/*
7260 $(qnotroot style, path1 .. pathN) - same as $(notroot ), except files
7261 rather than space delimited word tokens. See func_notroot().
7262
7263 This is mainly for dealing with drive letters and UNC paths on Windows
7264 and OS/2.
7265 */
7266static char *
7267func_q_notroot (char *o, char **argv, const char *funcname UNUSED)
7268{
7269 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT);
7270 struct nameseq *chain = helper_parse_file_list (argv[1], style, 0);
7271 struct nameseq *cur;
7272
7273 for (cur = chain; cur; cur = cur->next)
7274 {
7275 const char *start = cur->name;
7276 char ch;
7277
7278# ifdef HAVE_DOS_PATHS
7279 if (isalpha(start[0]) && start[1] == ':')
7280 start += 2;
7281 else if ( IS_PATHSEP(start[0])
7282 && IS_PATHSEP(start[1])
7283 && !IS_PATHSEP(start[2]) && start[2] != '\0'
7284 && start[3] != '\0')
7285 {
7286 /* Min recognized UNC: "//./" - find the next slash
7287 Typical root: "//srv/shr/" */
7288 /* XXX: Check if //./ needs special handling. */
7289 start += 3;
7290 while ((ch = *start) != '\0' && !IS_PATHSEP(ch))
7291 start++;
7292
7293 if (IS_PATHSEP(ch) && !IS_PATHSEP(start[1]))
7294 {
7295 start++;
7296 while ((ch = *start) != '\0' && !IS_PATHSEP(ch))
7297 start++;
7298 }
7299 else
7300 start = cur->name; /* invalid UNC, pretend it's a couple unixy root slashes. */
7301 }
7302
7303# elif defined (VMS) || defined (AMGIA)
7304 /* XXX: VMS and AMGIA */
7305 OS (fatal, NILF, _("$(%s) is not implemented on this platform"), funcname);
7306# endif
7307
7308 /* Exclude all subsequent / leading path separators. */
7309 while ((ch = *start) != '\0' && IS_PATHSEP(ch))
7310 start++;
7311
7312 if (ch != '\0')
7313 o = helper_return_file(o, start, style, cur->next == NULL);
7314 else
7315 o = helper_return_file_len (o, ".", 1, style, cur->next == NULL);
7316 }
7317
7318 free_ns_chain_no_strcache (chain);
7319 return o;
7320}
7321
7322# endif
7323
7324/* $(qrealpath style, path1 .. pathN) - same as $(realpath ), except files
7325 rather than space delimited word tokens. See func_realpath(). */
7326
7327static char *
7328func_q_realpath (char *o, char **argv, const char *funcname UNUSED)
7329{
7330 PATH_VAR (outbuf);
7331 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT);
7332 struct nameseq *chain = helper_parse_file_list (argv[1], style, 0);
7333
7334 /* Pass one: Do the realpath/abspath thing and remove anything that fails
7335 or doesn't exists. */
7336 struct nameseq *cur = chain;
7337 struct nameseq *prev = NULL;
7338 while (cur)
7339 {
7340 char *result;
7341#ifdef HAVE_REALPATH
7342 ENULLLOOP (result, realpath (cur->name, outbuf));
7343#else
7344 result = abspath (cur->name, outbuf);
7345#endif
7346 if (result)
7347 {
7348 struct stat st;
7349 int r;
7350 EINTRLOOP (r, stat (outbuf, &st));
7351 if (r == 0)
7352 {
7353 free ((char *)cur->name);
7354 cur->name = xstrdup (result);
7355 prev = cur;
7356 cur = cur->next;
7357 }
7358 else
7359 cur = helper_unlink_and_free_ns(cur, prev, &chain);
7360 }
7361 else
7362 cur = helper_unlink_and_free_ns(cur, prev, &chain);
7363 }
7364
7365 /* Pass two: Output. */
7366 return helper_return_and_free_chain (o, chain, style);
7367}
7368
7369/* $(qwildcard path1 .. pathN [, style]) - same as $(wildcard ), except files
7370 rather than space delimited word tokens. See func_wildcard(). */
7371
7372static char *
7373func_q_wildcard (char *o, char **argv, const char *funcname UNUSED)
7374{
7375 unsigned int const style = helper_file_quoting_style (argv[0], Q_QDEFAULT);
7376 struct nameseq *chain = helper_parse_file_list (argv[1], style, 1 /*glob*/);
7377#ifdef _AMIGA
7378 OS (fatal, NILF, _("$(%s ) is not implemented on this platform"), funcname);
7379#endif
7380 return helper_return_and_free_chain (o, chain, style);
7381}
7382
7383#endif /* KMK */
7384
7385
7386/* Lookup table for builtin functions.
7387
7388 This doesn't have to be sorted; we use a straight lookup. We might gain
7389 some efficiency by moving most often used functions to the start of the
7390 table.
7391
7392 If MAXIMUM_ARGS is 0, that means there is no maximum and all
7393 comma-separated values are treated as arguments.
7394
7395 EXPAND_ARGS means that all arguments should be expanded before invocation.
7396 Functions that do namespace tricks (foreach) don't automatically expand. */
7397
7398static char *func_call (char *o, char **argv, const char *funcname);
7399
7400#define FT_ENTRY(_name, _min, _max, _exp, _func) \
7401 { { (_func) }, STRING_SIZE_TUPLE(_name), (_min), (_max), (_exp), 0 }
7402
7403static struct function_table_entry function_table_init[] =
7404{
7405 /* Name MIN MAX EXP? Function */
7406 FT_ENTRY ("abspath", 0, 1, 1, func_abspath),
7407 FT_ENTRY ("addprefix", 2, 2, 1, func_addsuffix_addprefix),
7408 FT_ENTRY ("addsuffix", 2, 2, 1, func_addsuffix_addprefix),
7409 FT_ENTRY ("basename", 0, 1, 1, func_basename_dir),
7410 FT_ENTRY ("dir", 0, 1, 1, func_basename_dir),
7411 FT_ENTRY ("notdir", 0, 1, 1, func_notdir_suffix),
7412#ifdef CONFIG_WITH_ROOT_FUNC
7413 FT_ENTRY ("root", 0, 1, 1, func_root),
7414 FT_ENTRY ("notroot", 0, 1, 1, func_notroot),
7415#endif
7416 FT_ENTRY ("subst", 3, 3, 1, func_subst),
7417 FT_ENTRY ("suffix", 0, 1, 1, func_notdir_suffix),
7418 FT_ENTRY ("filter", 2, 2, 1, func_filter_filterout),
7419 FT_ENTRY ("filter-out", 2, 2, 1, func_filter_filterout),
7420 FT_ENTRY ("findstring", 2, 2, 1, func_findstring),
7421#ifdef CONFIG_WITH_DEFINED_FUNCTIONS
7422 FT_ENTRY ("firstdefined", 0, 2, 1, func_firstdefined),
7423#endif
7424 FT_ENTRY ("firstword", 0, 1, 1, func_firstword),
7425 FT_ENTRY ("flavor", 0, 1, 1, func_flavor),
7426 FT_ENTRY ("join", 2, 2, 1, func_join),
7427#ifdef CONFIG_WITH_DEFINED_FUNCTIONS
7428 FT_ENTRY ("lastdefined", 0, 2, 1, func_lastdefined),
7429#endif
7430 FT_ENTRY ("lastword", 0, 1, 1, func_lastword),
7431 FT_ENTRY ("patsubst", 3, 3, 1, func_patsubst),
7432 FT_ENTRY ("realpath", 0, 1, 1, func_realpath),
7433#ifdef CONFIG_WITH_RSORT
7434 FT_ENTRY ("rsort", 0, 1, 1, func_sort),
7435# ifdef KMK
7436 FT_ENTRY ("rversort", 0, 1, 1, func_sort),
7437# endif
7438#endif
7439 FT_ENTRY ("shell", 0, 1, 1, func_shell),
7440 FT_ENTRY ("sort", 0, 1, 1, func_sort),
7441# ifdef KMK
7442 FT_ENTRY ("versort", 0, 1, 1, func_sort),
7443# endif
7444 FT_ENTRY ("strip", 0, 1, 1, func_strip),
7445#ifdef CONFIG_WITH_WHERE_FUNCTION
7446 FT_ENTRY ("where", 0, 1, 1, func_where),
7447#endif
7448 FT_ENTRY ("wildcard", 0, 1, 1, func_wildcard),
7449 FT_ENTRY ("word", 2, 2, 1, func_word),
7450 FT_ENTRY ("wordlist", 3, 3, 1, func_wordlist),
7451 FT_ENTRY ("words", 0, 1, 1, func_words),
7452 FT_ENTRY ("origin", 0, 1, 1, func_origin),
7453 FT_ENTRY ("foreach", 3, 3, 0, func_foreach),
7454#ifdef CONFIG_WITH_LOOP_FUNCTIONS
7455 FT_ENTRY ("for", 4, 4, 0, func_for),
7456 FT_ENTRY ("while", 2, 2, 0, func_while),
7457#endif
7458 FT_ENTRY ("call", 1, 0, 1, func_call),
7459 FT_ENTRY ("info", 0, 1, 1, func_error),
7460 FT_ENTRY ("error", 0, 1, 1, func_error),
7461 FT_ENTRY ("warning", 0, 1, 1, func_error),
7462 FT_ENTRY ("if", 2, 3, 0, func_if),
7463 FT_ENTRY ("or", 1, 0, 0, func_or),
7464 FT_ENTRY ("and", 1, 0, 0, func_and),
7465 FT_ENTRY ("value", 0, 1, 1, func_value),
7466#ifdef EXPERIMENTAL
7467 FT_ENTRY ("eq", 2, 2, 1, func_eq),
7468 FT_ENTRY ("not", 0, 1, 1, func_not),
7469#endif
7470 FT_ENTRY ("eval", 0, 1, 1, func_eval),
7471#ifdef CONFIG_WITH_EVALPLUS
7472 FT_ENTRY ("evalctx", 0, 1, 1, func_evalctx),
7473 FT_ENTRY ("evalval", 1, 1, 1, func_evalval),
7474 FT_ENTRY ("evalvalctx", 1, 1, 1, func_evalval),
7475 FT_ENTRY ("evalcall", 1, 0, 1, func_call),
7476 FT_ENTRY ("evalcall2", 1, 0, 1, func_call),
7477 FT_ENTRY ("eval-opt-var", 1, 0, 1, func_eval_optimize_variable),
7478#endif
7479 FT_ENTRY ("file", 1, 2, 1, func_file),
7480#ifdef CONFIG_WITH_STRING_FUNCTIONS
7481 FT_ENTRY ("length", 1, 1, 1, func_length),
7482 FT_ENTRY ("length-var", 1, 1, 1, func_length_var),
7483 FT_ENTRY ("insert", 2, 5, 1, func_insert),
7484 FT_ENTRY ("pos", 2, 3, 1, func_pos),
7485 FT_ENTRY ("lastpos", 2, 3, 1, func_pos),
7486 FT_ENTRY ("substr", 2, 4, 1, func_substr),
7487 FT_ENTRY ("translate", 2, 4, 1, func_translate),
7488#endif
7489#ifdef CONFIG_WITH_PRINTF
7490 FT_ENTRY ("printf", 1, 0, 1, kmk_builtin_func_printf),
7491#endif
7492#ifdef CONFIG_WITH_LAZY_DEPS_VARS
7493 FT_ENTRY ("deps", 1, 2, 1, func_deps),
7494 FT_ENTRY ("deps-all", 1, 2, 1, func_deps),
7495 FT_ENTRY ("deps-newer", 1, 2, 1, func_deps_newer),
7496 FT_ENTRY ("deps-oo", 1, 2, 1, func_deps_order_only),
7497#endif
7498#ifdef CONFIG_WITH_DEFINED
7499 FT_ENTRY ("defined", 1, 1, 1, func_defined),
7500#endif
7501#ifdef CONFIG_WITH_TOUPPER_TOLOWER
7502 FT_ENTRY ("toupper", 0, 1, 1, func_toupper_tolower),
7503 FT_ENTRY ("tolower", 0, 1, 1, func_toupper_tolower),
7504#endif
7505#ifdef CONFIG_WITH_ABSPATHEX
7506 FT_ENTRY ("abspathex", 0, 2, 1, func_abspathex),
7507#endif
7508#ifdef CONFIG_WITH_XARGS
7509 FT_ENTRY ("xargs", 2, 0, 1, func_xargs),
7510#endif
7511#if defined(CONFIG_WITH_VALUE_LENGTH) && defined(CONFIG_WITH_COMPARE)
7512 FT_ENTRY ("comp-vars", 3, 3, 1, func_comp_vars),
7513 FT_ENTRY ("comp-cmds", 3, 3, 1, func_comp_vars),
7514 FT_ENTRY ("comp-cmds-ex", 3, 3, 1, func_comp_cmds_ex),
7515#endif
7516#ifdef CONFIG_WITH_DATE
7517 FT_ENTRY ("date", 0, 1, 1, func_date),
7518 FT_ENTRY ("date-utc", 0, 3, 1, func_date),
7519#endif
7520#ifdef CONFIG_WITH_FILE_SIZE
7521 FT_ENTRY ("file-size", 1, 1, 1, func_file_size),
7522#endif
7523#ifdef CONFIG_WITH_WHICH
7524 FT_ENTRY ("which", 0, 0, 1, func_which),
7525#endif
7526#ifdef CONFIG_WITH_IF_CONDITIONALS
7527 FT_ENTRY ("expr", 1, 1, 0, func_expr),
7528 FT_ENTRY ("if-expr", 2, 3, 0, func_if_expr),
7529 FT_ENTRY ("select", 2, 0, 0, func_select),
7530#endif
7531#ifdef CONFIG_WITH_SET_CONDITIONALS
7532 FT_ENTRY ("intersects", 2, 2, 1, func_set_intersects),
7533#endif
7534#ifdef CONFIG_WITH_STACK
7535 FT_ENTRY ("stack-push", 2, 2, 1, func_stack_push),
7536 FT_ENTRY ("stack-pop", 1, 1, 1, func_stack_pop_top),
7537 FT_ENTRY ("stack-popv", 1, 1, 1, func_stack_pop_top),
7538 FT_ENTRY ("stack-top", 1, 1, 1, func_stack_pop_top),
7539#endif
7540#ifdef CONFIG_WITH_MATH
7541 FT_ENTRY ("int-add", 2, 0, 1, func_int_add),
7542 FT_ENTRY ("int-sub", 2, 0, 1, func_int_sub),
7543 FT_ENTRY ("int-mul", 2, 0, 1, func_int_mul),
7544 FT_ENTRY ("int-div", 2, 0, 1, func_int_div),
7545 FT_ENTRY ("int-mod", 2, 2, 1, func_int_mod),
7546 FT_ENTRY ("int-not", 1, 1, 1, func_int_not),
7547 FT_ENTRY ("int-and", 2, 0, 1, func_int_and),
7548 FT_ENTRY ("int-or", 2, 0, 1, func_int_or),
7549 FT_ENTRY ("int-xor", 2, 0, 1, func_int_xor),
7550 FT_ENTRY ("int-eq", 2, 2, 1, func_int_cmp),
7551 FT_ENTRY ("int-ne", 2, 2, 1, func_int_cmp),
7552 FT_ENTRY ("int-gt", 2, 2, 1, func_int_cmp),
7553 FT_ENTRY ("int-ge", 2, 2, 1, func_int_cmp),
7554 FT_ENTRY ("int-lt", 2, 2, 1, func_int_cmp),
7555 FT_ENTRY ("int-le", 2, 2, 1, func_int_cmp),
7556#endif
7557#ifdef CONFIG_WITH_NANOTS
7558 FT_ENTRY ("nanots", 0, 0, 0, func_nanots),
7559#endif
7560#ifdef CONFIG_WITH_OS2_LIBPATH
7561 FT_ENTRY ("libpath", 1, 2, 1, func_os2_libpath),
7562#endif
7563#if defined (CONFIG_WITH_MAKE_STATS) || defined (CONFIG_WITH_MINIMAL_STATS)
7564 FT_ENTRY ("make-stats", 0, 0, 0, func_make_stats),
7565#endif
7566#ifdef CONFIG_WITH_COMMANDS_FUNC
7567 FT_ENTRY ("commands", 1, 1, 1, func_commands),
7568 FT_ENTRY ("commands-sc", 1, 1, 1, func_commands),
7569 FT_ENTRY ("commands-usr", 2, 2, 1, func_commands),
7570#endif
7571#ifdef KMK_HELPERS
7572 FT_ENTRY ("kb-src-tool", 1, 2, 0, func_kbuild_source_tool),
7573 FT_ENTRY ("kb-obj-base", 1, 2, 0, func_kbuild_object_base),
7574 FT_ENTRY ("kb-obj-suff", 1, 2, 0, func_kbuild_object_suffix),
7575 FT_ENTRY ("kb-src-prop", 3, 4, 0, func_kbuild_source_prop),
7576 FT_ENTRY ("kb-src-one", 0, 1, 0, func_kbuild_source_one),
7577 FT_ENTRY ("kb-exp-tmpl", 6, 6, 1, func_kbuild_expand_template),
7578#endif
7579#ifdef KMK
7580 FT_ENTRY ("dircache-ctl", 1, 0, 1, func_dircache_ctl),
7581 FT_ENTRY ("breakpoint", 0, 0, 0, func_breakpoint),
7582 FT_ENTRY ("set-umask", 1, 3, 1, func_set_umask),
7583 FT_ENTRY ("get-umask", 0, 0, 0, func_get_umask),
7584#endif
7585#ifdef KMK
7586 FT_ENTRY ("quote", 1, 0, 1, func_quote_make),
7587 FT_ENTRY ("quote-dep", 1, 0, 1, func_quote_make),
7588 FT_ENTRY ("quote-tgt", 1, 0, 1, func_quote_make),
7589 FT_ENTRY ("quote-depend", 1, 0, 1, func_quote_make),
7590 FT_ENTRY ("quote-tgtend", 1, 0, 1, func_quote_make),
7591 FT_ENTRY ("quote-sh", 1, 0, 1, func_quote_shell),
7592 FT_ENTRY ("quote-sh-dq", 1, 1, 1, func_quote_shell_dq),
7593 FT_ENTRY ("quote-sh-sq", 1, 1, 1, func_quote_shell_sq),
7594 FT_ENTRY ("requote", 1, 0, 1, func_requote),
7595 /* Quoted input and maybe output variants of functions typically
7596 working with files: */
7597 FT_ENTRY ("firstfile", 0, 1, 1, func_firstfile),
7598 FT_ENTRY ("lastfile", 0, 1, 1, func_lastfile),
7599 FT_ENTRY ("filelist", 3, 3, 1, func_filelist),
7600 FT_ENTRY ("countfiles", 0, 1, 1, func_countfiles),
7601 FT_ENTRY ("foreachfile", 3, 3, 0, func_foreachfile),
7602 FT_ENTRY ("sortfiles", 0, 1, 1, func_sortfiles),
7603 FT_ENTRY ("versortfiles", 0, 1, 1, func_sortfiles),
7604# ifdef CONFIG_WITH_RSORT
7605 FT_ENTRY ("rsortfiles", 0, 1, 1, func_sortfiles),
7606 FT_ENTRY ("rversortfiles", 0, 1, 1, func_sortfiles),
7607# endif
7608 /* Function variants with preceding style argument and quoting by default. */
7609 FT_ENTRY ("qfirstfile", 1+0, 1+1, 1, func_q_firstfile),
7610 FT_ENTRY ("qlastfile", 1+0, 1+1, 1, func_q_lastfile),
7611 FT_ENTRY ("qfilelist", 1+3, 1+3, 1, func_q_filelist),
7612 FT_ENTRY ("qcountfiles", 1+0, 1+1, 1, func_q_countfiles),
7613 FT_ENTRY ("qforeachfile", 1+3, 1+3, 0, func_q_foreachfile),
7614 FT_ENTRY ("qsortfiles", 1+0, 1+1, 1, func_q_sortfiles),
7615 FT_ENTRY ("qversortfiles",1+0, 1+1, 1, func_q_sortfiles),
7616# ifdef CONFIG_WITH_RSORT
7617 FT_ENTRY ("qrsortfiles", 1+0, 1+1, 1, func_q_sortfiles),
7618 FT_ENTRY ("qrversortfiles",1+0,1+1, 1, func_q_sortfiles),
7619# endif
7620 FT_ENTRY ("qabspath", 1+0, 1+1, 1, func_q_abspath),
7621 FT_ENTRY ("qaddprefix", 1+2, 1+2, 1, func_q_addsuffix_addprefix),
7622 FT_ENTRY ("qaddsuffix", 1+2, 1+2, 1, func_q_addsuffix_addprefix),
7623 FT_ENTRY ("qbasename", 1+0, 1+1, 1, func_q_basename_dir),
7624 FT_ENTRY ("qdir", 1+0, 1+1, 1, func_q_basename_dir),
7625 FT_ENTRY ("qnotdir", 1+0, 1+1, 1, func_q_notdir),
7626# ifdef CONFIG_WITH_ROOT_FUNC
7627 FT_ENTRY ("qroot", 1+0, 1+1, 1, func_q_root),
7628 FT_ENTRY ("qnotroot", 1+0, 1+1, 1, func_q_notroot),
7629# endif
7630 FT_ENTRY ("qsuffix", 1+0, 1+1, 1, func_q_suffix),
7631 FT_ENTRY ("qrealpath", 1+0, 1+1, 1, func_q_realpath),
7632# ifdef CONFIG_WITH_ABSPATHEX
7633 FT_ENTRY ("qabspathex", 1+0, 1+2, 1, func_q_abspathex),
7634# endif
7635 FT_ENTRY ("qwildcard", 1+0, 1+1, 1, func_q_wildcard),
7636/** @todo XXX: Add more qxxxx variants. */
7637#endif
7638};
7639
7640#define FUNCTION_TABLE_ENTRIES (sizeof (function_table_init) / sizeof (struct function_table_entry))
7641
7642
7643
7644/* These must come after the definition of function_table. */
7645
7646static char *
7647expand_builtin_function (char *o, int argc, char **argv,
7648 const struct function_table_entry *entry_p)
7649{
7650 char *p;
7651
7652 if (argc < (int)entry_p->minimum_args)
7653 fatal (*expanding_var, strlen (entry_p->name),
7654 _("insufficient number of arguments (%d) to function '%s'"),
7655 argc, entry_p->name);
7656
7657 /* I suppose technically some function could do something with no arguments,
7658 but so far no internal ones do, so just test it for all functions here
7659 rather than in each one. We can change it later if necessary. */
7660
7661 if (!argc && !entry_p->alloc_fn)
7662 return o;
7663
7664 if (!entry_p->fptr.func_ptr)
7665 OS (fatal, *expanding_var,
7666 _("unimplemented on this platform: function '%s'"), entry_p->name);
7667
7668 if (!entry_p->alloc_fn)
7669 return entry_p->fptr.func_ptr (o, argv, entry_p->name);
7670
7671 /* This function allocates memory and returns it to us.
7672 Write it to the variable buffer, then free it. */
7673
7674 p = entry_p->fptr.alloc_func_ptr (entry_p->name, argc, argv);
7675 if (p)
7676 {
7677 o = variable_buffer_output (o, p, strlen (p));
7678 free (p);
7679 }
7680
7681 return o;
7682}
7683
7684/* Check for a function invocation in *STRINGP. *STRINGP points at the
7685 opening ( or { and is not null-terminated. If a function invocation
7686 is found, expand it into the buffer at *OP, updating *OP, incrementing
7687 *STRINGP past the reference and returning nonzero. If not, return zero. */
7688
7689static int
7690handle_function2 (const struct function_table_entry *entry_p, char **op, const char **stringp) /* bird split it up. */
7691{
7692 char openparen = (*stringp)[0];
7693 char closeparen = openparen == '(' ? ')' : '}';
7694 const char *beg;
7695 const char *end;
7696 int count = 0;
7697 char *abeg = NULL;
7698 char **argv, **argvp;
7699 int nargs;
7700
7701 beg = *stringp + 1;
7702
7703 /* We found a builtin function. Find the beginning of its arguments (skip
7704 whitespace after the name). */
7705
7706 beg += entry_p->len;
7707 NEXT_TOKEN (beg);
7708
7709 /* Find the end of the function invocation, counting nested use of
7710 whichever kind of parens we use. Since we're looking, count commas
7711 to get a rough estimate of how many arguments we might have. The
7712 count might be high, but it'll never be low. */
7713
7714 for (nargs=1, end=beg; *end != '\0'; ++end)
7715 if (*end == ',')
7716 ++nargs;
7717 else if (*end == openparen)
7718 ++count;
7719 else if (*end == closeparen && --count < 0)
7720 break;
7721
7722 if (count >= 0)
7723 fatal (*expanding_var, strlen (entry_p->name),
7724 _("unterminated call to function '%s': missing '%c'"),
7725 entry_p->name, closeparen);
7726
7727 *stringp = end;
7728
7729 /* Get some memory to store the arg pointers. */
7730 argvp = argv = alloca (sizeof (char *) * (nargs + 2));
7731
7732 /* Chop the string into arguments, then a nul. As soon as we hit
7733 MAXIMUM_ARGS (if it's >0) assume the rest of the string is part of the
7734 last argument.
7735
7736 If we're expanding, store pointers to the expansion of each one. If
7737 not, make a duplicate of the string and point into that, nul-terminating
7738 each argument. */
7739
7740 if (entry_p->expand_args)
7741 {
7742 const char *p;
7743 for (p=beg, nargs=0; p <= end; ++argvp)
7744 {
7745 const char *next;
7746
7747 ++nargs;
7748
7749 if (nargs == entry_p->maximum_args
7750 || (! (next = find_next_argument (openparen, closeparen, p, end))))
7751 next = end;
7752
7753 *argvp = expand_argument (p, next);
7754 p = next + 1;
7755 }
7756 }
7757 else
7758 {
7759 int len = end - beg;
7760 char *p, *aend;
7761
7762 abeg = xmalloc (len+1);
7763 memcpy (abeg, beg, len);
7764 abeg[len] = '\0';
7765 aend = abeg + len;
7766
7767 for (p=abeg, nargs=0; p <= aend; ++argvp)
7768 {
7769 char *next;
7770
7771 ++nargs;
7772
7773 if (nargs == entry_p->maximum_args
7774 || (! (next = find_next_argument (openparen, closeparen, p, aend))))
7775 next = aend;
7776
7777 *argvp = p;
7778 *next = '\0';
7779 p = next + 1;
7780 }
7781 }
7782 *argvp = NULL;
7783
7784 /* Finally! Run the function... */
7785 *op = expand_builtin_function (*op, nargs, argv, entry_p);
7786
7787 /* Free memory. */
7788 if (entry_p->expand_args)
7789 for (argvp=argv; *argvp != 0; ++argvp)
7790 free (*argvp);
7791 else
7792 free (abeg);
7793
7794 return 1;
7795}
7796
7797
7798int /* bird split it up and hacked it. */
7799#ifndef CONFIG_WITH_VALUE_LENGTH
7800handle_function (char **op, const char **stringp)
7801{
7802 const struct function_table_entry *entry_p = lookup_function (*stringp + 1);
7803 if (!entry_p)
7804 return 0;
7805 return handle_function2 (entry_p, op, stringp);
7806}
7807#else /* CONFIG_WITH_VALUE_LENGTH */
7808handle_function (char **op, const char **stringp, const char *nameend, const char *eol UNUSED)
7809{
7810 const char *fname = *stringp + 1;
7811 const struct function_table_entry *entry_p =
7812 lookup_function_in_hash_tab (fname, nameend - fname);
7813 if (!entry_p)
7814 return 0;
7815 return handle_function2 (entry_p, op, stringp);
7816}
7817#endif /* CONFIG_WITH_VALUE_LENGTH */
7818
7819#ifdef CONFIG_WITH_COMPILER
7820/* Used by the "compiler" to get all info about potential functions. */
7821make_function_ptr_t
7822lookup_function_for_compiler (const char *name, unsigned int len,
7823 unsigned char *minargsp, unsigned char *maxargsp,
7824 char *expargsp, const char **funcnamep)
7825{
7826 const struct function_table_entry *entry_p = lookup_function (name, len);
7827 if (!entry_p)
7828 return 0;
7829 *minargsp = entry_p->minimum_args;
7830 *maxargsp = entry_p->maximum_args;
7831 *expargsp = entry_p->expand_args;
7832 *funcnamep = entry_p->name;
7833 return entry_p->func_ptr;
7834}
7835#endif /* CONFIG_WITH_COMPILER */
7836
7837
7838
7839/* User-defined functions. Expand the first argument as either a builtin
7840 function or a make variable, in the context of the rest of the arguments
7841 assigned to $1, $2, ... $N. $0 is the name of the function. */
7842
7843static char *
7844func_call (char *o, char **argv, const char *funcname UNUSED)
7845{
7846 static int max_args = 0;
7847 char *fname;
7848 char *body;
7849 int flen;
7850 int i;
7851 int saved_args;
7852 const struct function_table_entry *entry_p;
7853 struct variable *v;
7854#ifdef CONFIG_WITH_EVALPLUS
7855 char *buf;
7856 unsigned int len;
7857#endif
7858#ifdef CONFIG_WITH_VALUE_LENGTH
7859 char *fname_end;
7860#endif
7861#if defined (CONFIG_WITH_EVALPLUS) || defined (CONFIG_WITH_VALUE_LENGTH)
7862 char num[11];
7863#endif
7864
7865 /* Clean up the name of the variable to be invoked. */
7866 fname = next_token (argv[0]);
7867#ifndef CONFIG_WITH_VALUE_LENGTH
7868 end_of_token (fname)[0] = '\0';
7869#else
7870 fname_end = end_of_token (fname);
7871 *fname_end = '\0';
7872#endif
7873
7874 /* Calling nothing is a no-op */
7875#ifndef CONFIG_WITH_VALUE_LENGTH
7876 if (*fname == '\0')
7877#else
7878 if (fname == fname_end)
7879#endif
7880 return o;
7881
7882 /* Are we invoking a builtin function? */
7883
7884#ifndef CONFIG_WITH_VALUE_LENGTH
7885 entry_p = lookup_function (fname);
7886#else
7887 entry_p = lookup_function (fname, fname_end - fname);
7888#endif
7889 if (entry_p)
7890 {
7891 /* How many arguments do we have? */
7892 for (i=0; argv[i+1]; ++i)
7893 ;
7894 return expand_builtin_function (o, i, argv+1, entry_p);
7895 }
7896
7897 /* Not a builtin, so the first argument is the name of a variable to be
7898 expanded and interpreted as a function. Find it. */
7899 flen = strlen (fname);
7900
7901 v = lookup_variable (fname, flen);
7902
7903 if (v == 0)
7904 warn_undefined (fname, flen);
7905
7906 if (v == 0 || *v->value == '\0')
7907 return o;
7908
7909 body = alloca (flen + 4);
7910 body[0] = '$';
7911 body[1] = '(';
7912 memcpy (body + 2, fname, flen);
7913 body[flen+2] = ')';
7914 body[flen+3] = '\0';
7915
7916 /* Set up arguments $(1) .. $(N). $(0) is the function name. */
7917
7918 push_new_variable_scope ();
7919
7920 for (i=0; *argv; ++i, ++argv)
7921#ifdef CONFIG_WITH_VALUE_LENGTH
7922 define_variable (num, sprintf (num, "%d", i), *argv, o_automatic, 0);
7923#else
7924 {
7925 char num[11];
7926
7927 sprintf (num, "%d", i);
7928 define_variable (num, strlen (num), *argv, o_automatic, 0);
7929 }
7930#endif
7931
7932#ifdef CONFIG_WITH_EVALPLUS
7933 /* $(.ARGC) is the argument count. */
7934
7935 len = sprintf (num, "%d", i - 1);
7936 define_variable_vl (".ARGC", sizeof (".ARGC") - 1, num, len,
7937 1 /* dup val */, o_automatic, 0);
7938#endif
7939
7940 /* If the number of arguments we have is < max_args, it means we're inside
7941 a recursive invocation of $(call ...). Fill in the remaining arguments
7942 in the new scope with the empty value, to hide them from this
7943 invocation. */
7944
7945 for (; i < max_args; ++i)
7946#ifdef CONFIG_WITH_VALUE_LENGTH
7947 define_variable (num, sprintf (num, "%d", i), "", o_automatic, 0);
7948#else
7949 {
7950 char num[11];
7951
7952 sprintf (num, "%d", i);
7953 define_variable (num, strlen (num), "", o_automatic, 0);
7954 }
7955#endif
7956
7957 saved_args = max_args;
7958 max_args = i;
7959
7960#ifdef CONFIG_WITH_EVALPLUS
7961 if (!strcmp (funcname, "call"))
7962 {
7963#endif
7964 /* Expand the body in the context of the arguments, adding the result to
7965 the variable buffer. */
7966
7967 v->exp_count = EXP_COUNT_MAX;
7968#ifndef CONFIG_WITH_VALUE_LENGTH
7969 o = variable_expand_string (o, body, flen+3);
7970 v->exp_count = 0;
7971
7972 o += strlen (o);
7973#else /* CONFIG_WITH_VALUE_LENGTH */
7974 variable_expand_string_2 (o, body, flen+3, &o);
7975 v->exp_count = 0;
7976#endif /* CONFIG_WITH_VALUE_LENGTH */
7977#ifdef CONFIG_WITH_EVALPLUS
7978 }
7979 else
7980 {
7981 const floc *reading_file_saved = reading_file;
7982 char *eos;
7983
7984 if (!strcmp (funcname, "evalcall"))
7985 {
7986 /* Evaluate the variable value without expanding it. We
7987 need a copy since eval_buffer is destructive. */
7988
7989 size_t off = o - variable_buffer;
7990 eos = variable_buffer_output (o, v->value, v->value_length + 1) - 1;
7991 o = variable_buffer + off;
7992 if (v->fileinfo.filenm)
7993 reading_file = &v->fileinfo;
7994 }
7995 else
7996 {
7997 /* Expand the body first and then evaluate the output. */
7998
7999 v->exp_count = EXP_COUNT_MAX;
8000 o = variable_expand_string_2 (o, body, flen+3, &eos);
8001 v->exp_count = 0;
8002 }
8003
8004 install_variable_buffer (&buf, &len);
8005 eval_buffer (o, NULL, eos);
8006 restore_variable_buffer (buf, len);
8007 reading_file = reading_file_saved;
8008
8009 /* Deal with the .RETURN value if present. */
8010
8011 v = lookup_variable_in_set (".RETURN", sizeof (".RETURN") - 1,
8012 current_variable_set_list->set);
8013 if (v && v->value_length)
8014 {
8015 if (v->recursive && !IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR (v))
8016 {
8017 v->exp_count = EXP_COUNT_MAX;
8018 variable_expand_string_2 (o, v->value, v->value_length, &o);
8019 v->exp_count = 0;
8020 }
8021 else
8022 o = variable_buffer_output (o, v->value, v->value_length);
8023 }
8024 }
8025#endif /* CONFIG_WITH_EVALPLUS */
8026
8027 max_args = saved_args;
8028
8029 pop_variable_scope ();
8030
8031 return o;
8032}
8033
8034void
8035define_new_function (const floc *flocp, const char *name,
8036 unsigned int min, unsigned int max, unsigned int flags,
8037 gmk_func_ptr func)
8038{
8039 const char *e = name;
8040 struct function_table_entry *ent;
8041 size_t len;
8042
8043 while (STOP_SET (*e, MAP_USERFUNC))
8044 e++;
8045 len = e - name;
8046
8047 if (len == 0)
8048 O (fatal, flocp, _("Empty function name"));
8049 if (*name == '.' || *e != '\0')
8050 OS (fatal, flocp, _("Invalid function name: %s"), name);
8051 if (len > 255)
8052 OS (fatal, flocp, _("Function name too long: %s"), name);
8053 if (min > 255)
8054 ONS (fatal, flocp,
8055 _("Invalid minimum argument count (%u) for function %s"), min, name);
8056 if (max > 255 || (max && max < min))
8057 ONS (fatal, flocp,
8058 _("Invalid maximum argument count (%u) for function %s"), max, name);
8059
8060 ent = xmalloc (sizeof (struct function_table_entry));
8061 ent->name = name;
8062 ent->len = len;
8063 ent->minimum_args = min;
8064 ent->maximum_args = max;
8065 ent->expand_args = ANY_SET(flags, GMK_FUNC_NOEXPAND) ? 0 : 1;
8066 ent->alloc_fn = 1;
8067 ent->fptr.alloc_func_ptr = func;
8068
8069 hash_insert (&function_table, ent);
8070}
8071
8072void
8073hash_init_function_table (void)
8074{
8075 hash_init (&function_table, FUNCTION_TABLE_ENTRIES * 2,
8076 function_table_entry_hash_1, function_table_entry_hash_2,
8077 function_table_entry_hash_cmp);
8078 hash_load (&function_table, function_table_init,
8079 FUNCTION_TABLE_ENTRIES, sizeof (struct function_table_entry));
8080#if defined (CONFIG_WITH_OPTIMIZATION_HACKS) || defined (CONFIG_WITH_VALUE_LENGTH)
8081 {
8082 unsigned int i;
8083 for (i = 0; i < FUNCTION_TABLE_ENTRIES; i++)
8084 {
8085 const char *fn = function_table_init[i].name;
8086 while (*fn)
8087 {
8088 func_char_map[(int)*fn] = 1;
8089 fn++;
8090 }
8091 assert (function_table_init[i].len <= MAX_FUNCTION_LENGTH);
8092 assert (function_table_init[i].len >= MIN_FUNCTION_LENGTH);
8093 }
8094 }
8095#endif
8096}
Note: See TracBrowser for help on using the repository browser.

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