VirtualBox

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

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

kmk/win: Some fixes & docs.

  • 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 = w32ify((char *)name, 1);
2879 if (!dest)
2880 return NULL;
2881 {
2882 size_t len = strlen(dest);
2883 memcpy(apath, dest, len);
2884 dest = apath + len;
2885 }
2886
2887 (void)end; (void)start; (void)apath_limit;
2888
2889#elif defined __OS2__ /* bird */
2890 if (_abspath(apath, name, GET_PATH_MAX))
2891 return NULL;
2892 dest = strchr(apath, '\0');
2893
2894 (void)end; (void)start; (void)apath_limit; (void)dest;
2895
2896#else /* !WINDOWS32 && !__OS2__ */
2897 apath_limit = apath + GET_PATH_MAX;
2898
2899 if (!IS_ABSOLUTE(name))
2900 {
2901 /* It is unlikely we would make it until here but just to make sure. */
2902 if (!starting_directory)
2903 return NULL;
2904
2905 strcpy (apath, starting_directory);
2906
2907#ifdef HAVE_DOS_PATHS
2908 if (STOP_SET (name[0], MAP_DIRSEP))
2909 {
2910 if (STOP_SET (name[1], MAP_DIRSEP))
2911 {
2912 /* A UNC. Don't prepend a drive letter. */
2913 apath[0] = name[0];
2914 apath[1] = name[1];
2915 root_len = 2;
2916 }
2917 /* We have /foo, an absolute file name except for the drive
2918 letter. Assume the missing drive letter is the current
2919 drive, which we can get if we remove from starting_directory
2920 everything past the root directory. */
2921 apath[root_len] = '\0';
2922 }
2923#endif
2924
2925 dest = strchr (apath, '\0');
2926 }
2927 else
2928 {
2929#if defined(__CYGWIN__) && defined(HAVE_DOS_PATHS)
2930 if (STOP_SET (name[0], MAP_DIRSEP))
2931 root_len = 1;
2932#endif
2933 strncpy (apath, name, root_len);
2934 apath[root_len] = '\0';
2935 dest = apath + root_len;
2936 /* Get past the root, since we already copied it. */
2937 name += root_len;
2938#ifdef HAVE_DOS_PATHS
2939 if (! STOP_SET (apath[root_len - 1], MAP_DIRSEP))
2940 {
2941 /* Convert d:foo into d:./foo and increase root_len. */
2942 apath[2] = '.';
2943 apath[3] = '/';
2944 dest++;
2945 root_len++;
2946 /* strncpy above copied one character too many. */
2947 name--;
2948 }
2949 else
2950 apath[root_len - 1] = '/'; /* make sure it's a forward slash */
2951#endif
2952 }
2953
2954 for (start = end = name; *start != '\0'; start = end)
2955 {
2956 unsigned long len;
2957
2958 /* Skip sequence of multiple path-separators. */
2959 while (STOP_SET (*start, MAP_DIRSEP))
2960 ++start;
2961
2962 /* Find end of path component. */
2963 for (end = start; ! STOP_SET (*end, MAP_DIRSEP|MAP_NUL); ++end)
2964 ;
2965
2966 len = end - start;
2967
2968 if (len == 0)
2969 break;
2970 else if (len == 1 && start[0] == '.')
2971 /* nothing */;
2972 else if (len == 2 && start[0] == '.' && start[1] == '.')
2973 {
2974 /* Back up to previous component, ignore if at root already. */
2975 if (dest > apath + root_len)
2976 for (--dest; ! STOP_SET (dest[-1], MAP_DIRSEP); --dest)
2977 ;
2978 }
2979 else
2980 {
2981 if (! STOP_SET (dest[-1], MAP_DIRSEP))
2982 *dest++ = '/';
2983
2984 if (dest + len >= apath_limit)
2985 return NULL;
2986
2987 dest = memcpy (dest, start, len);
2988 dest += len;
2989 *dest = '\0';
2990 }
2991 }
2992#endif /* !WINDOWS32 && !__OS2__ */
2993
2994 /* Unless it is root strip trailing separator. */
2995 if (dest > apath + root_len && STOP_SET (dest[-1], MAP_DIRSEP))
2996 --dest;
2997
2998 *dest = '\0';
2999
3000 return apath;
3001}
3002
3003
3004static char *
3005func_realpath (char *o, char **argv, const char *funcname UNUSED)
3006{
3007 /* Expand the argument. */
3008 const char *p = argv[0];
3009 const char *path = 0;
3010 int doneany = 0;
3011 unsigned int len = 0;
3012
3013 while ((path = find_next_token (&p, &len)) != 0)
3014 {
3015 if (len < GET_PATH_MAX)
3016 {
3017 char *rp;
3018 struct stat st;
3019 PATH_VAR (in);
3020 PATH_VAR (out);
3021
3022 strncpy (in, path, len);
3023 in[len] = '\0';
3024
3025#ifdef HAVE_REALPATH
3026 ENULLLOOP (rp, realpath (in, out));
3027#else
3028 rp = abspath (in, out);
3029#endif
3030
3031 if (rp)
3032 {
3033 int r;
3034 EINTRLOOP (r, stat (out, &st));
3035 if (r == 0)
3036 {
3037 o = variable_buffer_output (o, out, strlen (out));
3038 o = variable_buffer_output (o, " ", 1);
3039 doneany = 1;
3040 }
3041 }
3042 }
3043 }
3044
3045 /* Kill last space. */
3046 if (doneany)
3047 --o;
3048
3049 return o;
3050}
3051
3052static char *
3053func_file (char *o, char **argv, const char *funcname UNUSED)
3054{
3055 char *fn = argv[0];
3056
3057 if (fn[0] == '>')
3058 {
3059 FILE *fp;
3060#ifdef KMK_FOPEN_NO_INHERIT_MODE
3061 const char *mode = "w" KMK_FOPEN_NO_INHERIT_MODE;
3062#else
3063 const char *mode = "w";
3064#endif
3065
3066 /* We are writing a file. */
3067 ++fn;
3068 if (fn[0] == '>')
3069 {
3070#ifdef KMK_FOPEN_NO_INHERIT_MODE
3071 mode = "a" KMK_FOPEN_NO_INHERIT_MODE;
3072#else
3073 mode = "a";
3074#endif
3075 ++fn;
3076 }
3077 NEXT_TOKEN (fn);
3078
3079 if (fn[0] == '\0')
3080 O (fatal, *expanding_var, _("file: missing filename"));
3081
3082 ENULLLOOP (fp, fopen (fn, mode));
3083 if (fp == NULL)
3084 OSS (fatal, reading_file, _("open: %s: %s"), fn, strerror (errno));
3085
3086 if (argv[1])
3087 {
3088 int l = strlen (argv[1]);
3089 int nl = l == 0 || argv[1][l-1] != '\n';
3090
3091 if (fputs (argv[1], fp) == EOF || (nl && fputc ('\n', fp) == EOF))
3092 OSS (fatal, reading_file, _("write: %s: %s"), fn, strerror (errno));
3093 }
3094 if (fclose (fp))
3095 OSS (fatal, reading_file, _("close: %s: %s"), fn, strerror (errno));
3096 }
3097 else if (fn[0] == '<')
3098 {
3099 char *preo = o;
3100 FILE *fp;
3101
3102 ++fn;
3103 NEXT_TOKEN (fn);
3104 if (fn[0] == '\0')
3105 O (fatal, *expanding_var, _("file: missing filename"));
3106
3107 if (argv[1])
3108 O (fatal, *expanding_var, _("file: too many arguments"));
3109
3110#ifdef KMK_FOPEN_NO_INHERIT_MODE
3111 ENULLLOOP (fp, fopen (fn, "r" KMK_FOPEN_NO_INHERIT_MODE));
3112#else
3113 ENULLLOOP (fp, fopen (fn, "r"));
3114#endif
3115 if (fp == NULL)
3116 {
3117 if (errno == ENOENT)
3118 return o;
3119 OSS (fatal, reading_file, _("open: %s: %s"), fn, strerror (errno));
3120 }
3121
3122 while (1)
3123 {
3124 char buf[1024];
3125 size_t l = fread (buf, 1, sizeof (buf), fp);
3126 if (l > 0)
3127 o = variable_buffer_output (o, buf, l);
3128
3129 if (ferror (fp))
3130 if (errno != EINTR)
3131 OSS (fatal, reading_file, _("read: %s: %s"), fn, strerror (errno));
3132 if (feof (fp))
3133 break;
3134 }
3135 if (fclose (fp))
3136 OSS (fatal, reading_file, _("close: %s: %s"), fn, strerror (errno));
3137
3138 /* Remove trailing newline. */
3139 if (o > preo && o[-1] == '\n')
3140 if (--o > preo && o[-1] == '\r')
3141 --o;
3142 }
3143 else
3144 OS (fatal, *expanding_var, _("file: invalid file operation: %s"), fn);
3145
3146 return o;
3147}
3148
3149static char *
3150func_abspath (char *o, char **argv, const char *funcname UNUSED)
3151{
3152 /* Expand the argument. */
3153 const char *p = argv[0];
3154 const char *path = 0;
3155 int doneany = 0;
3156 unsigned int len = 0;
3157
3158 while ((path = find_next_token (&p, &len)) != 0)
3159 {
3160 if (len < GET_PATH_MAX)
3161 {
3162 PATH_VAR (in);
3163 PATH_VAR (out);
3164
3165 strncpy (in, path, len);
3166 in[len] = '\0';
3167
3168 if (abspath (in, out))
3169 {
3170 o = variable_buffer_output (o, out, strlen (out));
3171 o = variable_buffer_output (o, " ", 1);
3172 doneany = 1;
3173 }
3174 }
3175 }
3176
3177 /* Kill last space. */
3178 if (doneany)
3179 --o;
3180
3181 return o;
3182}
3183
3184#ifdef CONFIG_WITH_ABSPATHEX
3185/* Same as abspath except that the current path may be given as the
3186 2nd argument. */
3187static char *
3188func_abspathex (char *o, char **argv, const char *funcname UNUSED)
3189{
3190 char *cwd = argv[1];
3191
3192 /* cwd needs leading spaces chopped and may be optional,
3193 in which case we're exactly like $(abspath ). */
3194 if (cwd)
3195 while (ISBLANK (*cwd))
3196 cwd++;
3197 if (!cwd || !*cwd)
3198 o = func_abspath (o, argv, funcname);
3199 else
3200 {
3201 /* Expand the argument. */
3202 const char *p = argv[0];
3203 unsigned int cwd_len = ~0U;
3204 char *path = 0;
3205 int doneany = 0;
3206 unsigned int len = 0;
3207 PATH_VAR (in);
3208 PATH_VAR (out);
3209
3210 while ((path = find_next_token (&p, &len)) != 0)
3211 {
3212 if (len < GET_PATH_MAX)
3213 {
3214#ifdef HAVE_DOS_PATHS
3215 if (path[0] != '/' && path[0] != '\\' && (len < 2 || path[1] != ':') && cwd)
3216#else
3217 if (path[0] != '/' && cwd)
3218#endif
3219 {
3220 /* relative path, prefix with cwd. */
3221 if (cwd_len == ~0U)
3222 cwd_len = strlen (cwd);
3223 if (cwd_len + len + 1 >= GET_PATH_MAX)
3224 continue;
3225 memcpy (in, cwd, cwd_len);
3226 in[cwd_len] = '/';
3227 memcpy (in + cwd_len + 1, path, len);
3228 in[cwd_len + len + 1] = '\0';
3229 }
3230 else
3231 {
3232 /* absolute path pass it as-is. */
3233 memcpy (in, path, len);
3234 in[len] = '\0';
3235 }
3236
3237 if (abspath (in, out))
3238 {
3239 o = variable_buffer_output (o, out, strlen (out));
3240 o = variable_buffer_output (o, " ", 1);
3241 doneany = 1;
3242 }
3243 }
3244 }
3245
3246 /* Kill last space. */
3247 if (doneany)
3248 --o;
3249 }
3250
3251 return o;
3252}
3253#endif
3254
3255#ifdef CONFIG_WITH_XARGS
3256/* Create one or more command lines avoiding the max argument
3257 length restriction of the host OS.
3258
3259 The last argument is the list of arguments that the normal
3260 xargs command would be fed from stdin.
3261
3262 The first argument is initial command and it's arguments.
3263
3264 If there are three or more arguments, the 2nd argument is
3265 the command and arguments to be used on subsequent
3266 command lines. Defaults to the initial command.
3267
3268 If there are four or more arguments, the 3rd argument is
3269 the command to be used at the final command line. Defaults
3270 to the sub sequent or initial command .
3271
3272 A future version of this function may define more arguments
3273 and therefor anyone specifying six or more arguments will
3274 cause fatal errors.
3275
3276 Typical usage is:
3277 $(xargs ar cas mylib.a,$(objects))
3278 or
3279 $(xargs ar cas mylib.a,ar as mylib.a,$(objects))
3280
3281 It will then create one or more "ar mylib.a ..." command
3282 lines with proper \n\t separation so it can be used when
3283 writing rules. */
3284static char *
3285func_xargs (char *o, char **argv, const char *funcname UNUSED)
3286{
3287 int argc;
3288 const char *initial_cmd;
3289 size_t initial_cmd_len;
3290 const char *subsequent_cmd;
3291 size_t subsequent_cmd_len;
3292 const char *final_cmd;
3293 size_t final_cmd_len;
3294 const char *args;
3295 size_t max_args;
3296 int i;
3297
3298#ifdef ARG_MAX
3299 /* ARG_MAX is a bit unreliable (environment), so drop 25% of the max. */
3300# define XARGS_MAX (ARG_MAX - (ARG_MAX / 4))
3301#else /* FIXME: update configure with a command line length test. */
3302# define XARGS_MAX 10240
3303#endif
3304
3305 argc = 0;
3306 while (argv[argc])
3307 argc++;
3308 if (argc > 4)
3309 O (fatal, NILF, _("Too many arguments for $(xargs)!\n"));
3310
3311 /* first: the initial / default command.*/
3312 initial_cmd = argv[0];
3313 while (ISSPACE (*initial_cmd))
3314 initial_cmd++;
3315 max_args = initial_cmd_len = strlen (initial_cmd);
3316
3317 /* second: the command for the subsequent command lines. defaults to the initial cmd. */
3318 subsequent_cmd = argc > 2 && argv[1][0] != '\0' ? argv[1] : "\0";
3319 while (ISSPACE (*subsequent_cmd))
3320 subsequent_cmd++; /* gcc 7.3.0 complains "offset ‘1’ outside bounds of constant string" if constant is "" rather than "\0". */
3321 if (*subsequent_cmd)
3322 {
3323 subsequent_cmd_len = strlen (subsequent_cmd);
3324 if (subsequent_cmd_len > max_args)
3325 max_args = subsequent_cmd_len;
3326 }
3327 else
3328 {
3329 subsequent_cmd = initial_cmd;
3330 subsequent_cmd_len = initial_cmd_len;
3331 }
3332
3333 /* third: the final command. defaults to the subseq cmd. */
3334 final_cmd = argc > 3 && argv[2][0] != '\0' ? argv[2] : "\0";
3335 while (ISSPACE (*final_cmd))
3336 final_cmd++; /* gcc 7.3.0: same complaint as for subsequent_cmd++ */
3337 if (*final_cmd)
3338 {
3339 final_cmd_len = strlen (final_cmd);
3340 if (final_cmd_len > max_args)
3341 max_args = final_cmd_len;
3342 }
3343 else
3344 {
3345 final_cmd = subsequent_cmd;
3346 final_cmd_len = subsequent_cmd_len;
3347 }
3348
3349 /* last: the arguments to split up into sensible portions. */
3350 args = argv[argc - 1];
3351
3352 /* calc the max argument length. */
3353 if (XARGS_MAX <= max_args + 2)
3354 ONN (fatal, NILF, _("$(xargs): the commands are longer than the max exec argument length. (%lu <= %lu)\n"),
3355 (unsigned long)XARGS_MAX, (unsigned long)max_args + 2);
3356 max_args = XARGS_MAX - max_args - 1;
3357
3358 /* generate the commands. */
3359 i = 0;
3360 for (i = 0; ; i++)
3361 {
3362 unsigned int len;
3363 const char *iterator = args;
3364 const char *end = args;
3365 const char *cur;
3366 const char *tmp;
3367
3368 /* scan the arguments till we reach the end or the max length. */
3369 while ((cur = find_next_token(&iterator, &len))
3370 && (size_t)((cur + len) - args) < max_args)
3371 end = cur + len;
3372 if (cur && end == args)
3373 O (fatal, NILF, _("$(xargs): command + one single arg is too much. giving up.\n"));
3374
3375 /* emit the command. */
3376 if (i == 0)
3377 {
3378 o = variable_buffer_output (o, (char *)initial_cmd, initial_cmd_len);
3379 o = variable_buffer_output (o, " ", 1);
3380 }
3381 else if (cur)
3382 {
3383 o = variable_buffer_output (o, "\n\t", 2);
3384 o = variable_buffer_output (o, (char *)subsequent_cmd, subsequent_cmd_len);
3385 o = variable_buffer_output (o, " ", 1);
3386 }
3387 else
3388 {
3389 o = variable_buffer_output (o, "\n\t", 2);
3390 o = variable_buffer_output (o, (char *)final_cmd, final_cmd_len);
3391 o = variable_buffer_output (o, " ", 1);
3392 }
3393
3394 tmp = end;
3395 while (tmp > args && ISSPACE (tmp[-1])) /* drop trailing spaces. */
3396 tmp--;
3397 o = variable_buffer_output (o, (char *)args, tmp - args);
3398
3399
3400 /* next */
3401 if (!cur)
3402 break;
3403 args = end;
3404 while (ISSPACE (*args))
3405 args++;
3406 }
3407
3408 return o;
3409}
3410#endif
3411
3412
3413#ifdef CONFIG_WITH_STRING_FUNCTIONS
3414/*
3415 $(length string)
3416
3417 XXX: This doesn't take multibyte locales into account.
3418 */
3419static char *
3420func_length (char *o, char **argv, const char *funcname UNUSED)
3421{
3422 size_t len = strlen (argv[0]);
3423 return math_int_to_variable_buffer (o, len);
3424}
3425
3426/*
3427 $(length-var var)
3428
3429 XXX: This doesn't take multibyte locales into account.
3430 */
3431static char *
3432func_length_var (char *o, char **argv, const char *funcname UNUSED)
3433{
3434 struct variable *var = lookup_variable (argv[0], strlen (argv[0]));
3435 return math_int_to_variable_buffer (o, var ? var->value_length : 0);
3436}
3437
3438
3439/* func_insert and func_substr helper. */
3440static char *
3441helper_pad (char *o, size_t to_add, const char *pad, size_t pad_len)
3442{
3443 while (to_add > 0)
3444 {
3445 size_t size = to_add > pad_len ? pad_len : to_add;
3446 o = variable_buffer_output (o, pad, size);
3447 to_add -= size;
3448 }
3449 return o;
3450}
3451
3452/*
3453 $(insert in, str[, n[, length[, pad]]])
3454
3455 XXX: This doesn't take multibyte locales into account.
3456 */
3457static char *
3458func_insert (char *o, char **argv, const char *funcname UNUSED)
3459{
3460 const char *in = argv[0];
3461 math_int in_len = (math_int)strlen (in);
3462 const char *str = argv[1];
3463 math_int str_len = (math_int)strlen (str);
3464 math_int n = 0;
3465 math_int length = str_len;
3466 const char *pad = " ";
3467 size_t pad_len = 16;
3468 size_t i;
3469
3470 if (argv[2] != NULL)
3471 {
3472 n = math_int_from_string (argv[2]);
3473 if (n > 0)
3474 n--; /* one-origin */
3475 else if (n == 0)
3476 n = str_len; /* append */
3477 else
3478 { /* n < 0: from the end */
3479 n = str_len + n;
3480 if (n < 0)
3481 n = 0;
3482 }
3483 if (n > 16*1024*1024) /* 16MB */
3484 OS (fatal, NILF, _("$(insert ): n=%s is out of bounds\n"), argv[2]);
3485
3486 if (argv[3] != NULL)
3487 {
3488 length = math_int_from_string (argv[3]);
3489 if (length < 0 || length > 16*1024*1024 /* 16MB */)
3490 OS (fatal, NILF, _("$(insert ): length=%s is out of bounds\n"), argv[3]);
3491
3492 if (argv[4] != NULL)
3493 {
3494 const char *tmp = argv[4];
3495 for (i = 0; tmp[i] == ' '; i++)
3496 /* nothing */;
3497 if (tmp[i] != '\0')
3498 {
3499 pad = argv[4];
3500 pad_len = strlen (pad);
3501 }
3502 /* else: it was all default spaces. */
3503 }
3504 }
3505 }
3506
3507 /* the head of the original string */
3508 if (n > 0)
3509 {
3510 if (n <= str_len)
3511 o = variable_buffer_output (o, str, n);
3512 else
3513 {
3514 o = variable_buffer_output (o, str, str_len);
3515 o = helper_pad (o, n - str_len, pad, pad_len);
3516 }
3517 }
3518
3519 /* insert the string */
3520 if (length <= in_len)
3521 o = variable_buffer_output (o, in, length);
3522 else
3523 {
3524 o = variable_buffer_output (o, in, in_len);
3525 o = helper_pad (o, length - in_len, pad, pad_len);
3526 }
3527
3528 /* the tail of the original string */
3529 if (n < str_len)
3530 o = variable_buffer_output (o, str + n, str_len - n);
3531
3532 return o;
3533}
3534
3535
3536/*
3537 $(pos needle, haystack[, start])
3538 $(lastpos needle, haystack[, start])
3539
3540 XXX: This doesn't take multibyte locales into account.
3541 */
3542static char *
3543func_pos (char *o, char **argv, const char *funcname UNUSED)
3544{
3545 const char *needle = *argv[0] ? argv[0] : " ";
3546 size_t needle_len = strlen (needle);
3547 const char *haystack = argv[1];
3548 size_t haystack_len = strlen (haystack);
3549 math_int start = 0;
3550 const char *hit;
3551
3552 if (argv[2] != NULL)
3553 {
3554 start = math_int_from_string (argv[2]);
3555 if (start > 0)
3556 start--; /* one-origin */
3557 else if (start < 0)
3558 start = haystack_len + start; /* from the end */
3559 if (start < 0 || start + needle_len > haystack_len)
3560 return math_int_to_variable_buffer (o, 0);
3561 }
3562 else if (funcname[0] == 'l')
3563 start = haystack_len - 1;
3564
3565 /* do the searching */
3566 if (funcname[0] != 'l')
3567 { /* pos */
3568 if (needle_len == 1)
3569 hit = strchr (haystack + start, *needle);
3570 else
3571 hit = strstr (haystack + start, needle);
3572 }
3573 else
3574 { /* last pos */
3575 int ch = *needle;
3576 size_t off = start + 1;
3577
3578 hit = NULL;
3579 while (off-- > 0)
3580 {
3581 if ( haystack[off] == ch
3582 && ( needle_len == 1
3583 || strncmp (&haystack[off], needle, needle_len) == 0))
3584 {
3585 hit = haystack + off;
3586 break;
3587 }
3588 }
3589 }
3590
3591 return math_int_to_variable_buffer (o, hit ? hit - haystack + 1 : 0);
3592}
3593
3594
3595/*
3596 $(substr str, start[, length[, pad]])
3597
3598 XXX: This doesn't take multibyte locales into account.
3599 */
3600static char *
3601func_substr (char *o, char **argv, const char *funcname UNUSED)
3602{
3603 const char *str = argv[0];
3604 math_int str_len = (math_int)strlen (str);
3605 math_int start = math_int_from_string (argv[1]);
3606 math_int length = 0;
3607 const char *pad = NULL;
3608 size_t pad_len = 0;
3609
3610 if (argv[2] != NULL)
3611 {
3612 if (argv[3] != NULL)
3613 {
3614 pad = argv[3];
3615 for (pad_len = 0; pad[pad_len] == ' '; pad_len++)
3616 /* nothing */;
3617 if (pad[pad_len] != '\0')
3618 pad_len = strlen (pad);
3619 else
3620 {
3621 pad = " ";
3622 pad_len = 16;
3623 }
3624 }
3625 length = math_int_from_string (argv[2]);
3626 if (pad != NULL && length > 16*1024*1024 /* 16MB */)
3627 OS (fatal, NILF, _("$(substr ): length=%s is out of bounds\n"), argv[2]);
3628 if (pad != NULL && length < 0)
3629 OS (fatal, NILF, _("$(substr ): negative length (%s) and padding doesn't mix.\n"), argv[2]);
3630 if (length == 0)
3631 return o;
3632 }
3633
3634 /* Note that negative start is and length are used for referencing from the
3635 end of the string. */
3636 if (pad == NULL)
3637 {
3638 if (start > 0)
3639 start--; /* one-origin */
3640 else
3641 {
3642 start = str_len + start;
3643 if (start <= 0)
3644 {
3645 if (length < 0)
3646 return o;
3647 start += length;
3648 if (start <= 0)
3649 return o;
3650 length = start;
3651 start = 0;
3652 }
3653 }
3654
3655 if (start >= str_len)
3656 return o;
3657 if (length == 0)
3658 length = str_len - start;
3659 else if (length < 0)
3660 {
3661 if (str_len <= -length)
3662 return o;
3663 length += str_len;
3664 if (length <= start)
3665 return o;
3666 length -= start;
3667 }
3668 else if (start + length > str_len)
3669 length = str_len - start;
3670
3671 o = variable_buffer_output (o, str + start, length);
3672 }
3673 else
3674 {
3675 if (start > 0)
3676 {
3677 start--; /* one-origin */
3678 if (start >= str_len)
3679 return length ? helper_pad (o, length, pad, pad_len) : o;
3680 if (length == 0)
3681 length = str_len - start;
3682 }
3683 else
3684 {
3685 start = str_len + start;
3686 if (start <= 0)
3687 {
3688 if (start + length <= 0)
3689 return length ? helper_pad (o, length, pad, pad_len) : o;
3690 o = helper_pad (o, -start, pad, pad_len);
3691 return variable_buffer_output (o, str, length + start);
3692 }
3693 if (length == 0)
3694 length = str_len - start;
3695 }
3696 if (start + length <= str_len)
3697 o = variable_buffer_output (o, str + start, length);
3698 else
3699 {
3700 o = variable_buffer_output (o, str + start, str_len - start);
3701 o = helper_pad (o, start + length - str_len, pad, pad_len);
3702 }
3703 }
3704
3705 return o;
3706}
3707
3708
3709/*
3710 $(translate string, from-set[, to-set[, pad-char]])
3711
3712 XXX: This doesn't take multibyte locales into account.
3713 */
3714static char *
3715func_translate (char *o, char **argv, const char *funcname UNUSED)
3716{
3717 const unsigned char *str = (const unsigned char *)argv[0];
3718 const unsigned char *from_set = (const unsigned char *)argv[1];
3719 const char *to_set = argv[2] != NULL ? argv[2] : "";
3720 char trans_tab[1 << CHAR_BIT];
3721 int i;
3722 char ch;
3723
3724 /* init the array. */
3725 for (i = 0; i < (1 << CHAR_BIT); i++)
3726 trans_tab[i] = i;
3727
3728 while ( (i = *from_set) != '\0'
3729 && (ch = *to_set) != '\0')
3730 {
3731 trans_tab[i] = ch;
3732 from_set++;
3733 to_set++;
3734 }
3735
3736 if (i != '\0')
3737 {
3738 ch = '\0'; /* no padding == remove char */
3739 if (argv[2] != NULL && argv[3] != NULL)
3740 {
3741 ch = argv[3][0];
3742 if (ch && argv[3][1])
3743 OS (fatal, NILF, _("$(translate ): pad=`%s' expected a single char\n"), argv[3]);
3744 if (ch == '\0') /* no char == space */
3745 ch = ' ';
3746 }
3747 while ((i = *from_set++) != '\0')
3748 trans_tab[i] = ch;
3749 }
3750
3751 /* do the translation */
3752 while ((i = *str++) != '\0')
3753 {
3754 ch = trans_tab[i];
3755 if (ch)
3756 o = variable_buffer_output (o, &ch, 1);
3757 }
3758
3759 return o;
3760}
3761#endif /* CONFIG_WITH_STRING_FUNCTIONS */
3762
3763
3764#ifdef CONFIG_WITH_LAZY_DEPS_VARS
3765
3766/* This is also in file.c (bad). */
3767# if VMS
3768# define FILE_LIST_SEPARATOR ','
3769# else
3770# define FILE_LIST_SEPARATOR ' '
3771# endif
3772
3773/* Implements $^ and $+.
3774
3775 The first comes with FUNCNAME 'deps', the second as 'deps-all'.
3776
3777 If no second argument is given, or if it's empty, or if it's zero,
3778 all dependencies will be returned. If the second argument is non-zero
3779 the dependency at that position will be returned. If the argument is
3780 negative a fatal error is thrown. */
3781static char *
3782func_deps (char *o, char **argv, const char *funcname)
3783{
3784 unsigned int idx = 0;
3785 struct file *file;
3786
3787 /* Handle the argument if present. */
3788
3789 if (argv[1])
3790 {
3791 char *p = argv[1];
3792 while (ISSPACE (*p))
3793 p++;
3794 if (*p != '\0')
3795 {
3796 char *n;
3797 long l = strtol (p, &n, 0);
3798 while (ISSPACE (*n))
3799 n++;
3800 idx = l;
3801 if (*n != '\0' || l < 0 || (long)idx != l)
3802 OSS (fatal, NILF, _("%s: invalid index value: `%s'\n"), funcname, p);
3803 }
3804 }
3805
3806 /* Find the file and select the list corresponding to FUNCNAME. */
3807
3808 file = lookup_file (argv[0]);
3809 if (file)
3810 {
3811 struct dep *deps;
3812 struct dep *d;
3813 if (funcname[4] == '\0')
3814 {
3815 deps = file->deps_no_dupes;
3816 if (!deps && file->deps)
3817 deps = file->deps = create_uniqute_deps_chain (file->deps);
3818 }
3819 else
3820 deps = file->deps;
3821
3822 if ( file->double_colon
3823 && ( file->double_colon != file
3824 || file->last != file))
3825 OSS (error, NILF, _("$(%s ) cannot be used on files with multiple double colon rules like `%s'\n"),
3826 funcname, file->name);
3827
3828 if (idx == 0 /* all */)
3829 {
3830 unsigned int total_len = 0;
3831
3832 /* calc the result length. */
3833
3834 for (d = deps; d; d = d->next)
3835 if (!d->ignore_mtime)
3836 {
3837 const char *c = dep_name (d);
3838
3839#ifndef NO_ARCHIVES
3840 if (ar_name (c))
3841 {
3842 c = strchr (c, '(') + 1;
3843 total_len += strlen (c);
3844 }
3845 else
3846#elif defined (CONFIG_WITH_STRCACHE2)
3847 total_len += strcache2_get_len (&file_strcache, c) + 1;
3848#else
3849 total_len += strlen (c) + 1;
3850#endif
3851 }
3852
3853 if (total_len)
3854 {
3855 /* prepare the variable buffer dude wrt to the output size and
3856 pass along the strings. */
3857
3858 o = variable_buffer_output (o + total_len, "", 0) - total_len; /* a hack */
3859
3860 for (d = deps; d; d = d->next)
3861 if (!d->ignore_mtime)
3862 {
3863 unsigned int len;
3864 const char *c = dep_name (d);
3865
3866#ifndef NO_ARCHIVES
3867 if (ar_name (c))
3868 {
3869 c = strchr (c, '(') + 1;
3870 len = strlen (c);
3871 }
3872 else
3873#elif defined (CONFIG_WITH_STRCACHE2)
3874 len = strcache2_get_len (&file_strcache, c) + 1;
3875#else
3876 len = strlen (c) + 1;
3877#endif
3878 o = variable_buffer_output (o, c, len);
3879 o[-1] = FILE_LIST_SEPARATOR;
3880 }
3881
3882 --o; /* nuke the last list separator */
3883 *o = '\0';
3884 }
3885 }
3886 else
3887 {
3888 /* Dependency given by index. */
3889
3890 for (d = deps; d; d = d->next)
3891 if (!d->ignore_mtime)
3892 {
3893 if (--idx == 0) /* 1 based indexing */
3894 {
3895 unsigned int len;
3896 const char *c = dep_name (d);
3897
3898#ifndef NO_ARCHIVES
3899 if (ar_name (c))
3900 {
3901 c = strchr (c, '(') + 1;
3902 len = strlen (c) - 1;
3903 }
3904 else
3905#elif defined (CONFIG_WITH_STRCACHE2)
3906 len = strcache2_get_len (&file_strcache, c);
3907#else
3908 len = strlen (c);
3909#endif
3910 o = variable_buffer_output (o, c, len);
3911 break;
3912 }
3913 }
3914 }
3915 }
3916
3917 return o;
3918}
3919
3920/* Implements $?.
3921
3922 If no second argument is given, or if it's empty, or if it's zero,
3923 all dependencies will be returned. If the second argument is non-zero
3924 the dependency at that position will be returned. If the argument is
3925 negative a fatal error is thrown. */
3926static char *
3927func_deps_newer (char *o, char **argv, const char *funcname)
3928{
3929 unsigned int idx = 0;
3930 struct file *file;
3931
3932 /* Handle the argument if present. */
3933
3934 if (argv[1])
3935 {
3936 char *p = argv[1];
3937 while (ISSPACE (*p))
3938 p++;
3939 if (*p != '\0')
3940 {
3941 char *n;
3942 long l = strtol (p, &n, 0);
3943 while (ISSPACE (*n))
3944 n++;
3945 idx = l;
3946 if (*n != '\0' || l < 0 || (long)idx != l)
3947 OSS (fatal, NILF, _("%s: invalid index value: `%s'\n"), funcname, p);
3948 }
3949 }
3950
3951 /* Find the file. */
3952
3953 file = lookup_file (argv[0]);
3954 if (file)
3955 {
3956 struct dep *deps = file->deps;
3957 struct dep *d;
3958
3959 if ( file->double_colon
3960 && ( file->double_colon != file
3961 || file->last != file))
3962 OSS (error, NILF, _("$(%s ) cannot be used on files with multiple double colon rules like `%s'\n"),
3963 funcname, file->name);
3964
3965 if (idx == 0 /* all */)
3966 {
3967 unsigned int total_len = 0;
3968
3969 /* calc the result length. */
3970
3971 for (d = deps; d; d = d->next)
3972 if (!d->ignore_mtime && d->changed)
3973 {
3974 const char *c = dep_name (d);
3975
3976#ifndef NO_ARCHIVES
3977 if (ar_name (c))
3978 {
3979 c = strchr (c, '(') + 1;
3980 total_len += strlen (c);
3981 }
3982 else
3983#elif defined (CONFIG_WITH_STRCACHE2)
3984 total_len += strcache2_get_len (&file_strcache, c) + 1;
3985#else
3986 total_len += strlen (c) + 1;
3987#endif
3988 }
3989
3990 if (total_len)
3991 {
3992 /* prepare the variable buffer dude wrt to the output size and
3993 pass along the strings. */
3994
3995 o = variable_buffer_output (o + total_len, "", 0) - total_len; /* a hack */
3996
3997 for (d = deps; d; d = d->next)
3998 if (!d->ignore_mtime && d->changed)
3999 {
4000 unsigned int len;
4001 const char *c = dep_name (d);
4002
4003#ifndef NO_ARCHIVES
4004 if (ar_name (c))
4005 {
4006 c = strchr (c, '(') + 1;
4007 len = strlen (c);
4008 }
4009 else
4010#elif defined (CONFIG_WITH_STRCACHE2)
4011 len = strcache2_get_len (&file_strcache, c) + 1;
4012#else
4013 len = strlen (c) + 1;
4014#endif
4015 o = variable_buffer_output (o, c, len);
4016 o[-1] = FILE_LIST_SEPARATOR;
4017 }
4018
4019 --o; /* nuke the last list separator */
4020 *o = '\0';
4021 }
4022 }
4023 else
4024 {
4025 /* Dependency given by index. */
4026
4027 for (d = deps; d; d = d->next)
4028 if (!d->ignore_mtime && d->changed)
4029 {
4030 if (--idx == 0) /* 1 based indexing */
4031 {
4032 unsigned int len;
4033 const char *c = dep_name (d);
4034
4035#ifndef NO_ARCHIVES
4036 if (ar_name (c))
4037 {
4038 c = strchr (c, '(') + 1;
4039 len = strlen (c) - 1;
4040 }
4041 else
4042#elif defined (CONFIG_WITH_STRCACHE2)
4043 len = strcache2_get_len (&file_strcache, c);
4044#else
4045 len = strlen (c);
4046#endif
4047 o = variable_buffer_output (o, c, len);
4048 break;
4049 }
4050 }
4051 }
4052 }
4053
4054 return o;
4055}
4056
4057/* Implements $|, the order only dependency list.
4058
4059 If no second argument is given, or if it's empty, or if it's zero,
4060 all dependencies will be returned. If the second argument is non-zero
4061 the dependency at that position will be returned. If the argument is
4062 negative a fatal error is thrown. */
4063static char *
4064func_deps_order_only (char *o, char **argv, const char *funcname)
4065{
4066 unsigned int idx = 0;
4067 struct file *file;
4068
4069 /* Handle the argument if present. */
4070
4071 if (argv[1])
4072 {
4073 char *p = argv[1];
4074 while (ISSPACE (*p))
4075 p++;
4076 if (*p != '\0')
4077 {
4078 char *n;
4079 long l = strtol (p, &n, 0);
4080 while (ISSPACE (*n))
4081 n++;
4082 idx = l;
4083 if (*n != '\0' || l < 0 || (long)idx != l)
4084 OSS (fatal, NILF, _("%s: invalid index value: `%s'\n"), funcname, p);
4085 }
4086 }
4087
4088 /* Find the file. */
4089
4090 file = lookup_file (argv[0]);
4091 if (file)
4092 {
4093 struct dep *deps = file->deps;
4094 struct dep *d;
4095
4096 if ( file->double_colon
4097 && ( file->double_colon != file
4098 || file->last != file))
4099 OSS (error, NILF, _("$(%s ) cannot be used on files with multiple double colon rules like `%s'\n"),
4100 funcname, file->name);
4101
4102 if (idx == 0 /* all */)
4103 {
4104 unsigned int total_len = 0;
4105
4106 /* calc the result length. */
4107
4108 for (d = deps; d; d = d->next)
4109 if (d->ignore_mtime)
4110 {
4111 const char *c = dep_name (d);
4112
4113#ifndef NO_ARCHIVES
4114 if (ar_name (c))
4115 {
4116 c = strchr (c, '(') + 1;
4117 total_len += strlen (c);
4118 }
4119 else
4120#elif defined (CONFIG_WITH_STRCACHE2)
4121 total_len += strcache2_get_len (&file_strcache, c) + 1;
4122#else
4123 total_len += strlen (c) + 1;
4124#endif
4125 }
4126
4127 if (total_len)
4128 {
4129 /* prepare the variable buffer dude wrt to the output size and
4130 pass along the strings. */
4131
4132 o = variable_buffer_output (o + total_len, "", 0) - total_len; /* a hack */
4133
4134 for (d = deps; d; d = d->next)
4135 if (d->ignore_mtime)
4136 {
4137 unsigned int len;
4138 const char *c = dep_name (d);
4139
4140#ifndef NO_ARCHIVES
4141 if (ar_name (c))
4142 {
4143 c = strchr (c, '(') + 1;
4144 len = strlen (c);
4145 }
4146 else
4147#elif defined (CONFIG_WITH_STRCACHE2)
4148 len = strcache2_get_len (&file_strcache, c) + 1;
4149#else
4150 len = strlen (c) + 1;
4151#endif
4152 o = variable_buffer_output (o, c, len);
4153 o[-1] = FILE_LIST_SEPARATOR;
4154 }
4155
4156 --o; /* nuke the last list separator */
4157 *o = '\0';
4158 }
4159 }
4160 else
4161 {
4162 /* Dependency given by index. */
4163
4164 for (d = deps; d; d = d->next)
4165 if (d->ignore_mtime)
4166 {
4167 if (--idx == 0) /* 1 based indexing */
4168 {
4169 unsigned int len;
4170 const char *c = dep_name (d);
4171
4172#ifndef NO_ARCHIVES
4173 if (ar_name (c))
4174 {
4175 c = strchr (c, '(') + 1;
4176 len = strlen (c) - 1;
4177 }
4178 else
4179#elif defined (CONFIG_WITH_STRCACHE2)
4180 len = strcache2_get_len (&file_strcache, c);
4181#else
4182 len = strlen (c);
4183#endif
4184 o = variable_buffer_output (o, c, len);
4185 break;
4186 }
4187 }
4188 }
4189 }
4190
4191 return o;
4192}
4193#endif /* CONFIG_WITH_LAZY_DEPS_VARS */
4194
4195
4196
4197#ifdef CONFIG_WITH_DEFINED
4198/* Similar to ifdef. */
4199static char *
4200func_defined (char *o, char **argv, const char *funcname UNUSED)
4201{
4202 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
4203 int result = v != NULL && *v->value != '\0';
4204 o = variable_buffer_output (o, result ? "1" : "", result);
4205 return o;
4206}
4207#endif /* CONFIG_WITH_DEFINED*/
4208
4209#ifdef CONFIG_WITH_TOUPPER_TOLOWER
4210static char *
4211func_toupper_tolower (char *o, char **argv, const char *funcname)
4212{
4213 /* Expand the argument. */
4214 const char *p = argv[0];
4215 while (*p)
4216 {
4217 /* convert to temporary buffer */
4218 char tmp[256];
4219 unsigned int i;
4220 if (!strcmp(funcname, "toupper"))
4221 for (i = 0; i < sizeof(tmp) && *p; i++, p++)
4222 tmp[i] = toupper(*p);
4223 else
4224 for (i = 0; i < sizeof(tmp) && *p; i++, p++)
4225 tmp[i] = tolower(*p);
4226 o = variable_buffer_output (o, tmp, i);
4227 }
4228
4229 return o;
4230}
4231#endif /* CONFIG_WITH_TOUPPER_TOLOWER */
4232
4233#if defined(CONFIG_WITH_VALUE_LENGTH) && defined(CONFIG_WITH_COMPARE)
4234
4235/* Strip leading spaces and other things off a command. */
4236static const char *
4237comp_cmds_strip_leading (const char *s, const char *e)
4238{
4239 while (s < e)
4240 {
4241 const char ch = *s;
4242 if (!ISBLANK (ch)
4243 && ch != '@'
4244#ifdef CONFIG_WITH_COMMANDS_FUNC
4245 && ch != '%'
4246#endif
4247 && ch != '+'
4248 && ch != '-')
4249 break;
4250 s++;
4251 }
4252 return s;
4253}
4254
4255/* Worker for func_comp_vars() which is called if the comparision failed.
4256 It will do the slow command by command comparision of the commands
4257 when there invoked as comp-cmds. */
4258static char *
4259comp_vars_ne (char *o, const char *s1, const char *e1, const char *s2, const char *e2,
4260 char *ne_retval, const char *funcname)
4261{
4262 /* give up at once if not comp-cmds or comp-cmds-ex. */
4263 if (strcmp (funcname, "comp-cmds") != 0
4264 && strcmp (funcname, "comp-cmds-ex") != 0)
4265 o = variable_buffer_output (o, ne_retval, strlen (ne_retval));
4266 else
4267 {
4268 const char * const s1_start = s1;
4269 int new_cmd = 1;
4270 int diff;
4271 for (;;)
4272 {
4273 /* if it's a new command, strip leading stuff. */
4274 if (new_cmd)
4275 {
4276 s1 = comp_cmds_strip_leading (s1, e1);
4277 s2 = comp_cmds_strip_leading (s2, e2);
4278 new_cmd = 0;
4279 }
4280 if (s1 >= e1 || s2 >= e2)
4281 break;
4282
4283 /*
4284 * Inner compare loop which compares one line.
4285 * FIXME: parse quoting!
4286 */
4287 for (;;)
4288 {
4289 const char ch1 = *s1;
4290 const char ch2 = *s2;
4291 diff = ch1 - ch2;
4292 if (diff)
4293 break;
4294 if (ch1 == '\n')
4295 break;
4296 assert (ch1 != '\r');
4297
4298 /* next */
4299 s1++;
4300 s2++;
4301 if (s1 >= e1 || s2 >= e2)
4302 break;
4303 }
4304
4305 /*
4306 * If we exited because of a difference try to end-of-command
4307 * comparision, e.g. ignore trailing spaces.
4308 */
4309 if (diff)
4310 {
4311 /* strip */
4312 while (s1 < e1 && ISBLANK (*s1))
4313 s1++;
4314 while (s2 < e2 && ISBLANK (*s2))
4315 s2++;
4316 if (s1 >= e1 || s2 >= e2)
4317 break;
4318
4319 /* compare again and check that it's a newline. */
4320 if (*s2 != '\n' || *s1 != '\n')
4321 break;
4322 }
4323 /* Break out if we exited because of EOS. */
4324 else if (s1 >= e1 || s2 >= e2)
4325 break;
4326
4327 /*
4328 * Detect the end of command lines.
4329 */
4330 if (*s1 == '\n')
4331 new_cmd = s1 == s1_start || s1[-1] != '\\';
4332 s1++;
4333 s2++;
4334 }
4335
4336 /*
4337 * Ignore trailing empty lines.
4338 */
4339 if (s1 < e1 || s2 < e2)
4340 {
4341 while (s1 < e1 && (ISBLANK (*s1) || *s1 == '\n'))
4342 if (*s1++ == '\n')
4343 s1 = comp_cmds_strip_leading (s1, e1);
4344 while (s2 < e2 && (ISBLANK (*s2) || *s2 == '\n'))
4345 if (*s2++ == '\n')
4346 s2 = comp_cmds_strip_leading (s2, e2);
4347 }
4348
4349 /* emit the result. */
4350 if (s1 == e1 && s2 == e2)
4351 o = variable_buffer_output (o, "", 1) - 1; /** @todo check why this was necessary back the... */
4352 else
4353 o = variable_buffer_output (o, ne_retval, strlen (ne_retval));
4354 }
4355 return o;
4356}
4357
4358/*
4359 $(comp-vars var1,var2,not-equal-return)
4360 or
4361 $(comp-cmds cmd-var1,cmd-var2,not-equal-return)
4362
4363 Compares the two variables (that's given by name to avoid unnecessary
4364 expanding) and return the string in the third argument if not equal.
4365 If equal, nothing is returned.
4366
4367 comp-vars will to an exact comparision only stripping leading and
4368 trailing spaces.
4369
4370 comp-cmds will compare command by command, ignoring not only leading
4371 and trailing spaces on each line but also leading one leading '@',
4372 '-', '+' and '%'
4373*/
4374static char *
4375func_comp_vars (char *o, char **argv, const char *funcname)
4376{
4377 const char *s1, *e1, *x1, *s2, *e2, *x2;
4378 char *a1 = NULL, *a2 = NULL;
4379 size_t l, l1, l2;
4380 struct variable *var1 = lookup_variable (argv[0], strlen (argv[0]));
4381 struct variable *var2 = lookup_variable (argv[1], strlen (argv[1]));
4382
4383 /* the simple cases */
4384 if (var1 == var2)
4385 return variable_buffer_output (o, "", 0); /* eq */
4386 if (!var1 || !var2)
4387 return variable_buffer_output (o, argv[2], strlen(argv[2]));
4388 if (var1->value == var2->value)
4389 return variable_buffer_output (o, "", 0); /* eq */
4390 if ( (!var1->recursive || IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR (var1))
4391 && (!var2->recursive || IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR (var2)) )
4392 {
4393 if ( var1->value_length == var2->value_length
4394 && !memcmp (var1->value, var2->value, var1->value_length))
4395 return variable_buffer_output (o, "", 0); /* eq */
4396
4397 /* ignore trailing and leading blanks */
4398 s1 = var1->value;
4399 e1 = s1 + var1->value_length;
4400 while (ISBLANK (*s1))
4401 s1++;
4402 while (e1 > s1 && ISBLANK (e1[-1]))
4403 e1--;
4404
4405 s2 = var2->value;
4406 e2 = s2 + var2->value_length;
4407 while (ISBLANK (*s2))
4408 s2++;
4409 while (e2 > s2 && ISBLANK (e2[-1]))
4410 e2--;
4411
4412 if (e1 - s1 != e2 - s2)
4413 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4414 if (!memcmp (s1, s2, e1 - s1))
4415 return variable_buffer_output (o, "", 0); /* eq */
4416 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4417 }
4418
4419 /* ignore trailing and leading blanks */
4420 s1 = var1->value;
4421 e1 = s1 + var1->value_length;
4422 while (ISBLANK (*s1))
4423 s1++;
4424 while (e1 > s1 && ISBLANK (e1[-1]))
4425 e1--;
4426
4427 s2 = var2->value;
4428 e2 = s2 + var2->value_length;
4429 while (ISBLANK (*s2))
4430 s2++;
4431 while (e2 > s2 && ISBLANK (e2[-1]))
4432 e2--;
4433
4434 /* both empty after stripping? */
4435 if (s1 == e1 && s2 == e2)
4436 return variable_buffer_output (o, "", 0); /* eq */
4437
4438 /* optimist. */
4439 if ( e1 - s1 == e2 - s2
4440 && !memcmp(s1, s2, e1 - s1))
4441 return variable_buffer_output (o, "", 0); /* eq */
4442
4443 /* compare up to the first '$' or the end. */
4444 x1 = var1->recursive ? memchr (s1, '$', e1 - s1) : NULL;
4445 x2 = var2->recursive ? memchr (s2, '$', e2 - s2) : NULL;
4446 if (!x1 && !x2)
4447 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4448
4449 l1 = x1 ? x1 - s1 : e1 - s1;
4450 l2 = x2 ? x2 - s2 : e2 - s2;
4451 l = l1 <= l2 ? l1 : l2;
4452 if (l && memcmp (s1, s2, l))
4453 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4454
4455 /* one or both buffers now require expanding. */
4456 if (!x1)
4457 s1 += l;
4458 else
4459 {
4460 s1 = a1 = allocated_variable_expand ((char *)s1 + l);
4461 if (!l)
4462 while (ISBLANK (*s1))
4463 s1++;
4464 e1 = strchr (s1, '\0');
4465 while (e1 > s1 && ISBLANK (e1[-1]))
4466 e1--;
4467 }
4468
4469 if (!x2)
4470 s2 += l;
4471 else
4472 {
4473 s2 = a2 = allocated_variable_expand ((char *)s2 + l);
4474 if (!l)
4475 while (ISBLANK (*s2))
4476 s2++;
4477 e2 = strchr (s2, '\0');
4478 while (e2 > s2 && ISBLANK (e2[-1]))
4479 e2--;
4480 }
4481
4482 /* the final compare */
4483 if ( e1 - s1 != e2 - s2
4484 || memcmp (s1, s2, e1 - s1))
4485 o = comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4486 else
4487 o = variable_buffer_output (o, "", 1) - 1; /* eq */ /** @todo check why this was necessary back the... */
4488 if (a1)
4489 free (a1);
4490 if (a2)
4491 free (a2);
4492 return o;
4493}
4494
4495/*
4496 $(comp-cmds-ex cmds1,cmds2,not-equal-return)
4497
4498 Compares the two strings and return the string in the third argument
4499 if not equal. If equal, nothing is returned.
4500
4501 The comparision will be performed command by command, ignoring not
4502 only leading and trailing spaces on each line but also leading one
4503 leading '@', '-', '+' and '%'.
4504*/
4505static char *
4506func_comp_cmds_ex (char *o, char **argv, const char *funcname)
4507{
4508 const char *s1, *e1, *s2, *e2;
4509 size_t l1, l2;
4510
4511 /* the simple cases */
4512 s1 = argv[0];
4513 s2 = argv[1];
4514 if (s1 == s2)
4515 return variable_buffer_output (o, "", 0); /* eq */
4516 l1 = strlen (argv[0]);
4517 l2 = strlen (argv[1]);
4518
4519 if ( l1 == l2
4520 && !memcmp (s1, s2, l1))
4521 return variable_buffer_output (o, "", 0); /* eq */
4522
4523 /* ignore trailing and leading blanks */
4524 e1 = s1 + l1;
4525 s1 = comp_cmds_strip_leading (s1, e1);
4526
4527 e2 = s2 + l2;
4528 s2 = comp_cmds_strip_leading (s2, e2);
4529
4530 if (e1 - s1 != e2 - s2)
4531 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4532 if (!memcmp (s1, s2, e1 - s1))
4533 return variable_buffer_output (o, "", 0); /* eq */
4534 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4535}
4536#endif
4537
4538#ifdef CONFIG_WITH_DATE
4539# if defined (_MSC_VER) /* FIXME: !defined (HAVE_STRPTIME) */
4540char *strptime(const char *s, const char *format, struct tm *tm)
4541{
4542 return (char *)"strptime is not implemented";
4543}
4544# endif
4545/* Check if the string is all blanks or not. */
4546static int
4547all_blanks (const char *s)
4548{
4549 if (!s)
4550 return 1;
4551 while (ISSPACE (*s))
4552 s++;
4553 return *s == '\0';
4554}
4555
4556/* The first argument is the strftime format string, a iso
4557 timestamp is the default if nothing is given.
4558
4559 The second argument is a time value if given. The format
4560 is either the format from the first argument or given as
4561 an additional third argument. */
4562static char *
4563func_date (char *o, char **argv, const char *funcname)
4564{
4565 char *p;
4566 char *buf;
4567 size_t buf_size;
4568 struct tm t;
4569 const char *format;
4570
4571 /* determin the format - use a single word as the default. */
4572 format = !strcmp (funcname, "date-utc")
4573 ? "%Y-%m-%dT%H:%M:%SZ"
4574 : "%Y-%m-%dT%H:%M:%S";
4575 if (!all_blanks (argv[0]))
4576 format = argv[0];
4577
4578 /* get the time. */
4579 memset (&t, 0, sizeof(t));
4580 if (argv[0] && !all_blanks (argv[1]))
4581 {
4582 const char *input_format = !all_blanks (argv[2]) ? argv[2] : format;
4583 p = strptime (argv[1], input_format, &t);
4584 if (!p || *p != '\0')
4585 {
4586 OSSSS (error, NILF, _("$(%s): strptime(%s,%s,) -> %s\n"), funcname,
4587 argv[1], input_format, p ? p : "<null>");
4588 return variable_buffer_output (o, "", 0);
4589 }
4590 }
4591 else
4592 {
4593 time_t tval;
4594 time (&tval);
4595 if (!strcmp (funcname, "date-utc"))
4596 t = *gmtime (&tval);
4597 else
4598 t = *localtime (&tval);
4599 }
4600
4601 /* format it. note that zero isn't necessarily an error, so we'll
4602 have to keep shut about failures. */
4603 buf_size = 64;
4604 buf = xmalloc (buf_size);
4605 while (strftime (buf, buf_size, format, &t) == 0)
4606 {
4607 if (buf_size >= 4096)
4608 {
4609 *buf = '\0';
4610 break;
4611 }
4612 buf = xrealloc (buf, buf_size <<= 1);
4613 }
4614 o = variable_buffer_output (o, buf, strlen (buf));
4615 free (buf);
4616 return o;
4617}
4618#endif
4619
4620#ifdef CONFIG_WITH_FILE_SIZE
4621/* Prints the size of the specified file. Only one file is
4622 permitted, notthing is stripped. -1 is returned if stat
4623 fails. */
4624static char *
4625func_file_size (char *o, char **argv, const char *funcname UNUSED)
4626{
4627 struct stat st;
4628 if (stat (argv[0], &st))
4629 return variable_buffer_output (o, "-1", 2);
4630 return math_int_to_variable_buffer (o, st.st_size);
4631}
4632#endif
4633
4634#ifdef CONFIG_WITH_WHICH
4635/* Checks if the specified file exists an is executable.
4636 On systems employing executable extensions, the name may
4637 be modified to include the extension. */
4638static int func_which_test_x (char *file)
4639{
4640 struct stat st;
4641# if defined(WINDOWS32) || defined(__OS2__)
4642 char *ext;
4643 char *slash;
4644
4645 /* fix slashes first. */
4646 slash = file;
4647 while ((slash = strchr (slash, '\\')) != NULL)
4648 *slash++ = '/';
4649
4650 /* straight */
4651 if (stat (file, &st) == 0
4652 && S_ISREG (st.st_mode))
4653 return 1;
4654
4655 /* don't try add an extension if there already is one */
4656 ext = strchr (file, '\0');
4657 if (ext - file >= 4
4658 && ( !stricmp (ext - 4, ".exe")
4659 || !stricmp (ext - 4, ".cmd")
4660 || !stricmp (ext - 4, ".bat")
4661 || !stricmp (ext - 4, ".com")))
4662 return 0;
4663
4664 /* try the extensions. */
4665 strcpy (ext, ".exe");
4666 if (stat (file, &st) == 0
4667 && S_ISREG (st.st_mode))
4668 return 1;
4669
4670 strcpy (ext, ".cmd");
4671 if (stat (file, &st) == 0
4672 && S_ISREG (st.st_mode))
4673 return 1;
4674
4675 strcpy (ext, ".bat");
4676 if (stat (file, &st) == 0
4677 && S_ISREG (st.st_mode))
4678 return 1;
4679
4680 strcpy (ext, ".com");
4681 if (stat (file, &st) == 0
4682 && S_ISREG (st.st_mode))
4683 return 1;
4684
4685 return 0;
4686
4687# else
4688
4689 return access (file, X_OK) == 0
4690 && stat (file, &st) == 0
4691 && S_ISREG (st.st_mode);
4692# endif
4693}
4694
4695/* Searches for the specified programs in the PATH and print
4696 their full location if found. Prints nothing if not found. */
4697static char *
4698func_which (char *o, char **argv, const char *funcname UNUSED)
4699{
4700 const char *path;
4701 struct variable *path_var;
4702 unsigned i;
4703 int first = 1;
4704 PATH_VAR (buf);
4705
4706 path_var = lookup_variable ("PATH", 4);
4707 if (path_var)
4708 path = path_var->value;
4709 else
4710 path = ".";
4711
4712 /* iterate input */
4713 for (i = 0; argv[i]; i++)
4714 {
4715 unsigned int len;
4716 const char *iterator = argv[i];
4717 char *cur;
4718
4719 while ((cur = find_next_token (&iterator, &len)))
4720 {
4721 /* if there is a separator, don't walk the path. */
4722 if (memchr (cur, '/', len)
4723#ifdef HAVE_DOS_PATHS
4724 || memchr (cur, '\\', len)
4725 || memchr (cur, ':', len)
4726#endif
4727 )
4728 {
4729 if (len + 1 + 4 < GET_PATH_MAX) /* +4 for .exe */
4730 {
4731 memcpy (buf, cur, len);
4732 buf[len] = '\0';
4733 if (func_which_test_x (buf))
4734 o = variable_buffer_output (o, buf, strlen (buf));
4735 }
4736 }
4737 else
4738 {
4739 const char *comp = path;
4740 for (;;)
4741 {
4742 const char *src = comp;
4743 const char *end = strchr (comp, PATH_SEPARATOR_CHAR);
4744 size_t src_len = end ? (size_t)(end - comp) : strlen (comp);
4745 if (!src_len)
4746 {
4747 src_len = 1;
4748 src = ".";
4749 }
4750 if (len + src_len + 2 + 4 < GET_PATH_MAX) /* +4 for .exe */
4751 {
4752 memcpy (buf, src, src_len);
4753 buf [src_len] = '/';
4754 memcpy (&buf[src_len + 1], cur, len);
4755 buf[src_len + 1 + len] = '\0';
4756
4757 if (func_which_test_x (buf))
4758 {
4759 if (!first)
4760 o = variable_buffer_output (o, " ", 1);
4761 o = variable_buffer_output (o, buf, strlen (buf));
4762 first = 0;
4763 break;
4764 }
4765 }
4766
4767 /* next */
4768 if (!end)
4769 break;
4770 comp = end + 1;
4771 }
4772 }
4773 }
4774 }
4775
4776 return variable_buffer_output (o, "", 0);
4777}
4778#endif /* CONFIG_WITH_WHICH */
4779
4780#ifdef CONFIG_WITH_IF_CONDITIONALS
4781
4782/* Evaluates the expression given in the argument using the
4783 same evaluator as for the new 'if' statements, except now
4784 we don't force the result into a boolean like for 'if' and
4785 '$(if-expr ,,)'. */
4786static char *
4787func_expr (char *o, char **argv, const char *funcname UNUSED)
4788{
4789 o = expr_eval_to_string (o, argv[0]);
4790 return o;
4791}
4792
4793/* Same as '$(if ,,)' except the first argument is evaluated
4794 using the same evaluator as for the new 'if' statements. */
4795static char *
4796func_if_expr (char *o, char **argv, const char *funcname UNUSED)
4797{
4798 int rc;
4799 char *to_expand;
4800
4801 /* Evaluate the condition in argv[0] and expand the 2nd or
4802 3rd (optional) argument according to the result. */
4803 rc = expr_eval_if_conditionals (argv[0], NULL);
4804 to_expand = rc == 0 ? argv[1] : argv[2];
4805 if (to_expand && *to_expand)
4806 variable_expand_string_2 (o, to_expand, -1, &o);
4807
4808 return o;
4809}
4810
4811/*
4812 $(select when1-cond, when1-body[,whenN-cond, whenN-body]).
4813 */
4814static char *
4815func_select (char *o, char **argv, const char *funcname UNUSED)
4816{
4817 int i;
4818
4819 /* Test WHEN-CONDs until one matches. The check for 'otherwise[:]'
4820 and 'default[:]' make this a bit more fun... */
4821
4822 for (i = 0; argv[i] != NULL; i += 2)
4823 {
4824 const char *cond = argv[i];
4825 int is_otherwise = 0;
4826
4827 if (argv[i + 1] == NULL)
4828 O (fatal, NILF, _("$(select ): not an even argument count\n"));
4829
4830 while (ISSPACE (*cond))
4831 cond++;
4832 if ( (*cond == 'o' && strncmp (cond, "otherwise", 9) == 0)
4833 || (*cond == 'd' && strncmp (cond, "default", 7) == 0))
4834 {
4835 const char *end = cond + (*cond == 'o' ? 9 : 7);
4836 while (ISSPACE (*end))
4837 end++;
4838 if (*end == ':')
4839 do end++;
4840 while (ISSPACE (*end));
4841 is_otherwise = *end == '\0';
4842 }
4843
4844 if ( is_otherwise
4845 || expr_eval_if_conditionals (cond, NULL) == 0 /* true */)
4846 {
4847 variable_expand_string_2 (o, argv[i + 1], -1, &o);
4848 break;
4849 }
4850 }
4851
4852 return o;
4853}
4854
4855#endif /* CONFIG_WITH_IF_CONDITIONALS */
4856
4857#ifdef CONFIG_WITH_SET_CONDITIONALS
4858static char *
4859func_set_intersects (char *o, char **argv, const char *funcname UNUSED)
4860{
4861 const char *s1_cur;
4862 unsigned int s1_len;
4863 const char *s1_iterator = argv[0];
4864
4865 while ((s1_cur = find_next_token (&s1_iterator, &s1_len)) != 0)
4866 {
4867 const char *s2_cur;
4868 unsigned int s2_len;
4869 const char *s2_iterator = argv[1];
4870 while ((s2_cur = find_next_token (&s2_iterator, &s2_len)) != 0)
4871 if (s2_len == s1_len
4872 && strneq (s2_cur, s1_cur, s1_len) )
4873 return variable_buffer_output (o, "1", 1); /* found intersection */
4874 }
4875
4876 return o; /* no intersection */
4877}
4878#endif /* CONFIG_WITH_SET_CONDITIONALS */
4879
4880#ifdef CONFIG_WITH_STACK
4881
4882/* Push an item (string without spaces). */
4883static char *
4884func_stack_push (char *o, char **argv, const char *funcname UNUSED)
4885{
4886 do_variable_definition(NILF, argv[0], argv[1], o_file, f_append, 0 /* !target_var */);
4887 return o;
4888}
4889
4890/* Pops an item off the stack / get the top stack element.
4891 (This is what's tricky to do in pure GNU make syntax.) */
4892static char *
4893func_stack_pop_top (char *o, char **argv, const char *funcname)
4894{
4895 struct variable *stack_var;
4896 const char *stack = argv[0];
4897
4898 stack_var = lookup_variable (stack, strlen (stack) );
4899 if (stack_var)
4900 {
4901 unsigned int len;
4902 const char *iterator = stack_var->value;
4903 char *lastitem = NULL;
4904 char *cur;
4905
4906 while ((cur = find_next_token (&iterator, &len)))
4907 lastitem = cur;
4908
4909 if (lastitem != NULL)
4910 {
4911 if (strcmp (funcname, "stack-popv") != 0)
4912 o = variable_buffer_output (o, lastitem, len);
4913 if (strcmp (funcname, "stack-top") != 0)
4914 {
4915 *lastitem = '\0';
4916 while (lastitem > stack_var->value && ISSPACE (lastitem[-1]))
4917 *--lastitem = '\0';
4918#ifdef CONFIG_WITH_VALUE_LENGTH
4919 stack_var->value_length = lastitem - stack_var->value;
4920#endif
4921 VARIABLE_CHANGED (stack_var);
4922 }
4923 }
4924 }
4925 return o;
4926}
4927#endif /* CONFIG_WITH_STACK */
4928
4929#if defined (CONFIG_WITH_MATH) || defined (CONFIG_WITH_NANOTS) || defined (CONFIG_WITH_FILE_SIZE)
4930/* outputs the number (as a string) into the variable buffer. */
4931static char *
4932math_int_to_variable_buffer (char *o, math_int num)
4933{
4934 static const char xdigits[17] = "0123456789abcdef";
4935 int negative;
4936 char strbuf[24]; /* 16 hex + 2 prefix + sign + term => 20
4937 or 20 dec + sign + term => 22 */
4938 char *str = &strbuf[sizeof (strbuf) - 1];
4939
4940 negative = num < 0;
4941 if (negative)
4942 num = -num;
4943
4944 *str = '\0';
4945
4946 do
4947 {
4948#ifdef HEX_MATH_NUMBERS
4949 *--str = xdigits[num & 0xf];
4950 num >>= 4;
4951#else
4952 *--str = xdigits[num % 10];
4953 num /= 10;
4954#endif
4955 }
4956 while (num);
4957
4958#ifdef HEX_MATH_NUMBERS
4959 *--str = 'x';
4960 *--str = '0';
4961#endif
4962
4963 if (negative)
4964 *--str = '-';
4965
4966 return variable_buffer_output (o, str, &strbuf[sizeof (strbuf) - 1] - str);
4967}
4968#endif /* CONFIG_WITH_MATH || CONFIG_WITH_NANOTS */
4969
4970#ifdef CONFIG_WITH_MATH
4971
4972/* Converts a string to an integer, causes an error if the format is invalid. */
4973static math_int
4974math_int_from_string (const char *str)
4975{
4976 const char *start;
4977 unsigned base = 0;
4978 int negative = 0;
4979 math_int num = 0;
4980
4981 /* strip spaces */
4982 while (ISSPACE (*str))
4983 str++;
4984 if (!*str)
4985 {
4986 O (error, NILF, _("bad number: empty\n"));
4987 return 0;
4988 }
4989 start = str;
4990
4991 /* check for +/- */
4992 while (*str == '+' || *str == '-' || ISSPACE (*str))
4993 if (*str++ == '-')
4994 negative = !negative;
4995
4996 /* check for prefix - we do not accept octal numbers, sorry. */
4997 if (*str == '0' && (str[1] == 'x' || str[1] == 'X'))
4998 {
4999 base = 16;
5000 str += 2;
5001 }
5002 else
5003 {
5004 /* look for a hex digit, if not found treat it as decimal */
5005 const char *p2 = str;
5006 for ( ; *p2; p2++)
5007 if (isxdigit (*p2) && !isdigit (*p2) && isascii (*p2) )
5008 {
5009 base = 16;
5010 break;
5011 }
5012 if (base == 0)
5013 base = 10;
5014 }
5015
5016 /* must have at least one digit! */
5017 if ( !isascii (*str)
5018 || !(base == 16 ? isxdigit (*str) : isdigit (*str)) )
5019 {
5020 OS (error, NILF, _("bad number: '%s'\n"), start);
5021 return 0;
5022 }
5023
5024 /* convert it! */
5025 while (*str && !ISSPACE (*str))
5026 {
5027 int ch = *str++;
5028 if (ch >= '0' && ch <= '9')
5029 ch -= '0';
5030 else if (base == 16 && ch >= 'a' && ch <= 'f')
5031 ch -= 'a' - 10;
5032 else if (base == 16 && ch >= 'A' && ch <= 'F')
5033 ch -= 'A' - 10;
5034 else
5035 {
5036 OSNN (error, NILF, _("bad number: '%s' (base=%u, pos=%lu)\n"), start, base, (unsigned long)(str - start));
5037 return 0;
5038 }
5039 num *= base;
5040 num += ch;
5041 }
5042
5043 /* check trailing spaces. */
5044 while (ISSPACE (*str))
5045 str++;
5046 if (*str)
5047 {
5048 OS (error, NILF, _("bad number: '%s'\n"), start);
5049 return 0;
5050 }
5051
5052 return negative ? -num : num;
5053}
5054
5055/* Add two or more integer numbers. */
5056static char *
5057func_int_add (char *o, char **argv, const char *funcname UNUSED)
5058{
5059 math_int num;
5060 int i;
5061
5062 num = math_int_from_string (argv[0]);
5063 for (i = 1; argv[i]; i++)
5064 num += math_int_from_string (argv[i]);
5065
5066 return math_int_to_variable_buffer (o, num);
5067}
5068
5069/* Subtract two or more integer numbers. */
5070static char *
5071func_int_sub (char *o, char **argv, const char *funcname UNUSED)
5072{
5073 math_int num;
5074 int i;
5075
5076 num = math_int_from_string (argv[0]);
5077 for (i = 1; argv[i]; i++)
5078 num -= math_int_from_string (argv[i]);
5079
5080 return math_int_to_variable_buffer (o, num);
5081}
5082
5083/* Multiply two or more integer numbers. */
5084static char *
5085func_int_mul (char *o, char **argv, const char *funcname UNUSED)
5086{
5087 math_int num;
5088 int i;
5089
5090 num = math_int_from_string (argv[0]);
5091 for (i = 1; argv[i]; i++)
5092 num *= math_int_from_string (argv[i]);
5093
5094 return math_int_to_variable_buffer (o, num);
5095}
5096
5097/* Divide an integer number by one or more divisors. */
5098static char *
5099func_int_div (char *o, char **argv, const char *funcname UNUSED)
5100{
5101 math_int num;
5102 math_int divisor;
5103 int i;
5104
5105 num = math_int_from_string (argv[0]);
5106 for (i = 1; argv[i]; i++)
5107 {
5108 divisor = math_int_from_string (argv[i]);
5109 if (!divisor)
5110 {
5111 OS (error, NILF, _("divide by zero ('%s')\n"), argv[i]);
5112 return math_int_to_variable_buffer (o, 0);
5113 }
5114 num /= divisor;
5115 }
5116
5117 return math_int_to_variable_buffer (o, num);
5118}
5119
5120
5121/* Divide and return the remainder. */
5122static char *
5123func_int_mod (char *o, char **argv, const char *funcname UNUSED)
5124{
5125 math_int num;
5126 math_int divisor;
5127
5128 num = math_int_from_string (argv[0]);
5129 divisor = math_int_from_string (argv[1]);
5130 if (!divisor)
5131 {
5132 OS (error, NILF, _("divide by zero ('%s')\n"), argv[1]);
5133 return math_int_to_variable_buffer (o, 0);
5134 }
5135 num %= divisor;
5136
5137 return math_int_to_variable_buffer (o, num);
5138}
5139
5140/* 2-complement. */
5141static char *
5142func_int_not (char *o, char **argv, const char *funcname UNUSED)
5143{
5144 math_int num;
5145
5146 num = math_int_from_string (argv[0]);
5147 num = ~num;
5148
5149 return math_int_to_variable_buffer (o, num);
5150}
5151
5152/* Bitwise AND (two or more numbers). */
5153static char *
5154func_int_and (char *o, char **argv, const char *funcname UNUSED)
5155{
5156 math_int num;
5157 int i;
5158
5159 num = math_int_from_string (argv[0]);
5160 for (i = 1; argv[i]; i++)
5161 num &= math_int_from_string (argv[i]);
5162
5163 return math_int_to_variable_buffer (o, num);
5164}
5165
5166/* Bitwise OR (two or more numbers). */
5167static char *
5168func_int_or (char *o, char **argv, const char *funcname UNUSED)
5169{
5170 math_int num;
5171 int i;
5172
5173 num = math_int_from_string (argv[0]);
5174 for (i = 1; argv[i]; i++)
5175 num |= math_int_from_string (argv[i]);
5176
5177 return math_int_to_variable_buffer (o, num);
5178}
5179
5180/* Bitwise XOR (two or more numbers). */
5181static char *
5182func_int_xor (char *o, char **argv, const char *funcname UNUSED)
5183{
5184 math_int num;
5185 int i;
5186
5187 num = math_int_from_string (argv[0]);
5188 for (i = 1; argv[i]; i++)
5189 num ^= math_int_from_string (argv[i]);
5190
5191 return math_int_to_variable_buffer (o, num);
5192}
5193
5194/* Compare two integer numbers. Returns make boolean (true="1"; false=""). */
5195static char *
5196func_int_cmp (char *o, char **argv, const char *funcname)
5197{
5198 math_int num1;
5199 math_int num2;
5200 int rc;
5201
5202 num1 = math_int_from_string (argv[0]);
5203 num2 = math_int_from_string (argv[1]);
5204
5205 funcname += sizeof ("int-") - 1;
5206 if (!strcmp (funcname, "eq"))
5207 rc = num1 == num2;
5208 else if (!strcmp (funcname, "ne"))
5209 rc = num1 != num2;
5210 else if (!strcmp (funcname, "gt"))
5211 rc = num1 > num2;
5212 else if (!strcmp (funcname, "ge"))
5213 rc = num1 >= num2;
5214 else if (!strcmp (funcname, "lt"))
5215 rc = num1 < num2;
5216 else /*if (!strcmp (funcname, "le"))*/
5217 rc = num1 <= num2;
5218
5219 return variable_buffer_output (o, rc ? "1" : "", rc);
5220}
5221
5222#endif /* CONFIG_WITH_MATH */
5223
5224#ifdef CONFIG_WITH_NANOTS
5225/* Returns the current timestamp as nano seconds. The time
5226 source is a high res monotone one if the platform provides
5227 this (and we know about it).
5228
5229 Tip. Use this with int-sub to profile makefile reading
5230 and similar. */
5231static char *
5232func_nanots (char *o, char **argv UNUSED, const char *funcname UNUSED)
5233{
5234 return math_int_to_variable_buffer (o, nano_timestamp ());
5235}
5236#endif
5237
5238#ifdef CONFIG_WITH_OS2_LIBPATH
5239/* Sets or gets the OS/2 libpath variables.
5240
5241 The first argument indicates which variable - BEGINLIBPATH,
5242 ENDLIBPATH, LIBPATHSTRICT or LIBPATH.
5243
5244 The second indicates whether this is a get (not present) or
5245 set (present) operation. When present it is the new value for
5246 the variable. */
5247static char *
5248func_os2_libpath (char *o, char **argv, const char *funcname UNUSED)
5249{
5250 char buf[4096];
5251 ULONG fVar;
5252 APIRET rc;
5253
5254 /* translate variable name (first arg) */
5255 if (!strcmp (argv[0], "BEGINLIBPATH"))
5256 fVar = BEGIN_LIBPATH;
5257 else if (!strcmp (argv[0], "ENDLIBPATH"))
5258 fVar = END_LIBPATH;
5259 else if (!strcmp (argv[0], "LIBPATHSTRICT"))
5260 fVar = LIBPATHSTRICT;
5261 else if (!strcmp (argv[0], "LIBPATH"))
5262 fVar = 0;
5263 else
5264 {
5265 OS (error, NILF, _("$(libpath): unknown variable `%s'"), argv[0]);
5266 return variable_buffer_output (o, "", 0);
5267 }
5268
5269 if (!argv[1])
5270 {
5271 /* get the variable value. */
5272 if (fVar != 0)
5273 {
5274 buf[0] = buf[1] = buf[2] = buf[3] = '\0';
5275 rc = DosQueryExtLIBPATH (buf, fVar);
5276 }
5277 else
5278 rc = DosQueryHeaderInfo (NULLHANDLE, 0, buf, sizeof(buf), QHINF_LIBPATH);
5279 if (rc != NO_ERROR)
5280 {
5281 OSN (error, NILF, _("$(libpath): failed to query `%s', rc=%d"), argv[0], rc);
5282 return variable_buffer_output (o, "", 0);
5283 }
5284 o = variable_buffer_output (o, buf, strlen (buf));
5285 }
5286 else
5287 {
5288 /* set the variable value. */
5289 size_t len;
5290 size_t len_max = sizeof (buf) < 2048 ? sizeof (buf) : 2048;
5291 const char *val;
5292 const char *end;
5293
5294 if (fVar == 0)
5295 {
5296 O (error, NILF, _("$(libpath): LIBPATH is read-only"));
5297 return variable_buffer_output (o, "", 0);
5298 }
5299
5300 /* strip leading and trailing spaces and check for max length. */
5301 val = argv[1];
5302 while (ISSPACE (*val))
5303 val++;
5304 end = strchr (val, '\0');
5305 while (end > val && ISSPACE (end[-1]))
5306 end--;
5307
5308 len = end - val;
5309 if (len >= len_max)
5310 {
5311 OSNN (error, NILF, _("$(libpath): The new `%s' value is too long (%d bytes, max %d)"),
5312 argv[0], len, len_max);
5313 return variable_buffer_output (o, "", 0);
5314 }
5315
5316 /* make a stripped copy in low memory and try set it. */
5317 memcpy (buf, val, len);
5318 buf[len] = '\0';
5319 rc = DosSetExtLIBPATH (buf, fVar);
5320 if (rc != NO_ERROR)
5321 {
5322 OSSN (error, (NILF, _("$(libpath): failed to set `%s' to `%s', rc=%d"), argv[0], buf, rc);
5323 return variable_buffer_output (o, "", 0);
5324 }
5325
5326 o = variable_buffer_output (o, "", 0);
5327 }
5328 return o;
5329}
5330#endif /* CONFIG_WITH_OS2_LIBPATH */
5331
5332#if defined (CONFIG_WITH_MAKE_STATS) || defined (CONFIG_WITH_MINIMAL_STATS)
5333/* Retrieve make statistics. */
5334static char *
5335func_make_stats (char *o, char **argv, const char *funcname UNUSED)
5336{
5337 char buf[512];
5338 int len;
5339
5340 if (!argv[0] || (!argv[0][0] && !argv[1]))
5341 {
5342# ifdef CONFIG_WITH_MAKE_STATS
5343 len = sprintf (buf, "alloc-cur: %5ld/%3ld %3luMB hash: %5lu %2lu%%",
5344 make_stats_allocations,
5345 make_stats_reallocations,
5346 make_stats_allocated / (1024*1024),
5347 make_stats_ht_lookups,
5348 (make_stats_ht_collisions * 100) / make_stats_ht_lookups);
5349 o = variable_buffer_output (o, buf, len);
5350#endif
5351 }
5352 else
5353 {
5354 /* selective */
5355 int i;
5356 for (i = 0; argv[i]; i++)
5357 {
5358 unsigned long val;
5359 if (i != 0)
5360 o = variable_buffer_output (o, " ", 1);
5361 if (0)
5362 continue;
5363# ifdef CONFIG_WITH_MAKE_STATS
5364 else if (!strcmp(argv[i], "allocations"))
5365 val = make_stats_allocations;
5366 else if (!strcmp(argv[i], "reallocations"))
5367 val = make_stats_reallocations;
5368 else if (!strcmp(argv[i], "allocated"))
5369 val = make_stats_allocated;
5370 else if (!strcmp(argv[i], "ht_lookups"))
5371 val = make_stats_ht_lookups;
5372 else if (!strcmp(argv[i], "ht_collisions"))
5373 val = make_stats_ht_collisions;
5374 else if (!strcmp(argv[i], "ht_collisions_pct"))
5375 val = (make_stats_ht_collisions * 100) / make_stats_ht_lookups;
5376#endif
5377 else
5378 {
5379 o = variable_buffer_output (o, argv[i], strlen (argv[i]));
5380 continue;
5381 }
5382
5383 len = sprintf (buf, "%ld", val);
5384 o = variable_buffer_output (o, buf, len);
5385 }
5386 }
5387
5388 return o;
5389}
5390#endif /* CONFIG_WITH_MAKE_STATS */
5391
5392#ifdef CONFIG_WITH_COMMANDS_FUNC
5393/* Gets all the commands for a target, separated by newlines.
5394
5395 This is useful when creating and checking target dependencies since
5396 it reduces the amount of work and the memory consuption. A new prefix
5397 character '%' has been introduced for skipping certain lines, like
5398 for instance the one calling this function and pushing to a dep file.
5399 Blank lines are also skipped.
5400
5401 The commands function takes exactly one argument, which is the name of
5402 the target which commands should be returned.
5403
5404 The commands-sc is identical to commands except that it uses a ';' to
5405 separate the commands.
5406
5407 The commands-usr is similar to commands except that it takes a 2nd
5408 argument that is used to separate the commands. */
5409char *
5410func_commands (char *o, char **argv, const char *funcname)
5411{
5412 struct file *file;
5413 static int recursive = 0;
5414
5415 if (recursive)
5416 {
5417 OS (error, reading_file, _("$(%s ) was invoked recursivly"), funcname);
5418 return variable_buffer_output (o, "recursive", sizeof ("recursive") - 1);
5419 }
5420 if (*argv[0] == '\0')
5421 {
5422 OS (error, reading_file, _("$(%s ) was invoked with an empty target name"), funcname);
5423 return o;
5424 }
5425 recursive = 1;
5426
5427 file = lookup_file (argv[0]);
5428 if (file && file->cmds)
5429 {
5430 unsigned int i;
5431 int cmd_sep_len;
5432 struct commands *cmds = file->cmds;
5433 const char *cmd_sep;
5434
5435 if (!strcmp (funcname, "commands"))
5436 {
5437 cmd_sep = "\n";
5438 cmd_sep_len = 1;
5439 }
5440 else if (!strcmp (funcname, "commands-sc"))
5441 {
5442 cmd_sep = ";";
5443 cmd_sep_len = 1;
5444 }
5445 else /*if (!strcmp (funcname, "commands-usr"))*/
5446 {
5447 cmd_sep = argv[1];
5448 cmd_sep_len = strlen (cmd_sep);
5449 }
5450
5451 initialize_file_variables (file, 1 /* don't search for pattern vars */);
5452 set_file_variables (file, 1 /* early call */);
5453 chop_commands (cmds);
5454
5455 for (i = 0; i < cmds->ncommand_lines; i++)
5456 {
5457 char *p;
5458 char *in, *out, *ref;
5459
5460 /* Skip it if it has a '%' prefix or is blank. */
5461 if (cmds->lines_flags[i] & COMMAND_GETTER_SKIP_IT)
5462 continue;
5463 p = cmds->command_lines[i];
5464 while (ISBLANK (*p))
5465 p++;
5466 if (*p == '\0')
5467 continue;
5468
5469 /* --- copied from new_job() in job.c --- */
5470
5471 /* Collapse backslash-newline combinations that are inside variable
5472 or function references. These are left alone by the parser so
5473 that they will appear in the echoing of commands (where they look
5474 nice); and collapsed by construct_command_argv when it tokenizes.
5475 But letting them survive inside function invocations loses because
5476 we don't want the functions to see them as part of the text. */
5477
5478 /* IN points to where in the line we are scanning.
5479 OUT points to where in the line we are writing.
5480 When we collapse a backslash-newline combination,
5481 IN gets ahead of OUT. */
5482
5483 in = out = p;
5484 while ((ref = strchr (in, '$')) != 0)
5485 {
5486 ++ref; /* Move past the $. */
5487
5488 if (out != in)
5489 /* Copy the text between the end of the last chunk
5490 we processed (where IN points) and the new chunk
5491 we are about to process (where REF points). */
5492 memmove (out, in, ref - in);
5493
5494 /* Move both pointers past the boring stuff. */
5495 out += ref - in;
5496 in = ref;
5497
5498 if (*ref == '(' || *ref == '{')
5499 {
5500 char openparen = *ref;
5501 char closeparen = openparen == '(' ? ')' : '}';
5502 int count;
5503 char *p2;
5504
5505 *out++ = *in++; /* Copy OPENPAREN. */
5506 /* IN now points past the opening paren or brace.
5507 Count parens or braces until it is matched. */
5508 count = 0;
5509 while (*in != '\0')
5510 {
5511 if (*in == closeparen && --count < 0)
5512 break;
5513 else if (*in == '\\' && in[1] == '\n')
5514 {
5515 /* We have found a backslash-newline inside a
5516 variable or function reference. Eat it and
5517 any following whitespace. */
5518
5519 int quoted = 0;
5520 for (p2 = in - 1; p2 > ref && *p2 == '\\'; --p2)
5521 quoted = !quoted;
5522
5523 if (quoted)
5524 /* There were two or more backslashes, so this is
5525 not really a continuation line. We don't collapse
5526 the quoting backslashes here as is done in
5527 collapse_continuations, because the line will
5528 be collapsed again after expansion. */
5529 *out++ = *in++;
5530 else
5531 {
5532 /* Skip the backslash, newline and
5533 any following whitespace. */
5534 in = next_token (in + 2);
5535
5536 /* Discard any preceding whitespace that has
5537 already been written to the output. */
5538 while (out > ref
5539 && ISBLANK (out[-1]))
5540 --out;
5541
5542 /* Replace it all with a single space. */
5543 *out++ = ' ';
5544 }
5545 }
5546 else
5547 {
5548 if (*in == openparen)
5549 ++count;
5550
5551 *out++ = *in++;
5552 }
5553 }
5554 }
5555 /* Some of these can be amended ($< perhaps), but we're likely to be called while the
5556 dep expansion happens, so it would have to be on a hackish basis. sad... */
5557 else if (*ref == '<' || *ref == '*' || *ref == '%' || *ref == '^' || *ref == '+')
5558 OSN (error, reading_file, _("$(%s ) does not work reliably with $%c in all cases"), funcname, *ref);
5559 }
5560
5561 /* There are no more references in this line to worry about.
5562 Copy the remaining uninteresting text to the output. */
5563 if (out != in)
5564 strcpy (out, in);
5565
5566 /* --- copied from new_job() in job.c --- */
5567
5568 /* Finally, expand the line. */
5569 if (i)
5570 o = variable_buffer_output (o, cmd_sep, cmd_sep_len);
5571 o = variable_expand_for_file_2 (o, cmds->command_lines[i], ~0U, file, NULL);
5572
5573 /* Skip it if it has a '%' prefix or is blank. */
5574 p = o;
5575 while (ISBLANK (*o)
5576 || *o == '@'
5577 || *o == '-'
5578 || *o == '+')
5579 o++;
5580 if (*o != '\0' && *o != '%')
5581 o = strchr (o, '\0');
5582 else if (i)
5583 o = p - cmd_sep_len;
5584 else
5585 o = p;
5586 } /* for each command line */
5587 }
5588 /* else FIXME: bitch about it? */
5589
5590 recursive = 0;
5591 return o;
5592}
5593#endif /* CONFIG_WITH_COMMANDS_FUNC */
5594#ifdef KMK
5595
5596/* Useful when debugging kmk and/or makefiles. */
5597char *
5598func_breakpoint (char *o, char **argv UNUSED, const char *funcname UNUSED)
5599{
5600#ifdef _MSC_VER
5601 __debugbreak();
5602#elif defined(__i386__) || defined(__x86__) || defined(__X86__) || defined(_M_IX86) || defined(__i386) \
5603 || defined(__amd64__) || defined(__x86_64__) || defined(__AMD64__) || defined(_M_X64) || defined(__amd64)
5604# ifdef __sun__
5605 __asm__ __volatile__ ("int $3\n\t");
5606# else
5607 __asm__ __volatile__ ("int3\n\t");
5608# endif
5609#else
5610 char *p = (char *)0;
5611 *p = '\0';
5612#endif
5613 return o;
5614}
5615
5616/* umask | umask -S. */
5617char *
5618func_get_umask (char *o, char **argv UNUSED, const char *funcname UNUSED)
5619{
5620 char sz[80];
5621 int off;
5622 mode_t u;
5623 int symbolic = 0;
5624 const char *psz = argv[0];
5625
5626 if (psz)
5627 {
5628 const char *pszEnd = strchr (psz, '\0');
5629 strip_whitespace (&psz, &pszEnd);
5630
5631 if (pszEnd != psz)
5632 {
5633 if ( STR_N_EQUALS (psz, pszEnd - pszEnd, "S")
5634 || STR_N_EQUALS (psz, pszEnd - pszEnd, "-S")
5635 || STR_N_EQUALS (psz, pszEnd - pszEnd, "symbolic") )
5636 symbolic = 1;
5637 else
5638 OSS (error, reading_file, _("$(%s ) invalid argument `%s'"),
5639 funcname, argv[0]);
5640 }
5641 }
5642
5643 u = umask (002);
5644 umask (u);
5645
5646 if (symbolic)
5647 {
5648 off = 0;
5649 sz[off++] = 'u';
5650 sz[off++] = '=';
5651 if ((u & S_IRUSR) == 0)
5652 sz[off++] = 'r';
5653 if ((u & S_IWUSR) == 0)
5654 sz[off++] = 'w';
5655 if ((u & S_IXUSR) == 0)
5656 sz[off++] = 'x';
5657 sz[off++] = ',';
5658 sz[off++] = 'g';
5659 sz[off++] = '=';
5660 if ((u & S_IRGRP) == 0)
5661 sz[off++] = 'r';
5662 if ((u & S_IWGRP) == 0)
5663 sz[off++] = 'w';
5664 if ((u & S_IXGRP) == 0)
5665 sz[off++] = 'x';
5666 sz[off++] = ',';
5667 sz[off++] = 'o';
5668 sz[off++] = '=';
5669 if ((u & S_IROTH) == 0)
5670 sz[off++] = 'r';
5671 if ((u & S_IWOTH) == 0)
5672 sz[off++] = 'w';
5673 if ((u & S_IXOTH) == 0)
5674 sz[off++] = 'x';
5675 }
5676 else
5677 off = sprintf (sz, "%.4o", u);
5678
5679 return variable_buffer_output (o, sz, off);
5680}
5681
5682
5683/* umask 0002 | umask u=rwx,g=rwx,o=rx. */
5684char *
5685func_set_umask (char *o, char **argv UNUSED, const char *funcname UNUSED)
5686{
5687 mode_t u;
5688 const char *psz;
5689
5690 /* Figure what kind of input this is. */
5691 psz = argv[0];
5692 while (ISBLANK (*psz))
5693 psz++;
5694
5695 if (isdigit ((unsigned char)*psz))
5696 {
5697 u = 0;
5698 while (*psz)
5699 {
5700 u <<= 3;
5701 if (*psz < '0' || *psz >= '8')
5702 {
5703 OSS (error, reading_file, _("$(%s ) illegal number `%s'"), funcname, argv[0]);
5704 break;
5705 }
5706 u += *psz - '0';
5707 psz++;
5708 }
5709
5710 if (argv[1] != NULL)
5711 OS (error, reading_file, _("$(%s ) too many arguments for octal mode"), funcname);
5712 }
5713 else
5714 {
5715 u = umask(0);
5716 umask(u);
5717 OS (error, reading_file, _("$(%s ) symbol mode is not implemented"), funcname);
5718 }
5719
5720 umask(u);
5721
5722 return o;
5723}
5724
5725
5726/* Controls the cache in dir-bird-nt.c. */
5727
5728char *
5729func_dircache_ctl (char *o, char **argv UNUSED, const char *funcname UNUSED)
5730{
5731# ifdef KBUILD_OS_WINDOWS
5732 const char *cmd = argv[0];
5733 while (ISBLANK (*cmd))
5734 cmd++;
5735 if (strcmp (cmd, "invalidate") == 0)
5736 {
5737 if (argv[1] != NULL)
5738 O (error, reading_file, "$(dircache-ctl invalidate) takes no parameters");
5739 dir_cache_invalid_all ();
5740 }
5741 else if (strcmp (cmd, "invalidate-missing") == 0)
5742 {
5743 if (argv[1] != NULL)
5744 O (error, reading_file, "$(dircache-ctl invalidate-missing) takes no parameters");
5745 dir_cache_invalid_missing ();
5746 }
5747 else if (strcmp (cmd, "volatile") == 0)
5748 {
5749 size_t i;
5750 for (i = 1; argv[i] != NULL; i++)
5751 {
5752 const char *dir = argv[i];
5753 while (ISBLANK (*dir))
5754 dir++;
5755 if (*dir)
5756 dir_cache_volatile_dir (dir);
5757 }
5758 }
5759 else if (strcmp (cmd, "deleted") == 0)
5760 {
5761 size_t i;
5762 for (i = 1; argv[i] != NULL; i++)
5763 {
5764 const char *dir = argv[i];
5765 while (ISBLANK (*dir))
5766 dir++;
5767 if (*dir)
5768 dir_cache_deleted_directory (dir);
5769 }
5770 }
5771 else
5772 OS (error, reading_file, "Unknown $(dircache-ctl ) command: '%s'", cmd);
5773# endif
5774 return o;
5775}
5776
5777#endif /* KMK */
5778
5779
5780/* Lookup table for builtin functions.
5781
5782 This doesn't have to be sorted; we use a straight lookup. We might gain
5783 some efficiency by moving most often used functions to the start of the
5784 table.
5785
5786 If MAXIMUM_ARGS is 0, that means there is no maximum and all
5787 comma-separated values are treated as arguments.
5788
5789 EXPAND_ARGS means that all arguments should be expanded before invocation.
5790 Functions that do namespace tricks (foreach) don't automatically expand. */
5791
5792static char *func_call (char *o, char **argv, const char *funcname);
5793
5794#define FT_ENTRY(_name, _min, _max, _exp, _func) \
5795 { { (_func) }, STRING_SIZE_TUPLE(_name), (_min), (_max), (_exp), 0 }
5796
5797static struct function_table_entry function_table_init[] =
5798{
5799 /* Name MIN MAX EXP? Function */
5800 FT_ENTRY ("abspath", 0, 1, 1, func_abspath),
5801 FT_ENTRY ("addprefix", 2, 2, 1, func_addsuffix_addprefix),
5802 FT_ENTRY ("addsuffix", 2, 2, 1, func_addsuffix_addprefix),
5803 FT_ENTRY ("basename", 0, 1, 1, func_basename_dir),
5804 FT_ENTRY ("dir", 0, 1, 1, func_basename_dir),
5805 FT_ENTRY ("notdir", 0, 1, 1, func_notdir_suffix),
5806#ifdef CONFIG_WITH_ROOT_FUNC
5807 FT_ENTRY ("root", 0, 1, 1, func_root),
5808 FT_ENTRY ("notroot", 0, 1, 1, func_notroot),
5809#endif
5810 FT_ENTRY ("subst", 3, 3, 1, func_subst),
5811 FT_ENTRY ("suffix", 0, 1, 1, func_notdir_suffix),
5812 FT_ENTRY ("filter", 2, 2, 1, func_filter_filterout),
5813 FT_ENTRY ("filter-out", 2, 2, 1, func_filter_filterout),
5814 FT_ENTRY ("findstring", 2, 2, 1, func_findstring),
5815#ifdef CONFIG_WITH_DEFINED_FUNCTIONS
5816 FT_ENTRY ("firstdefined", 0, 2, 1, func_firstdefined),
5817#endif
5818 FT_ENTRY ("firstword", 0, 1, 1, func_firstword),
5819 FT_ENTRY ("flavor", 0, 1, 1, func_flavor),
5820 FT_ENTRY ("join", 2, 2, 1, func_join),
5821#ifdef CONFIG_WITH_DEFINED_FUNCTIONS
5822 FT_ENTRY ("lastdefined", 0, 2, 1, func_lastdefined),
5823#endif
5824 FT_ENTRY ("lastword", 0, 1, 1, func_lastword),
5825 FT_ENTRY ("patsubst", 3, 3, 1, func_patsubst),
5826 FT_ENTRY ("realpath", 0, 1, 1, func_realpath),
5827#ifdef CONFIG_WITH_RSORT
5828 FT_ENTRY ("rsort", 0, 1, 1, func_sort),
5829#endif
5830 FT_ENTRY ("shell", 0, 1, 1, func_shell),
5831 FT_ENTRY ("sort", 0, 1, 1, func_sort),
5832 FT_ENTRY ("strip", 0, 1, 1, func_strip),
5833#ifdef CONFIG_WITH_WHERE_FUNCTION
5834 FT_ENTRY ("where", 0, 1, 1, func_where),
5835#endif
5836 FT_ENTRY ("wildcard", 0, 1, 1, func_wildcard),
5837 FT_ENTRY ("word", 2, 2, 1, func_word),
5838 FT_ENTRY ("wordlist", 3, 3, 1, func_wordlist),
5839 FT_ENTRY ("words", 0, 1, 1, func_words),
5840 FT_ENTRY ("origin", 0, 1, 1, func_origin),
5841 FT_ENTRY ("foreach", 3, 3, 0, func_foreach),
5842#ifdef CONFIG_WITH_LOOP_FUNCTIONS
5843 FT_ENTRY ("for", 4, 4, 0, func_for),
5844 FT_ENTRY ("while", 2, 2, 0, func_while),
5845#endif
5846 FT_ENTRY ("call", 1, 0, 1, func_call),
5847 FT_ENTRY ("info", 0, 1, 1, func_error),
5848 FT_ENTRY ("error", 0, 1, 1, func_error),
5849 FT_ENTRY ("warning", 0, 1, 1, func_error),
5850 FT_ENTRY ("if", 2, 3, 0, func_if),
5851 FT_ENTRY ("or", 1, 0, 0, func_or),
5852 FT_ENTRY ("and", 1, 0, 0, func_and),
5853 FT_ENTRY ("value", 0, 1, 1, func_value),
5854#ifdef EXPERIMENTAL
5855 FT_ENTRY ("eq", 2, 2, 1, func_eq),
5856 FT_ENTRY ("not", 0, 1, 1, func_not),
5857#endif
5858 FT_ENTRY ("eval", 0, 1, 1, func_eval),
5859#ifdef CONFIG_WITH_EVALPLUS
5860 FT_ENTRY ("evalctx", 0, 1, 1, func_evalctx),
5861 FT_ENTRY ("evalval", 1, 1, 1, func_evalval),
5862 FT_ENTRY ("evalvalctx", 1, 1, 1, func_evalval),
5863 FT_ENTRY ("evalcall", 1, 0, 1, func_call),
5864 FT_ENTRY ("evalcall2", 1, 0, 1, func_call),
5865 FT_ENTRY ("eval-opt-var", 1, 0, 1, func_eval_optimize_variable),
5866#endif
5867 FT_ENTRY ("file", 1, 2, 1, func_file),
5868#ifdef CONFIG_WITH_STRING_FUNCTIONS
5869 FT_ENTRY ("length", 1, 1, 1, func_length),
5870 FT_ENTRY ("length-var", 1, 1, 1, func_length_var),
5871 FT_ENTRY ("insert", 2, 5, 1, func_insert),
5872 FT_ENTRY ("pos", 2, 3, 1, func_pos),
5873 FT_ENTRY ("lastpos", 2, 3, 1, func_pos),
5874 FT_ENTRY ("substr", 2, 4, 1, func_substr),
5875 FT_ENTRY ("translate", 2, 4, 1, func_translate),
5876#endif
5877#ifdef CONFIG_WITH_PRINTF
5878 FT_ENTRY ("printf", 1, 0, 1, kmk_builtin_func_printf),
5879#endif
5880#ifdef CONFIG_WITH_LAZY_DEPS_VARS
5881 FT_ENTRY ("deps", 1, 2, 1, func_deps),
5882 FT_ENTRY ("deps-all", 1, 2, 1, func_deps),
5883 FT_ENTRY ("deps-newer", 1, 2, 1, func_deps_newer),
5884 FT_ENTRY ("deps-oo", 1, 2, 1, func_deps_order_only),
5885#endif
5886#ifdef CONFIG_WITH_DEFINED
5887 FT_ENTRY ("defined", 1, 1, 1, func_defined),
5888#endif
5889#ifdef CONFIG_WITH_TOUPPER_TOLOWER
5890 FT_ENTRY ("toupper", 0, 1, 1, func_toupper_tolower),
5891 FT_ENTRY ("tolower", 0, 1, 1, func_toupper_tolower),
5892#endif
5893#ifdef CONFIG_WITH_ABSPATHEX
5894 FT_ENTRY ("abspathex", 0, 2, 1, func_abspathex),
5895#endif
5896#ifdef CONFIG_WITH_XARGS
5897 FT_ENTRY ("xargs", 2, 0, 1, func_xargs),
5898#endif
5899#if defined(CONFIG_WITH_VALUE_LENGTH) && defined(CONFIG_WITH_COMPARE)
5900 FT_ENTRY ("comp-vars", 3, 3, 1, func_comp_vars),
5901 FT_ENTRY ("comp-cmds", 3, 3, 1, func_comp_vars),
5902 FT_ENTRY ("comp-cmds-ex", 3, 3, 1, func_comp_cmds_ex),
5903#endif
5904#ifdef CONFIG_WITH_DATE
5905 FT_ENTRY ("date", 0, 1, 1, func_date),
5906 FT_ENTRY ("date-utc", 0, 3, 1, func_date),
5907#endif
5908#ifdef CONFIG_WITH_FILE_SIZE
5909 FT_ENTRY ("file-size", 1, 1, 1, func_file_size),
5910#endif
5911#ifdef CONFIG_WITH_WHICH
5912 FT_ENTRY ("which", 0, 0, 1, func_which),
5913#endif
5914#ifdef CONFIG_WITH_IF_CONDITIONALS
5915 FT_ENTRY ("expr", 1, 1, 0, func_expr),
5916 FT_ENTRY ("if-expr", 2, 3, 0, func_if_expr),
5917 FT_ENTRY ("select", 2, 0, 0, func_select),
5918#endif
5919#ifdef CONFIG_WITH_SET_CONDITIONALS
5920 FT_ENTRY ("intersects", 2, 2, 1, func_set_intersects),
5921#endif
5922#ifdef CONFIG_WITH_STACK
5923 FT_ENTRY ("stack-push", 2, 2, 1, func_stack_push),
5924 FT_ENTRY ("stack-pop", 1, 1, 1, func_stack_pop_top),
5925 FT_ENTRY ("stack-popv", 1, 1, 1, func_stack_pop_top),
5926 FT_ENTRY ("stack-top", 1, 1, 1, func_stack_pop_top),
5927#endif
5928#ifdef CONFIG_WITH_MATH
5929 FT_ENTRY ("int-add", 2, 0, 1, func_int_add),
5930 FT_ENTRY ("int-sub", 2, 0, 1, func_int_sub),
5931 FT_ENTRY ("int-mul", 2, 0, 1, func_int_mul),
5932 FT_ENTRY ("int-div", 2, 0, 1, func_int_div),
5933 FT_ENTRY ("int-mod", 2, 2, 1, func_int_mod),
5934 FT_ENTRY ("int-not", 1, 1, 1, func_int_not),
5935 FT_ENTRY ("int-and", 2, 0, 1, func_int_and),
5936 FT_ENTRY ("int-or", 2, 0, 1, func_int_or),
5937 FT_ENTRY ("int-xor", 2, 0, 1, func_int_xor),
5938 FT_ENTRY ("int-eq", 2, 2, 1, func_int_cmp),
5939 FT_ENTRY ("int-ne", 2, 2, 1, func_int_cmp),
5940 FT_ENTRY ("int-gt", 2, 2, 1, func_int_cmp),
5941 FT_ENTRY ("int-ge", 2, 2, 1, func_int_cmp),
5942 FT_ENTRY ("int-lt", 2, 2, 1, func_int_cmp),
5943 FT_ENTRY ("int-le", 2, 2, 1, func_int_cmp),
5944#endif
5945#ifdef CONFIG_WITH_NANOTS
5946 FT_ENTRY ("nanots", 0, 0, 0, func_nanots),
5947#endif
5948#ifdef CONFIG_WITH_OS2_LIBPATH
5949 FT_ENTRY ("libpath", 1, 2, 1, func_os2_libpath),
5950#endif
5951#if defined (CONFIG_WITH_MAKE_STATS) || defined (CONFIG_WITH_MINIMAL_STATS)
5952 FT_ENTRY ("make-stats", 0, 0, 0, func_make_stats),
5953#endif
5954#ifdef CONFIG_WITH_COMMANDS_FUNC
5955 FT_ENTRY ("commands", 1, 1, 1, func_commands),
5956 FT_ENTRY ("commands-sc", 1, 1, 1, func_commands),
5957 FT_ENTRY ("commands-usr", 2, 2, 1, func_commands),
5958#endif
5959#ifdef KMK_HELPERS
5960 FT_ENTRY ("kb-src-tool", 1, 1, 0, func_kbuild_source_tool),
5961 FT_ENTRY ("kb-obj-base", 1, 1, 0, func_kbuild_object_base),
5962 FT_ENTRY ("kb-obj-suff", 1, 1, 0, func_kbuild_object_suffix),
5963 FT_ENTRY ("kb-src-prop", 3, 4, 0, func_kbuild_source_prop),
5964 FT_ENTRY ("kb-src-one", 0, 1, 0, func_kbuild_source_one),
5965 FT_ENTRY ("kb-exp-tmpl", 6, 6, 1, func_kbuild_expand_template),
5966#endif
5967#ifdef KMK
5968 FT_ENTRY ("dircache-ctl", 1, 0, 1, func_dircache_ctl),
5969 FT_ENTRY ("breakpoint", 0, 0, 0, func_breakpoint),
5970 FT_ENTRY ("set-umask", 1, 3, 1, func_set_umask),
5971 FT_ENTRY ("get-umask", 0, 0, 0, func_get_umask),
5972#endif
5973};
5974
5975#define FUNCTION_TABLE_ENTRIES (sizeof (function_table_init) / sizeof (struct function_table_entry))
5976
5977
5978
5979/* These must come after the definition of function_table. */
5980
5981static char *
5982expand_builtin_function (char *o, int argc, char **argv,
5983 const struct function_table_entry *entry_p)
5984{
5985 char *p;
5986
5987 if (argc < (int)entry_p->minimum_args)
5988 fatal (*expanding_var, strlen (entry_p->name),
5989 _("insufficient number of arguments (%d) to function '%s'"),
5990 argc, entry_p->name);
5991
5992 /* I suppose technically some function could do something with no arguments,
5993 but so far no internal ones do, so just test it for all functions here
5994 rather than in each one. We can change it later if necessary. */
5995
5996 if (!argc && !entry_p->alloc_fn)
5997 return o;
5998
5999 if (!entry_p->fptr.func_ptr)
6000 OS (fatal, *expanding_var,
6001 _("unimplemented on this platform: function '%s'"), entry_p->name);
6002
6003 if (!entry_p->alloc_fn)
6004 return entry_p->fptr.func_ptr (o, argv, entry_p->name);
6005
6006 /* This function allocates memory and returns it to us.
6007 Write it to the variable buffer, then free it. */
6008
6009 p = entry_p->fptr.alloc_func_ptr (entry_p->name, argc, argv);
6010 if (p)
6011 {
6012 o = variable_buffer_output (o, p, strlen (p));
6013 free (p);
6014 }
6015
6016 return o;
6017}
6018
6019/* Check for a function invocation in *STRINGP. *STRINGP points at the
6020 opening ( or { and is not null-terminated. If a function invocation
6021 is found, expand it into the buffer at *OP, updating *OP, incrementing
6022 *STRINGP past the reference and returning nonzero. If not, return zero. */
6023
6024static int
6025handle_function2 (const struct function_table_entry *entry_p, char **op, const char **stringp) /* bird split it up. */
6026{
6027 char openparen = (*stringp)[0];
6028 char closeparen = openparen == '(' ? ')' : '}';
6029 const char *beg;
6030 const char *end;
6031 int count = 0;
6032 char *abeg = NULL;
6033 char **argv, **argvp;
6034 int nargs;
6035
6036 beg = *stringp + 1;
6037
6038 /* We found a builtin function. Find the beginning of its arguments (skip
6039 whitespace after the name). */
6040
6041 beg += entry_p->len;
6042 NEXT_TOKEN (beg);
6043
6044 /* Find the end of the function invocation, counting nested use of
6045 whichever kind of parens we use. Since we're looking, count commas
6046 to get a rough estimate of how many arguments we might have. The
6047 count might be high, but it'll never be low. */
6048
6049 for (nargs=1, end=beg; *end != '\0'; ++end)
6050 if (*end == ',')
6051 ++nargs;
6052 else if (*end == openparen)
6053 ++count;
6054 else if (*end == closeparen && --count < 0)
6055 break;
6056
6057 if (count >= 0)
6058 fatal (*expanding_var, strlen (entry_p->name),
6059 _("unterminated call to function '%s': missing '%c'"),
6060 entry_p->name, closeparen);
6061
6062 *stringp = end;
6063
6064 /* Get some memory to store the arg pointers. */
6065 argvp = argv = alloca (sizeof (char *) * (nargs + 2));
6066
6067 /* Chop the string into arguments, then a nul. As soon as we hit
6068 MAXIMUM_ARGS (if it's >0) assume the rest of the string is part of the
6069 last argument.
6070
6071 If we're expanding, store pointers to the expansion of each one. If
6072 not, make a duplicate of the string and point into that, nul-terminating
6073 each argument. */
6074
6075 if (entry_p->expand_args)
6076 {
6077 const char *p;
6078 for (p=beg, nargs=0; p <= end; ++argvp)
6079 {
6080 const char *next;
6081
6082 ++nargs;
6083
6084 if (nargs == entry_p->maximum_args
6085 || (! (next = find_next_argument (openparen, closeparen, p, end))))
6086 next = end;
6087
6088 *argvp = expand_argument (p, next);
6089 p = next + 1;
6090 }
6091 }
6092 else
6093 {
6094 int len = end - beg;
6095 char *p, *aend;
6096
6097 abeg = xmalloc (len+1);
6098 memcpy (abeg, beg, len);
6099 abeg[len] = '\0';
6100 aend = abeg + len;
6101
6102 for (p=abeg, nargs=0; p <= aend; ++argvp)
6103 {
6104 char *next;
6105
6106 ++nargs;
6107
6108 if (nargs == entry_p->maximum_args
6109 || (! (next = find_next_argument (openparen, closeparen, p, aend))))
6110 next = aend;
6111
6112 *argvp = p;
6113 *next = '\0';
6114 p = next + 1;
6115 }
6116 }
6117 *argvp = NULL;
6118
6119 /* Finally! Run the function... */
6120 *op = expand_builtin_function (*op, nargs, argv, entry_p);
6121
6122 /* Free memory. */
6123 if (entry_p->expand_args)
6124 for (argvp=argv; *argvp != 0; ++argvp)
6125 free (*argvp);
6126 else
6127 free (abeg);
6128
6129 return 1;
6130}
6131
6132
6133int /* bird split it up and hacked it. */
6134#ifndef CONFIG_WITH_VALUE_LENGTH
6135handle_function (char **op, const char **stringp)
6136{
6137 const struct function_table_entry *entry_p = lookup_function (*stringp + 1);
6138 if (!entry_p)
6139 return 0;
6140 return handle_function2 (entry_p, op, stringp);
6141}
6142#else /* CONFIG_WITH_VALUE_LENGTH */
6143handle_function (char **op, const char **stringp, const char *nameend, const char *eol UNUSED)
6144{
6145 const char *fname = *stringp + 1;
6146 const struct function_table_entry *entry_p =
6147 lookup_function_in_hash_tab (fname, nameend - fname);
6148 if (!entry_p)
6149 return 0;
6150 return handle_function2 (entry_p, op, stringp);
6151}
6152#endif /* CONFIG_WITH_VALUE_LENGTH */
6153
6154#ifdef CONFIG_WITH_COMPILER
6155/* Used by the "compiler" to get all info about potential functions. */
6156make_function_ptr_t
6157lookup_function_for_compiler (const char *name, unsigned int len,
6158 unsigned char *minargsp, unsigned char *maxargsp,
6159 char *expargsp, const char **funcnamep)
6160{
6161 const struct function_table_entry *entry_p = lookup_function (name, len);
6162 if (!entry_p)
6163 return 0;
6164 *minargsp = entry_p->minimum_args;
6165 *maxargsp = entry_p->maximum_args;
6166 *expargsp = entry_p->expand_args;
6167 *funcnamep = entry_p->name;
6168 return entry_p->func_ptr;
6169}
6170#endif /* CONFIG_WITH_COMPILER */
6171
6172
6173
6174/* User-defined functions. Expand the first argument as either a builtin
6175 function or a make variable, in the context of the rest of the arguments
6176 assigned to $1, $2, ... $N. $0 is the name of the function. */
6177
6178static char *
6179func_call (char *o, char **argv, const char *funcname UNUSED)
6180{
6181 static int max_args = 0;
6182 char *fname;
6183 char *body;
6184 int flen;
6185 int i;
6186 int saved_args;
6187 const struct function_table_entry *entry_p;
6188 struct variable *v;
6189#ifdef CONFIG_WITH_EVALPLUS
6190 char *buf;
6191 unsigned int len;
6192#endif
6193#ifdef CONFIG_WITH_VALUE_LENGTH
6194 char *fname_end;
6195#endif
6196#if defined (CONFIG_WITH_EVALPLUS) || defined (CONFIG_WITH_VALUE_LENGTH)
6197 char num[11];
6198#endif
6199
6200 /* Clean up the name of the variable to be invoked. */
6201 fname = next_token (argv[0]);
6202#ifndef CONFIG_WITH_VALUE_LENGTH
6203 end_of_token (fname)[0] = '\0';
6204#else
6205 fname_end = end_of_token (fname);
6206 *fname_end = '\0';
6207#endif
6208
6209 /* Calling nothing is a no-op */
6210#ifndef CONFIG_WITH_VALUE_LENGTH
6211 if (*fname == '\0')
6212#else
6213 if (fname == fname_end)
6214#endif
6215 return o;
6216
6217 /* Are we invoking a builtin function? */
6218
6219#ifndef CONFIG_WITH_VALUE_LENGTH
6220 entry_p = lookup_function (fname);
6221#else
6222 entry_p = lookup_function (fname, fname_end - fname);
6223#endif
6224 if (entry_p)
6225 {
6226 /* How many arguments do we have? */
6227 for (i=0; argv[i+1]; ++i)
6228 ;
6229 return expand_builtin_function (o, i, argv+1, entry_p);
6230 }
6231
6232 /* Not a builtin, so the first argument is the name of a variable to be
6233 expanded and interpreted as a function. Find it. */
6234 flen = strlen (fname);
6235
6236 v = lookup_variable (fname, flen);
6237
6238 if (v == 0)
6239 warn_undefined (fname, flen);
6240
6241 if (v == 0 || *v->value == '\0')
6242 return o;
6243
6244 body = alloca (flen + 4);
6245 body[0] = '$';
6246 body[1] = '(';
6247 memcpy (body + 2, fname, flen);
6248 body[flen+2] = ')';
6249 body[flen+3] = '\0';
6250
6251 /* Set up arguments $(1) .. $(N). $(0) is the function name. */
6252
6253 push_new_variable_scope ();
6254
6255 for (i=0; *argv; ++i, ++argv)
6256#ifdef CONFIG_WITH_VALUE_LENGTH
6257 define_variable (num, sprintf (num, "%d", i), *argv, o_automatic, 0);
6258#else
6259 {
6260 char num[11];
6261
6262 sprintf (num, "%d", i);
6263 define_variable (num, strlen (num), *argv, o_automatic, 0);
6264 }
6265#endif
6266
6267#ifdef CONFIG_WITH_EVALPLUS
6268 /* $(.ARGC) is the argument count. */
6269
6270 len = sprintf (num, "%d", i - 1);
6271 define_variable_vl (".ARGC", sizeof (".ARGC") - 1, num, len,
6272 1 /* dup val */, o_automatic, 0);
6273#endif
6274
6275 /* If the number of arguments we have is < max_args, it means we're inside
6276 a recursive invocation of $(call ...). Fill in the remaining arguments
6277 in the new scope with the empty value, to hide them from this
6278 invocation. */
6279
6280 for (; i < max_args; ++i)
6281#ifdef CONFIG_WITH_VALUE_LENGTH
6282 define_variable (num, sprintf (num, "%d", i), "", o_automatic, 0);
6283#else
6284 {
6285 char num[11];
6286
6287 sprintf (num, "%d", i);
6288 define_variable (num, strlen (num), "", o_automatic, 0);
6289 }
6290#endif
6291
6292 saved_args = max_args;
6293 max_args = i;
6294
6295#ifdef CONFIG_WITH_EVALPLUS
6296 if (!strcmp (funcname, "call"))
6297 {
6298#endif
6299 /* Expand the body in the context of the arguments, adding the result to
6300 the variable buffer. */
6301
6302 v->exp_count = EXP_COUNT_MAX;
6303#ifndef CONFIG_WITH_VALUE_LENGTH
6304 o = variable_expand_string (o, body, flen+3);
6305 v->exp_count = 0;
6306
6307 o += strlen (o);
6308#else /* CONFIG_WITH_VALUE_LENGTH */
6309 variable_expand_string_2 (o, body, flen+3, &o);
6310 v->exp_count = 0;
6311#endif /* CONFIG_WITH_VALUE_LENGTH */
6312#ifdef CONFIG_WITH_EVALPLUS
6313 }
6314 else
6315 {
6316 const floc *reading_file_saved = reading_file;
6317 char *eos;
6318
6319 if (!strcmp (funcname, "evalcall"))
6320 {
6321 /* Evaluate the variable value without expanding it. We
6322 need a copy since eval_buffer is destructive. */
6323
6324 size_t off = o - variable_buffer;
6325 eos = variable_buffer_output (o, v->value, v->value_length + 1) - 1;
6326 o = variable_buffer + off;
6327 if (v->fileinfo.filenm)
6328 reading_file = &v->fileinfo;
6329 }
6330 else
6331 {
6332 /* Expand the body first and then evaluate the output. */
6333
6334 v->exp_count = EXP_COUNT_MAX;
6335 o = variable_expand_string_2 (o, body, flen+3, &eos);
6336 v->exp_count = 0;
6337 }
6338
6339 install_variable_buffer (&buf, &len);
6340 eval_buffer (o, NULL, eos);
6341 restore_variable_buffer (buf, len);
6342 reading_file = reading_file_saved;
6343
6344 /* Deal with the .RETURN value if present. */
6345
6346 v = lookup_variable_in_set (".RETURN", sizeof (".RETURN") - 1,
6347 current_variable_set_list->set);
6348 if (v && v->value_length)
6349 {
6350 if (v->recursive && !IS_VARIABLE_RECURSIVE_WITHOUT_DOLLAR (v))
6351 {
6352 v->exp_count = EXP_COUNT_MAX;
6353 variable_expand_string_2 (o, v->value, v->value_length, &o);
6354 v->exp_count = 0;
6355 }
6356 else
6357 o = variable_buffer_output (o, v->value, v->value_length);
6358 }
6359 }
6360#endif /* CONFIG_WITH_EVALPLUS */
6361
6362 max_args = saved_args;
6363
6364 pop_variable_scope ();
6365
6366 return o;
6367}
6368
6369void
6370define_new_function (const floc *flocp, const char *name,
6371 unsigned int min, unsigned int max, unsigned int flags,
6372 gmk_func_ptr func)
6373{
6374 const char *e = name;
6375 struct function_table_entry *ent;
6376 size_t len;
6377
6378 while (STOP_SET (*e, MAP_USERFUNC))
6379 e++;
6380 len = e - name;
6381
6382 if (len == 0)
6383 O (fatal, flocp, _("Empty function name"));
6384 if (*name == '.' || *e != '\0')
6385 OS (fatal, flocp, _("Invalid function name: %s"), name);
6386 if (len > 255)
6387 OS (fatal, flocp, _("Function name too long: %s"), name);
6388 if (min > 255)
6389 ONS (fatal, flocp,
6390 _("Invalid minimum argument count (%u) for function %s"), min, name);
6391 if (max > 255 || (max && max < min))
6392 ONS (fatal, flocp,
6393 _("Invalid maximum argument count (%u) for function %s"), max, name);
6394
6395 ent = xmalloc (sizeof (struct function_table_entry));
6396 ent->name = name;
6397 ent->len = len;
6398 ent->minimum_args = min;
6399 ent->maximum_args = max;
6400 ent->expand_args = ANY_SET(flags, GMK_FUNC_NOEXPAND) ? 0 : 1;
6401 ent->alloc_fn = 1;
6402 ent->fptr.alloc_func_ptr = func;
6403
6404 hash_insert (&function_table, ent);
6405}
6406
6407void
6408hash_init_function_table (void)
6409{
6410 hash_init (&function_table, FUNCTION_TABLE_ENTRIES * 2,
6411 function_table_entry_hash_1, function_table_entry_hash_2,
6412 function_table_entry_hash_cmp);
6413 hash_load (&function_table, function_table_init,
6414 FUNCTION_TABLE_ENTRIES, sizeof (struct function_table_entry));
6415#if defined (CONFIG_WITH_OPTIMIZATION_HACKS) || defined (CONFIG_WITH_VALUE_LENGTH)
6416 {
6417 unsigned int i;
6418 for (i = 0; i < FUNCTION_TABLE_ENTRIES; i++)
6419 {
6420 const char *fn = function_table_init[i].name;
6421 while (*fn)
6422 {
6423 func_char_map[(int)*fn] = 1;
6424 fn++;
6425 }
6426 assert (function_table_init[i].len <= MAX_FUNCTION_LENGTH);
6427 assert (function_table_init[i].len >= MIN_FUNCTION_LENGTH);
6428 }
6429 }
6430#endif
6431}
Note: See TracBrowser for help on using the repository browser.

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