VirtualBox

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

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

Initial code for the string expansion 'compiler'.

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

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