VirtualBox

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

Last change on this file since 3140 was 3140, checked in by bird, 7 years ago

kmk: Merged in changes from GNU make 4.2.1 (2e55f5e4abdc0e38c1d64be703b446695e70b3b6 / https://git.savannah.gnu.org/git/make.git).

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

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