VirtualBox

source: kBuild/trunk/src/kmk/function.c@ 1408

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

Implemented local variable definitions - CONFIG_WITH_LOCAL_VARIABLES.

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

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