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