VirtualBox

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

Last change on this file since 2758 was 2758, checked in by bird, 10 years ago

Some more variable stats I added the other day (not in release builds).

  • Property svn:eol-style set to native
File size: 159.0 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, 2007, 2008, 2009,
42010 Free Software Foundation, 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 3 of the License, or (at your option) any later
10version.
11
12GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License along with
17this program. If not, see <http://www.gnu.org/licenses/>. */
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_PRINTF
39# include "kmkbuiltin.h"
40#endif
41#ifdef CONFIG_WITH_XARGS /* bird */
42# ifdef HAVE_LIMITS_H
43# include <limits.h>
44# endif
45#endif
46#include <assert.h> /* bird */
47
48#if defined (CONFIG_WITH_MATH) || defined (CONFIG_WITH_NANOTS) || defined (CONFIG_WITH_FILE_SIZE) /* bird */
49# include <ctype.h>
50typedef big_int math_int;
51static char *math_int_to_variable_buffer (char *, math_int);
52static math_int math_int_from_string (const char *str);
53#endif
54
55#ifdef CONFIG_WITH_NANOTS /* bird */
56# ifdef WINDOWS32
57# include <Windows.h>
58# endif
59#endif
60
61#ifdef __OS2__
62# define CONFIG_WITH_OS2_LIBPATH 1
63#endif
64#ifdef CONFIG_WITH_OS2_LIBPATH
65# define INCL_BASE
66# define INCL_ERRROS
67# include <os2.h>
68
69# define QHINF_EXEINFO 1 /* NE exeinfo. */
70# define QHINF_READRSRCTBL 2 /* Reads from the resource table. */
71# define QHINF_READFILE 3 /* Reads from the executable file. */
72# define QHINF_LIBPATHLENGTH 4 /* Gets the libpath length. */
73# define QHINF_LIBPATH 5 /* Gets the entire libpath. */
74# define QHINF_FIXENTRY 6 /* NE only */
75# define QHINF_STE 7 /* NE only */
76# define QHINF_MAPSEL 8 /* NE only */
77 extern APIRET APIENTRY DosQueryHeaderInfo(HMODULE hmod, ULONG ulIndex, PVOID pvBuffer, ULONG cbBuffer, ULONG ulSubFunction);
78#endif /* CONFIG_WITH_OS2_LIBPATH */
79
80#ifdef KMK
81/** Checks if the @a_cch characters (bytes) in @a a_psz equals @a a_szConst. */
82# define STR_N_EQUALS(a_psz, a_cch, a_szConst) \
83 ( (a_cch) == sizeof (a_szConst) - 1 && !strncmp ((a_psz), (a_szConst), sizeof (a_szConst) - 1) )
84
85# ifdef _MSC_VER
86# include "kmkbuiltin/mscfakes.h"
87# endif
88#endif
89
90
91struct function_table_entry
92 {
93 const char *name;
94 unsigned char len;
95 unsigned char minimum_args;
96 unsigned char maximum_args;
97 char expand_args;
98 char *(*func_ptr) (char *output, char **argv, const char *fname);
99 };
100
101static unsigned long
102function_table_entry_hash_1 (const void *keyv)
103{
104 const struct function_table_entry *key = keyv;
105 return_STRING_N_HASH_1 (key->name, key->len);
106}
107
108static unsigned long
109function_table_entry_hash_2 (const void *keyv)
110{
111 const struct function_table_entry *key = keyv;
112 return_STRING_N_HASH_2 (key->name, key->len);
113}
114
115static int
116function_table_entry_hash_cmp (const void *xv, const void *yv)
117{
118 const struct function_table_entry *x = xv;
119 const struct function_table_entry *y = yv;
120 int result = x->len - y->len;
121 if (result)
122 return result;
123 return_STRING_N_COMPARE (x->name, y->name, x->len);
124}
125
126static struct hash_table function_table;
127
128#ifdef CONFIG_WITH_MAKE_STATS
129long make_stats_allocations = 0;
130long make_stats_reallocations = 0;
131unsigned long make_stats_allocated = 0;
132unsigned long make_stats_ht_lookups = 0;
133unsigned long make_stats_ht_collisions = 0;
134#endif
135
136
137
138/* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing
139 each occurrence of SUBST with REPLACE. TEXT is null-terminated. SLEN is
140 the length of SUBST and RLEN is the length of REPLACE. If BY_WORD is
141 nonzero, substitutions are done only on matches which are complete
142 whitespace-delimited words. */
143
144char *
145subst_expand (char *o, const char *text, const char *subst, const char *replace,
146 unsigned int slen, unsigned int rlen, int by_word)
147{
148 const char *t = text;
149 const char *p;
150
151 if (slen == 0 && !by_word)
152 {
153 /* The first occurrence of "" in any string is its end. */
154 o = variable_buffer_output (o, t, strlen (t));
155 if (rlen > 0)
156 o = variable_buffer_output (o, replace, rlen);
157 return o;
158 }
159
160 do
161 {
162 if (by_word && slen == 0)
163 /* When matching by words, the empty string should match
164 the end of each word, rather than the end of the whole text. */
165 p = end_of_token (next_token (t));
166 else
167 {
168 p = strstr (t, subst);
169 if (p == 0)
170 {
171 /* No more matches. Output everything left on the end. */
172 o = variable_buffer_output (o, t, strlen (t));
173 return o;
174 }
175 }
176
177 /* Output everything before this occurrence of the string to replace. */
178 if (p > t)
179 o = variable_buffer_output (o, t, p - t);
180
181 /* If we're substituting only by fully matched words,
182 or only at the ends of words, check that this case qualifies. */
183 if (by_word
184 && ((p > text && !isblank ((unsigned char)p[-1]))
185 || (p[slen] != '\0' && !isblank ((unsigned char)p[slen]))))
186 /* Struck out. Output the rest of the string that is
187 no longer to be replaced. */
188 o = variable_buffer_output (o, subst, slen);
189 else if (rlen > 0)
190 /* Output the replacement string. */
191 o = variable_buffer_output (o, replace, rlen);
192
193 /* Advance T past the string to be replaced. */
194 t = p + slen;
195 } while (*t != '\0');
196
197 return o;
198}
199
200
201
202/* Store into VARIABLE_BUFFER at O the result of scanning TEXT
203 and replacing strings matching PATTERN with REPLACE.
204 If PATTERN_PERCENT is not nil, PATTERN has already been
205 run through find_percent, and PATTERN_PERCENT is the result.
206 If REPLACE_PERCENT is not nil, REPLACE has already been
207 run through find_percent, and REPLACE_PERCENT is the result.
208 Note that we expect PATTERN_PERCENT and REPLACE_PERCENT to point to the
209 character _AFTER_ the %, not to the % itself.
210*/
211
212char *
213patsubst_expand_pat (char *o, const char *text,
214 const char *pattern, const char *replace,
215 const char *pattern_percent, const char *replace_percent)
216{
217 unsigned int pattern_prepercent_len, pattern_postpercent_len;
218 unsigned int replace_prepercent_len, replace_postpercent_len;
219 const char *t;
220 unsigned int len;
221 int doneany = 0;
222
223 /* Record the length of REPLACE before and after the % so we don't have to
224 compute these lengths more than once. */
225 if (replace_percent)
226 {
227 replace_prepercent_len = replace_percent - replace - 1;
228 replace_postpercent_len = strlen (replace_percent);
229 }
230 else
231 {
232 replace_prepercent_len = strlen (replace);
233 replace_postpercent_len = 0;
234 }
235
236 if (!pattern_percent)
237 /* With no % in the pattern, this is just a simple substitution. */
238 return subst_expand (o, text, pattern, replace,
239 strlen (pattern), strlen (replace), 1);
240
241 /* Record the length of PATTERN before and after the %
242 so we don't have to compute it more than once. */
243 pattern_prepercent_len = pattern_percent - pattern - 1;
244 pattern_postpercent_len = strlen (pattern_percent);
245
246 while ((t = find_next_token (&text, &len)) != 0)
247 {
248 int fail = 0;
249
250 /* Is it big enough to match? */
251 if (len < pattern_prepercent_len + pattern_postpercent_len)
252 fail = 1;
253
254 /* Does the prefix match? */
255 if (!fail && pattern_prepercent_len > 0
256 && (*t != *pattern
257 || t[pattern_prepercent_len - 1] != pattern_percent[-2]
258 || !strneq (t + 1, pattern + 1, pattern_prepercent_len - 1)))
259 fail = 1;
260
261 /* Does the suffix match? */
262 if (!fail && pattern_postpercent_len > 0
263 && (t[len - 1] != pattern_percent[pattern_postpercent_len - 1]
264 || t[len - pattern_postpercent_len] != *pattern_percent
265 || !strneq (&t[len - pattern_postpercent_len],
266 pattern_percent, pattern_postpercent_len - 1)))
267 fail = 1;
268
269 if (fail)
270 /* It didn't match. Output the string. */
271 o = variable_buffer_output (o, t, len);
272 else
273 {
274 /* It matched. Output the replacement. */
275
276 /* Output the part of the replacement before the %. */
277 o = variable_buffer_output (o, replace, replace_prepercent_len);
278
279 if (replace_percent != 0)
280 {
281 /* Output the part of the matched string that
282 matched the % in the pattern. */
283 o = variable_buffer_output (o, t + pattern_prepercent_len,
284 len - (pattern_prepercent_len
285 + pattern_postpercent_len));
286 /* Output the part of the replacement after the %. */
287 o = variable_buffer_output (o, replace_percent,
288 replace_postpercent_len);
289 }
290 }
291
292 /* Output a space, but not if the replacement is "". */
293 if (fail || replace_prepercent_len > 0
294 || (replace_percent != 0 && len + replace_postpercent_len > 0))
295 {
296 o = variable_buffer_output (o, " ", 1);
297 doneany = 1;
298 }
299 }
300#ifndef CONFIG_WITH_VALUE_LENGTH
301 if (doneany)
302 /* Kill the last space. */
303 --o;
304#else
305 /* Kill the last space and make sure there is a terminator there
306 so that strcache_add_len doesn't have to do a lot of exacty work
307 when expand_deps sends the output its way. */
308 if (doneany)
309 *--o = '\0';
310 else
311 o = variable_buffer_output (o, "\0", 1) - 1;
312#endif
313
314 return o;
315}
316
317/* Store into VARIABLE_BUFFER at O the result of scanning TEXT
318 and replacing strings matching PATTERN with REPLACE.
319 If PATTERN_PERCENT is not nil, PATTERN has already been
320 run through find_percent, and PATTERN_PERCENT is the result.
321 If REPLACE_PERCENT is not nil, REPLACE has already been
322 run through find_percent, and REPLACE_PERCENT is the result.
323 Note that we expect PATTERN_PERCENT and REPLACE_PERCENT to point to the
324 character _AFTER_ the %, not to the % itself.
325*/
326
327char *
328patsubst_expand (char *o, const char *text, char *pattern, char *replace)
329{
330 const char *pattern_percent = find_percent (pattern);
331 const char *replace_percent = find_percent (replace);
332
333 /* If there's a percent in the pattern or replacement skip it. */
334 if (replace_percent)
335 ++replace_percent;
336 if (pattern_percent)
337 ++pattern_percent;
338
339 return patsubst_expand_pat (o, text, pattern, replace,
340 pattern_percent, replace_percent);
341}
342
343
344#if defined (CONFIG_WITH_OPTIMIZATION_HACKS) || defined (CONFIG_WITH_VALUE_LENGTH)
345
346/* Char map containing the valid function name characters. */
347char func_char_map[256];
348
349/* Do the hash table lookup. */
350
351MY_INLINE const struct function_table_entry *
352lookup_function_in_hash_tab (const char *s, unsigned char len)
353{
354 struct function_table_entry function_table_entry_key;
355 function_table_entry_key.name = s;
356 function_table_entry_key.len = len;
357
358 return hash_find_item (&function_table, &function_table_entry_key);
359}
360
361/* Look up a function by name. */
362
363MY_INLINE const struct function_table_entry *
364lookup_function (const char *s, unsigned int len)
365{
366 unsigned char ch;
367# if 0 /* insane loop unroll */
368
369 if (len > MAX_FUNCTION_LENGTH)
370 len = MAX_FUNCTION_LENGTH + 1;
371
372# define X(idx) \
373 if (!func_char_map[ch = s[idx]]) \
374 { \
375 if (isblank (ch)) \
376 return lookup_function_in_hash_tab (s, idx); \
377 return 0; \
378 }
379# define Z(idx) \
380 return lookup_function_in_hash_tab (s, idx);
381
382 switch (len)
383 {
384 default:
385 assert (0);
386 case 0: return 0;
387 case 1: return 0;
388 case 2: X(0); X(1); Z(2);
389 case 3: X(0); X(1); X(2); Z(3);
390 case 4: X(0); X(1); X(2); X(3); Z(4);
391 case 5: X(0); X(1); X(2); X(3); X(4); Z(5);
392 case 6: X(0); X(1); X(2); X(3); X(4); X(5); Z(6);
393 case 7: X(0); X(1); X(2); X(3); X(4); X(5); X(6); Z(7);
394 case 8: X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); Z(8);
395 case 9: X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); X(8); Z(9);
396 case 10: X(0); X(1); X(2); X(3); X(4); X(5); X(6); X(7); X(8); X(9); Z(10);
397 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);
398 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);
399 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);
400 if ((ch = s[12]) == '\0' || isblank (ch))
401 return lookup_function_in_hash_tab (s, 12);
402 return 0;
403 }
404# undef Z
405# undef X
406
407# else /* normal loop */
408 const char *e = s;
409 if (len > MAX_FUNCTION_LENGTH)
410 len = MAX_FUNCTION_LENGTH;
411 while (func_char_map[ch = *e])
412 {
413 if (!len--)
414 return 0;
415 e++;
416 }
417 if (ch == '\0' || isblank (ch))
418 return lookup_function_in_hash_tab (s, e - s);
419 return 0;
420# endif /* normal loop */
421}
422
423#else /* original code */
424/* Look up a function by name. */
425
426static const struct function_table_entry *
427lookup_function (const char *s)
428{
429 const char *e = s;
430 while (*e && ( (*e >= 'a' && *e <= 'z') || *e == '-'))
431 e++;
432 if (*e == '\0' || isblank ((unsigned char) *e))
433 {
434 struct function_table_entry function_table_entry_key;
435 function_table_entry_key.name = s;
436 function_table_entry_key.len = e - s;
437
438 return hash_find_item (&function_table, &function_table_entry_key);
439 }
440 return 0;
441}
442#endif /* original code */
443
444
445
446/* Return 1 if PATTERN matches STR, 0 if not. */
447
448int
449pattern_matches (const char *pattern, const char *percent, const char *str)
450{
451 unsigned int sfxlen, strlength;
452
453 if (percent == 0)
454 {
455 unsigned int len = strlen (pattern) + 1;
456 char *new_chars = alloca (len);
457 memcpy (new_chars, pattern, len);
458 percent = find_percent (new_chars);
459 if (percent == 0)
460 return streq (new_chars, str);
461 pattern = new_chars;
462 }
463
464 sfxlen = strlen (percent + 1);
465 strlength = strlen (str);
466
467 if (strlength < (percent - pattern) + sfxlen
468 || !strneq (pattern, str, percent - pattern))
469 return 0;
470
471 return !strcmp (percent + 1, str + (strlength - sfxlen));
472}
473
474
475
476/* Find the next comma or ENDPAREN (counting nested STARTPAREN and
477 ENDPARENtheses), starting at PTR before END. Return a pointer to
478 next character.
479
480 If no next argument is found, return NULL.
481*/
482
483static char *
484find_next_argument (char startparen, char endparen,
485 const char *ptr, const char *end)
486{
487 int count = 0;
488
489 for (; ptr < end; ++ptr)
490 if (*ptr == startparen)
491 ++count;
492
493 else if (*ptr == endparen)
494 {
495 --count;
496 if (count < 0)
497 return NULL;
498 }
499
500 else if (*ptr == ',' && !count)
501 return (char *)ptr;
502
503 /* We didn't find anything. */
504 return NULL;
505}
506
507
508
509/* Glob-expand LINE. The returned pointer is
510 only good until the next call to string_glob. */
511
512static char *
513string_glob (char *line)
514{
515 static char *result = 0;
516 static unsigned int length;
517 struct nameseq *chain;
518 unsigned int idx;
519
520 chain = PARSE_FILE_SEQ (&line, struct nameseq, '\0', NULL,
521 /* We do not want parse_file_seq to strip `./'s.
522 That would break examples like:
523 $(patsubst ./%.c,obj/%.o,$(wildcard ./?*.c)). */
524 PARSEFS_NOSTRIP|PARSEFS_NOCACHE|PARSEFS_EXISTS);
525
526 if (result == 0)
527 {
528 length = 100;
529 result = xmalloc (100);
530 }
531
532 idx = 0;
533 while (chain != 0)
534 {
535 struct nameseq *next = chain->next;
536 unsigned int len = strlen (chain->name);
537
538 if (idx + len + 1 > length)
539 {
540 length += (len + 1) * 2;
541 result = xrealloc (result, length);
542 }
543 memcpy (&result[idx], chain->name, len);
544 idx += len;
545 result[idx++] = ' ';
546
547 /* Because we used PARSEFS_NOCACHE above, we have to free() NAME. */
548 free ((char *)chain->name);
549#ifndef CONFIG_WITH_ALLOC_CACHES
550 free (chain);
551#else
552 alloccache_free (&nameseq_cache, chain);
553#endif
554 chain = next;
555 }
556
557 /* Kill the last space and terminate the string. */
558 if (idx == 0)
559 result[0] = '\0';
560 else
561 result[idx - 1] = '\0';
562
563 return result;
564}
565
566
567/*
568 Builtin functions
569 */
570
571static char *
572func_patsubst (char *o, char **argv, const char *funcname UNUSED)
573{
574 o = patsubst_expand (o, argv[2], argv[0], argv[1]);
575 return o;
576}
577
578
579static char *
580func_join (char *o, char **argv, const char *funcname UNUSED)
581{
582 int doneany = 0;
583
584 /* Write each word of the first argument directly followed
585 by the corresponding word of the second argument.
586 If the two arguments have a different number of words,
587 the excess words are just output separated by blanks. */
588 const char *tp;
589 const char *pp;
590 const char *list1_iterator = argv[0];
591 const char *list2_iterator = argv[1];
592 do
593 {
594 unsigned int len1, len2;
595
596 tp = find_next_token (&list1_iterator, &len1);
597 if (tp != 0)
598 o = variable_buffer_output (o, tp, len1);
599
600 pp = find_next_token (&list2_iterator, &len2);
601 if (pp != 0)
602 o = variable_buffer_output (o, pp, len2);
603
604 if (tp != 0 || pp != 0)
605 {
606 o = variable_buffer_output (o, " ", 1);
607 doneany = 1;
608 }
609 }
610 while (tp != 0 || pp != 0);
611 if (doneany)
612 /* Kill the last blank. */
613 --o;
614
615 return o;
616}
617
618
619static char *
620func_origin (char *o, char **argv, const char *funcname UNUSED)
621{
622 /* Expand the argument. */
623 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
624 if (v == 0)
625 o = variable_buffer_output (o, "undefined", 9);
626 else
627 switch (v->origin)
628 {
629 default:
630 case o_invalid:
631 abort ();
632 break;
633 case o_default:
634 o = variable_buffer_output (o, "default", 7);
635 break;
636 case o_env:
637 o = variable_buffer_output (o, "environment", 11);
638 break;
639 case o_file:
640 o = variable_buffer_output (o, "file", 4);
641 break;
642 case o_env_override:
643 o = variable_buffer_output (o, "environment override", 20);
644 break;
645 case o_command:
646 o = variable_buffer_output (o, "command line", 12);
647 break;
648 case o_override:
649 o = variable_buffer_output (o, "override", 8);
650 break;
651 case o_automatic:
652 o = variable_buffer_output (o, "automatic", 9);
653 break;
654#ifdef CONFIG_WITH_LOCAL_VARIABLES
655 case o_local:
656 o = variable_buffer_output (o, "local", 5);
657 break;
658#endif
659 }
660
661 return o;
662}
663
664static char *
665func_flavor (char *o, char **argv, const char *funcname UNUSED)
666{
667 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
668
669 if (v == 0)
670 o = variable_buffer_output (o, "undefined", 9);
671 else
672 if (v->recursive)
673 o = variable_buffer_output (o, "recursive", 9);
674 else
675 o = variable_buffer_output (o, "simple", 6);
676
677 return o;
678}
679
680#ifdef CONFIG_WITH_WHERE_FUNCTION
681static char *
682func_where (char *o, char **argv, const char *funcname UNUSED)
683{
684 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
685 char buf[64];
686
687 if (v == 0)
688 o = variable_buffer_output (o, "undefined", 9);
689 else
690 if (v->fileinfo.filenm)
691 {
692 o = variable_buffer_output (o, v->fileinfo.filenm, strlen(v->fileinfo.filenm));
693 sprintf (buf, ":%lu", v->fileinfo.lineno);
694 o = variable_buffer_output (o, buf, strlen(buf));
695 }
696 else
697 o = variable_buffer_output (o, "no-location", 11);
698
699 return o;
700}
701#endif /* CONFIG_WITH_WHERE_FUNCTION */
702
703#ifdef VMS
704# define IS_PATHSEP(c) ((c) == ']')
705#else
706# ifdef HAVE_DOS_PATHS
707# define IS_PATHSEP(c) ((c) == '/' || (c) == '\\')
708# else
709# define IS_PATHSEP(c) ((c) == '/')
710# endif
711#endif
712
713
714static char *
715func_notdir_suffix (char *o, char **argv, const char *funcname)
716{
717 /* Expand the argument. */
718 const char *list_iterator = argv[0];
719 const char *p2;
720 int doneany =0;
721 unsigned int len=0;
722
723 int is_suffix = streq (funcname, "suffix");
724 int is_notdir = !is_suffix;
725 while ((p2 = find_next_token (&list_iterator, &len)) != 0)
726 {
727 const char *p = p2 + len;
728
729
730 while (p >= p2 && (!is_suffix || *p != '.'))
731 {
732 if (IS_PATHSEP (*p))
733 break;
734 --p;
735 }
736
737 if (p >= p2)
738 {
739 if (is_notdir)
740 ++p;
741 else if (*p != '.')
742 continue;
743 o = variable_buffer_output (o, p, len - (p - p2));
744 }
745#ifdef HAVE_DOS_PATHS
746 /* Handle the case of "d:foo/bar". */
747 else if (streq (funcname, "notdir") && p2[0] && p2[1] == ':')
748 {
749 p = p2 + 2;
750 o = variable_buffer_output (o, p, len - (p - p2));
751 }
752#endif
753 else if (is_notdir)
754 o = variable_buffer_output (o, p2, len);
755
756 if (is_notdir || p >= p2)
757 {
758 o = variable_buffer_output (o, " ", 1);
759 doneany = 1;
760 }
761 }
762
763 if (doneany)
764 /* Kill last space. */
765 --o;
766
767 return o;
768}
769
770
771static char *
772func_basename_dir (char *o, char **argv, const char *funcname)
773{
774 /* Expand the argument. */
775 const char *p3 = argv[0];
776 const char *p2;
777 int doneany=0;
778 unsigned int len=0;
779
780 int is_basename= streq (funcname, "basename");
781 int is_dir= !is_basename;
782
783 while ((p2 = find_next_token (&p3, &len)) != 0)
784 {
785 const char *p = p2 + len;
786 while (p >= p2 && (!is_basename || *p != '.'))
787 {
788 if (IS_PATHSEP (*p))
789 break;
790 --p;
791 }
792
793 if (p >= p2 && (is_dir))
794 o = variable_buffer_output (o, p2, ++p - p2);
795 else if (p >= p2 && (*p == '.'))
796 o = variable_buffer_output (o, p2, p - p2);
797#ifdef HAVE_DOS_PATHS
798 /* Handle the "d:foobar" case */
799 else if (p2[0] && p2[1] == ':' && is_dir)
800 o = variable_buffer_output (o, p2, 2);
801#endif
802 else if (is_dir)
803#ifdef VMS
804 o = variable_buffer_output (o, "[]", 2);
805#else
806#ifndef _AMIGA
807 o = variable_buffer_output (o, "./", 2);
808#else
809 ; /* Just a nop... */
810#endif /* AMIGA */
811#endif /* !VMS */
812 else
813 /* The entire name is the basename. */
814 o = variable_buffer_output (o, p2, len);
815
816 o = variable_buffer_output (o, " ", 1);
817 doneany = 1;
818 }
819
820 if (doneany)
821 /* Kill last space. */
822 --o;
823
824 return o;
825}
826
827#ifdef CONFIG_WITH_ROOT_FUNC
828
829/*
830 $(root path)
831
832 This is mainly for dealing with drive letters and UNC paths on Windows
833 and OS/2.
834 */
835static char *
836func_root (char *o, char **argv, const char *funcname UNUSED)
837{
838 const char *paths = argv[0] ? argv[0] : "";
839 int doneany = 0;
840 const char *p;
841 unsigned int len;
842
843 while ((p = find_next_token (&paths, &len)) != 0)
844 {
845 const char *p2 = p;
846
847#ifdef HAVE_DOS_PATHS
848 if ( len >= 2
849 && p2[1] == ':'
850 && ( (p2[0] >= 'A' && p2[0] <= 'Z')
851 || (p2[0] >= 'a' && p2[0] <= 'z')))
852 {
853 p2 += 2;
854 len -= 2;
855 }
856 else if (len >= 4 && IS_PATHSEP(p2[0]) && IS_PATHSEP(p2[1])
857 && !IS_PATHSEP(p2[2]))
858 {
859 /* Min recognized UNC: "//./" - find the next slash
860 Typical root: "//srv/shr/" */
861 /* XXX: Check if //./ needs special handling. */
862
863 p2 += 3;
864 len -= 3;
865 while (len > 0 && !IS_PATHSEP(*p2))
866 p2++, len--;
867
868 if (len && IS_PATHSEP(p2[0]) && (len == 1 || !IS_PATHSEP(p2[1])))
869 {
870 p2++;
871 len--;
872
873 if (len) /* optional share */
874 while (len > 0 && !IS_PATHSEP(*p2))
875 p2++, len--;
876 }
877 else
878 p2 = NULL;
879 }
880 else if (IS_PATHSEP(*p2))
881 {
882 p2++;
883 len--;
884 }
885 else
886 p2 = NULL;
887
888#elif defined (VMS) || defined (AMGIA)
889 /* XXX: VMS and AMGIA */
890 fatal (NILF, _("$(root ) is not implemented on this platform"));
891#else
892 if (IS_PATHSEP(*p2))
893 {
894 p2++;
895 len--;
896 }
897 else
898 p2 = NULL;
899#endif
900 if (p2 != NULL)
901 {
902 /* Include all subsequent path separators. */
903
904 while (len > 0 && IS_PATHSEP(*p2))
905 p2++, len--;
906 o = variable_buffer_output (o, p, p2 - p);
907 o = variable_buffer_output (o, " ", 1);
908 doneany = 1;
909 }
910 }
911
912 if (doneany)
913 /* Kill last space. */
914 --o;
915
916 return o;
917}
918
919/*
920 $(notroot path)
921
922 This is mainly for dealing with drive letters and UNC paths on Windows
923 and OS/2.
924 */
925static char *
926func_notroot (char *o, char **argv, const char *funcname UNUSED)
927{
928 const char *paths = argv[0] ? argv[0] : "";
929 int doneany = 0;
930 const char *p;
931 unsigned int len;
932
933 while ((p = find_next_token (&paths, &len)) != 0)
934 {
935 const char *p2 = p;
936
937#ifdef HAVE_DOS_PATHS
938 if ( len >= 2
939 && p2[1] == ':'
940 && ( (p2[0] >= 'A' && p2[0] <= 'Z')
941 || (p2[0] >= 'a' && p2[0] <= 'z')))
942 {
943 p2 += 2;
944 len -= 2;
945 }
946 else if (len >= 4 && IS_PATHSEP(p2[0]) && IS_PATHSEP(p2[1])
947 && !IS_PATHSEP(p2[2]))
948 {
949 /* Min recognized UNC: "//./" - find the next slash
950 Typical root: "//srv/shr/" */
951 /* XXX: Check if //./ needs special handling. */
952 unsigned int saved_len = len;
953
954 p2 += 3;
955 len -= 3;
956 while (len > 0 && !IS_PATHSEP(*p2))
957 p2++, len--;
958
959 if (len && IS_PATHSEP(p2[0]) && (len == 1 || !IS_PATHSEP(p2[1])))
960 {
961 p2++;
962 len--;
963
964 if (len) /* optional share */
965 while (len > 0 && !IS_PATHSEP(*p2))
966 p2++, len--;
967 }
968 else
969 {
970 p2 = p;
971 len = saved_len;
972 }
973 }
974
975#elif defined (VMS) || defined (AMGIA)
976 /* XXX: VMS and AMGIA */
977 fatal (NILF, _("$(root ) is not implemented on this platform"));
978#endif
979
980 /* Exclude all subsequent / leading path separators. */
981
982 while (len > 0 && IS_PATHSEP(*p2))
983 p2++, len--;
984 if (len > 0)
985 o = variable_buffer_output (o, p2, len);
986 else
987 o = variable_buffer_output (o, ".", 1);
988 o = variable_buffer_output (o, " ", 1);
989 doneany = 1;
990 }
991
992 if (doneany)
993 /* Kill last space. */
994 --o;
995
996 return o;
997}
998
999#endif /* CONFIG_WITH_ROOT_FUNC */
1000
1001static char *
1002func_addsuffix_addprefix (char *o, char **argv, const char *funcname)
1003{
1004 int fixlen = strlen (argv[0]);
1005 const char *list_iterator = argv[1];
1006 int is_addprefix = streq (funcname, "addprefix");
1007 int is_addsuffix = !is_addprefix;
1008
1009 int doneany = 0;
1010 const char *p;
1011 unsigned int len;
1012
1013 while ((p = find_next_token (&list_iterator, &len)) != 0)
1014 {
1015 if (is_addprefix)
1016 o = variable_buffer_output (o, argv[0], fixlen);
1017 o = variable_buffer_output (o, p, len);
1018 if (is_addsuffix)
1019 o = variable_buffer_output (o, argv[0], fixlen);
1020 o = variable_buffer_output (o, " ", 1);
1021 doneany = 1;
1022 }
1023
1024 if (doneany)
1025 /* Kill last space. */
1026 --o;
1027
1028 return o;
1029}
1030
1031static char *
1032func_subst (char *o, char **argv, const char *funcname UNUSED)
1033{
1034 o = subst_expand (o, argv[2], argv[0], argv[1], strlen (argv[0]),
1035 strlen (argv[1]), 0);
1036
1037 return o;
1038}
1039
1040#ifdef CONFIG_WITH_DEFINED_FUNCTIONS
1041
1042/* Used by func_firstdefined and func_lastdefined to parse the optional last
1043 argument. Returns 0 if the variable name is to be returned and 1 if it's
1044 the variable value value. */
1045static int
1046parse_value_name_argument (const char *arg1, const char *funcname)
1047{
1048 const char *end;
1049 int rc;
1050
1051 if (arg1 == NULL)
1052 return 0;
1053
1054 end = strchr (arg1, '\0');
1055 strip_whitespace (&arg1, &end);
1056
1057 if (!strncmp (arg1, "name", end - arg1))
1058 rc = 0;
1059 else if (!strncmp (arg1, "value", end - arg1))
1060 rc = 1;
1061 else
1062#if 1 /* FIXME: later */
1063 fatal (*expanding_var,
1064 _("second argument to `%s' function must be `name' or `value', not `%s'"),
1065 funcname, arg1);
1066#else
1067 {
1068 /* check the expanded form */
1069 char *exp = expand_argument (arg1, strchr (arg1, '\0'));
1070 arg1 = exp;
1071 end = strchr (arg1, '\0');
1072 strip_whitespace (&arg1, &end);
1073
1074 if (!strncmp (arg1, "name", end - arg1))
1075 rc = 0;
1076 else if (!strncmp (arg1, "value", end - arg1))
1077 rc = 1;
1078 else
1079 fatal (*expanding_var,
1080 _("second argument to `%s' function must be `name' or `value', not `%s'"),
1081 funcname, exp);
1082 free (exp);
1083 }
1084#endif
1085
1086 return rc;
1087}
1088
1089/* Given a list of variable names (ARGV[0]), returned the first variable which
1090 is defined (i.e. value is not empty). ARGV[1] indicates whether to return
1091 the variable name or its value. */
1092static char *
1093func_firstdefined (char *o, char **argv, const char *funcname)
1094{
1095 unsigned int i;
1096 const char *words = argv[0]; /* Use a temp variable for find_next_token */
1097 const char *p;
1098 int ret_value = parse_value_name_argument (argv[1], funcname);
1099
1100 /* FIXME: Optimize by not expanding the arguments, but instead expand them
1101 one by one here. This will require a find_next_token variant which
1102 takes `$(' and `)' into account. */
1103 while ((p = find_next_token (&words, &i)) != NULL)
1104 {
1105 struct variable *v = lookup_variable (p, i);
1106 if (v && v->value_length)
1107 {
1108 if (ret_value)
1109 variable_expand_string_2 (o, v->value, v->value_length, &o);
1110 else
1111 o = variable_buffer_output (o, p, i);
1112 break;
1113 }
1114 }
1115
1116 return o;
1117}
1118
1119/* Given a list of variable names (ARGV[0]), returned the last variable which
1120 is defined (i.e. value is not empty). ARGV[1] indicates whether to return
1121 the variable name or its value. */
1122static char *
1123func_lastdefined (char *o, char **argv, const char *funcname)
1124{
1125 struct variable *last_v = NULL;
1126 unsigned int i;
1127 const char *words = argv[0]; /* Use a temp variable for find_next_token */
1128 const char *p;
1129 int ret_value = parse_value_name_argument (argv[1], funcname);
1130
1131 /* FIXME: Optimize this. Walk from the end on unexpanded arguments. */
1132 while ((p = find_next_token (&words, &i)) != NULL)
1133 {
1134 struct variable *v = lookup_variable (p, i);
1135 if (v && v->value_length)
1136 {
1137 last_v = v;
1138 break;
1139 }
1140 }
1141
1142 if (last_v != NULL)
1143 {
1144 if (ret_value)
1145 variable_expand_string_2 (o, last_v->value, last_v->value_length, &o);
1146 else
1147 o = variable_buffer_output (o, last_v->name, last_v->length);
1148 }
1149 return o;
1150}
1151
1152#endif /* CONFIG_WITH_DEFINED_FUNCTIONS */
1153
1154static char *
1155func_firstword (char *o, char **argv, const char *funcname UNUSED)
1156{
1157 unsigned int i;
1158 const char *words = argv[0]; /* Use a temp variable for find_next_token */
1159 const char *p = find_next_token (&words, &i);
1160
1161 if (p != 0)
1162 o = variable_buffer_output (o, p, i);
1163
1164 return o;
1165}
1166
1167static char *
1168func_lastword (char *o, char **argv, const char *funcname UNUSED)
1169{
1170 unsigned int i;
1171 const char *words = argv[0]; /* Use a temp variable for find_next_token */
1172 const char *p = NULL;
1173 const char *t;
1174
1175 while ((t = find_next_token (&words, &i)))
1176 p = t;
1177
1178 if (p != 0)
1179 o = variable_buffer_output (o, p, i);
1180
1181 return o;
1182}
1183
1184static char *
1185func_words (char *o, char **argv, const char *funcname UNUSED)
1186{
1187 int i = 0;
1188 const char *word_iterator = argv[0];
1189 char buf[20];
1190
1191 while (find_next_token (&word_iterator, (unsigned int *) 0) != 0)
1192 ++i;
1193
1194 sprintf (buf, "%d", i);
1195 o = variable_buffer_output (o, buf, strlen (buf));
1196
1197 return o;
1198}
1199
1200/* Set begpp to point to the first non-whitespace character of the string,
1201 * and endpp to point to the last non-whitespace character of the string.
1202 * If the string is empty or contains nothing but whitespace, endpp will be
1203 * begpp-1.
1204 */
1205char *
1206strip_whitespace (const char **begpp, const char **endpp)
1207{
1208 while (*begpp <= *endpp && isspace ((unsigned char)**begpp))
1209 (*begpp) ++;
1210 while (*endpp >= *begpp && isspace ((unsigned char)**endpp))
1211 (*endpp) --;
1212 return (char *)*begpp;
1213}
1214
1215static void
1216check_numeric (const char *s, const char *msg)
1217{
1218 const char *end = s + strlen (s) - 1;
1219 const char *beg = s;
1220 strip_whitespace (&s, &end);
1221
1222 for (; s <= end; ++s)
1223 if (!ISDIGIT (*s)) /* ISDIGIT only evals its arg once: see make.h. */
1224 break;
1225
1226 if (s <= end || end - beg < 0)
1227 fatal (*expanding_var, "%s: '%s'", msg, beg);
1228}
1229
1230
1231
1232static char *
1233func_word (char *o, char **argv, const char *funcname UNUSED)
1234{
1235 const char *end_p;
1236 const char *p;
1237 int i;
1238
1239 /* Check the first argument. */
1240 check_numeric (argv[0], _("non-numeric first argument to `word' function"));
1241 i = atoi (argv[0]);
1242
1243 if (i == 0)
1244 fatal (*expanding_var,
1245 _("first argument to `word' function must be greater than 0"));
1246
1247 end_p = argv[1];
1248 while ((p = find_next_token (&end_p, 0)) != 0)
1249 if (--i == 0)
1250 break;
1251
1252 if (i == 0)
1253 o = variable_buffer_output (o, p, end_p - p);
1254
1255 return o;
1256}
1257
1258static char *
1259func_wordlist (char *o, char **argv, const char *funcname UNUSED)
1260{
1261 int start, count;
1262
1263 /* Check the arguments. */
1264 check_numeric (argv[0],
1265 _("non-numeric first argument to `wordlist' function"));
1266 check_numeric (argv[1],
1267 _("non-numeric second argument to `wordlist' function"));
1268
1269 start = atoi (argv[0]);
1270 if (start < 1)
1271 fatal (*expanding_var,
1272 "invalid first argument to `wordlist' function: `%d'", start);
1273
1274 count = atoi (argv[1]) - start + 1;
1275
1276 if (count > 0)
1277 {
1278 const char *p;
1279 const char *end_p = argv[2];
1280
1281 /* Find the beginning of the "start"th word. */
1282 while (((p = find_next_token (&end_p, 0)) != 0) && --start)
1283 ;
1284
1285 if (p)
1286 {
1287 /* Find the end of the "count"th word from start. */
1288 while (--count && (find_next_token (&end_p, 0) != 0))
1289 ;
1290
1291 /* Return the stuff in the middle. */
1292 o = variable_buffer_output (o, p, end_p - p);
1293 }
1294 }
1295
1296 return o;
1297}
1298
1299static char *
1300func_findstring (char *o, char **argv, const char *funcname UNUSED)
1301{
1302 /* Find the first occurrence of the first string in the second. */
1303 if (strstr (argv[1], argv[0]) != 0)
1304 o = variable_buffer_output (o, argv[0], strlen (argv[0]));
1305
1306 return o;
1307}
1308
1309static char *
1310func_foreach (char *o, char **argv, const char *funcname UNUSED)
1311{
1312 /* expand only the first two. */
1313 char *varname = expand_argument (argv[0], NULL);
1314 char *list = expand_argument (argv[1], NULL);
1315 const char *body = argv[2];
1316#ifdef CONFIG_WITH_VALUE_LENGTH
1317 long body_len = strlen (body);
1318#endif
1319
1320 int doneany = 0;
1321 const char *list_iterator = list;
1322 const char *p;
1323 unsigned int len;
1324 struct variable *var;
1325
1326 push_new_variable_scope ();
1327 var = define_variable (varname, strlen (varname), "", o_automatic, 0);
1328
1329 /* loop through LIST, put the value in VAR and expand BODY */
1330 while ((p = find_next_token (&list_iterator, &len)) != 0)
1331 {
1332#ifndef CONFIG_WITH_VALUE_LENGTH
1333 char *result = 0;
1334
1335 free (var->value);
1336 var->value = xstrndup (p, len);
1337
1338 result = allocated_variable_expand (body);
1339
1340 o = variable_buffer_output (o, result, strlen (result));
1341 o = variable_buffer_output (o, " ", 1);
1342 doneany = 1;
1343 free (result);
1344#else /* CONFIG_WITH_VALUE_LENGTH */
1345 if (len >= var->value_alloc_len)
1346 {
1347# ifdef CONFIG_WITH_RDONLY_VARIABLE_VALUE
1348 if (var->rdonly_val)
1349 var->rdonly_val = 0;
1350 else
1351# endif
1352 free (var->value);
1353 var->value_alloc_len = VAR_ALIGN_VALUE_ALLOC (len + 1);
1354 var->value = xmalloc (var->value_alloc_len);
1355 }
1356 memcpy (var->value, p, len);
1357 var->value[len] = '\0';
1358 var->value_length = len;
1359
1360 variable_expand_string_2 (o, body, body_len, &o);
1361 o = variable_buffer_output (o, " ", 1);
1362 doneany = 1;
1363#endif /* CONFIG_WITH_VALUE_LENGTH */
1364 }
1365
1366 if (doneany)
1367 /* Kill the last space. */
1368 --o;
1369
1370 pop_variable_scope ();
1371 free (varname);
1372 free (list);
1373
1374 return o;
1375}
1376
1377#ifdef CONFIG_WITH_LOOP_FUNCTIONS
1378
1379
1380/* Helper for func_for that evaluates the INIT and NEXT parts. */
1381static void
1382helper_eval (char *text, size_t text_len)
1383{
1384 unsigned int buf_len;
1385 char *buf;
1386
1387 install_variable_buffer (&buf, &buf_len);
1388 eval_buffer (text, text + text_len);
1389 restore_variable_buffer (buf, buf_len);
1390}
1391
1392/*
1393 $(for init,condition,next,body)
1394 */
1395static char *
1396func_for (char *o, char **argv, const char *funcname UNUSED)
1397{
1398 char *init = argv[0];
1399 const char *cond = argv[1];
1400 const char *next = argv[2];
1401 size_t next_len = strlen (next);
1402 char *next_buf = xmalloc (next_len + 1);
1403 const char *body = argv[3];
1404 size_t body_len = strlen (body);
1405 unsigned int doneany = 0;
1406
1407 push_new_variable_scope ();
1408
1409 /* Evaluate INIT. */
1410
1411 helper_eval (init, strlen (init));
1412
1413 /* Loop till COND is false. */
1414
1415 while (expr_eval_if_conditionals (cond, NULL) == 0 /* true */)
1416 {
1417 /* Expand BODY. */
1418
1419 if (!doneany)
1420 doneany = 1;
1421 else
1422 o = variable_buffer_output (o, " ", 1);
1423 variable_expand_string_2 (o, body, body_len, &o);
1424
1425 /* Evaluate NEXT. */
1426
1427 memcpy (next_buf, next, next_len + 1);
1428 helper_eval (next_buf, next_len);
1429 }
1430
1431 pop_variable_scope ();
1432 free (next_buf);
1433
1434 return o;
1435}
1436
1437/*
1438 $(while condition,body)
1439 */
1440static char *
1441func_while (char *o, char **argv, const char *funcname UNUSED)
1442{
1443 const char *cond = argv[0];
1444 const char *body = argv[1];
1445 size_t body_len = strlen (body);
1446 unsigned int doneany = 0;
1447
1448 push_new_variable_scope ();
1449
1450 while (expr_eval_if_conditionals (cond, NULL) == 0 /* true */)
1451 {
1452 if (!doneany)
1453 doneany = 1;
1454 else
1455 o = variable_buffer_output (o, " ", 1);
1456 variable_expand_string_2 (o, body, body_len, &o);
1457 }
1458
1459 pop_variable_scope ();
1460
1461 return o;
1462}
1463
1464
1465#endif /* CONFIG_WITH_LOOP_FUNCTIONS */
1466
1467struct a_word
1468{
1469 struct a_word *next;
1470 struct a_word *chain;
1471 char *str;
1472 int length;
1473 int matched;
1474};
1475
1476static unsigned long
1477a_word_hash_1 (const void *key)
1478{
1479 return_STRING_HASH_1 (((struct a_word const *) key)->str);
1480}
1481
1482static unsigned long
1483a_word_hash_2 (const void *key)
1484{
1485 return_STRING_HASH_2 (((struct a_word const *) key)->str);
1486}
1487
1488static int
1489a_word_hash_cmp (const void *x, const void *y)
1490{
1491 int result = ((struct a_word const *) x)->length - ((struct a_word const *) y)->length;
1492 if (result)
1493 return result;
1494 return_STRING_COMPARE (((struct a_word const *) x)->str,
1495 ((struct a_word const *) y)->str);
1496}
1497
1498struct a_pattern
1499{
1500 struct a_pattern *next;
1501 char *str;
1502 char *percent;
1503 int length;
1504 int save_c;
1505};
1506
1507static char *
1508func_filter_filterout (char *o, char **argv, const char *funcname)
1509{
1510 struct a_word *wordhead;
1511 struct a_word **wordtail;
1512 struct a_word *wp;
1513 struct a_pattern *pathead;
1514 struct a_pattern **pattail;
1515 struct a_pattern *pp;
1516
1517 struct hash_table a_word_table;
1518 int is_filter = streq (funcname, "filter");
1519 const char *pat_iterator = argv[0];
1520 const char *word_iterator = argv[1];
1521 int literals = 0;
1522 int words = 0;
1523 int hashing = 0;
1524 char *p;
1525 unsigned int len;
1526
1527 /* Chop ARGV[0] up into patterns to match against the words. */
1528
1529 pattail = &pathead;
1530 while ((p = find_next_token (&pat_iterator, &len)) != 0)
1531 {
1532 struct a_pattern *pat = alloca (sizeof (struct a_pattern));
1533
1534 *pattail = pat;
1535 pattail = &pat->next;
1536
1537 if (*pat_iterator != '\0')
1538 ++pat_iterator;
1539
1540 pat->str = p;
1541 pat->length = len;
1542 pat->save_c = p[len];
1543 p[len] = '\0';
1544 pat->percent = find_percent (p);
1545 if (pat->percent == 0)
1546 literals++;
1547 }
1548 *pattail = 0;
1549
1550 /* Chop ARGV[1] up into words to match against the patterns. */
1551
1552 wordtail = &wordhead;
1553 while ((p = find_next_token (&word_iterator, &len)) != 0)
1554 {
1555 struct a_word *word = alloca (sizeof (struct a_word));
1556
1557 *wordtail = word;
1558 wordtail = &word->next;
1559
1560 if (*word_iterator != '\0')
1561 ++word_iterator;
1562
1563 p[len] = '\0';
1564 word->str = p;
1565 word->length = len;
1566 word->matched = 0;
1567 word->chain = 0;
1568 words++;
1569 }
1570 *wordtail = 0;
1571
1572 /* Only use a hash table if arg list lengths justifies the cost. */
1573 hashing = (literals >= 2 && (literals * words) >= 10);
1574 if (hashing)
1575 {
1576 hash_init (&a_word_table, words, a_word_hash_1, a_word_hash_2,
1577 a_word_hash_cmp);
1578 for (wp = wordhead; wp != 0; wp = wp->next)
1579 {
1580 struct a_word *owp = hash_insert (&a_word_table, wp);
1581 if (owp)
1582 wp->chain = owp;
1583 }
1584 }
1585
1586 if (words)
1587 {
1588 int doneany = 0;
1589
1590 /* Run each pattern through the words, killing words. */
1591 for (pp = pathead; pp != 0; pp = pp->next)
1592 {
1593 if (pp->percent)
1594 for (wp = wordhead; wp != 0; wp = wp->next)
1595 wp->matched |= pattern_matches (pp->str, pp->percent, wp->str);
1596 else if (hashing)
1597 {
1598 struct a_word a_word_key;
1599 a_word_key.str = pp->str;
1600 a_word_key.length = pp->length;
1601 wp = hash_find_item (&a_word_table, &a_word_key);
1602 while (wp)
1603 {
1604 wp->matched |= 1;
1605 wp = wp->chain;
1606 }
1607 }
1608 else
1609 for (wp = wordhead; wp != 0; wp = wp->next)
1610 wp->matched |= (wp->length == pp->length
1611 && strneq (pp->str, wp->str, wp->length));
1612 }
1613
1614 /* Output the words that matched (or didn't, for filter-out). */
1615 for (wp = wordhead; wp != 0; wp = wp->next)
1616 if (is_filter ? wp->matched : !wp->matched)
1617 {
1618 o = variable_buffer_output (o, wp->str, strlen (wp->str));
1619 o = variable_buffer_output (o, " ", 1);
1620 doneany = 1;
1621 }
1622
1623 if (doneany)
1624 /* Kill the last space. */
1625 --o;
1626 }
1627
1628 for (pp = pathead; pp != 0; pp = pp->next)
1629 pp->str[pp->length] = pp->save_c;
1630
1631 if (hashing)
1632 hash_free (&a_word_table, 0);
1633
1634 return o;
1635}
1636
1637
1638static char *
1639func_strip (char *o, char **argv, const char *funcname UNUSED)
1640{
1641 const char *p = argv[0];
1642 int doneany = 0;
1643
1644 while (*p != '\0')
1645 {
1646 int i=0;
1647 const char *word_start;
1648
1649 while (isspace ((unsigned char)*p))
1650 ++p;
1651 word_start = p;
1652 for (i=0; *p != '\0' && !isspace ((unsigned char)*p); ++p, ++i)
1653 {}
1654 if (!i)
1655 break;
1656 o = variable_buffer_output (o, word_start, i);
1657 o = variable_buffer_output (o, " ", 1);
1658 doneany = 1;
1659 }
1660
1661 if (doneany)
1662 /* Kill the last space. */
1663 --o;
1664
1665 return o;
1666}
1667
1668/*
1669 Print a warning or fatal message.
1670*/
1671static char *
1672func_error (char *o, char **argv, const char *funcname)
1673{
1674 char **argvp;
1675 char *msg, *p;
1676 int len;
1677
1678 /* The arguments will be broken on commas. Rather than create yet
1679 another special case where function arguments aren't broken up,
1680 just create a format string that puts them back together. */
1681 for (len=0, argvp=argv; *argvp != 0; ++argvp)
1682 len += strlen (*argvp) + 2;
1683
1684 p = msg = alloca (len + 1);
1685
1686 for (argvp=argv; argvp[1] != 0; ++argvp)
1687 {
1688 strcpy (p, *argvp);
1689 p += strlen (*argvp);
1690 *(p++) = ',';
1691 *(p++) = ' ';
1692 }
1693 strcpy (p, *argvp);
1694
1695 switch (*funcname) {
1696 case 'e':
1697 fatal (reading_file, "%s", msg);
1698
1699 case 'w':
1700 error (reading_file, "%s", msg);
1701 break;
1702
1703 case 'i':
1704 printf ("%s\n", msg);
1705 fflush(stdout);
1706 break;
1707
1708 default:
1709 fatal (*expanding_var, "Internal error: func_error: '%s'", funcname);
1710 }
1711
1712 /* The warning function expands to the empty string. */
1713 return o;
1714}
1715
1716
1717/*
1718 chop argv[0] into words, and sort them.
1719 */
1720static char *
1721func_sort (char *o, char **argv, const char *funcname UNUSED)
1722{
1723 const char *t;
1724 char **words;
1725 int wordi;
1726 char *p;
1727 unsigned int len;
1728 int i;
1729
1730 /* Find the maximum number of words we'll have. */
1731 t = argv[0];
1732 wordi = 1;
1733 while (*t != '\0')
1734 {
1735 char c = *(t++);
1736
1737 if (! isspace ((unsigned char)c))
1738 continue;
1739
1740 ++wordi;
1741
1742 while (isspace ((unsigned char)*t))
1743 ++t;
1744 }
1745
1746 words = xmalloc (wordi * sizeof (char *));
1747
1748 /* Now assign pointers to each string in the array. */
1749 t = argv[0];
1750 wordi = 0;
1751 while ((p = find_next_token (&t, &len)) != 0)
1752 {
1753 ++t;
1754 p[len] = '\0';
1755 words[wordi++] = p;
1756 }
1757
1758 if (wordi)
1759 {
1760 /* Now sort the list of words. */
1761 qsort (words, wordi, sizeof (char *), alpha_compare);
1762
1763 /* Now write the sorted list, uniquified. */
1764#ifdef CONFIG_WITH_RSORT
1765 if (strcmp (funcname, "rsort"))
1766 {
1767 /* sort */
1768#endif
1769 for (i = 0; i < wordi; ++i)
1770 {
1771 len = strlen (words[i]);
1772 if (i == wordi - 1 || strlen (words[i + 1]) != len
1773 || strcmp (words[i], words[i + 1]))
1774 {
1775 o = variable_buffer_output (o, words[i], len);
1776 o = variable_buffer_output (o, " ", 1);
1777 }
1778 }
1779#ifdef CONFIG_WITH_RSORT
1780 }
1781 else
1782 {
1783 /* rsort - reverse the result */
1784 i = wordi;
1785 while (i-- > 0)
1786 {
1787 len = strlen (words[i]);
1788 if (i == 0 || strlen (words[i - 1]) != len
1789 || strcmp (words[i], words[i - 1]))
1790 {
1791 o = variable_buffer_output (o, words[i], len);
1792 o = variable_buffer_output (o, " ", 1);
1793 }
1794 }
1795 }
1796#endif
1797
1798 /* Kill the last space. */
1799 --o;
1800 }
1801
1802 free (words);
1803
1804 return o;
1805}
1806
1807/*
1808 $(if condition,true-part[,false-part])
1809
1810 CONDITION is false iff it evaluates to an empty string. White
1811 space before and after condition are stripped before evaluation.
1812
1813 If CONDITION is true, then TRUE-PART is evaluated, otherwise FALSE-PART is
1814 evaluated (if it exists). Because only one of the two PARTs is evaluated,
1815 you can use $(if ...) to create side-effects (with $(shell ...), for
1816 example).
1817*/
1818
1819static char *
1820func_if (char *o, char **argv, const char *funcname UNUSED)
1821{
1822 const char *begp = argv[0];
1823 const char *endp = begp + strlen (argv[0]) - 1;
1824 int result = 0;
1825
1826 /* Find the result of the condition: if we have a value, and it's not
1827 empty, the condition is true. If we don't have a value, or it's the
1828 empty string, then it's false. */
1829
1830 strip_whitespace (&begp, &endp);
1831
1832 if (begp <= endp)
1833 {
1834 char *expansion = expand_argument (begp, endp+1);
1835
1836 result = strlen (expansion);
1837 free (expansion);
1838 }
1839
1840 /* If the result is true (1) we want to eval the first argument, and if
1841 it's false (0) we want to eval the second. If the argument doesn't
1842 exist we do nothing, otherwise expand it and add to the buffer. */
1843
1844 argv += 1 + !result;
1845
1846 if (*argv)
1847 {
1848 char *expansion = expand_argument (*argv, NULL);
1849
1850 o = variable_buffer_output (o, expansion, strlen (expansion));
1851
1852 free (expansion);
1853 }
1854
1855 return o;
1856}
1857
1858/*
1859 $(or condition1[,condition2[,condition3[...]]])
1860
1861 A CONDITION is false iff it evaluates to an empty string. White
1862 space before and after CONDITION are stripped before evaluation.
1863
1864 CONDITION1 is evaluated. If it's true, then this is the result of
1865 expansion. If it's false, CONDITION2 is evaluated, and so on. If none of
1866 the conditions are true, the expansion is the empty string.
1867
1868 Once a CONDITION is true no further conditions are evaluated
1869 (short-circuiting).
1870*/
1871
1872static char *
1873func_or (char *o, char **argv, const char *funcname UNUSED)
1874{
1875 for ( ; *argv ; ++argv)
1876 {
1877 const char *begp = *argv;
1878 const char *endp = begp + strlen (*argv) - 1;
1879 char *expansion;
1880 int result = 0;
1881
1882 /* Find the result of the condition: if it's false keep going. */
1883
1884 strip_whitespace (&begp, &endp);
1885
1886 if (begp > endp)
1887 continue;
1888
1889 expansion = expand_argument (begp, endp+1);
1890 result = strlen (expansion);
1891
1892 /* If the result is false keep going. */
1893 if (!result)
1894 {
1895 free (expansion);
1896 continue;
1897 }
1898
1899 /* It's true! Keep this result and return. */
1900 o = variable_buffer_output (o, expansion, result);
1901 free (expansion);
1902 break;
1903 }
1904
1905 return o;
1906}
1907
1908/*
1909 $(and condition1[,condition2[,condition3[...]]])
1910
1911 A CONDITION is false iff it evaluates to an empty string. White
1912 space before and after CONDITION are stripped before evaluation.
1913
1914 CONDITION1 is evaluated. If it's false, then this is the result of
1915 expansion. If it's true, CONDITION2 is evaluated, and so on. If all of
1916 the conditions are true, the expansion is the result of the last condition.
1917
1918 Once a CONDITION is false no further conditions are evaluated
1919 (short-circuiting).
1920*/
1921
1922static char *
1923func_and (char *o, char **argv, const char *funcname UNUSED)
1924{
1925 char *expansion;
1926 int result;
1927
1928 while (1)
1929 {
1930 const char *begp = *argv;
1931 const char *endp = begp + strlen (*argv) - 1;
1932
1933 /* An empty condition is always false. */
1934 strip_whitespace (&begp, &endp);
1935 if (begp > endp)
1936 return o;
1937
1938 expansion = expand_argument (begp, endp+1);
1939 result = strlen (expansion);
1940
1941 /* If the result is false, stop here: we're done. */
1942 if (!result)
1943 break;
1944
1945 /* Otherwise the result is true. If this is the last one, keep this
1946 result and quit. Otherwise go on to the next one! */
1947
1948 if (*(++argv))
1949 free (expansion);
1950 else
1951 {
1952 o = variable_buffer_output (o, expansion, result);
1953 break;
1954 }
1955 }
1956
1957 free (expansion);
1958
1959 return o;
1960}
1961
1962static char *
1963func_wildcard (char *o, char **argv, const char *funcname UNUSED)
1964{
1965#ifdef _AMIGA
1966 o = wildcard_expansion (argv[0], o);
1967#else
1968 char *p = string_glob (argv[0]);
1969 o = variable_buffer_output (o, p, strlen (p));
1970#endif
1971 return o;
1972}
1973
1974/*
1975 $(eval <makefile string>)
1976
1977 Always resolves to the empty string.
1978
1979 Treat the arguments as a segment of makefile, and parse them.
1980*/
1981
1982static char *
1983func_eval (char *o, char **argv, const char *funcname UNUSED)
1984{
1985 char *buf;
1986 unsigned int len;
1987
1988 /* Eval the buffer. Pop the current variable buffer setting so that the
1989 eval'd code can use its own without conflicting. */
1990
1991 install_variable_buffer (&buf, &len);
1992
1993#ifndef CONFIG_WITH_VALUE_LENGTH
1994 eval_buffer (argv[0]);
1995#else
1996 eval_buffer (argv[0], strchr (argv[0], '\0'));
1997#endif
1998
1999 restore_variable_buffer (buf, len);
2000
2001 return o;
2002}
2003
2004
2005#ifdef CONFIG_WITH_EVALPLUS
2006/* Same as func_eval except that we push and pop the local variable
2007 context before evaluating the buffer. */
2008static char *
2009func_evalctx (char *o, char **argv, const char *funcname UNUSED)
2010{
2011 char *buf;
2012 unsigned int len;
2013
2014 /* Eval the buffer. Pop the current variable buffer setting so that the
2015 eval'd code can use its own without conflicting. */
2016
2017 install_variable_buffer (&buf, &len);
2018
2019 push_new_variable_scope ();
2020
2021 eval_buffer (argv[0], strchr (argv[0], '\0'));
2022
2023 pop_variable_scope ();
2024
2025 restore_variable_buffer (buf, len);
2026
2027 return o;
2028}
2029
2030/* A mix of func_eval and func_value, saves memory for the expansion.
2031 This implements both evalval and evalvalctx, the latter has its own
2032 variable context just like evalctx. */
2033static char *
2034func_evalval (char *o, char **argv, const char *funcname)
2035{
2036 /* Look up the variable. */
2037 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
2038 if (v)
2039 {
2040 char *buf;
2041 unsigned int len;
2042 int var_ctx;
2043 size_t off;
2044 const struct floc *reading_file_saved = reading_file;
2045#ifdef CONFIG_WITH_MAKE_STATS
2046 unsigned long long uStartTick = CURRENT_CLOCK_TICK();
2047 MAKE_STATS_2(v->cEvalVals++);
2048#endif
2049
2050 /* Make a copy of the value to the variable buffer since
2051 eval_buffer will make changes to its input. */
2052
2053 off = o - variable_buffer;
2054 variable_buffer_output (o, v->value, v->value_length + 1);
2055 o = variable_buffer + off;
2056
2057 /* Eval the value. Pop the current variable buffer setting so that the
2058 eval'd code can use its own without conflicting. (really necessary?) */
2059
2060 install_variable_buffer (&buf, &len);
2061 var_ctx = !strcmp (funcname, "evalvalctx");
2062 if (var_ctx)
2063 push_new_variable_scope ();
2064 if (v->fileinfo.filenm)
2065 reading_file = &v->fileinfo;
2066
2067 assert (!o[v->value_length]);
2068 eval_buffer (o, o + v->value_length);
2069
2070 reading_file = reading_file_saved;
2071 if (var_ctx)
2072 pop_variable_scope ();
2073 restore_variable_buffer (buf, len);
2074
2075 MAKE_STATS_2(v->cTicksEvalVal += CURRENT_CLOCK_TICK() - uStartTick);
2076 }
2077
2078 return o;
2079}
2080
2081/* Optimizes the content of one or more variables to save time in
2082 the eval functions. This function will collapse line continuations
2083 and remove comments. */
2084static char *
2085func_eval_optimize_variable (char *o, char **argv, const char *funcname)
2086{
2087 unsigned int i;
2088
2089 for (i = 0; argv[i]; i++)
2090 {
2091 struct variable *v = lookup_variable (argv[i], strlen (argv[i]));
2092# ifdef CONFIG_WITH_RDONLY_VARIABLE_VALUE
2093 if (v && !v->origin != o_automatic && !v->rdonly_val)
2094# else
2095 if (v && !v->origin != o_automatic)
2096# endif
2097 {
2098 char *eos, *src;
2099
2100 eos = collapse_continuations (v->value, v->value_length);
2101 v->value_length = eos - v->value;
2102
2103 /* remove comments */
2104
2105 src = memchr (v->value, '#', v->value_length);
2106 if (src)
2107 {
2108 unsigned char ch = '\0';
2109 char *dst = src;
2110 do
2111 {
2112 /* drop blanks preceeding the comment */
2113 while (dst > v->value)
2114 {
2115 ch = (unsigned char)dst[-1];
2116 if (!isblank (ch))
2117 break;
2118 dst--;
2119 }
2120
2121 /* advance SRC to eol / eos. */
2122 src = memchr (src, '\n', eos - src);
2123 if (!src)
2124 break;
2125
2126 /* drop a preceeding newline if possible (full line comment) */
2127 if (dst > v->value && dst[-1] == '\n')
2128 dst--;
2129
2130 /* copy till next comment or eol. */
2131 while (src < eos)
2132 {
2133 ch = *src++;
2134 if (ch == '#')
2135 break;
2136 *dst++ = ch;
2137 }
2138 }
2139 while (ch == '#' && src < eos);
2140
2141 *dst = '\0';
2142 v->value_length = dst - v->value;
2143 }
2144 }
2145 else if (v)
2146 error (NILF, _("$(%s ): variable `%s' is of the wrong type\n"), funcname, v->name);
2147 }
2148
2149 return o;
2150}
2151
2152#endif /* CONFIG_WITH_EVALPLUS */
2153
2154static char *
2155func_value (char *o, char **argv, const char *funcname UNUSED)
2156{
2157 /* Look up the variable. */
2158 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
2159
2160 /* Copy its value into the output buffer without expanding it. */
2161 if (v)
2162#ifdef CONFIG_WITH_VALUE_LENGTH
2163 {
2164 assert (v->value_length == strlen (v->value));
2165 o = variable_buffer_output (o, v->value, v->value_length);
2166 }
2167#else
2168 o = variable_buffer_output (o, v->value, strlen(v->value));
2169#endif
2170
2171 return o;
2172}
2173
2174/*
2175 \r is replaced on UNIX as well. Is this desirable?
2176 */
2177static void
2178fold_newlines (char *buffer, unsigned int *length)
2179{
2180 char *dst = buffer;
2181 char *src = buffer;
2182 char *last_nonnl = buffer -1;
2183 src[*length] = 0;
2184 for (; *src != '\0'; ++src)
2185 {
2186 if (src[0] == '\r' && src[1] == '\n')
2187 continue;
2188 if (*src == '\n')
2189 {
2190 *dst++ = ' ';
2191 }
2192 else
2193 {
2194 last_nonnl = dst;
2195 *dst++ = *src;
2196 }
2197 }
2198 *(++last_nonnl) = '\0';
2199 *length = last_nonnl - buffer;
2200}
2201
2202
2203
2204int shell_function_pid = 0, shell_function_completed;
2205
2206
2207#ifdef WINDOWS32
2208/*untested*/
2209
2210#include <windows.h>
2211#include <io.h>
2212#include "sub_proc.h"
2213
2214
2215void
2216windows32_openpipe (int *pipedes, pid_t *pid_p, char **command_argv, char **envp)
2217{
2218 SECURITY_ATTRIBUTES saAttr;
2219 HANDLE hIn;
2220 HANDLE hErr;
2221 HANDLE hChildOutRd;
2222 HANDLE hChildOutWr;
2223 HANDLE hProcess;
2224
2225
2226 saAttr.nLength = sizeof (SECURITY_ATTRIBUTES);
2227 saAttr.bInheritHandle = TRUE;
2228 saAttr.lpSecurityDescriptor = NULL;
2229
2230 if (DuplicateHandle (GetCurrentProcess(),
2231 GetStdHandle(STD_INPUT_HANDLE),
2232 GetCurrentProcess(),
2233 &hIn,
2234 0,
2235 TRUE,
2236 DUPLICATE_SAME_ACCESS) == FALSE) {
2237 fatal (NILF, _("windows32_openpipe(): DuplicateHandle(In) failed (e=%ld)\n"),
2238 GetLastError());
2239
2240 }
2241 if (DuplicateHandle(GetCurrentProcess(),
2242 GetStdHandle(STD_ERROR_HANDLE),
2243 GetCurrentProcess(),
2244 &hErr,
2245 0,
2246 TRUE,
2247 DUPLICATE_SAME_ACCESS) == FALSE) {
2248 fatal (NILF, _("windows32_open_pipe(): DuplicateHandle(Err) failed (e=%ld)\n"),
2249 GetLastError());
2250 }
2251
2252 if (!CreatePipe(&hChildOutRd, &hChildOutWr, &saAttr, 0))
2253 fatal (NILF, _("CreatePipe() failed (e=%ld)\n"), GetLastError());
2254
2255 hProcess = process_init_fd(hIn, hChildOutWr, hErr);
2256
2257 if (!hProcess)
2258 fatal (NILF, _("windows32_openpipe(): process_init_fd() failed\n"));
2259
2260 /* make sure that CreateProcess() has Path it needs */
2261 sync_Path_environment();
2262 /* `sync_Path_environment' may realloc `environ', so take note of
2263 the new value. */
2264 envp = environ;
2265
2266 if (!process_begin(hProcess, command_argv, envp, command_argv[0], NULL)) {
2267 /* register process for wait */
2268 process_register(hProcess);
2269
2270 /* set the pid for returning to caller */
2271 *pid_p = (pid_t) hProcess;
2272
2273 /* set up to read data from child */
2274 pipedes[0] = _open_osfhandle((intptr_t) hChildOutRd, O_RDONLY);
2275
2276 /* this will be closed almost right away */
2277 pipedes[1] = _open_osfhandle((intptr_t) hChildOutWr, O_APPEND);
2278 } else {
2279 /* reap/cleanup the failed process */
2280 process_cleanup(hProcess);
2281
2282 /* close handles which were duplicated, they weren't used */
2283 CloseHandle(hIn);
2284 CloseHandle(hErr);
2285
2286 /* close pipe handles, they won't be used */
2287 CloseHandle(hChildOutRd);
2288 CloseHandle(hChildOutWr);
2289
2290 /* set status for return */
2291 pipedes[0] = pipedes[1] = -1;
2292 *pid_p = (pid_t)-1;
2293 }
2294}
2295#endif
2296
2297
2298#ifdef __MSDOS__
2299FILE *
2300msdos_openpipe (int* pipedes, int *pidp, char *text)
2301{
2302 FILE *fpipe=0;
2303 /* MSDOS can't fork, but it has `popen'. */
2304 struct variable *sh = lookup_variable ("SHELL", 5);
2305 int e;
2306 extern int dos_command_running, dos_status;
2307
2308 /* Make sure not to bother processing an empty line. */
2309 while (isblank ((unsigned char)*text))
2310 ++text;
2311 if (*text == '\0')
2312 return 0;
2313
2314 if (sh)
2315 {
2316 char buf[PATH_MAX + 7];
2317 /* This makes sure $SHELL value is used by $(shell), even
2318 though the target environment is not passed to it. */
2319 sprintf (buf, "SHELL=%s", sh->value);
2320 putenv (buf);
2321 }
2322
2323 e = errno;
2324 errno = 0;
2325 dos_command_running = 1;
2326 dos_status = 0;
2327 /* If dos_status becomes non-zero, it means the child process
2328 was interrupted by a signal, like SIGINT or SIGQUIT. See
2329 fatal_error_signal in commands.c. */
2330 fpipe = popen (text, "rt");
2331 dos_command_running = 0;
2332 if (!fpipe || dos_status)
2333 {
2334 pipedes[0] = -1;
2335 *pidp = -1;
2336 if (dos_status)
2337 errno = EINTR;
2338 else if (errno == 0)
2339 errno = ENOMEM;
2340 shell_function_completed = -1;
2341 }
2342 else
2343 {
2344 pipedes[0] = fileno (fpipe);
2345 *pidp = 42; /* Yes, the Meaning of Life, the Universe, and Everything! */
2346 errno = e;
2347 shell_function_completed = 1;
2348 }
2349 return fpipe;
2350}
2351#endif
2352
2353/*
2354 Do shell spawning, with the naughty bits for different OSes.
2355 */
2356
2357#ifdef VMS
2358
2359/* VMS can't do $(shell ...) */
2360#define func_shell 0
2361
2362#else
2363#ifndef _AMIGA
2364static char *
2365func_shell (char * volatile o, char **argv, const char *funcname UNUSED)
2366{
2367 char *batch_filename = NULL;
2368
2369#ifdef __MSDOS__
2370 FILE *fpipe;
2371#endif
2372 char **command_argv;
2373 const char * volatile error_prefix; /* bird: this volatile and the 'o' one, is for shutting up gcc warnings */
2374 char **envp;
2375 int pipedes[2];
2376 pid_t pid;
2377
2378#ifndef __MSDOS__
2379 /* Construct the argument list. */
2380 command_argv = construct_command_argv (argv[0], NULL, NULL, 0,
2381 &batch_filename);
2382 if (command_argv == 0)
2383 return o;
2384#endif
2385
2386 /* Using a target environment for `shell' loses in cases like:
2387 export var = $(shell echo foobie)
2388 because target_environment hits a loop trying to expand $(var)
2389 to put it in the environment. This is even more confusing when
2390 var was not explicitly exported, but just appeared in the
2391 calling environment.
2392
2393 See Savannah bug #10593.
2394
2395 envp = target_environment (NILF);
2396 */
2397
2398 envp = environ;
2399
2400 /* For error messages. */
2401 if (reading_file && reading_file->filenm)
2402 {
2403 char *p = alloca (strlen (reading_file->filenm)+11+4);
2404 sprintf (p, "%s:%lu: ", reading_file->filenm, reading_file->lineno);
2405 error_prefix = p;
2406 }
2407 else
2408 error_prefix = "";
2409
2410#if defined(__MSDOS__)
2411 fpipe = msdos_openpipe (pipedes, &pid, argv[0]);
2412 if (pipedes[0] < 0)
2413 {
2414 perror_with_name (error_prefix, "pipe");
2415 return o;
2416 }
2417#elif defined(WINDOWS32)
2418 windows32_openpipe (pipedes, &pid, command_argv, envp);
2419 if (pipedes[0] < 0)
2420 {
2421 /* open of the pipe failed, mark as failed execution */
2422 shell_function_completed = -1;
2423
2424 return o;
2425 }
2426 else
2427#else
2428 if (pipe (pipedes) < 0)
2429 {
2430 perror_with_name (error_prefix, "pipe");
2431 return o;
2432 }
2433
2434# ifdef __EMX__
2435 /* close some handles that are unnecessary for the child process */
2436 CLOSE_ON_EXEC(pipedes[1]);
2437 CLOSE_ON_EXEC(pipedes[0]);
2438 /* Never use fork()/exec() here! Use spawn() instead in exec_command() */
2439 pid = child_execute_job (0, pipedes[1], command_argv, envp);
2440 if (pid < 0)
2441 perror_with_name (error_prefix, "spawn");
2442# else /* ! __EMX__ */
2443 pid = vfork ();
2444 if (pid < 0)
2445 perror_with_name (error_prefix, "fork");
2446 else if (pid == 0)
2447 child_execute_job (0, pipedes[1], command_argv, envp);
2448 else
2449# endif
2450#endif
2451 {
2452 /* We are the parent. */
2453 char *buffer;
2454 unsigned int maxlen, i;
2455 int cc;
2456
2457 /* Record the PID for reap_children. */
2458 shell_function_pid = pid;
2459#ifndef __MSDOS__
2460 shell_function_completed = 0;
2461
2462 /* Free the storage only the child needed. */
2463 free (command_argv[0]);
2464 free (command_argv);
2465
2466 /* Close the write side of the pipe. We test for -1, since
2467 pipedes[1] is -1 on MS-Windows, and some versions of MS
2468 libraries barf when `close' is called with -1. */
2469 if (pipedes[1] >= 0)
2470 close (pipedes[1]);
2471#endif
2472
2473 /* Set up and read from the pipe. */
2474
2475 maxlen = 200;
2476 buffer = xmalloc (maxlen + 1);
2477
2478 /* Read from the pipe until it gets EOF. */
2479 for (i = 0; ; i += cc)
2480 {
2481 if (i == maxlen)
2482 {
2483 maxlen += 512;
2484 buffer = xrealloc (buffer, maxlen + 1);
2485 }
2486
2487 EINTRLOOP (cc, read (pipedes[0], &buffer[i], maxlen - i));
2488 if (cc <= 0)
2489 break;
2490 }
2491 buffer[i] = '\0';
2492
2493 /* Close the read side of the pipe. */
2494#ifdef __MSDOS__
2495 if (fpipe)
2496 (void) pclose (fpipe);
2497#else
2498# ifdef _MSC_VER /* Avoid annoying msvcrt when debugging. (bird) */
2499 if (pipedes[0] != -1)
2500# endif
2501 (void) close (pipedes[0]);
2502#endif
2503
2504 /* Loop until child_handler or reap_children() sets
2505 shell_function_completed to the status of our child shell. */
2506 while (shell_function_completed == 0)
2507 reap_children (1, 0);
2508
2509 if (batch_filename) {
2510 DB (DB_VERBOSE, (_("Cleaning up temporary batch file %s\n"),
2511 batch_filename));
2512 remove (batch_filename);
2513 free (batch_filename);
2514 }
2515 shell_function_pid = 0;
2516
2517 /* The child_handler function will set shell_function_completed
2518 to 1 when the child dies normally, or to -1 if it
2519 dies with status 127, which is most likely an exec fail. */
2520
2521 if (shell_function_completed == -1)
2522 {
2523 /* This likely means that the execvp failed, so we should just
2524 write the error message in the pipe from the child. */
2525 fputs (buffer, stderr);
2526 fflush (stderr);
2527 }
2528 else
2529 {
2530 /* The child finished normally. Replace all newlines in its output
2531 with spaces, and put that in the variable output buffer. */
2532 fold_newlines (buffer, &i);
2533 o = variable_buffer_output (o, buffer, i);
2534 }
2535
2536 free (buffer);
2537 }
2538
2539 return o;
2540}
2541
2542#else /* _AMIGA */
2543
2544/* Do the Amiga version of func_shell. */
2545
2546static char *
2547func_shell (char *o, char **argv, const char *funcname)
2548{
2549 /* Amiga can't fork nor spawn, but I can start a program with
2550 redirection of my choice. However, this means that we
2551 don't have an opportunity to reopen stdout to trap it. Thus,
2552 we save our own stdout onto a new descriptor and dup a temp
2553 file's descriptor onto our stdout temporarily. After we
2554 spawn the shell program, we dup our own stdout back to the
2555 stdout descriptor. The buffer reading is the same as above,
2556 except that we're now reading from a file. */
2557
2558#include <dos/dos.h>
2559#include <proto/dos.h>
2560
2561 BPTR child_stdout;
2562 char tmp_output[FILENAME_MAX];
2563 unsigned int maxlen = 200, i;
2564 int cc;
2565 char * buffer, * ptr;
2566 char ** aptr;
2567 int len = 0;
2568 char* batch_filename = NULL;
2569
2570 /* Construct the argument list. */
2571 command_argv = construct_command_argv (argv[0], NULL, NULL, 0,
2572 &batch_filename);
2573 if (command_argv == 0)
2574 return o;
2575
2576 /* Note the mktemp() is a security hole, but this only runs on Amiga.
2577 Ideally we would use main.c:open_tmpfile(), but this uses a special
2578 Open(), not fopen(), and I'm not familiar enough with the code to mess
2579 with it. */
2580 strcpy (tmp_output, "t:MakeshXXXXXXXX");
2581 mktemp (tmp_output);
2582 child_stdout = Open (tmp_output, MODE_NEWFILE);
2583
2584 for (aptr=command_argv; *aptr; aptr++)
2585 len += strlen (*aptr) + 1;
2586
2587 buffer = xmalloc (len + 1);
2588 ptr = buffer;
2589
2590 for (aptr=command_argv; *aptr; aptr++)
2591 {
2592 strcpy (ptr, *aptr);
2593 ptr += strlen (ptr) + 1;
2594 *ptr ++ = ' ';
2595 *ptr = 0;
2596 }
2597
2598 ptr[-1] = '\n';
2599
2600 Execute (buffer, NULL, child_stdout);
2601 free (buffer);
2602
2603 Close (child_stdout);
2604
2605 child_stdout = Open (tmp_output, MODE_OLDFILE);
2606
2607 buffer = xmalloc (maxlen);
2608 i = 0;
2609 do
2610 {
2611 if (i == maxlen)
2612 {
2613 maxlen += 512;
2614 buffer = xrealloc (buffer, maxlen + 1);
2615 }
2616
2617 cc = Read (child_stdout, &buffer[i], maxlen - i);
2618 if (cc > 0)
2619 i += cc;
2620 } while (cc > 0);
2621
2622 Close (child_stdout);
2623
2624 fold_newlines (buffer, &i);
2625 o = variable_buffer_output (o, buffer, i);
2626 free (buffer);
2627 return o;
2628}
2629#endif /* _AMIGA */
2630#endif /* !VMS */
2631
2632#ifdef EXPERIMENTAL
2633
2634/*
2635 equality. Return is string-boolean, ie, the empty string is false.
2636 */
2637static char *
2638func_eq (char *o, char **argv, const char *funcname UNUSED)
2639{
2640 int result = ! strcmp (argv[0], argv[1]);
2641 o = variable_buffer_output (o, result ? "1" : "", result);
2642 return o;
2643}
2644
2645
2646/*
2647 string-boolean not operator.
2648 */
2649static char *
2650func_not (char *o, char **argv, const char *funcname UNUSED)
2651{
2652 const char *s = argv[0];
2653 int result = 0;
2654 while (isspace ((unsigned char)*s))
2655 s++;
2656 result = ! (*s);
2657 o = variable_buffer_output (o, result ? "1" : "", result);
2658 return o;
2659}
2660#endif
2661
2662
2663#ifdef CONFIG_WITH_STRING_FUNCTIONS
2664/*
2665 $(length string)
2666
2667 XXX: This doesn't take multibyte locales into account.
2668 */
2669static char *
2670func_length (char *o, char **argv, const char *funcname UNUSED)
2671{
2672 size_t len = strlen (argv[0]);
2673 return math_int_to_variable_buffer (o, len);
2674}
2675
2676/*
2677 $(length-var var)
2678
2679 XXX: This doesn't take multibyte locales into account.
2680 */
2681static char *
2682func_length_var (char *o, char **argv, const char *funcname UNUSED)
2683{
2684 struct variable *var = lookup_variable (argv[0], strlen (argv[0]));
2685 return math_int_to_variable_buffer (o, var ? var->value_length : 0);
2686}
2687
2688
2689/* func_insert and func_substr helper. */
2690static char *
2691helper_pad (char *o, size_t to_add, const char *pad, size_t pad_len)
2692{
2693 while (to_add > 0)
2694 {
2695 size_t size = to_add > pad_len ? pad_len : to_add;
2696 o = variable_buffer_output (o, pad, size);
2697 to_add -= size;
2698 }
2699 return o;
2700}
2701
2702/*
2703 $(insert in, str[, n[, length[, pad]]])
2704
2705 XXX: This doesn't take multibyte locales into account.
2706 */
2707static char *
2708func_insert (char *o, char **argv, const char *funcname UNUSED)
2709{
2710 const char *in = argv[0];
2711 math_int in_len = (math_int)strlen (in);
2712 const char *str = argv[1];
2713 math_int str_len = (math_int)strlen (str);
2714 math_int n = 0;
2715 math_int length = str_len;
2716 const char *pad = " ";
2717 size_t pad_len = 16;
2718 size_t i;
2719
2720 if (argv[2] != NULL)
2721 {
2722 n = math_int_from_string (argv[2]);
2723 if (n > 0)
2724 n--; /* one-origin */
2725 else if (n == 0)
2726 n = str_len; /* append */
2727 else
2728 { /* n < 0: from the end */
2729 n = str_len + n;
2730 if (n < 0)
2731 n = 0;
2732 }
2733 if (n > 16*1024*1024) /* 16MB */
2734 fatal (NILF, _("$(insert ): n=%s is out of bounds\n"), argv[2]);
2735
2736 if (argv[3] != NULL)
2737 {
2738 length = math_int_from_string (argv[3]);
2739 if (length < 0 || length > 16*1024*1024 /* 16MB */)
2740 fatal (NILF, _("$(insert ): length=%s is out of bounds\n"), argv[3]);
2741
2742 if (argv[4] != NULL)
2743 {
2744 const char *tmp = argv[4];
2745 for (i = 0; tmp[i] == ' '; i++)
2746 /* nothing */;
2747 if (tmp[i] != '\0')
2748 {
2749 pad = argv[4];
2750 pad_len = strlen (pad);
2751 }
2752 /* else: it was all default spaces. */
2753 }
2754 }
2755 }
2756
2757 /* the head of the original string */
2758 if (n > 0)
2759 {
2760 if (n <= str_len)
2761 o = variable_buffer_output (o, str, n);
2762 else
2763 {
2764 o = variable_buffer_output (o, str, str_len);
2765 o = helper_pad (o, n - str_len, pad, pad_len);
2766 }
2767 }
2768
2769 /* insert the string */
2770 if (length <= in_len)
2771 o = variable_buffer_output (o, in, length);
2772 else
2773 {
2774 o = variable_buffer_output (o, in, in_len);
2775 o = helper_pad (o, length - in_len, pad, pad_len);
2776 }
2777
2778 /* the tail of the original string */
2779 if (n < str_len)
2780 o = variable_buffer_output (o, str + n, str_len - n);
2781
2782 return o;
2783}
2784
2785
2786/*
2787 $(pos needle, haystack[, start])
2788 $(lastpos needle, haystack[, start])
2789
2790 XXX: This doesn't take multibyte locales into account.
2791 */
2792static char *
2793func_pos (char *o, char **argv, const char *funcname UNUSED)
2794{
2795 const char *needle = *argv[0] ? argv[0] : " ";
2796 size_t needle_len = strlen (needle);
2797 const char *haystack = argv[1];
2798 size_t haystack_len = strlen (haystack);
2799 math_int start = 0;
2800 const char *hit;
2801
2802 if (argv[2] != NULL)
2803 {
2804 start = math_int_from_string (argv[2]);
2805 if (start > 0)
2806 start--; /* one-origin */
2807 else if (start < 0)
2808 start = haystack_len + start; /* from the end */
2809 if (start < 0 || start + needle_len > haystack_len)
2810 return math_int_to_variable_buffer (o, 0);
2811 }
2812 else if (funcname[0] == 'l')
2813 start = haystack_len - 1;
2814
2815 /* do the searching */
2816 if (funcname[0] != 'l')
2817 { /* pos */
2818 if (needle_len == 1)
2819 hit = strchr (haystack + start, *needle);
2820 else
2821 hit = strstr (haystack + start, needle);
2822 }
2823 else
2824 { /* last pos */
2825 int ch = *needle;
2826 size_t off = start + 1;
2827
2828 hit = NULL;
2829 while (off-- > 0)
2830 {
2831 if ( haystack[off] == ch
2832 && ( needle_len == 1
2833 || strncmp (&haystack[off], needle, needle_len) == 0))
2834 {
2835 hit = haystack + off;
2836 break;
2837 }
2838 }
2839 }
2840
2841 return math_int_to_variable_buffer (o, hit ? hit - haystack + 1 : 0);
2842}
2843
2844
2845/*
2846 $(substr str, start[, length[, pad]])
2847
2848 XXX: This doesn't take multibyte locales into account.
2849 */
2850static char *
2851func_substr (char *o, char **argv, const char *funcname UNUSED)
2852{
2853 const char *str = argv[0];
2854 math_int str_len = (math_int)strlen (str);
2855 math_int start = math_int_from_string (argv[1]);
2856 math_int length = 0;
2857 const char *pad = NULL;
2858 size_t pad_len = 0;
2859
2860 if (argv[2] != NULL)
2861 {
2862 if (argv[3] != NULL)
2863 {
2864 pad = argv[3];
2865 for (pad_len = 0; pad[pad_len] == ' '; pad_len++)
2866 /* nothing */;
2867 if (pad[pad_len] != '\0')
2868 pad_len = strlen (pad);
2869 else
2870 {
2871 pad = " ";
2872 pad_len = 16;
2873 }
2874 }
2875 length = math_int_from_string (argv[2]);
2876 if (pad != NULL && length > 16*1024*1024 /* 16MB */)
2877 fatal (NILF, _("$(substr ): length=%s is out of bounds\n"), argv[2]);
2878 if (pad != NULL && length < 0)
2879 fatal (NILF, _("$(substr ): negative length (%s) and padding doesn't mix.\n"), argv[2]);
2880 if (length == 0)
2881 return o;
2882 }
2883
2884 /* Note that negative start is and length are used for referencing from the
2885 end of the string. */
2886 if (pad == NULL)
2887 {
2888 if (start > 0)
2889 start--; /* one-origin */
2890 else
2891 {
2892 start = str_len + start;
2893 if (start <= 0)
2894 {
2895 if (length < 0)
2896 return o;
2897 start += length;
2898 if (start <= 0)
2899 return o;
2900 length = start;
2901 start = 0;
2902 }
2903 }
2904
2905 if (start >= str_len)
2906 return o;
2907 if (length == 0)
2908 length = str_len - start;
2909 else if (length < 0)
2910 {
2911 if (str_len <= -length)
2912 return o;
2913 length += str_len;
2914 if (length <= start)
2915 return o;
2916 length -= start;
2917 }
2918 else if (start + length > str_len)
2919 length = str_len - start;
2920
2921 o = variable_buffer_output (o, str + start, length);
2922 }
2923 else
2924 {
2925 if (start > 0)
2926 {
2927 start--; /* one-origin */
2928 if (start >= str_len)
2929 return length ? helper_pad (o, length, pad, pad_len) : o;
2930 if (length == 0)
2931 length = str_len - start;
2932 }
2933 else
2934 {
2935 start = str_len + start;
2936 if (start <= 0)
2937 {
2938 if (start + length <= 0)
2939 return length ? helper_pad (o, length, pad, pad_len) : o;
2940 o = helper_pad (o, -start, pad, pad_len);
2941 return variable_buffer_output (o, str, length + start);
2942 }
2943 if (length == 0)
2944 length = str_len - start;
2945 }
2946 if (start + length <= str_len)
2947 o = variable_buffer_output (o, str + start, length);
2948 else
2949 {
2950 o = variable_buffer_output (o, str + start, str_len - start);
2951 o = helper_pad (o, start + length - str_len, pad, pad_len);
2952 }
2953 }
2954
2955 return o;
2956}
2957
2958
2959/*
2960 $(translate string, from-set[, to-set[, pad-char]])
2961
2962 XXX: This doesn't take multibyte locales into account.
2963 */
2964static char *
2965func_translate (char *o, char **argv, const char *funcname UNUSED)
2966{
2967 const unsigned char *str = (const unsigned char *)argv[0];
2968 const unsigned char *from_set = (const unsigned char *)argv[1];
2969 const char *to_set = argv[2] != NULL ? argv[2] : "";
2970 char trans_tab[1 << CHAR_BIT];
2971 int i;
2972 char ch;
2973
2974 /* init the array. */
2975 for (i = 0; i < (1 << CHAR_BIT); i++)
2976 trans_tab[i] = i;
2977
2978 while ( (i = *from_set) != '\0'
2979 && (ch = *to_set) != '\0')
2980 {
2981 trans_tab[i] = ch;
2982 from_set++;
2983 to_set++;
2984 }
2985
2986 if (i != '\0')
2987 {
2988 ch = '\0'; /* no padding == remove char */
2989 if (argv[2] != NULL && argv[3] != NULL)
2990 {
2991 ch = argv[3][0];
2992 if (ch && argv[3][1])
2993 fatal (NILF, _("$(translate ): pad=`%s' expected a single char\n"), argv[3]);
2994 if (ch == '\0') /* no char == space */
2995 ch = ' ';
2996 }
2997 while ((i = *from_set++) != '\0')
2998 trans_tab[i] = ch;
2999 }
3000
3001 /* do the translation */
3002 while ((i = *str++) != '\0')
3003 {
3004 ch = trans_tab[i];
3005 if (ch)
3006 o = variable_buffer_output (o, &ch, 1);
3007 }
3008
3009 return o;
3010}
3011#endif /* CONFIG_WITH_STRING_FUNCTIONS */
3012
3013
3014#ifdef CONFIG_WITH_LAZY_DEPS_VARS
3015
3016/* This is also in file.c (bad). */
3017# if VMS
3018# define FILE_LIST_SEPARATOR ','
3019# else
3020# define FILE_LIST_SEPARATOR ' '
3021# endif
3022
3023/* Implements $^ and $+.
3024
3025 The first comes with FUNCNAME 'deps', the second as 'deps-all'.
3026
3027 If no second argument is given, or if it's empty, or if it's zero,
3028 all dependencies will be returned. If the second argument is non-zero
3029 the dependency at that position will be returned. If the argument is
3030 negative a fatal error is thrown. */
3031static char *
3032func_deps (char *o, char **argv, const char *funcname)
3033{
3034 unsigned int idx = 0;
3035 struct file *file;
3036
3037 /* Handle the argument if present. */
3038
3039 if (argv[1])
3040 {
3041 char *p = argv[1];
3042 while (isspace ((unsigned int)*p))
3043 p++;
3044 if (*p != '\0')
3045 {
3046 char *n;
3047 long l = strtol (p, &n, 0);
3048 while (isspace ((unsigned int)*n))
3049 n++;
3050 idx = l;
3051 if (*n != '\0' || l < 0 || (long)idx != l)
3052 fatal (NILF, _("%s: invalid index value: `%s'\n"), funcname, p);
3053 }
3054 }
3055
3056 /* Find the file and select the list corresponding to FUNCNAME. */
3057
3058 file = lookup_file (argv[0]);
3059 if (file)
3060 {
3061 struct dep *deps;
3062 struct dep *d;
3063 if (funcname[4] == '\0')
3064 {
3065 deps = file->deps_no_dupes;
3066 if (!deps && file->deps)
3067 deps = file->deps = create_uniqute_deps_chain (file->deps);
3068 }
3069 else
3070 deps = file->deps;
3071
3072 if ( file->double_colon
3073 && ( file->double_colon != file
3074 || file->last != file))
3075 error (NILF, _("$(%s ) cannot be used on files with multiple double colon rules like `%s'\n"),
3076 funcname, file->name);
3077
3078 if (idx == 0 /* all */)
3079 {
3080 unsigned int total_len = 0;
3081
3082 /* calc the result length. */
3083
3084 for (d = deps; d; d = d->next)
3085 if (!d->ignore_mtime)
3086 {
3087 const char *c = dep_name (d);
3088
3089#ifndef NO_ARCHIVES
3090 if (ar_name (c))
3091 {
3092 c = strchr (c, '(') + 1;
3093 total_len += strlen (c);
3094 }
3095 else
3096#elif defined (CONFIG_WITH_STRCACHE2)
3097 total_len += strcache2_get_len (&file_strcache, c) + 1;
3098#else
3099 total_len += strlen (c) + 1;
3100#endif
3101 }
3102
3103 if (total_len)
3104 {
3105 /* prepare the variable buffer dude wrt to the output size and
3106 pass along the strings. */
3107
3108 o = variable_buffer_output (o + total_len, "", 0) - total_len; /* a hack */
3109
3110 for (d = deps; d; d = d->next)
3111 if (!d->ignore_mtime)
3112 {
3113 unsigned int len;
3114 const char *c = dep_name (d);
3115
3116#ifndef NO_ARCHIVES
3117 if (ar_name (c))
3118 {
3119 c = strchr (c, '(') + 1;
3120 len = strlen (c);
3121 }
3122 else
3123#elif defined (CONFIG_WITH_STRCACHE2)
3124 len = strcache2_get_len (&file_strcache, c) + 1;
3125#else
3126 len = strlen (c) + 1;
3127#endif
3128 o = variable_buffer_output (o, c, len);
3129 o[-1] = FILE_LIST_SEPARATOR;
3130 }
3131
3132 --o; /* nuke the last list separator */
3133 *o = '\0';
3134 }
3135 }
3136 else
3137 {
3138 /* Dependency given by index. */
3139
3140 for (d = deps; d; d = d->next)
3141 if (!d->ignore_mtime)
3142 {
3143 if (--idx == 0) /* 1 based indexing */
3144 {
3145 unsigned int len;
3146 const char *c = dep_name (d);
3147
3148#ifndef NO_ARCHIVES
3149 if (ar_name (c))
3150 {
3151 c = strchr (c, '(') + 1;
3152 len = strlen (c) - 1;
3153 }
3154 else
3155#elif defined (CONFIG_WITH_STRCACHE2)
3156 len = strcache2_get_len (&file_strcache, c);
3157#else
3158 len = strlen (c);
3159#endif
3160 o = variable_buffer_output (o, c, len);
3161 break;
3162 }
3163 }
3164 }
3165 }
3166
3167 return o;
3168}
3169
3170/* Implements $?.
3171
3172 If no second argument is given, or if it's empty, or if it's zero,
3173 all dependencies will be returned. If the second argument is non-zero
3174 the dependency at that position will be returned. If the argument is
3175 negative a fatal error is thrown. */
3176static char *
3177func_deps_newer (char *o, char **argv, const char *funcname)
3178{
3179 unsigned int idx = 0;
3180 struct file *file;
3181
3182 /* Handle the argument if present. */
3183
3184 if (argv[1])
3185 {
3186 char *p = argv[1];
3187 while (isspace ((unsigned int)*p))
3188 p++;
3189 if (*p != '\0')
3190 {
3191 char *n;
3192 long l = strtol (p, &n, 0);
3193 while (isspace ((unsigned int)*n))
3194 n++;
3195 idx = l;
3196 if (*n != '\0' || l < 0 || (long)idx != l)
3197 fatal (NILF, _("%s: invalid index value: `%s'\n"), funcname, p);
3198 }
3199 }
3200
3201 /* Find the file. */
3202
3203 file = lookup_file (argv[0]);
3204 if (file)
3205 {
3206 struct dep *deps = file->deps;
3207 struct dep *d;
3208
3209 if ( file->double_colon
3210 && ( file->double_colon != file
3211 || file->last != file))
3212 error (NILF, _("$(%s ) cannot be used on files with multiple double colon rules like `%s'\n"),
3213 funcname, file->name);
3214
3215 if (idx == 0 /* all */)
3216 {
3217 unsigned int total_len = 0;
3218
3219 /* calc the result length. */
3220
3221 for (d = deps; d; d = d->next)
3222 if (!d->ignore_mtime && d->changed)
3223 {
3224 const char *c = dep_name (d);
3225
3226#ifndef NO_ARCHIVES
3227 if (ar_name (c))
3228 {
3229 c = strchr (c, '(') + 1;
3230 total_len += strlen (c);
3231 }
3232 else
3233#elif defined (CONFIG_WITH_STRCACHE2)
3234 total_len += strcache2_get_len (&file_strcache, c) + 1;
3235#else
3236 total_len += strlen (c) + 1;
3237#endif
3238 }
3239
3240 if (total_len)
3241 {
3242 /* prepare the variable buffer dude wrt to the output size and
3243 pass along the strings. */
3244
3245 o = variable_buffer_output (o + total_len, "", 0) - total_len; /* a hack */
3246
3247 for (d = deps; d; d = d->next)
3248 if (!d->ignore_mtime && d->changed)
3249 {
3250 unsigned int len;
3251 const char *c = dep_name (d);
3252
3253#ifndef NO_ARCHIVES
3254 if (ar_name (c))
3255 {
3256 c = strchr (c, '(') + 1;
3257 len = strlen (c);
3258 }
3259 else
3260#elif defined (CONFIG_WITH_STRCACHE2)
3261 len = strcache2_get_len (&file_strcache, c) + 1;
3262#else
3263 len = strlen (c) + 1;
3264#endif
3265 o = variable_buffer_output (o, c, len);
3266 o[-1] = FILE_LIST_SEPARATOR;
3267 }
3268
3269 --o; /* nuke the last list separator */
3270 *o = '\0';
3271 }
3272 }
3273 else
3274 {
3275 /* Dependency given by index. */
3276
3277 for (d = deps; d; d = d->next)
3278 if (!d->ignore_mtime && d->changed)
3279 {
3280 if (--idx == 0) /* 1 based indexing */
3281 {
3282 unsigned int len;
3283 const char *c = dep_name (d);
3284
3285#ifndef NO_ARCHIVES
3286 if (ar_name (c))
3287 {
3288 c = strchr (c, '(') + 1;
3289 len = strlen (c) - 1;
3290 }
3291 else
3292#elif defined (CONFIG_WITH_STRCACHE2)
3293 len = strcache2_get_len (&file_strcache, c);
3294#else
3295 len = strlen (c);
3296#endif
3297 o = variable_buffer_output (o, c, len);
3298 break;
3299 }
3300 }
3301 }
3302 }
3303
3304 return o;
3305}
3306
3307/* Implements $|, the order only dependency list.
3308
3309 If no second argument is given, or if it's empty, or if it's zero,
3310 all dependencies will be returned. If the second argument is non-zero
3311 the dependency at that position will be returned. If the argument is
3312 negative a fatal error is thrown. */
3313static char *
3314func_deps_order_only (char *o, char **argv, const char *funcname)
3315{
3316 unsigned int idx = 0;
3317 struct file *file;
3318
3319 /* Handle the argument if present. */
3320
3321 if (argv[1])
3322 {
3323 char *p = argv[1];
3324 while (isspace ((unsigned int)*p))
3325 p++;
3326 if (*p != '\0')
3327 {
3328 char *n;
3329 long l = strtol (p, &n, 0);
3330 while (isspace ((unsigned int)*n))
3331 n++;
3332 idx = l;
3333 if (*n != '\0' || l < 0 || (long)idx != l)
3334 fatal (NILF, _("%s: invalid index value: `%s'\n"), funcname, p);
3335 }
3336 }
3337
3338 /* Find the file. */
3339
3340 file = lookup_file (argv[0]);
3341 if (file)
3342 {
3343 struct dep *deps = file->deps;
3344 struct dep *d;
3345
3346 if ( file->double_colon
3347 && ( file->double_colon != file
3348 || file->last != file))
3349 error (NILF, _("$(%s ) cannot be used on files with multiple double colon rules like `%s'\n"),
3350 funcname, file->name);
3351
3352 if (idx == 0 /* all */)
3353 {
3354 unsigned int total_len = 0;
3355
3356 /* calc the result length. */
3357
3358 for (d = deps; d; d = d->next)
3359 if (d->ignore_mtime)
3360 {
3361 const char *c = dep_name (d);
3362
3363#ifndef NO_ARCHIVES
3364 if (ar_name (c))
3365 {
3366 c = strchr (c, '(') + 1;
3367 total_len += strlen (c);
3368 }
3369 else
3370#elif defined (CONFIG_WITH_STRCACHE2)
3371 total_len += strcache2_get_len (&file_strcache, c) + 1;
3372#else
3373 total_len += strlen (c) + 1;
3374#endif
3375 }
3376
3377 if (total_len)
3378 {
3379 /* prepare the variable buffer dude wrt to the output size and
3380 pass along the strings. */
3381
3382 o = variable_buffer_output (o + total_len, "", 0) - total_len; /* a hack */
3383
3384 for (d = deps; d; d = d->next)
3385 if (d->ignore_mtime)
3386 {
3387 unsigned int len;
3388 const char *c = dep_name (d);
3389
3390#ifndef NO_ARCHIVES
3391 if (ar_name (c))
3392 {
3393 c = strchr (c, '(') + 1;
3394 len = strlen (c);
3395 }
3396 else
3397#elif defined (CONFIG_WITH_STRCACHE2)
3398 len = strcache2_get_len (&file_strcache, c) + 1;
3399#else
3400 len = strlen (c) + 1;
3401#endif
3402 o = variable_buffer_output (o, c, len);
3403 o[-1] = FILE_LIST_SEPARATOR;
3404 }
3405
3406 --o; /* nuke the last list separator */
3407 *o = '\0';
3408 }
3409 }
3410 else
3411 {
3412 /* Dependency given by index. */
3413
3414 for (d = deps; d; d = d->next)
3415 if (d->ignore_mtime)
3416 {
3417 if (--idx == 0) /* 1 based indexing */
3418 {
3419 unsigned int len;
3420 const char *c = dep_name (d);
3421
3422#ifndef NO_ARCHIVES
3423 if (ar_name (c))
3424 {
3425 c = strchr (c, '(') + 1;
3426 len = strlen (c) - 1;
3427 }
3428 else
3429#elif defined (CONFIG_WITH_STRCACHE2)
3430 len = strcache2_get_len (&file_strcache, c);
3431#else
3432 len = strlen (c);
3433#endif
3434 o = variable_buffer_output (o, c, len);
3435 break;
3436 }
3437 }
3438 }
3439 }
3440
3441 return o;
3442}
3443#endif /* CONFIG_WITH_LAZY_DEPS_VARS */
3444
3445
3446
3447#ifdef CONFIG_WITH_DEFINED
3448/* Similar to ifdef. */
3449static char *
3450func_defined (char *o, char **argv, const char *funcname UNUSED)
3451{
3452 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
3453 int result = v != NULL && *v->value != '\0';
3454 o = variable_buffer_output (o, result ? "1" : "", result);
3455 return o;
3456}
3457#endif /* CONFIG_WITH_DEFINED*/
3458
3459
3460
3461#ifdef HAVE_DOS_PATHS
3462#define IS_ABSOLUTE(n) (n[0] && n[1] == ':')
3463#define ROOT_LEN 3
3464#else
3465#define IS_ABSOLUTE(n) (n[0] == '/')
3466#define ROOT_LEN 1
3467#endif
3468
3469/* Return the absolute name of file NAME which does not contain any `.',
3470 `..' components nor any repeated path separators ('/'). */
3471#ifdef KMK
3472char *
3473#else
3474static char *
3475#endif
3476abspath (const char *name, char *apath)
3477{
3478 char *dest;
3479 const char *start, *end, *apath_limit;
3480 unsigned long root_len = ROOT_LEN;
3481
3482 if (name[0] == '\0' || apath == NULL)
3483 return NULL;
3484
3485#ifdef WINDOWS32 /* bird */
3486 dest = w32ify((char *)name, 1);
3487 if (!dest)
3488 return NULL;
3489 {
3490 size_t len = strlen(dest);
3491 memcpy(apath, dest, len);
3492 dest = apath + len;
3493 }
3494
3495 (void)end; (void)start; (void)apath_limit;
3496
3497#elif defined __OS2__ /* bird */
3498 if (_abspath(apath, name, GET_PATH_MAX))
3499 return NULL;
3500 dest = strchr(apath, '\0');
3501
3502 (void)end; (void)start; (void)apath_limit; (void)dest;
3503
3504#else /* !WINDOWS32 && !__OS2__ */
3505 apath_limit = apath + GET_PATH_MAX;
3506
3507 if (!IS_ABSOLUTE(name))
3508 {
3509 /* It is unlikely we would make it until here but just to make sure. */
3510 if (!starting_directory)
3511 return NULL;
3512
3513 strcpy (apath, starting_directory);
3514
3515#ifdef HAVE_DOS_PATHS
3516 if (IS_PATHSEP(name[0]))
3517 {
3518 if (IS_PATHSEP(name[1]))
3519 {
3520 /* A UNC. Don't prepend a drive letter. */
3521 apath[0] = name[0];
3522 apath[1] = name[1];
3523 root_len = 2;
3524 }
3525 /* We have /foo, an absolute file name except for the drive
3526 letter. Assume the missing drive letter is the current
3527 drive, which we can get if we remove from starting_directory
3528 everything past the root directory. */
3529 apath[root_len] = '\0';
3530 }
3531#endif
3532
3533 dest = strchr (apath, '\0');
3534 }
3535 else
3536 {
3537 strncpy (apath, name, root_len);
3538 apath[root_len] = '\0';
3539 dest = apath + root_len;
3540 /* Get past the root, since we already copied it. */
3541 name += root_len;
3542#ifdef HAVE_DOS_PATHS
3543 if (!IS_PATHSEP(apath[2]))
3544 {
3545 /* Convert d:foo into d:./foo and increase root_len. */
3546 apath[2] = '.';
3547 apath[3] = '/';
3548 dest++;
3549 root_len++;
3550 /* strncpy above copied one character too many. */
3551 name--;
3552 }
3553 else
3554 apath[2] = '/'; /* make sure it's a forward slash */
3555#endif
3556 }
3557
3558 for (start = end = name; *start != '\0'; start = end)
3559 {
3560 unsigned long len;
3561
3562 /* Skip sequence of multiple path-separators. */
3563 while (IS_PATHSEP(*start))
3564 ++start;
3565
3566 /* Find end of path component. */
3567 for (end = start; *end != '\0' && !IS_PATHSEP(*end); ++end)
3568 ;
3569
3570 len = end - start;
3571
3572 if (len == 0)
3573 break;
3574 else if (len == 1 && start[0] == '.')
3575 /* nothing */;
3576 else if (len == 2 && start[0] == '.' && start[1] == '.')
3577 {
3578 /* Back up to previous component, ignore if at root already. */
3579 if (dest > apath + root_len)
3580 for (--dest; !IS_PATHSEP(dest[-1]); --dest);
3581 }
3582 else
3583 {
3584 if (!IS_PATHSEP(dest[-1]))
3585 *dest++ = '/';
3586
3587 if (dest + len >= apath_limit)
3588 return NULL;
3589
3590 dest = memcpy (dest, start, len);
3591 dest += len;
3592 *dest = '\0';
3593 }
3594 }
3595#endif /* !WINDOWS32 && !__OS2__ */
3596
3597 /* Unless it is root strip trailing separator. */
3598 if (dest > apath + root_len && IS_PATHSEP(dest[-1]))
3599 --dest;
3600
3601 *dest = '\0';
3602
3603 return apath;
3604}
3605
3606
3607static char *
3608func_realpath (char *o, char **argv, const char *funcname UNUSED)
3609{
3610 /* Expand the argument. */
3611 const char *p = argv[0];
3612 const char *path = 0;
3613 int doneany = 0;
3614 unsigned int len = 0;
3615#ifndef HAVE_REALPATH
3616 struct stat st;
3617#endif
3618 PATH_VAR (in);
3619 PATH_VAR (out);
3620
3621 while ((path = find_next_token (&p, &len)) != 0)
3622 {
3623 if (len < GET_PATH_MAX)
3624 {
3625 strncpy (in, path, len);
3626 in[len] = '\0';
3627
3628 if (
3629#ifdef HAVE_REALPATH
3630 realpath (in, out)
3631#else
3632 abspath (in, out) && stat (out, &st) == 0
3633#endif
3634 )
3635 {
3636 o = variable_buffer_output (o, out, strlen (out));
3637 o = variable_buffer_output (o, " ", 1);
3638 doneany = 1;
3639 }
3640 }
3641 }
3642
3643 /* Kill last space. */
3644 if (doneany)
3645 --o;
3646
3647 return o;
3648}
3649
3650static char *
3651func_abspath (char *o, char **argv, const char *funcname UNUSED)
3652{
3653 /* Expand the argument. */
3654 const char *p = argv[0];
3655 const char *path = 0;
3656 int doneany = 0;
3657 unsigned int len = 0;
3658 PATH_VAR (in);
3659 PATH_VAR (out);
3660
3661 while ((path = find_next_token (&p, &len)) != 0)
3662 {
3663 if (len < GET_PATH_MAX)
3664 {
3665 strncpy (in, path, len);
3666 in[len] = '\0';
3667
3668 if (abspath (in, out))
3669 {
3670 o = variable_buffer_output (o, out, strlen (out));
3671 o = variable_buffer_output (o, " ", 1);
3672 doneany = 1;
3673 }
3674 }
3675 }
3676
3677 /* Kill last space. */
3678 if (doneany)
3679 --o;
3680
3681 return o;
3682}
3683
3684#ifdef CONFIG_WITH_ABSPATHEX
3685/* Same as abspath except that the current path may be given as the
3686 2nd argument. */
3687static char *
3688func_abspathex (char *o, char **argv, const char *funcname UNUSED)
3689{
3690 char *cwd = argv[1];
3691
3692 /* cwd needs leading spaces chopped and may be optional,
3693 in which case we're exactly like $(abspath ). */
3694 if (cwd)
3695 while (isblank (*cwd))
3696 cwd++;
3697 if (!cwd || !*cwd)
3698 o = func_abspath (o, argv, funcname);
3699 else
3700 {
3701 /* Expand the argument. */
3702 const char *p = argv[0];
3703 unsigned int cwd_len = ~0U;
3704 char *path = 0;
3705 int doneany = 0;
3706 unsigned int len = 0;
3707 PATH_VAR (in);
3708 PATH_VAR (out);
3709
3710 while ((path = find_next_token (&p, &len)) != 0)
3711 {
3712 if (len < GET_PATH_MAX)
3713 {
3714#ifdef HAVE_DOS_PATHS
3715 if (path[0] != '/' && path[0] != '\\' && (len < 2 || path[1] != ':') && cwd)
3716#else
3717 if (path[0] != '/' && cwd)
3718#endif
3719 {
3720 /* relative path, prefix with cwd. */
3721 if (cwd_len == ~0U)
3722 cwd_len = strlen (cwd);
3723 if (cwd_len + len + 1 >= GET_PATH_MAX)
3724 continue;
3725 memcpy (in, cwd, cwd_len);
3726 in[cwd_len] = '/';
3727 memcpy (in + cwd_len + 1, path, len);
3728 in[cwd_len + len + 1] = '\0';
3729 }
3730 else
3731 {
3732 /* absolute path pass it as-is. */
3733 memcpy (in, path, len);
3734 in[len] = '\0';
3735 }
3736
3737 if (abspath (in, out))
3738 {
3739 o = variable_buffer_output (o, out, strlen (out));
3740 o = variable_buffer_output (o, " ", 1);
3741 doneany = 1;
3742 }
3743 }
3744 }
3745
3746 /* Kill last space. */
3747 if (doneany)
3748 --o;
3749 }
3750
3751 return o;
3752}
3753#endif
3754
3755#ifdef CONFIG_WITH_XARGS
3756/* Create one or more command lines avoiding the max argument
3757 length restriction of the host OS.
3758
3759 The last argument is the list of arguments that the normal
3760 xargs command would be fed from stdin.
3761
3762 The first argument is initial command and it's arguments.
3763
3764 If there are three or more arguments, the 2nd argument is
3765 the command and arguments to be used on subsequent
3766 command lines. Defaults to the initial command.
3767
3768 If there are four or more arguments, the 3rd argument is
3769 the command to be used at the final command line. Defaults
3770 to the sub sequent or initial command .
3771
3772 A future version of this function may define more arguments
3773 and therefor anyone specifying six or more arguments will
3774 cause fatal errors.
3775
3776 Typical usage is:
3777 $(xargs ar cas mylib.a,$(objects))
3778 or
3779 $(xargs ar cas mylib.a,ar as mylib.a,$(objects))
3780
3781 It will then create one or more "ar mylib.a ..." command
3782 lines with proper \n\t separation so it can be used when
3783 writing rules. */
3784static char *
3785func_xargs (char *o, char **argv, const char *funcname UNUSED)
3786{
3787 int argc;
3788 const char *initial_cmd;
3789 size_t initial_cmd_len;
3790 const char *subsequent_cmd;
3791 size_t subsequent_cmd_len;
3792 const char *final_cmd;
3793 size_t final_cmd_len;
3794 const char *args;
3795 size_t max_args;
3796 int i;
3797
3798#ifdef ARG_MAX
3799 /* ARG_MAX is a bit unreliable (environment), so drop 25% of the max. */
3800# define XARGS_MAX (ARG_MAX - (ARG_MAX / 4))
3801#else /* FIXME: update configure with a command line length test. */
3802# define XARGS_MAX 10240
3803#endif
3804
3805 argc = 0;
3806 while (argv[argc])
3807 argc++;
3808 if (argc > 4)
3809 fatal (NILF, _("Too many arguments for $(xargs)!\n"));
3810
3811 /* first: the initial / default command.*/
3812 initial_cmd = argv[0];
3813 while (isspace ((unsigned char)*initial_cmd))
3814 initial_cmd++;
3815 max_args = initial_cmd_len = strlen (initial_cmd);
3816
3817 /* second: the command for the subsequent command lines. defaults to the initial cmd. */
3818 subsequent_cmd = argc > 2 && argv[1][0] != '\0' ? argv[1] : "";
3819 while (isspace ((unsigned char)*subsequent_cmd))
3820 subsequent_cmd++;
3821 if (*subsequent_cmd)
3822 {
3823 subsequent_cmd_len = strlen (subsequent_cmd);
3824 if (subsequent_cmd_len > max_args)
3825 max_args = subsequent_cmd_len;
3826 }
3827 else
3828 {
3829 subsequent_cmd = initial_cmd;
3830 subsequent_cmd_len = initial_cmd_len;
3831 }
3832
3833 /* third: the final command. defaults to the subseq cmd. */
3834 final_cmd = argc > 3 && argv[2][0] != '\0' ? argv[2] : "";
3835 while (isspace ((unsigned char)*final_cmd))
3836 final_cmd++;
3837 if (*final_cmd)
3838 {
3839 final_cmd_len = strlen (final_cmd);
3840 if (final_cmd_len > max_args)
3841 max_args = final_cmd_len;
3842 }
3843 else
3844 {
3845 final_cmd = subsequent_cmd;
3846 final_cmd_len = subsequent_cmd_len;
3847 }
3848
3849 /* last: the arguments to split up into sensible portions. */
3850 args = argv[argc - 1];
3851
3852 /* calc the max argument length. */
3853 if (XARGS_MAX <= max_args + 2)
3854 fatal (NILF, _("$(xargs): the commands are longer than the max exec argument length. (%lu <= %lu)\n"),
3855 (unsigned long)XARGS_MAX, (unsigned long)max_args + 2);
3856 max_args = XARGS_MAX - max_args - 1;
3857
3858 /* generate the commands. */
3859 i = 0;
3860 for (i = 0; ; i++)
3861 {
3862 unsigned int len;
3863 const char *iterator = args;
3864 const char *end = args;
3865 const char *cur;
3866 const char *tmp;
3867
3868 /* scan the arguments till we reach the end or the max length. */
3869 while ((cur = find_next_token(&iterator, &len))
3870 && (size_t)((cur + len) - args) < max_args)
3871 end = cur + len;
3872 if (cur && end == args)
3873 fatal (NILF, _("$(xargs): command + one single arg is too much. giving up.\n"));
3874
3875 /* emit the command. */
3876 if (i == 0)
3877 {
3878 o = variable_buffer_output (o, (char *)initial_cmd, initial_cmd_len);
3879 o = variable_buffer_output (o, " ", 1);
3880 }
3881 else if (cur)
3882 {
3883 o = variable_buffer_output (o, "\n\t", 2);
3884 o = variable_buffer_output (o, (char *)subsequent_cmd, subsequent_cmd_len);
3885 o = variable_buffer_output (o, " ", 1);
3886 }
3887 else
3888 {
3889 o = variable_buffer_output (o, "\n\t", 2);
3890 o = variable_buffer_output (o, (char *)final_cmd, final_cmd_len);
3891 o = variable_buffer_output (o, " ", 1);
3892 }
3893
3894 tmp = end;
3895 while (tmp > args && isspace ((unsigned char)tmp[-1])) /* drop trailing spaces. */
3896 tmp--;
3897 o = variable_buffer_output (o, (char *)args, tmp - args);
3898
3899
3900 /* next */
3901 if (!cur)
3902 break;
3903 args = end;
3904 while (isspace ((unsigned char)*args))
3905 args++;
3906 }
3907
3908 return o;
3909}
3910#endif
3911
3912#ifdef CONFIG_WITH_TOUPPER_TOLOWER
3913static char *
3914func_toupper_tolower (char *o, char **argv, const char *funcname)
3915{
3916 /* Expand the argument. */
3917 const char *p = argv[0];
3918 while (*p)
3919 {
3920 /* convert to temporary buffer */
3921 char tmp[256];
3922 unsigned int i;
3923 if (!strcmp(funcname, "toupper"))
3924 for (i = 0; i < sizeof(tmp) && *p; i++, p++)
3925 tmp[i] = toupper(*p);
3926 else
3927 for (i = 0; i < sizeof(tmp) && *p; i++, p++)
3928 tmp[i] = tolower(*p);
3929 o = variable_buffer_output (o, tmp, i);
3930 }
3931
3932 return o;
3933}
3934#endif /* CONFIG_WITH_TOUPPER_TOLOWER */
3935
3936#if defined(CONFIG_WITH_VALUE_LENGTH) && defined(CONFIG_WITH_COMPARE)
3937
3938/* Strip leading spaces and other things off a command. */
3939static const char *
3940comp_cmds_strip_leading (const char *s, const char *e)
3941{
3942 while (s < e)
3943 {
3944 const char ch = *s;
3945 if (!isblank (ch)
3946 && ch != '@'
3947#ifdef CONFIG_WITH_COMMANDS_FUNC
3948 && ch != '%'
3949#endif
3950 && ch != '+'
3951 && ch != '-')
3952 break;
3953 s++;
3954 }
3955 return s;
3956}
3957
3958/* Worker for func_comp_vars() which is called if the comparision failed.
3959 It will do the slow command by command comparision of the commands
3960 when there invoked as comp-cmds. */
3961static char *
3962comp_vars_ne (char *o, const char *s1, const char *e1, const char *s2, const char *e2,
3963 char *ne_retval, const char *funcname)
3964{
3965 /* give up at once if not comp-cmds or comp-cmds-ex. */
3966 if (strcmp (funcname, "comp-cmds") != 0
3967 && strcmp (funcname, "comp-cmds-ex") != 0)
3968 o = variable_buffer_output (o, ne_retval, strlen (ne_retval));
3969 else
3970 {
3971 const char * const s1_start = s1;
3972 int new_cmd = 1;
3973 int diff;
3974 for (;;)
3975 {
3976 /* if it's a new command, strip leading stuff. */
3977 if (new_cmd)
3978 {
3979 s1 = comp_cmds_strip_leading (s1, e1);
3980 s2 = comp_cmds_strip_leading (s2, e2);
3981 new_cmd = 0;
3982 }
3983 if (s1 >= e1 || s2 >= e2)
3984 break;
3985
3986 /*
3987 * Inner compare loop which compares one line.
3988 * FIXME: parse quoting!
3989 */
3990 for (;;)
3991 {
3992 const char ch1 = *s1;
3993 const char ch2 = *s2;
3994 diff = ch1 - ch2;
3995 if (diff)
3996 break;
3997 if (ch1 == '\n')
3998 break;
3999 assert (ch1 != '\r');
4000
4001 /* next */
4002 s1++;
4003 s2++;
4004 if (s1 >= e1 || s2 >= e2)
4005 break;
4006 }
4007
4008 /*
4009 * If we exited because of a difference try to end-of-command
4010 * comparision, e.g. ignore trailing spaces.
4011 */
4012 if (diff)
4013 {
4014 /* strip */
4015 while (s1 < e1 && isblank (*s1))
4016 s1++;
4017 while (s2 < e2 && isblank (*s2))
4018 s2++;
4019 if (s1 >= e1 || s2 >= e2)
4020 break;
4021
4022 /* compare again and check that it's a newline. */
4023 if (*s2 != '\n' || *s1 != '\n')
4024 break;
4025 }
4026 /* Break out if we exited because of EOS. */
4027 else if (s1 >= e1 || s2 >= e2)
4028 break;
4029
4030 /*
4031 * Detect the end of command lines.
4032 */
4033 if (*s1 == '\n')
4034 new_cmd = s1 == s1_start || s1[-1] != '\\';
4035 s1++;
4036 s2++;
4037 }
4038
4039 /*
4040 * Ignore trailing empty lines.
4041 */
4042 if (s1 < e1 || s2 < e2)
4043 {
4044 while (s1 < e1 && (isblank (*s1) || *s1 == '\n'))
4045 if (*s1++ == '\n')
4046 s1 = comp_cmds_strip_leading (s1, e1);
4047 while (s2 < e2 && (isblank (*s2) || *s2 == '\n'))
4048 if (*s2++ == '\n')
4049 s2 = comp_cmds_strip_leading (s2, e2);
4050 }
4051
4052 /* emit the result. */
4053 if (s1 == e1 && s2 == e2)
4054 o = variable_buffer_output (o, "", 1) - 1; /** @todo check why this was necessary back the... */
4055 else
4056 o = variable_buffer_output (o, ne_retval, strlen (ne_retval));
4057 }
4058 return o;
4059}
4060
4061/*
4062 $(comp-vars var1,var2,not-equal-return)
4063 or
4064 $(comp-cmds cmd-var1,cmd-var2,not-equal-return)
4065
4066 Compares the two variables (that's given by name to avoid unnecessary
4067 expanding) and return the string in the third argument if not equal.
4068 If equal, nothing is returned.
4069
4070 comp-vars will to an exact comparision only stripping leading and
4071 trailing spaces.
4072
4073 comp-cmds will compare command by command, ignoring not only leading
4074 and trailing spaces on each line but also leading one leading '@',
4075 '-', '+' and '%'
4076*/
4077static char *
4078func_comp_vars (char *o, char **argv, const char *funcname)
4079{
4080 const char *s1, *e1, *x1, *s2, *e2, *x2;
4081 char *a1 = NULL, *a2 = NULL;
4082 size_t l, l1, l2;
4083 struct variable *var1 = lookup_variable (argv[0], strlen (argv[0]));
4084 struct variable *var2 = lookup_variable (argv[1], strlen (argv[1]));
4085
4086 /* the simple cases */
4087 if (var1 == var2)
4088 return variable_buffer_output (o, "", 0); /* eq */
4089 if (!var1 || !var2)
4090 return variable_buffer_output (o, argv[2], strlen(argv[2]));
4091 if (var1->value == var2->value)
4092 return variable_buffer_output (o, "", 0); /* eq */
4093 if (!var1->recursive && !var2->recursive)
4094 {
4095 if ( var1->value_length == var2->value_length
4096 && !memcmp (var1->value, var2->value, var1->value_length))
4097 return variable_buffer_output (o, "", 0); /* eq */
4098
4099 /* ignore trailing and leading blanks */
4100 s1 = var1->value;
4101 e1 = s1 + var1->value_length;
4102 while (isblank ((unsigned char) *s1))
4103 s1++;
4104 while (e1 > s1 && isblank ((unsigned char) e1[-1]))
4105 e1--;
4106
4107 s2 = var2->value;
4108 e2 = s2 + var2->value_length;
4109 while (isblank ((unsigned char) *s2))
4110 s2++;
4111 while (e2 > s2 && isblank ((unsigned char) e2[-1]))
4112 e2--;
4113
4114 if (e1 - s1 != e2 - s2)
4115 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4116 if (!memcmp (s1, s2, e1 - s1))
4117 return variable_buffer_output (o, "", 0); /* eq */
4118 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4119 }
4120
4121 /* ignore trailing and leading blanks */
4122 s1 = var1->value;
4123 e1 = s1 + var1->value_length;
4124 while (isblank ((unsigned char) *s1))
4125 s1++;
4126 while (e1 > s1 && isblank ((unsigned char) e1[-1]))
4127 e1--;
4128
4129 s2 = var2->value;
4130 e2 = s2 + var2->value_length;
4131 while (isblank((unsigned char)*s2))
4132 s2++;
4133 while (e2 > s2 && isblank ((unsigned char) e2[-1]))
4134 e2--;
4135
4136 /* both empty after stripping? */
4137 if (s1 == e1 && s2 == e2)
4138 return variable_buffer_output (o, "", 0); /* eq */
4139
4140 /* optimist. */
4141 if ( e1 - s1 == e2 - s2
4142 && !memcmp(s1, s2, e1 - s1))
4143 return variable_buffer_output (o, "", 0); /* eq */
4144
4145 /* compare up to the first '$' or the end. */
4146 x1 = var1->recursive ? memchr (s1, '$', e1 - s1) : NULL;
4147 x2 = var2->recursive ? memchr (s2, '$', e2 - s2) : NULL;
4148 if (!x1 && !x2)
4149 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4150
4151 l1 = x1 ? x1 - s1 : e1 - s1;
4152 l2 = x2 ? x2 - s2 : e2 - s2;
4153 l = l1 <= l2 ? l1 : l2;
4154 if (l && memcmp (s1, s2, l))
4155 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4156
4157 /* one or both buffers now require expanding. */
4158 if (!x1)
4159 s1 += l;
4160 else
4161 {
4162 s1 = a1 = allocated_variable_expand ((char *)s1 + l);
4163 if (!l)
4164 while (isblank ((unsigned char) *s1))
4165 s1++;
4166 e1 = strchr (s1, '\0');
4167 while (e1 > s1 && isblank ((unsigned char) e1[-1]))
4168 e1--;
4169 }
4170
4171 if (!x2)
4172 s2 += l;
4173 else
4174 {
4175 s2 = a2 = allocated_variable_expand ((char *)s2 + l);
4176 if (!l)
4177 while (isblank ((unsigned char) *s2))
4178 s2++;
4179 e2 = strchr (s2, '\0');
4180 while (e2 > s2 && isblank ((unsigned char) e2[-1]))
4181 e2--;
4182 }
4183
4184 /* the final compare */
4185 if ( e1 - s1 != e2 - s2
4186 || memcmp (s1, s2, e1 - s1))
4187 o = comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4188 else
4189 o = variable_buffer_output (o, "", 1) - 1; /* eq */ /** @todo check why this was necessary back the... */
4190 if (a1)
4191 free (a1);
4192 if (a2)
4193 free (a2);
4194 return o;
4195}
4196
4197/*
4198 $(comp-cmds-ex cmds1,cmds2,not-equal-return)
4199
4200 Compares the two strings and return the string in the third argument
4201 if not equal. If equal, nothing is returned.
4202
4203 The comparision will be performed command by command, ignoring not
4204 only leading and trailing spaces on each line but also leading one
4205 leading '@', '-', '+' and '%'.
4206*/
4207static char *
4208func_comp_cmds_ex (char *o, char **argv, const char *funcname)
4209{
4210 const char *s1, *e1, *s2, *e2;
4211 size_t l1, l2;
4212
4213 /* the simple cases */
4214 s1 = argv[0];
4215 s2 = argv[1];
4216 if (s1 == s2)
4217 return variable_buffer_output (o, "", 0); /* eq */
4218 l1 = strlen (argv[0]);
4219 l2 = strlen (argv[1]);
4220
4221 if ( l1 == l2
4222 && !memcmp (s1, s2, l1))
4223 return variable_buffer_output (o, "", 0); /* eq */
4224
4225 /* ignore trailing and leading blanks */
4226 e1 = s1 + l1;
4227 s1 = comp_cmds_strip_leading (s1, e1);
4228
4229 e2 = s2 + l2;
4230 s2 = comp_cmds_strip_leading (s2, e2);
4231
4232 if (e1 - s1 != e2 - s2)
4233 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4234 if (!memcmp (s1, s2, e1 - s1))
4235 return variable_buffer_output (o, "", 0); /* eq */
4236 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4237}
4238#endif
4239
4240#ifdef CONFIG_WITH_DATE
4241# if defined (_MSC_VER) /* FIXME: !defined (HAVE_STRPTIME) */
4242char *strptime(const char *s, const char *format, struct tm *tm)
4243{
4244 return (char *)"strptime is not implemented";
4245}
4246# endif
4247/* Check if the string is all blanks or not. */
4248static int
4249all_blanks (const char *s)
4250{
4251 if (!s)
4252 return 1;
4253 while (isspace ((unsigned char)*s))
4254 s++;
4255 return *s == '\0';
4256}
4257
4258/* The first argument is the strftime format string, a iso
4259 timestamp is the default if nothing is given.
4260
4261 The second argument is a time value if given. The format
4262 is either the format from the first argument or given as
4263 an additional third argument. */
4264static char *
4265func_date (char *o, char **argv, const char *funcname)
4266{
4267 char *p;
4268 char *buf;
4269 size_t buf_size;
4270 struct tm t;
4271 const char *format;
4272
4273 /* determin the format - use a single word as the default. */
4274 format = !strcmp (funcname, "date-utc")
4275 ? "%Y-%m-%dT%H:%M:%SZ"
4276 : "%Y-%m-%dT%H:%M:%S";
4277 if (!all_blanks (argv[0]))
4278 format = argv[0];
4279
4280 /* get the time. */
4281 memset (&t, 0, sizeof(t));
4282 if (argv[0] && !all_blanks (argv[1]))
4283 {
4284 const char *input_format = !all_blanks (argv[2]) ? argv[2] : format;
4285 p = strptime (argv[1], input_format, &t);
4286 if (!p || *p != '\0')
4287 {
4288 error (NILF, _("$(%s): strptime(%s,%s,) -> %s\n"), funcname,
4289 argv[1], input_format, p ? p : "<null>");
4290 return variable_buffer_output (o, "", 0);
4291 }
4292 }
4293 else
4294 {
4295 time_t tval;
4296 time (&tval);
4297 if (!strcmp (funcname, "date-utc"))
4298 t = *gmtime (&tval);
4299 else
4300 t = *localtime (&tval);
4301 }
4302
4303 /* format it. note that zero isn't necessarily an error, so we'll
4304 have to keep shut about failures. */
4305 buf_size = 64;
4306 buf = xmalloc (buf_size);
4307 while (strftime (buf, buf_size, format, &t) == 0)
4308 {
4309 if (buf_size >= 4096)
4310 {
4311 *buf = '\0';
4312 break;
4313 }
4314 buf = xrealloc (buf, buf_size <<= 1);
4315 }
4316 o = variable_buffer_output (o, buf, strlen (buf));
4317 free (buf);
4318 return o;
4319}
4320#endif
4321
4322#ifdef CONFIG_WITH_FILE_SIZE
4323/* Prints the size of the specified file. Only one file is
4324 permitted, notthing is stripped. -1 is returned if stat
4325 fails. */
4326static char *
4327func_file_size (char *o, char **argv, const char *funcname UNUSED)
4328{
4329 struct stat st;
4330 if (stat (argv[0], &st))
4331 return variable_buffer_output (o, "-1", 2);
4332 return math_int_to_variable_buffer (o, st.st_size);
4333}
4334#endif
4335
4336#ifdef CONFIG_WITH_WHICH
4337/* Checks if the specified file exists an is executable.
4338 On systems employing executable extensions, the name may
4339 be modified to include the extension. */
4340static int func_which_test_x (char *file)
4341{
4342 struct stat st;
4343# if defined(WINDOWS32) || defined(__OS2__)
4344 char *ext;
4345 char *slash;
4346
4347 /* fix slashes first. */
4348 slash = file;
4349 while ((slash = strchr (slash, '\\')) != NULL)
4350 *slash++ = '/';
4351
4352 /* straight */
4353 if (stat (file, &st) == 0
4354 && S_ISREG (st.st_mode))
4355 return 1;
4356
4357 /* don't try add an extension if there already is one */
4358 ext = strchr (file, '\0');
4359 if (ext - file >= 4
4360 && ( !stricmp (ext - 4, ".exe")
4361 || !stricmp (ext - 4, ".cmd")
4362 || !stricmp (ext - 4, ".bat")
4363 || !stricmp (ext - 4, ".com")))
4364 return 0;
4365
4366 /* try the extensions. */
4367 strcpy (ext, ".exe");
4368 if (stat (file, &st) == 0
4369 && S_ISREG (st.st_mode))
4370 return 1;
4371
4372 strcpy (ext, ".cmd");
4373 if (stat (file, &st) == 0
4374 && S_ISREG (st.st_mode))
4375 return 1;
4376
4377 strcpy (ext, ".bat");
4378 if (stat (file, &st) == 0
4379 && S_ISREG (st.st_mode))
4380 return 1;
4381
4382 strcpy (ext, ".com");
4383 if (stat (file, &st) == 0
4384 && S_ISREG (st.st_mode))
4385 return 1;
4386
4387 return 0;
4388
4389# else
4390
4391 return access (file, X_OK) == 0
4392 && stat (file, &st) == 0
4393 && S_ISREG (st.st_mode);
4394# endif
4395}
4396
4397/* Searches for the specified programs in the PATH and print
4398 their full location if found. Prints nothing if not found. */
4399static char *
4400func_which (char *o, char **argv, const char *funcname UNUSED)
4401{
4402 const char *path;
4403 struct variable *path_var;
4404 unsigned i;
4405 int first = 1;
4406 PATH_VAR (buf);
4407
4408 path_var = lookup_variable ("PATH", 4);
4409 if (path_var)
4410 path = path_var->value;
4411 else
4412 path = ".";
4413
4414 /* iterate input */
4415 for (i = 0; argv[i]; i++)
4416 {
4417 unsigned int len;
4418 const char *iterator = argv[i];
4419 char *cur;
4420
4421 while ((cur = find_next_token (&iterator, &len)))
4422 {
4423 /* if there is a separator, don't walk the path. */
4424 if (memchr (cur, '/', len)
4425#ifdef HAVE_DOS_PATHS
4426 || memchr (cur, '\\', len)
4427 || memchr (cur, ':', len)
4428#endif
4429 )
4430 {
4431 if (len + 1 + 4 < GET_PATH_MAX) /* +4 for .exe */
4432 {
4433 memcpy (buf, cur, len);
4434 buf[len] = '\0';
4435 if (func_which_test_x (buf))
4436 o = variable_buffer_output (o, buf, strlen (buf));
4437 }
4438 }
4439 else
4440 {
4441 const char *comp = path;
4442 for (;;)
4443 {
4444 const char *src = comp;
4445 const char *end = strchr (comp, PATH_SEPARATOR_CHAR);
4446 size_t src_len = end ? (size_t)(end - comp) : strlen (comp);
4447 if (!src_len)
4448 {
4449 src_len = 1;
4450 src = ".";
4451 }
4452 if (len + src_len + 2 + 4 < GET_PATH_MAX) /* +4 for .exe */
4453 {
4454 memcpy (buf, src, src_len);
4455 buf [src_len] = '/';
4456 memcpy (&buf[src_len + 1], cur, len);
4457 buf[src_len + 1 + len] = '\0';
4458
4459 if (func_which_test_x (buf))
4460 {
4461 if (!first)
4462 o = variable_buffer_output (o, " ", 1);
4463 o = variable_buffer_output (o, buf, strlen (buf));
4464 first = 0;
4465 break;
4466 }
4467 }
4468
4469 /* next */
4470 if (!end)
4471 break;
4472 comp = end + 1;
4473 }
4474 }
4475 }
4476 }
4477
4478 return variable_buffer_output (o, "", 0);
4479}
4480#endif /* CONFIG_WITH_WHICH */
4481
4482#ifdef CONFIG_WITH_IF_CONDITIONALS
4483
4484/* Evaluates the expression given in the argument using the
4485 same evaluator as for the new 'if' statements, except now
4486 we don't force the result into a boolean like for 'if' and
4487 '$(if-expr ,,)'. */
4488static char *
4489func_expr (char *o, char **argv, const char *funcname UNUSED)
4490{
4491 o = expr_eval_to_string (o, argv[0]);
4492 return o;
4493}
4494
4495/* Same as '$(if ,,)' except the first argument is evaluated
4496 using the same evaluator as for the new 'if' statements. */
4497static char *
4498func_if_expr (char *o, char **argv, const char *funcname UNUSED)
4499{
4500 int rc;
4501 char *to_expand;
4502
4503 /* Evaluate the condition in argv[0] and expand the 2nd or
4504 3rd (optional) argument according to the result. */
4505 rc = expr_eval_if_conditionals (argv[0], NULL);
4506 to_expand = rc == 0 ? argv[1] : argv[2];
4507 if (to_expand && *to_expand)
4508 variable_expand_string_2 (o, to_expand, -1, &o);
4509
4510 return o;
4511}
4512
4513/*
4514 $(select when1-cond, when1-body[,whenN-cond, whenN-body]).
4515 */
4516static char *
4517func_select (char *o, char **argv, const char *funcname UNUSED)
4518{
4519 int i;
4520
4521 /* Test WHEN-CONDs until one matches. The check for 'otherwise[:]'
4522 and 'default[:]' make this a bit more fun... */
4523
4524 for (i = 0; argv[i] != NULL; i += 2)
4525 {
4526 const char *cond = argv[i];
4527 int is_otherwise = 0;
4528
4529 if (argv[i + 1] == NULL)
4530 fatal (NILF, _("$(select ): not an even argument count\n"));
4531
4532 while (isspace ((unsigned char)*cond))
4533 cond++;
4534 if ( (*cond == 'o' && strncmp (cond, "otherwise", 9) == 0)
4535 || (*cond == 'd' && strncmp (cond, "default", 7) == 0))
4536 {
4537 const char *end = cond + (*cond == 'o' ? 9 : 7);
4538 while (isspace ((unsigned char)*end))
4539 end++;
4540 if (*end == ':')
4541 do end++;
4542 while (isspace ((unsigned char)*end));
4543 is_otherwise = *end == '\0';
4544 }
4545
4546 if ( is_otherwise
4547 || expr_eval_if_conditionals (cond, NULL) == 0 /* true */)
4548 {
4549 variable_expand_string_2 (o, argv[i + 1], -1, &o);
4550 break;
4551 }
4552 }
4553
4554 return o;
4555}
4556
4557#endif /* CONFIG_WITH_IF_CONDITIONALS */
4558
4559#ifdef CONFIG_WITH_SET_CONDITIONALS
4560static char *
4561func_set_intersects (char *o, char **argv, const char *funcname UNUSED)
4562{
4563 const char *s1_cur;
4564 unsigned int s1_len;
4565 const char *s1_iterator = argv[0];
4566
4567 while ((s1_cur = find_next_token (&s1_iterator, &s1_len)) != 0)
4568 {
4569 const char *s2_cur;
4570 unsigned int s2_len;
4571 const char *s2_iterator = argv[1];
4572 while ((s2_cur = find_next_token (&s2_iterator, &s2_len)) != 0)
4573 if (s2_len == s1_len
4574 && strneq (s2_cur, s1_cur, s1_len) )
4575 return variable_buffer_output (o, "1", 1); /* found intersection */
4576 }
4577
4578 return o; /* no intersection */
4579}
4580#endif /* CONFIG_WITH_SET_CONDITIONALS */
4581
4582#ifdef CONFIG_WITH_STACK
4583
4584/* Push an item (string without spaces). */
4585static char *
4586func_stack_push (char *o, char **argv, const char *funcname UNUSED)
4587{
4588 do_variable_definition(NILF, argv[0], argv[1], o_file, f_append, 0 /* !target_var */);
4589 return o;
4590}
4591
4592/* Pops an item off the stack / get the top stack element.
4593 (This is what's tricky to do in pure GNU make syntax.) */
4594static char *
4595func_stack_pop_top (char *o, char **argv, const char *funcname)
4596{
4597 struct variable *stack_var;
4598 const char *stack = argv[0];
4599
4600 stack_var = lookup_variable (stack, strlen (stack) );
4601 if (stack_var)
4602 {
4603 unsigned int len;
4604 const char *iterator = stack_var->value;
4605 char *lastitem = NULL;
4606 char *cur;
4607
4608 while ((cur = find_next_token (&iterator, &len)))
4609 lastitem = cur;
4610
4611 if (lastitem != NULL)
4612 {
4613 if (strcmp (funcname, "stack-popv") != 0)
4614 o = variable_buffer_output (o, lastitem, len);
4615 if (strcmp (funcname, "stack-top") != 0)
4616 {
4617 *lastitem = '\0';
4618 while (lastitem > stack_var->value && isspace (lastitem[-1]))
4619 *--lastitem = '\0';
4620#ifdef CONFIG_WITH_VALUE_LENGTH
4621 stack_var->value_length = lastitem - stack_var->value;
4622#endif
4623 }
4624 }
4625 }
4626 return o;
4627}
4628#endif /* CONFIG_WITH_STACK */
4629
4630#if defined (CONFIG_WITH_MATH) || defined (CONFIG_WITH_NANOTS) || defined (CONFIG_WITH_FILE_SIZE)
4631/* outputs the number (as a string) into the variable buffer. */
4632static char *
4633math_int_to_variable_buffer (char *o, math_int num)
4634{
4635 static const char xdigits[17] = "0123456789abcdef";
4636 int negative;
4637 char strbuf[24]; /* 16 hex + 2 prefix + sign + term => 20
4638 or 20 dec + sign + term => 22 */
4639 char *str = &strbuf[sizeof (strbuf) - 1];
4640
4641 negative = num < 0;
4642 if (negative)
4643 num = -num;
4644
4645 *str = '\0';
4646
4647 do
4648 {
4649#ifdef HEX_MATH_NUMBERS
4650 *--str = xdigits[num & 0xf];
4651 num >>= 4;
4652#else
4653 *--str = xdigits[num % 10];
4654 num /= 10;
4655#endif
4656 }
4657 while (num);
4658
4659#ifdef HEX_MATH_NUMBERS
4660 *--str = 'x';
4661 *--str = '0';
4662#endif
4663
4664 if (negative)
4665 *--str = '-';
4666
4667 return variable_buffer_output (o, str, &strbuf[sizeof (strbuf) - 1] - str);
4668}
4669#endif /* CONFIG_WITH_MATH || CONFIG_WITH_NANOTS */
4670
4671#ifdef CONFIG_WITH_MATH
4672
4673/* Converts a string to an integer, causes an error if the format is invalid. */
4674static math_int
4675math_int_from_string (const char *str)
4676{
4677 const char *start;
4678 unsigned base = 0;
4679 int negative = 0;
4680 math_int num = 0;
4681
4682 /* strip spaces */
4683 while (isspace (*str))
4684 str++;
4685 if (!*str)
4686 {
4687 error (NILF, _("bad number: empty\n"));
4688 return 0;
4689 }
4690 start = str;
4691
4692 /* check for +/- */
4693 while (*str == '+' || *str == '-' || isspace (*str))
4694 if (*str++ == '-')
4695 negative = !negative;
4696
4697 /* check for prefix - we do not accept octal numbers, sorry. */
4698 if (*str == '0' && (str[1] == 'x' || str[1] == 'X'))
4699 {
4700 base = 16;
4701 str += 2;
4702 }
4703 else
4704 {
4705 /* look for a hex digit, if not found treat it as decimal */
4706 const char *p2 = str;
4707 for ( ; *p2; p2++)
4708 if (isxdigit (*p2) && !isdigit (*p2) && isascii (*p2) )
4709 {
4710 base = 16;
4711 break;
4712 }
4713 if (base == 0)
4714 base = 10;
4715 }
4716
4717 /* must have at least one digit! */
4718 if ( !isascii (*str)
4719 || !(base == 16 ? isxdigit (*str) : isdigit (*str)) )
4720 {
4721 error (NILF, _("bad number: '%s'\n"), start);
4722 return 0;
4723 }
4724
4725 /* convert it! */
4726 while (*str && !isspace (*str))
4727 {
4728 int ch = *str++;
4729 if (ch >= '0' && ch <= '9')
4730 ch -= '0';
4731 else if (base == 16 && ch >= 'a' && ch <= 'f')
4732 ch -= 'a' - 10;
4733 else if (base == 16 && ch >= 'A' && ch <= 'F')
4734 ch -= 'A' - 10;
4735 else
4736 {
4737 error (NILF, _("bad number: '%s' (base=%u, pos=%lu)\n"), start, base, (unsigned long)(str - start));
4738 return 0;
4739 }
4740 num *= base;
4741 num += ch;
4742 }
4743
4744 /* check trailing spaces. */
4745 while (isspace (*str))
4746 str++;
4747 if (*str)
4748 {
4749 error (NILF, _("bad number: '%s'\n"), start);
4750 return 0;
4751 }
4752
4753 return negative ? -num : num;
4754}
4755
4756/* Add two or more integer numbers. */
4757static char *
4758func_int_add (char *o, char **argv, const char *funcname UNUSED)
4759{
4760 math_int num;
4761 int i;
4762
4763 num = math_int_from_string (argv[0]);
4764 for (i = 1; argv[i]; i++)
4765 num += math_int_from_string (argv[i]);
4766
4767 return math_int_to_variable_buffer (o, num);
4768}
4769
4770/* Subtract two or more integer numbers. */
4771static char *
4772func_int_sub (char *o, char **argv, const char *funcname UNUSED)
4773{
4774 math_int num;
4775 int i;
4776
4777 num = math_int_from_string (argv[0]);
4778 for (i = 1; argv[i]; i++)
4779 num -= math_int_from_string (argv[i]);
4780
4781 return math_int_to_variable_buffer (o, num);
4782}
4783
4784/* Multiply two or more integer numbers. */
4785static char *
4786func_int_mul (char *o, char **argv, const char *funcname UNUSED)
4787{
4788 math_int num;
4789 int i;
4790
4791 num = math_int_from_string (argv[0]);
4792 for (i = 1; argv[i]; i++)
4793 num *= math_int_from_string (argv[i]);
4794
4795 return math_int_to_variable_buffer (o, num);
4796}
4797
4798/* Divide an integer number by one or more divisors. */
4799static char *
4800func_int_div (char *o, char **argv, const char *funcname UNUSED)
4801{
4802 math_int num;
4803 math_int divisor;
4804 int i;
4805
4806 num = math_int_from_string (argv[0]);
4807 for (i = 1; argv[i]; i++)
4808 {
4809 divisor = math_int_from_string (argv[i]);
4810 if (!divisor)
4811 {
4812 error (NILF, _("divide by zero ('%s')\n"), argv[i]);
4813 return math_int_to_variable_buffer (o, 0);
4814 }
4815 num /= divisor;
4816 }
4817
4818 return math_int_to_variable_buffer (o, num);
4819}
4820
4821
4822/* Divide and return the remainder. */
4823static char *
4824func_int_mod (char *o, char **argv, const char *funcname UNUSED)
4825{
4826 math_int num;
4827 math_int divisor;
4828
4829 num = math_int_from_string (argv[0]);
4830 divisor = math_int_from_string (argv[1]);
4831 if (!divisor)
4832 {
4833 error (NILF, _("divide by zero ('%s')\n"), argv[1]);
4834 return math_int_to_variable_buffer (o, 0);
4835 }
4836 num %= divisor;
4837
4838 return math_int_to_variable_buffer (o, num);
4839}
4840
4841/* 2-complement. */
4842static char *
4843func_int_not (char *o, char **argv, const char *funcname UNUSED)
4844{
4845 math_int num;
4846
4847 num = math_int_from_string (argv[0]);
4848 num = ~num;
4849
4850 return math_int_to_variable_buffer (o, num);
4851}
4852
4853/* Bitwise AND (two or more numbers). */
4854static char *
4855func_int_and (char *o, char **argv, const char *funcname UNUSED)
4856{
4857 math_int num;
4858 int i;
4859
4860 num = math_int_from_string (argv[0]);
4861 for (i = 1; argv[i]; i++)
4862 num &= math_int_from_string (argv[i]);
4863
4864 return math_int_to_variable_buffer (o, num);
4865}
4866
4867/* Bitwise OR (two or more numbers). */
4868static char *
4869func_int_or (char *o, char **argv, const char *funcname UNUSED)
4870{
4871 math_int num;
4872 int i;
4873
4874 num = math_int_from_string (argv[0]);
4875 for (i = 1; argv[i]; i++)
4876 num |= math_int_from_string (argv[i]);
4877
4878 return math_int_to_variable_buffer (o, num);
4879}
4880
4881/* Bitwise XOR (two or more numbers). */
4882static char *
4883func_int_xor (char *o, char **argv, const char *funcname UNUSED)
4884{
4885 math_int num;
4886 int i;
4887
4888 num = math_int_from_string (argv[0]);
4889 for (i = 1; argv[i]; i++)
4890 num ^= math_int_from_string (argv[i]);
4891
4892 return math_int_to_variable_buffer (o, num);
4893}
4894
4895/* Compare two integer numbers. Returns make boolean (true="1"; false=""). */
4896static char *
4897func_int_cmp (char *o, char **argv, const char *funcname)
4898{
4899 math_int num1;
4900 math_int num2;
4901 int rc;
4902
4903 num1 = math_int_from_string (argv[0]);
4904 num2 = math_int_from_string (argv[1]);
4905
4906 funcname += sizeof ("int-") - 1;
4907 if (!strcmp (funcname, "eq"))
4908 rc = num1 == num2;
4909 else if (!strcmp (funcname, "ne"))
4910 rc = num1 != num2;
4911 else if (!strcmp (funcname, "gt"))
4912 rc = num1 > num2;
4913 else if (!strcmp (funcname, "ge"))
4914 rc = num1 >= num2;
4915 else if (!strcmp (funcname, "lt"))
4916 rc = num1 < num2;
4917 else /*if (!strcmp (funcname, "le"))*/
4918 rc = num1 <= num2;
4919
4920 return variable_buffer_output (o, rc ? "1" : "", rc);
4921}
4922
4923#endif /* CONFIG_WITH_MATH */
4924
4925#ifdef CONFIG_WITH_NANOTS
4926/* Returns the current timestamp as nano seconds. The time
4927 source is a high res monotone one if the platform provides
4928 this (and we know about it).
4929
4930 Tip. Use this with int-sub to profile makefile reading
4931 and similar. */
4932static char *
4933func_nanots (char *o, char **argv UNUSED, const char *funcname UNUSED)
4934{
4935 return math_int_to_variable_buffer (o, nano_timestamp ());
4936}
4937#endif
4938
4939#ifdef CONFIG_WITH_OS2_LIBPATH
4940/* Sets or gets the OS/2 libpath variables.
4941
4942 The first argument indicates which variable - BEGINLIBPATH,
4943 ENDLIBPATH, LIBPATHSTRICT or LIBPATH.
4944
4945 The second indicates whether this is a get (not present) or
4946 set (present) operation. When present it is the new value for
4947 the variable. */
4948static char *
4949func_os2_libpath (char *o, char **argv, const char *funcname UNUSED)
4950{
4951 char buf[4096];
4952 ULONG fVar;
4953 APIRET rc;
4954
4955 /* translate variable name (first arg) */
4956 if (!strcmp (argv[0], "BEGINLIBPATH"))
4957 fVar = BEGIN_LIBPATH;
4958 else if (!strcmp (argv[0], "ENDLIBPATH"))
4959 fVar = END_LIBPATH;
4960 else if (!strcmp (argv[0], "LIBPATHSTRICT"))
4961 fVar = LIBPATHSTRICT;
4962 else if (!strcmp (argv[0], "LIBPATH"))
4963 fVar = 0;
4964 else
4965 {
4966 error (NILF, _("$(libpath): unknown variable `%s'"), argv[0]);
4967 return variable_buffer_output (o, "", 0);
4968 }
4969
4970 if (!argv[1])
4971 {
4972 /* get the variable value. */
4973 if (fVar != 0)
4974 {
4975 buf[0] = buf[1] = buf[2] = buf[3] = '\0';
4976 rc = DosQueryExtLIBPATH (buf, fVar);
4977 }
4978 else
4979 rc = DosQueryHeaderInfo (NULLHANDLE, 0, buf, sizeof(buf), QHINF_LIBPATH);
4980 if (rc != NO_ERROR)
4981 {
4982 error (NILF, _("$(libpath): failed to query `%s', rc=%d"), argv[0], rc);
4983 return variable_buffer_output (o, "", 0);
4984 }
4985 o = variable_buffer_output (o, buf, strlen (buf));
4986 }
4987 else
4988 {
4989 /* set the variable value. */
4990 size_t len;
4991 size_t len_max = sizeof (buf) < 2048 ? sizeof (buf) : 2048;
4992 const char *val;
4993 const char *end;
4994
4995 if (fVar == 0)
4996 {
4997 error (NILF, _("$(libpath): LIBPATH is read-only"));
4998 return variable_buffer_output (o, "", 0);
4999 }
5000
5001 /* strip leading and trailing spaces and check for max length. */
5002 val = argv[1];
5003 while (isspace (*val))
5004 val++;
5005 end = strchr (val, '\0');
5006 while (end > val && isspace (end[-1]))
5007 end--;
5008
5009 len = end - val;
5010 if (len >= len_max)
5011 {
5012 error (NILF, _("$(libpath): The new `%s' value is too long (%d bytes, max %d)"),
5013 argv[0], len, len_max);
5014 return variable_buffer_output (o, "", 0);
5015 }
5016
5017 /* make a stripped copy in low memory and try set it. */
5018 memcpy (buf, val, len);
5019 buf[len] = '\0';
5020 rc = DosSetExtLIBPATH (buf, fVar);
5021 if (rc != NO_ERROR)
5022 {
5023 error (NILF, _("$(libpath): failed to set `%s' to `%s', rc=%d"), argv[0], buf, rc);
5024 return variable_buffer_output (o, "", 0);
5025 }
5026
5027 o = variable_buffer_output (o, "", 0);
5028 }
5029 return o;
5030}
5031#endif /* CONFIG_WITH_OS2_LIBPATH */
5032
5033#if defined (CONFIG_WITH_MAKE_STATS) || defined (CONFIG_WITH_MINIMAL_STATS)
5034/* Retrieve make statistics. */
5035static char *
5036func_make_stats (char *o, char **argv, const char *funcname UNUSED)
5037{
5038 char buf[512];
5039 int len;
5040
5041 if (!argv[0] || (!argv[0][0] && !argv[1]))
5042 {
5043# ifdef CONFIG_WITH_MAKE_STATS
5044 len = sprintf (buf, "alloc-cur: %5ld/%3ld %3luMB hash: %5lu %2lu%%",
5045 make_stats_allocations,
5046 make_stats_reallocations,
5047 make_stats_allocated / (1024*1024),
5048 make_stats_ht_lookups,
5049 (make_stats_ht_collisions * 100) / make_stats_ht_lookups);
5050 o = variable_buffer_output (o, buf, len);
5051#endif
5052 }
5053 else
5054 {
5055 /* selective */
5056 int i;
5057 for (i = 0; argv[i]; i++)
5058 {
5059 unsigned long val;
5060 if (i != 0)
5061 o = variable_buffer_output (o, " ", 1);
5062 if (0)
5063 continue;
5064# ifdef CONFIG_WITH_MAKE_STATS
5065 else if (!strcmp(argv[i], "allocations"))
5066 val = make_stats_allocations;
5067 else if (!strcmp(argv[i], "reallocations"))
5068 val = make_stats_reallocations;
5069 else if (!strcmp(argv[i], "allocated"))
5070 val = make_stats_allocated;
5071 else if (!strcmp(argv[i], "ht_lookups"))
5072 val = make_stats_ht_lookups;
5073 else if (!strcmp(argv[i], "ht_collisions"))
5074 val = make_stats_ht_collisions;
5075 else if (!strcmp(argv[i], "ht_collisions_pct"))
5076 val = (make_stats_ht_collisions * 100) / make_stats_ht_lookups;
5077#endif
5078 else
5079 {
5080 o = variable_buffer_output (o, argv[i], strlen (argv[i]));
5081 continue;
5082 }
5083
5084 len = sprintf (buf, "%ld", val);
5085 o = variable_buffer_output (o, buf, len);
5086 }
5087 }
5088
5089 return o;
5090}
5091#endif /* CONFIG_WITH_MAKE_STATS */
5092
5093#ifdef CONFIG_WITH_COMMANDS_FUNC
5094/* Gets all the commands for a target, separated by newlines.
5095
5096 This is useful when creating and checking target dependencies since
5097 it reduces the amount of work and the memory consuption. A new prefix
5098 character '%' has been introduced for skipping certain lines, like
5099 for instance the one calling this function and pushing to a dep file.
5100 Blank lines are also skipped.
5101
5102 The commands function takes exactly one argument, which is the name of
5103 the target which commands should be returned.
5104
5105 The commands-sc is identical to commands except that it uses a ';' to
5106 separate the commands.
5107
5108 The commands-usr is similar to commands except that it takes a 2nd
5109 argument that is used to separate the commands. */
5110char *
5111func_commands (char *o, char **argv, const char *funcname)
5112{
5113 struct file *file;
5114 static int recursive = 0;
5115
5116 if (recursive)
5117 {
5118 error (reading_file, _("$(%s ) was invoked recursivly"), funcname);
5119 return variable_buffer_output (o, "recursive", sizeof ("recursive") - 1);
5120 }
5121 if (*argv[0] == '\0')
5122 {
5123 error (reading_file, _("$(%s ) was invoked with an empty target name"), funcname);
5124 return o;
5125 }
5126 recursive = 1;
5127
5128 file = lookup_file (argv[0]);
5129 if (file && file->cmds)
5130 {
5131 unsigned int i;
5132 int cmd_sep_len;
5133 struct commands *cmds = file->cmds;
5134 const char *cmd_sep;
5135
5136 if (!strcmp (funcname, "commands"))
5137 {
5138 cmd_sep = "\n";
5139 cmd_sep_len = 1;
5140 }
5141 else if (!strcmp (funcname, "commands-sc"))
5142 {
5143 cmd_sep = ";";
5144 cmd_sep_len = 1;
5145 }
5146 else /*if (!strcmp (funcname, "commands-usr"))*/
5147 {
5148 cmd_sep = argv[1];
5149 cmd_sep_len = strlen (cmd_sep);
5150 }
5151
5152 initialize_file_variables (file, 1 /* don't search for pattern vars */);
5153 set_file_variables (file, 1 /* early call */);
5154 chop_commands (cmds);
5155
5156 for (i = 0; i < cmds->ncommand_lines; i++)
5157 {
5158 char *p;
5159 char *in, *out, *ref;
5160
5161 /* Skip it if it has a '%' prefix or is blank. */
5162 if (cmds->lines_flags[i] & COMMAND_GETTER_SKIP_IT)
5163 continue;
5164 p = cmds->command_lines[i];
5165 while (isblank ((unsigned char)*p))
5166 p++;
5167 if (*p == '\0')
5168 continue;
5169
5170 /* --- copied from new_job() in job.c --- */
5171
5172 /* Collapse backslash-newline combinations that are inside variable
5173 or function references. These are left alone by the parser so
5174 that they will appear in the echoing of commands (where they look
5175 nice); and collapsed by construct_command_argv when it tokenizes.
5176 But letting them survive inside function invocations loses because
5177 we don't want the functions to see them as part of the text. */
5178
5179 /* IN points to where in the line we are scanning.
5180 OUT points to where in the line we are writing.
5181 When we collapse a backslash-newline combination,
5182 IN gets ahead of OUT. */
5183
5184 in = out = p;
5185 while ((ref = strchr (in, '$')) != 0)
5186 {
5187 ++ref; /* Move past the $. */
5188
5189 if (out != in)
5190 /* Copy the text between the end of the last chunk
5191 we processed (where IN points) and the new chunk
5192 we are about to process (where REF points). */
5193 memmove (out, in, ref - in);
5194
5195 /* Move both pointers past the boring stuff. */
5196 out += ref - in;
5197 in = ref;
5198
5199 if (*ref == '(' || *ref == '{')
5200 {
5201 char openparen = *ref;
5202 char closeparen = openparen == '(' ? ')' : '}';
5203 int count;
5204 char *p2;
5205
5206 *out++ = *in++; /* Copy OPENPAREN. */
5207 /* IN now points past the opening paren or brace.
5208 Count parens or braces until it is matched. */
5209 count = 0;
5210 while (*in != '\0')
5211 {
5212 if (*in == closeparen && --count < 0)
5213 break;
5214 else if (*in == '\\' && in[1] == '\n')
5215 {
5216 /* We have found a backslash-newline inside a
5217 variable or function reference. Eat it and
5218 any following whitespace. */
5219
5220 int quoted = 0;
5221 for (p2 = in - 1; p2 > ref && *p2 == '\\'; --p2)
5222 quoted = !quoted;
5223
5224 if (quoted)
5225 /* There were two or more backslashes, so this is
5226 not really a continuation line. We don't collapse
5227 the quoting backslashes here as is done in
5228 collapse_continuations, because the line will
5229 be collapsed again after expansion. */
5230 *out++ = *in++;
5231 else
5232 {
5233 /* Skip the backslash, newline and
5234 any following whitespace. */
5235 in = next_token (in + 2);
5236
5237 /* Discard any preceding whitespace that has
5238 already been written to the output. */
5239 while (out > ref
5240 && isblank ((unsigned char)out[-1]))
5241 --out;
5242
5243 /* Replace it all with a single space. */
5244 *out++ = ' ';
5245 }
5246 }
5247 else
5248 {
5249 if (*in == openparen)
5250 ++count;
5251
5252 *out++ = *in++;
5253 }
5254 }
5255 }
5256 /* Some of these can be amended ($< perhaps), but we're likely to be called while the
5257 dep expansion happens, so it would have to be on a hackish basis. sad... */
5258 else if (*ref == '<' || *ref == '*' || *ref == '%' || *ref == '^' || *ref == '+')
5259 error (reading_file, _("$(%s ) does not work reliably with $%c in all cases"), funcname, *ref);
5260 }
5261
5262 /* There are no more references in this line to worry about.
5263 Copy the remaining uninteresting text to the output. */
5264 if (out != in)
5265 strcpy (out, in);
5266
5267 /* --- copied from new_job() in job.c --- */
5268
5269 /* Finally, expand the line. */
5270 if (i)
5271 o = variable_buffer_output (o, cmd_sep, cmd_sep_len);
5272 o = variable_expand_for_file_2 (o, cmds->command_lines[i], ~0U, file, NULL);
5273
5274 /* Skip it if it has a '%' prefix or is blank. */
5275 p = o;
5276 while (isblank ((unsigned char)*o)
5277 || *o == '@'
5278 || *o == '-'
5279 || *o == '+')
5280 o++;
5281 if (*o != '\0' && *o != '%')
5282 o = strchr (o, '\0');
5283 else if (i)
5284 o = p - cmd_sep_len;
5285 else
5286 o = p;
5287 } /* for each command line */
5288 }
5289 /* else FIXME: bitch about it? */
5290
5291 recursive = 0;
5292 return o;
5293}
5294#endif /* CONFIG_WITH_COMMANDS_FUNC */
5295#ifdef KMK
5296
5297/* Useful when debugging kmk and/or makefiles. */
5298char *
5299func_breakpoint (char *o, char **argv UNUSED, const char *funcname UNUSED)
5300{
5301#ifdef _MSC_VER
5302 __debugbreak();
5303#elif defined(__i386__) || defined(__x86__) || defined(__X86__) || defined(_M_IX86) || defined(__i386) \
5304 || defined(__amd64__) || defined(__x86_64__) || defined(__AMD64__) || defined(_M_X64) || defined(__amd64)
5305# ifdef __sun__
5306 __asm__ __volatile__ ("int $3\n\t");
5307# else
5308 __asm__ __volatile__ ("int3\n\t");
5309# endif
5310#else
5311 char *p = (char *)0;
5312 *p = '\0';
5313#endif
5314 return o;
5315}
5316
5317/* umask | umask -S. */
5318char *
5319func_get_umask (char *o, char **argv UNUSED, const char *funcname UNUSED)
5320{
5321 char sz[80];
5322 int off;
5323 mode_t u;
5324 int symbolic = 0;
5325 const char *psz = argv[0];
5326
5327 if (psz)
5328 {
5329 const char *pszEnd = strchr (psz, '\0');
5330 strip_whitespace (&psz, &pszEnd);
5331
5332 if (pszEnd != psz)
5333 {
5334 if ( STR_N_EQUALS (psz, pszEnd - pszEnd, "S")
5335 || STR_N_EQUALS (psz, pszEnd - pszEnd, "-S")
5336 || STR_N_EQUALS (psz, pszEnd - pszEnd, "symbolic") )
5337 symbolic = 1;
5338 else
5339 error (reading_file, _("$(%s ) invalid argument `%s'"),
5340 funcname, argv[0]);
5341 }
5342 }
5343
5344 u = umask (002);
5345 umask (u);
5346
5347 if (symbolic)
5348 {
5349 off = 0;
5350 sz[off++] = 'u';
5351 sz[off++] = '=';
5352 if ((u & S_IRUSR) == 0)
5353 sz[off++] = 'r';
5354 if ((u & S_IWUSR) == 0)
5355 sz[off++] = 'w';
5356 if ((u & S_IXUSR) == 0)
5357 sz[off++] = 'x';
5358 sz[off++] = ',';
5359 sz[off++] = 'g';
5360 sz[off++] = '=';
5361 if ((u & S_IRGRP) == 0)
5362 sz[off++] = 'r';
5363 if ((u & S_IWGRP) == 0)
5364 sz[off++] = 'w';
5365 if ((u & S_IXGRP) == 0)
5366 sz[off++] = 'x';
5367 sz[off++] = ',';
5368 sz[off++] = 'o';
5369 sz[off++] = '=';
5370 if ((u & S_IROTH) == 0)
5371 sz[off++] = 'r';
5372 if ((u & S_IWOTH) == 0)
5373 sz[off++] = 'w';
5374 if ((u & S_IXOTH) == 0)
5375 sz[off++] = 'x';
5376 }
5377 else
5378 off = sprintf (sz, "%.4o", u);
5379
5380 return variable_buffer_output (o, sz, off);
5381}
5382
5383
5384/* umask 0002 | umask u=rwx,g=rwx,o=rx. */
5385char *
5386func_set_umask (char *o, char **argv UNUSED, const char *funcname UNUSED)
5387{
5388 mode_t u;
5389 const char *psz;
5390
5391 /* Figure what kind of input this is. */
5392 psz = argv[0];
5393 while (isblank ((unsigned char)*psz))
5394 psz++;
5395
5396 if (isdigit ((unsigned char)*psz))
5397 {
5398 u = 0;
5399 while (*psz)
5400 {
5401 u <<= 3;
5402 if (*psz < '0' || *psz >= '8')
5403 {
5404 error (reading_file, _("$(%s ) illegal number `%s'"), funcname, argv[0]);
5405 break;
5406 }
5407 u += *psz - '0';
5408 psz++;
5409 }
5410
5411 if (argv[1] != NULL)
5412 error (reading_file, _("$(%s ) too many arguments for octal mode"), funcname);
5413 }
5414 else
5415 {
5416 u = umask(0);
5417 umask(u);
5418 error (reading_file, _("$(%s ) symbol mode is not implemented"), funcname);
5419 }
5420
5421 umask(u);
5422
5423 return o;
5424}
5425
5426#endif /* KMK */
5427
5428
5429/* Lookup table for builtin functions.
5430
5431 This doesn't have to be sorted; we use a straight lookup. We might gain
5432 some efficiency by moving most often used functions to the start of the
5433 table.
5434
5435 If MAXIMUM_ARGS is 0, that means there is no maximum and all
5436 comma-separated values are treated as arguments.
5437
5438 EXPAND_ARGS means that all arguments should be expanded before invocation.
5439 Functions that do namespace tricks (foreach) don't automatically expand. */
5440
5441static char *func_call (char *o, char **argv, const char *funcname);
5442
5443
5444static struct function_table_entry function_table_init[] =
5445{
5446 /* Name/size */ /* MIN MAX EXP? Function */
5447 { STRING_SIZE_TUPLE("abspath"), 0, 1, 1, func_abspath},
5448 { STRING_SIZE_TUPLE("addprefix"), 2, 2, 1, func_addsuffix_addprefix},
5449 { STRING_SIZE_TUPLE("addsuffix"), 2, 2, 1, func_addsuffix_addprefix},
5450 { STRING_SIZE_TUPLE("basename"), 0, 1, 1, func_basename_dir},
5451 { STRING_SIZE_TUPLE("dir"), 0, 1, 1, func_basename_dir},
5452 { STRING_SIZE_TUPLE("notdir"), 0, 1, 1, func_notdir_suffix},
5453#ifdef CONFIG_WITH_ROOT_FUNC
5454 { STRING_SIZE_TUPLE("root"), 0, 1, 1, func_root},
5455 { STRING_SIZE_TUPLE("notroot"), 0, 1, 1, func_notroot},
5456#endif
5457 { STRING_SIZE_TUPLE("subst"), 3, 3, 1, func_subst},
5458 { STRING_SIZE_TUPLE("suffix"), 0, 1, 1, func_notdir_suffix},
5459 { STRING_SIZE_TUPLE("filter"), 2, 2, 1, func_filter_filterout},
5460 { STRING_SIZE_TUPLE("filter-out"), 2, 2, 1, func_filter_filterout},
5461 { STRING_SIZE_TUPLE("findstring"), 2, 2, 1, func_findstring},
5462#ifdef CONFIG_WITH_DEFINED_FUNCTIONS
5463 { STRING_SIZE_TUPLE("firstdefined"), 0, 2, 1, func_firstdefined},
5464#endif
5465 { STRING_SIZE_TUPLE("firstword"), 0, 1, 1, func_firstword},
5466 { STRING_SIZE_TUPLE("flavor"), 0, 1, 1, func_flavor},
5467 { STRING_SIZE_TUPLE("join"), 2, 2, 1, func_join},
5468#ifdef CONFIG_WITH_DEFINED_FUNCTIONS
5469 { STRING_SIZE_TUPLE("lastdefined"), 0, 2, 1, func_lastdefined},
5470#endif
5471 { STRING_SIZE_TUPLE("lastword"), 0, 1, 1, func_lastword},
5472 { STRING_SIZE_TUPLE("patsubst"), 3, 3, 1, func_patsubst},
5473 { STRING_SIZE_TUPLE("realpath"), 0, 1, 1, func_realpath},
5474#ifdef CONFIG_WITH_RSORT
5475 { STRING_SIZE_TUPLE("rsort"), 0, 1, 1, func_sort},
5476#endif
5477 { STRING_SIZE_TUPLE("shell"), 0, 1, 1, func_shell},
5478 { STRING_SIZE_TUPLE("sort"), 0, 1, 1, func_sort},
5479 { STRING_SIZE_TUPLE("strip"), 0, 1, 1, func_strip},
5480#ifdef CONFIG_WITH_WHERE_FUNCTION
5481 { STRING_SIZE_TUPLE("where"), 0, 1, 1, func_where},
5482#endif
5483 { STRING_SIZE_TUPLE("wildcard"), 0, 1, 1, func_wildcard},
5484 { STRING_SIZE_TUPLE("word"), 2, 2, 1, func_word},
5485 { STRING_SIZE_TUPLE("wordlist"), 3, 3, 1, func_wordlist},
5486 { STRING_SIZE_TUPLE("words"), 0, 1, 1, func_words},
5487 { STRING_SIZE_TUPLE("origin"), 0, 1, 1, func_origin},
5488 { STRING_SIZE_TUPLE("foreach"), 3, 3, 0, func_foreach},
5489#ifdef CONFIG_WITH_LOOP_FUNCTIONS
5490 { STRING_SIZE_TUPLE("for"), 4, 4, 0, func_for},
5491 { STRING_SIZE_TUPLE("while"), 2, 2, 0, func_while},
5492#endif
5493 { STRING_SIZE_TUPLE("call"), 1, 0, 1, func_call},
5494 { STRING_SIZE_TUPLE("info"), 0, 1, 1, func_error},
5495 { STRING_SIZE_TUPLE("error"), 0, 1, 1, func_error},
5496 { STRING_SIZE_TUPLE("warning"), 0, 1, 1, func_error},
5497 { STRING_SIZE_TUPLE("if"), 2, 3, 0, func_if},
5498 { STRING_SIZE_TUPLE("or"), 1, 0, 0, func_or},
5499 { STRING_SIZE_TUPLE("and"), 1, 0, 0, func_and},
5500 { STRING_SIZE_TUPLE("value"), 0, 1, 1, func_value},
5501 { STRING_SIZE_TUPLE("eval"), 0, 1, 1, func_eval},
5502#ifdef CONFIG_WITH_EVALPLUS
5503 { STRING_SIZE_TUPLE("evalctx"), 0, 1, 1, func_evalctx},
5504 { STRING_SIZE_TUPLE("evalval"), 1, 1, 1, func_evalval},
5505 { STRING_SIZE_TUPLE("evalvalctx"), 1, 1, 1, func_evalval},
5506 { STRING_SIZE_TUPLE("evalcall"), 1, 0, 1, func_call},
5507 { STRING_SIZE_TUPLE("evalcall2"), 1, 0, 1, func_call},
5508 { STRING_SIZE_TUPLE("eval-opt-var"), 1, 0, 1, func_eval_optimize_variable},
5509#endif
5510#ifdef EXPERIMENTAL
5511 { STRING_SIZE_TUPLE("eq"), 2, 2, 1, func_eq},
5512 { STRING_SIZE_TUPLE("not"), 0, 1, 1, func_not},
5513#endif
5514#ifdef CONFIG_WITH_STRING_FUNCTIONS
5515 { STRING_SIZE_TUPLE("length"), 1, 1, 1, func_length},
5516 { STRING_SIZE_TUPLE("length-var"), 1, 1, 1, func_length_var},
5517 { STRING_SIZE_TUPLE("insert"), 2, 5, 1, func_insert},
5518 { STRING_SIZE_TUPLE("pos"), 2, 3, 1, func_pos},
5519 { STRING_SIZE_TUPLE("lastpos"), 2, 3, 1, func_pos},
5520 { STRING_SIZE_TUPLE("substr"), 2, 4, 1, func_substr},
5521 { STRING_SIZE_TUPLE("translate"), 2, 4, 1, func_translate},
5522#endif
5523#ifdef CONFIG_WITH_PRINTF
5524 { STRING_SIZE_TUPLE("printf"), 1, 0, 1, kmk_builtin_func_printf},
5525#endif
5526#ifdef CONFIG_WITH_LAZY_DEPS_VARS
5527 { STRING_SIZE_TUPLE("deps"), 1, 2, 1, func_deps},
5528 { STRING_SIZE_TUPLE("deps-all"), 1, 2, 1, func_deps},
5529 { STRING_SIZE_TUPLE("deps-newer"), 1, 2, 1, func_deps_newer},
5530 { STRING_SIZE_TUPLE("deps-oo"), 1, 2, 1, func_deps_order_only},
5531#endif
5532#ifdef CONFIG_WITH_DEFINED
5533 { STRING_SIZE_TUPLE("defined"), 1, 1, 1, func_defined},
5534#endif
5535#ifdef CONFIG_WITH_TOUPPER_TOLOWER
5536 { STRING_SIZE_TUPLE("toupper"), 0, 1, 1, func_toupper_tolower},
5537 { STRING_SIZE_TUPLE("tolower"), 0, 1, 1, func_toupper_tolower},
5538#endif
5539#ifdef CONFIG_WITH_ABSPATHEX
5540 { STRING_SIZE_TUPLE("abspathex"), 0, 2, 1, func_abspathex},
5541#endif
5542#ifdef CONFIG_WITH_XARGS
5543 { STRING_SIZE_TUPLE("xargs"), 2, 0, 1, func_xargs},
5544#endif
5545#if defined(CONFIG_WITH_VALUE_LENGTH) && defined(CONFIG_WITH_COMPARE)
5546 { STRING_SIZE_TUPLE("comp-vars"), 3, 3, 1, func_comp_vars},
5547 { STRING_SIZE_TUPLE("comp-cmds"), 3, 3, 1, func_comp_vars},
5548 { STRING_SIZE_TUPLE("comp-cmds-ex"), 3, 3, 1, func_comp_cmds_ex},
5549#endif
5550#ifdef CONFIG_WITH_DATE
5551 { STRING_SIZE_TUPLE("date"), 0, 1, 1, func_date},
5552 { STRING_SIZE_TUPLE("date-utc"), 0, 3, 1, func_date},
5553#endif
5554#ifdef CONFIG_WITH_FILE_SIZE
5555 { STRING_SIZE_TUPLE("file-size"), 1, 1, 1, func_file_size},
5556#endif
5557#ifdef CONFIG_WITH_WHICH
5558 { STRING_SIZE_TUPLE("which"), 0, 0, 1, func_which},
5559#endif
5560#ifdef CONFIG_WITH_IF_CONDITIONALS
5561 { STRING_SIZE_TUPLE("expr"), 1, 1, 0, func_expr},
5562 { STRING_SIZE_TUPLE("if-expr"), 2, 3, 0, func_if_expr},
5563 { STRING_SIZE_TUPLE("select"), 2, 0, 0, func_select},
5564#endif
5565#ifdef CONFIG_WITH_SET_CONDITIONALS
5566 { STRING_SIZE_TUPLE("intersects"), 2, 2, 1, func_set_intersects},
5567#endif
5568#ifdef CONFIG_WITH_STACK
5569 { STRING_SIZE_TUPLE("stack-push"), 2, 2, 1, func_stack_push},
5570 { STRING_SIZE_TUPLE("stack-pop"), 1, 1, 1, func_stack_pop_top},
5571 { STRING_SIZE_TUPLE("stack-popv"), 1, 1, 1, func_stack_pop_top},
5572 { STRING_SIZE_TUPLE("stack-top"), 1, 1, 1, func_stack_pop_top},
5573#endif
5574#ifdef CONFIG_WITH_MATH
5575 { STRING_SIZE_TUPLE("int-add"), 2, 0, 1, func_int_add},
5576 { STRING_SIZE_TUPLE("int-sub"), 2, 0, 1, func_int_sub},
5577 { STRING_SIZE_TUPLE("int-mul"), 2, 0, 1, func_int_mul},
5578 { STRING_SIZE_TUPLE("int-div"), 2, 0, 1, func_int_div},
5579 { STRING_SIZE_TUPLE("int-mod"), 2, 2, 1, func_int_mod},
5580 { STRING_SIZE_TUPLE("int-not"), 1, 1, 1, func_int_not},
5581 { STRING_SIZE_TUPLE("int-and"), 2, 0, 1, func_int_and},
5582 { STRING_SIZE_TUPLE("int-or"), 2, 0, 1, func_int_or},
5583 { STRING_SIZE_TUPLE("int-xor"), 2, 0, 1, func_int_xor},
5584 { STRING_SIZE_TUPLE("int-eq"), 2, 2, 1, func_int_cmp},
5585 { STRING_SIZE_TUPLE("int-ne"), 2, 2, 1, func_int_cmp},
5586 { STRING_SIZE_TUPLE("int-gt"), 2, 2, 1, func_int_cmp},
5587 { STRING_SIZE_TUPLE("int-ge"), 2, 2, 1, func_int_cmp},
5588 { STRING_SIZE_TUPLE("int-lt"), 2, 2, 1, func_int_cmp},
5589 { STRING_SIZE_TUPLE("int-le"), 2, 2, 1, func_int_cmp},
5590#endif
5591#ifdef CONFIG_WITH_NANOTS
5592 { STRING_SIZE_TUPLE("nanots"), 0, 0, 0, func_nanots},
5593#endif
5594#ifdef CONFIG_WITH_OS2_LIBPATH
5595 { STRING_SIZE_TUPLE("libpath"), 1, 2, 1, func_os2_libpath},
5596#endif
5597#if defined (CONFIG_WITH_MAKE_STATS) || defined (CONFIG_WITH_MINIMAL_STATS)
5598 { STRING_SIZE_TUPLE("make-stats"), 0, 0, 0, func_make_stats},
5599#endif
5600#ifdef CONFIG_WITH_COMMANDS_FUNC
5601 { STRING_SIZE_TUPLE("commands"), 1, 1, 1, func_commands},
5602 { STRING_SIZE_TUPLE("commands-sc"), 1, 1, 1, func_commands},
5603 { STRING_SIZE_TUPLE("commands-usr"), 2, 2, 1, func_commands},
5604#endif
5605#ifdef KMK_HELPERS
5606 { STRING_SIZE_TUPLE("kb-src-tool"), 1, 1, 0, func_kbuild_source_tool},
5607 { STRING_SIZE_TUPLE("kb-obj-base"), 1, 1, 0, func_kbuild_object_base},
5608 { STRING_SIZE_TUPLE("kb-obj-suff"), 1, 1, 0, func_kbuild_object_suffix},
5609 { STRING_SIZE_TUPLE("kb-src-prop"), 3, 4, 0, func_kbuild_source_prop},
5610 { STRING_SIZE_TUPLE("kb-src-one"), 0, 1, 0, func_kbuild_source_one},
5611 { STRING_SIZE_TUPLE("kb-exp-tmpl"), 6, 6, 1, func_kbuild_expand_template},
5612#endif
5613#ifdef KMK
5614 { STRING_SIZE_TUPLE("breakpoint"), 0, 0, 0, func_breakpoint},
5615 { STRING_SIZE_TUPLE("set-umask"), 1, 3, 1, func_set_umask},
5616 { STRING_SIZE_TUPLE("get-umask"), 0, 0, 0, func_get_umask},
5617#endif
5618};
5619
5620#define FUNCTION_TABLE_ENTRIES (sizeof (function_table_init) / sizeof (struct function_table_entry))
5621
5622
5623
5624/* These must come after the definition of function_table. */
5625
5626static char *
5627expand_builtin_function (char *o, int argc, char **argv,
5628 const struct function_table_entry *entry_p)
5629{
5630 if (argc < (int)entry_p->minimum_args)
5631 fatal (*expanding_var,
5632 _("insufficient number of arguments (%d) to function `%s'"),
5633 argc, entry_p->name);
5634
5635 /* I suppose technically some function could do something with no
5636 arguments, but so far none do, so just test it for all functions here
5637 rather than in each one. We can change it later if necessary. */
5638
5639 if (!argc)
5640 return o;
5641
5642 if (!entry_p->func_ptr)
5643 fatal (*expanding_var,
5644 _("unimplemented on this platform: function `%s'"), entry_p->name);
5645
5646 return entry_p->func_ptr (o, argv, entry_p->name);
5647}
5648
5649/* Check for a function invocation in *STRINGP. *STRINGP points at the
5650 opening ( or { and is not null-terminated. If a function invocation
5651 is found, expand it into the buffer at *OP, updating *OP, incrementing
5652 *STRINGP past the reference and returning nonzero. If not, return zero. */
5653
5654static int
5655handle_function2 (const struct function_table_entry *entry_p, char **op, const char **stringp) /* bird split it up. */
5656{
5657 char openparen = (*stringp)[0];
5658 char closeparen = openparen == '(' ? ')' : '}';
5659 const char *beg;
5660 const char *end;
5661 int count = 0;
5662 char *abeg = NULL;
5663 char **argv, **argvp;
5664 int nargs;
5665
5666 beg = *stringp + 1;
5667
5668 /* We found a builtin function. Find the beginning of its arguments (skip
5669 whitespace after the name). */
5670
5671 beg = next_token (beg + entry_p->len);
5672
5673 /* Find the end of the function invocation, counting nested use of
5674 whichever kind of parens we use. Since we're looking, count commas
5675 to get a rough estimate of how many arguments we might have. The
5676 count might be high, but it'll never be low. */
5677
5678 for (nargs=1, end=beg; *end != '\0'; ++end)
5679 if (*end == ',')
5680 ++nargs;
5681 else if (*end == openparen)
5682 ++count;
5683 else if (*end == closeparen && --count < 0)
5684 break;
5685
5686 if (count >= 0)
5687 fatal (*expanding_var,
5688 _("unterminated call to function `%s': missing `%c'"),
5689 entry_p->name, closeparen);
5690
5691 *stringp = end;
5692
5693 /* Get some memory to store the arg pointers. */
5694 argvp = argv = alloca (sizeof (char *) * (nargs + 2));
5695
5696 /* Chop the string into arguments, then a nul. As soon as we hit
5697 MAXIMUM_ARGS (if it's >0) assume the rest of the string is part of the
5698 last argument.
5699
5700 If we're expanding, store pointers to the expansion of each one. If
5701 not, make a duplicate of the string and point into that, nul-terminating
5702 each argument. */
5703
5704 if (entry_p->expand_args)
5705 {
5706 const char *p;
5707 for (p=beg, nargs=0; p <= end; ++argvp)
5708 {
5709 const char *next;
5710
5711 ++nargs;
5712
5713 if (nargs == entry_p->maximum_args
5714 || (! (next = find_next_argument (openparen, closeparen, p, end))))
5715 next = end;
5716
5717 *argvp = expand_argument (p, next);
5718 p = next + 1;
5719 }
5720 }
5721 else
5722 {
5723 int len = end - beg;
5724 char *p, *aend;
5725
5726 abeg = xmalloc (len+1);
5727 memcpy (abeg, beg, len);
5728 abeg[len] = '\0';
5729 aend = abeg + len;
5730
5731 for (p=abeg, nargs=0; p <= aend; ++argvp)
5732 {
5733 char *next;
5734
5735 ++nargs;
5736
5737 if (nargs == entry_p->maximum_args
5738 || (! (next = find_next_argument (openparen, closeparen, p, aend))))
5739 next = aend;
5740
5741 *argvp = p;
5742 *next = '\0';
5743 p = next + 1;
5744 }
5745 }
5746 *argvp = NULL;
5747
5748 /* Finally! Run the function... */
5749 *op = expand_builtin_function (*op, nargs, argv, entry_p);
5750
5751 /* Free memory. */
5752 if (entry_p->expand_args)
5753 for (argvp=argv; *argvp != 0; ++argvp)
5754 free (*argvp);
5755 if (abeg)
5756 free (abeg);
5757
5758 return 1;
5759}
5760
5761
5762int /* bird split it up and hacked it. */
5763#ifndef CONFIG_WITH_VALUE_LENGTH
5764handle_function (char **op, const char **stringp)
5765{
5766 const struct function_table_entry *entry_p = lookup_function (*stringp + 1);
5767 if (!entry_p)
5768 return 0;
5769 return handle_function2 (entry_p, op, stringp);
5770}
5771#else /* CONFIG_WITH_VALUE_LENGTH */
5772handle_function (char **op, const char **stringp, const char *nameend, const char *eol UNUSED)
5773{
5774 const char *fname = *stringp + 1;
5775 const struct function_table_entry *entry_p =
5776 lookup_function_in_hash_tab (fname, nameend - fname);
5777 if (!entry_p)
5778 return 0;
5779 return handle_function2 (entry_p, op, stringp);
5780}
5781#endif /* CONFIG_WITH_VALUE_LENGTH */
5782
5783
5784
5785/* User-defined functions. Expand the first argument as either a builtin
5786 function or a make variable, in the context of the rest of the arguments
5787 assigned to $1, $2, ... $N. $0 is the name of the function. */
5788
5789static char *
5790func_call (char *o, char **argv, const char *funcname UNUSED)
5791{
5792 static int max_args = 0;
5793 char *fname;
5794 char *cp;
5795 char *body;
5796 int flen;
5797 int i;
5798 int saved_args;
5799 const struct function_table_entry *entry_p;
5800 struct variable *v;
5801#ifdef CONFIG_WITH_EVALPLUS
5802 char *buf;
5803 unsigned int len;
5804#endif
5805#if defined (CONFIG_WITH_EVALPLUS) || defined (CONFIG_WITH_VALUE_LENGTH)
5806 char num[11];
5807#endif
5808
5809 /* There is no way to define a variable with a space in the name, so strip
5810 leading and trailing whitespace as a favor to the user. */
5811 fname = argv[0];
5812 while (*fname != '\0' && isspace ((unsigned char)*fname))
5813 ++fname;
5814
5815 cp = fname + strlen (fname) - 1;
5816 while (cp > fname && isspace ((unsigned char)*cp))
5817 --cp;
5818 cp[1] = '\0';
5819
5820 /* Calling nothing is a no-op */
5821 if (*fname == '\0')
5822 return o;
5823
5824 /* Are we invoking a builtin function? */
5825
5826#ifndef CONFIG_WITH_VALUE_LENGTH
5827 entry_p = lookup_function (fname);
5828#else
5829 entry_p = lookup_function (fname, cp - fname + 1);
5830#endif
5831 if (entry_p)
5832 {
5833 /* How many arguments do we have? */
5834 for (i=0; argv[i+1]; ++i)
5835 ;
5836 return expand_builtin_function (o, i, argv+1, entry_p);
5837 }
5838
5839 /* Not a builtin, so the first argument is the name of a variable to be
5840 expanded and interpreted as a function. Find it. */
5841 flen = strlen (fname);
5842
5843 v = lookup_variable (fname, flen);
5844
5845 if (v == 0)
5846 warn_undefined (fname, flen);
5847
5848 if (v == 0 || *v->value == '\0')
5849 return o;
5850
5851 body = alloca (flen + 4);
5852 body[0] = '$';
5853 body[1] = '(';
5854 memcpy (body + 2, fname, flen);
5855 body[flen+2] = ')';
5856 body[flen+3] = '\0';
5857
5858 /* Set up arguments $(1) .. $(N). $(0) is the function name. */
5859
5860 push_new_variable_scope ();
5861
5862 for (i=0; *argv; ++i, ++argv)
5863#ifdef CONFIG_WITH_VALUE_LENGTH
5864 define_variable (num, sprintf (num, "%d", i), *argv, o_automatic, 0);
5865#else
5866 {
5867 char num[11];
5868
5869 sprintf (num, "%d", i);
5870 define_variable (num, strlen (num), *argv, o_automatic, 0);
5871 }
5872#endif
5873
5874#ifdef CONFIG_WITH_EVALPLUS
5875 /* $(.ARGC) is the argument count. */
5876
5877 len = sprintf (num, "%d", i - 1);
5878 define_variable_vl (".ARGC", sizeof (".ARGC") - 1, num, len,
5879 1 /* dup val */, o_automatic, 0);
5880#endif
5881
5882 /* If the number of arguments we have is < max_args, it means we're inside
5883 a recursive invocation of $(call ...). Fill in the remaining arguments
5884 in the new scope with the empty value, to hide them from this
5885 invocation. */
5886
5887 for (; i < max_args; ++i)
5888#ifdef CONFIG_WITH_VALUE_LENGTH
5889 define_variable (num, sprintf (num, "%d", i), "", o_automatic, 0);
5890#else
5891 {
5892 char num[11];
5893
5894 sprintf (num, "%d", i);
5895 define_variable (num, strlen (num), "", o_automatic, 0);
5896 }
5897#endif
5898
5899 saved_args = max_args;
5900 max_args = i;
5901
5902#ifdef CONFIG_WITH_EVALPLUS
5903 if (!strcmp (funcname, "call"))
5904 {
5905#endif
5906 /* Expand the body in the context of the arguments, adding the result to
5907 the variable buffer. */
5908
5909 v->exp_count = EXP_COUNT_MAX;
5910#ifndef CONFIG_WITH_VALUE_LENGTH
5911 o = variable_expand_string (o, body, flen+3);
5912 v->exp_count = 0;
5913
5914 o += strlen (o);
5915#else /* CONFIG_WITH_VALUE_LENGTH */
5916 variable_expand_string_2 (o, body, flen+3, &o);
5917 v->exp_count = 0;
5918#endif /* CONFIG_WITH_VALUE_LENGTH */
5919#ifdef CONFIG_WITH_EVALPLUS
5920 }
5921 else
5922 {
5923 const struct floc *reading_file_saved = reading_file;
5924 char *eos;
5925
5926 if (!strcmp (funcname, "evalcall"))
5927 {
5928 /* Evaluate the variable value without expanding it. We
5929 need a copy since eval_buffer is destructive. */
5930
5931 size_t off = o - variable_buffer;
5932 eos = variable_buffer_output (o, v->value, v->value_length + 1) - 1;
5933 o = variable_buffer + off;
5934 if (v->fileinfo.filenm)
5935 reading_file = &v->fileinfo;
5936 }
5937 else
5938 {
5939 /* Expand the body first and then evaluate the output. */
5940
5941 v->exp_count = EXP_COUNT_MAX;
5942 o = variable_expand_string_2 (o, body, flen+3, &eos);
5943 v->exp_count = 0;
5944 }
5945
5946 install_variable_buffer (&buf, &len);
5947 eval_buffer (o, eos);
5948 restore_variable_buffer (buf, len);
5949 reading_file = reading_file_saved;
5950
5951 /* Deal with the .RETURN value if present. */
5952
5953 v = lookup_variable_in_set (".RETURN", sizeof (".RETURN") - 1,
5954 current_variable_set_list->set);
5955 if (v && v->value_length)
5956 {
5957 if (v->recursive)
5958 {
5959 v->exp_count = EXP_COUNT_MAX;
5960 variable_expand_string_2 (o, v->value, v->value_length, &o);
5961 v->exp_count = 0;
5962 }
5963 else
5964 o = variable_buffer_output (o, v->value, v->value_length);
5965 }
5966 }
5967#endif /* CONFIG_WITH_EVALPLUS */
5968
5969 max_args = saved_args;
5970
5971 pop_variable_scope ();
5972
5973 return o;
5974}
5975
5976void
5977hash_init_function_table (void)
5978{
5979 hash_init (&function_table, FUNCTION_TABLE_ENTRIES * 2,
5980 function_table_entry_hash_1, function_table_entry_hash_2,
5981 function_table_entry_hash_cmp);
5982 hash_load (&function_table, function_table_init,
5983 FUNCTION_TABLE_ENTRIES, sizeof (struct function_table_entry));
5984#if defined (CONFIG_WITH_OPTIMIZATION_HACKS) || defined (CONFIG_WITH_VALUE_LENGTH)
5985 {
5986 unsigned int i;
5987 for (i = 0; i < FUNCTION_TABLE_ENTRIES; i++)
5988 {
5989 const char *fn = function_table_init[i].name;
5990 while (*fn)
5991 {
5992 func_char_map[(int)*fn] = 1;
5993 fn++;
5994 }
5995 assert (function_table_init[i].len <= MAX_FUNCTION_LENGTH);
5996 assert (function_table_init[i].len >= MIN_FUNCTION_LENGTH);
5997 }
5998 }
5999#endif
6000}
Note: See TracBrowser for help on using the repository browser.

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