VirtualBox

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

Last change on this file since 3387 was 3359, checked in by bird, 4 years ago

kmk,kFsCache: Added variant of kFsCacheInvalidateAll that also closes directory handles, we need to do this befor ere-executing kmk after having remake some include file we needed. It messes up fetching otherwise.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use