source: trunk/src/kmk/function.c@ 2702

Last change on this file since 2702 was 2702, checked in by bird, 12 years ago

kmk/WindowsNT: Avoiding unnecessary stat() calls. Reimplemented stat(), lstat(), fstat(), opendir(), readdir(), and closedir() using native NT APIs.

  • Property svn:eol-style set to native
File size: 158.8 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
2046 /* Make a copy of the value to the variable buffer since
2047 eval_buffer will make changes to its input. */
2048
2049 off = o - variable_buffer;
2050 variable_buffer_output (o, v->value, v->value_length + 1);
2051 o = variable_buffer + off;
2052
2053 /* Eval the value. Pop the current variable buffer setting so that the
2054 eval'd code can use its own without conflicting. (really necessary?) */
2055
2056 install_variable_buffer (&buf, &len);
2057 var_ctx = !strcmp (funcname, "evalvalctx");
2058 if (var_ctx)
2059 push_new_variable_scope ();
2060 if (v->fileinfo.filenm)
2061 reading_file = &v->fileinfo;
2062
2063 assert (!o[v->value_length]);
2064 eval_buffer (o, o + v->value_length);
2065
2066 reading_file = reading_file_saved;
2067 if (var_ctx)
2068 pop_variable_scope ();
2069 restore_variable_buffer (buf, len);
2070 }
2071
2072 return o;
2073}
2074
2075/* Optimizes the content of one or more variables to save time in
2076 the eval functions. This function will collapse line continuations
2077 and remove comments. */
2078static char *
2079func_eval_optimize_variable (char *o, char **argv, const char *funcname)
2080{
2081 unsigned int i;
2082
2083 for (i = 0; argv[i]; i++)
2084 {
2085 struct variable *v = lookup_variable (argv[i], strlen (argv[i]));
2086# ifdef CONFIG_WITH_RDONLY_VARIABLE_VALUE
2087 if (v && !v->origin != o_automatic && !v->rdonly_val)
2088# else
2089 if (v && !v->origin != o_automatic)
2090# endif
2091 {
2092 char *eos, *src;
2093
2094 eos = collapse_continuations (v->value, v->value_length);
2095 v->value_length = eos - v->value;
2096
2097 /* remove comments */
2098
2099 src = memchr (v->value, '#', v->value_length);
2100 if (src)
2101 {
2102 unsigned char ch = '\0';
2103 char *dst = src;
2104 do
2105 {
2106 /* drop blanks preceeding the comment */
2107 while (dst > v->value)
2108 {
2109 ch = (unsigned char)dst[-1];
2110 if (!isblank (ch))
2111 break;
2112 dst--;
2113 }
2114
2115 /* advance SRC to eol / eos. */
2116 src = memchr (src, '\n', eos - src);
2117 if (!src)
2118 break;
2119
2120 /* drop a preceeding newline if possible (full line comment) */
2121 if (dst > v->value && dst[-1] == '\n')
2122 dst--;
2123
2124 /* copy till next comment or eol. */
2125 while (src < eos)
2126 {
2127 ch = *src++;
2128 if (ch == '#')
2129 break;
2130 *dst++ = ch;
2131 }
2132 }
2133 while (ch == '#' && src < eos);
2134
2135 *dst = '\0';
2136 v->value_length = dst - v->value;
2137 }
2138 }
2139 else if (v)
2140 error (NILF, _("$(%s ): variable `%s' is of the wrong type\n"), funcname, v->name);
2141 }
2142
2143 return o;
2144}
2145
2146#endif /* CONFIG_WITH_EVALPLUS */
2147
2148static char *
2149func_value (char *o, char **argv, const char *funcname UNUSED)
2150{
2151 /* Look up the variable. */
2152 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
2153
2154 /* Copy its value into the output buffer without expanding it. */
2155 if (v)
2156#ifdef CONFIG_WITH_VALUE_LENGTH
2157 {
2158 assert (v->value_length == strlen (v->value));
2159 o = variable_buffer_output (o, v->value, v->value_length);
2160 }
2161#else
2162 o = variable_buffer_output (o, v->value, strlen(v->value));
2163#endif
2164
2165 return o;
2166}
2167
2168/*
2169 \r is replaced on UNIX as well. Is this desirable?
2170 */
2171static void
2172fold_newlines (char *buffer, unsigned int *length)
2173{
2174 char *dst = buffer;
2175 char *src = buffer;
2176 char *last_nonnl = buffer -1;
2177 src[*length] = 0;
2178 for (; *src != '\0'; ++src)
2179 {
2180 if (src[0] == '\r' && src[1] == '\n')
2181 continue;
2182 if (*src == '\n')
2183 {
2184 *dst++ = ' ';
2185 }
2186 else
2187 {
2188 last_nonnl = dst;
2189 *dst++ = *src;
2190 }
2191 }
2192 *(++last_nonnl) = '\0';
2193 *length = last_nonnl - buffer;
2194}
2195
2196
2197
2198int shell_function_pid = 0, shell_function_completed;
2199
2200
2201#ifdef WINDOWS32
2202/*untested*/
2203
2204#include <windows.h>
2205#include <io.h>
2206#include "sub_proc.h"
2207
2208
2209void
2210windows32_openpipe (int *pipedes, pid_t *pid_p, char **command_argv, char **envp)
2211{
2212 SECURITY_ATTRIBUTES saAttr;
2213 HANDLE hIn;
2214 HANDLE hErr;
2215 HANDLE hChildOutRd;
2216 HANDLE hChildOutWr;
2217 HANDLE hProcess;
2218
2219
2220 saAttr.nLength = sizeof (SECURITY_ATTRIBUTES);
2221 saAttr.bInheritHandle = TRUE;
2222 saAttr.lpSecurityDescriptor = NULL;
2223
2224 if (DuplicateHandle (GetCurrentProcess(),
2225 GetStdHandle(STD_INPUT_HANDLE),
2226 GetCurrentProcess(),
2227 &hIn,
2228 0,
2229 TRUE,
2230 DUPLICATE_SAME_ACCESS) == FALSE) {
2231 fatal (NILF, _("windows32_openpipe(): DuplicateHandle(In) failed (e=%ld)\n"),
2232 GetLastError());
2233
2234 }
2235 if (DuplicateHandle(GetCurrentProcess(),
2236 GetStdHandle(STD_ERROR_HANDLE),
2237 GetCurrentProcess(),
2238 &hErr,
2239 0,
2240 TRUE,
2241 DUPLICATE_SAME_ACCESS) == FALSE) {
2242 fatal (NILF, _("windows32_open_pipe(): DuplicateHandle(Err) failed (e=%ld)\n"),
2243 GetLastError());
2244 }
2245
2246 if (!CreatePipe(&hChildOutRd, &hChildOutWr, &saAttr, 0))
2247 fatal (NILF, _("CreatePipe() failed (e=%ld)\n"), GetLastError());
2248
2249 hProcess = process_init_fd(hIn, hChildOutWr, hErr);
2250
2251 if (!hProcess)
2252 fatal (NILF, _("windows32_openpipe(): process_init_fd() failed\n"));
2253
2254 /* make sure that CreateProcess() has Path it needs */
2255 sync_Path_environment();
2256 /* `sync_Path_environment' may realloc `environ', so take note of
2257 the new value. */
2258 envp = environ;
2259
2260 if (!process_begin(hProcess, command_argv, envp, command_argv[0], NULL)) {
2261 /* register process for wait */
2262 process_register(hProcess);
2263
2264 /* set the pid for returning to caller */
2265 *pid_p = (pid_t) hProcess;
2266
2267 /* set up to read data from child */
2268 pipedes[0] = _open_osfhandle((intptr_t) hChildOutRd, O_RDONLY);
2269
2270 /* this will be closed almost right away */
2271 pipedes[1] = _open_osfhandle((intptr_t) hChildOutWr, O_APPEND);
2272 } else {
2273 /* reap/cleanup the failed process */
2274 process_cleanup(hProcess);
2275
2276 /* close handles which were duplicated, they weren't used */
2277 CloseHandle(hIn);
2278 CloseHandle(hErr);
2279
2280 /* close pipe handles, they won't be used */
2281 CloseHandle(hChildOutRd);
2282 CloseHandle(hChildOutWr);
2283
2284 /* set status for return */
2285 pipedes[0] = pipedes[1] = -1;
2286 *pid_p = (pid_t)-1;
2287 }
2288}
2289#endif
2290
2291
2292#ifdef __MSDOS__
2293FILE *
2294msdos_openpipe (int* pipedes, int *pidp, char *text)
2295{
2296 FILE *fpipe=0;
2297 /* MSDOS can't fork, but it has `popen'. */
2298 struct variable *sh = lookup_variable ("SHELL", 5);
2299 int e;
2300 extern int dos_command_running, dos_status;
2301
2302 /* Make sure not to bother processing an empty line. */
2303 while (isblank ((unsigned char)*text))
2304 ++text;
2305 if (*text == '\0')
2306 return 0;
2307
2308 if (sh)
2309 {
2310 char buf[PATH_MAX + 7];
2311 /* This makes sure $SHELL value is used by $(shell), even
2312 though the target environment is not passed to it. */
2313 sprintf (buf, "SHELL=%s", sh->value);
2314 putenv (buf);
2315 }
2316
2317 e = errno;
2318 errno = 0;
2319 dos_command_running = 1;
2320 dos_status = 0;
2321 /* If dos_status becomes non-zero, it means the child process
2322 was interrupted by a signal, like SIGINT or SIGQUIT. See
2323 fatal_error_signal in commands.c. */
2324 fpipe = popen (text, "rt");
2325 dos_command_running = 0;
2326 if (!fpipe || dos_status)
2327 {
2328 pipedes[0] = -1;
2329 *pidp = -1;
2330 if (dos_status)
2331 errno = EINTR;
2332 else if (errno == 0)
2333 errno = ENOMEM;
2334 shell_function_completed = -1;
2335 }
2336 else
2337 {
2338 pipedes[0] = fileno (fpipe);
2339 *pidp = 42; /* Yes, the Meaning of Life, the Universe, and Everything! */
2340 errno = e;
2341 shell_function_completed = 1;
2342 }
2343 return fpipe;
2344}
2345#endif
2346
2347/*
2348 Do shell spawning, with the naughty bits for different OSes.
2349 */
2350
2351#ifdef VMS
2352
2353/* VMS can't do $(shell ...) */
2354#define func_shell 0
2355
2356#else
2357#ifndef _AMIGA
2358static char *
2359func_shell (char * volatile o, char **argv, const char *funcname UNUSED)
2360{
2361 char *batch_filename = NULL;
2362
2363#ifdef __MSDOS__
2364 FILE *fpipe;
2365#endif
2366 char **command_argv;
2367 const char * volatile error_prefix; /* bird: this volatile and the 'o' one, is for shutting up gcc warnings */
2368 char **envp;
2369 int pipedes[2];
2370 pid_t pid;
2371
2372#ifndef __MSDOS__
2373 /* Construct the argument list. */
2374 command_argv = construct_command_argv (argv[0], NULL, NULL, 0,
2375 &batch_filename);
2376 if (command_argv == 0)
2377 return o;
2378#endif
2379
2380 /* Using a target environment for `shell' loses in cases like:
2381 export var = $(shell echo foobie)
2382 because target_environment hits a loop trying to expand $(var)
2383 to put it in the environment. This is even more confusing when
2384 var was not explicitly exported, but just appeared in the
2385 calling environment.
2386
2387 See Savannah bug #10593.
2388
2389 envp = target_environment (NILF);
2390 */
2391
2392 envp = environ;
2393
2394 /* For error messages. */
2395 if (reading_file && reading_file->filenm)
2396 {
2397 char *p = alloca (strlen (reading_file->filenm)+11+4);
2398 sprintf (p, "%s:%lu: ", reading_file->filenm, reading_file->lineno);
2399 error_prefix = p;
2400 }
2401 else
2402 error_prefix = "";
2403
2404#if defined(__MSDOS__)
2405 fpipe = msdos_openpipe (pipedes, &pid, argv[0]);
2406 if (pipedes[0] < 0)
2407 {
2408 perror_with_name (error_prefix, "pipe");
2409 return o;
2410 }
2411#elif defined(WINDOWS32)
2412 windows32_openpipe (pipedes, &pid, command_argv, envp);
2413 if (pipedes[0] < 0)
2414 {
2415 /* open of the pipe failed, mark as failed execution */
2416 shell_function_completed = -1;
2417
2418 return o;
2419 }
2420 else
2421#else
2422 if (pipe (pipedes) < 0)
2423 {
2424 perror_with_name (error_prefix, "pipe");
2425 return o;
2426 }
2427
2428# ifdef __EMX__
2429 /* close some handles that are unnecessary for the child process */
2430 CLOSE_ON_EXEC(pipedes[1]);
2431 CLOSE_ON_EXEC(pipedes[0]);
2432 /* Never use fork()/exec() here! Use spawn() instead in exec_command() */
2433 pid = child_execute_job (0, pipedes[1], command_argv, envp);
2434 if (pid < 0)
2435 perror_with_name (error_prefix, "spawn");
2436# else /* ! __EMX__ */
2437 pid = vfork ();
2438 if (pid < 0)
2439 perror_with_name (error_prefix, "fork");
2440 else if (pid == 0)
2441 child_execute_job (0, pipedes[1], command_argv, envp);
2442 else
2443# endif
2444#endif
2445 {
2446 /* We are the parent. */
2447 char *buffer;
2448 unsigned int maxlen, i;
2449 int cc;
2450
2451 /* Record the PID for reap_children. */
2452 shell_function_pid = pid;
2453#ifndef __MSDOS__
2454 shell_function_completed = 0;
2455
2456 /* Free the storage only the child needed. */
2457 free (command_argv[0]);
2458 free (command_argv);
2459
2460 /* Close the write side of the pipe. We test for -1, since
2461 pipedes[1] is -1 on MS-Windows, and some versions of MS
2462 libraries barf when `close' is called with -1. */
2463 if (pipedes[1] >= 0)
2464 close (pipedes[1]);
2465#endif
2466
2467 /* Set up and read from the pipe. */
2468
2469 maxlen = 200;
2470 buffer = xmalloc (maxlen + 1);
2471
2472 /* Read from the pipe until it gets EOF. */
2473 for (i = 0; ; i += cc)
2474 {
2475 if (i == maxlen)
2476 {
2477 maxlen += 512;
2478 buffer = xrealloc (buffer, maxlen + 1);
2479 }
2480
2481 EINTRLOOP (cc, read (pipedes[0], &buffer[i], maxlen - i));
2482 if (cc <= 0)
2483 break;
2484 }
2485 buffer[i] = '\0';
2486
2487 /* Close the read side of the pipe. */
2488#ifdef __MSDOS__
2489 if (fpipe)
2490 (void) pclose (fpipe);
2491#else
2492# ifdef _MSC_VER /* Avoid annoying msvcrt when debugging. (bird) */
2493 if (pipedes[0] != -1)
2494# endif
2495 (void) close (pipedes[0]);
2496#endif
2497
2498 /* Loop until child_handler or reap_children() sets
2499 shell_function_completed to the status of our child shell. */
2500 while (shell_function_completed == 0)
2501 reap_children (1, 0);
2502
2503 if (batch_filename) {
2504 DB (DB_VERBOSE, (_("Cleaning up temporary batch file %s\n"),
2505 batch_filename));
2506 remove (batch_filename);
2507 free (batch_filename);
2508 }
2509 shell_function_pid = 0;
2510
2511 /* The child_handler function will set shell_function_completed
2512 to 1 when the child dies normally, or to -1 if it
2513 dies with status 127, which is most likely an exec fail. */
2514
2515 if (shell_function_completed == -1)
2516 {
2517 /* This likely means that the execvp failed, so we should just
2518 write the error message in the pipe from the child. */
2519 fputs (buffer, stderr);
2520 fflush (stderr);
2521 }
2522 else
2523 {
2524 /* The child finished normally. Replace all newlines in its output
2525 with spaces, and put that in the variable output buffer. */
2526 fold_newlines (buffer, &i);
2527 o = variable_buffer_output (o, buffer, i);
2528 }
2529
2530 free (buffer);
2531 }
2532
2533 return o;
2534}
2535
2536#else /* _AMIGA */
2537
2538/* Do the Amiga version of func_shell. */
2539
2540static char *
2541func_shell (char *o, char **argv, const char *funcname)
2542{
2543 /* Amiga can't fork nor spawn, but I can start a program with
2544 redirection of my choice. However, this means that we
2545 don't have an opportunity to reopen stdout to trap it. Thus,
2546 we save our own stdout onto a new descriptor and dup a temp
2547 file's descriptor onto our stdout temporarily. After we
2548 spawn the shell program, we dup our own stdout back to the
2549 stdout descriptor. The buffer reading is the same as above,
2550 except that we're now reading from a file. */
2551
2552#include <dos/dos.h>
2553#include <proto/dos.h>
2554
2555 BPTR child_stdout;
2556 char tmp_output[FILENAME_MAX];
2557 unsigned int maxlen = 200, i;
2558 int cc;
2559 char * buffer, * ptr;
2560 char ** aptr;
2561 int len = 0;
2562 char* batch_filename = NULL;
2563
2564 /* Construct the argument list. */
2565 command_argv = construct_command_argv (argv[0], NULL, NULL, 0,
2566 &batch_filename);
2567 if (command_argv == 0)
2568 return o;
2569
2570 /* Note the mktemp() is a security hole, but this only runs on Amiga.
2571 Ideally we would use main.c:open_tmpfile(), but this uses a special
2572 Open(), not fopen(), and I'm not familiar enough with the code to mess
2573 with it. */
2574 strcpy (tmp_output, "t:MakeshXXXXXXXX");
2575 mktemp (tmp_output);
2576 child_stdout = Open (tmp_output, MODE_NEWFILE);
2577
2578 for (aptr=command_argv; *aptr; aptr++)
2579 len += strlen (*aptr) + 1;
2580
2581 buffer = xmalloc (len + 1);
2582 ptr = buffer;
2583
2584 for (aptr=command_argv; *aptr; aptr++)
2585 {
2586 strcpy (ptr, *aptr);
2587 ptr += strlen (ptr) + 1;
2588 *ptr ++ = ' ';
2589 *ptr = 0;
2590 }
2591
2592 ptr[-1] = '\n';
2593
2594 Execute (buffer, NULL, child_stdout);
2595 free (buffer);
2596
2597 Close (child_stdout);
2598
2599 child_stdout = Open (tmp_output, MODE_OLDFILE);
2600
2601 buffer = xmalloc (maxlen);
2602 i = 0;
2603 do
2604 {
2605 if (i == maxlen)
2606 {
2607 maxlen += 512;
2608 buffer = xrealloc (buffer, maxlen + 1);
2609 }
2610
2611 cc = Read (child_stdout, &buffer[i], maxlen - i);
2612 if (cc > 0)
2613 i += cc;
2614 } while (cc > 0);
2615
2616 Close (child_stdout);
2617
2618 fold_newlines (buffer, &i);
2619 o = variable_buffer_output (o, buffer, i);
2620 free (buffer);
2621 return o;
2622}
2623#endif /* _AMIGA */
2624#endif /* !VMS */
2625
2626#ifdef EXPERIMENTAL
2627
2628/*
2629 equality. Return is string-boolean, ie, the empty string is false.
2630 */
2631static char *
2632func_eq (char *o, char **argv, const char *funcname UNUSED)
2633{
2634 int result = ! strcmp (argv[0], argv[1]);
2635 o = variable_buffer_output (o, result ? "1" : "", result);
2636 return o;
2637}
2638
2639
2640/*
2641 string-boolean not operator.
2642 */
2643static char *
2644func_not (char *o, char **argv, const char *funcname UNUSED)
2645{
2646 const char *s = argv[0];
2647 int result = 0;
2648 while (isspace ((unsigned char)*s))
2649 s++;
2650 result = ! (*s);
2651 o = variable_buffer_output (o, result ? "1" : "", result);
2652 return o;
2653}
2654#endif
2655
2656
2657#ifdef CONFIG_WITH_STRING_FUNCTIONS
2658/*
2659 $(length string)
2660
2661 XXX: This doesn't take multibyte locales into account.
2662 */
2663static char *
2664func_length (char *o, char **argv, const char *funcname UNUSED)
2665{
2666 size_t len = strlen (argv[0]);
2667 return math_int_to_variable_buffer (o, len);
2668}
2669
2670/*
2671 $(length-var var)
2672
2673 XXX: This doesn't take multibyte locales into account.
2674 */
2675static char *
2676func_length_var (char *o, char **argv, const char *funcname UNUSED)
2677{
2678 struct variable *var = lookup_variable (argv[0], strlen (argv[0]));
2679 return math_int_to_variable_buffer (o, var ? var->value_length : 0);
2680}
2681
2682
2683/* func_insert and func_substr helper. */
2684static char *
2685helper_pad (char *o, size_t to_add, const char *pad, size_t pad_len)
2686{
2687 while (to_add > 0)
2688 {
2689 size_t size = to_add > pad_len ? pad_len : to_add;
2690 o = variable_buffer_output (o, pad, size);
2691 to_add -= size;
2692 }
2693 return o;
2694}
2695
2696/*
2697 $(insert in, str[, n[, length[, pad]]])
2698
2699 XXX: This doesn't take multibyte locales into account.
2700 */
2701static char *
2702func_insert (char *o, char **argv, const char *funcname UNUSED)
2703{
2704 const char *in = argv[0];
2705 math_int in_len = (math_int)strlen (in);
2706 const char *str = argv[1];
2707 math_int str_len = (math_int)strlen (str);
2708 math_int n = 0;
2709 math_int length = str_len;
2710 const char *pad = " ";
2711 size_t pad_len = 16;
2712 size_t i;
2713
2714 if (argv[2] != NULL)
2715 {
2716 n = math_int_from_string (argv[2]);
2717 if (n > 0)
2718 n--; /* one-origin */
2719 else if (n == 0)
2720 n = str_len; /* append */
2721 else
2722 { /* n < 0: from the end */
2723 n = str_len + n;
2724 if (n < 0)
2725 n = 0;
2726 }
2727 if (n > 16*1024*1024) /* 16MB */
2728 fatal (NILF, _("$(insert ): n=%s is out of bounds\n"), argv[2]);
2729
2730 if (argv[3] != NULL)
2731 {
2732 length = math_int_from_string (argv[3]);
2733 if (length < 0 || length > 16*1024*1024 /* 16MB */)
2734 fatal (NILF, _("$(insert ): length=%s is out of bounds\n"), argv[3]);
2735
2736 if (argv[4] != NULL)
2737 {
2738 const char *tmp = argv[4];
2739 for (i = 0; tmp[i] == ' '; i++)
2740 /* nothing */;
2741 if (tmp[i] != '\0')
2742 {
2743 pad = argv[4];
2744 pad_len = strlen (pad);
2745 }
2746 /* else: it was all default spaces. */
2747 }
2748 }
2749 }
2750
2751 /* the head of the original string */
2752 if (n > 0)
2753 {
2754 if (n <= str_len)
2755 o = variable_buffer_output (o, str, n);
2756 else
2757 {
2758 o = variable_buffer_output (o, str, str_len);
2759 o = helper_pad (o, n - str_len, pad, pad_len);
2760 }
2761 }
2762
2763 /* insert the string */
2764 if (length <= in_len)
2765 o = variable_buffer_output (o, in, length);
2766 else
2767 {
2768 o = variable_buffer_output (o, in, in_len);
2769 o = helper_pad (o, length - in_len, pad, pad_len);
2770 }
2771
2772 /* the tail of the original string */
2773 if (n < str_len)
2774 o = variable_buffer_output (o, str + n, str_len - n);
2775
2776 return o;
2777}
2778
2779
2780/*
2781 $(pos needle, haystack[, start])
2782 $(lastpos needle, haystack[, start])
2783
2784 XXX: This doesn't take multibyte locales into account.
2785 */
2786static char *
2787func_pos (char *o, char **argv, const char *funcname UNUSED)
2788{
2789 const char *needle = *argv[0] ? argv[0] : " ";
2790 size_t needle_len = strlen (needle);
2791 const char *haystack = argv[1];
2792 size_t haystack_len = strlen (haystack);
2793 math_int start = 0;
2794 const char *hit;
2795
2796 if (argv[2] != NULL)
2797 {
2798 start = math_int_from_string (argv[2]);
2799 if (start > 0)
2800 start--; /* one-origin */
2801 else if (start < 0)
2802 start = haystack_len + start; /* from the end */
2803 if (start < 0 || start + needle_len > haystack_len)
2804 return math_int_to_variable_buffer (o, 0);
2805 }
2806 else if (funcname[0] == 'l')
2807 start = haystack_len - 1;
2808
2809 /* do the searching */
2810 if (funcname[0] != 'l')
2811 { /* pos */
2812 if (needle_len == 1)
2813 hit = strchr (haystack + start, *needle);
2814 else
2815 hit = strstr (haystack + start, needle);
2816 }
2817 else
2818 { /* last pos */
2819 int ch = *needle;
2820 size_t off = start + 1;
2821
2822 hit = NULL;
2823 while (off-- > 0)
2824 {
2825 if ( haystack[off] == ch
2826 && ( needle_len == 1
2827 || strncmp (&haystack[off], needle, needle_len) == 0))
2828 {
2829 hit = haystack + off;
2830 break;
2831 }
2832 }
2833 }
2834
2835 return math_int_to_variable_buffer (o, hit ? hit - haystack + 1 : 0);
2836}
2837
2838
2839/*
2840 $(substr str, start[, length[, pad]])
2841
2842 XXX: This doesn't take multibyte locales into account.
2843 */
2844static char *
2845func_substr (char *o, char **argv, const char *funcname UNUSED)
2846{
2847 const char *str = argv[0];
2848 math_int str_len = (math_int)strlen (str);
2849 math_int start = math_int_from_string (argv[1]);
2850 math_int length = 0;
2851 const char *pad = NULL;
2852 size_t pad_len = 0;
2853
2854 if (argv[2] != NULL)
2855 {
2856 if (argv[3] != NULL)
2857 {
2858 pad = argv[3];
2859 for (pad_len = 0; pad[pad_len] == ' '; pad_len++)
2860 /* nothing */;
2861 if (pad[pad_len] != '\0')
2862 pad_len = strlen (pad);
2863 else
2864 {
2865 pad = " ";
2866 pad_len = 16;
2867 }
2868 }
2869 length = math_int_from_string (argv[2]);
2870 if (pad != NULL && length > 16*1024*1024 /* 16MB */)
2871 fatal (NILF, _("$(substr ): length=%s is out of bounds\n"), argv[2]);
2872 if (pad != NULL && length < 0)
2873 fatal (NILF, _("$(substr ): negative length (%s) and padding doesn't mix.\n"), argv[2]);
2874 if (length == 0)
2875 return o;
2876 }
2877
2878 /* Note that negative start is and length are used for referencing from the
2879 end of the string. */
2880 if (pad == NULL)
2881 {
2882 if (start > 0)
2883 start--; /* one-origin */
2884 else
2885 {
2886 start = str_len + start;
2887 if (start <= 0)
2888 {
2889 if (length < 0)
2890 return o;
2891 start += length;
2892 if (start <= 0)
2893 return o;
2894 length = start;
2895 start = 0;
2896 }
2897 }
2898
2899 if (start >= str_len)
2900 return o;
2901 if (length == 0)
2902 length = str_len - start;
2903 else if (length < 0)
2904 {
2905 if (str_len <= -length)
2906 return o;
2907 length += str_len;
2908 if (length <= start)
2909 return o;
2910 length -= start;
2911 }
2912 else if (start + length > str_len)
2913 length = str_len - start;
2914
2915 o = variable_buffer_output (o, str + start, length);
2916 }
2917 else
2918 {
2919 if (start > 0)
2920 {
2921 start--; /* one-origin */
2922 if (start >= str_len)
2923 return length ? helper_pad (o, length, pad, pad_len) : o;
2924 if (length == 0)
2925 length = str_len - start;
2926 }
2927 else
2928 {
2929 start = str_len + start;
2930 if (start <= 0)
2931 {
2932 if (start + length <= 0)
2933 return length ? helper_pad (o, length, pad, pad_len) : o;
2934 o = helper_pad (o, -start, pad, pad_len);
2935 return variable_buffer_output (o, str, length + start);
2936 }
2937 if (length == 0)
2938 length = str_len - start;
2939 }
2940 if (start + length <= str_len)
2941 o = variable_buffer_output (o, str + start, length);
2942 else
2943 {
2944 o = variable_buffer_output (o, str + start, str_len - start);
2945 o = helper_pad (o, start + length - str_len, pad, pad_len);
2946 }
2947 }
2948
2949 return o;
2950}
2951
2952
2953/*
2954 $(translate string, from-set[, to-set[, pad-char]])
2955
2956 XXX: This doesn't take multibyte locales into account.
2957 */
2958static char *
2959func_translate (char *o, char **argv, const char *funcname UNUSED)
2960{
2961 const unsigned char *str = (const unsigned char *)argv[0];
2962 const unsigned char *from_set = (const unsigned char *)argv[1];
2963 const char *to_set = argv[2] != NULL ? argv[2] : "";
2964 char trans_tab[1 << CHAR_BIT];
2965 int i;
2966 char ch;
2967
2968 /* init the array. */
2969 for (i = 0; i < (1 << CHAR_BIT); i++)
2970 trans_tab[i] = i;
2971
2972 while ( (i = *from_set) != '\0'
2973 && (ch = *to_set) != '\0')
2974 {
2975 trans_tab[i] = ch;
2976 from_set++;
2977 to_set++;
2978 }
2979
2980 if (i != '\0')
2981 {
2982 ch = '\0'; /* no padding == remove char */
2983 if (argv[2] != NULL && argv[3] != NULL)
2984 {
2985 ch = argv[3][0];
2986 if (ch && argv[3][1])
2987 fatal (NILF, _("$(translate ): pad=`%s' expected a single char\n"), argv[3]);
2988 if (ch == '\0') /* no char == space */
2989 ch = ' ';
2990 }
2991 while ((i = *from_set++) != '\0')
2992 trans_tab[i] = ch;
2993 }
2994
2995 /* do the translation */
2996 while ((i = *str++) != '\0')
2997 {
2998 ch = trans_tab[i];
2999 if (ch)
3000 o = variable_buffer_output (o, &ch, 1);
3001 }
3002
3003 return o;
3004}
3005#endif /* CONFIG_WITH_STRING_FUNCTIONS */
3006
3007
3008#ifdef CONFIG_WITH_LAZY_DEPS_VARS
3009
3010/* This is also in file.c (bad). */
3011# if VMS
3012# define FILE_LIST_SEPARATOR ','
3013# else
3014# define FILE_LIST_SEPARATOR ' '
3015# endif
3016
3017/* Implements $^ and $+.
3018
3019 The first comes with FUNCNAME 'deps', the second as 'deps-all'.
3020
3021 If no second argument is given, or if it's empty, or if it's zero,
3022 all dependencies will be returned. If the second argument is non-zero
3023 the dependency at that position will be returned. If the argument is
3024 negative a fatal error is thrown. */
3025static char *
3026func_deps (char *o, char **argv, const char *funcname)
3027{
3028 unsigned int idx = 0;
3029 struct file *file;
3030
3031 /* Handle the argument if present. */
3032
3033 if (argv[1])
3034 {
3035 char *p = argv[1];
3036 while (isspace ((unsigned int)*p))
3037 p++;
3038 if (*p != '\0')
3039 {
3040 char *n;
3041 long l = strtol (p, &n, 0);
3042 while (isspace ((unsigned int)*n))
3043 n++;
3044 idx = l;
3045 if (*n != '\0' || l < 0 || (long)idx != l)
3046 fatal (NILF, _("%s: invalid index value: `%s'\n"), funcname, p);
3047 }
3048 }
3049
3050 /* Find the file and select the list corresponding to FUNCNAME. */
3051
3052 file = lookup_file (argv[0]);
3053 if (file)
3054 {
3055 struct dep *deps;
3056 struct dep *d;
3057 if (funcname[4] == '\0')
3058 {
3059 deps = file->deps_no_dupes;
3060 if (!deps && file->deps)
3061 deps = file->deps = create_uniqute_deps_chain (file->deps);
3062 }
3063 else
3064 deps = file->deps;
3065
3066 if ( file->double_colon
3067 && ( file->double_colon != file
3068 || file->last != file))
3069 error (NILF, _("$(%s ) cannot be used on files with multiple double colon rules like `%s'\n"),
3070 funcname, file->name);
3071
3072 if (idx == 0 /* all */)
3073 {
3074 unsigned int total_len = 0;
3075
3076 /* calc the result length. */
3077
3078 for (d = deps; d; d = d->next)
3079 if (!d->ignore_mtime)
3080 {
3081 const char *c = dep_name (d);
3082
3083#ifndef NO_ARCHIVES
3084 if (ar_name (c))
3085 {
3086 c = strchr (c, '(') + 1;
3087 total_len += strlen (c);
3088 }
3089 else
3090#elif defined (CONFIG_WITH_STRCACHE2)
3091 total_len += strcache2_get_len (&file_strcache, c) + 1;
3092#else
3093 total_len += strlen (c) + 1;
3094#endif
3095 }
3096
3097 if (total_len)
3098 {
3099 /* prepare the variable buffer dude wrt to the output size and
3100 pass along the strings. */
3101
3102 o = variable_buffer_output (o + total_len, "", 0) - total_len; /* a hack */
3103
3104 for (d = deps; d; d = d->next)
3105 if (!d->ignore_mtime)
3106 {
3107 unsigned int len;
3108 const char *c = dep_name (d);
3109
3110#ifndef NO_ARCHIVES
3111 if (ar_name (c))
3112 {
3113 c = strchr (c, '(') + 1;
3114 len = strlen (c);
3115 }
3116 else
3117#elif defined (CONFIG_WITH_STRCACHE2)
3118 len = strcache2_get_len (&file_strcache, c) + 1;
3119#else
3120 len = strlen (c) + 1;
3121#endif
3122 o = variable_buffer_output (o, c, len);
3123 o[-1] = FILE_LIST_SEPARATOR;
3124 }
3125
3126 --o; /* nuke the last list separator */
3127 *o = '\0';
3128 }
3129 }
3130 else
3131 {
3132 /* Dependency given by index. */
3133
3134 for (d = deps; d; d = d->next)
3135 if (!d->ignore_mtime)
3136 {
3137 if (--idx == 0) /* 1 based indexing */
3138 {
3139 unsigned int len;
3140 const char *c = dep_name (d);
3141
3142#ifndef NO_ARCHIVES
3143 if (ar_name (c))
3144 {
3145 c = strchr (c, '(') + 1;
3146 len = strlen (c) - 1;
3147 }
3148 else
3149#elif defined (CONFIG_WITH_STRCACHE2)
3150 len = strcache2_get_len (&file_strcache, c);
3151#else
3152 len = strlen (c);
3153#endif
3154 o = variable_buffer_output (o, c, len);
3155 break;
3156 }
3157 }
3158 }
3159 }
3160
3161 return o;
3162}
3163
3164/* Implements $?.
3165
3166 If no second argument is given, or if it's empty, or if it's zero,
3167 all dependencies will be returned. If the second argument is non-zero
3168 the dependency at that position will be returned. If the argument is
3169 negative a fatal error is thrown. */
3170static char *
3171func_deps_newer (char *o, char **argv, const char *funcname)
3172{
3173 unsigned int idx = 0;
3174 struct file *file;
3175
3176 /* Handle the argument if present. */
3177
3178 if (argv[1])
3179 {
3180 char *p = argv[1];
3181 while (isspace ((unsigned int)*p))
3182 p++;
3183 if (*p != '\0')
3184 {
3185 char *n;
3186 long l = strtol (p, &n, 0);
3187 while (isspace ((unsigned int)*n))
3188 n++;
3189 idx = l;
3190 if (*n != '\0' || l < 0 || (long)idx != l)
3191 fatal (NILF, _("%s: invalid index value: `%s'\n"), funcname, p);
3192 }
3193 }
3194
3195 /* Find the file. */
3196
3197 file = lookup_file (argv[0]);
3198 if (file)
3199 {
3200 struct dep *deps = file->deps;
3201 struct dep *d;
3202
3203 if ( file->double_colon
3204 && ( file->double_colon != file
3205 || file->last != file))
3206 error (NILF, _("$(%s ) cannot be used on files with multiple double colon rules like `%s'\n"),
3207 funcname, file->name);
3208
3209 if (idx == 0 /* all */)
3210 {
3211 unsigned int total_len = 0;
3212
3213 /* calc the result length. */
3214
3215 for (d = deps; d; d = d->next)
3216 if (!d->ignore_mtime && d->changed)
3217 {
3218 const char *c = dep_name (d);
3219
3220#ifndef NO_ARCHIVES
3221 if (ar_name (c))
3222 {
3223 c = strchr (c, '(') + 1;
3224 total_len += strlen (c);
3225 }
3226 else
3227#elif defined (CONFIG_WITH_STRCACHE2)
3228 total_len += strcache2_get_len (&file_strcache, c) + 1;
3229#else
3230 total_len += strlen (c) + 1;
3231#endif
3232 }
3233
3234 if (total_len)
3235 {
3236 /* prepare the variable buffer dude wrt to the output size and
3237 pass along the strings. */
3238
3239 o = variable_buffer_output (o + total_len, "", 0) - total_len; /* a hack */
3240
3241 for (d = deps; d; d = d->next)
3242 if (!d->ignore_mtime && d->changed)
3243 {
3244 unsigned int len;
3245 const char *c = dep_name (d);
3246
3247#ifndef NO_ARCHIVES
3248 if (ar_name (c))
3249 {
3250 c = strchr (c, '(') + 1;
3251 len = strlen (c);
3252 }
3253 else
3254#elif defined (CONFIG_WITH_STRCACHE2)
3255 len = strcache2_get_len (&file_strcache, c) + 1;
3256#else
3257 len = strlen (c) + 1;
3258#endif
3259 o = variable_buffer_output (o, c, len);
3260 o[-1] = FILE_LIST_SEPARATOR;
3261 }
3262
3263 --o; /* nuke the last list separator */
3264 *o = '\0';
3265 }
3266 }
3267 else
3268 {
3269 /* Dependency given by index. */
3270
3271 for (d = deps; d; d = d->next)
3272 if (!d->ignore_mtime && d->changed)
3273 {
3274 if (--idx == 0) /* 1 based indexing */
3275 {
3276 unsigned int len;
3277 const char *c = dep_name (d);
3278
3279#ifndef NO_ARCHIVES
3280 if (ar_name (c))
3281 {
3282 c = strchr (c, '(') + 1;
3283 len = strlen (c) - 1;
3284 }
3285 else
3286#elif defined (CONFIG_WITH_STRCACHE2)
3287 len = strcache2_get_len (&file_strcache, c);
3288#else
3289 len = strlen (c);
3290#endif
3291 o = variable_buffer_output (o, c, len);
3292 break;
3293 }
3294 }
3295 }
3296 }
3297
3298 return o;
3299}
3300
3301/* Implements $|, the order only dependency list.
3302
3303 If no second argument is given, or if it's empty, or if it's zero,
3304 all dependencies will be returned. If the second argument is non-zero
3305 the dependency at that position will be returned. If the argument is
3306 negative a fatal error is thrown. */
3307static char *
3308func_deps_order_only (char *o, char **argv, const char *funcname)
3309{
3310 unsigned int idx = 0;
3311 struct file *file;
3312
3313 /* Handle the argument if present. */
3314
3315 if (argv[1])
3316 {
3317 char *p = argv[1];
3318 while (isspace ((unsigned int)*p))
3319 p++;
3320 if (*p != '\0')
3321 {
3322 char *n;
3323 long l = strtol (p, &n, 0);
3324 while (isspace ((unsigned int)*n))
3325 n++;
3326 idx = l;
3327 if (*n != '\0' || l < 0 || (long)idx != l)
3328 fatal (NILF, _("%s: invalid index value: `%s'\n"), funcname, p);
3329 }
3330 }
3331
3332 /* Find the file. */
3333
3334 file = lookup_file (argv[0]);
3335 if (file)
3336 {
3337 struct dep *deps = file->deps;
3338 struct dep *d;
3339
3340 if ( file->double_colon
3341 && ( file->double_colon != file
3342 || file->last != file))
3343 error (NILF, _("$(%s ) cannot be used on files with multiple double colon rules like `%s'\n"),
3344 funcname, file->name);
3345
3346 if (idx == 0 /* all */)
3347 {
3348 unsigned int total_len = 0;
3349
3350 /* calc the result length. */
3351
3352 for (d = deps; d; d = d->next)
3353 if (d->ignore_mtime)
3354 {
3355 const char *c = dep_name (d);
3356
3357#ifndef NO_ARCHIVES
3358 if (ar_name (c))
3359 {
3360 c = strchr (c, '(') + 1;
3361 total_len += strlen (c);
3362 }
3363 else
3364#elif defined (CONFIG_WITH_STRCACHE2)
3365 total_len += strcache2_get_len (&file_strcache, c) + 1;
3366#else
3367 total_len += strlen (c) + 1;
3368#endif
3369 }
3370
3371 if (total_len)
3372 {
3373 /* prepare the variable buffer dude wrt to the output size and
3374 pass along the strings. */
3375
3376 o = variable_buffer_output (o + total_len, "", 0) - total_len; /* a hack */
3377
3378 for (d = deps; d; d = d->next)
3379 if (d->ignore_mtime)
3380 {
3381 unsigned int len;
3382 const char *c = dep_name (d);
3383
3384#ifndef NO_ARCHIVES
3385 if (ar_name (c))
3386 {
3387 c = strchr (c, '(') + 1;
3388 len = strlen (c);
3389 }
3390 else
3391#elif defined (CONFIG_WITH_STRCACHE2)
3392 len = strcache2_get_len (&file_strcache, c) + 1;
3393#else
3394 len = strlen (c) + 1;
3395#endif
3396 o = variable_buffer_output (o, c, len);
3397 o[-1] = FILE_LIST_SEPARATOR;
3398 }
3399
3400 --o; /* nuke the last list separator */
3401 *o = '\0';
3402 }
3403 }
3404 else
3405 {
3406 /* Dependency given by index. */
3407
3408 for (d = deps; d; d = d->next)
3409 if (d->ignore_mtime)
3410 {
3411 if (--idx == 0) /* 1 based indexing */
3412 {
3413 unsigned int len;
3414 const char *c = dep_name (d);
3415
3416#ifndef NO_ARCHIVES
3417 if (ar_name (c))
3418 {
3419 c = strchr (c, '(') + 1;
3420 len = strlen (c) - 1;
3421 }
3422 else
3423#elif defined (CONFIG_WITH_STRCACHE2)
3424 len = strcache2_get_len (&file_strcache, c);
3425#else
3426 len = strlen (c);
3427#endif
3428 o = variable_buffer_output (o, c, len);
3429 break;
3430 }
3431 }
3432 }
3433 }
3434
3435 return o;
3436}
3437#endif /* CONFIG_WITH_LAZY_DEPS_VARS */
3438
3439
3440
3441#ifdef CONFIG_WITH_DEFINED
3442/* Similar to ifdef. */
3443static char *
3444func_defined (char *o, char **argv, const char *funcname UNUSED)
3445{
3446 struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
3447 int result = v != NULL && *v->value != '\0';
3448 o = variable_buffer_output (o, result ? "1" : "", result);
3449 return o;
3450}
3451#endif /* CONFIG_WITH_DEFINED*/
3452
3453
3454
3455#ifdef HAVE_DOS_PATHS
3456#define IS_ABSOLUTE(n) (n[0] && n[1] == ':')
3457#define ROOT_LEN 3
3458#else
3459#define IS_ABSOLUTE(n) (n[0] == '/')
3460#define ROOT_LEN 1
3461#endif
3462
3463/* Return the absolute name of file NAME which does not contain any `.',
3464 `..' components nor any repeated path separators ('/'). */
3465#ifdef KMK
3466char *
3467#else
3468static char *
3469#endif
3470abspath (const char *name, char *apath)
3471{
3472 char *dest;
3473 const char *start, *end, *apath_limit;
3474 unsigned long root_len = ROOT_LEN;
3475
3476 if (name[0] == '\0' || apath == NULL)
3477 return NULL;
3478
3479#ifdef WINDOWS32 /* bird */
3480 dest = w32ify((char *)name, 1);
3481 if (!dest)
3482 return NULL;
3483 {
3484 size_t len = strlen(dest);
3485 memcpy(apath, dest, len);
3486 dest = apath + len;
3487 }
3488
3489 (void)end; (void)start; (void)apath_limit;
3490
3491#elif defined __OS2__ /* bird */
3492 if (_abspath(apath, name, GET_PATH_MAX))
3493 return NULL;
3494 dest = strchr(apath, '\0');
3495
3496 (void)end; (void)start; (void)apath_limit; (void)dest;
3497
3498#else /* !WINDOWS32 && !__OS2__ */
3499 apath_limit = apath + GET_PATH_MAX;
3500
3501 if (!IS_ABSOLUTE(name))
3502 {
3503 /* It is unlikely we would make it until here but just to make sure. */
3504 if (!starting_directory)
3505 return NULL;
3506
3507 strcpy (apath, starting_directory);
3508
3509#ifdef HAVE_DOS_PATHS
3510 if (IS_PATHSEP(name[0]))
3511 {
3512 if (IS_PATHSEP(name[1]))
3513 {
3514 /* A UNC. Don't prepend a drive letter. */
3515 apath[0] = name[0];
3516 apath[1] = name[1];
3517 root_len = 2;
3518 }
3519 /* We have /foo, an absolute file name except for the drive
3520 letter. Assume the missing drive letter is the current
3521 drive, which we can get if we remove from starting_directory
3522 everything past the root directory. */
3523 apath[root_len] = '\0';
3524 }
3525#endif
3526
3527 dest = strchr (apath, '\0');
3528 }
3529 else
3530 {
3531 strncpy (apath, name, root_len);
3532 apath[root_len] = '\0';
3533 dest = apath + root_len;
3534 /* Get past the root, since we already copied it. */
3535 name += root_len;
3536#ifdef HAVE_DOS_PATHS
3537 if (!IS_PATHSEP(apath[2]))
3538 {
3539 /* Convert d:foo into d:./foo and increase root_len. */
3540 apath[2] = '.';
3541 apath[3] = '/';
3542 dest++;
3543 root_len++;
3544 /* strncpy above copied one character too many. */
3545 name--;
3546 }
3547 else
3548 apath[2] = '/'; /* make sure it's a forward slash */
3549#endif
3550 }
3551
3552 for (start = end = name; *start != '\0'; start = end)
3553 {
3554 unsigned long len;
3555
3556 /* Skip sequence of multiple path-separators. */
3557 while (IS_PATHSEP(*start))
3558 ++start;
3559
3560 /* Find end of path component. */
3561 for (end = start; *end != '\0' && !IS_PATHSEP(*end); ++end)
3562 ;
3563
3564 len = end - start;
3565
3566 if (len == 0)
3567 break;
3568 else if (len == 1 && start[0] == '.')
3569 /* nothing */;
3570 else if (len == 2 && start[0] == '.' && start[1] == '.')
3571 {
3572 /* Back up to previous component, ignore if at root already. */
3573 if (dest > apath + root_len)
3574 for (--dest; !IS_PATHSEP(dest[-1]); --dest);
3575 }
3576 else
3577 {
3578 if (!IS_PATHSEP(dest[-1]))
3579 *dest++ = '/';
3580
3581 if (dest + len >= apath_limit)
3582 return NULL;
3583
3584 dest = memcpy (dest, start, len);
3585 dest += len;
3586 *dest = '\0';
3587 }
3588 }
3589#endif /* !WINDOWS32 && !__OS2__ */
3590
3591 /* Unless it is root strip trailing separator. */
3592 if (dest > apath + root_len && IS_PATHSEP(dest[-1]))
3593 --dest;
3594
3595 *dest = '\0';
3596
3597 return apath;
3598}
3599
3600
3601static char *
3602func_realpath (char *o, char **argv, const char *funcname UNUSED)
3603{
3604 /* Expand the argument. */
3605 const char *p = argv[0];
3606 const char *path = 0;
3607 int doneany = 0;
3608 unsigned int len = 0;
3609#ifndef HAVE_REALPATH
3610 struct stat st;
3611#endif
3612 PATH_VAR (in);
3613 PATH_VAR (out);
3614
3615 while ((path = find_next_token (&p, &len)) != 0)
3616 {
3617 if (len < GET_PATH_MAX)
3618 {
3619 strncpy (in, path, len);
3620 in[len] = '\0';
3621
3622 if (
3623#ifdef HAVE_REALPATH
3624 realpath (in, out)
3625#else
3626 abspath (in, out) && stat (out, &st) == 0
3627#endif
3628 )
3629 {
3630 o = variable_buffer_output (o, out, strlen (out));
3631 o = variable_buffer_output (o, " ", 1);
3632 doneany = 1;
3633 }
3634 }
3635 }
3636
3637 /* Kill last space. */
3638 if (doneany)
3639 --o;
3640
3641 return o;
3642}
3643
3644static char *
3645func_abspath (char *o, char **argv, const char *funcname UNUSED)
3646{
3647 /* Expand the argument. */
3648 const char *p = argv[0];
3649 const char *path = 0;
3650 int doneany = 0;
3651 unsigned int len = 0;
3652 PATH_VAR (in);
3653 PATH_VAR (out);
3654
3655 while ((path = find_next_token (&p, &len)) != 0)
3656 {
3657 if (len < GET_PATH_MAX)
3658 {
3659 strncpy (in, path, len);
3660 in[len] = '\0';
3661
3662 if (abspath (in, out))
3663 {
3664 o = variable_buffer_output (o, out, strlen (out));
3665 o = variable_buffer_output (o, " ", 1);
3666 doneany = 1;
3667 }
3668 }
3669 }
3670
3671 /* Kill last space. */
3672 if (doneany)
3673 --o;
3674
3675 return o;
3676}
3677
3678#ifdef CONFIG_WITH_ABSPATHEX
3679/* Same as abspath except that the current path may be given as the
3680 2nd argument. */
3681static char *
3682func_abspathex (char *o, char **argv, const char *funcname UNUSED)
3683{
3684 char *cwd = argv[1];
3685
3686 /* cwd needs leading spaces chopped and may be optional,
3687 in which case we're exactly like $(abspath ). */
3688 if (cwd)
3689 while (isblank (*cwd))
3690 cwd++;
3691 if (!cwd || !*cwd)
3692 o = func_abspath (o, argv, funcname);
3693 else
3694 {
3695 /* Expand the argument. */
3696 const char *p = argv[0];
3697 unsigned int cwd_len = ~0U;
3698 char *path = 0;
3699 int doneany = 0;
3700 unsigned int len = 0;
3701 PATH_VAR (in);
3702 PATH_VAR (out);
3703
3704 while ((path = find_next_token (&p, &len)) != 0)
3705 {
3706 if (len < GET_PATH_MAX)
3707 {
3708#ifdef HAVE_DOS_PATHS
3709 if (path[0] != '/' && path[0] != '\\' && (len < 2 || path[1] != ':') && cwd)
3710#else
3711 if (path[0] != '/' && cwd)
3712#endif
3713 {
3714 /* relative path, prefix with cwd. */
3715 if (cwd_len == ~0U)
3716 cwd_len = strlen (cwd);
3717 if (cwd_len + len + 1 >= GET_PATH_MAX)
3718 continue;
3719 memcpy (in, cwd, cwd_len);
3720 in[cwd_len] = '/';
3721 memcpy (in + cwd_len + 1, path, len);
3722 in[cwd_len + len + 1] = '\0';
3723 }
3724 else
3725 {
3726 /* absolute path pass it as-is. */
3727 memcpy (in, path, len);
3728 in[len] = '\0';
3729 }
3730
3731 if (abspath (in, out))
3732 {
3733 o = variable_buffer_output (o, out, strlen (out));
3734 o = variable_buffer_output (o, " ", 1);
3735 doneany = 1;
3736 }
3737 }
3738 }
3739
3740 /* Kill last space. */
3741 if (doneany)
3742 --o;
3743 }
3744
3745 return o;
3746}
3747#endif
3748
3749#ifdef CONFIG_WITH_XARGS
3750/* Create one or more command lines avoiding the max argument
3751 length restriction of the host OS.
3752
3753 The last argument is the list of arguments that the normal
3754 xargs command would be fed from stdin.
3755
3756 The first argument is initial command and it's arguments.
3757
3758 If there are three or more arguments, the 2nd argument is
3759 the command and arguments to be used on subsequent
3760 command lines. Defaults to the initial command.
3761
3762 If there are four or more arguments, the 3rd argument is
3763 the command to be used at the final command line. Defaults
3764 to the sub sequent or initial command .
3765
3766 A future version of this function may define more arguments
3767 and therefor anyone specifying six or more arguments will
3768 cause fatal errors.
3769
3770 Typical usage is:
3771 $(xargs ar cas mylib.a,$(objects))
3772 or
3773 $(xargs ar cas mylib.a,ar as mylib.a,$(objects))
3774
3775 It will then create one or more "ar mylib.a ..." command
3776 lines with proper \n\t separation so it can be used when
3777 writing rules. */
3778static char *
3779func_xargs (char *o, char **argv, const char *funcname UNUSED)
3780{
3781 int argc;
3782 const char *initial_cmd;
3783 size_t initial_cmd_len;
3784 const char *subsequent_cmd;
3785 size_t subsequent_cmd_len;
3786 const char *final_cmd;
3787 size_t final_cmd_len;
3788 const char *args;
3789 size_t max_args;
3790 int i;
3791
3792#ifdef ARG_MAX
3793 /* ARG_MAX is a bit unreliable (environment), so drop 25% of the max. */
3794# define XARGS_MAX (ARG_MAX - (ARG_MAX / 4))
3795#else /* FIXME: update configure with a command line length test. */
3796# define XARGS_MAX 10240
3797#endif
3798
3799 argc = 0;
3800 while (argv[argc])
3801 argc++;
3802 if (argc > 4)
3803 fatal (NILF, _("Too many arguments for $(xargs)!\n"));
3804
3805 /* first: the initial / default command.*/
3806 initial_cmd = argv[0];
3807 while (isspace ((unsigned char)*initial_cmd))
3808 initial_cmd++;
3809 max_args = initial_cmd_len = strlen (initial_cmd);
3810
3811 /* second: the command for the subsequent command lines. defaults to the initial cmd. */
3812 subsequent_cmd = argc > 2 && argv[1][0] != '\0' ? argv[1] : "";
3813 while (isspace ((unsigned char)*subsequent_cmd))
3814 subsequent_cmd++;
3815 if (*subsequent_cmd)
3816 {
3817 subsequent_cmd_len = strlen (subsequent_cmd);
3818 if (subsequent_cmd_len > max_args)
3819 max_args = subsequent_cmd_len;
3820 }
3821 else
3822 {
3823 subsequent_cmd = initial_cmd;
3824 subsequent_cmd_len = initial_cmd_len;
3825 }
3826
3827 /* third: the final command. defaults to the subseq cmd. */
3828 final_cmd = argc > 3 && argv[2][0] != '\0' ? argv[2] : "";
3829 while (isspace ((unsigned char)*final_cmd))
3830 final_cmd++;
3831 if (*final_cmd)
3832 {
3833 final_cmd_len = strlen (final_cmd);
3834 if (final_cmd_len > max_args)
3835 max_args = final_cmd_len;
3836 }
3837 else
3838 {
3839 final_cmd = subsequent_cmd;
3840 final_cmd_len = subsequent_cmd_len;
3841 }
3842
3843 /* last: the arguments to split up into sensible portions. */
3844 args = argv[argc - 1];
3845
3846 /* calc the max argument length. */
3847 if (XARGS_MAX <= max_args + 2)
3848 fatal (NILF, _("$(xargs): the commands are longer than the max exec argument length. (%lu <= %lu)\n"),
3849 (unsigned long)XARGS_MAX, (unsigned long)max_args + 2);
3850 max_args = XARGS_MAX - max_args - 1;
3851
3852 /* generate the commands. */
3853 i = 0;
3854 for (i = 0; ; i++)
3855 {
3856 unsigned int len;
3857 const char *iterator = args;
3858 const char *end = args;
3859 const char *cur;
3860 const char *tmp;
3861
3862 /* scan the arguments till we reach the end or the max length. */
3863 while ((cur = find_next_token(&iterator, &len))
3864 && (size_t)((cur + len) - args) < max_args)
3865 end = cur + len;
3866 if (cur && end == args)
3867 fatal (NILF, _("$(xargs): command + one single arg is too much. giving up.\n"));
3868
3869 /* emit the command. */
3870 if (i == 0)
3871 {
3872 o = variable_buffer_output (o, (char *)initial_cmd, initial_cmd_len);
3873 o = variable_buffer_output (o, " ", 1);
3874 }
3875 else if (cur)
3876 {
3877 o = variable_buffer_output (o, "\n\t", 2);
3878 o = variable_buffer_output (o, (char *)subsequent_cmd, subsequent_cmd_len);
3879 o = variable_buffer_output (o, " ", 1);
3880 }
3881 else
3882 {
3883 o = variable_buffer_output (o, "\n\t", 2);
3884 o = variable_buffer_output (o, (char *)final_cmd, final_cmd_len);
3885 o = variable_buffer_output (o, " ", 1);
3886 }
3887
3888 tmp = end;
3889 while (tmp > args && isspace ((unsigned char)tmp[-1])) /* drop trailing spaces. */
3890 tmp--;
3891 o = variable_buffer_output (o, (char *)args, tmp - args);
3892
3893
3894 /* next */
3895 if (!cur)
3896 break;
3897 args = end;
3898 while (isspace ((unsigned char)*args))
3899 args++;
3900 }
3901
3902 return o;
3903}
3904#endif
3905
3906#ifdef CONFIG_WITH_TOUPPER_TOLOWER
3907static char *
3908func_toupper_tolower (char *o, char **argv, const char *funcname)
3909{
3910 /* Expand the argument. */
3911 const char *p = argv[0];
3912 while (*p)
3913 {
3914 /* convert to temporary buffer */
3915 char tmp[256];
3916 unsigned int i;
3917 if (!strcmp(funcname, "toupper"))
3918 for (i = 0; i < sizeof(tmp) && *p; i++, p++)
3919 tmp[i] = toupper(*p);
3920 else
3921 for (i = 0; i < sizeof(tmp) && *p; i++, p++)
3922 tmp[i] = tolower(*p);
3923 o = variable_buffer_output (o, tmp, i);
3924 }
3925
3926 return o;
3927}
3928#endif /* CONFIG_WITH_TOUPPER_TOLOWER */
3929
3930#if defined(CONFIG_WITH_VALUE_LENGTH) && defined(CONFIG_WITH_COMPARE)
3931
3932/* Strip leading spaces and other things off a command. */
3933static const char *
3934comp_cmds_strip_leading (const char *s, const char *e)
3935{
3936 while (s < e)
3937 {
3938 const char ch = *s;
3939 if (!isblank (ch)
3940 && ch != '@'
3941#ifdef CONFIG_WITH_COMMANDS_FUNC
3942 && ch != '%'
3943#endif
3944 && ch != '+'
3945 && ch != '-')
3946 break;
3947 s++;
3948 }
3949 return s;
3950}
3951
3952/* Worker for func_comp_vars() which is called if the comparision failed.
3953 It will do the slow command by command comparision of the commands
3954 when there invoked as comp-cmds. */
3955static char *
3956comp_vars_ne (char *o, const char *s1, const char *e1, const char *s2, const char *e2,
3957 char *ne_retval, const char *funcname)
3958{
3959 /* give up at once if not comp-cmds or comp-cmds-ex. */
3960 if (strcmp (funcname, "comp-cmds") != 0
3961 && strcmp (funcname, "comp-cmds-ex") != 0)
3962 o = variable_buffer_output (o, ne_retval, strlen (ne_retval));
3963 else
3964 {
3965 const char * const s1_start = s1;
3966 int new_cmd = 1;
3967 int diff;
3968 for (;;)
3969 {
3970 /* if it's a new command, strip leading stuff. */
3971 if (new_cmd)
3972 {
3973 s1 = comp_cmds_strip_leading (s1, e1);
3974 s2 = comp_cmds_strip_leading (s2, e2);
3975 new_cmd = 0;
3976 }
3977 if (s1 >= e1 || s2 >= e2)
3978 break;
3979
3980 /*
3981 * Inner compare loop which compares one line.
3982 * FIXME: parse quoting!
3983 */
3984 for (;;)
3985 {
3986 const char ch1 = *s1;
3987 const char ch2 = *s2;
3988 diff = ch1 - ch2;
3989 if (diff)
3990 break;
3991 if (ch1 == '\n')
3992 break;
3993 assert (ch1 != '\r');
3994
3995 /* next */
3996 s1++;
3997 s2++;
3998 if (s1 >= e1 || s2 >= e2)
3999 break;
4000 }
4001
4002 /*
4003 * If we exited because of a difference try to end-of-command
4004 * comparision, e.g. ignore trailing spaces.
4005 */
4006 if (diff)
4007 {
4008 /* strip */
4009 while (s1 < e1 && isblank (*s1))
4010 s1++;
4011 while (s2 < e2 && isblank (*s2))
4012 s2++;
4013 if (s1 >= e1 || s2 >= e2)
4014 break;
4015
4016 /* compare again and check that it's a newline. */
4017 if (*s2 != '\n' || *s1 != '\n')
4018 break;
4019 }
4020 /* Break out if we exited because of EOS. */
4021 else if (s1 >= e1 || s2 >= e2)
4022 break;
4023
4024 /*
4025 * Detect the end of command lines.
4026 */
4027 if (*s1 == '\n')
4028 new_cmd = s1 == s1_start || s1[-1] != '\\';
4029 s1++;
4030 s2++;
4031 }
4032
4033 /*
4034 * Ignore trailing empty lines.
4035 */
4036 if (s1 < e1 || s2 < e2)
4037 {
4038 while (s1 < e1 && (isblank (*s1) || *s1 == '\n'))
4039 if (*s1++ == '\n')
4040 s1 = comp_cmds_strip_leading (s1, e1);
4041 while (s2 < e2 && (isblank (*s2) || *s2 == '\n'))
4042 if (*s2++ == '\n')
4043 s2 = comp_cmds_strip_leading (s2, e2);
4044 }
4045
4046 /* emit the result. */
4047 if (s1 == e1 && s2 == e2)
4048 o = variable_buffer_output (o, "", 1) - 1; /** @todo check why this was necessary back the... */
4049 else
4050 o = variable_buffer_output (o, ne_retval, strlen (ne_retval));
4051 }
4052 return o;
4053}
4054
4055/*
4056 $(comp-vars var1,var2,not-equal-return)
4057 or
4058 $(comp-cmds cmd-var1,cmd-var2,not-equal-return)
4059
4060 Compares the two variables (that's given by name to avoid unnecessary
4061 expanding) and return the string in the third argument if not equal.
4062 If equal, nothing is returned.
4063
4064 comp-vars will to an exact comparision only stripping leading and
4065 trailing spaces.
4066
4067 comp-cmds will compare command by command, ignoring not only leading
4068 and trailing spaces on each line but also leading one leading '@',
4069 '-', '+' and '%'
4070*/
4071static char *
4072func_comp_vars (char *o, char **argv, const char *funcname)
4073{
4074 const char *s1, *e1, *x1, *s2, *e2, *x2;
4075 char *a1 = NULL, *a2 = NULL;
4076 size_t l, l1, l2;
4077 struct variable *var1 = lookup_variable (argv[0], strlen (argv[0]));
4078 struct variable *var2 = lookup_variable (argv[1], strlen (argv[1]));
4079
4080 /* the simple cases */
4081 if (var1 == var2)
4082 return variable_buffer_output (o, "", 0); /* eq */
4083 if (!var1 || !var2)
4084 return variable_buffer_output (o, argv[2], strlen(argv[2]));
4085 if (var1->value == var2->value)
4086 return variable_buffer_output (o, "", 0); /* eq */
4087 if (!var1->recursive && !var2->recursive)
4088 {
4089 if ( var1->value_length == var2->value_length
4090 && !memcmp (var1->value, var2->value, var1->value_length))
4091 return variable_buffer_output (o, "", 0); /* eq */
4092
4093 /* ignore trailing and leading blanks */
4094 s1 = var1->value;
4095 e1 = s1 + var1->value_length;
4096 while (isblank ((unsigned char) *s1))
4097 s1++;
4098 while (e1 > s1 && isblank ((unsigned char) e1[-1]))
4099 e1--;
4100
4101 s2 = var2->value;
4102 e2 = s2 + var2->value_length;
4103 while (isblank ((unsigned char) *s2))
4104 s2++;
4105 while (e2 > s2 && isblank ((unsigned char) e2[-1]))
4106 e2--;
4107
4108 if (e1 - s1 != e2 - s2)
4109 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4110 if (!memcmp (s1, s2, e1 - s1))
4111 return variable_buffer_output (o, "", 0); /* eq */
4112 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4113 }
4114
4115 /* ignore trailing and leading blanks */
4116 s1 = var1->value;
4117 e1 = s1 + var1->value_length;
4118 while (isblank ((unsigned char) *s1))
4119 s1++;
4120 while (e1 > s1 && isblank ((unsigned char) e1[-1]))
4121 e1--;
4122
4123 s2 = var2->value;
4124 e2 = s2 + var2->value_length;
4125 while (isblank((unsigned char)*s2))
4126 s2++;
4127 while (e2 > s2 && isblank ((unsigned char) e2[-1]))
4128 e2--;
4129
4130 /* both empty after stripping? */
4131 if (s1 == e1 && s2 == e2)
4132 return variable_buffer_output (o, "", 0); /* eq */
4133
4134 /* optimist. */
4135 if ( e1 - s1 == e2 - s2
4136 && !memcmp(s1, s2, e1 - s1))
4137 return variable_buffer_output (o, "", 0); /* eq */
4138
4139 /* compare up to the first '$' or the end. */
4140 x1 = var1->recursive ? memchr (s1, '$', e1 - s1) : NULL;
4141 x2 = var2->recursive ? memchr (s2, '$', e2 - s2) : NULL;
4142 if (!x1 && !x2)
4143 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4144
4145 l1 = x1 ? x1 - s1 : e1 - s1;
4146 l2 = x2 ? x2 - s2 : e2 - s2;
4147 l = l1 <= l2 ? l1 : l2;
4148 if (l && memcmp (s1, s2, l))
4149 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4150
4151 /* one or both buffers now require expanding. */
4152 if (!x1)
4153 s1 += l;
4154 else
4155 {
4156 s1 = a1 = allocated_variable_expand ((char *)s1 + l);
4157 if (!l)
4158 while (isblank ((unsigned char) *s1))
4159 s1++;
4160 e1 = strchr (s1, '\0');
4161 while (e1 > s1 && isblank ((unsigned char) e1[-1]))
4162 e1--;
4163 }
4164
4165 if (!x2)
4166 s2 += l;
4167 else
4168 {
4169 s2 = a2 = allocated_variable_expand ((char *)s2 + l);
4170 if (!l)
4171 while (isblank ((unsigned char) *s2))
4172 s2++;
4173 e2 = strchr (s2, '\0');
4174 while (e2 > s2 && isblank ((unsigned char) e2[-1]))
4175 e2--;
4176 }
4177
4178 /* the final compare */
4179 if ( e1 - s1 != e2 - s2
4180 || memcmp (s1, s2, e1 - s1))
4181 o = comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4182 else
4183 o = variable_buffer_output (o, "", 1) - 1; /* eq */ /** @todo check why this was necessary back the... */
4184 if (a1)
4185 free (a1);
4186 if (a2)
4187 free (a2);
4188 return o;
4189}
4190
4191/*
4192 $(comp-cmds-ex cmds1,cmds2,not-equal-return)
4193
4194 Compares the two strings and return the string in the third argument
4195 if not equal. If equal, nothing is returned.
4196
4197 The comparision will be performed command by command, ignoring not
4198 only leading and trailing spaces on each line but also leading one
4199 leading '@', '-', '+' and '%'.
4200*/
4201static char *
4202func_comp_cmds_ex (char *o, char **argv, const char *funcname)
4203{
4204 const char *s1, *e1, *s2, *e2;
4205 size_t l1, l2;
4206
4207 /* the simple cases */
4208 s1 = argv[0];
4209 s2 = argv[1];
4210 if (s1 == s2)
4211 return variable_buffer_output (o, "", 0); /* eq */
4212 l1 = strlen (argv[0]);
4213 l2 = strlen (argv[1]);
4214
4215 if ( l1 == l2
4216 && !memcmp (s1, s2, l1))
4217 return variable_buffer_output (o, "", 0); /* eq */
4218
4219 /* ignore trailing and leading blanks */
4220 e1 = s1 + l1;
4221 s1 = comp_cmds_strip_leading (s1, e1);
4222
4223 e2 = s2 + l2;
4224 s2 = comp_cmds_strip_leading (s2, e2);
4225
4226 if (e1 - s1 != e2 - s2)
4227 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4228 if (!memcmp (s1, s2, e1 - s1))
4229 return variable_buffer_output (o, "", 0); /* eq */
4230 return comp_vars_ne (o, s1, e1, s2, e2, argv[2], funcname);
4231}
4232#endif
4233
4234#ifdef CONFIG_WITH_DATE
4235# if defined (_MSC_VER) /* FIXME: !defined (HAVE_STRPTIME) */
4236char *strptime(const char *s, const char *format, struct tm *tm)
4237{
4238 return (char *)"strptime is not implemented";
4239}
4240# endif
4241/* Check if the string is all blanks or not. */
4242static int
4243all_blanks (const char *s)
4244{
4245 if (!s)
4246 return 1;
4247 while (isspace ((unsigned char)*s))
4248 s++;
4249 return *s == '\0';
4250}
4251
4252/* The first argument is the strftime format string, a iso
4253 timestamp is the default if nothing is given.
4254
4255 The second argument is a time value if given. The format
4256 is either the format from the first argument or given as
4257 an additional third argument. */
4258static char *
4259func_date (char *o, char **argv, const char *funcname)
4260{
4261 char *p;
4262 char *buf;
4263 size_t buf_size;
4264 struct tm t;
4265 const char *format;
4266
4267 /* determin the format - use a single word as the default. */
4268 format = !strcmp (funcname, "date-utc")
4269 ? "%Y-%m-%dT%H:%M:%SZ"
4270 : "%Y-%m-%dT%H:%M:%S";
4271 if (!all_blanks (argv[0]))
4272 format = argv[0];
4273
4274 /* get the time. */
4275 memset (&t, 0, sizeof(t));
4276 if (argv[0] && !all_blanks (argv[1]))
4277 {
4278 const char *input_format = !all_blanks (argv[2]) ? argv[2] : format;
4279 p = strptime (argv[1], input_format, &t);
4280 if (!p || *p != '\0')
4281 {
4282 error (NILF, _("$(%s): strptime(%s,%s,) -> %s\n"), funcname,
4283 argv[1], input_format, p ? p : "<null>");
4284 return variable_buffer_output (o, "", 0);
4285 }
4286 }
4287 else
4288 {
4289 time_t tval;
4290 time (&tval);
4291 if (!strcmp (funcname, "date-utc"))
4292 t = *gmtime (&tval);
4293 else
4294 t = *localtime (&tval);
4295 }
4296
4297 /* format it. note that zero isn't necessarily an error, so we'll
4298 have to keep shut about failures. */
4299 buf_size = 64;
4300 buf = xmalloc (buf_size);
4301 while (strftime (buf, buf_size, format, &t) == 0)
4302 {
4303 if (buf_size >= 4096)
4304 {
4305 *buf = '\0';
4306 break;
4307 }
4308 buf = xrealloc (buf, buf_size <<= 1);
4309 }
4310 o = variable_buffer_output (o, buf, strlen (buf));
4311 free (buf);
4312 return o;
4313}
4314#endif
4315
4316#ifdef CONFIG_WITH_FILE_SIZE
4317/* Prints the size of the specified file. Only one file is
4318 permitted, notthing is stripped. -1 is returned if stat
4319 fails. */
4320static char *
4321func_file_size (char *o, char **argv, const char *funcname UNUSED)
4322{
4323 struct stat st;
4324 if (stat (argv[0], &st))
4325 return variable_buffer_output (o, "-1", 2);
4326 return math_int_to_variable_buffer (o, st.st_size);
4327}
4328#endif
4329
4330#ifdef CONFIG_WITH_WHICH
4331/* Checks if the specified file exists an is executable.
4332 On systems employing executable extensions, the name may
4333 be modified to include the extension. */
4334static int func_which_test_x (char *file)
4335{
4336 struct stat st;
4337# if defined(WINDOWS32) || defined(__OS2__)
4338 char *ext;
4339 char *slash;
4340
4341 /* fix slashes first. */
4342 slash = file;
4343 while ((slash = strchr (slash, '\\')) != NULL)
4344 *slash++ = '/';
4345
4346 /* straight */
4347 if (stat (file, &st) == 0
4348 && S_ISREG (st.st_mode))
4349 return 1;
4350
4351 /* don't try add an extension if there already is one */
4352 ext = strchr (file, '\0');
4353 if (ext - file >= 4
4354 && ( !stricmp (ext - 4, ".exe")
4355 || !stricmp (ext - 4, ".cmd")
4356 || !stricmp (ext - 4, ".bat")
4357 || !stricmp (ext - 4, ".com")))
4358 return 0;
4359
4360 /* try the extensions. */
4361 strcpy (ext, ".exe");
4362 if (stat (file, &st) == 0
4363 && S_ISREG (st.st_mode))
4364 return 1;
4365
4366 strcpy (ext, ".cmd");
4367 if (stat (file, &st) == 0
4368 && S_ISREG (st.st_mode))
4369 return 1;
4370
4371 strcpy (ext, ".bat");
4372 if (stat (file, &st) == 0
4373 && S_ISREG (st.st_mode))
4374 return 1;
4375
4376 strcpy (ext, ".com");
4377 if (stat (file, &st) == 0
4378 && S_ISREG (st.st_mode))
4379 return 1;
4380
4381 return 0;
4382
4383# else
4384
4385 return access (file, X_OK) == 0
4386 && stat (file, &st) == 0
4387 && S_ISREG (st.st_mode);
4388# endif
4389}
4390
4391/* Searches for the specified programs in the PATH and print
4392 their full location if found. Prints nothing if not found. */
4393static char *
4394func_which (char *o, char **argv, const char *funcname UNUSED)
4395{
4396 const char *path;
4397 struct variable *path_var;
4398 unsigned i;
4399 int first = 1;
4400 PATH_VAR (buf);
4401
4402 path_var = lookup_variable ("PATH", 4);
4403 if (path_var)
4404 path = path_var->value;
4405 else
4406 path = ".";
4407
4408 /* iterate input */
4409 for (i = 0; argv[i]; i++)
4410 {
4411 unsigned int len;
4412 const char *iterator = argv[i];
4413 char *cur;
4414
4415 while ((cur = find_next_token (&iterator, &len)))
4416 {
4417 /* if there is a separator, don't walk the path. */
4418 if (memchr (cur, '/', len)
4419#ifdef HAVE_DOS_PATHS
4420 || memchr (cur, '\\', len)
4421 || memchr (cur, ':', len)
4422#endif
4423 )
4424 {
4425 if (len + 1 + 4 < GET_PATH_MAX) /* +4 for .exe */
4426 {
4427 memcpy (buf, cur, len);
4428 buf[len] = '\0';
4429 if (func_which_test_x (buf))
4430 o = variable_buffer_output (o, buf, strlen (buf));
4431 }
4432 }
4433 else
4434 {
4435 const char *comp = path;
4436 for (;;)
4437 {
4438 const char *src = comp;
4439 const char *end = strchr (comp, PATH_SEPARATOR_CHAR);
4440 size_t src_len = end ? (size_t)(end - comp) : strlen (comp);
4441 if (!src_len)
4442 {
4443 src_len = 1;
4444 src = ".";
4445 }
4446 if (len + src_len + 2 + 4 < GET_PATH_MAX) /* +4 for .exe */
4447 {
4448 memcpy (buf, src, src_len);
4449 buf [src_len] = '/';
4450 memcpy (&buf[src_len + 1], cur, len);
4451 buf[src_len + 1 + len] = '\0';
4452
4453 if (func_which_test_x (buf))
4454 {
4455 if (!first)
4456 o = variable_buffer_output (o, " ", 1);
4457 o = variable_buffer_output (o, buf, strlen (buf));
4458 first = 0;
4459 break;
4460 }
4461 }
4462
4463 /* next */
4464 if (!end)
4465 break;
4466 comp = end + 1;
4467 }
4468 }
4469 }
4470 }
4471
4472 return variable_buffer_output (o, "", 0);
4473}
4474#endif /* CONFIG_WITH_WHICH */
4475
4476#ifdef CONFIG_WITH_IF_CONDITIONALS
4477
4478/* Evaluates the expression given in the argument using the
4479 same evaluator as for the new 'if' statements, except now
4480 we don't force the result into a boolean like for 'if' and
4481 '$(if-expr ,,)'. */
4482static char *
4483func_expr (char *o, char **argv, const char *funcname UNUSED)
4484{
4485 o = expr_eval_to_string (o, argv[0]);
4486 return o;
4487}
4488
4489/* Same as '$(if ,,)' except the first argument is evaluated
4490 using the same evaluator as for the new 'if' statements. */
4491static char *
4492func_if_expr (char *o, char **argv, const char *funcname UNUSED)
4493{
4494 int rc;
4495 char *to_expand;
4496
4497 /* Evaluate the condition in argv[0] and expand the 2nd or
4498 3rd (optional) argument according to the result. */
4499 rc = expr_eval_if_conditionals (argv[0], NULL);
4500 to_expand = rc == 0 ? argv[1] : argv[2];
4501 if (to_expand && *to_expand)
4502 variable_expand_string_2 (o, to_expand, -1, &o);
4503
4504 return o;
4505}
4506
4507/*
4508 $(select when1-cond, when1-body[,whenN-cond, whenN-body]).
4509 */
4510static char *
4511func_select (char *o, char **argv, const char *funcname UNUSED)
4512{
4513 int i;
4514
4515 /* Test WHEN-CONDs until one matches. The check for 'otherwise[:]'
4516 and 'default[:]' make this a bit more fun... */
4517
4518 for (i = 0; argv[i] != NULL; i += 2)
4519 {
4520 const char *cond = argv[i];
4521 int is_otherwise = 0;
4522
4523 if (argv[i + 1] == NULL)
4524 fatal (NILF, _("$(select ): not an even argument count\n"));
4525
4526 while (isspace ((unsigned char)*cond))
4527 cond++;
4528 if ( (*cond == 'o' && strncmp (cond, "otherwise", 9) == 0)
4529 || (*cond == 'd' && strncmp (cond, "default", 7) == 0))
4530 {
4531 const char *end = cond + (*cond == 'o' ? 9 : 7);
4532 while (isspace ((unsigned char)*end))
4533 end++;
4534 if (*end == ':')
4535 do end++;
4536 while (isspace ((unsigned char)*end));
4537 is_otherwise = *end == '\0';
4538 }
4539
4540 if ( is_otherwise
4541 || expr_eval_if_conditionals (cond, NULL) == 0 /* true */)
4542 {
4543 variable_expand_string_2 (o, argv[i + 1], -1, &o);
4544 break;
4545 }
4546 }
4547
4548 return o;
4549}
4550
4551#endif /* CONFIG_WITH_IF_CONDITIONALS */
4552
4553#ifdef CONFIG_WITH_SET_CONDITIONALS
4554static char *
4555func_set_intersects (char *o, char **argv, const char *funcname UNUSED)
4556{
4557 const char *s1_cur;
4558 unsigned int s1_len;
4559 const char *s1_iterator = argv[0];
4560
4561 while ((s1_cur = find_next_token (&s1_iterator, &s1_len)) != 0)
4562 {
4563 const char *s2_cur;
4564 unsigned int s2_len;
4565 const char *s2_iterator = argv[1];
4566 while ((s2_cur = find_next_token (&s2_iterator, &s2_len)) != 0)
4567 if (s2_len == s1_len
4568 && strneq (s2_cur, s1_cur, s1_len) )
4569 return variable_buffer_output (o, "1", 1); /* found intersection */
4570 }
4571
4572 return o; /* no intersection */
4573}
4574#endif /* CONFIG_WITH_SET_CONDITIONALS */
4575
4576#ifdef CONFIG_WITH_STACK
4577
4578/* Push an item (string without spaces). */
4579static char *
4580func_stack_push (char *o, char **argv, const char *funcname UNUSED)
4581{
4582 do_variable_definition(NILF, argv[0], argv[1], o_file, f_append, 0 /* !target_var */);
4583 return o;
4584}
4585
4586/* Pops an item off the stack / get the top stack element.
4587 (This is what's tricky to do in pure GNU make syntax.) */
4588static char *
4589func_stack_pop_top (char *o, char **argv, const char *funcname)
4590{
4591 struct variable *stack_var;
4592 const char *stack = argv[0];
4593
4594 stack_var = lookup_variable (stack, strlen (stack) );
4595 if (stack_var)
4596 {
4597 unsigned int len;
4598 const char *iterator = stack_var->value;
4599 char *lastitem = NULL;
4600 char *cur;
4601
4602 while ((cur = find_next_token (&iterator, &len)))
4603 lastitem = cur;
4604
4605 if (lastitem != NULL)
4606 {
4607 if (strcmp (funcname, "stack-popv") != 0)
4608 o = variable_buffer_output (o, lastitem, len);
4609 if (strcmp (funcname, "stack-top") != 0)
4610 {
4611 *lastitem = '\0';
4612 while (lastitem > stack_var->value && isspace (lastitem[-1]))
4613 *--lastitem = '\0';
4614#ifdef CONFIG_WITH_VALUE_LENGTH
4615 stack_var->value_length = lastitem - stack_var->value;
4616#endif
4617 }
4618 }
4619 }
4620 return o;
4621}
4622#endif /* CONFIG_WITH_STACK */
4623
4624#if defined (CONFIG_WITH_MATH) || defined (CONFIG_WITH_NANOTS) || defined (CONFIG_WITH_FILE_SIZE)
4625/* outputs the number (as a string) into the variable buffer. */
4626static char *
4627math_int_to_variable_buffer (char *o, math_int num)
4628{
4629 static const char xdigits[17] = "0123456789abcdef";
4630 int negative;
4631 char strbuf[24]; /* 16 hex + 2 prefix + sign + term => 20
4632 or 20 dec + sign + term => 22 */
4633 char *str = &strbuf[sizeof (strbuf) - 1];
4634
4635 negative = num < 0;
4636 if (negative)
4637 num = -num;
4638
4639 *str = '\0';
4640
4641 do
4642 {
4643#ifdef HEX_MATH_NUMBERS
4644 *--str = xdigits[num & 0xf];
4645 num >>= 4;
4646#else
4647 *--str = xdigits[num % 10];
4648 num /= 10;
4649#endif
4650 }
4651 while (num);
4652
4653#ifdef HEX_MATH_NUMBERS
4654 *--str = 'x';
4655 *--str = '0';
4656#endif
4657
4658 if (negative)
4659 *--str = '-';
4660
4661 return variable_buffer_output (o, str, &strbuf[sizeof (strbuf) - 1] - str);
4662}
4663#endif /* CONFIG_WITH_MATH || CONFIG_WITH_NANOTS */
4664
4665#ifdef CONFIG_WITH_MATH
4666
4667/* Converts a string to an integer, causes an error if the format is invalid. */
4668static math_int
4669math_int_from_string (const char *str)
4670{
4671 const char *start;
4672 unsigned base = 0;
4673 int negative = 0;
4674 math_int num = 0;
4675
4676 /* strip spaces */
4677 while (isspace (*str))
4678 str++;
4679 if (!*str)
4680 {
4681 error (NILF, _("bad number: empty\n"));
4682 return 0;
4683 }
4684 start = str;
4685
4686 /* check for +/- */
4687 while (*str == '+' || *str == '-' || isspace (*str))
4688 if (*str++ == '-')
4689 negative = !negative;
4690
4691 /* check for prefix - we do not accept octal numbers, sorry. */
4692 if (*str == '0' && (str[1] == 'x' || str[1] == 'X'))
4693 {
4694 base = 16;
4695 str += 2;
4696 }
4697 else
4698 {
4699 /* look for a hex digit, if not found treat it as decimal */
4700 const char *p2 = str;
4701 for ( ; *p2; p2++)
4702 if (isxdigit (*p2) && !isdigit (*p2) && isascii (*p2) )
4703 {
4704 base = 16;
4705 break;
4706 }
4707 if (base == 0)
4708 base = 10;
4709 }
4710
4711 /* must have at least one digit! */
4712 if ( !isascii (*str)
4713 || !(base == 16 ? isxdigit (*str) : isdigit (*str)) )
4714 {
4715 error (NILF, _("bad number: '%s'\n"), start);
4716 return 0;
4717 }
4718
4719 /* convert it! */
4720 while (*str && !isspace (*str))
4721 {
4722 int ch = *str++;
4723 if (ch >= '0' && ch <= '9')
4724 ch -= '0';
4725 else if (base == 16 && ch >= 'a' && ch <= 'f')
4726 ch -= 'a' - 10;
4727 else if (base == 16 && ch >= 'A' && ch <= 'F')
4728 ch -= 'A' - 10;
4729 else
4730 {
4731 error (NILF, _("bad number: '%s' (base=%u, pos=%lu)\n"), start, base, (unsigned long)(str - start));
4732 return 0;
4733 }
4734 num *= base;
4735 num += ch;
4736 }
4737
4738 /* check trailing spaces. */
4739 while (isspace (*str))
4740 str++;
4741 if (*str)
4742 {
4743 error (NILF, _("bad number: '%s'\n"), start);
4744 return 0;
4745 }
4746
4747 return negative ? -num : num;
4748}
4749
4750/* Add two or more integer numbers. */
4751static char *
4752func_int_add (char *o, char **argv, const char *funcname UNUSED)
4753{
4754 math_int num;
4755 int i;
4756
4757 num = math_int_from_string (argv[0]);
4758 for (i = 1; argv[i]; i++)
4759 num += math_int_from_string (argv[i]);
4760
4761 return math_int_to_variable_buffer (o, num);
4762}
4763
4764/* Subtract two or more integer numbers. */
4765static char *
4766func_int_sub (char *o, char **argv, const char *funcname UNUSED)
4767{
4768 math_int num;
4769 int i;
4770
4771 num = math_int_from_string (argv[0]);
4772 for (i = 1; argv[i]; i++)
4773 num -= math_int_from_string (argv[i]);
4774
4775 return math_int_to_variable_buffer (o, num);
4776}
4777
4778/* Multiply two or more integer numbers. */
4779static char *
4780func_int_mul (char *o, char **argv, const char *funcname UNUSED)
4781{
4782 math_int num;
4783 int i;
4784
4785 num = math_int_from_string (argv[0]);
4786 for (i = 1; argv[i]; i++)
4787 num *= math_int_from_string (argv[i]);
4788
4789 return math_int_to_variable_buffer (o, num);
4790}
4791
4792/* Divide an integer number by one or more divisors. */
4793static char *
4794func_int_div (char *o, char **argv, const char *funcname UNUSED)
4795{
4796 math_int num;
4797 math_int divisor;
4798 int i;
4799
4800 num = math_int_from_string (argv[0]);
4801 for (i = 1; argv[i]; i++)
4802 {
4803 divisor = math_int_from_string (argv[i]);
4804 if (!divisor)
4805 {
4806 error (NILF, _("divide by zero ('%s')\n"), argv[i]);
4807 return math_int_to_variable_buffer (o, 0);
4808 }
4809 num /= divisor;
4810 }
4811
4812 return math_int_to_variable_buffer (o, num);
4813}
4814
4815
4816/* Divide and return the remainder. */
4817static char *
4818func_int_mod (char *o, char **argv, const char *funcname UNUSED)
4819{
4820 math_int num;
4821 math_int divisor;
4822
4823 num = math_int_from_string (argv[0]);
4824 divisor = math_int_from_string (argv[1]);
4825 if (!divisor)
4826 {
4827 error (NILF, _("divide by zero ('%s')\n"), argv[1]);
4828 return math_int_to_variable_buffer (o, 0);
4829 }
4830 num %= divisor;
4831
4832 return math_int_to_variable_buffer (o, num);
4833}
4834
4835/* 2-complement. */
4836static char *
4837func_int_not (char *o, char **argv, const char *funcname UNUSED)
4838{
4839 math_int num;
4840
4841 num = math_int_from_string (argv[0]);
4842 num = ~num;
4843
4844 return math_int_to_variable_buffer (o, num);
4845}
4846
4847/* Bitwise AND (two or more numbers). */
4848static char *
4849func_int_and (char *o, char **argv, const char *funcname UNUSED)
4850{
4851 math_int num;
4852 int i;
4853
4854 num = math_int_from_string (argv[0]);
4855 for (i = 1; argv[i]; i++)
4856 num &= math_int_from_string (argv[i]);
4857
4858 return math_int_to_variable_buffer (o, num);
4859}
4860
4861/* Bitwise OR (two or more numbers). */
4862static char *
4863func_int_or (char *o, char **argv, const char *funcname UNUSED)
4864{
4865 math_int num;
4866 int i;
4867
4868 num = math_int_from_string (argv[0]);
4869 for (i = 1; argv[i]; i++)
4870 num |= math_int_from_string (argv[i]);
4871
4872 return math_int_to_variable_buffer (o, num);
4873}
4874
4875/* Bitwise XOR (two or more numbers). */
4876static char *
4877func_int_xor (char *o, char **argv, const char *funcname UNUSED)
4878{
4879 math_int num;
4880 int i;
4881
4882 num = math_int_from_string (argv[0]);
4883 for (i = 1; argv[i]; i++)
4884 num ^= math_int_from_string (argv[i]);
4885
4886 return math_int_to_variable_buffer (o, num);
4887}
4888
4889/* Compare two integer numbers. Returns make boolean (true="1"; false=""). */
4890static char *
4891func_int_cmp (char *o, char **argv, const char *funcname)
4892{
4893 math_int num1;
4894 math_int num2;
4895 int rc;
4896
4897 num1 = math_int_from_string (argv[0]);
4898 num2 = math_int_from_string (argv[1]);
4899
4900 funcname += sizeof ("int-") - 1;
4901 if (!strcmp (funcname, "eq"))
4902 rc = num1 == num2;
4903 else if (!strcmp (funcname, "ne"))
4904 rc = num1 != num2;
4905 else if (!strcmp (funcname, "gt"))
4906 rc = num1 > num2;
4907 else if (!strcmp (funcname, "ge"))
4908 rc = num1 >= num2;
4909 else if (!strcmp (funcname, "lt"))
4910 rc = num1 < num2;
4911 else /*if (!strcmp (funcname, "le"))*/
4912 rc = num1 <= num2;
4913
4914 return variable_buffer_output (o, rc ? "1" : "", rc);
4915}
4916
4917#endif /* CONFIG_WITH_MATH */
4918
4919#ifdef CONFIG_WITH_NANOTS
4920/* Returns the current timestamp as nano seconds. The time
4921 source is a high res monotone one if the platform provides
4922 this (and we know about it).
4923
4924 Tip. Use this with int-sub to profile makefile reading
4925 and similar. */
4926static char *
4927func_nanots (char *o, char **argv UNUSED, const char *funcname UNUSED)
4928{
4929 return math_int_to_variable_buffer (o, nano_timestamp ());
4930}
4931#endif
4932
4933#ifdef CONFIG_WITH_OS2_LIBPATH
4934/* Sets or gets the OS/2 libpath variables.
4935
4936 The first argument indicates which variable - BEGINLIBPATH,
4937 ENDLIBPATH, LIBPATHSTRICT or LIBPATH.
4938
4939 The second indicates whether this is a get (not present) or
4940 set (present) operation. When present it is the new value for
4941 the variable. */
4942static char *
4943func_os2_libpath (char *o, char **argv, const char *funcname UNUSED)
4944{
4945 char buf[4096];
4946 ULONG fVar;
4947 APIRET rc;
4948
4949 /* translate variable name (first arg) */
4950 if (!strcmp (argv[0], "BEGINLIBPATH"))
4951 fVar = BEGIN_LIBPATH;
4952 else if (!strcmp (argv[0], "ENDLIBPATH"))
4953 fVar = END_LIBPATH;
4954 else if (!strcmp (argv[0], "LIBPATHSTRICT"))
4955 fVar = LIBPATHSTRICT;
4956 else if (!strcmp (argv[0], "LIBPATH"))
4957 fVar = 0;
4958 else
4959 {
4960 error (NILF, _("$(libpath): unknown variable `%s'"), argv[0]);
4961 return variable_buffer_output (o, "", 0);
4962 }
4963
4964 if (!argv[1])
4965 {
4966 /* get the variable value. */
4967 if (fVar != 0)
4968 {
4969 buf[0] = buf[1] = buf[2] = buf[3] = '\0';
4970 rc = DosQueryExtLIBPATH (buf, fVar);
4971 }
4972 else
4973 rc = DosQueryHeaderInfo (NULLHANDLE, 0, buf, sizeof(buf), QHINF_LIBPATH);
4974 if (rc != NO_ERROR)
4975 {
4976 error (NILF, _("$(libpath): failed to query `%s', rc=%d"), argv[0], rc);
4977 return variable_buffer_output (o, "", 0);
4978 }
4979 o = variable_buffer_output (o, buf, strlen (buf));
4980 }
4981 else
4982 {
4983 /* set the variable value. */
4984 size_t len;
4985 size_t len_max = sizeof (buf) < 2048 ? sizeof (buf) : 2048;
4986 const char *val;
4987 const char *end;
4988
4989 if (fVar == 0)
4990 {
4991 error (NILF, _("$(libpath): LIBPATH is read-only"));
4992 return variable_buffer_output (o, "", 0);
4993 }
4994
4995 /* strip leading and trailing spaces and check for max length. */
4996 val = argv[1];
4997 while (isspace (*val))
4998 val++;
4999 end = strchr (val, '\0');
5000 while (end > val && isspace (end[-1]))
5001 end--;
5002
5003 len = end - val;
5004 if (len >= len_max)
5005 {
5006 error (NILF, _("$(libpath): The new `%s' value is too long (%d bytes, max %d)"),
5007 argv[0], len, len_max);
5008 return variable_buffer_output (o, "", 0);
5009 }
5010
5011 /* make a stripped copy in low memory and try set it. */
5012 memcpy (buf, val, len);
5013 buf[len] = '\0';
5014 rc = DosSetExtLIBPATH (buf, fVar);
5015 if (rc != NO_ERROR)
5016 {
5017 error (NILF, _("$(libpath): failed to set `%s' to `%s', rc=%d"), argv[0], buf, rc);
5018 return variable_buffer_output (o, "", 0);
5019 }
5020
5021 o = variable_buffer_output (o, "", 0);
5022 }
5023 return o;
5024}
5025#endif /* CONFIG_WITH_OS2_LIBPATH */
5026
5027#if defined (CONFIG_WITH_MAKE_STATS) || defined (CONFIG_WITH_MINIMAL_STATS)
5028/* Retrieve make statistics. */
5029static char *
5030func_make_stats (char *o, char **argv, const char *funcname UNUSED)
5031{
5032 char buf[512];
5033 int len;
5034
5035 if (!argv[0] || (!argv[0][0] && !argv[1]))
5036 {
5037# ifdef CONFIG_WITH_MAKE_STATS
5038 len = sprintf (buf, "alloc-cur: %5ld/%3ld %3luMB hash: %5lu %2lu%%",
5039 make_stats_allocations,
5040 make_stats_reallocations,
5041 make_stats_allocated / (1024*1024),
5042 make_stats_ht_lookups,
5043 (make_stats_ht_collisions * 100) / make_stats_ht_lookups);
5044 o = variable_buffer_output (o, buf, len);
5045#endif
5046 }
5047 else
5048 {
5049 /* selective */
5050 int i;
5051 for (i = 0; argv[i]; i++)
5052 {
5053 unsigned long val;
5054 if (i != 0)
5055 o = variable_buffer_output (o, " ", 1);
5056 if (0)
5057 continue;
5058# ifdef CONFIG_WITH_MAKE_STATS
5059 else if (!strcmp(argv[i], "allocations"))
5060 val = make_stats_allocations;
5061 else if (!strcmp(argv[i], "reallocations"))
5062 val = make_stats_reallocations;
5063 else if (!strcmp(argv[i], "allocated"))
5064 val = make_stats_allocated;
5065 else if (!strcmp(argv[i], "ht_lookups"))
5066 val = make_stats_ht_lookups;
5067 else if (!strcmp(argv[i], "ht_collisions"))
5068 val = make_stats_ht_collisions;
5069 else if (!strcmp(argv[i], "ht_collisions_pct"))
5070 val = (make_stats_ht_collisions * 100) / make_stats_ht_lookups;
5071#endif
5072 else
5073 {
5074 o = variable_buffer_output (o, argv[i], strlen (argv[i]));
5075 continue;
5076 }
5077
5078 len = sprintf (buf, "%ld", val);
5079 o = variable_buffer_output (o, buf, len);
5080 }
5081 }
5082
5083 return o;
5084}
5085#endif /* CONFIG_WITH_MAKE_STATS */
5086
5087#ifdef CONFIG_WITH_COMMANDS_FUNC
5088/* Gets all the commands for a target, separated by newlines.
5089
5090 This is useful when creating and checking target dependencies since
5091 it reduces the amount of work and the memory consuption. A new prefix
5092 character '%' has been introduced for skipping certain lines, like
5093 for instance the one calling this function and pushing to a dep file.
5094 Blank lines are also skipped.
5095
5096 The commands function takes exactly one argument, which is the name of
5097 the target which commands should be returned.
5098
5099 The commands-sc is identical to commands except that it uses a ';' to
5100 separate the commands.
5101
5102 The commands-usr is similar to commands except that it takes a 2nd
5103 argument that is used to separate the commands. */
5104char *
5105func_commands (char *o, char **argv, const char *funcname)
5106{
5107 struct file *file;
5108 static int recursive = 0;
5109
5110 if (recursive)
5111 {
5112 error (reading_file, _("$(%s ) was invoked recursivly"), funcname);
5113 return variable_buffer_output (o, "recursive", sizeof ("recursive") - 1);
5114 }
5115 if (*argv[0] == '\0')
5116 {
5117 error (reading_file, _("$(%s ) was invoked with an empty target name"), funcname);
5118 return o;
5119 }
5120 recursive = 1;
5121
5122 file = lookup_file (argv[0]);
5123 if (file && file->cmds)
5124 {
5125 unsigned int i;
5126 int cmd_sep_len;
5127 struct commands *cmds = file->cmds;
5128 const char *cmd_sep;
5129
5130 if (!strcmp (funcname, "commands"))
5131 {
5132 cmd_sep = "\n";
5133 cmd_sep_len = 1;
5134 }
5135 else if (!strcmp (funcname, "commands-sc"))
5136 {
5137 cmd_sep = ";";
5138 cmd_sep_len = 1;
5139 }
5140 else /*if (!strcmp (funcname, "commands-usr"))*/
5141 {
5142 cmd_sep = argv[1];
5143 cmd_sep_len = strlen (cmd_sep);
5144 }
5145
5146 initialize_file_variables (file, 1 /* don't search for pattern vars */);
5147 set_file_variables (file, 1 /* early call */);
5148 chop_commands (cmds);
5149
5150 for (i = 0; i < cmds->ncommand_lines; i++)
5151 {
5152 char *p;
5153 char *in, *out, *ref;
5154
5155 /* Skip it if it has a '%' prefix or is blank. */
5156 if (cmds->lines_flags[i] & COMMAND_GETTER_SKIP_IT)
5157 continue;
5158 p = cmds->command_lines[i];
5159 while (isblank ((unsigned char)*p))
5160 p++;
5161 if (*p == '\0')
5162 continue;
5163
5164 /* --- copied from new_job() in job.c --- */
5165
5166 /* Collapse backslash-newline combinations that are inside variable
5167 or function references. These are left alone by the parser so
5168 that they will appear in the echoing of commands (where they look
5169 nice); and collapsed by construct_command_argv when it tokenizes.
5170 But letting them survive inside function invocations loses because
5171 we don't want the functions to see them as part of the text. */
5172
5173 /* IN points to where in the line we are scanning.
5174 OUT points to where in the line we are writing.
5175 When we collapse a backslash-newline combination,
5176 IN gets ahead of OUT. */
5177
5178 in = out = p;
5179 while ((ref = strchr (in, '$')) != 0)
5180 {
5181 ++ref; /* Move past the $. */
5182
5183 if (out != in)
5184 /* Copy the text between the end of the last chunk
5185 we processed (where IN points) and the new chunk
5186 we are about to process (where REF points). */
5187 memmove (out, in, ref - in);
5188
5189 /* Move both pointers past the boring stuff. */
5190 out += ref - in;
5191 in = ref;
5192
5193 if (*ref == '(' || *ref == '{')
5194 {
5195 char openparen = *ref;
5196 char closeparen = openparen == '(' ? ')' : '}';
5197 int count;
5198 char *p2;
5199
5200 *out++ = *in++; /* Copy OPENPAREN. */
5201 /* IN now points past the opening paren or brace.
5202 Count parens or braces until it is matched. */
5203 count = 0;
5204 while (*in != '\0')
5205 {
5206 if (*in == closeparen && --count < 0)
5207 break;
5208 else if (*in == '\\' && in[1] == '\n')
5209 {
5210 /* We have found a backslash-newline inside a
5211 variable or function reference. Eat it and
5212 any following whitespace. */
5213
5214 int quoted = 0;
5215 for (p2 = in - 1; p2 > ref && *p2 == '\\'; --p2)
5216 quoted = !quoted;
5217
5218 if (quoted)
5219 /* There were two or more backslashes, so this is
5220 not really a continuation line. We don't collapse
5221 the quoting backslashes here as is done in
5222 collapse_continuations, because the line will
5223 be collapsed again after expansion. */
5224 *out++ = *in++;
5225 else
5226 {
5227 /* Skip the backslash, newline and
5228 any following whitespace. */
5229 in = next_token (in + 2);
5230
5231 /* Discard any preceding whitespace that has
5232 already been written to the output. */
5233 while (out > ref
5234 && isblank ((unsigned char)out[-1]))
5235 --out;
5236
5237 /* Replace it all with a single space. */
5238 *out++ = ' ';
5239 }
5240 }
5241 else
5242 {
5243 if (*in == openparen)
5244 ++count;
5245
5246 *out++ = *in++;
5247 }
5248 }
5249 }
5250 /* Some of these can be amended ($< perhaps), but we're likely to be called while the
5251 dep expansion happens, so it would have to be on a hackish basis. sad... */
5252 else if (*ref == '<' || *ref == '*' || *ref == '%' || *ref == '^' || *ref == '+')
5253 error (reading_file, _("$(%s ) does not work reliably with $%c in all cases"), funcname, *ref);
5254 }
5255
5256 /* There are no more references in this line to worry about.
5257 Copy the remaining uninteresting text to the output. */
5258 if (out != in)
5259 strcpy (out, in);
5260
5261 /* --- copied from new_job() in job.c --- */
5262
5263 /* Finally, expand the line. */
5264 if (i)
5265 o = variable_buffer_output (o, cmd_sep, cmd_sep_len);
5266 o = variable_expand_for_file_2 (o, cmds->command_lines[i], ~0U, file, NULL);
5267
5268 /* Skip it if it has a '%' prefix or is blank. */
5269 p = o;
5270 while (isblank ((unsigned char)*o)
5271 || *o == '@'
5272 || *o == '-'
5273 || *o == '+')
5274 o++;
5275 if (*o != '\0' && *o != '%')
5276 o = strchr (o, '\0');
5277 else if (i)
5278 o = p - cmd_sep_len;
5279 else
5280 o = p;
5281 } /* for each command line */
5282 }
5283 /* else FIXME: bitch about it? */
5284
5285 recursive = 0;
5286 return o;
5287}
5288#endif /* CONFIG_WITH_COMMANDS_FUNC */
5289#ifdef KMK
5290
5291/* Useful when debugging kmk and/or makefiles. */
5292char *
5293func_breakpoint (char *o, char **argv UNUSED, const char *funcname UNUSED)
5294{
5295#ifdef _MSC_VER
5296 __debugbreak();
5297#elif defined(__i386__) || defined(__x86__) || defined(__X86__) || defined(_M_IX86) || defined(__i386) \
5298 || defined(__amd64__) || defined(__x86_64__) || defined(__AMD64__) || defined(_M_X64) || defined(__amd64)
5299# ifdef __sun__
5300 __asm__ __volatile__ ("int $3\n\t");
5301# else
5302 __asm__ __volatile__ ("int3\n\t");
5303# endif
5304#else
5305 char *p = (char *)0;
5306 *p = '\0';
5307#endif
5308 return o;
5309}
5310
5311/* umask | umask -S. */
5312char *
5313func_get_umask (char *o, char **argv UNUSED, const char *funcname UNUSED)
5314{
5315 char sz[80];
5316 int off;
5317 mode_t u;
5318 int symbolic = 0;
5319 const char *psz = argv[0];
5320
5321 if (psz)
5322 {
5323 const char *pszEnd = strchr (psz, '\0');
5324 strip_whitespace (&psz, &pszEnd);
5325
5326 if (pszEnd != psz)
5327 {
5328 if ( STR_N_EQUALS (psz, pszEnd - pszEnd, "S")
5329 || STR_N_EQUALS (psz, pszEnd - pszEnd, "-S")
5330 || STR_N_EQUALS (psz, pszEnd - pszEnd, "symbolic") )
5331 symbolic = 1;
5332 else
5333 error (reading_file, _("$(%s ) invalid argument `%s'"),
5334 funcname, argv[0]);
5335 }
5336 }
5337
5338 u = umask (002);
5339 umask (u);
5340
5341 if (symbolic)
5342 {
5343 off = 0;
5344 sz[off++] = 'u';
5345 sz[off++] = '=';
5346 if ((u & S_IRUSR) == 0)
5347 sz[off++] = 'r';
5348 if ((u & S_IWUSR) == 0)
5349 sz[off++] = 'w';
5350 if ((u & S_IXUSR) == 0)
5351 sz[off++] = 'x';
5352 sz[off++] = ',';
5353 sz[off++] = 'g';
5354 sz[off++] = '=';
5355 if ((u & S_IRGRP) == 0)
5356 sz[off++] = 'r';
5357 if ((u & S_IWGRP) == 0)
5358 sz[off++] = 'w';
5359 if ((u & S_IXGRP) == 0)
5360 sz[off++] = 'x';
5361 sz[off++] = ',';
5362 sz[off++] = 'o';
5363 sz[off++] = '=';
5364 if ((u & S_IROTH) == 0)
5365 sz[off++] = 'r';
5366 if ((u & S_IWOTH) == 0)
5367 sz[off++] = 'w';
5368 if ((u & S_IXOTH) == 0)
5369 sz[off++] = 'x';
5370 }
5371 else
5372 off = sprintf (sz, "%.4o", u);
5373
5374 return variable_buffer_output (o, sz, off);
5375}
5376
5377
5378/* umask 0002 | umask u=rwx,g=rwx,o=rx. */
5379char *
5380func_set_umask (char *o, char **argv UNUSED, const char *funcname UNUSED)
5381{
5382 mode_t u;
5383 const char *psz;
5384
5385 /* Figure what kind of input this is. */
5386 psz = argv[0];
5387 while (isblank ((unsigned char)*psz))
5388 psz++;
5389
5390 if (isdigit ((unsigned char)*psz))
5391 {
5392 u = 0;
5393 while (*psz)
5394 {
5395 u <<= 3;
5396 if (*psz < '0' || *psz >= '8')
5397 {
5398 error (reading_file, _("$(%s ) illegal number `%s'"), funcname, argv[0]);
5399 break;
5400 }
5401 u += *psz - '0';
5402 psz++;
5403 }
5404
5405 if (argv[1] != NULL)
5406 error (reading_file, _("$(%s ) too many arguments for octal mode"), funcname);
5407 }
5408 else
5409 {
5410 u = umask(0);
5411 umask(u);
5412 error (reading_file, _("$(%s ) symbol mode is not implemented"), funcname);
5413 }
5414
5415 umask(u);
5416
5417 return o;
5418}
5419
5420#endif /* KMK */
5421
5422
5423/* Lookup table for builtin functions.
5424
5425 This doesn't have to be sorted; we use a straight lookup. We might gain
5426 some efficiency by moving most often used functions to the start of the
5427 table.
5428
5429 If MAXIMUM_ARGS is 0, that means there is no maximum and all
5430 comma-separated values are treated as arguments.
5431
5432 EXPAND_ARGS means that all arguments should be expanded before invocation.
5433 Functions that do namespace tricks (foreach) don't automatically expand. */
5434
5435static char *func_call (char *o, char **argv, const char *funcname);
5436
5437
5438static struct function_table_entry function_table_init[] =
5439{
5440 /* Name/size */ /* MIN MAX EXP? Function */
5441 { STRING_SIZE_TUPLE("abspath"), 0, 1, 1, func_abspath},
5442 { STRING_SIZE_TUPLE("addprefix"), 2, 2, 1, func_addsuffix_addprefix},
5443 { STRING_SIZE_TUPLE("addsuffix"), 2, 2, 1, func_addsuffix_addprefix},
5444 { STRING_SIZE_TUPLE("basename"), 0, 1, 1, func_basename_dir},
5445 { STRING_SIZE_TUPLE("dir"), 0, 1, 1, func_basename_dir},
5446 { STRING_SIZE_TUPLE("notdir"), 0, 1, 1, func_notdir_suffix},
5447#ifdef CONFIG_WITH_ROOT_FUNC
5448 { STRING_SIZE_TUPLE("root"), 0, 1, 1, func_root},
5449 { STRING_SIZE_TUPLE("notroot"), 0, 1, 1, func_notroot},
5450#endif
5451 { STRING_SIZE_TUPLE("subst"), 3, 3, 1, func_subst},
5452 { STRING_SIZE_TUPLE("suffix"), 0, 1, 1, func_notdir_suffix},
5453 { STRING_SIZE_TUPLE("filter"), 2, 2, 1, func_filter_filterout},
5454 { STRING_SIZE_TUPLE("filter-out"), 2, 2, 1, func_filter_filterout},
5455 { STRING_SIZE_TUPLE("findstring"), 2, 2, 1, func_findstring},
5456#ifdef CONFIG_WITH_DEFINED_FUNCTIONS
5457 { STRING_SIZE_TUPLE("firstdefined"), 0, 2, 1, func_firstdefined},
5458#endif
5459 { STRING_SIZE_TUPLE("firstword"), 0, 1, 1, func_firstword},
5460 { STRING_SIZE_TUPLE("flavor"), 0, 1, 1, func_flavor},
5461 { STRING_SIZE_TUPLE("join"), 2, 2, 1, func_join},
5462#ifdef CONFIG_WITH_DEFINED_FUNCTIONS
5463 { STRING_SIZE_TUPLE("lastdefined"), 0, 2, 1, func_lastdefined},
5464#endif
5465 { STRING_SIZE_TUPLE("lastword"), 0, 1, 1, func_lastword},
5466 { STRING_SIZE_TUPLE("patsubst"), 3, 3, 1, func_patsubst},
5467 { STRING_SIZE_TUPLE("realpath"), 0, 1, 1, func_realpath},
5468#ifdef CONFIG_WITH_RSORT
5469 { STRING_SIZE_TUPLE("rsort"), 0, 1, 1, func_sort},
5470#endif
5471 { STRING_SIZE_TUPLE("shell"), 0, 1, 1, func_shell},
5472 { STRING_SIZE_TUPLE("sort"), 0, 1, 1, func_sort},
5473 { STRING_SIZE_TUPLE("strip"), 0, 1, 1, func_strip},
5474#ifdef CONFIG_WITH_WHERE_FUNCTION
5475 { STRING_SIZE_TUPLE("where"), 0, 1, 1, func_where},
5476#endif
5477 { STRING_SIZE_TUPLE("wildcard"), 0, 1, 1, func_wildcard},
5478 { STRING_SIZE_TUPLE("word"), 2, 2, 1, func_word},
5479 { STRING_SIZE_TUPLE("wordlist"), 3, 3, 1, func_wordlist},
5480 { STRING_SIZE_TUPLE("words"), 0, 1, 1, func_words},
5481 { STRING_SIZE_TUPLE("origin"), 0, 1, 1, func_origin},
5482 { STRING_SIZE_TUPLE("foreach"), 3, 3, 0, func_foreach},
5483#ifdef CONFIG_WITH_LOOP_FUNCTIONS
5484 { STRING_SIZE_TUPLE("for"), 4, 4, 0, func_for},
5485 { STRING_SIZE_TUPLE("while"), 2, 2, 0, func_while},
5486#endif
5487 { STRING_SIZE_TUPLE("call"), 1, 0, 1, func_call},
5488 { STRING_SIZE_TUPLE("info"), 0, 1, 1, func_error},
5489 { STRING_SIZE_TUPLE("error"), 0, 1, 1, func_error},
5490 { STRING_SIZE_TUPLE("warning"), 0, 1, 1, func_error},
5491 { STRING_SIZE_TUPLE("if"), 2, 3, 0, func_if},
5492 { STRING_SIZE_TUPLE("or"), 1, 0, 0, func_or},
5493 { STRING_SIZE_TUPLE("and"), 1, 0, 0, func_and},
5494 { STRING_SIZE_TUPLE("value"), 0, 1, 1, func_value},
5495 { STRING_SIZE_TUPLE("eval"), 0, 1, 1, func_eval},
5496#ifdef CONFIG_WITH_EVALPLUS
5497 { STRING_SIZE_TUPLE("evalctx"), 0, 1, 1, func_evalctx},
5498 { STRING_SIZE_TUPLE("evalval"), 1, 1, 1, func_evalval},
5499 { STRING_SIZE_TUPLE("evalvalctx"), 1, 1, 1, func_evalval},
5500 { STRING_SIZE_TUPLE("evalcall"), 1, 0, 1, func_call},
5501 { STRING_SIZE_TUPLE("evalcall2"), 1, 0, 1, func_call},
5502 { STRING_SIZE_TUPLE("eval-opt-var"), 1, 0, 1, func_eval_optimize_variable},
5503#endif
5504#ifdef EXPERIMENTAL
5505 { STRING_SIZE_TUPLE("eq"), 2, 2, 1, func_eq},
5506 { STRING_SIZE_TUPLE("not"), 0, 1, 1, func_not},
5507#endif
5508#ifdef CONFIG_WITH_STRING_FUNCTIONS
5509 { STRING_SIZE_TUPLE("length"), 1, 1, 1, func_length},
5510 { STRING_SIZE_TUPLE("length-var"), 1, 1, 1, func_length_var},
5511 { STRING_SIZE_TUPLE("insert"), 2, 5, 1, func_insert},
5512 { STRING_SIZE_TUPLE("pos"), 2, 3, 1, func_pos},
5513 { STRING_SIZE_TUPLE("lastpos"), 2, 3, 1, func_pos},
5514 { STRING_SIZE_TUPLE("substr"), 2, 4, 1, func_substr},
5515 { STRING_SIZE_TUPLE("translate"), 2, 4, 1, func_translate},
5516#endif
5517#ifdef CONFIG_WITH_PRINTF
5518 { STRING_SIZE_TUPLE("printf"), 1, 0, 1, kmk_builtin_func_printf},
5519#endif
5520#ifdef CONFIG_WITH_LAZY_DEPS_VARS
5521 { STRING_SIZE_TUPLE("deps"), 1, 2, 1, func_deps},
5522 { STRING_SIZE_TUPLE("deps-all"), 1, 2, 1, func_deps},
5523 { STRING_SIZE_TUPLE("deps-newer"), 1, 2, 1, func_deps_newer},
5524 { STRING_SIZE_TUPLE("deps-oo"), 1, 2, 1, func_deps_order_only},
5525#endif
5526#ifdef CONFIG_WITH_DEFINED
5527 { STRING_SIZE_TUPLE("defined"), 1, 1, 1, func_defined},
5528#endif
5529#ifdef CONFIG_WITH_TOUPPER_TOLOWER
5530 { STRING_SIZE_TUPLE("toupper"), 0, 1, 1, func_toupper_tolower},
5531 { STRING_SIZE_TUPLE("tolower"), 0, 1, 1, func_toupper_tolower},
5532#endif
5533#ifdef CONFIG_WITH_ABSPATHEX
5534 { STRING_SIZE_TUPLE("abspathex"), 0, 2, 1, func_abspathex},
5535#endif
5536#ifdef CONFIG_WITH_XARGS
5537 { STRING_SIZE_TUPLE("xargs"), 2, 0, 1, func_xargs},
5538#endif
5539#if defined(CONFIG_WITH_VALUE_LENGTH) && defined(CONFIG_WITH_COMPARE)
5540 { STRING_SIZE_TUPLE("comp-vars"), 3, 3, 1, func_comp_vars},
5541 { STRING_SIZE_TUPLE("comp-cmds"), 3, 3, 1, func_comp_vars},
5542 { STRING_SIZE_TUPLE("comp-cmds-ex"), 3, 3, 1, func_comp_cmds_ex},
5543#endif
5544#ifdef CONFIG_WITH_DATE
5545 { STRING_SIZE_TUPLE("date"), 0, 1, 1, func_date},
5546 { STRING_SIZE_TUPLE("date-utc"), 0, 3, 1, func_date},
5547#endif
5548#ifdef CONFIG_WITH_FILE_SIZE
5549 { STRING_SIZE_TUPLE("file-size"), 1, 1, 1, func_file_size},
5550#endif
5551#ifdef CONFIG_WITH_WHICH
5552 { STRING_SIZE_TUPLE("which"), 0, 0, 1, func_which},
5553#endif
5554#ifdef CONFIG_WITH_IF_CONDITIONALS
5555 { STRING_SIZE_TUPLE("expr"), 1, 1, 0, func_expr},
5556 { STRING_SIZE_TUPLE("if-expr"), 2, 3, 0, func_if_expr},
5557 { STRING_SIZE_TUPLE("select"), 2, 0, 0, func_select},
5558#endif
5559#ifdef CONFIG_WITH_SET_CONDITIONALS
5560 { STRING_SIZE_TUPLE("intersects"), 2, 2, 1, func_set_intersects},
5561#endif
5562#ifdef CONFIG_WITH_STACK
5563 { STRING_SIZE_TUPLE("stack-push"), 2, 2, 1, func_stack_push},
5564 { STRING_SIZE_TUPLE("stack-pop"), 1, 1, 1, func_stack_pop_top},
5565 { STRING_SIZE_TUPLE("stack-popv"), 1, 1, 1, func_stack_pop_top},
5566 { STRING_SIZE_TUPLE("stack-top"), 1, 1, 1, func_stack_pop_top},
5567#endif
5568#ifdef CONFIG_WITH_MATH
5569 { STRING_SIZE_TUPLE("int-add"), 2, 0, 1, func_int_add},
5570 { STRING_SIZE_TUPLE("int-sub"), 2, 0, 1, func_int_sub},
5571 { STRING_SIZE_TUPLE("int-mul"), 2, 0, 1, func_int_mul},
5572 { STRING_SIZE_TUPLE("int-div"), 2, 0, 1, func_int_div},
5573 { STRING_SIZE_TUPLE("int-mod"), 2, 2, 1, func_int_mod},
5574 { STRING_SIZE_TUPLE("int-not"), 1, 1, 1, func_int_not},
5575 { STRING_SIZE_TUPLE("int-and"), 2, 0, 1, func_int_and},
5576 { STRING_SIZE_TUPLE("int-or"), 2, 0, 1, func_int_or},
5577 { STRING_SIZE_TUPLE("int-xor"), 2, 0, 1, func_int_xor},
5578 { STRING_SIZE_TUPLE("int-eq"), 2, 2, 1, func_int_cmp},
5579 { STRING_SIZE_TUPLE("int-ne"), 2, 2, 1, func_int_cmp},
5580 { STRING_SIZE_TUPLE("int-gt"), 2, 2, 1, func_int_cmp},
5581 { STRING_SIZE_TUPLE("int-ge"), 2, 2, 1, func_int_cmp},
5582 { STRING_SIZE_TUPLE("int-lt"), 2, 2, 1, func_int_cmp},
5583 { STRING_SIZE_TUPLE("int-le"), 2, 2, 1, func_int_cmp},
5584#endif
5585#ifdef CONFIG_WITH_NANOTS
5586 { STRING_SIZE_TUPLE("nanots"), 0, 0, 0, func_nanots},
5587#endif
5588#ifdef CONFIG_WITH_OS2_LIBPATH
5589 { STRING_SIZE_TUPLE("libpath"), 1, 2, 1, func_os2_libpath},
5590#endif
5591#if defined (CONFIG_WITH_MAKE_STATS) || defined (CONFIG_WITH_MINIMAL_STATS)
5592 { STRING_SIZE_TUPLE("make-stats"), 0, 0, 0, func_make_stats},
5593#endif
5594#ifdef CONFIG_WITH_COMMANDS_FUNC
5595 { STRING_SIZE_TUPLE("commands"), 1, 1, 1, func_commands},
5596 { STRING_SIZE_TUPLE("commands-sc"), 1, 1, 1, func_commands},
5597 { STRING_SIZE_TUPLE("commands-usr"), 2, 2, 1, func_commands},
5598#endif
5599#ifdef KMK_HELPERS
5600 { STRING_SIZE_TUPLE("kb-src-tool"), 1, 1, 0, func_kbuild_source_tool},
5601 { STRING_SIZE_TUPLE("kb-obj-base"), 1, 1, 0, func_kbuild_object_base},
5602 { STRING_SIZE_TUPLE("kb-obj-suff"), 1, 1, 0, func_kbuild_object_suffix},
5603 { STRING_SIZE_TUPLE("kb-src-prop"), 3, 4, 0, func_kbuild_source_prop},
5604 { STRING_SIZE_TUPLE("kb-src-one"), 0, 1, 0, func_kbuild_source_one},
5605 { STRING_SIZE_TUPLE("kb-exp-tmpl"), 6, 6, 1, func_kbuild_expand_template},
5606#endif
5607#ifdef KMK
5608 { STRING_SIZE_TUPLE("breakpoint"), 0, 0, 0, func_breakpoint},
5609 { STRING_SIZE_TUPLE("set-umask"), 1, 3, 1, func_set_umask},
5610 { STRING_SIZE_TUPLE("get-umask"), 0, 0, 0, func_get_umask},
5611#endif
5612};
5613
5614#define FUNCTION_TABLE_ENTRIES (sizeof (function_table_init) / sizeof (struct function_table_entry))
5615
5616
5617
5618/* These must come after the definition of function_table. */
5619
5620static char *
5621expand_builtin_function (char *o, int argc, char **argv,
5622 const struct function_table_entry *entry_p)
5623{
5624 if (argc < (int)entry_p->minimum_args)
5625 fatal (*expanding_var,
5626 _("insufficient number of arguments (%d) to function `%s'"),
5627 argc, entry_p->name);
5628
5629 /* I suppose technically some function could do something with no
5630 arguments, but so far none do, so just test it for all functions here
5631 rather than in each one. We can change it later if necessary. */
5632
5633 if (!argc)
5634 return o;
5635
5636 if (!entry_p->func_ptr)
5637 fatal (*expanding_var,
5638 _("unimplemented on this platform: function `%s'"), entry_p->name);
5639
5640 return entry_p->func_ptr (o, argv, entry_p->name);
5641}
5642
5643/* Check for a function invocation in *STRINGP. *STRINGP points at the
5644 opening ( or { and is not null-terminated. If a function invocation
5645 is found, expand it into the buffer at *OP, updating *OP, incrementing
5646 *STRINGP past the reference and returning nonzero. If not, return zero. */
5647
5648static int
5649handle_function2 (const struct function_table_entry *entry_p, char **op, const char **stringp) /* bird split it up. */
5650{
5651 char openparen = (*stringp)[0];
5652 char closeparen = openparen == '(' ? ')' : '}';
5653 const char *beg;
5654 const char *end;
5655 int count = 0;
5656 char *abeg = NULL;
5657 char **argv, **argvp;
5658 int nargs;
5659
5660 beg = *stringp + 1;
5661
5662 /* We found a builtin function. Find the beginning of its arguments (skip
5663 whitespace after the name). */
5664
5665 beg = next_token (beg + entry_p->len);
5666
5667 /* Find the end of the function invocation, counting nested use of
5668 whichever kind of parens we use. Since we're looking, count commas
5669 to get a rough estimate of how many arguments we might have. The
5670 count might be high, but it'll never be low. */
5671
5672 for (nargs=1, end=beg; *end != '\0'; ++end)
5673 if (*end == ',')
5674 ++nargs;
5675 else if (*end == openparen)
5676 ++count;
5677 else if (*end == closeparen && --count < 0)
5678 break;
5679
5680 if (count >= 0)
5681 fatal (*expanding_var,
5682 _("unterminated call to function `%s': missing `%c'"),
5683 entry_p->name, closeparen);
5684
5685 *stringp = end;
5686
5687 /* Get some memory to store the arg pointers. */
5688 argvp = argv = alloca (sizeof (char *) * (nargs + 2));
5689
5690 /* Chop the string into arguments, then a nul. As soon as we hit
5691 MAXIMUM_ARGS (if it's >0) assume the rest of the string is part of the
5692 last argument.
5693
5694 If we're expanding, store pointers to the expansion of each one. If
5695 not, make a duplicate of the string and point into that, nul-terminating
5696 each argument. */
5697
5698 if (entry_p->expand_args)
5699 {
5700 const char *p;
5701 for (p=beg, nargs=0; p <= end; ++argvp)
5702 {
5703 const char *next;
5704
5705 ++nargs;
5706
5707 if (nargs == entry_p->maximum_args
5708 || (! (next = find_next_argument (openparen, closeparen, p, end))))
5709 next = end;
5710
5711 *argvp = expand_argument (p, next);
5712 p = next + 1;
5713 }
5714 }
5715 else
5716 {
5717 int len = end - beg;
5718 char *p, *aend;
5719
5720 abeg = xmalloc (len+1);
5721 memcpy (abeg, beg, len);
5722 abeg[len] = '\0';
5723 aend = abeg + len;
5724
5725 for (p=abeg, nargs=0; p <= aend; ++argvp)
5726 {
5727 char *next;
5728
5729 ++nargs;
5730
5731 if (nargs == entry_p->maximum_args
5732 || (! (next = find_next_argument (openparen, closeparen, p, aend))))
5733 next = aend;
5734
5735 *argvp = p;
5736 *next = '\0';
5737 p = next + 1;
5738 }
5739 }
5740 *argvp = NULL;
5741
5742 /* Finally! Run the function... */
5743 *op = expand_builtin_function (*op, nargs, argv, entry_p);
5744
5745 /* Free memory. */
5746 if (entry_p->expand_args)
5747 for (argvp=argv; *argvp != 0; ++argvp)
5748 free (*argvp);
5749 if (abeg)
5750 free (abeg);
5751
5752 return 1;
5753}
5754
5755
5756int /* bird split it up and hacked it. */
5757#ifndef CONFIG_WITH_VALUE_LENGTH
5758handle_function (char **op, const char **stringp)
5759{
5760 const struct function_table_entry *entry_p = lookup_function (*stringp + 1);
5761 if (!entry_p)
5762 return 0;
5763 return handle_function2 (entry_p, op, stringp);
5764}
5765#else /* CONFIG_WITH_VALUE_LENGTH */
5766handle_function (char **op, const char **stringp, const char *nameend, const char *eol UNUSED)
5767{
5768 const char *fname = *stringp + 1;
5769 const struct function_table_entry *entry_p =
5770 lookup_function_in_hash_tab (fname, nameend - fname);
5771 if (!entry_p)
5772 return 0;
5773 return handle_function2 (entry_p, op, stringp);
5774}
5775#endif /* CONFIG_WITH_VALUE_LENGTH */
5776
5777
5778
5779/* User-defined functions. Expand the first argument as either a builtin
5780 function or a make variable, in the context of the rest of the arguments
5781 assigned to $1, $2, ... $N. $0 is the name of the function. */
5782
5783static char *
5784func_call (char *o, char **argv, const char *funcname UNUSED)
5785{
5786 static int max_args = 0;
5787 char *fname;
5788 char *cp;
5789 char *body;
5790 int flen;
5791 int i;
5792 int saved_args;
5793 const struct function_table_entry *entry_p;
5794 struct variable *v;
5795#ifdef CONFIG_WITH_EVALPLUS
5796 char *buf;
5797 unsigned int len;
5798#endif
5799#if defined (CONFIG_WITH_EVALPLUS) || defined (CONFIG_WITH_VALUE_LENGTH)
5800 char num[11];
5801#endif
5802
5803 /* There is no way to define a variable with a space in the name, so strip
5804 leading and trailing whitespace as a favor to the user. */
5805 fname = argv[0];
5806 while (*fname != '\0' && isspace ((unsigned char)*fname))
5807 ++fname;
5808
5809 cp = fname + strlen (fname) - 1;
5810 while (cp > fname && isspace ((unsigned char)*cp))
5811 --cp;
5812 cp[1] = '\0';
5813
5814 /* Calling nothing is a no-op */
5815 if (*fname == '\0')
5816 return o;
5817
5818 /* Are we invoking a builtin function? */
5819
5820#ifndef CONFIG_WITH_VALUE_LENGTH
5821 entry_p = lookup_function (fname);
5822#else
5823 entry_p = lookup_function (fname, cp - fname + 1);
5824#endif
5825 if (entry_p)
5826 {
5827 /* How many arguments do we have? */
5828 for (i=0; argv[i+1]; ++i)
5829 ;
5830 return expand_builtin_function (o, i, argv+1, entry_p);
5831 }
5832
5833 /* Not a builtin, so the first argument is the name of a variable to be
5834 expanded and interpreted as a function. Find it. */
5835 flen = strlen (fname);
5836
5837 v = lookup_variable (fname, flen);
5838
5839 if (v == 0)
5840 warn_undefined (fname, flen);
5841
5842 if (v == 0 || *v->value == '\0')
5843 return o;
5844
5845 body = alloca (flen + 4);
5846 body[0] = '$';
5847 body[1] = '(';
5848 memcpy (body + 2, fname, flen);
5849 body[flen+2] = ')';
5850 body[flen+3] = '\0';
5851
5852 /* Set up arguments $(1) .. $(N). $(0) is the function name. */
5853
5854 push_new_variable_scope ();
5855
5856 for (i=0; *argv; ++i, ++argv)
5857#ifdef CONFIG_WITH_VALUE_LENGTH
5858 define_variable (num, sprintf (num, "%d", i), *argv, o_automatic, 0);
5859#else
5860 {
5861 char num[11];
5862
5863 sprintf (num, "%d", i);
5864 define_variable (num, strlen (num), *argv, o_automatic, 0);
5865 }
5866#endif
5867
5868#ifdef CONFIG_WITH_EVALPLUS
5869 /* $(.ARGC) is the argument count. */
5870
5871 len = sprintf (num, "%d", i - 1);
5872 define_variable_vl (".ARGC", sizeof (".ARGC") - 1, num, len,
5873 1 /* dup val */, o_automatic, 0);
5874#endif
5875
5876 /* If the number of arguments we have is < max_args, it means we're inside
5877 a recursive invocation of $(call ...). Fill in the remaining arguments
5878 in the new scope with the empty value, to hide them from this
5879 invocation. */
5880
5881 for (; i < max_args; ++i)
5882#ifdef CONFIG_WITH_VALUE_LENGTH
5883 define_variable (num, sprintf (num, "%d", i), "", o_automatic, 0);
5884#else
5885 {
5886 char num[11];
5887
5888 sprintf (num, "%d", i);
5889 define_variable (num, strlen (num), "", o_automatic, 0);
5890 }
5891#endif
5892
5893 saved_args = max_args;
5894 max_args = i;
5895
5896#ifdef CONFIG_WITH_EVALPLUS
5897 if (!strcmp (funcname, "call"))
5898 {
5899#endif
5900 /* Expand the body in the context of the arguments, adding the result to
5901 the variable buffer. */
5902
5903 v->exp_count = EXP_COUNT_MAX;
5904#ifndef CONFIG_WITH_VALUE_LENGTH
5905 o = variable_expand_string (o, body, flen+3);
5906 v->exp_count = 0;
5907
5908 o += strlen (o);
5909#else /* CONFIG_WITH_VALUE_LENGTH */
5910 variable_expand_string_2 (o, body, flen+3, &o);
5911 v->exp_count = 0;
5912#endif /* CONFIG_WITH_VALUE_LENGTH */
5913#ifdef CONFIG_WITH_EVALPLUS
5914 }
5915 else
5916 {
5917 const struct floc *reading_file_saved = reading_file;
5918 char *eos;
5919
5920 if (!strcmp (funcname, "evalcall"))
5921 {
5922 /* Evaluate the variable value without expanding it. We
5923 need a copy since eval_buffer is destructive. */
5924
5925 size_t off = o - variable_buffer;
5926 eos = variable_buffer_output (o, v->value, v->value_length + 1) - 1;
5927 o = variable_buffer + off;
5928 if (v->fileinfo.filenm)
5929 reading_file = &v->fileinfo;
5930 }
5931 else
5932 {
5933 /* Expand the body first and then evaluate the output. */
5934
5935 v->exp_count = EXP_COUNT_MAX;
5936 o = variable_expand_string_2 (o, body, flen+3, &eos);
5937 v->exp_count = 0;
5938 }
5939
5940 install_variable_buffer (&buf, &len);
5941 eval_buffer (o, eos);
5942 restore_variable_buffer (buf, len);
5943 reading_file = reading_file_saved;
5944
5945 /* Deal with the .RETURN value if present. */
5946
5947 v = lookup_variable_in_set (".RETURN", sizeof (".RETURN") - 1,
5948 current_variable_set_list->set);
5949 if (v && v->value_length)
5950 {
5951 if (v->recursive)
5952 {
5953 v->exp_count = EXP_COUNT_MAX;
5954 variable_expand_string_2 (o, v->value, v->value_length, &o);
5955 v->exp_count = 0;
5956 }
5957 else
5958 o = variable_buffer_output (o, v->value, v->value_length);
5959 }
5960 }
5961#endif /* CONFIG_WITH_EVALPLUS */
5962
5963 max_args = saved_args;
5964
5965 pop_variable_scope ();
5966
5967 return o;
5968}
5969
5970void
5971hash_init_function_table (void)
5972{
5973 hash_init (&function_table, FUNCTION_TABLE_ENTRIES * 2,
5974 function_table_entry_hash_1, function_table_entry_hash_2,
5975 function_table_entry_hash_cmp);
5976 hash_load (&function_table, function_table_init,
5977 FUNCTION_TABLE_ENTRIES, sizeof (struct function_table_entry));
5978#if defined (CONFIG_WITH_OPTIMIZATION_HACKS) || defined (CONFIG_WITH_VALUE_LENGTH)
5979 {
5980 unsigned int i;
5981 for (i = 0; i < FUNCTION_TABLE_ENTRIES; i++)
5982 {
5983 const char *fn = function_table_init[i].name;
5984 while (*fn)
5985 {
5986 func_char_map[(int)*fn] = 1;
5987 fn++;
5988 }
5989 assert (function_table_init[i].len <= MAX_FUNCTION_LENGTH);
5990 assert (function_table_init[i].len >= MIN_FUNCTION_LENGTH);
5991 }
5992 }
5993#endif
5994}
Note: See TracBrowser for help on using the repository browser.