source: trunk/src/kmk/function.c@ 3186

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

kmk: replaced w32ify() as it uses unsafe static buffer and encourages buffer size assumptions.

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