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

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

tuning. libc is 1-2 seconds faster to load now.

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