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

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

kmk: Extended the substr function to allow refering length from the end of the string by using negative numbers (just like the start offset).

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