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

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

Using the variable buffer for temp storage is (probably) fast, smaller and better.

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