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

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

Added $(make-stats ) that provides access to memory and hash stats (if CONFIG_WITH_MAKE_STATS is defined).

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