VirtualBox

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

Last change on this file since 1822 was 1809, checked in by bird, 17 years ago

kmk: More length and alloc optimizations. Made all the length optimizations from yesterday CONFIG_WITH_VALUE_LENGTH instead of KMK.

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

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