source: trunk/third/gmake/function.c @ 15972

Revision 15972, 44.8 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r15971, which included commits to RCS files with non-trunk default branches.
Line 
1/* Builtin function expansion for GNU Make.
2Copyright (C) 1988,1989,1991-1997,1999 Free Software Foundation, Inc.
3This file is part of GNU Make.
4
5GNU Make is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation; either version 2, or (at your option)
8any later version.
9
10GNU Make is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with GNU Make; see the file COPYING.  If not, write to
17the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18Boston, MA 02111-1307, USA.  */
19
20#include "make.h"
21#include "filedef.h"
22#include "variable.h"
23#include "dep.h"
24#include "job.h"
25#include "commands.h"
26#include "debug.h"
27
28#ifdef _AMIGA
29#include "amiga.h"
30#endif
31
32
33struct function_table_entry
34  {
35    const char *name;
36    unsigned char len;
37    unsigned char minimum_args;
38    unsigned char maximum_args;
39    char expand_args;
40    char *(*func_ptr) PARAMS ((char *output, char **argv, const char *fname));
41  };
42
43
44/* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing
45   each occurrence of SUBST with REPLACE. TEXT is null-terminated.  SLEN is
46   the length of SUBST and RLEN is the length of REPLACE.  If BY_WORD is
47   nonzero, substitutions are done only on matches which are complete
48   whitespace-delimited words.  If SUFFIX_ONLY is nonzero, substitutions are
49   done only at the ends of whitespace-delimited words.  */
50
51char *
52subst_expand (o, text, subst, replace, slen, rlen, by_word, suffix_only)
53     char *o;
54     char *text;
55     char *subst, *replace;
56     unsigned int slen, rlen;
57     int by_word, suffix_only;
58{
59  register char *t = text;
60  register char *p;
61
62  if (slen == 0 && !by_word && !suffix_only)
63    {
64      /* The first occurrence of "" in any string is its end.  */
65      o = variable_buffer_output (o, t, strlen (t));
66      if (rlen > 0)
67        o = variable_buffer_output (o, replace, rlen);
68      return o;
69    }
70
71  do
72    {
73      if ((by_word | suffix_only) && slen == 0)
74        /* When matching by words, the empty string should match
75           the end of each word, rather than the end of the whole text.  */
76        p = end_of_token (next_token (t));
77      else
78        {
79          p = sindex (t, 0, subst, slen);
80          if (p == 0)
81            {
82              /* No more matches.  Output everything left on the end.  */
83              o = variable_buffer_output (o, t, strlen (t));
84              return o;
85            }
86        }
87
88      /* Output everything before this occurrence of the string to replace.  */
89      if (p > t)
90        o = variable_buffer_output (o, t, p - t);
91
92      /* If we're substituting only by fully matched words,
93         or only at the ends of words, check that this case qualifies.  */
94      if ((by_word
95           && ((p > t && !isblank ((unsigned char)p[-1]))
96               || (p[slen] != '\0' && !isblank ((unsigned char)p[slen]))))
97          || (suffix_only
98              && (p[slen] != '\0' && !isblank ((unsigned char)p[slen]))))
99        /* Struck out.  Output the rest of the string that is
100           no longer to be replaced.  */
101        o = variable_buffer_output (o, subst, slen);
102      else if (rlen > 0)
103        /* Output the replacement string.  */
104        o = variable_buffer_output (o, replace, rlen);
105
106      /* Advance T past the string to be replaced.  */
107      t = p + slen;
108    } while (*t != '\0');
109
110  return o;
111}
112
113
114/* Store into VARIABLE_BUFFER at O the result of scanning TEXT
115   and replacing strings matching PATTERN with REPLACE.
116   If PATTERN_PERCENT is not nil, PATTERN has already been
117   run through find_percent, and PATTERN_PERCENT is the result.
118   If REPLACE_PERCENT is not nil, REPLACE has already been
119   run through find_percent, and REPLACE_PERCENT is the result.  */
120
121char *
122patsubst_expand (o, text, pattern, replace, pattern_percent, replace_percent)
123     char *o;
124     char *text;
125     register char *pattern, *replace;
126     register char *pattern_percent, *replace_percent;
127{
128  unsigned int pattern_prepercent_len, pattern_postpercent_len;
129  unsigned int replace_prepercent_len, replace_postpercent_len = 0;
130  char *t;
131  int len;
132  int doneany = 0;
133
134  /* We call find_percent on REPLACE before checking PATTERN so that REPLACE
135     will be collapsed before we call subst_expand if PATTERN has no %.  */
136  if (replace_percent == 0)
137    replace_percent = find_percent (replace);
138  if (replace_percent != 0)
139    {
140      /* Record the length of REPLACE before and after the % so
141         we don't have to compute these lengths more than once.  */
142      replace_prepercent_len = replace_percent - replace;
143      replace_postpercent_len = strlen (replace_percent + 1);
144    }
145  else
146    /* We store the length of the replacement
147       so we only need to compute it once.  */
148    replace_prepercent_len = strlen (replace);
149
150  if (pattern_percent == 0)
151    pattern_percent = find_percent (pattern);
152  if (pattern_percent == 0)
153    /* With no % in the pattern, this is just a simple substitution.  */
154    return subst_expand (o, text, pattern, replace,
155                         strlen (pattern), strlen (replace), 1, 0);
156
157  /* Record the length of PATTERN before and after the %
158     so we don't have to compute it more than once.  */
159  pattern_prepercent_len = pattern_percent - pattern;
160  pattern_postpercent_len = strlen (pattern_percent + 1);
161
162  while ((t = find_next_token (&text, &len)) != 0)
163    {
164      int fail = 0;
165
166      /* Is it big enough to match?  */
167      if (len < pattern_prepercent_len + pattern_postpercent_len)
168        fail = 1;
169
170      /* Does the prefix match? */
171      if (!fail && pattern_prepercent_len > 0
172          && (*t != *pattern
173              || t[pattern_prepercent_len - 1] != pattern_percent[-1]
174              || !strneq (t + 1, pattern + 1, pattern_prepercent_len - 1)))
175        fail = 1;
176
177      /* Does the suffix match? */
178      if (!fail && pattern_postpercent_len > 0
179          && (t[len - 1] != pattern_percent[pattern_postpercent_len]
180              || t[len - pattern_postpercent_len] != pattern_percent[1]
181              || !strneq (&t[len - pattern_postpercent_len],
182                          &pattern_percent[1], pattern_postpercent_len - 1)))
183        fail = 1;
184
185      if (fail)
186        /* It didn't match.  Output the string.  */
187        o = variable_buffer_output (o, t, len);
188      else
189        {
190          /* It matched.  Output the replacement.  */
191
192          /* Output the part of the replacement before the %.  */
193          o = variable_buffer_output (o, replace, replace_prepercent_len);
194
195          if (replace_percent != 0)
196            {
197              /* Output the part of the matched string that
198                 matched the % in the pattern.  */
199              o = variable_buffer_output (o, t + pattern_prepercent_len,
200                                          len - (pattern_prepercent_len
201                                                 + pattern_postpercent_len));
202              /* Output the part of the replacement after the %.  */
203              o = variable_buffer_output (o, replace_percent + 1,
204                                          replace_postpercent_len);
205            }
206        }
207
208      /* Output a space, but not if the replacement is "".  */
209      if (fail || replace_prepercent_len > 0
210          || (replace_percent != 0 && len + replace_postpercent_len > 0))
211        {
212          o = variable_buffer_output (o, " ", 1);
213          doneany = 1;
214        }
215    }
216  if (doneany)
217    /* Kill the last space.  */
218    --o;
219
220  return o;
221}
222
223
224/* Look up a function by name.
225   The table is currently small enough that it's not really worthwhile to use
226   a fancier lookup algorithm.  If it gets larger, maybe...
227*/
228
229static const struct function_table_entry *
230lookup_function (table, s)
231     const struct function_table_entry *table;
232     const char *s;
233{
234  int len = strlen (s);
235
236  for (; table->name != NULL; ++table)
237    if (table->len <= len
238        && (isblank ((unsigned char)s[table->len]) || s[table->len] == '\0')
239        && strneq (s, table->name, table->len))
240      return table;
241
242  return NULL;
243}
244
245
246/* Return 1 if PATTERN matches STR, 0 if not.  */
247
248int
249pattern_matches (pattern, percent, str)
250     register char *pattern, *percent, *str;
251{
252  unsigned int sfxlen, strlength;
253
254  if (percent == 0)
255    {
256      unsigned int len = strlen (pattern) + 1;
257      char *new_chars = (char *) alloca (len);
258      bcopy (pattern, new_chars, len);
259      pattern = new_chars;
260      percent = find_percent (pattern);
261      if (percent == 0)
262        return streq (pattern, str);
263    }
264
265  sfxlen = strlen (percent + 1);
266  strlength = strlen (str);
267
268  if (strlength < (percent - pattern) + sfxlen
269      || !strneq (pattern, str, percent - pattern))
270    return 0;
271
272  return !strcmp (percent + 1, str + (strlength - sfxlen));
273}
274
275
276/* Find the next comma or ENDPAREN (counting nested STARTPAREN and
277   ENDPARENtheses), starting at PTR before END.  Return a pointer to
278   next character.
279
280   If no next argument is found, return NULL.
281*/
282
283static char *
284find_next_argument (startparen, endparen, ptr, end)
285     char startparen;
286     char endparen;
287     const char *ptr;
288     const char *end;
289{
290  int count = 0;
291
292  for (; ptr < end; ++ptr)
293    if (*ptr == startparen)
294      ++count;
295
296    else if (*ptr == endparen)
297      {
298        --count;
299        if (count < 0)
300          return NULL;
301      }
302
303    else if (*ptr == ',' && !count)
304      return (char *)ptr;
305
306  /* We didn't find anything.  */
307  return NULL;
308}
309
310
311/* Glob-expand LINE.  The returned pointer is
312   only good until the next call to string_glob.  */
313
314static char *
315string_glob (line)
316     char *line;
317{
318  static char *result = 0;
319  static unsigned int length;
320  register struct nameseq *chain;
321  register unsigned int idx;
322
323  chain = multi_glob (parse_file_seq
324                      (&line, '\0', sizeof (struct nameseq),
325                       /* We do not want parse_file_seq to strip `./'s.
326                          That would break examples like:
327                          $(patsubst ./%.c,obj/%.o,$(wildcard ./?*.c)).  */
328                       0),
329                      sizeof (struct nameseq));
330
331  if (result == 0)
332    {
333      length = 100;
334      result = (char *) xmalloc (100);
335    }
336
337  idx = 0;
338  while (chain != 0)
339    {
340      register char *name = chain->name;
341      unsigned int len = strlen (name);
342
343      struct nameseq *next = chain->next;
344      free ((char *) chain);
345      chain = next;
346
347      /* multi_glob will pass names without globbing metacharacters
348         through as is, but we want only files that actually exist.  */
349      if (file_exists_p (name))
350        {
351          if (idx + len + 1 > length)
352            {
353              length += (len + 1) * 2;
354              result = (char *) xrealloc (result, length);
355            }
356          bcopy (name, &result[idx], len);
357          idx += len;
358          result[idx++] = ' ';
359        }
360
361      free (name);
362    }
363
364  /* Kill the last space and terminate the string.  */
365  if (idx == 0)
366    result[0] = '\0';
367  else
368    result[idx - 1] = '\0';
369
370  return result;
371}
372
373/*
374  Builtin functions
375 */
376
377static char *
378func_patsubst (o, argv, funcname)
379     char *o;
380     char **argv;
381     const char *funcname;
382{
383  o = patsubst_expand (o, argv[2], argv[0], argv[1], (char *) 0, (char *) 0);
384  return o;
385}
386
387
388static char *
389func_join (o, argv, funcname)
390     char *o;
391     char **argv;
392     const char *funcname;
393{
394  int doneany = 0;
395
396  /* Write each word of the first argument directly followed
397     by the corresponding word of the second argument.
398     If the two arguments have a different number of words,
399     the excess words are just output separated by blanks.  */
400  register char *tp;
401  register char *pp;
402  char *list1_iterator = argv[0];
403  char *list2_iterator = argv[1];
404  do
405    {
406      unsigned int len1, len2;
407
408      tp = find_next_token (&list1_iterator, &len1);
409      if (tp != 0)
410        o = variable_buffer_output (o, tp, len1);
411
412      pp = find_next_token (&list2_iterator, &len2);
413      if (pp != 0)
414        o = variable_buffer_output (o, pp, len2);
415
416      if (tp != 0 || pp != 0)
417        {
418          o = variable_buffer_output (o, " ", 1);
419          doneany = 1;
420        }
421    }
422  while (tp != 0 || pp != 0);
423  if (doneany)
424    /* Kill the last blank.  */
425    --o;
426
427  return o;
428}
429
430
431static char *
432func_origin (o, argv, funcname)
433     char *o;
434     char **argv;
435     const char *funcname;
436{
437  /* Expand the argument.  */
438  register struct variable *v = lookup_variable (argv[0], strlen (argv[0]));
439  if (v == 0)
440    o = variable_buffer_output (o, "undefined", 9);
441  else
442    switch (v->origin)
443      {
444      default:
445      case o_invalid:
446        abort ();
447        break;
448      case o_default:
449        o = variable_buffer_output (o, "default", 7);
450        break;
451      case o_env:
452        o = variable_buffer_output (o, "environment", 11);
453        break;
454      case o_file:
455        o = variable_buffer_output (o, "file", 4);
456        break;
457      case o_env_override:
458        o = variable_buffer_output (o, "environment override", 20);
459        break;
460      case o_command:
461        o = variable_buffer_output (o, "command line", 12);
462        break;
463      case o_override:
464        o = variable_buffer_output (o, "override", 8);
465        break;
466      case o_automatic:
467        o = variable_buffer_output (o, "automatic", 9);
468        break;
469      }
470
471  return o;
472}
473
474#ifdef VMS
475#define IS_PATHSEP(c) ((c) == ']')
476#else
477#if defined(__MSDOS__) || defined(WINDOWS32)
478#define IS_PATHSEP(c) ((c) == '/' || (c) == '\\')
479#else
480#define IS_PATHSEP(c) ((c) == '/')
481#endif
482#endif
483
484
485static char *
486func_notdir_suffix (o, argv, funcname)
487     char *o;
488     char **argv;
489     const char *funcname;
490{
491  /* Expand the argument.  */
492  char *list_iterator = argv[0];
493  char *p2 =0;
494  int doneany =0;
495  unsigned int len=0;
496
497  int is_suffix = streq (funcname, "suffix");
498  int is_notdir = !is_suffix;
499  while ((p2 = find_next_token (&list_iterator, &len)) != 0)
500    {
501      char *p = p2 + len;
502
503
504      while (p >= p2 && (!is_suffix || *p != '.'))
505        {
506          if (IS_PATHSEP (*p))
507            break;
508          --p;
509        }
510
511      if (p >= p2)
512        {
513          if (is_notdir)
514            ++p;
515          else if (*p != '.')
516            continue;
517          o = variable_buffer_output (o, p, len - (p - p2));
518        }
519#if defined(WINDOWS32) || defined(__MSDOS__)
520      /* Handle the case of "d:foo/bar".  */
521      else if (streq (funcname, "notdir") && p2[0] && p2[1] == ':')
522        {
523          p = p2 + 2;
524          o = variable_buffer_output (o, p, len - (p - p2));
525        }
526#endif
527      else if (is_notdir)
528        o = variable_buffer_output (o, p2, len);
529
530      if (is_notdir || p >= p2)
531        {
532          o = variable_buffer_output (o, " ", 1);
533          doneany = 1;
534        }
535    }
536  if (doneany)
537    /* Kill last space.  */
538    --o;
539
540
541  return o;
542
543}
544
545
546static char *
547func_basename_dir (o, argv, funcname)
548     char *o;
549     char **argv;
550     const char *funcname;
551{
552  /* Expand the argument.  */
553  char *p3 = argv[0];
554  char *p2=0;
555  int doneany=0;
556  unsigned int len=0;
557  char *p=0;
558  int is_basename= streq (funcname, "basename");
559  int is_dir= !is_basename;
560
561  while ((p2 = find_next_token (&p3, &len)) != 0)
562        {
563          p = p2 + len;
564          while (p >= p2 && (!is_basename  || *p != '.'))
565            {
566              if (IS_PATHSEP (*p))
567                break;
568                    --p;
569            }
570
571          if (p >= p2 && (is_dir))
572            o = variable_buffer_output (o, p2, ++p - p2);
573          else if (p >= p2 && (*p == '.'))
574            o = variable_buffer_output (o, p2, p - p2);
575#if defined(WINDOWS32) || defined(__MSDOS__)
576        /* Handle the "d:foobar" case */
577          else if (p2[0] && p2[1] == ':' && is_dir)
578            o = variable_buffer_output (o, p2, 2);
579#endif
580          else if (is_dir)
581#ifdef VMS
582            o = variable_buffer_output (o, "[]", 2);
583#else
584#ifndef _AMIGA
585            o = variable_buffer_output (o, "./", 2);
586#else
587            ; /* Just a nop...  */
588#endif /* AMIGA */
589#endif /* !VMS */
590          else
591            /* The entire name is the basename.  */
592            o = variable_buffer_output (o, p2, len);
593
594          o = variable_buffer_output (o, " ", 1);
595          doneany = 1;
596        }
597      if (doneany)
598        /* Kill last space.  */
599        --o;
600
601
602 return o;
603}
604
605static char *
606func_addsuffix_addprefix (o, argv, funcname)
607     char *o;
608     char **argv;
609     const char *funcname;
610{
611  int fixlen = strlen (argv[0]);
612  char *list_iterator = argv[1];
613  int is_addprefix = streq (funcname, "addprefix");
614  int is_addsuffix = !is_addprefix;
615
616  int doneany = 0;
617  char *p;
618  unsigned int len;
619
620  while ((p = find_next_token (&list_iterator, &len)) != 0)
621    {
622      if (is_addprefix)
623        o = variable_buffer_output (o, argv[0], fixlen);
624      o = variable_buffer_output (o, p, len);
625      if (is_addsuffix)
626        o = variable_buffer_output (o, argv[0], fixlen);
627      o = variable_buffer_output (o, " ", 1);
628      doneany = 1;
629    }
630
631  if (doneany)
632    /* Kill last space.  */
633    --o;
634
635  return o;
636}
637
638static char *
639func_subst (o, argv, funcname)
640     char *o;
641     char **argv;
642     const char *funcname;
643{
644  o = subst_expand (o, argv[2], argv[0], argv[1], strlen (argv[0]),
645                    strlen (argv[1]), 0, 0);
646
647  return o;
648}
649
650
651static char *
652func_firstword (o, argv, funcname)
653     char *o;
654     char **argv;
655     const char *funcname;
656{
657  unsigned int i;
658  char *words = argv[0];    /* Use a temp variable for find_next_token */
659  char *p = find_next_token (&words, &i);
660
661  if (p != 0)
662    o = variable_buffer_output (o, p, i);
663
664  return o;
665}
666
667
668static char *
669func_words (o, argv, funcname)
670     char *o;
671     char **argv;
672     const char *funcname;
673{
674  int i = 0;
675  char *word_iterator = argv[0];
676  char buf[20];
677
678  while (find_next_token (&word_iterator, (unsigned int *) 0) != 0)
679    ++i;
680
681  sprintf (buf, "%d", i);
682  o = variable_buffer_output (o, buf, strlen (buf));
683
684
685  return o;
686}
687
688char *
689strip_whitespace (begpp, endpp)
690     char **begpp;
691     char **endpp;
692{
693  while (isspace ((unsigned char)**begpp) && *begpp <= *endpp)
694    (*begpp) ++;
695  while (isspace ((unsigned char)**endpp) && *endpp >= *begpp)
696    (*endpp) --;
697  return *begpp;
698}
699
700int
701is_numeric (p)
702     char *p;
703{
704  char *end = p + strlen (p) - 1;
705  char *beg = p;
706  strip_whitespace (&p, &end);
707
708  while (p <= end)
709    if (!ISDIGIT (*(p++)))  /* ISDIGIT only evals its arg once: see make.h.  */
710      return 0;
711
712  return (end - beg >= 0);
713}
714
715void
716check_numeric (s, message)
717     char *s;
718     char *message;
719{
720  if (!is_numeric (s))
721    fatal (reading_file, message);
722}
723
724
725
726static char *
727func_word (o, argv, funcname)
728     char *o;
729     char **argv;
730     const char *funcname;
731{
732  char *end_p=0;
733  int i=0;
734  char *p=0;
735
736  /* Check the first argument.  */
737  check_numeric (argv[0], _("non-numeric first argument to `word' function"));
738  i =  atoi (argv[0]);
739
740  if (i == 0)
741    fatal (reading_file, _("first argument to `word' function must be greater than 0"));
742
743
744  end_p = argv[1];
745  while ((p = find_next_token (&end_p, 0)) != 0)
746    if (--i == 0)
747      break;
748
749  if (i == 0)
750    o = variable_buffer_output (o, p, end_p - p);
751
752  return o;
753}
754
755static char *
756func_wordlist (o, argv, funcname)
757     char *o;
758     char **argv;
759     const char *funcname;
760{
761  int start, count;
762
763  /* Check the arguments.  */
764  check_numeric (argv[0],
765                 _("non-numeric first argument to `wordlist' function"));
766  check_numeric (argv[1],
767                 _("non-numeric second argument to `wordlist' function"));
768
769  start = atoi (argv[0]);
770  count = atoi (argv[1]) - start + 1;
771
772  if (count > 0)
773    {
774      char *p;
775      char *end_p = argv[2];
776
777      /* Find the beginning of the "start"th word.  */
778      while (((p = find_next_token (&end_p, 0)) != 0) && --start)
779        ;
780
781      if (p)
782        {
783          /* Find the end of the "count"th word from start.  */
784          while (--count && (find_next_token (&end_p, 0) != 0))
785            ;
786
787          /* Return the stuff in the middle.  */
788          o = variable_buffer_output (o, p, end_p - p);
789        }
790    }
791
792  return o;
793}
794
795static char*
796func_findstring (o, argv, funcname)
797     char *o;
798     char **argv;
799     const char *funcname;
800{
801  /* Find the first occurrence of the first string in the second.  */
802  int i = strlen (argv[0]);
803  if (sindex (argv[1], 0, argv[0], i) != 0)
804    o = variable_buffer_output (o, argv[0], i);
805
806  return o;
807}
808
809static char *
810func_foreach (o, argv, funcname)
811     char *o;
812     char **argv;
813     const char *funcname;
814{
815  /* expand only the first two.  */
816  char *varname = expand_argument (argv[0], NULL);
817  char *list = expand_argument (argv[1], NULL);
818  char *body = argv[2];
819
820  int doneany = 0;
821  char *list_iterator = list;
822  char *p;
823  unsigned int len;
824  register struct variable *var;
825
826  push_new_variable_scope ();
827  var = define_variable (varname, strlen (varname), "", o_automatic, 0);
828
829  /* loop through LIST,  put the value in VAR and expand BODY */
830  while ((p = find_next_token (&list_iterator, &len)) != 0)
831    {
832      char *result = 0;
833
834      {
835        char save = p[len];
836
837        p[len] = '\0';
838        free (var->value);
839        var->value = (char *) xstrdup ((char*) p);
840        p[len] = save;
841      }
842
843      result = allocated_variable_expand (body);
844
845      o = variable_buffer_output (o, result, strlen (result));
846      o = variable_buffer_output (o, " ", 1);
847      doneany = 1;
848      free (result);
849    }
850
851  if (doneany)
852    /* Kill the last space.  */
853    --o;
854
855  pop_variable_scope ();
856  free (varname);
857  free (list);
858
859  return o;
860}
861
862struct a_word
863{
864  struct a_word *next;
865  char *str;
866  int matched;
867};
868
869static char *
870func_filter_filterout (o, argv, funcname)
871     char *o;
872     char **argv;
873     const char *funcname;
874{
875  struct a_word *wordhead = 0;
876  struct a_word *wordtail = 0;
877
878  int is_filter = streq (funcname, "filter");
879  char *patterns = argv[0];
880  char *word_iterator = argv[1];
881
882  char *p;
883  unsigned int len;
884
885  /* Chop ARGV[1] up into words and then run each pattern through.  */
886  while ((p = find_next_token (&word_iterator, &len)) != 0)
887    {
888      struct a_word *w = (struct a_word *)alloca (sizeof (struct a_word));
889      if (wordhead == 0)
890        wordhead = w;
891      else
892        wordtail->next = w;
893      wordtail = w;
894
895      if (*word_iterator != '\0')
896        ++word_iterator;
897      p[len] = '\0';
898      w->str = p;
899      w->matched = 0;
900    }
901
902  if (wordhead != 0)
903    {
904      char *pat_iterator = patterns;
905      int doneany = 0;
906      struct a_word *wp;
907
908      wordtail->next = 0;
909
910      /* Run each pattern through the words, killing words.  */
911      while ((p = find_next_token (&pat_iterator, &len)) != 0)
912        {
913          char *percent;
914          char save = p[len];
915          p[len] = '\0';
916
917          percent = find_percent (p);
918          for (wp = wordhead; wp != 0; wp = wp->next)
919            wp->matched |= (percent == 0 ? streq (p, wp->str)
920                            : pattern_matches (p, percent, wp->str));
921
922          p[len] = save;
923        }
924
925      /* Output the words that matched (or didn't, for filter-out).  */
926      for (wp = wordhead; wp != 0; wp = wp->next)
927        if (is_filter ? wp->matched : !wp->matched)
928          {
929            o = variable_buffer_output (o, wp->str, strlen (wp->str));
930            o = variable_buffer_output (o, " ", 1);
931            doneany = 1;
932          }
933
934      if (doneany)
935        /* Kill the last space.  */
936        --o;
937    }
938
939  return o;
940}
941
942
943static char *
944func_strip (o, argv, funcname)
945     char *o;
946     char **argv;
947     const char *funcname;
948{
949  char *p = argv[0];
950  int doneany =0;
951
952  while (*p != '\0')
953    {
954      int i=0;
955      char *word_start=0;
956
957      while (isspace ((unsigned char)*p))
958        ++p;
959      word_start = p;
960      for (i=0; *p != '\0' && !isspace ((unsigned char)*p); ++p, ++i)
961        {}
962      if (!i)
963        break;
964      o = variable_buffer_output (o, word_start, i);
965      o = variable_buffer_output (o, " ", 1);
966      doneany = 1;
967    }
968
969  if (doneany)
970    /* Kill the last space.  */
971    --o;
972  return o;
973}
974
975/*
976  Print a warning or fatal message.
977*/
978static char *
979func_error (o, argv, funcname)
980     char *o;
981     char **argv;
982     const char *funcname;
983{
984  char **argvp;
985  char *msg, *p;
986  int len;
987
988  /* The arguments will be broken on commas.  Rather than create yet
989     another special case where function arguments aren't broken up,
990     just create a format string that puts them back together.  */
991  for (len=0, argvp=argv; *argvp != 0; ++argvp)
992    len += strlen (*argvp) + 2;
993
994  p = msg = alloca (len + 1);
995
996  for (argvp=argv; argvp[1] != 0; ++argvp)
997    {
998      strcpy (p, *argvp);
999      p += strlen (*argvp);
1000      *(p++) = ',';
1001      *(p++) = ' ';
1002    }
1003  strcpy (p, *argvp);
1004
1005  if (*funcname == 'e')
1006    fatal (reading_file, "%s", msg);
1007
1008  /* The warning function expands to the empty string.  */
1009  error (reading_file, "%s", msg);
1010
1011  return o;
1012}
1013
1014
1015/*
1016  chop argv[0] into words, and sort them.
1017 */
1018static char *
1019func_sort (o, argv, funcname)
1020     char *o;
1021     char **argv;
1022     const char *funcname;
1023{
1024  char **words = 0;
1025  int nwords = 0;
1026  register int wordi = 0;
1027
1028  /* Chop ARGV[0] into words and put them in WORDS.  */
1029  char *t = argv[0];
1030  char *p;
1031  unsigned int len;
1032  int i;
1033
1034  while ((p = find_next_token (&t, &len)) != 0)
1035    {
1036      if (wordi >= nwords - 1)
1037        {
1038          nwords = (2 * nwords) + 5;
1039          words = (char **) xrealloc ((char *) words,
1040                                      nwords * sizeof (char *));
1041        }
1042      words[wordi++] = savestring (p, len);
1043    }
1044
1045  if (!wordi)
1046    return o;
1047
1048  /* Now sort the list of words.  */
1049  qsort ((char *) words, wordi, sizeof (char *), alpha_compare);
1050
1051  /* Now write the sorted list.  */
1052  for (i = 0; i < wordi; ++i)
1053    {
1054      len = strlen (words[i]);
1055      if (i == wordi - 1 || strlen (words[i + 1]) != len
1056          || strcmp (words[i], words[i + 1]))
1057        {
1058          o = variable_buffer_output (o, words[i], len);
1059          o = variable_buffer_output (o, " ", 1);
1060        }
1061      free (words[i]);
1062    }
1063  /* Kill the last space.  */
1064  --o;
1065
1066  free (words);
1067
1068  return o;
1069}
1070
1071/*
1072  $(if condition,true-part[,false-part])
1073
1074  CONDITION is false iff it evaluates to an empty string.  White
1075  space before and after condition are stripped before evaluation.
1076
1077  If CONDITION is true, then TRUE-PART is evaluated, otherwise FALSE-PART is
1078  evaluated (if it exists).  Because only one of the two PARTs is evaluated,
1079  you can use $(if ...) to create side-effects (with $(shell ...), for
1080  example).
1081*/
1082
1083static char *
1084func_if (o, argv, funcname)
1085     char *o;
1086     char **argv;
1087     const char *funcname;
1088{
1089  char *begp = argv[0];
1090  char *endp = begp + strlen (argv[0]);
1091  int result = 0;
1092
1093  /* Find the result of the condition: if we have a value, and it's not
1094     empty, the condition is true.  If we don't have a value, or it's the
1095     empty string, then it's false.  */
1096
1097  strip_whitespace (&begp, &endp);
1098
1099  if (begp < endp)
1100    {
1101      char *expansion = expand_argument (begp, NULL);
1102
1103      result = strlen (expansion);
1104      free (expansion);
1105    }
1106
1107  /* If the result is true (1) we want to eval the first argument, and if
1108     it's false (0) we want to eval the second.  If the argument doesn't
1109     exist we do nothing, otherwise expand it and add to the buffer.  */
1110
1111  argv += 1 + !result;
1112
1113  if (argv[0])
1114    {
1115      char *expansion;
1116
1117      expansion = expand_argument (argv[0], NULL);
1118
1119      o = variable_buffer_output (o, expansion, strlen (expansion));
1120
1121      free (expansion);
1122    }
1123
1124  return o;
1125}
1126
1127static char *
1128func_wildcard (o, argv, funcname)
1129     char *o;
1130     char **argv;
1131     const char *funcname;
1132{
1133
1134#ifdef _AMIGA
1135   o = wildcard_expansion (argv[0], o);
1136#else
1137   char *p = string_glob (argv[0]);
1138   o = variable_buffer_output (o, p, strlen (p));
1139#endif
1140   return o;
1141}
1142
1143/*
1144  \r  is replaced on UNIX as well. Is this desirable?
1145 */
1146void
1147fold_newlines (buffer, length)
1148     char *buffer;
1149     int *length;
1150{
1151  char *dst = buffer;
1152  char *src = buffer;
1153  char *last_nonnl = buffer -1;
1154  src[*length] = 0;
1155  for (; *src != '\0'; ++src)
1156    {
1157      if (src[0] == '\r' && src[1] == '\n')
1158        continue;
1159      if (*src == '\n')
1160        {
1161          *dst++ = ' ';
1162        }
1163      else
1164        {
1165          last_nonnl = dst;
1166          *dst++ = *src;
1167        }
1168    }
1169  *(++last_nonnl) = '\0';
1170  *length = last_nonnl - buffer;
1171}
1172
1173
1174
1175int shell_function_pid = 0, shell_function_completed;
1176
1177
1178#ifdef WINDOWS32
1179/*untested*/
1180
1181#include <windows.h>
1182#include <io.h>
1183#include "sub_proc.h"
1184
1185
1186void
1187windows32_openpipe (int *pipedes, int *pid_p, char **command_argv, char **envp)
1188{
1189  SECURITY_ATTRIBUTES saAttr;
1190  HANDLE hIn;
1191  HANDLE hErr;
1192  HANDLE hChildOutRd;
1193  HANDLE hChildOutWr;
1194  HANDLE hProcess;
1195
1196
1197  saAttr.nLength = sizeof (SECURITY_ATTRIBUTES);
1198  saAttr.bInheritHandle = TRUE;
1199  saAttr.lpSecurityDescriptor = NULL;
1200
1201  if (DuplicateHandle (GetCurrentProcess(),
1202                      GetStdHandle(STD_INPUT_HANDLE),
1203                      GetCurrentProcess(),
1204                      &hIn,
1205                      0,
1206                      TRUE,
1207                      DUPLICATE_SAME_ACCESS) == FALSE) {
1208    fatal (NILF, _("create_child_process: DuplicateHandle(In) failed (e=%d)\n"),
1209           GetLastError());
1210
1211  }
1212  if (DuplicateHandle(GetCurrentProcess(),
1213                      GetStdHandle(STD_ERROR_HANDLE),
1214                      GetCurrentProcess(),
1215                      &hErr,
1216                      0,
1217                      TRUE,
1218                      DUPLICATE_SAME_ACCESS) == FALSE) {
1219    fatal (NILF, _("create_child_process: DuplicateHandle(Err) failed (e=%d)\n"),
1220           GetLastError());
1221  }
1222
1223  if (!CreatePipe(&hChildOutRd, &hChildOutWr, &saAttr, 0))
1224    fatal (NILF, _("CreatePipe() failed (e=%d)\n"), GetLastError());
1225
1226  hProcess = process_init_fd(hIn, hChildOutWr, hErr);
1227
1228  if (!hProcess)
1229    fatal (NILF, _("windows32_openpipe (): process_init_fd() failed\n"));
1230
1231  /* make sure that CreateProcess() has Path it needs */
1232  sync_Path_environment();
1233
1234  if (!process_begin(hProcess, command_argv, envp, command_argv[0], NULL)) {
1235    /* register process for wait */
1236    process_register(hProcess);
1237
1238    /* set the pid for returning to caller */
1239    *pid_p = (int) hProcess;
1240
1241  /* set up to read data from child */
1242  pipedes[0] = _open_osfhandle((long) hChildOutRd, O_RDONLY);
1243
1244  /* this will be closed almost right away */
1245  pipedes[1] = _open_osfhandle((long) hChildOutWr, O_APPEND);
1246  } else {
1247    /* reap/cleanup the failed process */
1248        process_cleanup(hProcess);
1249
1250    /* close handles which were duplicated, they weren't used */
1251        CloseHandle(hIn);
1252        CloseHandle(hErr);
1253
1254        /* close pipe handles, they won't be used */
1255        CloseHandle(hChildOutRd);
1256        CloseHandle(hChildOutWr);
1257
1258    /* set status for return */
1259    pipedes[0] = pipedes[1] = -1;
1260    *pid_p = -1;
1261  }
1262}
1263#endif
1264
1265
1266#ifdef __MSDOS__
1267FILE *
1268msdos_openpipe (int* pipedes, int *pidp, char *text)
1269{
1270  FILE *fpipe=0;
1271  /* MSDOS can't fork, but it has `popen'.  */
1272  struct variable *sh = lookup_variable ("SHELL", 5);
1273  int e;
1274  extern int dos_command_running, dos_status;
1275
1276  /* Make sure not to bother processing an empty line.  */
1277  while (isblank ((unsigned char)*text))
1278    ++text;
1279  if (*text == '\0')
1280    return 0;
1281
1282  if (sh)
1283    {
1284      char buf[PATH_MAX + 7];
1285      /* This makes sure $SHELL value is used by $(shell), even
1286         though the target environment is not passed to it.  */
1287      sprintf (buf, "SHELL=%s", sh->value);
1288      putenv (buf);
1289    }
1290
1291  e = errno;
1292  errno = 0;
1293  dos_command_running = 1;
1294  dos_status = 0;
1295  /* If dos_status becomes non-zero, it means the child process
1296     was interrupted by a signal, like SIGINT or SIGQUIT.  See
1297     fatal_error_signal in commands.c.  */
1298  fpipe = popen (text, "rt");
1299  dos_command_running = 0;
1300  if (!fpipe || dos_status)
1301    {
1302      pipedes[0] = -1;
1303      *pidp = -1;
1304      if (dos_status)
1305        errno = EINTR;
1306      else if (errno == 0)
1307        errno = ENOMEM;
1308      shell_function_completed = -1;
1309    }
1310  else
1311    {
1312      pipedes[0] = fileno (fpipe);
1313      *pidp = 42; /* Yes, the Meaning of Life, the Universe, and Everything! */
1314      errno = e;
1315      shell_function_completed = 1;
1316    }
1317  return fpipe;
1318}
1319#endif
1320
1321/*
1322  Do shell spawning, with the naughty bits for different OSes.
1323 */
1324
1325#ifdef VMS
1326
1327/* VMS can't do $(shell ...)  */
1328#define func_shell 0
1329
1330#else
1331#ifndef _AMIGA
1332static char *
1333func_shell (o, argv, funcname)
1334     char *o;
1335     char **argv;
1336     const char *funcname;
1337{
1338  char* batch_filename = NULL;
1339  int i;
1340
1341#ifdef __MSDOS__
1342  FILE *fpipe;
1343#endif
1344  char **command_argv;
1345  char *error_prefix;
1346  char **envp;
1347  int pipedes[2];
1348  int pid;
1349
1350#ifndef __MSDOS__
1351  /* Construct the argument list.  */
1352  command_argv = construct_command_argv (argv[0],
1353                                         (char **) NULL, (struct file *) 0,
1354                                         &batch_filename);
1355  if (command_argv == 0)
1356    return o;
1357#endif
1358
1359  /* Using a target environment for `shell' loses in cases like:
1360     export var = $(shell echo foobie)
1361     because target_environment hits a loop trying to expand $(var)
1362     to put it in the environment.  This is even more confusing when
1363     var was not explicitly exported, but just appeared in the
1364     calling environment.  */
1365
1366  envp = environ;
1367
1368  /* For error messages.  */
1369  if (reading_file != 0)
1370    {
1371      error_prefix = (char *) alloca (strlen (reading_file->filenm)+11+4);
1372      sprintf (error_prefix,
1373               "%s:%lu: ", reading_file->filenm, reading_file->lineno);
1374    }
1375  else
1376    error_prefix = "";
1377
1378#ifdef WINDOWS32
1379  windows32_openpipe (pipedes, &pid, command_argv, envp);
1380
1381  if (pipedes[0] < 0) {
1382        /* open of the pipe failed, mark as failed execution */
1383    shell_function_completed = -1;
1384
1385        return o;
1386  } else
1387#else /* WINDOWS32 */
1388
1389# ifdef __MSDOS__
1390  fpipe = msdos_openpipe (pipedes, &pid, argv[0]);
1391  if (pipedes[0] < 0)
1392    {
1393      perror_with_name (error_prefix, "pipe");
1394      return o;
1395    }
1396# else
1397  if (pipe (pipedes) < 0)
1398    {
1399      perror_with_name (error_prefix, "pipe");
1400      return o;
1401    }
1402
1403  pid = vfork ();
1404  if (pid < 0)
1405    perror_with_name (error_prefix, "fork");
1406  else if (pid == 0)
1407    child_execute_job (0, pipedes[1], command_argv, envp);
1408  else
1409# endif /* ! __MSDOS__ */
1410
1411#endif /* WINDOWS32 */
1412    {
1413      /* We are the parent.  */
1414
1415      char *buffer;
1416      unsigned int maxlen;
1417      int cc;
1418
1419      /* Record the PID for reap_children.  */
1420      shell_function_pid = pid;
1421#ifndef  __MSDOS__
1422      shell_function_completed = 0;
1423
1424      /* Free the storage only the child needed.  */
1425      free (command_argv[0]);
1426      free ((char *) command_argv);
1427
1428      /* Close the write side of the pipe.  */
1429      (void) close (pipedes[1]);
1430#endif
1431
1432      /* Set up and read from the pipe.  */
1433
1434      maxlen = 200;
1435      buffer = (char *) xmalloc (maxlen + 1);
1436
1437      /* Read from the pipe until it gets EOF.  */
1438      i = 0;
1439      do
1440        {
1441          if (i == maxlen)
1442            {
1443              maxlen += 512;
1444              buffer = (char *) xrealloc (buffer, maxlen + 1);
1445            }
1446
1447          errno = 0;
1448          cc = read (pipedes[0], &buffer[i], maxlen - i);
1449          if (cc > 0)
1450            i += cc;
1451        }
1452      while (cc > 0 || EINTR_SET);
1453
1454      /* Close the read side of the pipe.  */
1455#ifdef  __MSDOS__
1456      if (fpipe)
1457        (void) pclose (fpipe);
1458#else
1459      (void) close (pipedes[0]);
1460#endif
1461
1462      /* Loop until child_handler sets shell_function_completed
1463         to the status of our child shell.  */
1464      while (shell_function_completed == 0)
1465        reap_children (1, 0);
1466
1467      if (batch_filename) {
1468        DB (DB_VERBOSE, (_("Cleaning up temporary batch file %s\n"),
1469                       batch_filename));
1470        remove (batch_filename);
1471        free (batch_filename);
1472      }
1473      shell_function_pid = 0;
1474
1475      /* The child_handler function will set shell_function_completed
1476         to 1 when the child dies normally, or to -1 if it
1477         dies with status 127, which is most likely an exec fail.  */
1478
1479      if (shell_function_completed == -1)
1480        {
1481          /* This most likely means that the execvp failed,
1482             so we should just write out the error message
1483             that came in over the pipe from the child.  */
1484          fputs (buffer, stderr);
1485          fflush (stderr);
1486        }
1487      else
1488        {
1489          /* The child finished normally.  Replace all
1490             newlines in its output with spaces, and put
1491             that in the variable output buffer.  */
1492          fold_newlines (buffer, &i);
1493          o = variable_buffer_output (o, buffer, i);
1494        }
1495
1496      free (buffer);
1497    }
1498
1499  return o;
1500}
1501
1502#else   /* _AMIGA */
1503
1504/* Do the Amiga version of func_shell.  */
1505
1506static char *
1507func_shell (char *o, char **argv, const char *funcname)
1508{
1509  /* Amiga can't fork nor spawn, but I can start a program with
1510     redirection of my choice.  However, this means that we
1511     don't have an opportunity to reopen stdout to trap it.  Thus,
1512     we save our own stdout onto a new descriptor and dup a temp
1513     file's descriptor onto our stdout temporarily.  After we
1514     spawn the shell program, we dup our own stdout back to the
1515     stdout descriptor.  The buffer reading is the same as above,
1516     except that we're now reading from a file.  */
1517
1518#include <dos/dos.h>
1519#include <proto/dos.h>
1520
1521  BPTR child_stdout;
1522  char tmp_output[FILENAME_MAX];
1523  unsigned int maxlen = 200;
1524  int cc, i;
1525  char * buffer, * ptr;
1526  char ** aptr;
1527  int len = 0;
1528  char* batch_filename = NULL;
1529
1530  /* Construct the argument list.  */
1531  command_argv = construct_command_argv (argv[0], (char **) NULL,
1532                                         (struct file *) 0, &batch_filename);
1533  if (command_argv == 0)
1534    return o;
1535
1536  /* Note the mktemp() is a security hole, but this only runs on Amiga.
1537     Ideally we would use main.c:open_tmpfile(), but this uses a special
1538     Open(), not fopen(), and I'm not familiar enough with the code to mess
1539     with it.  */
1540  strcpy (tmp_output, "t:MakeshXXXXXXXX");
1541  mktemp (tmp_output);
1542  child_stdout = Open (tmp_output, MODE_NEWFILE);
1543
1544  for (aptr=command_argv; *aptr; aptr++)
1545    len += strlen (*aptr) + 1;
1546
1547  buffer = xmalloc (len + 1);
1548  ptr = buffer;
1549
1550  for (aptr=command_argv; *aptr; aptr++)
1551    {
1552      strcpy (ptr, *aptr);
1553      ptr += strlen (ptr) + 1;
1554      *ptr ++ = ' ';
1555      *ptr = 0;
1556    }
1557
1558  ptr[-1] = '\n';
1559
1560  Execute (buffer, NULL, child_stdout);
1561  free (buffer);
1562
1563  Close (child_stdout);
1564
1565  child_stdout = Open (tmp_output, MODE_OLDFILE);
1566
1567  buffer = xmalloc (maxlen);
1568  i = 0;
1569  do
1570    {
1571      if (i == maxlen)
1572        {
1573          maxlen += 512;
1574          buffer = (char *) xrealloc (buffer, maxlen + 1);
1575        }
1576
1577      cc = Read (child_stdout, &buffer[i], maxlen - i);
1578      if (cc > 0)
1579        i += cc;
1580    } while (cc > 0);
1581
1582  Close (child_stdout);
1583
1584  fold_newlines (buffer, &i);
1585  o = variable_buffer_output (o, buffer, i);
1586  free (buffer);
1587  return o;
1588}
1589#endif  /* _AMIGA */
1590#endif  /* !VMS */
1591
1592#ifdef EXPERIMENTAL
1593
1594/*
1595  equality. Return is string-boolean, ie, the empty string is false.
1596 */
1597static char *
1598func_eq (char* o, char **argv, char *funcname)
1599{
1600  int result = ! strcmp (argv[0], argv[1]);
1601  o = variable_buffer_output (o,  result ? "1" : "", result);
1602  return o;
1603}
1604
1605
1606/*
1607  string-boolean not operator.
1608 */
1609static char *
1610func_not (char* o, char **argv, char *funcname)
1611{
1612  char * s = argv[0];
1613  int result = 0;
1614  while (isspace ((unsigned char)*s))
1615    s++;
1616  result = ! (*s);
1617  o = variable_buffer_output (o,  result ? "1" : "", result);
1618  return o;
1619}
1620#endif
1621
1622
1623#define STRING_SIZE_TUPLE(_s) (_s), (sizeof (_s)-1)
1624
1625/* Lookup table for builtin functions.
1626
1627   This doesn't have to be sorted; we use a straight lookup.  We might gain
1628   some efficiency by moving most often used functions to the start of the
1629   table.
1630
1631   If MAXIMUM_ARGS is 0, that means there is no maximum and all
1632   comma-separated values are treated as arguments.
1633
1634   EXPAND_ARGS means that all arguments should be expanded before invocation.
1635   Functions that do namespace tricks (foreach) don't automatically expand.  */
1636
1637static char *func_call PARAMS ((char *o, char **argv, const char *funcname));
1638
1639
1640static struct function_table_entry function_table[] =
1641{
1642 /* Name/size */                    /* MIN MAX EXP? Function */
1643  { STRING_SIZE_TUPLE("addprefix"),     2,  2,  1,  func_addsuffix_addprefix},
1644  { STRING_SIZE_TUPLE("addsuffix"),     2,  2,  1,  func_addsuffix_addprefix},
1645  { STRING_SIZE_TUPLE("basename"),      0,  1,  1,  func_basename_dir},
1646  { STRING_SIZE_TUPLE("dir"),           0,  1,  1,  func_basename_dir},
1647  { STRING_SIZE_TUPLE("notdir"),        0,  1,  1,  func_notdir_suffix},
1648  { STRING_SIZE_TUPLE("subst"),         3,  3,  1,  func_subst},
1649  { STRING_SIZE_TUPLE("suffix"),        0,  1,  1,  func_notdir_suffix},
1650  { STRING_SIZE_TUPLE("filter"),        2,  2,  1,  func_filter_filterout},
1651  { STRING_SIZE_TUPLE("filter-out"),    2,  2,  1,  func_filter_filterout},
1652  { STRING_SIZE_TUPLE("findstring"),    2,  2,  1,  func_findstring},
1653  { STRING_SIZE_TUPLE("firstword"),     0,  1,  1,  func_firstword},
1654  { STRING_SIZE_TUPLE("join"),          2,  2,  1,  func_join},
1655  { STRING_SIZE_TUPLE("patsubst"),      3,  3,  1,  func_patsubst},
1656  { STRING_SIZE_TUPLE("shell"),         0,  1,  1,  func_shell},
1657  { STRING_SIZE_TUPLE("sort"),          0,  1,  1,  func_sort},
1658  { STRING_SIZE_TUPLE("strip"),         0,  1,  1,  func_strip},
1659  { STRING_SIZE_TUPLE("wildcard"),      0,  1,  1,  func_wildcard},
1660  { STRING_SIZE_TUPLE("word"),          2,  2,  1,  func_word},
1661  { STRING_SIZE_TUPLE("wordlist"),      3,  3,  1,  func_wordlist},
1662  { STRING_SIZE_TUPLE("words"),         0,  1,  1,  func_words},
1663  { STRING_SIZE_TUPLE("origin"),        0,  1,  1,  func_origin},
1664  { STRING_SIZE_TUPLE("foreach"),       3,  3,  0,  func_foreach},
1665  { STRING_SIZE_TUPLE("call"),          1,  0,  1,  func_call},
1666  { STRING_SIZE_TUPLE("error"),         0,  1,  1,  func_error},
1667  { STRING_SIZE_TUPLE("warning"),       0,  1,  1,  func_error},
1668  { STRING_SIZE_TUPLE("if"),            2,  3,  0,  func_if},
1669#ifdef EXPERIMENTAL
1670  { STRING_SIZE_TUPLE("eq"),            2,  2,  1,  func_eq},
1671  { STRING_SIZE_TUPLE("not"),           0,  1,  1,  func_not},
1672#endif
1673  { 0 }
1674};
1675
1676
1677/* These must come after the definition of function_table[].  */
1678
1679static char *
1680expand_builtin_function (o, argc, argv, entry_p)
1681     char *o;
1682     int argc;
1683     char **argv;
1684     struct function_table_entry *entry_p;
1685{
1686  if (argc < entry_p->minimum_args)
1687    fatal (reading_file,
1688           _("Insufficient number of arguments (%d) to function `%s'"),
1689           argc, entry_p->name);
1690
1691  /* I suppose technically some function could do something with no
1692     arguments, but so far none do, so just test it for all functions here
1693     rather than in each one.  We can change it later if necessary.  */
1694
1695  if (!argc)
1696    return o;
1697
1698  if (!entry_p->func_ptr)
1699    fatal (reading_file, _("Unimplemented on this platform: function `%s'"),
1700           entry_p->name);
1701
1702  return entry_p->func_ptr (o, argv, entry_p->name);
1703}
1704
1705/* Check for a function invocation in *STRINGP.  *STRINGP points at the
1706   opening ( or { and is not null-terminated.  If a function invocation
1707   is found, expand it into the buffer at *OP, updating *OP, incrementing
1708   *STRINGP past the reference and returning nonzero.  If not, return zero.  */
1709
1710int
1711handle_function (op, stringp)
1712     char **op;
1713     char **stringp;
1714{
1715  const struct function_table_entry *entry_p;
1716  char openparen = (*stringp)[0];
1717  char closeparen = openparen == '(' ? ')' : '}';
1718  char *beg;
1719  char *end;
1720  int count = 0;
1721  register char *p;
1722  char **argv, **argvp;
1723  int nargs;
1724
1725  beg = *stringp + 1;
1726
1727  entry_p = lookup_function (function_table, beg);
1728
1729  if (!entry_p)
1730    return 0;
1731
1732  /* We found a builtin function.  Find the beginning of its arguments (skip
1733     whitespace after the name).  */
1734
1735  beg = next_token (beg + entry_p->len);
1736
1737  /* Find the end of the function invocation, counting nested use of
1738     whichever kind of parens we use.  Since we're looking, count commas
1739     to get a rough estimate of how many arguments we might have.  The
1740     count might be high, but it'll never be low.  */
1741
1742  for (nargs=1, end=beg; *end != '\0'; ++end)
1743    if (*end == ',')
1744      ++nargs;
1745    else if (*end == openparen)
1746      ++count;
1747    else if (*end == closeparen && --count < 0)
1748      break;
1749
1750  if (count >= 0)
1751    fatal (reading_file,
1752           _("unterminated call to function `%s': missing `%c'"),
1753           entry_p->name, closeparen);
1754
1755  *stringp = end;
1756
1757  /* Get some memory to store the arg pointers.  */
1758  argvp = argv = (char **) alloca (sizeof (char *) * (nargs + 2));
1759
1760  /* Chop the string into arguments, then a nul.  As soon as we hit
1761     MAXIMUM_ARGS (if it's >0) assume the rest of the string is part of the
1762     last argument.
1763
1764     If we're expanding, store pointers to the expansion of each one.  If
1765     not, make a duplicate of the string and point into that, nul-terminating
1766     each argument.  */
1767
1768  if (!entry_p->expand_args)
1769    {
1770      int len = end - beg;
1771
1772      p = xmalloc (len+1);
1773      memcpy (p, beg, len);
1774      p[len] = '\0';
1775      beg = p;
1776      end = beg + len;
1777    }
1778
1779  for (p=beg, nargs=0; p <= end; ++argvp)
1780    {
1781      char *next;
1782
1783      ++nargs;
1784
1785      if (nargs == entry_p->maximum_args
1786          || (! (next = find_next_argument (openparen, closeparen, p, end))))
1787        next = end;
1788
1789      if (entry_p->expand_args)
1790        *argvp = expand_argument (p, next);
1791      else
1792        {
1793          *argvp = p;
1794          *next = '\0';
1795        }
1796
1797      p = next + 1;
1798    }
1799  *argvp = NULL;
1800
1801  /* Finally!  Run the function...  */
1802  *op = expand_builtin_function (*op, nargs, argv, entry_p);
1803
1804  /* Free memory.  */
1805  if (entry_p->expand_args)
1806    for (argvp=argv; *argvp != 0; ++argvp)
1807      free (*argvp);
1808  else
1809    free (beg);
1810
1811  return 1;
1812}
1813
1814
1815/* User-defined functions.  Expand the first argument as either a builtin
1816   function or a make variable, in the context of the rest of the arguments
1817   assigned to $1, $2, ... $N.  $0 is the name of the function.  */
1818
1819static char *
1820func_call (o, argv, funcname)
1821     char *o;
1822     char **argv;
1823     const char *funcname;
1824{
1825  char *fname;
1826  char *cp;
1827  int flen;
1828  char *body;
1829  int i;
1830  const struct function_table_entry *entry_p;
1831
1832  /* There is no way to define a variable with a space in the name, so strip
1833     leading and trailing whitespace as a favor to the user.  */
1834  fname = argv[0];
1835  while (*fname != '\0' && isspace ((unsigned char)*fname))
1836    ++fname;
1837
1838  cp = fname + strlen (fname) - 1;
1839  while (cp > fname && isspace ((unsigned char)*cp))
1840    --cp;
1841  cp[1] = '\0';
1842
1843  /* Calling nothing is a no-op */
1844  if (*fname == '\0')
1845    return o;
1846
1847  /* Are we invoking a builtin function?  */
1848
1849  entry_p = lookup_function (function_table, fname);
1850
1851  if (entry_p)
1852    {
1853      /* How many arguments do we have?  */
1854      for (i=0; argv[i+1]; ++i)
1855        ;
1856
1857      return expand_builtin_function (o, i, argv+1, entry_p);
1858    }
1859
1860  /* Not a builtin, so the first argument is the name of a variable to be
1861     expanded and interpreted as a function.  Create the variable
1862     reference.  */
1863  flen = strlen (fname);
1864
1865  body = alloca (flen + 4);
1866  body[0] = '$';
1867  body[1] = '(';
1868  memcpy (body + 2, fname, flen);
1869  body[flen+2] = ')';
1870  body[flen+3] = '\0';
1871
1872  /* Set up arguments $(1) .. $(N).  $(0) is the function name.  */
1873
1874  push_new_variable_scope ();
1875
1876  for (i=0; *argv; ++i, ++argv)
1877    {
1878      char num[11];
1879
1880      sprintf (num, "%d", i);
1881      define_variable (num, strlen (num), *argv, o_automatic, 1);
1882    }
1883
1884  /* Expand the body in the context of the arguments, adding the result to
1885     the variable buffer.  */
1886
1887  o = variable_expand_string (o, body, flen+3);
1888
1889  pop_variable_scope ();
1890
1891  return o + strlen (o);
1892}
Note: See TracBrowser for help on using the repository browser.