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

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

Fixed bug in $(commands ) that caused occational heap corruption.

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