source: trunk/src/gmake/function.c@ 528

Last change on this file since 528 was 527, checked in by bird, 19 years ago

CONFIG_WITH_OPTIMIZATION_HACKS

  • Property svn:eol-style set to native
File size: 59.2 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#include <assert.h> /* bird */
35
36
37struct function_table_entry
38 {
39 const char *name;
40 unsigned char len;
41 unsigned char minimum_args;
42 unsigned char maximum_args;
43 char expand_args;
44 char *(*func_ptr) PARAMS ((char *output, char **argv, const char *fname));
45 };
46
47static unsigned long
48function_table_entry_hash_1 (const void *keyv)
49{
50 struct function_table_entry const *key = (struct function_table_entry const *) keyv;
51 return_STRING_N_HASH_1 (key->name, key->len);
52}
53
54static unsigned long
55function_table_entry_hash_2 (const void *keyv)
56{
57 struct function_table_entry const *key = (struct function_table_entry const *) keyv;
58 return_STRING_N_HASH_2 (key->name, key->len);
59}
60
61static int
62function_table_entry_hash_cmp (const void *xv, const void *yv)
63{
64 struct function_table_entry const *x = (struct function_table_entry const *) xv;
65 struct function_table_entry const *y = (struct function_table_entry const *) yv;
66 int result = x->len - y->len;
67 if (result)
68 return result;
69 return_STRING_N_COMPARE (x->name, y->name, x->len);
70}
71
72static struct hash_table function_table;
73
74
75
76/* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing
77 each occurrence of SUBST with REPLACE. TEXT is null-terminated. SLEN is
78 the length of SUBST and RLEN is the length of REPLACE. If BY_WORD is
79 nonzero, substitutions are done only on matches which are complete
80 whitespace-delimited words. */
81
82char *
83subst_expand (char *o, char *text, char *subst, char *replace,
84 unsigned int slen, unsigned int rlen, int by_word)
85{
86 char *t = text;
87 char *p;
88
89 if (slen == 0 && !by_word)
90 {
91 /* The first occurrence of "" in any string is its end. */
92 o = variable_buffer_output (o, t, strlen (t));
93 if (rlen > 0)
94 o = variable_buffer_output (o, replace, rlen);
95 return o;
96 }
97
98 do
99 {
100 if (by_word && slen == 0)
101 /* When matching by words, the empty string should match
102 the end of each word, rather than the end of the whole text. */
103 p = end_of_token (next_token (t));
104 else
105 {
106 p = strstr (t, subst);
107 if (p == 0)
108 {
109 /* No more matches. Output everything left on the end. */
110 o = variable_buffer_output (o, t, strlen (t));
111 return o;
112 }
113 }
114
115 /* Output everything before this occurrence of the string to replace. */
116 if (p > t)
117 o = variable_buffer_output (o, t, p - t);
118
119 /* If we're substituting only by fully matched words,
120 or only at the ends of words, check that this case qualifies. */
121 if (by_word
122 && ((p > text && !isblank ((unsigned char)p[-1]))
123 || (p[slen] != '\0' && !isblank ((unsigned char)p[slen]))))
124 /* Struck out. Output the rest of the string that is
125 no longer to be replaced. */
126 o = variable_buffer_output (o, subst, slen);
127 else if (rlen > 0)
128 /* Output the replacement string. */
129 o = variable_buffer_output (o, replace, rlen);
130
131 /* Advance T past the string to be replaced. */
132 {
133 char *nt = p + slen;
134 t = nt;
135 }
136 } while (*t != '\0');
137
138 return o;
139}
140
141
142
143/* Store into VARIABLE_BUFFER at O the result of scanning TEXT
144 and replacing strings matching PATTERN with REPLACE.
145 If PATTERN_PERCENT is not nil, PATTERN has already been
146 run through find_percent, and PATTERN_PERCENT is the result.
147 If REPLACE_PERCENT is not nil, REPLACE has already been
148 run through find_percent, and REPLACE_PERCENT is the result.
149 Note that we expect PATTERN_PERCENT and REPLACE_PERCENT to point to the
150 character _AFTER_ the %, not to the % itself.
151*/
152
153char *
154patsubst_expand (char *o, char *text, char *pattern, char *replace,
155 char *pattern_percent, char *replace_percent)
156{
157 unsigned int pattern_prepercent_len, pattern_postpercent_len;
158 unsigned int replace_prepercent_len, replace_postpercent_len;
159 char *t;
160 unsigned int len;
161 int doneany = 0;
162
163 /* We call find_percent on REPLACE before checking PATTERN so that REPLACE
164 will be collapsed before we call subst_expand if PATTERN has no %. */
165 if (!replace_percent)
166 {
167 replace_percent = find_percent (replace);
168 if (replace_percent)
169 ++replace_percent;
170 }
171
172 /* Record the length of REPLACE before and after the % so we don't have to
173 compute these lengths more than once. */
174 if (replace_percent)
175 {
176 replace_prepercent_len = replace_percent - replace - 1;
177 replace_postpercent_len = strlen (replace_percent);
178 }
179 else
180 {
181 replace_prepercent_len = strlen (replace);
182 replace_postpercent_len = 0;
183 }
184
185 if (!pattern_percent)
186 {
187 pattern_percent = find_percent (pattern);
188 if (pattern_percent)
189 ++pattern_percent;
190 }
191 if (!pattern_percent)
192 /* With no % in the pattern, this is just a simple substitution. */
193 return subst_expand (o, text, pattern, replace,
194 strlen (pattern), strlen (replace), 1);
195
196 /* Record the length of PATTERN before and after the %
197 so we don't have to compute it more than once. */
198 pattern_prepercent_len = pattern_percent - pattern - 1;
199 pattern_postpercent_len = strlen (pattern_percent);
200
201 while ((t = find_next_token (&text, &len)) != 0)
202 {
203 int fail = 0;
204
205 /* Is it big enough to match? */
206 if (len < pattern_prepercent_len + pattern_postpercent_len)
207 fail = 1;
208
209 /* Does the prefix match? */
210 if (!fail && pattern_prepercent_len > 0
211 && (*t != *pattern
212 || t[pattern_prepercent_len - 1] != pattern_percent[-2]
213 || !strneq (t + 1, pattern + 1, pattern_prepercent_len - 1)))
214 fail = 1;
215
216 /* Does the suffix match? */
217 if (!fail && pattern_postpercent_len > 0
218 && (t[len - 1] != pattern_percent[pattern_postpercent_len - 1]
219 || t[len - pattern_postpercent_len] != *pattern_percent
220 || !strneq (&t[len - pattern_postpercent_len],
221 pattern_percent, pattern_postpercent_len - 1)))
222 fail = 1;
223
224 if (fail)
225 /* It didn't match. Output the string. */
226 o = variable_buffer_output (o, t, len);
227 else
228 {
229 /* It matched. Output the replacement. */
230
231 /* Output the part of the replacement before the %. */
232 o = variable_buffer_output (o, replace, replace_prepercent_len);
233
234 if (replace_percent != 0)
235 {
236 /* Output the part of the matched string that
237 matched the % in the pattern. */
238 o = variable_buffer_output (o, t + pattern_prepercent_len,
239 len - (pattern_prepercent_len
240 + pattern_postpercent_len));
241 /* Output the part of the replacement after the %. */
242 o = variable_buffer_output (o, replace_percent,
243 replace_postpercent_len);
244 }
245 }
246
247 /* Output a space, but not if the replacement is "". */
248 if (fail || replace_prepercent_len > 0
249 || (replace_percent != 0 && len + replace_postpercent_len > 0))
250 {
251 o = variable_buffer_output (o, " ", 1);
252 doneany = 1;
253 }
254 }
255 if (doneany)
256 /* Kill the last space. */
257 --o;
258
259 return o;
260}
261
262
263#ifdef CONFIG_WITH_OPTIMIZATION_HACKS
264/* The maximum length of a function, once reached there is
265 it can't be function and we can skip the hash lookup drop out. */
266
267#define MAX_FUNCTION_LENGTH 10 /* bird */
268
269/* Look up a function by name. */
270__inline
271#endif /* CONFIG_WITH_OPTIMIZATION_HACKS */
272static const struct function_table_entry *
273lookup_function (const char *s)
274{
275 const char *e = s;
276#ifdef CONFIG_WITH_OPTIMIZATION_HACKS
277 int left = MAX_FUNCTION_LENGTH;
278 int ch;
279 while (((ch = *e) >= 'a' && ch <='z') || ch == '-')
280 {
281 if (!left--)
282 return 0;
283 e++;
284 }
285#else
286 while (*e && ( (*e >= 'a' && *e <= 'z') || *e == '-'))
287 e++;
288#endif
289 if (*e == '\0' || isblank ((unsigned char) *e))
290 {
291 struct function_table_entry function_table_entry_key;
292 function_table_entry_key.name = s;
293 function_table_entry_key.len = e - s;
294
295 return hash_find_item (&function_table, &function_table_entry_key);
296 }
297 return 0;
298}
299
300
301
302/* Return 1 if PATTERN matches STR, 0 if not. */
303
304int
305pattern_matches (char *pattern, char *percent, char *str)
306{
307 unsigned int sfxlen, strlength;
308
309 if (percent == 0)
310 {
311 unsigned int len = strlen (pattern) + 1;
312 char *new_chars = (char *) alloca (len);
313 bcopy (pattern, new_chars, len);
314 pattern = new_chars;
315 percent = find_percent (pattern);
316 if (percent == 0)
317 return streq (pattern, str);
318 }
319
320 sfxlen = strlen (percent + 1);
321 strlength = strlen (str);
322
323 if (strlength < (percent - pattern) + sfxlen
324 || !strneq (pattern, str, percent - pattern))
325 return 0;
326
327 return !strcmp (percent + 1, str + (strlength - sfxlen));
328}
329
330
331
332/* Find the next comma or ENDPAREN (counting nested STARTPAREN and
333 ENDPARENtheses), starting at PTR before END. Return a pointer to
334 next character.
335
336 If no next argument is found, return NULL.
337*/
338
339static char *
340find_next_argument (char startparen, char endparen,
341 const char *ptr, const char *end)
342{
343 int count = 0;
344
345 for (; ptr < end; ++ptr)
346 if (*ptr == startparen)
347 ++count;
348
349 else if (*ptr == endparen)
350 {
351 --count;
352 if (count < 0)
353 return NULL;
354 }
355
356 else if (*ptr == ',' && !count)
357 return (char *)ptr;
358
359 /* We didn't find anything. */
360 return NULL;
361}
362
363
364
365/* Glob-expand LINE. The returned pointer is
366 only good until the next call to string_glob. */
367
368static char *
369string_glob (char *line)
370{
371 static char *result = 0;
372 static unsigned int length;
373 register struct nameseq *chain;
374 register unsigned int idx;
375
376 chain = multi_glob (parse_file_seq
377 (&line, '\0', sizeof (struct nameseq),
378 /* We do not want parse_file_seq to strip `./'s.
379 That would break examples like:
380 $(patsubst ./%.c,obj/%.o,$(wildcard ./?*.c)). */
381 0),
382 sizeof (struct nameseq));
383
384 if (result == 0)
385 {
386 length = 100;
387 result = (char *) xmalloc (100);
388 }
389
390 idx = 0;
391 while (chain != 0)
392 {
393 register char *name = chain->name;
394 unsigned int len = strlen (name);
395
396 struct nameseq *next = chain->next;
397 free ((char *) chain);
398 chain = next;
399
400 /* multi_glob will pass names without globbing metacharacters
401 through as is, but we want only files that actually exist. */
402 if (file_exists_p (name))
403 {
404 if (idx + len + 1 > length)
405 {
406 length += (len + 1) * 2;
407 result = (char *) xrealloc (result, length);
408 }
409 bcopy (name, &result[idx], len);
410 idx += len;
411 result[idx++] = ' ';
412 }
413
414 free (name);
415 }
416
417 /* Kill the last space and terminate the string. */
418 if (idx == 0)
419 result[0] = '\0';
420 else
421 result[idx - 1] = '\0';
422
423 return result;
424}
425
426
427/*
428 Builtin functions
429 */
430
431static char *
432func_patsubst (char *o, char **argv, const char *funcname UNUSED)
433{
434 o = patsubst_expand (o, argv[2], argv[0], argv[1], (char *) 0, (char *) 0);
435 return o;
436}
437
438
439static char *
440func_join (char *o, char **argv, const char *funcname UNUSED)
441{
442 int doneany = 0;
443
444 /* Write each word of the first argument directly followed
445 by the corresponding word of the second argument.
446 If the two arguments have a different number of words,
447 the excess words are just output separated by blanks. */
448 register char *tp;
449 register char *pp;
450 char *list1_iterator = argv[0];
451 char *list2_iterator = argv[1];
452 do
453 {
454 unsigned int len1, len2;
455
456 tp = find_next_token (&list1_iterator, &len1);
457 if (tp != 0)
458 o = variable_buffer_output (o, tp, len1);
459
460 pp = find_next_token (&list2_iterator, &len2);
461 if (pp != 0)
462 o = variable_buffer_output (o, pp, len2);
463
464 if (tp != 0 || pp != 0)
465 {
466 o = variable_buffer_output (o, " ", 1);
467 doneany = 1;
468 }
469 }
470 while (tp != 0 || pp != 0);
471 if (doneany)
472 /* Kill the last blank. */
473 --o;
474
475 return o;
476}
477
478
479static char *
480func_origin (char *o, char **argv, const char *funcname UNUSED)
481{
482 /* Expand the argument. */
483 register struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
484 if (v == 0)
485 o = variable_buffer_output (o, "undefined", 9);
486 else
487 switch (v->origin)
488 {
489 default:
490 case o_invalid:
491 abort ();
492 break;
493 case o_default:
494 o = variable_buffer_output (o, "default", 7);
495 break;
496 case o_env:
497 o = variable_buffer_output (o, "environment", 11);
498 break;
499 case o_file:
500 o = variable_buffer_output (o, "file", 4);
501 break;
502 case o_env_override:
503 o = variable_buffer_output (o, "environment override", 20);
504 break;
505 case o_command:
506 o = variable_buffer_output (o, "command line", 12);
507 break;
508 case o_override:
509 o = variable_buffer_output (o, "override", 8);
510 break;
511 case o_automatic:
512 o = variable_buffer_output (o, "automatic", 9);
513 break;
514 }
515
516 return o;
517}
518
519static char *
520func_flavor (char *o, char **argv, const char *funcname UNUSED)
521{
522 register struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
523
524 if (v == 0)
525 o = variable_buffer_output (o, "undefined", 9);
526 else
527 if (v->recursive)
528 o = variable_buffer_output (o, "recursive", 9);
529 else
530 o = variable_buffer_output (o, "simple", 6);
531
532 return o;
533}
534
535#ifdef VMS
536# define IS_PATHSEP(c) ((c) == ']')
537#else
538# ifdef HAVE_DOS_PATHS
539# define IS_PATHSEP(c) ((c) == '/' || (c) == '\\')
540# else
541# define IS_PATHSEP(c) ((c) == '/')
542# endif
543#endif
544
545
546static char *
547func_notdir_suffix (char *o, char **argv, const char *funcname)
548{
549 /* Expand the argument. */
550 char *list_iterator = argv[0];
551 char *p2 =0;
552 int doneany =0;
553 unsigned int len=0;
554
555 int is_suffix = streq (funcname, "suffix");
556 int is_notdir = !is_suffix;
557 while ((p2 = find_next_token (&list_iterator, &len)) != 0)
558 {
559 char *p = p2 + len;
560
561
562 while (p >= p2 && (!is_suffix || *p != '.'))
563 {
564 if (IS_PATHSEP (*p))
565 break;
566 --p;
567 }
568
569 if (p >= p2)
570 {
571 if (is_notdir)
572 ++p;
573 else if (*p != '.')
574 continue;
575 o = variable_buffer_output (o, p, len - (p - p2));
576 }
577#ifdef HAVE_DOS_PATHS
578 /* Handle the case of "d:foo/bar". */
579 else if (streq (funcname, "notdir") && p2[0] && p2[1] == ':')
580 {
581 p = p2 + 2;
582 o = variable_buffer_output (o, p, len - (p - p2));
583 }
584#endif
585 else if (is_notdir)
586 o = variable_buffer_output (o, p2, len);
587
588 if (is_notdir || p >= p2)
589 {
590 o = variable_buffer_output (o, " ", 1);
591 doneany = 1;
592 }
593 }
594 if (doneany)
595 /* Kill last space. */
596 --o;
597
598
599 return o;
600
601}
602
603
604static char *
605func_basename_dir (char *o, char **argv, const char *funcname)
606{
607 /* Expand the argument. */
608 char *p3 = argv[0];
609 char *p2=0;
610 int doneany=0;
611 unsigned int len=0;
612 char *p=0;
613 int is_basename= streq (funcname, "basename");
614 int is_dir= !is_basename;
615
616 while ((p2 = find_next_token (&p3, &len)) != 0)
617 {
618 p = p2 + len;
619 while (p >= p2 && (!is_basename || *p != '.'))
620 {
621 if (IS_PATHSEP (*p))
622 break;
623 --p;
624 }
625
626 if (p >= p2 && (is_dir))
627 o = variable_buffer_output (o, p2, ++p - p2);
628 else if (p >= p2 && (*p == '.'))
629 o = variable_buffer_output (o, p2, p - p2);
630#ifdef HAVE_DOS_PATHS
631 /* Handle the "d:foobar" case */
632 else if (p2[0] && p2[1] == ':' && is_dir)
633 o = variable_buffer_output (o, p2, 2);
634#endif
635 else if (is_dir)
636#ifdef VMS
637 o = variable_buffer_output (o, "[]", 2);
638#else
639#ifndef _AMIGA
640 o = variable_buffer_output (o, "./", 2);
641#else
642 ; /* Just a nop... */
643#endif /* AMIGA */
644#endif /* !VMS */
645 else
646 /* The entire name is the basename. */
647 o = variable_buffer_output (o, p2, len);
648
649 o = variable_buffer_output (o, " ", 1);
650 doneany = 1;
651 }
652 if (doneany)
653 /* Kill last space. */
654 --o;
655
656
657 return o;
658}
659
660static char *
661func_addsuffix_addprefix (char *o, char **argv, const char *funcname)
662{
663 int fixlen = strlen (argv[0]);
664 char *list_iterator = argv[1];
665 int is_addprefix = streq (funcname, "addprefix");
666 int is_addsuffix = !is_addprefix;
667
668 int doneany = 0;
669 char *p;
670 unsigned int len;
671
672 while ((p = find_next_token (&list_iterator, &len)) != 0)
673 {
674 if (is_addprefix)
675 o = variable_buffer_output (o, argv[0], fixlen);
676 o = variable_buffer_output (o, p, len);
677 if (is_addsuffix)
678 o = variable_buffer_output (o, argv[0], fixlen);
679 o = variable_buffer_output (o, " ", 1);
680 doneany = 1;
681 }
682
683 if (doneany)
684 /* Kill last space. */
685 --o;
686
687 return o;
688}
689
690static char *
691func_subst (char *o, char **argv, const char *funcname UNUSED)
692{
693 o = subst_expand (o, argv[2], argv[0], argv[1], strlen (argv[0]),
694 strlen (argv[1]), 0);
695
696 return o;
697}
698
699
700static char *
701func_firstword (char *o, char **argv, const char *funcname UNUSED)
702{
703 unsigned int i;
704 char *words = argv[0]; /* Use a temp variable for find_next_token */
705 char *p = find_next_token (&words, &i);
706
707 if (p != 0)
708 o = variable_buffer_output (o, p, i);
709
710 return o;
711}
712
713static char *
714func_lastword (char *o, char **argv, const char *funcname UNUSED)
715{
716 unsigned int i;
717 char *words = argv[0]; /* Use a temp variable for find_next_token */
718 char *p = 0;
719 char *t;
720
721 while ((t = find_next_token (&words, &i)))
722 p = t;
723
724 if (p != 0)
725 o = variable_buffer_output (o, p, i);
726
727 return o;
728}
729
730static char *
731func_words (char *o, char **argv, const char *funcname UNUSED)
732{
733 int i = 0;
734 char *word_iterator = argv[0];
735 char buf[20];
736
737 while (find_next_token (&word_iterator, (unsigned int *) 0) != 0)
738 ++i;
739
740 sprintf (buf, "%d", i);
741 o = variable_buffer_output (o, buf, strlen (buf));
742
743
744 return o;
745}
746
747/* Set begpp to point to the first non-whitespace character of the string,
748 * and endpp to point to the last non-whitespace character of the string.
749 * If the string is empty or contains nothing but whitespace, endpp will be
750 * begpp-1.
751 */
752char *
753strip_whitespace (const char **begpp, const char **endpp)
754{
755 while (*begpp <= *endpp && isspace ((unsigned char)**begpp))
756 (*begpp) ++;
757 while (*endpp >= *begpp && isspace ((unsigned char)**endpp))
758 (*endpp) --;
759 return (char *)*begpp;
760}
761
762static void
763check_numeric (const char *s, const char *message)
764{
765 const char *end = s + strlen (s) - 1;
766 const char *beg = s;
767 strip_whitespace (&s, &end);
768
769 for (; s <= end; ++s)
770 if (!ISDIGIT (*s)) /* ISDIGIT only evals its arg once: see make.h. */
771 break;
772
773 if (s <= end || end - beg < 0)
774 fatal (*expanding_var, "%s: '%s'", message, beg);
775}
776
777
778
779static char *
780func_word (char *o, char **argv, const char *funcname UNUSED)
781{
782 char *end_p=0;
783 int i=0;
784 char *p=0;
785
786 /* Check the first argument. */
787 check_numeric (argv[0], _("non-numeric first argument to `word' function"));
788 i = atoi (argv[0]);
789
790 if (i == 0)
791 fatal (*expanding_var,
792 _("first argument to `word' function must be greater than 0"));
793
794
795 end_p = argv[1];
796 while ((p = find_next_token (&end_p, 0)) != 0)
797 if (--i == 0)
798 break;
799
800 if (i == 0)
801 o = variable_buffer_output (o, p, end_p - p);
802
803 return o;
804}
805
806static char *
807func_wordlist (char *o, char **argv, const char *funcname UNUSED)
808{
809 int start, count;
810
811 /* Check the arguments. */
812 check_numeric (argv[0],
813 _("non-numeric first argument to `wordlist' function"));
814 check_numeric (argv[1],
815 _("non-numeric second argument to `wordlist' function"));
816
817 start = atoi (argv[0]);
818 if (start < 1)
819 fatal (*expanding_var,
820 "invalid first argument to `wordlist' function: `%d'", start);
821
822 count = atoi (argv[1]) - start + 1;
823
824 if (count > 0)
825 {
826 char *p;
827 char *end_p = argv[2];
828
829 /* Find the beginning of the "start"th word. */
830 while (((p = find_next_token (&end_p, 0)) != 0) && --start)
831 ;
832
833 if (p)
834 {
835 /* Find the end of the "count"th word from start. */
836 while (--count && (find_next_token (&end_p, 0) != 0))
837 ;
838
839 /* Return the stuff in the middle. */
840 o = variable_buffer_output (o, p, end_p - p);
841 }
842 }
843
844 return o;
845}
846
847static char*
848func_findstring (char *o, char **argv, const char *funcname UNUSED)
849{
850 /* Find the first occurrence of the first string in the second. */
851 if (strstr (argv[1], argv[0]) != 0)
852 o = variable_buffer_output (o, argv[0], strlen (argv[0]));
853
854 return o;
855}
856
857static char *
858func_foreach (char *o, char **argv, const char *funcname UNUSED)
859{
860 /* expand only the first two. */
861 char *varname = expand_argument (argv[0], NULL);
862 char *list = expand_argument (argv[1], NULL);
863 char *body = argv[2];
864
865 int doneany = 0;
866 char *list_iterator = list;
867 char *p;
868 unsigned int len;
869 register struct variable *var;
870
871 push_new_variable_scope ();
872 var = define_variable (varname, strlen (varname), "", o_automatic, 0);
873
874 /* loop through LIST, put the value in VAR and expand BODY */
875 while ((p = find_next_token (&list_iterator, &len)) != 0)
876 {
877 char *result = 0;
878
879 {
880 char save = p[len];
881
882 p[len] = '\0';
883 free (var->value);
884 var->value = (char *) xstrdup ((char*) p);
885 p[len] = save;
886 }
887
888 result = allocated_variable_expand (body);
889
890 o = variable_buffer_output (o, result, strlen (result));
891 o = variable_buffer_output (o, " ", 1);
892 doneany = 1;
893 free (result);
894 }
895
896 if (doneany)
897 /* Kill the last space. */
898 --o;
899
900 pop_variable_scope ();
901 free (varname);
902 free (list);
903
904 return o;
905}
906
907struct a_word
908{
909 struct a_word *next;
910 struct a_word *chain;
911 char *str;
912 int length;
913 int matched;
914};
915
916static unsigned long
917a_word_hash_1 (const void *key)
918{
919 return_STRING_HASH_1 (((struct a_word const *) key)->str);
920}
921
922static unsigned long
923a_word_hash_2 (const void *key)
924{
925 return_STRING_HASH_2 (((struct a_word const *) key)->str);
926}
927
928static int
929a_word_hash_cmp (const void *x, const void *y)
930{
931 int result = ((struct a_word const *) x)->length - ((struct a_word const *) y)->length;
932 if (result)
933 return result;
934 return_STRING_COMPARE (((struct a_word const *) x)->str,
935 ((struct a_word const *) y)->str);
936}
937
938struct a_pattern
939{
940 struct a_pattern *next;
941 char *str;
942 char *percent;
943 int length;
944 int save_c;
945};
946
947static char *
948func_filter_filterout (char *o, char **argv, const char *funcname)
949{
950 struct a_word *wordhead;
951 struct a_word **wordtail;
952 struct a_word *wp;
953 struct a_pattern *pathead;
954 struct a_pattern **pattail;
955 struct a_pattern *pp;
956
957 struct hash_table a_word_table;
958 int is_filter = streq (funcname, "filter");
959 char *pat_iterator = argv[0];
960 char *word_iterator = argv[1];
961 int literals = 0;
962 int words = 0;
963 int hashing = 0;
964 char *p;
965 unsigned int len;
966
967 /* Chop ARGV[0] up into patterns to match against the words. */
968
969 pattail = &pathead;
970 while ((p = find_next_token (&pat_iterator, &len)) != 0)
971 {
972 struct a_pattern *pat = (struct a_pattern *) alloca (sizeof (struct a_pattern));
973
974 *pattail = pat;
975 pattail = &pat->next;
976
977 if (*pat_iterator != '\0')
978 ++pat_iterator;
979
980 pat->str = p;
981 pat->length = len;
982 pat->save_c = p[len];
983 p[len] = '\0';
984 pat->percent = find_percent (p);
985 if (pat->percent == 0)
986 literals++;
987 }
988 *pattail = 0;
989
990 /* Chop ARGV[1] up into words to match against the patterns. */
991
992 wordtail = &wordhead;
993 while ((p = find_next_token (&word_iterator, &len)) != 0)
994 {
995 struct a_word *word = (struct a_word *) alloca (sizeof (struct a_word));
996
997 *wordtail = word;
998 wordtail = &word->next;
999
1000 if (*word_iterator != '\0')
1001 ++word_iterator;
1002
1003 p[len] = '\0';
1004 word->str = p;
1005 word->length = len;
1006 word->matched = 0;
1007 word->chain = 0;
1008 words++;
1009 }
1010 *wordtail = 0;
1011
1012 /* Only use a hash table if arg list lengths justifies the cost. */
1013 hashing = (literals >= 2 && (literals * words) >= 10);
1014 if (hashing)
1015 {
1016 hash_init (&a_word_table, words, a_word_hash_1, a_word_hash_2, a_word_hash_cmp);
1017 for (wp = wordhead; wp != 0; wp = wp->next)
1018 {
1019 struct a_word *owp = hash_insert (&a_word_table, wp);
1020 if (owp)
1021 wp->chain = owp;
1022 }
1023 }
1024
1025 if (words)
1026 {
1027 int doneany = 0;
1028
1029 /* Run each pattern through the words, killing words. */
1030 for (pp = pathead; pp != 0; pp = pp->next)
1031 {
1032 if (pp->percent)
1033 for (wp = wordhead; wp != 0; wp = wp->next)
1034 wp->matched |= pattern_matches (pp->str, pp->percent, wp->str);
1035 else if (hashing)
1036 {
1037 struct a_word a_word_key;
1038 a_word_key.str = pp->str;
1039 a_word_key.length = pp->length;
1040 wp = (struct a_word *) hash_find_item (&a_word_table, &a_word_key);
1041 while (wp)
1042 {
1043 wp->matched |= 1;
1044 wp = wp->chain;
1045 }
1046 }
1047 else
1048 for (wp = wordhead; wp != 0; wp = wp->next)
1049 wp->matched |= (wp->length == pp->length
1050 && strneq (pp->str, wp->str, wp->length));
1051 }
1052
1053 /* Output the words that matched (or didn't, for filter-out). */
1054 for (wp = wordhead; wp != 0; wp = wp->next)
1055 if (is_filter ? wp->matched : !wp->matched)
1056 {
1057 o = variable_buffer_output (o, wp->str, strlen (wp->str));
1058 o = variable_buffer_output (o, " ", 1);
1059 doneany = 1;
1060 }
1061
1062 if (doneany)
1063 /* Kill the last space. */
1064 --o;
1065 }
1066
1067 for (pp = pathead; pp != 0; pp = pp->next)
1068 pp->str[pp->length] = pp->save_c;
1069
1070 if (hashing)
1071 hash_free (&a_word_table, 0);
1072
1073 return o;
1074}
1075
1076
1077static char *
1078func_strip (char *o, char **argv, const char *funcname UNUSED)
1079{
1080 char *p = argv[0];
1081 int doneany =0;
1082
1083 while (*p != '\0')
1084 {
1085 int i=0;
1086 char *word_start=0;
1087
1088 while (isspace ((unsigned char)*p))
1089 ++p;
1090 word_start = p;
1091 for (i=0; *p != '\0' && !isspace ((unsigned char)*p); ++p, ++i)
1092 {}
1093 if (!i)
1094 break;
1095 o = variable_buffer_output (o, word_start, i);
1096 o = variable_buffer_output (o, " ", 1);
1097 doneany = 1;
1098 }
1099
1100 if (doneany)
1101 /* Kill the last space. */
1102 --o;
1103 return o;
1104}
1105
1106/*
1107 Print a warning or fatal message.
1108*/
1109static char *
1110func_error (char *o, char **argv, const char *funcname)
1111{
1112 char **argvp;
1113 char *msg, *p;
1114 int len;
1115
1116 /* The arguments will be broken on commas. Rather than create yet
1117 another special case where function arguments aren't broken up,
1118 just create a format string that puts them back together. */
1119 for (len=0, argvp=argv; *argvp != 0; ++argvp)
1120 len += strlen (*argvp) + 2;
1121
1122 p = msg = (char *) alloca (len + 1);
1123
1124 for (argvp=argv; argvp[1] != 0; ++argvp)
1125 {
1126 strcpy (p, *argvp);
1127 p += strlen (*argvp);
1128 *(p++) = ',';
1129 *(p++) = ' ';
1130 }
1131 strcpy (p, *argvp);
1132
1133 switch (*funcname) {
1134 case 'e':
1135 fatal (reading_file, "%s", msg);
1136
1137 case 'w':
1138 error (reading_file, "%s", msg);
1139 break;
1140
1141 case 'i':
1142 printf ("%s\n", msg);
1143 fflush(stdout);
1144 break;
1145
1146 default:
1147 fatal (*expanding_var, "Internal error: func_error: '%s'", funcname);
1148 }
1149
1150 /* The warning function expands to the empty string. */
1151 return o;
1152}
1153
1154
1155/*
1156 chop argv[0] into words, and sort them.
1157 */
1158static char *
1159func_sort (char *o, char **argv, const char *funcname UNUSED)
1160{
1161 char **words = 0;
1162 int nwords = 0;
1163 register int wordi = 0;
1164
1165 /* Chop ARGV[0] into words and put them in WORDS. */
1166 char *t = argv[0];
1167 char *p;
1168 unsigned int len;
1169 int i;
1170
1171 while ((p = find_next_token (&t, &len)) != 0)
1172 {
1173 if (wordi >= nwords - 1)
1174 {
1175 nwords = (2 * nwords) + 5;
1176 words = (char **) xrealloc ((char *) words,
1177 nwords * sizeof (char *));
1178 }
1179 words[wordi++] = savestring (p, len);
1180 }
1181
1182 if (!wordi)
1183 return o;
1184
1185 /* Now sort the list of words. */
1186 qsort ((char *) words, wordi, sizeof (char *), alpha_compare);
1187
1188 /* Now write the sorted list. */
1189 for (i = 0; i < wordi; ++i)
1190 {
1191 len = strlen (words[i]);
1192 if (i == wordi - 1 || strlen (words[i + 1]) != len
1193 || strcmp (words[i], words[i + 1]))
1194 {
1195 o = variable_buffer_output (o, words[i], len);
1196 o = variable_buffer_output (o, " ", 1);
1197 }
1198 free (words[i]);
1199 }
1200 /* Kill the last space. */
1201 --o;
1202
1203 free (words);
1204
1205 return o;
1206}
1207
1208/*
1209 $(if condition,true-part[,false-part])
1210
1211 CONDITION is false iff it evaluates to an empty string. White
1212 space before and after condition are stripped before evaluation.
1213
1214 If CONDITION is true, then TRUE-PART is evaluated, otherwise FALSE-PART is
1215 evaluated (if it exists). Because only one of the two PARTs is evaluated,
1216 you can use $(if ...) to create side-effects (with $(shell ...), for
1217 example).
1218*/
1219
1220static char *
1221func_if (char *o, char **argv, const char *funcname UNUSED)
1222{
1223 const char *begp = argv[0];
1224 const char *endp = begp + strlen (argv[0]) - 1;
1225 int result = 0;
1226
1227 /* Find the result of the condition: if we have a value, and it's not
1228 empty, the condition is true. If we don't have a value, or it's the
1229 empty string, then it's false. */
1230
1231 strip_whitespace (&begp, &endp);
1232
1233 if (begp <= endp)
1234 {
1235 char *expansion = expand_argument (begp, endp+1);
1236
1237 result = strlen (expansion);
1238 free (expansion);
1239 }
1240
1241 /* If the result is true (1) we want to eval the first argument, and if
1242 it's false (0) we want to eval the second. If the argument doesn't
1243 exist we do nothing, otherwise expand it and add to the buffer. */
1244
1245 argv += 1 + !result;
1246
1247 if (argv[0])
1248 {
1249 char *expansion;
1250
1251 expansion = expand_argument (argv[0], NULL);
1252
1253 o = variable_buffer_output (o, expansion, strlen (expansion));
1254
1255 free (expansion);
1256 }
1257
1258 return o;
1259}
1260
1261/*
1262 $(or condition1[,condition2[,condition3[...]]])
1263
1264 A CONDITION is false iff it evaluates to an empty string. White
1265 space before and after CONDITION are stripped before evaluation.
1266
1267 CONDITION1 is evaluated. If it's true, then this is the result of
1268 expansion. If it's false, CONDITION2 is evaluated, and so on. If none of
1269 the conditions are true, the expansion is the empty string.
1270
1271 Once a CONDITION is true no further conditions are evaluated
1272 (short-circuiting).
1273*/
1274
1275static char *
1276func_or (char *o, char **argv, const char *funcname UNUSED)
1277{
1278 for ( ; *argv ; ++argv)
1279 {
1280 const char *begp = *argv;
1281 const char *endp = begp + strlen (*argv) - 1;
1282 char *expansion;
1283 int result = 0;
1284
1285 /* Find the result of the condition: if it's false keep going. */
1286
1287 strip_whitespace (&begp, &endp);
1288
1289 if (begp > endp)
1290 continue;
1291
1292 expansion = expand_argument (begp, endp+1);
1293 result = strlen (expansion);
1294
1295 /* If the result is false keep going. */
1296 if (!result)
1297 {
1298 free (expansion);
1299 continue;
1300 }
1301
1302 /* It's true! Keep this result and return. */
1303 o = variable_buffer_output (o, expansion, result);
1304 free (expansion);
1305 break;
1306 }
1307
1308 return o;
1309}
1310
1311/*
1312 $(and condition1[,condition2[,condition3[...]]])
1313
1314 A CONDITION is false iff it evaluates to an empty string. White
1315 space before and after CONDITION are stripped before evaluation.
1316
1317 CONDITION1 is evaluated. If it's false, then this is the result of
1318 expansion. If it's true, CONDITION2 is evaluated, and so on. If all of
1319 the conditions are true, the expansion is the result of the last condition.
1320
1321 Once a CONDITION is false no further conditions are evaluated
1322 (short-circuiting).
1323*/
1324
1325static char *
1326func_and (char *o, char **argv, const char *funcname UNUSED)
1327{
1328 char *expansion;
1329 int result;
1330
1331 while (1)
1332 {
1333 const char *begp = *argv;
1334 const char *endp = begp + strlen (*argv) - 1;
1335
1336 /* An empty condition is always false. */
1337 strip_whitespace (&begp, &endp);
1338 if (begp > endp)
1339 return o;
1340
1341 expansion = expand_argument (begp, endp+1);
1342 result = strlen (expansion);
1343
1344 /* If the result is false, stop here: we're done. */
1345 if (!result)
1346 break;
1347
1348 /* Otherwise the result is true. If this is the last one, keep this
1349 result and quit. Otherwise go on to the next one! */
1350
1351 if (*(++argv))
1352 free (expansion);
1353 else
1354 {
1355 o = variable_buffer_output (o, expansion, result);
1356 break;
1357 }
1358 }
1359
1360 free (expansion);
1361
1362 return o;
1363}
1364
1365static char *
1366func_wildcard (char *o, char **argv, const char *funcname UNUSED)
1367{
1368
1369#ifdef _AMIGA
1370 o = wildcard_expansion (argv[0], o);
1371#else
1372 char *p = string_glob (argv[0]);
1373 o = variable_buffer_output (o, p, strlen (p));
1374#endif
1375 return o;
1376}
1377
1378/*
1379 $(eval <makefile string>)
1380
1381 Always resolves to the empty string.
1382
1383 Treat the arguments as a segment of makefile, and parse them.
1384*/
1385
1386static char *
1387func_eval (char *o, char **argv, const char *funcname UNUSED)
1388{
1389 char *buf;
1390 unsigned int len;
1391
1392 /* Eval the buffer. Pop the current variable buffer setting so that the
1393 eval'd code can use its own without conflicting. */
1394
1395 install_variable_buffer (&buf, &len);
1396
1397 eval_buffer (argv[0]);
1398
1399 restore_variable_buffer (buf, len);
1400
1401 return o;
1402}
1403
1404
1405static char *
1406func_value (char *o, char **argv, const char *funcname UNUSED)
1407{
1408 /* Look up the variable. */
1409 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
1410
1411 /* Copy its value into the output buffer without expanding it. */
1412 if (v)
1413 o = variable_buffer_output (o, v->value, strlen(v->value));
1414
1415 return o;
1416}
1417
1418/*
1419 \r is replaced on UNIX as well. Is this desirable?
1420 */
1421static void
1422fold_newlines (char *buffer, unsigned int *length)
1423{
1424 char *dst = buffer;
1425 char *src = buffer;
1426 char *last_nonnl = buffer -1;
1427 src[*length] = 0;
1428 for (; *src != '\0'; ++src)
1429 {
1430 if (src[0] == '\r' && src[1] == '\n')
1431 continue;
1432 if (*src == '\n')
1433 {
1434 *dst++ = ' ';
1435 }
1436 else
1437 {
1438 last_nonnl = dst;
1439 *dst++ = *src;
1440 }
1441 }
1442 *(++last_nonnl) = '\0';
1443 *length = last_nonnl - buffer;
1444}
1445
1446
1447
1448int shell_function_pid = 0, shell_function_completed;
1449
1450
1451#ifdef WINDOWS32
1452/*untested*/
1453
1454#include <windows.h>
1455#include <io.h>
1456#include "sub_proc.h"
1457
1458
1459void
1460windows32_openpipe (int *pipedes, int *pid_p, char **command_argv, char **envp)
1461{
1462 SECURITY_ATTRIBUTES saAttr;
1463 HANDLE hIn;
1464 HANDLE hErr;
1465 HANDLE hChildOutRd;
1466 HANDLE hChildOutWr;
1467 HANDLE hProcess;
1468
1469
1470 saAttr.nLength = sizeof (SECURITY_ATTRIBUTES);
1471 saAttr.bInheritHandle = TRUE;
1472 saAttr.lpSecurityDescriptor = NULL;
1473
1474 if (DuplicateHandle (GetCurrentProcess(),
1475 GetStdHandle(STD_INPUT_HANDLE),
1476 GetCurrentProcess(),
1477 &hIn,
1478 0,
1479 TRUE,
1480 DUPLICATE_SAME_ACCESS) == FALSE) {
1481 fatal (NILF, _("create_child_process: DuplicateHandle(In) failed (e=%ld)\n"),
1482 GetLastError());
1483
1484 }
1485 if (DuplicateHandle(GetCurrentProcess(),
1486 GetStdHandle(STD_ERROR_HANDLE),
1487 GetCurrentProcess(),
1488 &hErr,
1489 0,
1490 TRUE,
1491 DUPLICATE_SAME_ACCESS) == FALSE) {
1492 fatal (NILF, _("create_child_process: DuplicateHandle(Err) failed (e=%ld)\n"),
1493 GetLastError());
1494 }
1495
1496 if (!CreatePipe(&hChildOutRd, &hChildOutWr, &saAttr, 0))
1497 fatal (NILF, _("CreatePipe() failed (e=%ld)\n"), GetLastError());
1498
1499 hProcess = process_init_fd(hIn, hChildOutWr, hErr);
1500
1501 if (!hProcess)
1502 fatal (NILF, _("windows32_openpipe (): process_init_fd() failed\n"));
1503
1504 /* make sure that CreateProcess() has Path it needs */
1505 sync_Path_environment();
1506
1507 if (!process_begin(hProcess, command_argv, envp, command_argv[0], NULL)) {
1508 /* register process for wait */
1509 process_register(hProcess);
1510
1511 /* set the pid for returning to caller */
1512 *pid_p = (int) hProcess;
1513
1514 /* set up to read data from child */
1515 pipedes[0] = _open_osfhandle((long) hChildOutRd, O_RDONLY);
1516
1517 /* this will be closed almost right away */
1518 pipedes[1] = _open_osfhandle((long) hChildOutWr, O_APPEND);
1519 } else {
1520 /* reap/cleanup the failed process */
1521 process_cleanup(hProcess);
1522
1523 /* close handles which were duplicated, they weren't used */
1524 CloseHandle(hIn);
1525 CloseHandle(hErr);
1526
1527 /* close pipe handles, they won't be used */
1528 CloseHandle(hChildOutRd);
1529 CloseHandle(hChildOutWr);
1530
1531 /* set status for return */
1532 pipedes[0] = pipedes[1] = -1;
1533 *pid_p = -1;
1534 }
1535}
1536#endif
1537
1538
1539#ifdef __MSDOS__
1540FILE *
1541msdos_openpipe (int* pipedes, int *pidp, char *text)
1542{
1543 FILE *fpipe=0;
1544 /* MSDOS can't fork, but it has `popen'. */
1545 struct variable *sh = lookup_variable ("SHELL", 5);
1546 int e;
1547 extern int dos_command_running, dos_status;
1548
1549 /* Make sure not to bother processing an empty line. */
1550 while (isblank ((unsigned char)*text))
1551 ++text;
1552 if (*text == '\0')
1553 return 0;
1554
1555 if (sh)
1556 {
1557 char buf[PATH_MAX + 7];
1558 /* This makes sure $SHELL value is used by $(shell), even
1559 though the target environment is not passed to it. */
1560 sprintf (buf, "SHELL=%s", sh->value);
1561 putenv (buf);
1562 }
1563
1564 e = errno;
1565 errno = 0;
1566 dos_command_running = 1;
1567 dos_status = 0;
1568 /* If dos_status becomes non-zero, it means the child process
1569 was interrupted by a signal, like SIGINT or SIGQUIT. See
1570 fatal_error_signal in commands.c. */
1571 fpipe = popen (text, "rt");
1572 dos_command_running = 0;
1573 if (!fpipe || dos_status)
1574 {
1575 pipedes[0] = -1;
1576 *pidp = -1;
1577 if (dos_status)
1578 errno = EINTR;
1579 else if (errno == 0)
1580 errno = ENOMEM;
1581 shell_function_completed = -1;
1582 }
1583 else
1584 {
1585 pipedes[0] = fileno (fpipe);
1586 *pidp = 42; /* Yes, the Meaning of Life, the Universe, and Everything! */
1587 errno = e;
1588 shell_function_completed = 1;
1589 }
1590 return fpipe;
1591}
1592#endif
1593
1594/*
1595 Do shell spawning, with the naughty bits for different OSes.
1596 */
1597
1598#ifdef VMS
1599
1600/* VMS can't do $(shell ...) */
1601#define func_shell 0
1602
1603#else
1604#ifndef _AMIGA
1605static char *
1606func_shell (char *o, char **argv, const char *funcname UNUSED)
1607{
1608 char* batch_filename = NULL;
1609
1610#ifdef __MSDOS__
1611 FILE *fpipe;
1612#endif
1613 char **command_argv;
1614 char *error_prefix;
1615 char **envp;
1616 int pipedes[2];
1617 int pid;
1618
1619#ifndef __MSDOS__
1620 /* Construct the argument list. */
1621 command_argv = construct_command_argv (argv[0],
1622 (char **) NULL, (struct file *) 0,
1623 &batch_filename);
1624 if (command_argv == 0)
1625 return o;
1626#endif
1627
1628 /* Using a target environment for `shell' loses in cases like:
1629 export var = $(shell echo foobie)
1630 because target_environment hits a loop trying to expand $(var)
1631 to put it in the environment. This is even more confusing when
1632 var was not explicitly exported, but just appeared in the
1633 calling environment.
1634
1635 envp = target_environment (NILF);
1636 */
1637
1638 envp = environ;
1639
1640 /* For error messages. */
1641 if (reading_file && reading_file->filenm)
1642 {
1643 error_prefix = (char *) alloca (strlen (reading_file->filenm)+11+4);
1644 sprintf (error_prefix,
1645 "%s:%lu: ", reading_file->filenm, reading_file->lineno);
1646 }
1647 else
1648 error_prefix = "";
1649
1650#ifdef WINDOWS32
1651
1652 windows32_openpipe (pipedes, &pid, command_argv, envp);
1653
1654 if (pipedes[0] < 0) {
1655 /* open of the pipe failed, mark as failed execution */
1656 shell_function_completed = -1;
1657
1658 return o;
1659 } else
1660
1661#elif defined(__MSDOS__)
1662
1663 fpipe = msdos_openpipe (pipedes, &pid, argv[0]);
1664 if (pipedes[0] < 0)
1665 {
1666 perror_with_name (error_prefix, "pipe");
1667 return o;
1668 }
1669
1670#else
1671
1672 if (pipe (pipedes) < 0)
1673 {
1674 perror_with_name (error_prefix, "pipe");
1675 return o;
1676 }
1677
1678# ifdef __EMX__
1679
1680 /* close some handles that are unnecessary for the child process */
1681 CLOSE_ON_EXEC(pipedes[1]);
1682 CLOSE_ON_EXEC(pipedes[0]);
1683 /* Never use fork()/exec() here! Use spawn() instead in exec_command() */
1684 pid = child_execute_job (0, pipedes[1], command_argv, envp);
1685 if (pid < 0)
1686 perror_with_name (error_prefix, "spawn");
1687
1688# else /* ! __EMX__ */
1689
1690 pid = vfork ();
1691 if (pid < 0)
1692 perror_with_name (error_prefix, "fork");
1693 else if (pid == 0)
1694 child_execute_job (0, pipedes[1], command_argv, envp);
1695 else
1696
1697# endif
1698
1699#endif
1700 {
1701 /* We are the parent. */
1702 char *buffer;
1703 unsigned int maxlen, i;
1704 int cc;
1705
1706 /* Record the PID for reap_children. */
1707 shell_function_pid = pid;
1708#ifndef __MSDOS__
1709 shell_function_completed = 0;
1710
1711 /* Free the storage only the child needed. */
1712 free (command_argv[0]);
1713 free ((char *) command_argv);
1714
1715 /* Close the write side of the pipe. */
1716 (void) close (pipedes[1]);
1717#endif
1718
1719 /* Set up and read from the pipe. */
1720
1721 maxlen = 200;
1722 buffer = (char *) xmalloc (maxlen + 1);
1723
1724 /* Read from the pipe until it gets EOF. */
1725 for (i = 0; ; i += cc)
1726 {
1727 if (i == maxlen)
1728 {
1729 maxlen += 512;
1730 buffer = (char *) xrealloc (buffer, maxlen + 1);
1731 }
1732
1733 EINTRLOOP (cc, read (pipedes[0], &buffer[i], maxlen - i));
1734 if (cc <= 0)
1735 break;
1736 }
1737 buffer[i] = '\0';
1738
1739 /* Close the read side of the pipe. */
1740#ifdef __MSDOS__
1741 if (fpipe)
1742 (void) pclose (fpipe);
1743#else
1744 (void) close (pipedes[0]);
1745#endif
1746
1747 /* Loop until child_handler or reap_children() sets
1748 shell_function_completed to the status of our child shell. */
1749 while (shell_function_completed == 0)
1750 reap_children (1, 0);
1751
1752 if (batch_filename) {
1753 DB (DB_VERBOSE, (_("Cleaning up temporary batch file %s\n"),
1754 batch_filename));
1755 remove (batch_filename);
1756 free (batch_filename);
1757 }
1758 shell_function_pid = 0;
1759
1760 /* The child_handler function will set shell_function_completed
1761 to 1 when the child dies normally, or to -1 if it
1762 dies with status 127, which is most likely an exec fail. */
1763
1764 if (shell_function_completed == -1)
1765 {
1766 /* This likely means that the execvp failed, so we should just
1767 write the error message in the pipe from the child. */
1768 fputs (buffer, stderr);
1769 fflush (stderr);
1770 }
1771 else
1772 {
1773 /* The child finished normally. Replace all newlines in its output
1774 with spaces, and put that in the variable output buffer. */
1775 fold_newlines (buffer, &i);
1776 o = variable_buffer_output (o, buffer, i);
1777 }
1778
1779 free (buffer);
1780 }
1781
1782 return o;
1783}
1784
1785#else /* _AMIGA */
1786
1787/* Do the Amiga version of func_shell. */
1788
1789static char *
1790func_shell (char *o, char **argv, const char *funcname)
1791{
1792 /* Amiga can't fork nor spawn, but I can start a program with
1793 redirection of my choice. However, this means that we
1794 don't have an opportunity to reopen stdout to trap it. Thus,
1795 we save our own stdout onto a new descriptor and dup a temp
1796 file's descriptor onto our stdout temporarily. After we
1797 spawn the shell program, we dup our own stdout back to the
1798 stdout descriptor. The buffer reading is the same as above,
1799 except that we're now reading from a file. */
1800
1801#include <dos/dos.h>
1802#include <proto/dos.h>
1803
1804 BPTR child_stdout;
1805 char tmp_output[FILENAME_MAX];
1806 unsigned int maxlen = 200, i;
1807 int cc;
1808 char * buffer, * ptr;
1809 char ** aptr;
1810 int len = 0;
1811 char* batch_filename = NULL;
1812
1813 /* Construct the argument list. */
1814 command_argv = construct_command_argv (argv[0], (char **) NULL,
1815 (struct file *) 0, &batch_filename);
1816 if (command_argv == 0)
1817 return o;
1818
1819 /* Note the mktemp() is a security hole, but this only runs on Amiga.
1820 Ideally we would use main.c:open_tmpfile(), but this uses a special
1821 Open(), not fopen(), and I'm not familiar enough with the code to mess
1822 with it. */
1823 strcpy (tmp_output, "t:MakeshXXXXXXXX");
1824 mktemp (tmp_output);
1825 child_stdout = Open (tmp_output, MODE_NEWFILE);
1826
1827 for (aptr=command_argv; *aptr; aptr++)
1828 len += strlen (*aptr) + 1;
1829
1830 buffer = xmalloc (len + 1);
1831 ptr = buffer;
1832
1833 for (aptr=command_argv; *aptr; aptr++)
1834 {
1835 strcpy (ptr, *aptr);
1836 ptr += strlen (ptr) + 1;
1837 *ptr ++ = ' ';
1838 *ptr = 0;
1839 }
1840
1841 ptr[-1] = '\n';
1842
1843 Execute (buffer, NULL, child_stdout);
1844 free (buffer);
1845
1846 Close (child_stdout);
1847
1848 child_stdout = Open (tmp_output, MODE_OLDFILE);
1849
1850 buffer = xmalloc (maxlen);
1851 i = 0;
1852 do
1853 {
1854 if (i == maxlen)
1855 {
1856 maxlen += 512;
1857 buffer = (char *) xrealloc (buffer, maxlen + 1);
1858 }
1859
1860 cc = Read (child_stdout, &buffer[i], maxlen - i);
1861 if (cc > 0)
1862 i += cc;
1863 } while (cc > 0);
1864
1865 Close (child_stdout);
1866
1867 fold_newlines (buffer, &i);
1868 o = variable_buffer_output (o, buffer, i);
1869 free (buffer);
1870 return o;
1871}
1872#endif /* _AMIGA */
1873#endif /* !VMS */
1874
1875#ifdef EXPERIMENTAL
1876
1877/*
1878 equality. Return is string-boolean, ie, the empty string is false.
1879 */
1880static char *
1881func_eq (char *o, char **argv, char *funcname)
1882{
1883 int result = ! strcmp (argv[0], argv[1]);
1884 o = variable_buffer_output (o, result ? "1" : "", result);
1885 return o;
1886}
1887
1888
1889/*
1890 string-boolean not operator.
1891 */
1892static char *
1893func_not (char *o, char **argv, char *funcname)
1894{
1895 char *s = argv[0];
1896 int result = 0;
1897 while (isspace ((unsigned char)*s))
1898 s++;
1899 result = ! (*s);
1900 o = variable_buffer_output (o, result ? "1" : "", result);
1901 return o;
1902}
1903#endif
1904
1905
1906
1907/* Return the absolute name of file NAME which does not contain any `.',
1908 `..' components nor any repeated path separators ('/'). */
1909
1910static char *
1911abspath (const char *name, char *apath)
1912{
1913 char *dest;
1914 const char *start, *end, *apath_limit;
1915
1916 if (name[0] == '\0' || apath == NULL)
1917 return NULL;
1918
1919#ifdef WINDOWS32 /* bird */
1920 dest = w32ify((char *)name, 1);
1921 if (!dest)
1922 return NULL;
1923 {
1924 size_t len = strlen(dest);
1925 memcpy(apath, dest, len);
1926 dest = apath + len;
1927 }
1928
1929 (void)end; (void)start; (void)apath_limit;
1930
1931#elif defined __OS2__ /* bird */
1932 if (_abspath(apath, name, GET_PATH_MAX))
1933 return NULL;
1934 dest = strchr(apath, '\0');
1935
1936 (void)end; (void)start; (void)apath_limit; (void)dest;
1937
1938#else /* !WINDOWS32 && !__OS2__ */
1939 apath_limit = apath + GET_PATH_MAX;
1940
1941#ifdef HAVE_DOS_PATHS /* bird added this */
1942 if (isalpha(name[0]) && name[1] == ':')
1943 {
1944 /* drive spec */
1945 apath[0] = toupper(name[0]);
1946 apath[1] = ':';
1947 apath[2] = '/';
1948 name += 2;
1949 }
1950 else
1951#endif /* HAVE_DOS_PATHS */
1952 if (name[0] != '/')
1953 {
1954 /* It is unlikely we would make it until here but just to make sure. */
1955 if (!starting_directory)
1956 return NULL;
1957
1958 strcpy (apath, starting_directory);
1959
1960 dest = strchr (apath, '\0');
1961 }
1962 else
1963 {
1964 apath[0] = '/';
1965 dest = apath + 1;
1966 }
1967
1968 for (start = end = name; *start != '\0'; start = end)
1969 {
1970 unsigned long len;
1971
1972 /* Skip sequence of multiple path-separators. */
1973 while (*start == '/')
1974 ++start;
1975
1976 /* Find end of path component. */
1977 for (end = start; *end != '\0' && *end != '/'; ++end)
1978 ;
1979
1980 len = end - start;
1981
1982 if (len == 0)
1983 break;
1984 else if (len == 1 && start[0] == '.')
1985 /* nothing */;
1986 else if (len == 2 && start[0] == '.' && start[1] == '.')
1987 {
1988 /* Back up to previous component, ignore if at root already. */
1989 if (dest > apath + 1)
1990 while ((--dest)[-1] != '/');
1991 }
1992 else
1993 {
1994 if (dest[-1] != '/')
1995 *dest++ = '/';
1996
1997 if (dest + len >= apath_limit)
1998 return NULL;
1999
2000 dest = memcpy (dest, start, len);
2001 dest += len;
2002 *dest = '\0';
2003 }
2004 }
2005#endif /* !WINDOWS32 && !__OS2__ */
2006
2007 /* Unless it is root strip trailing separator. */
2008#ifdef HAVE_DOS_PATHS /* bird (is this correct? what about UNC?) */
2009 if (dest > apath + 1 + (apath[0] != '/') && dest[-1] == '/')
2010#else
2011 if (dest > apath + 1 && dest[-1] == '/')
2012#endif
2013 --dest;
2014
2015 *dest = '\0';
2016
2017 return apath;
2018}
2019
2020
2021static char *
2022func_realpath (char *o, char **argv, const char *funcname UNUSED)
2023{
2024 /* Expand the argument. */
2025 char *p = argv[0];
2026 char *path = 0;
2027 int doneany = 0;
2028 unsigned int len = 0;
2029 PATH_VAR (in);
2030 PATH_VAR (out);
2031
2032 while ((path = find_next_token (&p, &len)) != 0)
2033 {
2034 if (len < GET_PATH_MAX)
2035 {
2036 strncpy (in, path, len);
2037 in[len] = '\0';
2038
2039 if
2040 (
2041#ifdef HAVE_REALPATH
2042 realpath (in, out)
2043#else
2044 abspath (in, out)
2045#endif
2046 )
2047 {
2048 o = variable_buffer_output (o, out, strlen (out));
2049 o = variable_buffer_output (o, " ", 1);
2050 doneany = 1;
2051 }
2052 }
2053 }
2054
2055 /* Kill last space. */
2056 if (doneany)
2057 --o;
2058
2059 return o;
2060}
2061
2062static char *
2063func_abspath (char *o, char **argv, const char *funcname UNUSED)
2064{
2065 /* Expand the argument. */
2066 char *p = argv[0];
2067 char *path = 0;
2068 int doneany = 0;
2069 unsigned int len = 0;
2070 PATH_VAR (in);
2071 PATH_VAR (out);
2072
2073 while ((path = find_next_token (&p, &len)) != 0)
2074 {
2075 if (len < GET_PATH_MAX)
2076 {
2077 strncpy (in, path, len);
2078 in[len] = '\0';
2079
2080 if (abspath (in, out))
2081 {
2082 o = variable_buffer_output (o, out, strlen (out));
2083 o = variable_buffer_output (o, " ", 1);
2084 doneany = 1;
2085 }
2086 }
2087 }
2088
2089 /* Kill last space. */
2090 if (doneany)
2091 --o;
2092
2093 return o;
2094}
2095
2096#ifdef CONFIG_WITH_TOUPPER_TOLOWER
2097static char *
2098func_toupper_tolower (char *o, char **argv, const char *funcname)
2099{
2100 /* Expand the argument. */
2101 const char *p = argv[0];
2102 while (*p)
2103 {
2104 /* convert to temporary buffer */
2105 char tmp[256];
2106 unsigned int i;
2107 if (!strcmp(funcname, "toupper"))
2108 for (i = 0; i < sizeof(tmp) && *p; i++, p++)
2109 tmp[i] = toupper(*p);
2110 else
2111 for (i = 0; i < sizeof(tmp) && *p; i++, p++)
2112 tmp[i] = tolower(*p);
2113 o = variable_buffer_output (o, tmp, i);
2114 }
2115
2116 return o;
2117}
2118#endif /* CONFIG_WITH_TOUPPER_TOLOWER */
2119
2120/* Lookup table for builtin functions.
2121
2122 This doesn't have to be sorted; we use a straight lookup. We might gain
2123 some efficiency by moving most often used functions to the start of the
2124 table.
2125
2126 If MAXIMUM_ARGS is 0, that means there is no maximum and all
2127 comma-separated values are treated as arguments.
2128
2129 EXPAND_ARGS means that all arguments should be expanded before invocation.
2130 Functions that do namespace tricks (foreach) don't automatically expand. */
2131
2132static char *func_call PARAMS ((char *o, char **argv, const char *funcname));
2133
2134
2135static struct function_table_entry function_table_init[] =
2136{
2137 /* Name/size */ /* MIN MAX EXP? Function */
2138 { STRING_SIZE_TUPLE("abspath"), 0, 1, 1, func_abspath},
2139 { STRING_SIZE_TUPLE("addprefix"), 2, 2, 1, func_addsuffix_addprefix},
2140 { STRING_SIZE_TUPLE("addsuffix"), 2, 2, 1, func_addsuffix_addprefix},
2141 { STRING_SIZE_TUPLE("basename"), 0, 1, 1, func_basename_dir},
2142 { STRING_SIZE_TUPLE("dir"), 0, 1, 1, func_basename_dir},
2143 { STRING_SIZE_TUPLE("notdir"), 0, 1, 1, func_notdir_suffix},
2144 { STRING_SIZE_TUPLE("subst"), 3, 3, 1, func_subst},
2145 { STRING_SIZE_TUPLE("suffix"), 0, 1, 1, func_notdir_suffix},
2146 { STRING_SIZE_TUPLE("filter"), 2, 2, 1, func_filter_filterout},
2147 { STRING_SIZE_TUPLE("filter-out"), 2, 2, 1, func_filter_filterout},
2148 { STRING_SIZE_TUPLE("findstring"), 2, 2, 1, func_findstring},
2149 { STRING_SIZE_TUPLE("firstword"), 0, 1, 1, func_firstword},
2150 { STRING_SIZE_TUPLE("flavor"), 0, 1, 1, func_flavor},
2151 { STRING_SIZE_TUPLE("join"), 2, 2, 1, func_join},
2152 { STRING_SIZE_TUPLE("lastword"), 0, 1, 1, func_lastword},
2153 { STRING_SIZE_TUPLE("patsubst"), 3, 3, 1, func_patsubst},
2154 { STRING_SIZE_TUPLE("realpath"), 0, 1, 1, func_realpath},
2155 { STRING_SIZE_TUPLE("shell"), 0, 1, 1, func_shell},
2156 { STRING_SIZE_TUPLE("sort"), 0, 1, 1, func_sort},
2157 { STRING_SIZE_TUPLE("strip"), 0, 1, 1, func_strip},
2158 { STRING_SIZE_TUPLE("wildcard"), 0, 1, 1, func_wildcard},
2159 { STRING_SIZE_TUPLE("word"), 2, 2, 1, func_word},
2160 { STRING_SIZE_TUPLE("wordlist"), 3, 3, 1, func_wordlist},
2161 { STRING_SIZE_TUPLE("words"), 0, 1, 1, func_words},
2162 { STRING_SIZE_TUPLE("origin"), 0, 1, 1, func_origin},
2163 { STRING_SIZE_TUPLE("foreach"), 3, 3, 0, func_foreach},
2164 { STRING_SIZE_TUPLE("call"), 1, 0, 1, func_call},
2165 { STRING_SIZE_TUPLE("info"), 0, 1, 1, func_error},
2166 { STRING_SIZE_TUPLE("error"), 0, 1, 1, func_error},
2167 { STRING_SIZE_TUPLE("warning"), 0, 1, 1, func_error},
2168 { STRING_SIZE_TUPLE("if"), 2, 3, 0, func_if},
2169 { STRING_SIZE_TUPLE("or"), 1, 0, 0, func_or},
2170 { STRING_SIZE_TUPLE("and"), 1, 0, 0, func_and},
2171 { STRING_SIZE_TUPLE("value"), 0, 1, 1, func_value},
2172 { STRING_SIZE_TUPLE("eval"), 0, 1, 1, func_eval},
2173#ifdef EXPERIMENTAL
2174 { STRING_SIZE_TUPLE("eq"), 2, 2, 1, func_eq},
2175 { STRING_SIZE_TUPLE("not"), 0, 1, 1, func_not},
2176#endif
2177#ifdef CONFIG_WITH_TOUPPER_TOLOWER
2178 { STRING_SIZE_TUPLE("toupper"), 0, 1, 1, func_toupper_tolower},
2179 { STRING_SIZE_TUPLE("tolower"), 0, 1, 1, func_toupper_tolower},
2180#endif
2181};
2182
2183#define FUNCTION_TABLE_ENTRIES (sizeof (function_table_init) / sizeof (struct function_table_entry))
2184
2185
2186
2187/* These must come after the definition of function_table. */
2188
2189static char *
2190expand_builtin_function (char *o, int argc, char **argv,
2191 const struct function_table_entry *entry_p)
2192{
2193 if (argc < (int)entry_p->minimum_args)
2194 fatal (*expanding_var,
2195 _("insufficient number of arguments (%d) to function `%s'"),
2196 argc, entry_p->name);
2197
2198 /* I suppose technically some function could do something with no
2199 arguments, but so far none do, so just test it for all functions here
2200 rather than in each one. We can change it later if necessary. */
2201
2202 if (!argc)
2203 return o;
2204
2205 if (!entry_p->func_ptr)
2206 fatal (*expanding_var,
2207 _("unimplemented on this platform: function `%s'"), entry_p->name);
2208
2209 return entry_p->func_ptr (o, argv, entry_p->name);
2210}
2211
2212/* Check for a function invocation in *STRINGP. *STRINGP points at the
2213 opening ( or { and is not null-terminated. If a function invocation
2214 is found, expand it into the buffer at *OP, updating *OP, incrementing
2215 *STRINGP past the reference and returning nonzero. If not, return zero. */
2216
2217static int
2218handle_function2 (const struct function_table_entry *entry_p, char **op, char **stringp) /* bird split it up. */
2219{
2220 char openparen = (*stringp)[0];
2221 char closeparen = openparen == '(' ? ')' : '}';
2222 char *beg;
2223 char *end;
2224 int count = 0;
2225 register char *p;
2226 char **argv, **argvp;
2227 int nargs;
2228
2229 beg = *stringp + 1;
2230
2231 /* We found a builtin function. Find the beginning of its arguments (skip
2232 whitespace after the name). */
2233
2234 beg = next_token (beg + entry_p->len);
2235
2236 /* Find the end of the function invocation, counting nested use of
2237 whichever kind of parens we use. Since we're looking, count commas
2238 to get a rough estimate of how many arguments we might have. The
2239 count might be high, but it'll never be low. */
2240
2241 for (nargs=1, end=beg; *end != '\0'; ++end)
2242 if (*end == ',')
2243 ++nargs;
2244 else if (*end == openparen)
2245 ++count;
2246 else if (*end == closeparen && --count < 0)
2247 break;
2248
2249 if (count >= 0)
2250 fatal (*expanding_var,
2251 _("unterminated call to function `%s': missing `%c'"),
2252 entry_p->name, closeparen);
2253
2254 *stringp = end;
2255
2256 /* Get some memory to store the arg pointers. */
2257 argvp = argv = (char **) alloca (sizeof (char *) * (nargs + 2));
2258
2259 /* Chop the string into arguments, then a nul. As soon as we hit
2260 MAXIMUM_ARGS (if it's >0) assume the rest of the string is part of the
2261 last argument.
2262
2263 If we're expanding, store pointers to the expansion of each one. If
2264 not, make a duplicate of the string and point into that, nul-terminating
2265 each argument. */
2266
2267 if (!entry_p->expand_args)
2268 {
2269 int len = end - beg;
2270
2271 p = xmalloc (len+1);
2272 memcpy (p, beg, len);
2273 p[len] = '\0';
2274 beg = p;
2275 end = beg + len;
2276 }
2277
2278 for (p=beg, nargs=0; p <= end; ++argvp)
2279 {
2280 char *next;
2281
2282 ++nargs;
2283
2284 if (nargs == entry_p->maximum_args
2285 || (! (next = find_next_argument (openparen, closeparen, p, end))))
2286 next = end;
2287
2288 if (entry_p->expand_args)
2289 *argvp = expand_argument (p, next);
2290 else
2291 {
2292 *argvp = p;
2293 *next = '\0';
2294 }
2295
2296 p = next + 1;
2297 }
2298 *argvp = NULL;
2299
2300 /* Finally! Run the function... */
2301 *op = expand_builtin_function (*op, nargs, argv, entry_p);
2302
2303 /* Free memory. */
2304 if (entry_p->expand_args)
2305 for (argvp=argv; *argvp != 0; ++argvp)
2306 free (*argvp);
2307 else
2308 free (beg);
2309
2310 return 1;
2311}
2312
2313int
2314handle_function (char **op, char **stringp) /* bird split it up */
2315{
2316 const struct function_table_entry *entry_p = lookup_function (*stringp + 1);
2317 if (!entry_p)
2318 return 0;
2319 return handle_function2 (entry_p, op, stringp);
2320}
2321
2322
2323
2324/* User-defined functions. Expand the first argument as either a builtin
2325 function or a make variable, in the context of the rest of the arguments
2326 assigned to $1, $2, ... $N. $0 is the name of the function. */
2327
2328static char *
2329func_call (char *o, char **argv, const char *funcname UNUSED)
2330{
2331 static int max_args = 0;
2332 char *fname;
2333 char *cp;
2334 char *body;
2335 int flen;
2336 int i;
2337 int saved_args;
2338 const struct function_table_entry *entry_p;
2339 struct variable *v;
2340
2341 /* There is no way to define a variable with a space in the name, so strip
2342 leading and trailing whitespace as a favor to the user. */
2343 fname = argv[0];
2344 while (*fname != '\0' && isspace ((unsigned char)*fname))
2345 ++fname;
2346
2347 cp = fname + strlen (fname) - 1;
2348 while (cp > fname && isspace ((unsigned char)*cp))
2349 --cp;
2350 cp[1] = '\0';
2351
2352 /* Calling nothing is a no-op */
2353 if (*fname == '\0')
2354 return o;
2355
2356 /* Are we invoking a builtin function? */
2357
2358 entry_p = lookup_function (fname);
2359
2360 if (entry_p)
2361 {
2362 /* How many arguments do we have? */
2363 for (i=0; argv[i+1]; ++i)
2364 ;
2365
2366 return expand_builtin_function (o, i, argv+1, entry_p);
2367 }
2368
2369 /* Not a builtin, so the first argument is the name of a variable to be
2370 expanded and interpreted as a function. Find it. */
2371 flen = strlen (fname);
2372
2373 v = lookup_variable (fname, flen);
2374
2375 if (v == 0)
2376 warn_undefined (fname, flen);
2377
2378 if (v == 0 || *v->value == '\0')
2379 return o;
2380
2381 body = (char *) alloca (flen + 4);
2382 body[0] = '$';
2383 body[1] = '(';
2384 memcpy (body + 2, fname, flen);
2385 body[flen+2] = ')';
2386 body[flen+3] = '\0';
2387
2388 /* Set up arguments $(1) .. $(N). $(0) is the function name. */
2389
2390 push_new_variable_scope ();
2391
2392 for (i=0; *argv; ++i, ++argv)
2393 {
2394 char num[11];
2395
2396 sprintf (num, "%d", i);
2397 define_variable (num, strlen (num), *argv, o_automatic, 0);
2398 }
2399
2400 /* If the number of arguments we have is < max_args, it means we're inside
2401 a recursive invocation of $(call ...). Fill in the remaining arguments
2402 in the new scope with the empty value, to hide them from this
2403 invocation. */
2404
2405 for (; i < max_args; ++i)
2406 {
2407 char num[11];
2408
2409 sprintf (num, "%d", i);
2410 define_variable (num, strlen (num), "", o_automatic, 0);
2411 }
2412
2413 /* Expand the body in the context of the arguments, adding the result to
2414 the variable buffer. */
2415
2416 v->exp_count = EXP_COUNT_MAX;
2417
2418 saved_args = max_args;
2419 max_args = i;
2420 o = variable_expand_string (o, body, flen+3);
2421 max_args = saved_args;
2422
2423 v->exp_count = 0;
2424
2425 pop_variable_scope ();
2426
2427 return o + strlen (o);
2428}
2429
2430void
2431hash_init_function_table (void)
2432{
2433 hash_init (&function_table, FUNCTION_TABLE_ENTRIES * 2,
2434 function_table_entry_hash_1, function_table_entry_hash_2,
2435 function_table_entry_hash_cmp);
2436 hash_load (&function_table, function_table_init,
2437 FUNCTION_TABLE_ENTRIES, sizeof (struct function_table_entry));
2438#ifdef CONFIG_WITH_OPTIMIZATION_HACKS
2439 {
2440 unsigned i;
2441 for (i = 0; i < FUNCTION_TABLE_ENTRIES; i++)
2442 assert(function_table_init[i].len <= MAX_FUNCTION_LENGTH);
2443 }
2444#endif
2445}
Note: See TracBrowser for help on using the repository browser.