VirtualBox

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

Last change on this file since 1739 was 1727, checked in by bird, 16 years ago

kmk: Two new functions $(if-expr cond,exp-on-true,exp-on-false) and $(expr expression) that uses the expreval.c expression evaluator.

  • Property svn:eol-style set to native
File size: 114.3 KB
Line 
1/* Builtin function expansion for GNU Make.
2Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
31998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software
4Foundation, Inc.
5This file is part of GNU Make.
6
7GNU Make is free software; you can redistribute it and/or modify it under the
8terms of the GNU General Public License as published by the Free Software
9Foundation; either version 2, or (at your option) any later version.
10
11GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License along with
16GNU Make; see the file COPYING. If not, write to the Free Software
17Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */
18
19#include "make.h"
20#include "filedef.h"
21#include "variable.h"
22#include "dep.h"
23#include "job.h"
24#include "commands.h"
25#include "debug.h"
26
27#ifdef _AMIGA
28#include "amiga.h"
29#endif
30
31#ifdef WINDOWS32 /* bird */
32# include "pathstuff.h"
33#endif
34
35#ifdef KMK_HELPERS
36# include "kbuild.h"
37#endif
38#ifdef CONFIG_WITH_XARGS /* bird */
39# ifdef HAVE_LIMITS_H
40# include <limits.h>
41# endif
42#endif
43#include <assert.h> /* bird */
44
45#if defined (CONFIG_WITH_MATH) || defined (CONFIG_WITH_NANOTS) || defined (CONFIG_WITH_FILE_SIZE) /* bird */
46# include <ctype.h>
47# ifdef _MSC_VER
48typedef __int64 math_int;
49# else
50# include <stdint.h>
51typedef int64_t math_int;
52# endif
53static char *math_int_to_variable_buffer (char *, math_int);
54#endif
55
56#ifdef CONFIG_WITH_NANOTS /* bird */
57# ifdef WINDOWS32
58# include <Windows.h>
59# endif
60#endif
61
62#ifdef __OS2__
63# define CONFIG_WITH_OS2_LIBPATH 1
64#endif
65#ifdef CONFIG_WITH_OS2_LIBPATH
66# define INCL_BASE
67# define INCL_ERRROS
68# include <os2.h>
69
70# define QHINF_EXEINFO 1 /* NE exeinfo. */
71# define QHINF_READRSRCTBL 2 /* Reads from the resource table. */
72# define QHINF_READFILE 3 /* Reads from the executable file. */
73# define QHINF_LIBPATHLENGTH 4 /* Gets the libpath length. */
74# define QHINF_LIBPATH 5 /* Gets the entire libpath. */
75# define QHINF_FIXENTRY 6 /* NE only */
76# define QHINF_STE 7 /* NE only */
77# define QHINF_MAPSEL 8 /* NE only */
78 extern APIRET APIENTRY DosQueryHeaderInfo(HMODULE hmod, ULONG ulIndex, PVOID pvBuffer, ULONG cbBuffer, ULONG ulSubFunction);
79#endif /* CONFIG_WITH_OS2_LIBPATH */
80
81
82struct function_table_entry
83 {
84 const char *name;
85 unsigned char len;
86 unsigned char minimum_args;
87 unsigned char maximum_args;
88 char expand_args;
89 char *(*func_ptr) (char *output, char **argv, const char *fname);
90 };
91
92static unsigned long
93function_table_entry_hash_1 (const void *keyv)
94{
95 const struct function_table_entry *key = keyv;
96 return_STRING_N_HASH_1 (key->name, key->len);
97}
98
99static unsigned long
100function_table_entry_hash_2 (const void *keyv)
101{
102 const struct function_table_entry *key = keyv;
103 return_STRING_N_HASH_2 (key->name, key->len);
104}
105
106static int
107function_table_entry_hash_cmp (const void *xv, const void *yv)
108{
109 const struct function_table_entry *x = xv;
110 const struct function_table_entry *y = yv;
111 int result = x->len - y->len;
112 if (result)
113 return result;
114 return_STRING_N_COMPARE (x->name, y->name, x->len);
115}
116
117static struct hash_table function_table;
118
119#ifdef CONFIG_WITH_MAKE_STATS
120unsigned long make_stats_allocations = 0;
121unsigned long make_stats_allocated = 0;
122unsigned long make_stats_allocated_sum = 0;
123unsigned long make_stats_ht_lookups = 0;
124unsigned long make_stats_ht_collisions = 0;
125#endif
126
127
128
129/* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing
130 each occurrence of SUBST with REPLACE. TEXT is null-terminated. SLEN is
131 the length of SUBST and RLEN is the length of REPLACE. If BY_WORD is
132 nonzero, substitutions are done only on matches which are complete
133 whitespace-delimited words. */
134
135char *
136subst_expand (char *o, const char *text, const char *subst, const char *replace,
137 unsigned int slen, unsigned int rlen, int by_word)
138{
139 const char *t = text;
140 const char *p;
141
142 if (slen == 0 && !by_word)
143 {
144 /* The first occurrence of "" in any string is its end. */
145 o = variable_buffer_output (o, t, strlen (t));
146 if (rlen > 0)
147 o = variable_buffer_output (o, replace, rlen);
148 return o;
149 }
150
151 do
152 {
153 if (by_word && slen == 0)
154 /* When matching by words, the empty string should match
155 the end of each word, rather than the end of the whole text. */
156 p = end_of_token (next_token (t));
157 else
158 {
159 p = strstr (t, subst);
160 if (p == 0)
161 {
162 /* No more matches. Output everything left on the end. */
163 o = variable_buffer_output (o, t, strlen (t));
164 return o;
165 }
166 }
167
168 /* Output everything before this occurrence of the string to replace. */
169 if (p > t)
170 o = variable_buffer_output (o, t, p - t);
171
172 /* If we're substituting only by fully matched words,
173 or only at the ends of words, check that this case qualifies. */
174 if (by_word
175 && ((p > text && !isblank ((unsigned char)p[-1]))
176 || (p[slen] != '\0' && !isblank ((unsigned char)p[slen]))))
177 /* Struck out. Output the rest of the string that is
178 no longer to be replaced. */
179 o = variable_buffer_output (o, subst, slen);
180 else if (rlen > 0)
181 /* Output the replacement string. */
182 o = variable_buffer_output (o, replace, rlen);
183
184 /* Advance T past the string to be replaced. */
185 t = p + slen;
186 } while (*t != '\0');
187
188 return o;
189}
190
191
192
193/* Store into VARIABLE_BUFFER at O the result of scanning TEXT
194 and replacing strings matching PATTERN with REPLACE.
195 If PATTERN_PERCENT is not nil, PATTERN has already been
196 run through find_percent, and PATTERN_PERCENT is the result.
197 If REPLACE_PERCENT is not nil, REPLACE has already been
198 run through find_percent, and REPLACE_PERCENT is the result.
199 Note that we expect PATTERN_PERCENT and REPLACE_PERCENT to point to the
200 character _AFTER_ the %, not to the % itself.
201*/
202
203char *
204patsubst_expand_pat (char *o, const char *text,
205 const char *pattern, const char *replace,
206 const char *pattern_percent, const char *replace_percent)
207{
208 unsigned int pattern_prepercent_len, pattern_postpercent_len;
209 unsigned int replace_prepercent_len, replace_postpercent_len;
210 const char *t;
211 unsigned int len;
212 int doneany = 0;
213
214 /* Record the length of REPLACE before and after the % so we don't have to
215 compute these lengths more than once. */
216 if (replace_percent)
217 {
218 replace_prepercent_len = replace_percent - replace - 1;
219 replace_postpercent_len = strlen (replace_percent);
220 }
221 else
222 {
223 replace_prepercent_len = strlen (replace);
224 replace_postpercent_len = 0;
225 }
226
227 if (!pattern_percent)
228 /* With no % in the pattern, this is just a simple substitution. */
229 return subst_expand (o, text, pattern, replace,
230 strlen (pattern), strlen (replace), 1);
231
232 /* Record the length of PATTERN before and after the %
233 so we don't have to compute it more than once. */
234 pattern_prepercent_len = pattern_percent - pattern - 1;
235 pattern_postpercent_len = strlen (pattern_percent);
236
237 while ((t = find_next_token (&text, &len)) != 0)
238 {
239 int fail = 0;
240
241 /* Is it big enough to match? */
242 if (len < pattern_prepercent_len + pattern_postpercent_len)
243 fail = 1;
244
245 /* Does the prefix match? */
246 if (!fail && pattern_prepercent_len > 0
247 && (*t != *pattern
248 || t[pattern_prepercent_len - 1] != pattern_percent[-2]
249 || !strneq (t + 1, pattern + 1, pattern_prepercent_len - 1)))
250 fail = 1;
251
252 /* Does the suffix match? */
253 if (!fail && pattern_postpercent_len > 0
254 && (t[len - 1] != pattern_percent[pattern_postpercent_len - 1]
255 || t[len - pattern_postpercent_len] != *pattern_percent
256 || !strneq (&t[len - pattern_postpercent_len],
257 pattern_percent, pattern_postpercent_len - 1)))
258 fail = 1;
259
260 if (fail)
261 /* It didn't match. Output the string. */
262 o = variable_buffer_output (o, t, len);
263 else
264 {
265 /* It matched. Output the replacement. */
266
267 /* Output the part of the replacement before the %. */
268 o = variable_buffer_output (o, replace, replace_prepercent_len);
269
270 if (replace_percent != 0)
271 {
272 /* Output the part of the matched string that
273 matched the % in the pattern. */
274 o = variable_buffer_output (o, t + pattern_prepercent_len,
275 len - (pattern_prepercent_len
276 + pattern_postpercent_len));
277 /* Output the part of the replacement after the %. */
278 o = variable_buffer_output (o, replace_percent,
279 replace_postpercent_len);
280 }
281 }
282
283 /* Output a space, but not if the replacement is "". */
284 if (fail || replace_prepercent_len > 0
285 || (replace_percent != 0 && len + replace_postpercent_len > 0))
286 {
287 o = variable_buffer_output (o, " ", 1);
288 doneany = 1;
289 }
290 }
291 if (doneany)
292 /* Kill the last space. */
293 --o;
294
295 return o;
296}
297
298/* Store into VARIABLE_BUFFER at O the result of scanning TEXT
299 and replacing strings matching PATTERN with REPLACE.
300 If PATTERN_PERCENT is not nil, PATTERN has already been
301 run through find_percent, and PATTERN_PERCENT is the result.
302 If REPLACE_PERCENT is not nil, REPLACE has already been
303 run through find_percent, and REPLACE_PERCENT is the result.
304 Note that we expect PATTERN_PERCENT and REPLACE_PERCENT to point to the
305 character _AFTER_ the %, not to the % itself.
306*/
307
308char *
309patsubst_expand (char *o, const char *text, char *pattern, char *replace)
310{
311 const char *pattern_percent = find_percent (pattern);
312 const char *replace_percent = find_percent (replace);
313
314 /* If there's a percent in the pattern or replacement skip it. */
315 if (replace_percent)
316 ++replace_percent;
317 if (pattern_percent)
318 ++pattern_percent;
319
320 return patsubst_expand_pat (o, text, pattern, replace,
321 pattern_percent, replace_percent);
322}
323
324
325#ifdef CONFIG_WITH_OPTIMIZATION_HACKS
326/* The maximum length of a function, once reached there is
327 it can't be function and we can skip the hash lookup drop out. */
328
329# ifdef KMK
330# define MAX_FUNCTION_LENGTH 12
331# else
332# define MAX_FUNCTION_LENGTH 10
333# endif
334#endif /* CONFIG_WITH_OPTIMIZATION_HACKS */
335
336/* Look up a function by name. */
337
338#ifdef CONFIG_WITH_OPTIMIZATION_HACKS
339__inline
340#endif /* CONFIG_WITH_OPTIMIZATION_HACKS */
341static const struct function_table_entry *
342lookup_function (const char *s)
343{
344 const char *e = s;
345#ifdef CONFIG_WITH_OPTIMIZATION_HACKS
346 int left = MAX_FUNCTION_LENGTH;
347 int ch;
348 while (((ch = *e) >= 'a' && ch <='z') || ch == '-')
349 {
350 if (!left--)
351 return 0;
352 e++;
353 }
354#else
355 while (*e && ( (*e >= 'a' && *e <= 'z') || *e == '-'))
356 e++;
357#endif
358 if (*e == '\0' || isblank ((unsigned char) *e))
359 {
360 struct function_table_entry function_table_entry_key;
361 function_table_entry_key.name = s;
362 function_table_entry_key.len = e - s;
363
364 return hash_find_item (&function_table, &function_table_entry_key);
365 }
366 return 0;
367}
368
369
370
371/* Return 1 if PATTERN matches STR, 0 if not. */
372
373int
374pattern_matches (const char *pattern, const char *percent, const char *str)
375{
376 unsigned int sfxlen, strlength;
377
378 if (percent == 0)
379 {
380 unsigned int len = strlen (pattern) + 1;
381 char *new_chars = alloca (len);
382 memcpy (new_chars, pattern, len);
383 percent = find_percent (new_chars);
384 if (percent == 0)
385 return streq (new_chars, str);
386 pattern = new_chars;
387 }
388
389 sfxlen = strlen (percent + 1);
390 strlength = strlen (str);
391
392 if (strlength < (percent - pattern) + sfxlen
393 || !strneq (pattern, str, percent - pattern))
394 return 0;
395
396 return !strcmp (percent + 1, str + (strlength - sfxlen));
397}
398
399
400
401/* Find the next comma or ENDPAREN (counting nested STARTPAREN and
402 ENDPARENtheses), starting at PTR before END. Return a pointer to
403 next character.
404
405 If no next argument is found, return NULL.
406*/
407
408static char *
409find_next_argument (char startparen, char endparen,
410 const char *ptr, const char *end)
411{
412 int count = 0;
413
414 for (; ptr < end; ++ptr)
415 if (*ptr == startparen)
416 ++count;
417
418 else if (*ptr == endparen)
419 {
420 --count;
421 if (count < 0)
422 return NULL;
423 }
424
425 else if (*ptr == ',' && !count)
426 return (char *)ptr;
427
428 /* We didn't find anything. */
429 return NULL;
430}
431
432
433
434/* Glob-expand LINE. The returned pointer is
435 only good until the next call to string_glob. */
436
437static char *
438string_glob (char *line)
439{
440 static char *result = 0;
441 static unsigned int length;
442 struct nameseq *chain;
443 unsigned int idx;
444
445 chain = multi_glob (parse_file_seq
446 (&line, '\0', sizeof (struct nameseq),
447 /* We do not want parse_file_seq to strip `./'s.
448 That would break examples like:
449 $(patsubst ./%.c,obj/%.o,$(wildcard ./?*.c)). */
450 0),
451 sizeof (struct nameseq));
452
453 if (result == 0)
454 {
455 length = 100;
456 result = xmalloc (100);
457 }
458
459 idx = 0;
460 while (chain != 0)
461 {
462 const char *name = chain->name;
463 unsigned int len = strlen (name);
464
465 struct nameseq *next = chain->next;
466 free (chain);
467 chain = next;
468
469 /* multi_glob will pass names without globbing metacharacters
470 through as is, but we want only files that actually exist. */
471 if (file_exists_p (name))
472 {
473 if (idx + len + 1 > length)
474 {
475 length += (len + 1) * 2;
476 result = xrealloc (result, length);
477 }
478 memcpy (&result[idx], name, len);
479 idx += len;
480 result[idx++] = ' ';
481 }
482 }
483
484 /* Kill the last space and terminate the string. */
485 if (idx == 0)
486 result[0] = '\0';
487 else
488 result[idx - 1] = '\0';
489
490 return result;
491}
492
493
494/*
495 Builtin functions
496 */
497
498static char *
499func_patsubst (char *o, char **argv, const char *funcname UNUSED)
500{
501 o = patsubst_expand (o, argv[2], argv[0], argv[1]);
502 return o;
503}
504
505
506static char *
507func_join (char *o, char **argv, const char *funcname UNUSED)
508{
509 int doneany = 0;
510
511 /* Write each word of the first argument directly followed
512 by the corresponding word of the second argument.
513 If the two arguments have a different number of words,
514 the excess words are just output separated by blanks. */
515 const char *tp;
516 const char *pp;
517 const char *list1_iterator = argv[0];
518 const char *list2_iterator = argv[1];
519 do
520 {
521 unsigned int len1, len2;
522
523 tp = find_next_token (&list1_iterator, &len1);
524 if (tp != 0)
525 o = variable_buffer_output (o, tp, len1);
526
527 pp = find_next_token (&list2_iterator, &len2);
528 if (pp != 0)
529 o = variable_buffer_output (o, pp, len2);
530
531 if (tp != 0 || pp != 0)
532 {
533 o = variable_buffer_output (o, " ", 1);
534 doneany = 1;
535 }
536 }
537 while (tp != 0 || pp != 0);
538 if (doneany)
539 /* Kill the last blank. */
540 --o;
541
542 return o;
543}
544
545
546static char *
547func_origin (char *o, char **argv, const char *funcname UNUSED)
548{
549 /* Expand the argument. */
550 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
551 if (v == 0)
552 o = variable_buffer_output (o, "undefined", 9);
553 else
554 switch (v->origin)
555 {
556 default:
557 case o_invalid:
558 abort ();
559 break;
560 case o_default:
561 o = variable_buffer_output (o, "default", 7);
562 break;
563 case o_env:
564 o = variable_buffer_output (o, "environment", 11);
565 break;
566 case o_file:
567 o = variable_buffer_output (o, "file", 4);
568 break;
569 case o_env_override:
570 o = variable_buffer_output (o, "environment override", 20);
571 break;
572 case o_command:
573 o = variable_buffer_output (o, "command line", 12);
574 break;
575 case o_override:
576 o = variable_buffer_output (o, "override", 8);
577 break;
578 case o_automatic:
579 o = variable_buffer_output (o, "automatic", 9);
580 break;
581#ifdef CONFIG_WITH_LOCAL_VARIABLES
582 case o_local:
583 o = variable_buffer_output (o, "local", 5);
584 break;
585#endif
586 }
587
588 return o;
589}
590
591static char *
592func_flavor (char *o, char **argv, const char *funcname UNUSED)
593{
594 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
595
596 if (v == 0)
597 o = variable_buffer_output (o, "undefined", 9);
598 else
599 if (v->recursive)
600 o = variable_buffer_output (o, "recursive", 9);
601 else
602 o = variable_buffer_output (o, "simple", 6);
603
604 return o;
605}
606
607#ifdef VMS
608# define IS_PATHSEP(c) ((c) == ']')
609#else
610# ifdef HAVE_DOS_PATHS
611# define IS_PATHSEP(c) ((c) == '/' || (c) == '\\')
612# else
613# define IS_PATHSEP(c) ((c) == '/')
614# endif
615#endif
616
617
618static char *
619func_notdir_suffix (char *o, char **argv, const char *funcname)
620{
621 /* Expand the argument. */
622 const char *list_iterator = argv[0];
623 const char *p2;
624 int doneany =0;
625 unsigned int len=0;
626
627 int is_suffix = streq (funcname, "suffix");
628 int is_notdir = !is_suffix;
629 while ((p2 = find_next_token (&list_iterator, &len)) != 0)
630 {
631 const char *p = p2 + len;
632
633
634 while (p >= p2 && (!is_suffix || *p != '.'))
635 {
636 if (IS_PATHSEP (*p))
637 break;
638 --p;
639 }
640
641 if (p >= p2)
642 {
643 if (is_notdir)
644 ++p;
645 else if (*p != '.')
646 continue;
647 o = variable_buffer_output (o, p, len - (p - p2));
648 }
649#ifdef HAVE_DOS_PATHS
650 /* Handle the case of "d:foo/bar". */
651 else if (streq (funcname, "notdir") && p2[0] && p2[1] == ':')
652 {
653 p = p2 + 2;
654 o = variable_buffer_output (o, p, len - (p - p2));
655 }
656#endif
657 else if (is_notdir)
658 o = variable_buffer_output (o, p2, len);
659
660 if (is_notdir || p >= p2)
661 {
662 o = variable_buffer_output (o, " ", 1);
663 doneany = 1;
664 }
665 }
666
667 if (doneany)
668 /* Kill last space. */
669 --o;
670
671 return o;
672}
673
674
675static char *
676func_basename_dir (char *o, char **argv, const char *funcname)
677{
678 /* Expand the argument. */
679 const char *p3 = argv[0];
680 const char *p2;
681 int doneany=0;
682 unsigned int len=0;
683
684 int is_basename= streq (funcname, "basename");
685 int is_dir= !is_basename;
686
687 while ((p2 = find_next_token (&p3, &len)) != 0)
688 {
689 const char *p = p2 + len;
690 while (p >= p2 && (!is_basename || *p != '.'))
691 {
692 if (IS_PATHSEP (*p))
693 break;
694 --p;
695 }
696
697 if (p >= p2 && (is_dir))
698 o = variable_buffer_output (o, p2, ++p - p2);
699 else if (p >= p2 && (*p == '.'))
700 o = variable_buffer_output (o, p2, p - p2);
701#ifdef HAVE_DOS_PATHS
702 /* Handle the "d:foobar" case */
703 else if (p2[0] && p2[1] == ':' && is_dir)
704 o = variable_buffer_output (o, p2, 2);
705#endif
706 else if (is_dir)
707#ifdef VMS
708 o = variable_buffer_output (o, "[]", 2);
709#else
710#ifndef _AMIGA
711 o = variable_buffer_output (o, "./", 2);
712#else
713 ; /* Just a nop... */
714#endif /* AMIGA */
715#endif /* !VMS */
716 else
717 /* The entire name is the basename. */
718 o = variable_buffer_output (o, p2, len);
719
720 o = variable_buffer_output (o, " ", 1);
721 doneany = 1;
722 }
723
724 if (doneany)
725 /* Kill last space. */
726 --o;
727
728 return o;
729}
730
731static char *
732func_addsuffix_addprefix (char *o, char **argv, const char *funcname)
733{
734 int fixlen = strlen (argv[0]);
735 const char *list_iterator = argv[1];
736 int is_addprefix = streq (funcname, "addprefix");
737 int is_addsuffix = !is_addprefix;
738
739 int doneany = 0;
740 const char *p;
741 unsigned int len;
742
743 while ((p = find_next_token (&list_iterator, &len)) != 0)
744 {
745 if (is_addprefix)
746 o = variable_buffer_output (o, argv[0], fixlen);
747 o = variable_buffer_output (o, p, len);
748 if (is_addsuffix)
749 o = variable_buffer_output (o, argv[0], fixlen);
750 o = variable_buffer_output (o, " ", 1);
751 doneany = 1;
752 }
753
754 if (doneany)
755 /* Kill last space. */
756 --o;
757
758 return o;
759}
760
761static char *
762func_subst (char *o, char **argv, const char *funcname UNUSED)
763{
764 o = subst_expand (o, argv[2], argv[0], argv[1], strlen (argv[0]),
765 strlen (argv[1]), 0);
766
767 return o;
768}
769
770
771static char *
772func_firstword (char *o, char **argv, const char *funcname UNUSED)
773{
774 unsigned int i;
775 const char *words = argv[0]; /* Use a temp variable for find_next_token */
776 const char *p = find_next_token (&words, &i);
777
778 if (p != 0)
779 o = variable_buffer_output (o, p, i);
780
781 return o;
782}
783
784static char *
785func_lastword (char *o, char **argv, const char *funcname UNUSED)
786{
787 unsigned int i;
788 const char *words = argv[0]; /* Use a temp variable for find_next_token */
789 const char *p = NULL;
790 const char *t;
791
792 while ((t = find_next_token (&words, &i)))
793 p = t;
794
795 if (p != 0)
796 o = variable_buffer_output (o, p, i);
797
798 return o;
799}
800
801static char *
802func_words (char *o, char **argv, const char *funcname UNUSED)
803{
804 int i = 0;
805 const char *word_iterator = argv[0];
806 char buf[20];
807
808 while (find_next_token (&word_iterator, (unsigned int *) 0) != 0)
809 ++i;
810
811 sprintf (buf, "%d", i);
812 o = variable_buffer_output (o, buf, strlen (buf));
813
814 return o;
815}
816
817/* Set begpp to point to the first non-whitespace character of the string,
818 * and endpp to point to the last non-whitespace character of the string.
819 * If the string is empty or contains nothing but whitespace, endpp will be
820 * begpp-1.
821 */
822char *
823strip_whitespace (const char **begpp, const char **endpp)
824{
825 while (*begpp <= *endpp && isspace ((unsigned char)**begpp))
826 (*begpp) ++;
827 while (*endpp >= *begpp && isspace ((unsigned char)**endpp))
828 (*endpp) --;
829 return (char *)*begpp;
830}
831
832static void
833check_numeric (const char *s, const char *msg)
834{
835 const char *end = s + strlen (s) - 1;
836 const char *beg = s;
837 strip_whitespace (&s, &end);
838
839 for (; s <= end; ++s)
840 if (!ISDIGIT (*s)) /* ISDIGIT only evals its arg once: see make.h. */
841 break;
842
843 if (s <= end || end - beg < 0)
844 fatal (*expanding_var, "%s: '%s'", msg, beg);
845}
846
847
848
849static char *
850func_word (char *o, char **argv, const char *funcname UNUSED)
851{
852 const char *end_p;
853 const char *p;
854 int i;
855
856 /* Check the first argument. */
857 check_numeric (argv[0], _("non-numeric first argument to `word' function"));
858 i = atoi (argv[0]);
859
860 if (i == 0)
861 fatal (*expanding_var,
862 _("first argument to `word' function must be greater than 0"));
863
864 end_p = argv[1];
865 while ((p = find_next_token (&end_p, 0)) != 0)
866 if (--i == 0)
867 break;
868
869 if (i == 0)
870 o = variable_buffer_output (o, p, end_p - p);
871
872 return o;
873}
874
875static char *
876func_wordlist (char *o, char **argv, const char *funcname UNUSED)
877{
878 int start, count;
879
880 /* Check the arguments. */
881 check_numeric (argv[0],
882 _("non-numeric first argument to `wordlist' function"));
883 check_numeric (argv[1],
884 _("non-numeric second argument to `wordlist' function"));
885
886 start = atoi (argv[0]);
887 if (start < 1)
888 fatal (*expanding_var,
889 "invalid first argument to `wordlist' function: `%d'", start);
890
891 count = atoi (argv[1]) - start + 1;
892
893 if (count > 0)
894 {
895 const char *p;
896 const char *end_p = argv[2];
897
898 /* Find the beginning of the "start"th word. */
899 while (((p = find_next_token (&end_p, 0)) != 0) && --start)
900 ;
901
902 if (p)
903 {
904 /* Find the end of the "count"th word from start. */
905 while (--count && (find_next_token (&end_p, 0) != 0))
906 ;
907
908 /* Return the stuff in the middle. */
909 o = variable_buffer_output (o, p, end_p - p);
910 }
911 }
912
913 return o;
914}
915
916static char *
917func_findstring (char *o, char **argv, const char *funcname UNUSED)
918{
919 /* Find the first occurrence of the first string in the second. */
920 if (strstr (argv[1], argv[0]) != 0)
921 o = variable_buffer_output (o, argv[0], strlen (argv[0]));
922
923 return o;
924}
925
926static char *
927func_foreach (char *o, char **argv, const char *funcname UNUSED)
928{
929 /* expand only the first two. */
930 char *varname = expand_argument (argv[0], NULL);
931 char *list = expand_argument (argv[1], NULL);
932 const char *body = argv[2];
933
934 int doneany = 0;
935 const char *list_iterator = list;
936 const char *p;
937 unsigned int len;
938 struct variable *var;
939
940 push_new_variable_scope ();
941 var = define_variable (varname, strlen (varname), "", o_automatic, 0);
942
943 /* loop through LIST, put the value in VAR and expand BODY */
944 while ((p = find_next_token (&list_iterator, &len)) != 0)
945 {
946 char *result = 0;
947#ifdef CONFIG_WITH_VALUE_LENGTH
948 if (len >= (unsigned int)var->value_alloc_len)
949 {
950 free (var->value);
951 var->value_alloc_len = (len + 32) & ~31;
952 var->value = xmalloc (var->value_alloc_len);
953 }
954 memcpy (var->value, p, len);
955 var->value[len] = '\0';
956 var->value_length = len;
957#else
958 free (var->value);
959 var->value = savestring (p, len);
960#endif
961
962 result = allocated_variable_expand (body);
963
964 o = variable_buffer_output (o, result, strlen (result));
965 o = variable_buffer_output (o, " ", 1);
966 doneany = 1;
967 free (result);
968 }
969
970 if (doneany)
971 /* Kill the last space. */
972 --o;
973
974 pop_variable_scope ();
975 free (varname);
976 free (list);
977
978 return o;
979}
980
981struct a_word
982{
983 struct a_word *next;
984 struct a_word *chain;
985 char *str;
986 int length;
987 int matched;
988};
989
990static unsigned long
991a_word_hash_1 (const void *key)
992{
993 return_STRING_HASH_1 (((struct a_word const *) key)->str);
994}
995
996static unsigned long
997a_word_hash_2 (const void *key)
998{
999 return_STRING_HASH_2 (((struct a_word const *) key)->str);
1000}
1001
1002static int
1003a_word_hash_cmp (const void *x, const void *y)
1004{
1005 int result = ((struct a_word const *) x)->length - ((struct a_word const *) y)->length;
1006 if (result)
1007 return result;
1008 return_STRING_COMPARE (((struct a_word const *) x)->str,
1009 ((struct a_word const *) y)->str);
1010}
1011
1012struct a_pattern
1013{
1014 struct a_pattern *next;
1015 char *str;
1016 char *percent;
1017 int length;
1018 int save_c;
1019};
1020
1021static char *
1022func_filter_filterout (char *o, char **argv, const char *funcname)
1023{
1024 struct a_word *wordhead;
1025 struct a_word **wordtail;
1026 struct a_word *wp;
1027 struct a_pattern *pathead;
1028 struct a_pattern **pattail;
1029 struct a_pattern *pp;
1030
1031 struct hash_table a_word_table;
1032 int is_filter = streq (funcname, "filter");
1033 const char *pat_iterator = argv[0];
1034 const char *word_iterator = argv[1];
1035 int literals = 0;
1036 int words = 0;
1037 int hashing = 0;
1038 char *p;
1039 unsigned int len;
1040
1041 /* Chop ARGV[0] up into patterns to match against the words. */
1042
1043 pattail = &pathead;
1044 while ((p = find_next_token (&pat_iterator, &len)) != 0)
1045 {
1046 struct a_pattern *pat = alloca (sizeof (struct a_pattern));
1047
1048 *pattail = pat;
1049 pattail = &pat->next;
1050
1051 if (*pat_iterator != '\0')
1052 ++pat_iterator;
1053
1054 pat->str = p;
1055 pat->length = len;
1056 pat->save_c = p[len];
1057 p[len] = '\0';
1058 pat->percent = find_percent (p);
1059 if (pat->percent == 0)
1060 literals++;
1061 }
1062 *pattail = 0;
1063
1064 /* Chop ARGV[1] up into words to match against the patterns. */
1065
1066 wordtail = &wordhead;
1067 while ((p = find_next_token (&word_iterator, &len)) != 0)
1068 {
1069 struct a_word *word = alloca (sizeof (struct a_word));
1070
1071 *wordtail = word;
1072 wordtail = &word->next;
1073
1074 if (*word_iterator != '\0')
1075 ++word_iterator;
1076
1077 p[len] = '\0';
1078 word->str = p;
1079 word->length = len;
1080 word->matched = 0;
1081 word->chain = 0;
1082 words++;
1083 }
1084 *wordtail = 0;
1085
1086 /* Only use a hash table if arg list lengths justifies the cost. */
1087 hashing = (literals >= 2 && (literals * words) >= 10);
1088 if (hashing)
1089 {
1090 hash_init (&a_word_table, words, a_word_hash_1, a_word_hash_2,
1091 a_word_hash_cmp);
1092 for (wp = wordhead; wp != 0; wp = wp->next)
1093 {
1094 struct a_word *owp = hash_insert (&a_word_table, wp);
1095 if (owp)
1096 wp->chain = owp;
1097 }
1098 }
1099
1100 if (words)
1101 {
1102 int doneany = 0;
1103
1104 /* Run each pattern through the words, killing words. */
1105 for (pp = pathead; pp != 0; pp = pp->next)
1106 {
1107 if (pp->percent)
1108 for (wp = wordhead; wp != 0; wp = wp->next)
1109 wp->matched |= pattern_matches (pp->str, pp->percent, wp->str);
1110 else if (hashing)
1111 {
1112 struct a_word a_word_key;
1113 a_word_key.str = pp->str;
1114 a_word_key.length = pp->length;
1115 wp = hash_find_item (&a_word_table, &a_word_key);
1116 while (wp)
1117 {
1118 wp->matched |= 1;
1119 wp = wp->chain;
1120 }
1121 }
1122 else
1123 for (wp = wordhead; wp != 0; wp = wp->next)
1124 wp->matched |= (wp->length == pp->length
1125 && strneq (pp->str, wp->str, wp->length));
1126 }
1127
1128 /* Output the words that matched (or didn't, for filter-out). */
1129 for (wp = wordhead; wp != 0; wp = wp->next)
1130 if (is_filter ? wp->matched : !wp->matched)
1131 {
1132 o = variable_buffer_output (o, wp->str, strlen (wp->str));
1133 o = variable_buffer_output (o, " ", 1);
1134 doneany = 1;
1135 }
1136
1137 if (doneany)
1138 /* Kill the last space. */
1139 --o;
1140 }
1141
1142 for (pp = pathead; pp != 0; pp = pp->next)
1143 pp->str[pp->length] = pp->save_c;
1144
1145 if (hashing)
1146 hash_free (&a_word_table, 0);
1147
1148 return o;
1149}
1150
1151
1152static char *
1153func_strip (char *o, char **argv, const char *funcname UNUSED)
1154{
1155 const char *p = argv[0];
1156 int doneany = 0;
1157
1158 while (*p != '\0')
1159 {
1160 int i=0;
1161 const char *word_start;
1162
1163 while (isspace ((unsigned char)*p))
1164 ++p;
1165 word_start = p;
1166 for (i=0; *p != '\0' && !isspace ((unsigned char)*p); ++p, ++i)
1167 {}
1168 if (!i)
1169 break;
1170 o = variable_buffer_output (o, word_start, i);
1171 o = variable_buffer_output (o, " ", 1);
1172 doneany = 1;
1173 }
1174
1175 if (doneany)
1176 /* Kill the last space. */
1177 --o;
1178
1179 return o;
1180}
1181
1182/*
1183 Print a warning or fatal message.
1184*/
1185static char *
1186func_error (char *o, char **argv, const char *funcname)
1187{
1188 char **argvp;
1189 char *msg, *p;
1190 int len;
1191
1192 /* The arguments will be broken on commas. Rather than create yet
1193 another special case where function arguments aren't broken up,
1194 just create a format string that puts them back together. */
1195 for (len=0, argvp=argv; *argvp != 0; ++argvp)
1196 len += strlen (*argvp) + 2;
1197
1198 p = msg = alloca (len + 1);
1199
1200 for (argvp=argv; argvp[1] != 0; ++argvp)
1201 {
1202 strcpy (p, *argvp);
1203 p += strlen (*argvp);
1204 *(p++) = ',';
1205 *(p++) = ' ';
1206 }
1207 strcpy (p, *argvp);
1208
1209 switch (*funcname) {
1210 case 'e':
1211 fatal (reading_file, "%s", msg);
1212
1213 case 'w':
1214 error (reading_file, "%s", msg);
1215 break;
1216
1217 case 'i':
1218 printf ("%s\n", msg);
1219 fflush(stdout);
1220 break;
1221
1222 default:
1223 fatal (*expanding_var, "Internal error: func_error: '%s'", funcname);
1224 }
1225
1226 /* The warning function expands to the empty string. */
1227 return o;
1228}
1229
1230
1231/*
1232 chop argv[0] into words, and sort them.
1233 */
1234static char *
1235func_sort (char *o, char **argv, const char *funcname UNUSED)
1236{
1237 const char *t;
1238 char **words;
1239 int wordi;
1240 char *p;
1241 unsigned int len;
1242 int i;
1243
1244 /* Find the maximum number of words we'll have. */
1245 t = argv[0];
1246 wordi = 1;
1247 while (*t != '\0')
1248 {
1249 char c = *(t++);
1250
1251 if (! isspace ((unsigned char)c))
1252 continue;
1253
1254 ++wordi;
1255
1256 while (isspace ((unsigned char)*t))
1257 ++t;
1258 }
1259
1260 words = xmalloc (wordi * sizeof (char *));
1261
1262 /* Now assign pointers to each string in the array. */
1263 t = argv[0];
1264 wordi = 0;
1265 while ((p = find_next_token (&t, &len)) != 0)
1266 {
1267 ++t;
1268 p[len] = '\0';
1269 words[wordi++] = p;
1270 }
1271
1272 if (wordi)
1273 {
1274 /* Now sort the list of words. */
1275 qsort (words, wordi, sizeof (char *), alpha_compare);
1276
1277 /* Now write the sorted list, uniquified. */
1278#ifdef CONFIG_WITH_RSORT
1279 if (strcmp (funcname, "rsort"))
1280 {
1281 /* sort */
1282#endif
1283 for (i = 0; i < wordi; ++i)
1284 {
1285 len = strlen (words[i]);
1286 if (i == wordi - 1 || strlen (words[i + 1]) != len
1287 || strcmp (words[i], words[i + 1]))
1288 {
1289 o = variable_buffer_output (o, words[i], len);
1290 o = variable_buffer_output (o, " ", 1);
1291 }
1292 }
1293#ifdef CONFIG_WITH_RSORT
1294 }
1295 else
1296 {
1297 /* rsort - reverse the result */
1298 i = wordi;
1299 while (i-- > 0)
1300 {
1301 len = strlen (words[i]);
1302 if (i == 0 || strlen (words[i - 1]) != len
1303 || strcmp (words[i], words[i - 1]))
1304 {
1305 o = variable_buffer_output (o, words[i], len);
1306 o = variable_buffer_output (o, " ", 1);
1307 }
1308 }
1309 }
1310#endif
1311
1312 /* Kill the last space. */
1313 --o;
1314 }
1315
1316 free (words);
1317
1318 return o;
1319}
1320
1321/*
1322 $(if condition,true-part[,false-part])
1323
1324 CONDITION is false iff it evaluates to an empty string. White
1325 space before and after condition are stripped before evaluation.
1326
1327 If CONDITION is true, then TRUE-PART is evaluated, otherwise FALSE-PART is
1328 evaluated (if it exists). Because only one of the two PARTs is evaluated,
1329 you can use $(if ...) to create side-effects (with $(shell ...), for
1330 example).
1331*/
1332
1333static char *
1334func_if (char *o, char **argv, const char *funcname UNUSED)
1335{
1336 const char *begp = argv[0];
1337 const char *endp = begp + strlen (argv[0]) - 1;
1338 int result = 0;
1339
1340 /* Find the result of the condition: if we have a value, and it's not
1341 empty, the condition is true. If we don't have a value, or it's the
1342 empty string, then it's false. */
1343
1344 strip_whitespace (&begp, &endp);
1345
1346 if (begp <= endp)
1347 {
1348 char *expansion = expand_argument (begp, endp+1);
1349
1350 result = strlen (expansion);
1351 free (expansion);
1352 }
1353
1354 /* If the result is true (1) we want to eval the first argument, and if
1355 it's false (0) we want to eval the second. If the argument doesn't
1356 exist we do nothing, otherwise expand it and add to the buffer. */
1357
1358 argv += 1 + !result;
1359
1360 if (*argv)
1361 {
1362 char *expansion = expand_argument (*argv, NULL);
1363
1364 o = variable_buffer_output (o, expansion, strlen (expansion));
1365
1366 free (expansion);
1367 }
1368
1369 return o;
1370}
1371
1372/*
1373 $(or condition1[,condition2[,condition3[...]]])
1374
1375 A CONDITION is false iff it evaluates to an empty string. White
1376 space before and after CONDITION are stripped before evaluation.
1377
1378 CONDITION1 is evaluated. If it's true, then this is the result of
1379 expansion. If it's false, CONDITION2 is evaluated, and so on. If none of
1380 the conditions are true, the expansion is the empty string.
1381
1382 Once a CONDITION is true no further conditions are evaluated
1383 (short-circuiting).
1384*/
1385
1386static char *
1387func_or (char *o, char **argv, const char *funcname UNUSED)
1388{
1389 for ( ; *argv ; ++argv)
1390 {
1391 const char *begp = *argv;
1392 const char *endp = begp + strlen (*argv) - 1;
1393 char *expansion;
1394 int result = 0;
1395
1396 /* Find the result of the condition: if it's false keep going. */
1397
1398 strip_whitespace (&begp, &endp);
1399
1400 if (begp > endp)
1401 continue;
1402
1403 expansion = expand_argument (begp, endp+1);
1404 result = strlen (expansion);
1405
1406 /* If the result is false keep going. */
1407 if (!result)
1408 {
1409 free (expansion);
1410 continue;
1411 }
1412
1413 /* It's true! Keep this result and return. */
1414 o = variable_buffer_output (o, expansion, result);
1415 free (expansion);
1416 break;
1417 }
1418
1419 return o;
1420}
1421
1422/*
1423 $(and condition1[,condition2[,condition3[...]]])
1424
1425 A CONDITION is false iff it evaluates to an empty string. White
1426 space before and after CONDITION are stripped before evaluation.
1427
1428 CONDITION1 is evaluated. If it's false, then this is the result of
1429 expansion. If it's true, CONDITION2 is evaluated, and so on. If all of
1430 the conditions are true, the expansion is the result of the last condition.
1431
1432 Once a CONDITION is false no further conditions are evaluated
1433 (short-circuiting).
1434*/
1435
1436static char *
1437func_and (char *o, char **argv, const char *funcname UNUSED)
1438{
1439 char *expansion;
1440 int result;
1441
1442 while (1)
1443 {
1444 const char *begp = *argv;
1445 const char *endp = begp + strlen (*argv) - 1;
1446
1447 /* An empty condition is always false. */
1448 strip_whitespace (&begp, &endp);
1449 if (begp > endp)
1450 return o;
1451
1452 expansion = expand_argument (begp, endp+1);
1453 result = strlen (expansion);
1454
1455 /* If the result is false, stop here: we're done. */
1456 if (!result)
1457 break;
1458
1459 /* Otherwise the result is true. If this is the last one, keep this
1460 result and quit. Otherwise go on to the next one! */
1461
1462 if (*(++argv))
1463 free (expansion);
1464 else
1465 {
1466 o = variable_buffer_output (o, expansion, result);
1467 break;
1468 }
1469 }
1470
1471 free (expansion);
1472
1473 return o;
1474}
1475
1476static char *
1477func_wildcard (char *o, char **argv, const char *funcname UNUSED)
1478{
1479#ifdef _AMIGA
1480 o = wildcard_expansion (argv[0], o);
1481#else
1482 char *p = string_glob (argv[0]);
1483 o = variable_buffer_output (o, p, strlen (p));
1484#endif
1485 return o;
1486}
1487
1488/*
1489 $(eval <makefile string>)
1490
1491 Always resolves to the empty string.
1492
1493 Treat the arguments as a segment of makefile, and parse them.
1494*/
1495
1496static char *
1497func_eval (char *o, char **argv, const char *funcname UNUSED)
1498{
1499 char *buf;
1500 unsigned int len;
1501
1502 /* Eval the buffer. Pop the current variable buffer setting so that the
1503 eval'd code can use its own without conflicting. */
1504
1505 install_variable_buffer (&buf, &len);
1506
1507 eval_buffer (argv[0]);
1508
1509 restore_variable_buffer (buf, len);
1510
1511 return o;
1512}
1513
1514
1515#ifdef CONFIG_WITH_EVALPLUS
1516/* Same as func_eval except that we push and pop the local variable
1517 context before evaluating the buffer. */
1518static char *
1519func_evalctx (char *o, char **argv, const char *funcname UNUSED)
1520{
1521 char *buf;
1522 unsigned int len;
1523
1524 /* Eval the buffer. Pop the current variable buffer setting so that the
1525 eval'd code can use its own without conflicting. */
1526
1527 install_variable_buffer (&buf, &len);
1528
1529 push_new_variable_scope ();
1530
1531 eval_buffer (argv[0]);
1532
1533 pop_variable_scope ();
1534
1535 restore_variable_buffer (buf, len);
1536
1537 return o;
1538}
1539
1540/* A mix of func_eval and func_value, saves memory for the expansion.
1541 This implements both evalval and evalvalctx, the latter has its own
1542 variable context just like evalctx. */
1543static char *
1544func_evalval (char *o, char **argv, const char *funcname)
1545{
1546 /* Look up the variable. */
1547 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
1548 if (v)
1549 {
1550 char *buf;
1551 unsigned int len;
1552 int var_ctx;
1553 size_t off;
1554 const struct floc *reading_file_saved = reading_file;
1555
1556 /* Make a copy of the value to the variable buffer since
1557 eval_buffer will make changes to its input. */
1558
1559 off = o - variable_buffer;
1560 o = variable_buffer_output (o, v->value, v->value_length + 1);
1561 o = variable_buffer + off;
1562 assert (!o[v->value_length]);
1563
1564 /* Eval the value. Pop the current variable buffer setting so that the
1565 eval'd code can use its own without conflicting. (really necessary?) */
1566
1567 install_variable_buffer (&buf, &len);
1568 var_ctx = !strcmp (funcname, "evalvalctx");
1569 if (var_ctx)
1570 push_new_variable_scope ();
1571 if (v->fileinfo.filenm)
1572 reading_file = &v->fileinfo;
1573
1574 eval_buffer (o);
1575
1576 reading_file = reading_file_saved;
1577 if (var_ctx)
1578 pop_variable_scope ();
1579 restore_variable_buffer (buf, len);
1580 }
1581
1582 return o;
1583}
1584#endif /* CONFIG_WITH_EVALPLUS */
1585
1586static char *
1587func_value (char *o, char **argv, const char *funcname UNUSED)
1588{
1589 /* Look up the variable. */
1590 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
1591
1592 /* Copy its value into the output buffer without expanding it. */
1593 if (v)
1594#ifdef CONFIG_WITH_VALUE_LENGTH
1595 o = variable_buffer_output (o, v->value,
1596 v->value_length >= 0 ? v->value_length : strlen(v->value));
1597#else
1598 o = variable_buffer_output (o, v->value, strlen(v->value));
1599#endif
1600
1601 return o;
1602}
1603
1604/*
1605 \r is replaced on UNIX as well. Is this desirable?
1606 */
1607static void
1608fold_newlines (char *buffer, unsigned int *length)
1609{
1610 char *dst = buffer;
1611 char *src = buffer;
1612 char *last_nonnl = buffer -1;
1613 src[*length] = 0;
1614 for (; *src != '\0'; ++src)
1615 {
1616 if (src[0] == '\r' && src[1] == '\n')
1617 continue;
1618 if (*src == '\n')
1619 {
1620 *dst++ = ' ';
1621 }
1622 else
1623 {
1624 last_nonnl = dst;
1625 *dst++ = *src;
1626 }
1627 }
1628 *(++last_nonnl) = '\0';
1629 *length = last_nonnl - buffer;
1630}
1631
1632
1633
1634int shell_function_pid = 0, shell_function_completed;
1635
1636
1637#ifdef WINDOWS32
1638/*untested*/
1639
1640#include <windows.h>
1641#include <io.h>
1642#include "sub_proc.h"
1643
1644
1645void
1646windows32_openpipe (int *pipedes, int *pid_p, char **command_argv, char **envp)
1647{
1648 SECURITY_ATTRIBUTES saAttr;
1649 HANDLE hIn;
1650 HANDLE hErr;
1651 HANDLE hChildOutRd;
1652 HANDLE hChildOutWr;
1653 HANDLE hProcess;
1654
1655
1656 saAttr.nLength = sizeof (SECURITY_ATTRIBUTES);
1657 saAttr.bInheritHandle = TRUE;
1658 saAttr.lpSecurityDescriptor = NULL;
1659
1660 if (DuplicateHandle (GetCurrentProcess(),
1661 GetStdHandle(STD_INPUT_HANDLE),
1662 GetCurrentProcess(),
1663 &hIn,
1664 0,
1665 TRUE,
1666 DUPLICATE_SAME_ACCESS) == FALSE) {
1667 fatal (NILF, _("create_child_process: DuplicateHandle(In) failed (e=%ld)\n"),
1668 GetLastError());
1669
1670 }
1671 if (DuplicateHandle(GetCurrentProcess(),
1672 GetStdHandle(STD_ERROR_HANDLE),
1673 GetCurrentProcess(),
1674 &hErr,
1675 0,
1676 TRUE,
1677 DUPLICATE_SAME_ACCESS) == FALSE) {
1678 fatal (NILF, _("create_child_process: DuplicateHandle(Err) failed (e=%ld)\n"),
1679 GetLastError());
1680 }
1681
1682 if (!CreatePipe(&hChildOutRd, &hChildOutWr, &saAttr, 0))
1683 fatal (NILF, _("CreatePipe() failed (e=%ld)\n"), GetLastError());
1684
1685 hProcess = process_init_fd(hIn, hChildOutWr, hErr);
1686
1687 if (!hProcess)
1688 fatal (NILF, _("windows32_openpipe (): process_init_fd() failed\n"));
1689
1690 /* make sure that CreateProcess() has Path it needs */
1691 sync_Path_environment();
1692
1693 if (!process_begin(hProcess, command_argv, envp, command_argv[0], NULL)) {
1694 /* register process for wait */
1695 process_register(hProcess);
1696
1697 /* set the pid for returning to caller */
1698 *pid_p = (int) hProcess;
1699
1700 /* set up to read data from child */
1701 pipedes[0] = _open_osfhandle((long) hChildOutRd, O_RDONLY);
1702
1703 /* this will be closed almost right away */
1704 pipedes[1] = _open_osfhandle((long) hChildOutWr, O_APPEND);
1705 } else {
1706 /* reap/cleanup the failed process */
1707 process_cleanup(hProcess);
1708
1709 /* close handles which were duplicated, they weren't used */
1710 CloseHandle(hIn);
1711 CloseHandle(hErr);
1712
1713 /* close pipe handles, they won't be used */
1714 CloseHandle(hChildOutRd);
1715 CloseHandle(hChildOutWr);
1716
1717 /* set status for return */
1718 pipedes[0] = pipedes[1] = -1;
1719 *pid_p = -1;
1720 }
1721}
1722#endif
1723
1724
1725#ifdef __MSDOS__
1726FILE *
1727msdos_openpipe (int* pipedes, int *pidp, char *text)
1728{
1729 FILE *fpipe=0;
1730 /* MSDOS can't fork, but it has `popen'. */
1731 struct variable *sh = lookup_variable ("SHELL", 5);
1732 int e;
1733 extern int dos_command_running, dos_status;
1734
1735 /* Make sure not to bother processing an empty line. */
1736 while (isblank ((unsigned char)*text))
1737 ++text;
1738 if (*text == '\0')
1739 return 0;
1740
1741 if (sh)
1742 {
1743 char buf[PATH_MAX + 7];
1744 /* This makes sure $SHELL value is used by $(shell), even
1745 though the target environment is not passed to it. */
1746 sprintf (buf, "SHELL=%s", sh->value);
1747 putenv (buf);
1748 }
1749
1750 e = errno;
1751 errno = 0;
1752 dos_command_running = 1;
1753 dos_status = 0;
1754 /* If dos_status becomes non-zero, it means the child process
1755 was interrupted by a signal, like SIGINT or SIGQUIT. See
1756 fatal_error_signal in commands.c. */
1757 fpipe = popen (text, "rt");
1758 dos_command_running = 0;
1759 if (!fpipe || dos_status)
1760 {
1761 pipedes[0] = -1;
1762 *pidp = -1;
1763 if (dos_status)
1764 errno = EINTR;
1765 else if (errno == 0)
1766 errno = ENOMEM;
1767 shell_function_completed = -1;
1768 }
1769 else
1770 {
1771 pipedes[0] = fileno (fpipe);
1772 *pidp = 42; /* Yes, the Meaning of Life, the Universe, and Everything! */
1773 errno = e;
1774 shell_function_completed = 1;
1775 }
1776 return fpipe;
1777}
1778#endif
1779
1780/*
1781 Do shell spawning, with the naughty bits for different OSes.
1782 */
1783
1784#ifdef VMS
1785
1786/* VMS can't do $(shell ...) */
1787#define func_shell 0
1788
1789#else
1790#ifndef _AMIGA
1791static char *
1792func_shell (char *o, char **argv, const char *funcname UNUSED)
1793{
1794 char *batch_filename = NULL;
1795
1796#ifdef __MSDOS__
1797 FILE *fpipe;
1798#endif
1799 char **command_argv;
1800 const char *error_prefix;
1801 char **envp;
1802 int pipedes[2];
1803 int pid;
1804
1805#ifndef __MSDOS__
1806 /* Construct the argument list. */
1807 command_argv = construct_command_argv (argv[0], NULL, NULL, &batch_filename);
1808 if (command_argv == 0)
1809 return o;
1810#endif
1811
1812 /* Using a target environment for `shell' loses in cases like:
1813 export var = $(shell echo foobie)
1814 because target_environment hits a loop trying to expand $(var)
1815 to put it in the environment. This is even more confusing when
1816 var was not explicitly exported, but just appeared in the
1817 calling environment.
1818
1819 See Savannah bug #10593.
1820
1821 envp = target_environment (NILF);
1822 */
1823
1824 envp = environ;
1825
1826 /* For error messages. */
1827 if (reading_file && reading_file->filenm)
1828 {
1829 char *p = alloca (strlen (reading_file->filenm)+11+4);
1830 sprintf (p, "%s:%lu: ", reading_file->filenm, reading_file->lineno);
1831 error_prefix = p;
1832 }
1833 else
1834 error_prefix = "";
1835
1836#if defined(__MSDOS__)
1837 fpipe = msdos_openpipe (pipedes, &pid, argv[0]);
1838 if (pipedes[0] < 0)
1839 {
1840 perror_with_name (error_prefix, "pipe");
1841 return o;
1842 }
1843#elif defined(WINDOWS32)
1844 windows32_openpipe (pipedes, &pid, command_argv, envp);
1845 if (pipedes[0] < 0)
1846 {
1847 /* open of the pipe failed, mark as failed execution */
1848 shell_function_completed = -1;
1849
1850 return o;
1851 }
1852 else
1853#else
1854 if (pipe (pipedes) < 0)
1855 {
1856 perror_with_name (error_prefix, "pipe");
1857 return o;
1858 }
1859
1860# ifdef __EMX__
1861 /* close some handles that are unnecessary for the child process */
1862 CLOSE_ON_EXEC(pipedes[1]);
1863 CLOSE_ON_EXEC(pipedes[0]);
1864 /* Never use fork()/exec() here! Use spawn() instead in exec_command() */
1865 pid = child_execute_job (0, pipedes[1], command_argv, envp);
1866 if (pid < 0)
1867 perror_with_name (error_prefix, "spawn");
1868# else /* ! __EMX__ */
1869 pid = vfork ();
1870 if (pid < 0)
1871 perror_with_name (error_prefix, "fork");
1872 else if (pid == 0)
1873 child_execute_job (0, pipedes[1], command_argv, envp);
1874 else
1875# endif
1876#endif
1877 {
1878 /* We are the parent. */
1879 char *buffer;
1880 unsigned int maxlen, i;
1881 int cc;
1882
1883 /* Record the PID for reap_children. */
1884 shell_function_pid = pid;
1885#ifndef __MSDOS__
1886 shell_function_completed = 0;
1887
1888 /* Free the storage only the child needed. */
1889 free (command_argv[0]);
1890 free (command_argv);
1891
1892 /* Close the write side of the pipe. */
1893# ifdef _MSC_VER /* Avoid annoying msvcrt when debugging. (bird) */
1894 if (pipedes[1] != -1)
1895# endif
1896 close (pipedes[1]);
1897#endif
1898
1899 /* Set up and read from the pipe. */
1900
1901 maxlen = 200;
1902 buffer = xmalloc (maxlen + 1);
1903
1904 /* Read from the pipe until it gets EOF. */
1905 for (i = 0; ; i += cc)
1906 {
1907 if (i == maxlen)
1908 {
1909 maxlen += 512;
1910 buffer = xrealloc (buffer, maxlen + 1);
1911 }
1912
1913 EINTRLOOP (cc, read (pipedes[0], &buffer[i], maxlen - i));
1914 if (cc <= 0)
1915 break;
1916 }
1917 buffer[i] = '\0';
1918
1919 /* Close the read side of the pipe. */
1920#ifdef __MSDOS__
1921 if (fpipe)
1922 (void) pclose (fpipe);
1923#else
1924# ifdef _MSC_VER /* Avoid annoying msvcrt when debugging. (bird) */
1925 if (pipedes[0] != -1)
1926# endif
1927 (void) close (pipedes[0]);
1928#endif
1929
1930 /* Loop until child_handler or reap_children() sets
1931 shell_function_completed to the status of our child shell. */
1932 while (shell_function_completed == 0)
1933 reap_children (1, 0);
1934
1935 if (batch_filename) {
1936 DB (DB_VERBOSE, (_("Cleaning up temporary batch file %s\n"),
1937 batch_filename));
1938 remove (batch_filename);
1939 free (batch_filename);
1940 }
1941 shell_function_pid = 0;
1942
1943 /* The child_handler function will set shell_function_completed
1944 to 1 when the child dies normally, or to -1 if it
1945 dies with status 127, which is most likely an exec fail. */
1946
1947 if (shell_function_completed == -1)
1948 {
1949 /* This likely means that the execvp failed, so we should just
1950 write the error message in the pipe from the child. */
1951 fputs (buffer, stderr);
1952 fflush (stderr);
1953 }
1954 else
1955 {
1956 /* The child finished normally. Replace all newlines in its output
1957 with spaces, and put that in the variable output buffer. */
1958 fold_newlines (buffer, &i);
1959 o = variable_buffer_output (o, buffer, i);
1960 }
1961
1962 free (buffer);
1963 }
1964
1965 return o;
1966}
1967
1968#else /* _AMIGA */
1969
1970/* Do the Amiga version of func_shell. */
1971
1972static char *
1973func_shell (char *o, char **argv, const char *funcname)
1974{
1975 /* Amiga can't fork nor spawn, but I can start a program with
1976 redirection of my choice. However, this means that we
1977 don't have an opportunity to reopen stdout to trap it. Thus,
1978 we save our own stdout onto a new descriptor and dup a temp
1979 file's descriptor onto our stdout temporarily. After we
1980 spawn the shell program, we dup our own stdout back to the
1981 stdout descriptor. The buffer reading is the same as above,
1982 except that we're now reading from a file. */
1983
1984#include <dos/dos.h>
1985#include <proto/dos.h>
1986
1987 BPTR child_stdout;
1988 char tmp_output[FILENAME_MAX];
1989 unsigned int maxlen = 200, i;
1990 int cc;
1991 char * buffer, * ptr;
1992 char ** aptr;
1993 int len = 0;
1994 char* batch_filename = NULL;
1995
1996 /* Construct the argument list. */
1997 command_argv = construct_command_argv (argv[0], (char **) NULL,
1998 (struct file *) 0, &batch_filename);
1999 if (command_argv == 0)
2000 return o;
2001
2002 /* Note the mktemp() is a security hole, but this only runs on Amiga.
2003 Ideally we would use main.c:open_tmpfile(), but this uses a special
2004 Open(), not fopen(), and I'm not familiar enough with the code to mess
2005 with it. */
2006 strcpy (tmp_output, "t:MakeshXXXXXXXX");
2007 mktemp (tmp_output);
2008 child_stdout = Open (tmp_output, MODE_NEWFILE);
2009
2010 for (aptr=command_argv; *aptr; aptr++)
2011 len += strlen (*aptr) + 1;
2012
2013 buffer = xmalloc (len + 1);
2014 ptr = buffer;
2015
2016 for (aptr=command_argv; *aptr; aptr++)
2017 {
2018 strcpy (ptr, *aptr);
2019 ptr += strlen (ptr) + 1;
2020 *ptr ++ = ' ';
2021 *ptr = 0;
2022 }
2023
2024 ptr[-1] = '\n';
2025
2026 Execute (buffer, NULL, child_stdout);
2027 free (buffer);
2028
2029 Close (child_stdout);
2030
2031 child_stdout = Open (tmp_output, MODE_OLDFILE);
2032
2033 buffer = xmalloc (maxlen);
2034 i = 0;
2035 do
2036 {
2037 if (i == maxlen)
2038 {
2039 maxlen += 512;
2040 buffer = xrealloc (buffer, maxlen + 1);
2041 }
2042
2043 cc = Read (child_stdout, &buffer[i], maxlen - i);
2044 if (cc > 0)
2045 i += cc;
2046 } while (cc > 0);
2047
2048 Close (child_stdout);
2049
2050 fold_newlines (buffer, &i);
2051 o = variable_buffer_output (o, buffer, i);
2052 free (buffer);
2053 return o;
2054}
2055#endif /* _AMIGA */
2056#endif /* !VMS */
2057
2058#ifdef EXPERIMENTAL
2059
2060/*
2061 equality. Return is string-boolean, ie, the empty string is false.
2062 */
2063static char *
2064func_eq (char *o, char **argv, const char *funcname)
2065{
2066 int result = ! strcmp (argv[0], argv[1]);
2067 o = variable_buffer_output (o, result ? "1" : "", result);
2068 return o;
2069}
2070
2071
2072/*
2073 string-boolean not operator.
2074 */
2075static char *
2076func_not (char *o, char **argv, const char *funcname)
2077{
2078 const char *s = argv[0];
2079 int result = 0;
2080 while (isspace ((unsigned char)*s))
2081 s++;
2082 result = ! (*s);
2083 o = variable_buffer_output (o, result ? "1" : "", result);
2084 return o;
2085}
2086#endif
2087
2088
2089
2090#ifdef CONFIG_WITH_DEFINED
2091/* Similar to ifdef. */
2092static char *
2093func_defined (char *o, char **argv, const char *funcname)
2094{
2095 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
2096 int result = v != NULL && *v->value != '\0';
2097 o = variable_buffer_output (o, result ? "1" : "", result);
2098 return o;
2099}
2100#endif /* CONFIG_WITH_DEFINED*/
2101
2102
2103
2104/* Return the absolute name of file NAME which does not contain any `.',
2105 `..' components nor any repeated path separators ('/'). */
2106#ifdef KMK
2107char *
2108#else
2109static char *
2110#endif
2111abspath (const char *name, char *apath)
2112{
2113 char *dest;
2114 const char *start, *end, *apath_limit;
2115
2116 if (name[0] == '\0' || apath == NULL)
2117 return NULL;
2118
2119#ifdef WINDOWS32 /* bird */
2120 dest = w32ify((char *)name, 1);
2121 if (!dest)
2122 return NULL;
2123 {
2124 size_t len = strlen(dest);
2125 memcpy(apath, dest, len);
2126 dest = apath + len;
2127 }
2128
2129 (void)end; (void)start; (void)apath_limit;
2130
2131#elif defined __OS2__ /* bird */
2132 if (_abspath(apath, name, GET_PATH_MAX))
2133 return NULL;
2134 dest = strchr(apath, '\0');
2135
2136 (void)end; (void)start; (void)apath_limit; (void)dest;
2137
2138#else /* !WINDOWS32 && !__OS2__ */
2139 apath_limit = apath + GET_PATH_MAX;
2140
2141#ifdef HAVE_DOS_PATHS /* bird added this */
2142 if (isalpha(name[0]) && name[1] == ':')
2143 {
2144 /* drive spec */
2145 apath[0] = toupper(name[0]);
2146 apath[1] = ':';
2147 apath[2] = '/';
2148 name += 2;
2149 }
2150 else
2151#endif /* HAVE_DOS_PATHS */
2152 if (name[0] != '/')
2153 {
2154 /* It is unlikely we would make it until here but just to make sure. */
2155 if (!starting_directory)
2156 return NULL;
2157
2158 strcpy (apath, starting_directory);
2159
2160 dest = strchr (apath, '\0');
2161 }
2162 else
2163 {
2164 apath[0] = '/';
2165 dest = apath + 1;
2166 }
2167
2168 for (start = end = name; *start != '\0'; start = end)
2169 {
2170 unsigned long len;
2171
2172 /* Skip sequence of multiple path-separators. */
2173 while (*start == '/')
2174 ++start;
2175
2176 /* Find end of path component. */
2177 for (end = start; *end != '\0' && *end != '/'; ++end)
2178 ;
2179
2180 len = end - start;
2181
2182 if (len == 0)
2183 break;
2184 else if (len == 1 && start[0] == '.')
2185 /* nothing */;
2186 else if (len == 2 && start[0] == '.' && start[1] == '.')
2187 {
2188 /* Back up to previous component, ignore if at root already. */
2189 if (dest > apath + 1)
2190 while ((--dest)[-1] != '/');
2191 }
2192 else
2193 {
2194 if (dest[-1] != '/')
2195 *dest++ = '/';
2196
2197 if (dest + len >= apath_limit)
2198 return NULL;
2199
2200 dest = memcpy (dest, start, len);
2201 dest += len;
2202 *dest = '\0';
2203 }
2204 }
2205#endif /* !WINDOWS32 && !__OS2__ */
2206
2207 /* Unless it is root strip trailing separator. */
2208#ifdef HAVE_DOS_PATHS /* bird (is this correct? what about UNC?) */
2209 if (dest > apath + 1 + (apath[0] != '/') && dest[-1] == '/')
2210#else
2211 if (dest > apath + 1 && dest[-1] == '/')
2212#endif
2213 --dest;
2214
2215 *dest = '\0';
2216
2217 return apath;
2218}
2219
2220
2221static char *
2222func_realpath (char *o, char **argv, const char *funcname UNUSED)
2223{
2224 /* Expand the argument. */
2225 const char *p = argv[0];
2226 const char *path = 0;
2227 int doneany = 0;
2228 unsigned int len = 0;
2229 PATH_VAR (in);
2230 PATH_VAR (out);
2231
2232 while ((path = find_next_token (&p, &len)) != 0)
2233 {
2234 if (len < GET_PATH_MAX)
2235 {
2236 strncpy (in, path, len);
2237 in[len] = '\0';
2238
2239 if (
2240#ifdef HAVE_REALPATH
2241 realpath (in, out)
2242#else
2243 abspath (in, out)
2244#endif
2245 )
2246 {
2247 o = variable_buffer_output (o, out, strlen (out));
2248 o = variable_buffer_output (o, " ", 1);
2249 doneany = 1;
2250 }
2251 }
2252 }
2253
2254 /* Kill last space. */
2255 if (doneany)
2256 --o;
2257
2258 return o;
2259}
2260
2261static char *
2262func_abspath (char *o, char **argv, const char *funcname UNUSED)
2263{
2264 /* Expand the argument. */
2265 const char *p = argv[0];
2266 const char *path = 0;
2267 int doneany = 0;
2268 unsigned int len = 0;
2269 PATH_VAR (in);
2270 PATH_VAR (out);
2271
2272 while ((path = find_next_token (&p, &len)) != 0)
2273 {
2274 if (len < GET_PATH_MAX)
2275 {
2276 strncpy (in, path, len);
2277 in[len] = '\0';
2278
2279 if (abspath (in, out))
2280 {
2281 o = variable_buffer_output (o, out, strlen (out));
2282 o = variable_buffer_output (o, " ", 1);
2283 doneany = 1;
2284 }
2285 }
2286 }
2287
2288 /* Kill last space. */
2289 if (doneany)
2290 --o;
2291
2292 return o;
2293}
2294
2295#ifdef CONFIG_WITH_ABSPATHEX
2296/* Same as abspath except that the current path may be given as the
2297 2nd argument. */
2298static char *
2299func_abspathex (char *o, char **argv, const char *funcname UNUSED)
2300{
2301 char *cwd = argv[1];
2302
2303 /* cwd needs leading spaces chopped and may be optional,
2304 in which case we're exactly like $(abspath ). */
2305 while (isblank(*cwd))
2306 cwd++;
2307 if (!*cwd)
2308 o = func_abspath (o, argv, funcname);
2309 else
2310 {
2311 /* Expand the argument. */
2312 const char *p = argv[0];
2313 unsigned int cwd_len = ~0U;
2314 char *path = 0;
2315 int doneany = 0;
2316 unsigned int len = 0;
2317 PATH_VAR (in);
2318 PATH_VAR (out);
2319
2320 while ((path = find_next_token (&p, &len)) != 0)
2321 {
2322 if (len < GET_PATH_MAX)
2323 {
2324#ifdef HAVE_DOS_PATHS
2325 if (path[0] != '/' && path[0] != '\\' && (len < 2 || path[1] != ':') && cwd)
2326#else
2327 if (path[0] != '/' && cwd)
2328#endif
2329 {
2330 /* relative path, prefix with cwd. */
2331 if (cwd_len == ~0U)
2332 cwd_len = strlen (cwd);
2333 if (cwd_len + len + 1 >= GET_PATH_MAX)
2334 continue;
2335 memcpy (in, cwd, cwd_len);
2336 in[cwd_len] = '/';
2337 memcpy (in + cwd_len + 1, path, len);
2338 in[cwd_len + len + 1] = '\0';
2339 }
2340 else
2341 {
2342 /* absolute path pass it as-is. */
2343 memcpy (in, path, len);
2344 in[len] = '\0';
2345 }
2346
2347 if (abspath (in, out))
2348 {
2349 o = variable_buffer_output (o, out, strlen (out));
2350 o = variable_buffer_output (o, " ", 1);
2351 doneany = 1;
2352 }
2353 }
2354 }
2355
2356 /* Kill last space. */
2357 if (doneany)
2358 --o;
2359 }
2360
2361 return o;
2362}
2363#endif
2364
2365#ifdef CONFIG_WITH_XARGS
2366/* Create one or more command lines avoiding the max argument
2367 lenght restriction of the host OS.
2368
2369 The last argument is the list of arguments that the normal
2370 xargs command would be fed from stdin.
2371
2372 The first argument is initial command and it's arguments.
2373
2374 If there are three or more arguments, the 2nd argument is
2375 the command and arguments to be used on subsequent
2376 command lines. Defaults to the initial command.
2377
2378 If there are four or more arguments, the 3rd argument is
2379 the command to be used at the final command line. Defaults
2380 to the sub sequent or initial command .
2381
2382 A future version of this function may define more arguments
2383 and therefor anyone specifying six or more arguments will
2384 cause fatal errors.
2385
2386 Typical usage is:
2387 $(xargs ar cas mylib.a,$(objects))
2388 or
2389 $(xargs ar cas mylib.a,ar as mylib.a,$(objects))
2390
2391 It will then create one or more "ar mylib.a ..." command
2392 lines with proper \n\t separation so it can be used when
2393 writing rules. */
2394static char *
2395func_xargs (char *o, char **argv, const char *funcname UNUSED)
2396{
2397 int argc;
2398 const char *initial_cmd;
2399 size_t initial_cmd_len;
2400 const char *subsequent_cmd;
2401 size_t subsequent_cmd_len;
2402 const char *final_cmd;
2403 size_t final_cmd_len;
2404 const char *args;
2405 size_t max_args;
2406 int i;
2407
2408#ifdef ARG_MAX
2409 /* ARG_MAX is a bit unreliable (environment), so drop 25% of the max. */
2410# define XARGS_MAX (ARG_MAX - (ARG_MAX / 4))
2411#else /* FIXME: update configure with a command line length test. */
2412# define XARGS_MAX 10240
2413#endif
2414
2415 argc = 0;
2416 while (argv[argc])
2417 argc++;
2418 if (argc > 4)
2419 fatal (NILF, _("Too many arguments for $(xargs)!\n"));
2420
2421 /* first: the initial / default command.*/
2422 initial_cmd = argv[0];
2423 while (isspace ((unsigned char)*initial_cmd))
2424 initial_cmd++;
2425 max_args = initial_cmd_len = strlen (initial_cmd);
2426
2427 /* second: the command for the subsequent command lines. defaults to the initial cmd. */
2428 subsequent_cmd = argc > 2 && argv[1][0] != '\0' ? argv[1] : "";
2429 while (isspace ((unsigned char)*subsequent_cmd))
2430 subsequent_cmd++;
2431 if (*subsequent_cmd)
2432 {
2433 subsequent_cmd_len = strlen (subsequent_cmd);
2434 if (subsequent_cmd_len > max_args)
2435 max_args = subsequent_cmd_len;
2436 }
2437 else
2438 {
2439 subsequent_cmd = initial_cmd;
2440 subsequent_cmd_len = initial_cmd_len;
2441 }
2442
2443 /* third: the final command. defaults to the subseq cmd. */
2444 final_cmd = argc > 3 && argv[2][0] != '\0' ? argv[2] : "";
2445 while (isspace ((unsigned char)*final_cmd))
2446 final_cmd++;
2447 if (*final_cmd)
2448 {
2449 final_cmd_len = strlen (final_cmd);
2450 if (final_cmd_len > max_args)
2451 max_args = final_cmd_len;
2452 }
2453 else
2454 {
2455 final_cmd = subsequent_cmd;
2456 final_cmd_len = subsequent_cmd_len;
2457 }
2458
2459 /* last: the arguments to split up into sensible portions. */
2460 args = argv[argc - 1];
2461
2462 /* calc the max argument length. */
2463 if (XARGS_MAX <= max_args + 2)
2464 fatal (NILF, _("$(xargs): the commands are longer than the max exec argument length. (%lu <= %lu)\n"),
2465 (unsigned long)XARGS_MAX, (unsigned long)max_args + 2);
2466 max_args = XARGS_MAX - max_args - 1;
2467
2468 /* generate the commands. */
2469 i = 0;
2470 for (i = 0; ; i++)
2471 {
2472 unsigned int len;
2473 const char *iterator = args;
2474 const char *end = args;
2475 const char *cur;
2476 const char *tmp;
2477
2478 /* scan the arguments till we reach the end or the max length. */
2479 while ((cur = find_next_token(&iterator, &len))
2480 && (size_t)((cur + len) - args) < max_args)
2481 end = cur + len;
2482 if (cur && end == args)
2483 fatal (NILF, _("$(xargs): command + one single arg is too much. giving up.\n"));
2484
2485 /* emit the command. */
2486 if (i == 0)
2487 {
2488 o = variable_buffer_output (o, (char *)initial_cmd, initial_cmd_len);
2489 o = variable_buffer_output (o, " ", 1);
2490 }
2491 else if (cur)
2492 {
2493 o = variable_buffer_output (o, "\n\t", 2);
2494 o = variable_buffer_output (o, (char *)subsequent_cmd, subsequent_cmd_len);
2495 o = variable_buffer_output (o, " ", 1);
2496 }
2497 else
2498 {
2499 o = variable_buffer_output (o, "\n\t", 2);
2500 o = variable_buffer_output (o, (char *)final_cmd, final_cmd_len);
2501 o = variable_buffer_output (o, " ", 1);
2502 }
2503
2504 tmp = end;
2505 while (tmp > args && isspace ((unsigned char)tmp[-1])) /* drop trailing spaces. */
2506 tmp--;
2507 o = variable_buffer_output (o, (char *)args, tmp - args);
2508
2509
2510 /* next */
2511 if (!cur)
2512 break;
2513 args = end;
2514 while (isspace ((unsigned char)*args))
2515 args++;
2516 }
2517
2518 return o;
2519}
2520#endif
2521
2522#ifdef CONFIG_WITH_TOUPPER_TOLOWER
2523static char *
2524func_toupper_tolower (char *o, char **argv, const char *funcname)
2525{
2526 /* Expand the argument. */
2527 const char *p = argv[0];
2528 while (*p)
2529 {
2530 /* convert to temporary buffer */
2531 char tmp[256];
2532 unsigned int i;
2533 if (!strcmp(funcname, "toupper"))
2534 for (i = 0; i < sizeof(tmp) && *p; i++, p++)
2535 tmp[i] = toupper(*p);
2536 else
2537 for (i = 0; i < sizeof(tmp) && *p; i++, p++)
2538 tmp[i] = tolower(*p);
2539 o = variable_buffer_output (o, tmp, i);
2540 }
2541
2542 return o;
2543}
2544#endif /* CONFIG_WITH_TOUPPER_TOLOWER */
2545
2546#if defined(CONFIG_WITH_VALUE_LENGTH) && defined(CONFIG_WITH_COMPARE)
2547
2548/* Strip leading spaces and other things off a command. */
2549static const char *
2550comp_cmds_strip_leading (const char *s, const char *e)
2551{
2552 while (s < e)
2553 {
2554 const char ch = *s;
2555 if (!isblank (ch)
2556 && ch != '@'
2557#ifdef CONFIG_WITH_COMMANDS_FUNC
2558 && ch != '%'
2559#endif
2560 && ch != '+'
2561 && ch != '-')
2562 break;
2563 s++;
2564 }
2565 return s;
2566}
2567
2568/* Worker for func_comp_vars() which is called if the comparision failed.
2569 It will do the slow command by command comparision of the commands
2570 when there invoked as comp-cmds. */
2571static char *
2572comp_vars_ne (char *o, const char *s1, const char *e1, const char *s2, const char *e2,
2573 char *ne_retval, const char *funcname)
2574{
2575 /* give up at once if not comp-cmds or comp-cmds-ex. */
2576 if (strcmp (funcname, "comp-cmds") != 0
2577 && strcmp (funcname, "comp-cmds-ex") != 0)
2578 o = variable_buffer_output (o, ne_retval, strlen (ne_retval));
2579 else
2580 {
2581 const char * const s1_start = s1;
2582 int new_cmd = 1;
2583 int diff;
2584 for (;;)
2585 {
2586 /* if it's a new command, strip leading stuff. */
2587 if (new_cmd)
2588 {
2589 s1 = comp_cmds_strip_leading (s1, e1);
2590 s2 = comp_cmds_strip_leading (s2, e2);
2591 new_cmd = 0;
2592 }
2593 if (s1 >= e1 || s2 >= e2)
2594 break;
2595
2596 /*
2597 * Inner compare loop which compares one line.
2598 * FIXME: parse quoting!
2599 */
2600 for (;;)
2601 {
2602 const char ch1 = *s1;
2603 const char ch2 = *s2;
2604 diff = ch1 - ch2;
2605 if (diff)
2606 break;
2607 if (ch1 == '\n')
2608 break;
2609 assert (ch1 != '\r');
2610
2611 /* next */
2612 s1++;
2613 s2++;
2614 if (s1 >= e1 || s2 >= e2)
2615 break;
2616 }
2617
2618 /*
2619 * If we exited because of a difference try to end-of-command
2620 * comparision, e.g. ignore trailing spaces.
2621 */
2622 if (diff)
2623 {
2624 /* strip */
2625 while (s1 < e1 && isblank (*s1))
2626 s1++;
2627 while (s2 < e2 && isblank (*s2))
2628 s2++;
2629 if (s1 >= e1 || s2 >= e2)
2630 break;
2631
2632 /* compare again and check that it's a newline. */
2633 if (*s2 != '\n' || *s1 != '\n')
2634 break;
2635 }
2636 /* Break out if we exited because of EOS. */
2637 else if (s1 >= e1 || s2 >= e2)
2638 break;
2639
2640 /*
2641 * Detect the end of command lines.
2642 */
2643 if (*s1 == '\n')
2644 new_cmd = s1 == s1_start || s1[-1] != '\\';
2645 s1++;
2646 s2++;
2647 }
2648
2649 /*
2650 * Ignore trailing empty lines.
2651 */
2652 if (s1 < e1 || s2 < e2)
2653 {
2654 while (s1 < e1 && (isblank (*s1) || *s1 == '\n'))
2655 if (*s1++ == '\n')
2656 s1 = comp_cmds_strip_leading (s1, e1);
2657 while (s2 < e2 && (isblank (*s2) || *s2 == '\n'))
2658 if (*s2++ == '\n')
2659 s2 = comp_cmds_strip_leading (s2, e2);
2660 }
2661
2662 /* emit the result. */
2663 if (s1 == e1 && s2 == e2)
2664 o = variable_buffer_output (o, "", 1);
2665 else
2666 o = variable_buffer_output (o, ne_retval, strlen (ne_retval));
2667 }
2668 return o;
2669}
2670
2671/*
2672 $(comp-vars var1,var2,not-equal-return)
2673 or
2674 $(comp-cmds cmd-var1,cmd-var2,not-equal-return)
2675
2676 Compares the two variables (that's given by name to avoid unnecessary
2677 expanding) and return the string in the third argument if not equal.
2678 If equal, nothing is returned.
2679
2680 comp-vars will to an exact comparision only stripping leading and
2681 trailing spaces.
2682
2683 comp-cmds will compare command by command, ignoring not only leading
2684 and trailing spaces on each line but also leading one leading '@',
2685 '-', '+' and '%'
2686*/
2687static char *
2688func_comp_vars (char *o, char **argv, const char *funcname)
2689{
2690 const char *s1, *e1, *x1, *s2, *e2, *x2;
2691 char *a1 = NULL, *a2 = NULL;
2692 size_t l, l1, l2;
2693 struct variable *var1 = lookup_variable (argv[0], strlen (argv[0]));
2694 struct variable *var2 = lookup_variable (argv[1], strlen (argv[1]));
2695
2696 /* the simple cases */
2697 if (var1 == var2)
2698 return variable_buffer_output (o, "", 0); /* eq */
2699 if (!var1 || !var2)
2700 return variable_buffer_output (o, argv[2], strlen(argv[2]));
2701 if (var1->value == var2->value)
2702 return variable_buffer_output (o, "", 0); /* eq */
2703 if (!var1->recursive && !var2->recursive)
2704 {
2705 if ( var1->value_length == var2->value_length
2706 && !memcmp (var1->value, var2->value, var1->value_length))
2707 return variable_buffer_output (o, "", 0); /* eq */
2708
2709 /* ignore trailing and leading blanks */
2710 s1 = var1->value;
2711 e1 = s1 + var1->value_length;
2712 while (isblank ((unsigned char) *s1))
2713 s1++;
2714 while (e1 > s1 && isblank ((unsigned char) e1[-1]))
2715 e1--;
2716
2717 s2 = var2->value;
2718 e2 = s2 + var2->value_length;
2719 while (isblank ((unsigned char) *s2))
2720 s2++;
2721 while (e2 > s2 && isblank ((unsigned char) e2[-1]))
2722 e2--;
2723
2724 if (e1 - s1 != e2 - s2)
2725 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
2726 if (!memcmp (s1, s2, e1 - s1))
2727 return variable_buffer_output (o, "", 0); /* eq */
2728 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
2729 }
2730
2731 /* ignore trailing and leading blanks */
2732 s1 = var1->value;
2733 e1 = s1 + var1->value_length;
2734 while (isblank ((unsigned char) *s1))
2735 s1++;
2736 while (e1 > s1 && isblank ((unsigned char) e1[-1]))
2737 e1--;
2738
2739 s2 = var2->value;
2740 e2 = s2 + var2->value_length;
2741 while (isblank((unsigned char)*s2))
2742 s2++;
2743 while (e2 > s2 && isblank ((unsigned char) e2[-1]))
2744 e2--;
2745
2746 /* both empty after stripping? */
2747 if (s1 == e1 && s2 == e2)
2748 return variable_buffer_output (o, "", 0); /* eq */
2749
2750 /* optimist. */
2751 if ( e1 - s1 == e2 - s2
2752 && !memcmp(s1, s2, e1 - s1))
2753 return variable_buffer_output (o, "", 0); /* eq */
2754
2755 /* compare up to the first '$' or the end. */
2756 x1 = var1->recursive ? memchr (s1, '$', e1 - s1) : NULL;
2757 x2 = var2->recursive ? memchr (s2, '$', e2 - s2) : NULL;
2758 if (!x1 && !x2)
2759 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
2760
2761 l1 = x1 ? x1 - s1 : e1 - s1;
2762 l2 = x2 ? x2 - s2 : e2 - s2;
2763 l = l1 <= l2 ? l1 : l2;
2764 if (l && memcmp (s1, s2, l))
2765 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
2766
2767 /* one or both buffers now require expanding. */
2768 if (!x1)
2769 s1 += l;
2770 else
2771 {
2772 s1 = a1 = allocated_variable_expand ((char *)s1 + l);
2773 if (!l)
2774 while (isblank ((unsigned char) *s1))
2775 s1++;
2776 e1 = strchr (s1, '\0');
2777 while (e1 > s1 && isblank ((unsigned char) e1[-1]))
2778 e1--;
2779 }
2780
2781 if (!x2)
2782 s2 += l;
2783 else
2784 {
2785 s2 = a2 = allocated_variable_expand ((char *)s2 + l);
2786 if (!l)
2787 while (isblank ((unsigned char) *s2))
2788 s2++;
2789 e2 = strchr (s2, '\0');
2790 while (e2 > s2 && isblank ((unsigned char) e2[-1]))
2791 e2--;
2792 }
2793
2794 /* the final compare */
2795 if ( e1 - s1 != e2 - s2
2796 || memcmp (s1, s2, e1 - s1))
2797 o = comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
2798 else
2799 o = variable_buffer_output (o, "", 1); /* eq */
2800 if (a1)
2801 free (a1);
2802 if (a2)
2803 free (a2);
2804 return o;
2805}
2806
2807/*
2808 $(comp-cmds-ex cmds1,cmds2,not-equal-return)
2809
2810 Compares the two strings and return the string in the third argument
2811 if not equal. If equal, nothing is returned.
2812
2813 The comparision will be performed command by command, ignoring not
2814 only leading and trailing spaces on each line but also leading one
2815 leading '@', '-', '+' and '%'.
2816*/
2817static char *
2818func_comp_cmds_ex (char *o, char **argv, const char *funcname)
2819{
2820 const char *s1, *e1, *s2, *e2;
2821 size_t l1, l2;
2822
2823 /* the simple cases */
2824 s1 = argv[0];
2825 s2 = argv[1];
2826 if (s1 == s2)
2827 return variable_buffer_output (o, "", 0); /* eq */
2828 l1 = strlen (argv[0]);
2829 l2 = strlen (argv[1]);
2830
2831 if ( l1 == l2
2832 && !memcmp (s1, s2, l1))
2833 return variable_buffer_output (o, "", 0); /* eq */
2834
2835 /* ignore trailing and leading blanks */
2836 e1 = s1 + l1;
2837 s1 = comp_cmds_strip_leading (s1, e1);
2838
2839 e2 = s2 + l2;
2840 s2 = comp_cmds_strip_leading (s2, e2);
2841
2842 if (e1 - s1 != e2 - s2)
2843 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
2844 if (!memcmp (s1, s2, e1 - s1))
2845 return variable_buffer_output (o, "", 0); /* eq */
2846 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
2847}
2848#endif
2849
2850#ifdef CONFIG_WITH_DATE
2851# if defined (_MSC_VER) /* FIXME: !defined (HAVE_STRPTIME) */
2852char *strptime(const char *s, const char *format, struct tm *tm)
2853{
2854 return (char *)"strptime is not implemented";
2855}
2856# endif
2857/* Check if the string is all blanks or not. */
2858static int
2859all_blanks (const char *s)
2860{
2861 if (!s)
2862 return 1;
2863 while (isspace ((unsigned char)*s))
2864 s++;
2865 return *s == '\0';
2866}
2867
2868/* The first argument is the strftime format string, a iso
2869 timestamp is the default if nothing is given.
2870
2871 The second argument is a time value if given. The format
2872 is either the format from the first argument or given as
2873 an additional third argument. */
2874static char *
2875func_date (char *o, char **argv, const char *funcname)
2876{
2877 char *p;
2878 char *buf;
2879 size_t buf_size;
2880 struct tm t;
2881 const char *format;
2882
2883 /* determin the format - use a single word as the default. */
2884 format = !strcmp (funcname, "date-utc")
2885 ? "%Y-%m-%dT%H:%M:%SZ"
2886 : "%Y-%m-%dT%H:%M:%S";
2887 if (!all_blanks (argv[0]))
2888 format = argv[0];
2889
2890 /* get the time. */
2891 memset (&t, 0, sizeof(t));
2892 if (argv[0] && !all_blanks (argv[1]))
2893 {
2894 const char *input_format = !all_blanks (argv[2]) ? argv[2] : format;
2895 p = strptime (argv[1], input_format, &t);
2896 if (!p || *p != '\0')
2897 {
2898 error (NILF, _("$(%s): strptime(%s,%s,) -> %s\n"), funcname,
2899 argv[1], input_format, p ? p : "<null>");
2900 return variable_buffer_output (o, "", 0);
2901 }
2902 }
2903 else
2904 {
2905 time_t tval;
2906 time (&tval);
2907 if (!strcmp (funcname, "date-utc"))
2908 t = *gmtime (&tval);
2909 else
2910 t = *localtime (&tval);
2911 }
2912
2913 /* format it. note that zero isn't necessarily an error, so we'll
2914 have to keep shut about failures. */
2915 buf_size = 64;
2916 buf = xmalloc (buf_size);
2917 while (strftime (buf, buf_size, format, &t) == 0)
2918 {
2919 if (buf_size >= 4096)
2920 {
2921 *buf = '\0';
2922 break;
2923 }
2924 buf = xrealloc (buf, buf_size <<= 1);
2925 }
2926 o = variable_buffer_output (o, buf, strlen (buf));
2927 free (buf);
2928 return o;
2929}
2930#endif
2931
2932#ifdef CONFIG_WITH_FILE_SIZE
2933/* Prints the size of the specified file. Only one file is
2934 permitted, notthing is stripped. -1 is returned if stat
2935 fails. */
2936static char *
2937func_file_size (char *o, char **argv, const char *funcname UNUSED)
2938{
2939 struct stat st;
2940 if (stat (argv[0], &st))
2941 return variable_buffer_output (o, "-1", 2);
2942 return math_int_to_variable_buffer (o, st.st_size);
2943}
2944#endif
2945
2946#ifdef CONFIG_WITH_WHICH
2947/* Checks if the specified file exists an is executable.
2948 On systems employing executable extensions, the name may
2949 be modified to include the extension. */
2950static int func_which_test_x (char *file)
2951{
2952 struct stat st;
2953# if defined(WINDOWS32) || defined(__OS2__)
2954 char *ext;
2955 char *slash;
2956
2957 /* fix slashes first. */
2958 slash = file;
2959 while ((slash = strchr (slash, '\\')) != NULL)
2960 *slash++ = '/';
2961
2962 /* straight */
2963 if (stat (file, &st) == 0
2964 && S_ISREG (st.st_mode))
2965 return 1;
2966
2967 /* don't try add an extension if there already is one */
2968 ext = strchr (file, '\0');
2969 if (ext - file >= 4
2970 && ( !stricmp (ext - 4, ".exe")
2971 || !stricmp (ext - 4, ".cmd")
2972 || !stricmp (ext - 4, ".bat")
2973 || !stricmp (ext - 4, ".com")))
2974 return 0;
2975
2976 /* try the extensions. */
2977 strcpy (ext, ".exe");
2978 if (stat (file, &st) == 0
2979 && S_ISREG (st.st_mode))
2980 return 1;
2981
2982 strcpy (ext, ".cmd");
2983 if (stat (file, &st) == 0
2984 && S_ISREG (st.st_mode))
2985 return 1;
2986
2987 strcpy (ext, ".bat");
2988 if (stat (file, &st) == 0
2989 && S_ISREG (st.st_mode))
2990 return 1;
2991
2992 strcpy (ext, ".com");
2993 if (stat (file, &st) == 0
2994 && S_ISREG (st.st_mode))
2995 return 1;
2996
2997 return 0;
2998
2999# else
3000
3001 return access (file, X_OK) == 0
3002 && stat (file, &st) == 0
3003 && S_ISREG (st.st_mode);
3004# endif
3005}
3006
3007/* Searches for the specified programs in the PATH and print
3008 their full location if found. Prints nothing if not found. */
3009static char *
3010func_which (char *o, char **argv, const char *funcname UNUSED)
3011{
3012 const char *path;
3013 struct variable *path_var;
3014 unsigned i;
3015 int first = 1;
3016 PATH_VAR (buf);
3017
3018 path_var = lookup_variable ("PATH", 4);
3019 if (path_var)
3020 path = path_var->value;
3021 else
3022 path = ".";
3023
3024 /* iterate input */
3025 for (i = 0; argv[i]; i++)
3026 {
3027 unsigned int len;
3028 const char *iterator = argv[i];
3029 char *cur;
3030
3031 while ((cur = find_next_token (&iterator, &len)))
3032 {
3033 /* if there is a separator, don't walk the path. */
3034 if (memchr (cur, '/', len)
3035#ifdef HAVE_DOS_PATHS
3036 || memchr (cur, '\\', len)
3037 || memchr (cur, ':', len)
3038#endif
3039 )
3040 {
3041 if (len + 1 + 4 < GET_PATH_MAX) /* +4 for .exe */
3042 {
3043 memcpy (buf, cur, len);
3044 buf[len] = '\0';
3045 if (func_which_test_x (buf))
3046 o = variable_buffer_output (o, buf, strlen (buf));
3047 }
3048 }
3049 else
3050 {
3051 const char *comp = path;
3052 for (;;)
3053 {
3054 const char *src = comp;
3055 const char *end = strchr (comp, PATH_SEPARATOR_CHAR);
3056 size_t comp_len = end ? end - comp : strlen (comp);
3057 if (!comp_len)
3058 {
3059 comp_len = 1;
3060 src = ".";
3061 }
3062 if (len + comp_len + 2 + 4 < GET_PATH_MAX) /* +4 for .exe */
3063 {
3064 memcpy (buf, comp, comp_len);
3065 buf [comp_len] = '/';
3066 memcpy (&buf[comp_len + 1], cur, len);
3067 buf[comp_len + 1 + len] = '\0';
3068
3069 if (func_which_test_x (buf))
3070 {
3071 if (!first)
3072 o = variable_buffer_output (o, " ", 1);
3073 o = variable_buffer_output (o, buf, strlen (buf));
3074 first = 0;
3075 break;
3076 }
3077 }
3078
3079 /* next */
3080 if (!end)
3081 break;
3082 comp = end + 1;
3083 }
3084 }
3085 }
3086 }
3087
3088 return variable_buffer_output (o, "", 0);
3089}
3090#endif /* CONFIG_WITH_WHICH */
3091
3092#ifdef CONFIG_WITH_IF_CONDITIONALS
3093
3094/* Evaluates the expression given in the argument using the
3095 same evaluator as for the new 'if' statements, except now
3096 we don't force the result into a boolean like for 'if' and
3097 '$(if-expr ,,)'. */
3098static char *
3099func_expr (char *o, char **argv, const char *funcname UNUSED)
3100{
3101 o = expr_eval_to_string (o, argv[0]);
3102 return o;
3103}
3104
3105/* Same as '$(if ,,)' except the first argument is evaluated
3106 using the same evaluator as for the new 'if' statements. */
3107static char *
3108func_if_expr (char *o, char **argv, const char *funcname UNUSED)
3109{
3110 int rc;
3111 char *to_expand;
3112
3113 /* Evaluate the condition in argv[0] and expand the 2nd or
3114 3rd argument according to the result. */
3115 rc = expr_eval_if_conditionals (argv[0], NULL);
3116 to_expand = rc == 0 ? argv[1] : argv[2];
3117 if (*to_expand)
3118 {
3119 char *expansion = expand_argument (to_expand, NULL);
3120
3121 o = variable_buffer_output (o, expansion, strlen (expansion));
3122
3123 free (expansion);
3124 }
3125
3126 return o;
3127}
3128
3129#endif /* CONFIG_WITH_IF_CONDITIONALS */
3130
3131#ifdef CONFIG_WITH_STACK
3132
3133/* Push an item (string without spaces). */
3134static char *
3135func_stack_push (char *o, char **argv, const char *funcname UNUSED)
3136{
3137 do_variable_definition(NILF, argv[0], argv[1], o_file, f_append, 0 /* !target_var */);
3138 return o;
3139}
3140
3141/* Pops an item off the stack / get the top stack element.
3142 (This is what's tricky to do in pure GNU make syntax.) */
3143static char *
3144func_stack_pop_top (char *o, char **argv, const char *funcname)
3145{
3146 struct variable *stack_var;
3147 const char *stack = argv[0];
3148
3149 stack_var = lookup_variable (stack, strlen (stack) );
3150 if (stack_var)
3151 {
3152 unsigned int len;
3153 const char *iterator = stack_var->value;
3154 char *lastitem = NULL;
3155 char *cur;
3156
3157 while ((cur = find_next_token (&iterator, &len)))
3158 lastitem = cur;
3159
3160 if (lastitem != NULL)
3161 {
3162 if (strcmp (funcname, "stack-popv") != 0)
3163 o = variable_buffer_output (o, lastitem, len);
3164 if (strcmp (funcname, "stack-top") != 0)
3165 {
3166 *lastitem = '\0';
3167 while (lastitem > stack_var->value && isspace (lastitem[-1]))
3168 *--lastitem = '\0';
3169#ifdef CONFIG_WITH_VALUE_LENGTH
3170 stack_var->value_length = lastitem - stack_var->value;
3171#endif
3172 }
3173 }
3174 }
3175 return o;
3176}
3177#endif /* CONFIG_WITH_STACK */
3178
3179#if defined (CONFIG_WITH_MATH) || defined (CONFIG_WITH_NANOTS) || defined (CONFIG_WITH_FILE_SIZE)
3180/* outputs the number (as a string) into the variable buffer. */
3181static char *
3182math_int_to_variable_buffer (char *o, math_int num)
3183{
3184 static const char xdigits[17] = "0123456789abcdef";
3185 int negative;
3186 char strbuf[24]; /* 16 hex + 2 prefix + sign + term => 20
3187 or 20 dec + sign + term => 22 */
3188 char *str = &strbuf[sizeof (strbuf) - 1];
3189
3190 negative = num < 0;
3191 if (negative)
3192 num = -num;
3193
3194 *str = '\0';
3195
3196 do
3197 {
3198#ifdef HEX_MATH_NUMBERS
3199 *--str = xdigits[num & 0xf];
3200 num >>= 4;
3201#else
3202 *--str = xdigits[num % 10];
3203 num /= 10;
3204#endif
3205 }
3206 while (num);
3207
3208#ifdef HEX_MATH_NUMBERS
3209 *--str = 'x';
3210 *--str = '0';
3211#endif
3212
3213 if (negative)
3214 *--str = '-';
3215
3216 return variable_buffer_output (o, str, &strbuf[sizeof (strbuf) - 1] - str);
3217}
3218#endif /* CONFIG_WITH_MATH || CONFIG_WITH_NANOTS */
3219
3220#ifdef CONFIG_WITH_MATH
3221
3222/* Converts a string to an integer, causes an error if the format is invalid. */
3223static math_int
3224math_int_from_string (const char *str)
3225{
3226 const char *start;
3227 unsigned base = 0;
3228 int negative = 0;
3229 math_int num = 0;
3230
3231 /* strip spaces */
3232 while (isspace (*str))
3233 str++;
3234 if (!*str)
3235 {
3236 error (NILF, _("bad number: empty\n"));
3237 return 0;
3238 }
3239 start = str;
3240
3241 /* check for +/- */
3242 while (*str == '+' || *str == '-' || isspace (*str))
3243 if (*str++ == '-')
3244 negative = !negative;
3245
3246 /* check for prefix - we do not accept octal numbers, sorry. */
3247 if (*str == '0' && (str[1] == 'x' || str[1] == 'X'))
3248 {
3249 base = 16;
3250 str += 2;
3251 }
3252 else
3253 {
3254 /* look for a hex digit, if not found treat it as decimal */
3255 const char *p2 = str;
3256 for ( ; *p2; p2++)
3257 if (isxdigit (*p2) && !isdigit (*p2) && isascii (*p2) )
3258 {
3259 base = 16;
3260 break;
3261 }
3262 if (base == 0)
3263 base = 10;
3264 }
3265
3266 /* must have at least one digit! */
3267 if ( !isascii (*str)
3268 || !(base == 16 ? isxdigit (*str) : isdigit (*str)) )
3269 {
3270 error (NILF, _("bad number: '%s'\n"), start);
3271 return 0;
3272 }
3273
3274 /* convert it! */
3275 while (*str && !isspace (*str))
3276 {
3277 int ch = *str++;
3278 if (ch >= '0' && ch <= '9')
3279 ch -= '0';
3280 else if (base == 16 && ch >= 'a' && ch <= 'f')
3281 ch -= 'a' - 10;
3282 else if (base == 16 && ch >= 'A' && ch <= 'F')
3283 ch -= 'A' - 10;
3284 else
3285 {
3286 error (NILF, _("bad number: '%s' (base=%d, pos=%d)\n"), start, base, str - start);
3287 return 0;
3288 }
3289 num *= base;
3290 num += ch;
3291 }
3292
3293 /* check trailing spaces. */
3294 while (isspace (*str))
3295 str++;
3296 if (*str)
3297 {
3298 error (NILF, _("bad number: '%s'\n"), start);
3299 return 0;
3300 }
3301
3302 return negative ? -num : num;
3303}
3304
3305/* Add two or more integer numbers. */
3306static char *
3307func_int_add (char *o, char **argv, const char *funcname UNUSED)
3308{
3309 math_int num;
3310 int i;
3311
3312 num = math_int_from_string (argv[0]);
3313 for (i = 1; argv[i]; i++)
3314 num += math_int_from_string (argv[i]);
3315
3316 return math_int_to_variable_buffer (o, num);
3317}
3318
3319/* Subtract two or more integer numbers. */
3320static char *
3321func_int_sub (char *o, char **argv, const char *funcname UNUSED)
3322{
3323 math_int num;
3324 int i;
3325
3326 num = math_int_from_string (argv[0]);
3327 for (i = 1; argv[i]; i++)
3328 num -= math_int_from_string (argv[i]);
3329
3330 return math_int_to_variable_buffer (o, num);
3331}
3332
3333/* Multiply two or more integer numbers. */
3334static char *
3335func_int_mul (char *o, char **argv, const char *funcname UNUSED)
3336{
3337 math_int num;
3338 int i;
3339
3340 num = math_int_from_string (argv[0]);
3341 for (i = 1; argv[i]; i++)
3342 num *= math_int_from_string (argv[i]);
3343
3344 return math_int_to_variable_buffer (o, num);
3345}
3346
3347/* Divide an integer number by one or more divisors. */
3348static char *
3349func_int_div (char *o, char **argv, const char *funcname UNUSED)
3350{
3351 math_int num;
3352 math_int divisor;
3353 int i;
3354
3355 num = math_int_from_string (argv[0]);
3356 for (i = 1; argv[i]; i++)
3357 {
3358 divisor = math_int_from_string (argv[i]);
3359 if (!divisor)
3360 {
3361 error (NILF, _("divide by zero ('%s')\n"), argv[i]);
3362 return math_int_to_variable_buffer (o, 0);
3363 }
3364 num /= divisor;
3365 }
3366
3367 return math_int_to_variable_buffer (o, num);
3368}
3369
3370
3371/* Divide and return the remainder. */
3372static char *
3373func_int_mod (char *o, char **argv, const char *funcname UNUSED)
3374{
3375 math_int num;
3376 math_int divisor;
3377
3378 num = math_int_from_string (argv[0]);
3379 divisor = math_int_from_string (argv[1]);
3380 if (!divisor)
3381 {
3382 error (NILF, _("divide by zero ('%s')\n"), argv[1]);
3383 return math_int_to_variable_buffer (o, 0);
3384 }
3385 num %= divisor;
3386
3387 return math_int_to_variable_buffer (o, num);
3388}
3389
3390/* 2-complement. */
3391static char *
3392func_int_not (char *o, char **argv, const char *funcname UNUSED)
3393{
3394 math_int num;
3395
3396 num = math_int_from_string (argv[0]);
3397 num = ~num;
3398
3399 return math_int_to_variable_buffer (o, num);
3400}
3401
3402/* Bitwise AND (two or more numbers). */
3403static char *
3404func_int_and (char *o, char **argv, const char *funcname UNUSED)
3405{
3406 math_int num;
3407 int i;
3408
3409 num = math_int_from_string (argv[0]);
3410 for (i = 1; argv[i]; i++)
3411 num &= math_int_from_string (argv[i]);
3412
3413 return math_int_to_variable_buffer (o, num);
3414}
3415
3416/* Bitwise OR (two or more numbers). */
3417static char *
3418func_int_or (char *o, char **argv, const char *funcname UNUSED)
3419{
3420 math_int num;
3421 int i;
3422
3423 num = math_int_from_string (argv[0]);
3424 for (i = 1; argv[i]; i++)
3425 num |= math_int_from_string (argv[i]);
3426
3427 return math_int_to_variable_buffer (o, num);
3428}
3429
3430/* Bitwise XOR (two or more numbers). */
3431static char *
3432func_int_xor (char *o, char **argv, const char *funcname UNUSED)
3433{
3434 math_int num;
3435 int i;
3436
3437 num = math_int_from_string (argv[0]);
3438 for (i = 1; argv[i]; i++)
3439 num ^= math_int_from_string (argv[i]);
3440
3441 return math_int_to_variable_buffer (o, num);
3442}
3443
3444/* Compare two integer numbers. Returns make boolean (true="1"; false=""). */
3445static char *
3446func_int_cmp (char *o, char **argv, const char *funcname)
3447{
3448 math_int num1;
3449 math_int num2;
3450 int rc;
3451
3452 num1 = math_int_from_string (argv[0]);
3453 num2 = math_int_from_string (argv[1]);
3454
3455 funcname += sizeof ("int-") - 1;
3456 if (!strcmp (funcname, "eq"))
3457 rc = num1 == num2;
3458 else if (!strcmp (funcname, "ne"))
3459 rc = num1 != num2;
3460 else if (!strcmp (funcname, "gt"))
3461 rc = num1 > num2;
3462 else if (!strcmp (funcname, "ge"))
3463 rc = num1 >= num2;
3464 else if (!strcmp (funcname, "lt"))
3465 rc = num1 < num2;
3466 else /*if (!strcmp (funcname, "le"))*/
3467 rc = num1 <= num2;
3468
3469 return variable_buffer_output (o, rc ? "1" : "", rc);
3470}
3471
3472#endif /* CONFIG_WITH_MATH */
3473
3474#ifdef CONFIG_WITH_NANOTS
3475/* Returns the current timestamp as nano seconds. The time
3476 source is a high res monotone one if the platform provides
3477 this (and we know about it).
3478
3479 Tip. Use this with int-sub to profile makefile reading
3480 and similar. */
3481static char *
3482func_nanots (char *o, char **argv, const char *funcname)
3483{
3484 math_int ts;
3485
3486#if defined (WINDOWS32)
3487 static int s_state = -1;
3488 static LARGE_INTEGER s_freq;
3489
3490 if (s_state == -1)
3491 s_state = QueryPerformanceFrequency (&s_freq);
3492 if (s_state)
3493 {
3494 LARGE_INTEGER pc;
3495 if (!QueryPerformanceCounter (&pc))
3496 {
3497 s_state = 0;
3498 return func_nanots (o, argv, funcname);
3499 }
3500 ts = (math_int)((long double)pc.QuadPart / (long double)s_freq.QuadPart * 1000000000);
3501 }
3502 else
3503 {
3504 /* fall back to low resolution system time. */
3505 LARGE_INTEGER bigint;
3506 FILETIME ft = {0,0};
3507 GetSystemTimeAsFileTime (&ft);
3508 bigint.u.LowPart = ft.dwLowDateTime;
3509 bigint.u.HighPart = ft.dwLowDateTime;
3510 ts = bigint.QuadPart * 100;
3511 }
3512
3513/* FIXME: Linux and others have the realtime clock_* api, detect and use it. */
3514
3515#elif HAVE_GETTIMEOFDAY
3516 struct timeval tv;
3517 if (!gettimeofday (&tv, NULL))
3518 ts = (math_int)tv.tv_sec * 1000000000
3519 + tv.tv_usec * 1000;
3520 else
3521 {
3522 error (NILF, _("$(nanots): gettimeofday failed"));
3523 ts = 0;
3524 }
3525
3526#else
3527# error "PORTME"
3528#endif
3529
3530 return math_int_to_variable_buffer (o, ts);
3531}
3532#endif
3533
3534#ifdef CONFIG_WITH_OS2_LIBPATH
3535/* Sets or gets the OS/2 libpath variables.
3536
3537 The first argument indicates which variable - BEGINLIBPATH,
3538 ENDLIBPATH, LIBPATHSTRICT or LIBPATH.
3539
3540 The second indicates whether this is a get (not present) or
3541 set (present) operation. When present it is the new value for
3542 the variable. */
3543static char *
3544func_os2_libpath (char *o, char **argv, const char *funcname UNUSED)
3545{
3546 char buf[4096];
3547 ULONG fVar;
3548 APIRET rc;
3549
3550 /* translate variable name (first arg) */
3551 if (!strcmp (argv[0], "BEGINLIBPATH"))
3552 fVar = BEGIN_LIBPATH;
3553 else if (!strcmp (argv[0], "ENDLIBPATH"))
3554 fVar = END_LIBPATH;
3555 else if (!strcmp (argv[0], "LIBPATHSTRICT"))
3556 fVar = LIBPATHSTRICT;
3557 else if (!strcmp (argv[0], "LIBPATH"))
3558 fVar = 0;
3559 else
3560 {
3561 error (NILF, _("$(libpath): unknown variable `%s'"), argv[0]);
3562 return variable_buffer_output (o, "", 0);
3563 }
3564
3565 if (!argv[1])
3566 {
3567 /* get the variable value. */
3568 if (fVar != 0)
3569 {
3570 buf[0] = buf[1] = buf[2] = buf[3] = '\0';
3571 rc = DosQueryExtLIBPATH (buf, fVar);
3572 }
3573 else
3574 rc = DosQueryHeaderInfo (NULLHANDLE, 0, buf, sizeof(buf), QHINF_LIBPATH);
3575 if (rc != NO_ERROR)
3576 {
3577 error (NILF, _("$(libpath): failed to query `%s', rc=%d"), argv[0], rc);
3578 return variable_buffer_output (o, "", 0);
3579 }
3580 o = variable_buffer_output (o, buf, strlen (buf));
3581 }
3582 else
3583 {
3584 /* set the variable value. */
3585 size_t len;
3586 size_t len_max = sizeof (buf) < 2048 ? sizeof (buf) : 2048;
3587 const char *val;
3588 const char *end;
3589
3590 if (fVar == 0)
3591 {
3592 error (NILF, _("$(libpath): LIBPATH is read-only"));
3593 return variable_buffer_output (o, "", 0);
3594 }
3595
3596 /* strip leading and trailing spaces and check for max length. */
3597 val = argv[1];
3598 while (isspace (*val))
3599 val++;
3600 end = strchr (val, '\0');
3601 while (end > val && isspace (end[-1]))
3602 end--;
3603
3604 len = end - val;
3605 if (len >= len_max)
3606 {
3607 error (NILF, _("$(libpath): The new `%s' value is too long (%d bytes, max %d)"),
3608 argv[0], len, len_max);
3609 return variable_buffer_output (o, "", 0);
3610 }
3611
3612 /* make a stripped copy in low memory and try set it. */
3613 memcpy (buf, val, len);
3614 buf[len] = '\0';
3615 rc = DosSetExtLIBPATH (buf, fVar);
3616 if (rc != NO_ERROR)
3617 {
3618 error (NILF, _("$(libpath): failed to set `%s' to `%s', rc=%d"), argv[0], buf, rc);
3619 return variable_buffer_output (o, "", 0);
3620 }
3621
3622 o = variable_buffer_output (o, "", 0);
3623 }
3624 return o;
3625}
3626#endif /* CONFIG_WITH_OS2_LIBPATH */
3627
3628#ifdef CONFIG_WITH_MAKE_STATS
3629/* Retrieve make statistics. */
3630static char *
3631func_make_stats (char *o, char **argv, const char *funcname UNUSED)
3632{
3633 char buf[512];
3634 int len;
3635
3636 if (!argv[0] || (!argv[0][0] && !argv[1]))
3637 {
3638 len = sprintf (buf, "alloc-cur: %5lu %6luKB (/%3luMB) hash: %5lu %2lu%%",
3639 make_stats_allocations,
3640 make_stats_allocated / 1024,
3641 make_stats_allocated_sum / (1024*1024),
3642 make_stats_ht_lookups,
3643 (make_stats_ht_collisions * 100) / make_stats_ht_lookups);
3644 o = variable_buffer_output (o, buf, len);
3645 }
3646 else
3647 {
3648 /* selective */
3649 int i;
3650 for (i = 0; argv[i]; i++)
3651 {
3652 unsigned long val;
3653 if (i != 0)
3654 o = variable_buffer_output (o, " ", 1);
3655 if (!strcmp(argv[i], "allocations"))
3656 val = make_stats_allocations;
3657 else if (!strcmp(argv[i], "allocated"))
3658 val = make_stats_allocated;
3659 else if (!strcmp(argv[i], "allocated_sum"))
3660 val = make_stats_allocated_sum;
3661 else if (!strcmp(argv[i], "ht_lookups"))
3662 val = make_stats_ht_lookups;
3663 else if (!strcmp(argv[i], "ht_collisions"))
3664 val = make_stats_ht_collisions;
3665 else if (!strcmp(argv[i], "ht_collisions_pct"))
3666 val = (make_stats_ht_collisions * 100) / make_stats_ht_lookups;
3667 else
3668 {
3669 o = variable_buffer_output (o, argv[i], strlen (argv[i]));
3670 continue;
3671 }
3672
3673 len = sprintf (buf, "%ld", val);
3674 o = variable_buffer_output (o, buf, len);
3675 }
3676 }
3677 return o;
3678}
3679#endif /* CONFIG_WITH_MAKE_STATS */
3680
3681#ifdef CONFIG_WITH_COMMANDS_FUNC
3682/* Gets all the commands for a target, separated by newlines.
3683
3684 This is useful when creating and checking target dependencies since
3685 it reduces the amount of work and the memory consuption. A new prefix
3686 character '%' has been introduced for skipping certain lines, like
3687 for instance the one calling this function and pushing to a dep file.
3688 Blank lines are also skipped.
3689
3690 The commands function takes exactly one argument, which is the name of
3691 the target which commands should be returned.
3692
3693 The commands-sc is identical to commands except that it uses a ';' to
3694 separate the commands.
3695
3696 The commands-usr is similar to commands except that it takes a 2nd
3697 argument that is used to separate the commands. */
3698char *
3699func_commands (char *o, char **argv, const char *funcname)
3700{
3701 struct file *file;
3702 static int recursive = 0;
3703
3704 if (recursive)
3705 {
3706 error (reading_file, _("$(%s ) was invoked recursivly"), funcname);
3707 return variable_buffer_output (o, "recursive", sizeof ("recursive") - 1);
3708 }
3709 if (*argv[0] == '\0')
3710 {
3711 error (reading_file, _("$(%s ) was invoked with an empty target name"), funcname);
3712 return o;
3713 }
3714 recursive = 1;
3715
3716 file = lookup_file (argv[0]);
3717 if (file && file->cmds)
3718 {
3719 unsigned int i;
3720 int cmd_sep_len;
3721 struct commands *cmds = file->cmds;
3722 const char *cmd_sep;
3723
3724 if (!strcmp (funcname, "commands"))
3725 {
3726 cmd_sep = "\n";
3727 cmd_sep_len = 1;
3728 }
3729 else if (!strcmp (funcname, "commands-sc"))
3730 {
3731 cmd_sep = ";";
3732 cmd_sep_len = 1;
3733 }
3734 else /*if (!strcmp (funcname, "commands-usr"))*/
3735 {
3736 cmd_sep = argv[1];
3737 cmd_sep_len = strlen (cmd_sep);
3738 }
3739
3740 initialize_file_variables (file, 1 /* reading - FIXME: we don't know? */);
3741 set_file_variables (file);
3742 chop_commands (cmds);
3743
3744 for (i = 0; i < cmds->ncommand_lines; i++)
3745 {
3746 char *p;
3747 char *in, *out, *ref;
3748
3749 /* Skip it if it has a '%' prefix or is blank. */
3750 if (cmds->lines_flags[i] & COMMAND_GETTER_SKIP_IT)
3751 continue;
3752 p = cmds->command_lines[i];
3753 while (isblank ((unsigned char)*p))
3754 p++;
3755 if (*p == '\0')
3756 continue;
3757
3758 /* --- copied from new_job() in job.c --- */
3759
3760 /* Collapse backslash-newline combinations that are inside variable
3761 or function references. These are left alone by the parser so
3762 that they will appear in the echoing of commands (where they look
3763 nice); and collapsed by construct_command_argv when it tokenizes.
3764 But letting them survive inside function invocations loses because
3765 we don't want the functions to see them as part of the text. */
3766
3767 /* IN points to where in the line we are scanning.
3768 OUT points to where in the line we are writing.
3769 When we collapse a backslash-newline combination,
3770 IN gets ahead of OUT. */
3771
3772 in = out = p;
3773 while ((ref = strchr (in, '$')) != 0)
3774 {
3775 ++ref; /* Move past the $. */
3776
3777 if (out != in)
3778 /* Copy the text between the end of the last chunk
3779 we processed (where IN points) and the new chunk
3780 we are about to process (where REF points). */
3781 memmove (out, in, ref - in);
3782
3783 /* Move both pointers past the boring stuff. */
3784 out += ref - in;
3785 in = ref;
3786
3787 if (*ref == '(' || *ref == '{')
3788 {
3789 char openparen = *ref;
3790 char closeparen = openparen == '(' ? ')' : '}';
3791 int count;
3792 char *p;
3793
3794 *out++ = *in++; /* Copy OPENPAREN. */
3795 /* IN now points past the opening paren or brace.
3796 Count parens or braces until it is matched. */
3797 count = 0;
3798 while (*in != '\0')
3799 {
3800 if (*in == closeparen && --count < 0)
3801 break;
3802 else if (*in == '\\' && in[1] == '\n')
3803 {
3804 /* We have found a backslash-newline inside a
3805 variable or function reference. Eat it and
3806 any following whitespace. */
3807
3808 int quoted = 0;
3809 for (p = in - 1; p > ref && *p == '\\'; --p)
3810 quoted = !quoted;
3811
3812 if (quoted)
3813 /* There were two or more backslashes, so this is
3814 not really a continuation line. We don't collapse
3815 the quoting backslashes here as is done in
3816 collapse_continuations, because the line will
3817 be collapsed again after expansion. */
3818 *out++ = *in++;
3819 else
3820 {
3821 /* Skip the backslash, newline and
3822 any following whitespace. */
3823 in = next_token (in + 2);
3824
3825 /* Discard any preceding whitespace that has
3826 already been written to the output. */
3827 while (out > ref
3828 && isblank ((unsigned char)out[-1]))
3829 --out;
3830
3831 /* Replace it all with a single space. */
3832 *out++ = ' ';
3833 }
3834 }
3835 else
3836 {
3837 if (*in == openparen)
3838 ++count;
3839
3840 *out++ = *in++;
3841 }
3842 }
3843 }
3844 /* Some of these can be amended ($< perhaps), but we're likely to be called while the
3845 dep expansion happens, so it would have to be on a hackish basis. sad... */
3846 else if (*ref == '<' || *ref == '*' || *ref == '%' || *ref == '^' || *ref == '+')
3847 error (reading_file, _("$(%s ) does not work reliably with $%c in all cases"), funcname, *ref);
3848 }
3849
3850 /* There are no more references in this line to worry about.
3851 Copy the remaining uninteresting text to the output. */
3852 if (out != in)
3853 strcpy (out, in);
3854
3855 /* --- copied from new_job() in job.c --- */
3856
3857 /* Finally, expand the line. */
3858 if (i)
3859 o = variable_buffer_output (o, cmd_sep, cmd_sep_len);
3860 o = variable_expand_for_file_2 (o, cmds->command_lines[i], file);
3861
3862 /* Skip it if it has a '%' prefix or is blank. */
3863 p = o;
3864 while (isblank ((unsigned char)*o)
3865 || *o == '@'
3866 || *o == '-'
3867 || *o == '+')
3868 o++;
3869 if (*o != '\0' && *o != '%')
3870 o = strchr (o, '\0');
3871 else if (i)
3872 o = p - cmd_sep_len;
3873 else
3874 o = p;
3875 } /* for each command line */
3876 }
3877 /* else FIXME: bitch about it? */
3878
3879 recursive = 0;
3880 return o;
3881}
3882#endif /* CONFIG_WITH_COMMANDS_FUNC */
3883
3884#ifdef KMK
3885/* Useful when debugging kmk and/or makefiles. */
3886char *
3887func_breakpoint (char *o, char **argv, const char *funcname)
3888{
3889#ifdef _MSC_VER
3890 __debugbreak();
3891#elif defined(__i386__) || defined(__x86__) || defined(__X86__) || defined(_M_IX86) || defined(__i386) \
3892 || defined(__amd64__) || defined(__x86_64__) || defined(__AMD64__) || defined(_M_X64) || defined(__amd64)
3893 __asm__ __volatile__ ("int3\n\t");
3894#else
3895 char *p = (char *)0;
3896 *p = '\0';
3897#endif
3898 return o;
3899}
3900#endif /* KMK */
3901
3902
3903/* Lookup table for builtin functions.
3904
3905 This doesn't have to be sorted; we use a straight lookup. We might gain
3906 some efficiency by moving most often used functions to the start of the
3907 table.
3908
3909 If MAXIMUM_ARGS is 0, that means there is no maximum and all
3910 comma-separated values are treated as arguments.
3911
3912 EXPAND_ARGS means that all arguments should be expanded before invocation.
3913 Functions that do namespace tricks (foreach) don't automatically expand. */
3914
3915static char *func_call (char *o, char **argv, const char *funcname);
3916
3917
3918static struct function_table_entry function_table_init[] =
3919{
3920 /* Name/size */ /* MIN MAX EXP? Function */
3921 { STRING_SIZE_TUPLE("abspath"), 0, 1, 1, func_abspath},
3922 { STRING_SIZE_TUPLE("addprefix"), 2, 2, 1, func_addsuffix_addprefix},
3923 { STRING_SIZE_TUPLE("addsuffix"), 2, 2, 1, func_addsuffix_addprefix},
3924 { STRING_SIZE_TUPLE("basename"), 0, 1, 1, func_basename_dir},
3925 { STRING_SIZE_TUPLE("dir"), 0, 1, 1, func_basename_dir},
3926 { STRING_SIZE_TUPLE("notdir"), 0, 1, 1, func_notdir_suffix},
3927 { STRING_SIZE_TUPLE("subst"), 3, 3, 1, func_subst},
3928 { STRING_SIZE_TUPLE("suffix"), 0, 1, 1, func_notdir_suffix},
3929 { STRING_SIZE_TUPLE("filter"), 2, 2, 1, func_filter_filterout},
3930 { STRING_SIZE_TUPLE("filter-out"), 2, 2, 1, func_filter_filterout},
3931 { STRING_SIZE_TUPLE("findstring"), 2, 2, 1, func_findstring},
3932 { STRING_SIZE_TUPLE("firstword"), 0, 1, 1, func_firstword},
3933 { STRING_SIZE_TUPLE("flavor"), 0, 1, 1, func_flavor},
3934 { STRING_SIZE_TUPLE("join"), 2, 2, 1, func_join},
3935 { STRING_SIZE_TUPLE("lastword"), 0, 1, 1, func_lastword},
3936 { STRING_SIZE_TUPLE("patsubst"), 3, 3, 1, func_patsubst},
3937 { STRING_SIZE_TUPLE("realpath"), 0, 1, 1, func_realpath},
3938#ifdef CONFIG_WITH_RSORT
3939 { STRING_SIZE_TUPLE("rsort"), 0, 1, 1, func_sort},
3940#endif
3941 { STRING_SIZE_TUPLE("shell"), 0, 1, 1, func_shell},
3942 { STRING_SIZE_TUPLE("sort"), 0, 1, 1, func_sort},
3943 { STRING_SIZE_TUPLE("strip"), 0, 1, 1, func_strip},
3944 { STRING_SIZE_TUPLE("wildcard"), 0, 1, 1, func_wildcard},
3945 { STRING_SIZE_TUPLE("word"), 2, 2, 1, func_word},
3946 { STRING_SIZE_TUPLE("wordlist"), 3, 3, 1, func_wordlist},
3947 { STRING_SIZE_TUPLE("words"), 0, 1, 1, func_words},
3948 { STRING_SIZE_TUPLE("origin"), 0, 1, 1, func_origin},
3949 { STRING_SIZE_TUPLE("foreach"), 3, 3, 0, func_foreach},
3950 { STRING_SIZE_TUPLE("call"), 1, 0, 1, func_call},
3951 { STRING_SIZE_TUPLE("info"), 0, 1, 1, func_error},
3952 { STRING_SIZE_TUPLE("error"), 0, 1, 1, func_error},
3953 { STRING_SIZE_TUPLE("warning"), 0, 1, 1, func_error},
3954 { STRING_SIZE_TUPLE("if"), 2, 3, 0, func_if},
3955 { STRING_SIZE_TUPLE("or"), 1, 0, 0, func_or},
3956 { STRING_SIZE_TUPLE("and"), 1, 0, 0, func_and},
3957 { STRING_SIZE_TUPLE("value"), 0, 1, 1, func_value},
3958 { STRING_SIZE_TUPLE("eval"), 0, 1, 1, func_eval},
3959#ifdef CONFIG_WITH_EVALPLUS
3960 { STRING_SIZE_TUPLE("evalctx"), 0, 1, 1, func_evalctx},
3961 { STRING_SIZE_TUPLE("evalval"), 1, 1, 1, func_evalval},
3962 { STRING_SIZE_TUPLE("evalvalctx"), 1, 1, 1, func_evalval},
3963 { STRING_SIZE_TUPLE("evalcall"), 1, 0, 1, func_call},
3964 { STRING_SIZE_TUPLE("evalcall2"), 1, 0, 1, func_call},
3965#endif
3966#ifdef EXPERIMENTAL
3967 { STRING_SIZE_TUPLE("eq"), 2, 2, 1, func_eq},
3968 { STRING_SIZE_TUPLE("not"), 0, 1, 1, func_not},
3969#endif
3970#ifdef CONFIG_WITH_DEFINED
3971 { STRING_SIZE_TUPLE("defined"), 1, 1, 1, func_defined},
3972#endif
3973#ifdef CONFIG_WITH_TOUPPER_TOLOWER
3974 { STRING_SIZE_TUPLE("toupper"), 0, 1, 1, func_toupper_tolower},
3975 { STRING_SIZE_TUPLE("tolower"), 0, 1, 1, func_toupper_tolower},
3976#endif
3977#ifdef CONFIG_WITH_ABSPATHEX
3978 { STRING_SIZE_TUPLE("abspathex"), 0, 2, 1, func_abspathex},
3979#endif
3980#ifdef CONFIG_WITH_XARGS
3981 { STRING_SIZE_TUPLE("xargs"), 2, 0, 1, func_xargs},
3982#endif
3983#if defined(CONFIG_WITH_VALUE_LENGTH) && defined(CONFIG_WITH_COMPARE)
3984 { STRING_SIZE_TUPLE("comp-vars"), 3, 3, 1, func_comp_vars},
3985 { STRING_SIZE_TUPLE("comp-cmds"), 3, 3, 1, func_comp_vars},
3986 { STRING_SIZE_TUPLE("comp-cmds-ex"), 3, 3, 1, func_comp_cmds_ex},
3987#endif
3988#ifdef CONFIG_WITH_DATE
3989 { STRING_SIZE_TUPLE("date"), 0, 1, 1, func_date},
3990 { STRING_SIZE_TUPLE("date-utc"), 0, 3, 1, func_date},
3991#endif
3992#ifdef CONFIG_WITH_FILE_SIZE
3993 { STRING_SIZE_TUPLE("file-size"), 1, 1, 1, func_file_size},
3994#endif
3995#ifdef CONFIG_WITH_WHICH
3996 { STRING_SIZE_TUPLE("which"), 0, 0, 1, func_which},
3997#endif
3998#ifdef CONFIG_WITH_IF_CONDITIONALS
3999 { STRING_SIZE_TUPLE("expr"), 1, 1, 0, func_expr},
4000 { STRING_SIZE_TUPLE("if-expr"), 2, 3, 0, func_if_expr},
4001#endif
4002#ifdef CONFIG_WITH_STACK
4003 { STRING_SIZE_TUPLE("stack-push"), 2, 2, 1, func_stack_push},
4004 { STRING_SIZE_TUPLE("stack-pop"), 1, 1, 1, func_stack_pop_top},
4005 { STRING_SIZE_TUPLE("stack-popv"), 1, 1, 1, func_stack_pop_top},
4006 { STRING_SIZE_TUPLE("stack-top"), 1, 1, 1, func_stack_pop_top},
4007#endif
4008#ifdef CONFIG_WITH_MATH
4009 { STRING_SIZE_TUPLE("int-add"), 2, 0, 1, func_int_add},
4010 { STRING_SIZE_TUPLE("int-sub"), 2, 0, 1, func_int_sub},
4011 { STRING_SIZE_TUPLE("int-mul"), 2, 0, 1, func_int_mul},
4012 { STRING_SIZE_TUPLE("int-div"), 2, 0, 1, func_int_div},
4013 { STRING_SIZE_TUPLE("int-mod"), 2, 2, 1, func_int_mod},
4014 { STRING_SIZE_TUPLE("int-not"), 1, 1, 1, func_int_not},
4015 { STRING_SIZE_TUPLE("int-and"), 2, 0, 1, func_int_and},
4016 { STRING_SIZE_TUPLE("int-or"), 2, 0, 1, func_int_or},
4017 { STRING_SIZE_TUPLE("int-xor"), 2, 0, 1, func_int_xor},
4018 { STRING_SIZE_TUPLE("int-eq"), 2, 2, 1, func_int_cmp},
4019 { STRING_SIZE_TUPLE("int-ne"), 2, 2, 1, func_int_cmp},
4020 { STRING_SIZE_TUPLE("int-gt"), 2, 2, 1, func_int_cmp},
4021 { STRING_SIZE_TUPLE("int-ge"), 2, 2, 1, func_int_cmp},
4022 { STRING_SIZE_TUPLE("int-lt"), 2, 2, 1, func_int_cmp},
4023 { STRING_SIZE_TUPLE("int-le"), 2, 2, 1, func_int_cmp},
4024#endif
4025#ifdef CONFIG_WITH_NANOTS
4026 { STRING_SIZE_TUPLE("nanots"), 0, 0, 0, func_nanots},
4027#endif
4028#ifdef CONFIG_WITH_OS2_LIBPATH
4029 { STRING_SIZE_TUPLE("libpath"), 1, 2, 1, func_os2_libpath},
4030#endif
4031#ifdef CONFIG_WITH_MAKE_STATS
4032 { STRING_SIZE_TUPLE("make-stats"), 0, 0, 0, func_make_stats},
4033#endif
4034#ifdef CONFIG_WITH_COMMANDS_FUNC
4035 { STRING_SIZE_TUPLE("commands"), 1, 1, 1, func_commands},
4036 { STRING_SIZE_TUPLE("commands-sc"), 1, 1, 1, func_commands},
4037 { STRING_SIZE_TUPLE("commands-usr"), 2, 2, 1, func_commands},
4038#endif
4039#ifdef KMK_HELPERS
4040 { STRING_SIZE_TUPLE("kb-src-tool"), 1, 1, 0, func_kbuild_source_tool},
4041 { STRING_SIZE_TUPLE("kb-obj-base"), 1, 1, 0, func_kbuild_object_base},
4042 { STRING_SIZE_TUPLE("kb-obj-suff"), 1, 1, 0, func_kbuild_object_suffix},
4043 { STRING_SIZE_TUPLE("kb-src-prop"), 3, 4, 0, func_kbuild_source_prop},
4044 { STRING_SIZE_TUPLE("kb-src-one"), 0, 1, 0, func_kbuild_source_one},
4045#endif
4046#ifdef KMK
4047 { STRING_SIZE_TUPLE("breakpoint"), 0, 0, 0, func_breakpoint},
4048#endif
4049};
4050
4051#define FUNCTION_TABLE_ENTRIES (sizeof (function_table_init) / sizeof (struct function_table_entry))
4052
4053
4054
4055/* These must come after the definition of function_table. */
4056
4057static char *
4058expand_builtin_function (char *o, int argc, char **argv,
4059 const struct function_table_entry *entry_p)
4060{
4061 if (argc < (int)entry_p->minimum_args)
4062 fatal (*expanding_var,
4063 _("insufficient number of arguments (%d) to function `%s'"),
4064 argc, entry_p->name);
4065
4066 /* I suppose technically some function could do something with no
4067 arguments, but so far none do, so just test it for all functions here
4068 rather than in each one. We can change it later if necessary. */
4069
4070 if (!argc)
4071 return o;
4072
4073 if (!entry_p->func_ptr)
4074 fatal (*expanding_var,
4075 _("unimplemented on this platform: function `%s'"), entry_p->name);
4076
4077 return entry_p->func_ptr (o, argv, entry_p->name);
4078}
4079
4080/* Check for a function invocation in *STRINGP. *STRINGP points at the
4081 opening ( or { and is not null-terminated. If a function invocation
4082 is found, expand it into the buffer at *OP, updating *OP, incrementing
4083 *STRINGP past the reference and returning nonzero. If not, return zero. */
4084
4085static int
4086handle_function2 (const struct function_table_entry *entry_p, char **op, const char **stringp) /* bird split it up. */
4087{
4088 char openparen = (*stringp)[0];
4089 char closeparen = openparen == '(' ? ')' : '}';
4090 const char *beg;
4091 const char *end;
4092 int count = 0;
4093 char *abeg = NULL;
4094 char **argv, **argvp;
4095 int nargs;
4096
4097 beg = *stringp + 1;
4098
4099 /* We found a builtin function. Find the beginning of its arguments (skip
4100 whitespace after the name). */
4101
4102 beg = next_token (beg + entry_p->len);
4103
4104 /* Find the end of the function invocation, counting nested use of
4105 whichever kind of parens we use. Since we're looking, count commas
4106 to get a rough estimate of how many arguments we might have. The
4107 count might be high, but it'll never be low. */
4108
4109 for (nargs=1, end=beg; *end != '\0'; ++end)
4110 if (*end == ',')
4111 ++nargs;
4112 else if (*end == openparen)
4113 ++count;
4114 else if (*end == closeparen && --count < 0)
4115 break;
4116
4117 if (count >= 0)
4118 fatal (*expanding_var,
4119 _("unterminated call to function `%s': missing `%c'"),
4120 entry_p->name, closeparen);
4121
4122 *stringp = end;
4123
4124 /* Get some memory to store the arg pointers. */
4125 argvp = argv = alloca (sizeof (char *) * (nargs + 2));
4126
4127 /* Chop the string into arguments, then a nul. As soon as we hit
4128 MAXIMUM_ARGS (if it's >0) assume the rest of the string is part of the
4129 last argument.
4130
4131 If we're expanding, store pointers to the expansion of each one. If
4132 not, make a duplicate of the string and point into that, nul-terminating
4133 each argument. */
4134
4135 if (entry_p->expand_args)
4136 {
4137 const char *p;
4138 for (p=beg, nargs=0; p <= end; ++argvp)
4139 {
4140 const char *next;
4141
4142 ++nargs;
4143
4144 if (nargs == entry_p->maximum_args
4145 || (! (next = find_next_argument (openparen, closeparen, p, end))))
4146 next = end;
4147
4148 *argvp = expand_argument (p, next);
4149 p = next + 1;
4150 }
4151 }
4152 else
4153 {
4154 int len = end - beg;
4155 char *p, *aend;
4156
4157 abeg = xmalloc (len+1);
4158 memcpy (abeg, beg, len);
4159 abeg[len] = '\0';
4160 aend = abeg + len;
4161
4162 for (p=abeg, nargs=0; p <= aend; ++argvp)
4163 {
4164 char *next;
4165
4166 ++nargs;
4167
4168 if (nargs == entry_p->maximum_args
4169 || (! (next = find_next_argument (openparen, closeparen, p, aend))))
4170 next = aend;
4171
4172 *argvp = p;
4173 *next = '\0';
4174 p = next + 1;
4175 }
4176 }
4177 *argvp = NULL;
4178
4179 /* Finally! Run the function... */
4180 *op = expand_builtin_function (*op, nargs, argv, entry_p);
4181
4182 /* Free memory. */
4183 if (entry_p->expand_args)
4184 for (argvp=argv; *argvp != 0; ++argvp)
4185 free (*argvp);
4186 if (abeg)
4187 free (abeg);
4188
4189 return 1;
4190}
4191
4192int
4193handle_function (char **op, const char **stringp) /* bird split it up */
4194{
4195 const struct function_table_entry *entry_p = lookup_function (*stringp + 1);
4196 if (!entry_p)
4197 return 0;
4198 return handle_function2 (entry_p, op, stringp);
4199}
4200
4201
4202
4203/* User-defined functions. Expand the first argument as either a builtin
4204 function or a make variable, in the context of the rest of the arguments
4205 assigned to $1, $2, ... $N. $0 is the name of the function. */
4206
4207static char *
4208func_call (char *o, char **argv, const char *funcname UNUSED)
4209{
4210 static int max_args = 0;
4211 char *fname;
4212 char *cp;
4213 char *body;
4214 int flen;
4215 int i;
4216 int saved_args;
4217 const struct function_table_entry *entry_p;
4218 struct variable *v;
4219#ifdef CONFIG_WITH_EVALPLUS
4220 char *buf;
4221 unsigned int len;
4222#endif
4223
4224 /* There is no way to define a variable with a space in the name, so strip
4225 leading and trailing whitespace as a favor to the user. */
4226 fname = argv[0];
4227 while (*fname != '\0' && isspace ((unsigned char)*fname))
4228 ++fname;
4229
4230 cp = fname + strlen (fname) - 1;
4231 while (cp > fname && isspace ((unsigned char)*cp))
4232 --cp;
4233 cp[1] = '\0';
4234
4235 /* Calling nothing is a no-op */
4236 if (*fname == '\0')
4237 return o;
4238
4239 /* Are we invoking a builtin function? */
4240
4241 entry_p = lookup_function (fname);
4242 if (entry_p)
4243 {
4244 /* How many arguments do we have? */
4245 for (i=0; argv[i+1]; ++i)
4246 ;
4247 return expand_builtin_function (o, i, argv+1, entry_p);
4248 }
4249
4250 /* Not a builtin, so the first argument is the name of a variable to be
4251 expanded and interpreted as a function. Find it. */
4252 flen = strlen (fname);
4253
4254 v = lookup_variable (fname, flen);
4255
4256 if (v == 0)
4257 warn_undefined (fname, flen);
4258
4259 if (v == 0 || *v->value == '\0')
4260 return o;
4261
4262 body = alloca (flen + 4);
4263 body[0] = '$';
4264 body[1] = '(';
4265 memcpy (body + 2, fname, flen);
4266 body[flen+2] = ')';
4267 body[flen+3] = '\0';
4268
4269 /* Set up arguments $(1) .. $(N). $(0) is the function name. */
4270
4271 push_new_variable_scope ();
4272
4273 for (i=0; *argv; ++i, ++argv)
4274 {
4275 char num[11];
4276
4277 sprintf (num, "%d", i);
4278 define_variable (num, strlen (num), *argv, o_automatic, 0);
4279 }
4280
4281 /* If the number of arguments we have is < max_args, it means we're inside
4282 a recursive invocation of $(call ...). Fill in the remaining arguments
4283 in the new scope with the empty value, to hide them from this
4284 invocation. */
4285
4286 for (; i < max_args; ++i)
4287 {
4288 char num[11];
4289
4290 sprintf (num, "%d", i);
4291 define_variable (num, strlen (num), "", o_automatic, 0);
4292 }
4293
4294 saved_args = max_args;
4295 max_args = i;
4296
4297#ifdef CONFIG_WITH_EVALPLUS
4298 if (!strcmp (funcname, "call"))
4299 {
4300#endif
4301 /* Expand the body in the context of the arguments, adding the result to
4302 the variable buffer. */
4303
4304 v->exp_count = EXP_COUNT_MAX;
4305 o = variable_expand_string (o, body, flen+3);
4306 v->exp_count = 0;
4307
4308 o += strlen (o);
4309#ifdef CONFIG_WITH_EVALPLUS
4310 }
4311 else
4312 {
4313 const struct floc *reading_file_saved = reading_file;
4314
4315 if (!strcmp (funcname, "evalcall"))
4316 {
4317 /* Evaluate the variable value without expanding it. We
4318 need a copy since eval_buffer is destructive. */
4319
4320 size_t off = o - variable_buffer;
4321 o = variable_buffer_output (o, v->value, v->value_length + 1);
4322 o = variable_buffer + off;
4323 if (v->fileinfo.filenm)
4324 reading_file = &v->fileinfo;
4325 }
4326 else
4327 {
4328 /* Expand the body first and then evaluate the output. */
4329
4330 v->exp_count = EXP_COUNT_MAX;
4331 o = variable_expand_string (o, body, flen+3);
4332 v->exp_count = 0;
4333 }
4334
4335 install_variable_buffer (&buf, &len);
4336 eval_buffer (o);
4337 restore_variable_buffer (buf, len);
4338 reading_file = reading_file_saved;
4339 }
4340#endif /* CONFIG_WITH_EVALPLUS */
4341
4342 max_args = saved_args;
4343
4344 pop_variable_scope ();
4345
4346 return o;
4347}
4348
4349void
4350hash_init_function_table (void)
4351{
4352 hash_init (&function_table, FUNCTION_TABLE_ENTRIES * 2,
4353 function_table_entry_hash_1, function_table_entry_hash_2,
4354 function_table_entry_hash_cmp);
4355 hash_load (&function_table, function_table_init,
4356 FUNCTION_TABLE_ENTRIES, sizeof (struct function_table_entry));
4357#ifdef CONFIG_WITH_OPTIMIZATION_HACKS
4358 {
4359 unsigned i;
4360 for (i = 0; i < FUNCTION_TABLE_ENTRIES; i++)
4361 assert (function_table_init[i].len <= MAX_FUNCTION_LENGTH);
4362 }
4363#endif
4364}
Note: See TracBrowser for help on using the repository browser.

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