VirtualBox

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

Last change on this file since 1857 was 1847, checked in by bird, 16 years ago

kmk: Some optimizations for expand_deps.

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

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