VirtualBox

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

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

kmk: Some minor optimizations.

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