VirtualBox

source: kBuild/trunk/src/gmake/function.c@ 803

Last change on this file since 803 was 763, checked in by bird, 18 years ago

integer math functions.

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

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