home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / GNU_KIT / DISK8.ZIP / src / makest / function.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-08  |  29.0 KB  |  1,187 lines

  1. /* Variable function expansion for GNU Make.
  2. Copyright (C) 1988, 1989 Free Software Foundation, Inc.
  3. This file is part of GNU Make.
  4.  
  5. GNU Make is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 1, or (at your option)
  8. any later version.
  9.  
  10. GNU Make is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with GNU Make; see the file COPYING.  If not, write to
  17. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include "make.h"
  20. #include "variable.h"
  21. #include "dep.h"
  22. #include "commands.h"
  23. #include "job.h"
  24. #include <errno.h>
  25.  
  26. extern int errno;
  27.  
  28. static char *string_glob ();
  29.  
  30. /* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing
  31.    each occurrence of SUBST with REPLACE. TEXT is null-terminated.  SLEN is
  32.    the length of SUBST and RLEN is the length of REPLACE.  If BY_WORD is
  33.    nonzero, substitutions are done only on matches which are complete
  34.    whitespace-delimited words.  If SUFFIX_ONLY is nonzero, substitutions are
  35.    done only at the ends of whitespace-delimited words.  */
  36.    
  37. char *
  38. subst_expand (o, text, subst, replace, slen, rlen, by_word, suffix_only)
  39.      char *o;
  40.      char *text;
  41.      char *subst, *replace;
  42.      unsigned int slen, rlen;
  43.      int by_word, suffix_only;
  44. {
  45.   register char *t = text;
  46.   register char *p;
  47.  
  48.   if (slen == 0 && !by_word && !suffix_only)
  49.     {
  50.       /* The first occurrence of "" in any string is its end.  */
  51.       o = variable_buffer_output (o, t, strlen (t));
  52.       if (rlen > 0)
  53.     o = variable_buffer_output (o, replace, rlen);
  54.       return o;
  55.     }
  56.  
  57.   while ((p = sindex (t, 0, subst, slen)) != 0)
  58.     {
  59.       /* Output everything before this occurrence of the string to replace.  */
  60.       if (p > t)
  61.     o = variable_buffer_output (o, t, p - t);
  62.  
  63.       /* If we're substituting only by fully matched words,
  64.      or only at the ends of words, check that this case qualifies.  */
  65.       if ((by_word
  66.        && ((p > t && p[-1] != ' ' && p[-1] != '\t')
  67.            || (p[slen] != '\0' && p[slen] != ' ' && p[slen] != '\t'))
  68.        || (suffix_only
  69.            && (p[slen] != '\0' && p[slen] != ' ' && p[slen] != '\t'))))
  70.     /* Struck out.  Output the rest of the string that is
  71.        no longer to be replaced.  */
  72.     o = variable_buffer_output (o, subst, slen);
  73.       else if (rlen > 0)
  74.     /* Output the replacement string.  */
  75.     o = variable_buffer_output (o, replace, rlen);
  76.  
  77.       /* Advance T past the string to be replaced.  */
  78.       t = p + slen;
  79.     }
  80.  
  81.   /* Output everything left on the end.  */
  82.   if (*t != '\0')
  83.     o = variable_buffer_output (o, t, strlen (t));
  84.  
  85.   return o;
  86. }
  87.  
  88.  
  89. /* Store into VARIABLE_BUFFER at O the result of scanning TEXT
  90.    and replacing strings matching PATTERN with REPLACE.
  91.    If PATTERN_PERCENT is not nil, PATTERN has already been
  92.    run through find_percent, and PATTERN_PERCENT is the result.
  93.    If REPLACE_PERCENT is not nil, REPLACE has already been
  94.    run through find_percent, and REPLACE_PERCENT is the result.  */
  95.  
  96. char *
  97. patsubst_expand (o, text, pattern, replace, pattern_percent, replace_percent)
  98.      char *o;
  99.      char *text;
  100.      register char *pattern, *replace;
  101.      register char *pattern_percent, *replace_percent;
  102. {
  103.   register int pattern_prepercent_len, pattern_postpercent_len;
  104.   register int replace_prepercent_len, replace_postpercent_len;
  105.   register char *t;
  106.   unsigned int len;
  107.   int doneany = 0;
  108.  
  109.   /* We call find_percent on REPLACE before checking PATTERN so that REPLACE
  110.      will be collapsed before we call subst_expand if PATTERN has no %.  */
  111.   if (replace_percent == 0)
  112.     replace_percent = find_percent (replace);
  113.   if (replace_percent != 0)
  114.     {
  115.       /* Record the length of REPLACE before and after the % so
  116.      we don't have to compute these lengths more than once.  */
  117.       replace_prepercent_len = replace_percent - replace;
  118.       replace_postpercent_len = strlen (replace_percent + 1);
  119.     }
  120.   else
  121.     /* We store the length of the replacement
  122.        so we only need to compute it once.  */
  123.     replace_prepercent_len = strlen (replace);
  124.  
  125.   if (pattern_percent == 0)
  126.     pattern_percent = find_percent (pattern);
  127.   if (pattern_percent == 0)
  128.     /* With no % in the pattern, this is just a simple substitution.  */
  129.     return subst_expand (o, text, pattern, replace,
  130.              strlen (pattern), strlen (replace), 1, 0);
  131.  
  132.   /* Record the length of PATTERN before and after the %
  133.      so we don't have to compute it more than once.  */
  134.   pattern_prepercent_len = pattern_percent - pattern;
  135.   pattern_postpercent_len = strlen (pattern_percent + 1);
  136.  
  137.   while (t = find_next_token (&text, &len))
  138.     {
  139.       int fail = 0;
  140.  
  141.       /* Is it big enough to match?  */
  142.       if (len < pattern_prepercent_len + pattern_postpercent_len)
  143.     fail = 1;
  144.  
  145.       /* Does the prefix match?  */
  146.       if (!fail && pattern_prepercent_len > 0
  147.       && (*t != *pattern
  148.           || t[pattern_prepercent_len - 1] != pattern_percent[-1]
  149.           || strncmp (t + 1, pattern + 1, pattern_prepercent_len - 1)))
  150.     fail = 1;
  151.  
  152.       /* Does the suffix match?  */
  153.       if (!fail && pattern_postpercent_len > 0
  154.       && (t[len - 1] != pattern_percent[pattern_postpercent_len]
  155.           || t[len - pattern_postpercent_len] != pattern_percent[1]
  156.           || strncmp (&t[len - pattern_postpercent_len],
  157.               &pattern_percent[1], pattern_postpercent_len - 1)))
  158.     fail = 1;
  159.  
  160.       if (fail)
  161.     /* It didn't match.  Output the string.  */
  162.     o = variable_buffer_output (o, t, len);
  163.       else
  164.     {
  165.       /* It matched.  Output the replacement.  */
  166.  
  167.       /* Output the part of the replacement before the %.  */
  168.       o = variable_buffer_output (o, replace, replace_prepercent_len);
  169.  
  170.       if (replace_percent != 0)
  171.         {
  172.           /* Output the part of the matched string that
  173.          matched the % in the pattern.  */
  174.           o = variable_buffer_output (o, t + pattern_prepercent_len,
  175.                       len - (pattern_prepercent_len
  176.                          + pattern_postpercent_len));
  177.           /* Output the part of the replacement after the %.  */
  178.           o = variable_buffer_output (o, replace_percent + 1,
  179.                       replace_postpercent_len);
  180.         }
  181.     }
  182.  
  183.       /* Output a space, but not if the replacement is "".  */
  184.       if (fail || replace_prepercent_len > 0
  185.       || (replace_percent != 0 && len + replace_postpercent_len > 0))
  186.     {
  187.       o = variable_buffer_output (o, " ", 1);
  188.       doneany = 1;
  189.     }
  190.     }
  191.   if (doneany)
  192.     /* Kill the last space.  */
  193.     --o;
  194.  
  195.   return o;
  196. }
  197.  
  198. /* Handle variable-expansion-time functions such as $(dir foo/bar) ==> foo/  */
  199.  
  200. /* These enumeration constants distinguish the
  201.    various expansion-time built-in functions.  */
  202.  
  203. enum function
  204.   {
  205.     function_subst,
  206.     function_addsuffix,
  207.     function_addprefix,
  208.     function_dir,
  209.     function_notdir,
  210.     function_suffix,
  211.     function_basename,
  212.     function_wildcard,
  213.     function_firstword,
  214.     function_word,
  215.     function_words,
  216.     function_findstring,
  217.     function_strip,
  218.     function_join,
  219.     function_patsubst,
  220.     function_filter,
  221.     function_filter_out,
  222.     function_foreach,
  223.     function_sort,
  224.     function_origin,
  225.     function_shell,
  226.     function_invalid
  227.   };
  228.  
  229. /* Greater than the length of any function name.  */
  230. #define MAXFUNCTIONLEN 11
  231.  
  232. /* The function names and lengths of names, for looking them up.  */
  233.  
  234. static struct
  235.   {
  236.     char *name;
  237.     unsigned int len;
  238.     enum function function;
  239.   } function_table[] =
  240.   {
  241.     { "subst", 5, function_subst },
  242.     { "addsuffix", 9, function_addsuffix },
  243.     { "addprefix", 9, function_addprefix },
  244.     { "dir", 3, function_dir },
  245.     { "notdir", 6, function_notdir },
  246.     { "suffix", 6, function_suffix },
  247.     { "basename", 8, function_basename },
  248.     { "wildcard", 8, function_wildcard },
  249.     { "firstword", 9, function_firstword },
  250.     { "word", 4, function_word },
  251.     { "words", 5, function_words },
  252.     { "findstring", 10, function_findstring },
  253.     { "strip", 5, function_strip },
  254.     { "join", 4, function_join },
  255.     { "patsubst", 8, function_patsubst },
  256.     { "filter", 6, function_filter },
  257.     { "filter-out", 10, function_filter_out },
  258.     { "foreach", 7, function_foreach },
  259.     { "sort", 4, function_sort },
  260.     { "origin", 6, function_origin },
  261.     { "shell", 5, function_shell },
  262.     { 0, 0, function_invalid }
  263.   };
  264.  
  265. /* Return 1 if PATTERN matches WORD, 0 if not.  */
  266.  
  267. int
  268. pattern_matches (pattern, percent, word)
  269.      register char *pattern, *percent, *word;
  270. {
  271.   unsigned int len;
  272.  
  273.   if (percent == 0)
  274.     {
  275.       unsigned int len = strlen (pattern) + 1;
  276.       char *new = (char *) alloca (len);
  277.       bcopy (pattern, new, len);
  278.       pattern = new;
  279.       percent = find_percent (pattern);
  280.       if (percent == 0)
  281.     return streq (pattern, word);
  282.     }
  283.  
  284.   len = strlen (percent + 1);
  285.  
  286.   if (strlen (word) < (percent - pattern) + len
  287.       || strncmp (pattern, word, percent - pattern))
  288.     return 0;
  289.  
  290.   return !strcmp (percent + 1, word + (strlen (word) - len));
  291. }
  292.  
  293. int shell_function_pid = 0, shell_function_completed;
  294.  
  295. /* Perform the function specified by FUNCTION on the text at TEXT.
  296.    END is points to the end of the argument text (exclusive).
  297.    The output is written into VARIABLE_BUFFER starting at O.  */
  298.  
  299. /* Note this absorbs a semicolon and is safe to use in conditionals.  */
  300. #define BADARGS(func)  \
  301.   if (reading_filename != 0)                    \
  302.     fatal ("%s:%u: Insufficient arguments to function `%s'",    \
  303.        reading_filename, *reading_lineno_ptr, func);    \
  304.   else fatal ("insufficient arguments to function `%s'", func)
  305.  
  306. static char *
  307. expand_function (o, function, text, end)
  308.      char *o;
  309.      enum function function;
  310.      char *text;
  311.      char *end;
  312. {
  313.   char *p, *p2, *p3;
  314.   unsigned int i, len;
  315.   int doneany = 0;
  316.   int count;
  317.   char endparen = *end, startparen = *end == ')' ? '(' : '{';
  318.  
  319.   switch (function)
  320.     {
  321.     default:
  322.       abort ();
  323.       break;
  324.       
  325.     case function_shell:
  326.       {
  327.     extern int fork ();
  328.     extern int pipe ();
  329.     char **argv;
  330.     char buf[100];
  331.     int pipedes[2];
  332.     int pid;
  333.  
  334.     /* Expand the command line.  */
  335.     text = expand_argument (text, end);
  336.  
  337.     /* Construct the argument list.  */
  338.     argv = construct_command_argv (text, (struct file *) 0);
  339.     if (argv == 0)
  340.       break;
  341.  
  342.     /* For error messages.  */
  343.     if (reading_filename != 0)
  344.       sprintf (buf, "%s:%u: ", reading_filename, *reading_lineno_ptr);
  345.     else
  346.       buf[0] = '\0';
  347.  
  348. #ifdef atarist
  349.     perror_with_name (buf, "function not allowed under TOS");
  350. #else
  351.     if (pipe (pipedes) < 0)
  352.       {
  353.         perror_with_name (buf, "pipe");
  354.         break;
  355.       }
  356.  
  357.     push_signals_blocked_p (1);
  358.  
  359.     pid = fork ();
  360.     if (pid < 0)
  361.       perror_with_name (buf, "fork");
  362.     else if (pid == 0)
  363.       child_execute_job (0, pipedes[1], argv, environ);
  364.     else
  365.       {
  366.         /* We are the parent.  Set up and read from the pipe.  */
  367.         char *buffer = (char *) xmalloc (201);
  368.         unsigned int maxlen = 200;
  369.         int cc;
  370.  
  371.         /* Record the PID for child_handler.  */
  372.         shell_function_pid = pid;
  373.         shell_function_completed = 0;
  374.  
  375.         /* Close the write side of the pipe.  */
  376.         (void) close (pipedes[1]);
  377.  
  378.         /* Read from the pipe until it gets EOF.  */
  379.         i = 0;
  380.         do
  381.           {
  382.         if (i == maxlen)
  383.           {
  384.             maxlen += 512;
  385.             buffer = (char *) xrealloc (buffer, maxlen + 1);
  386.           }
  387.  
  388.         errno = 0;
  389.         cc = read (pipedes[0], &buffer[i], maxlen - i);
  390.         if (cc > 0)
  391.           i += cc;
  392.           }
  393. #ifdef EINTR
  394.         while (cc > 0 || errno == EINTR);
  395. #else
  396.         while (cc > 0);
  397. #endif
  398.  
  399.         /* Close the read side of the pipe.  */
  400.         (void) close (pipedes[0]);
  401.  
  402.         /* Loop until child_handler sets shell_function_completed
  403.            to the status of our child shell.  */
  404.         while (shell_function_completed == 0)
  405.           wait_for_children (1, 0);
  406.  
  407.         shell_function_pid = 0;
  408.  
  409.         /* The child_handler function will set shell_function_completed
  410.            to 1 when the child dies normally, or to -1 if it
  411.            dies with status 127, which is most likely an exec fail.  */
  412.  
  413.         if (shell_function_completed == -1)
  414.           {
  415.         /* This most likely means that the execvp failed,
  416.            so we should just write out the error message
  417.            that came in over the pipe from the child.  */
  418.         fputs (buffer, stderr);
  419.         fflush (stderr);
  420.           }
  421.         else
  422.           {
  423.         /* The child finished normally.  Replace all
  424.            newlines in its output with spaces, and put
  425.            that in the variable output buffer.  */
  426.         if (i > 0)
  427.           {
  428.             if (buffer[i - 1] == '\n')
  429.               buffer[--i] = '\0';
  430.             p = buffer;
  431.             while ((p = index (p, '\n')) != 0)
  432.               *p++ = ' ';
  433.             o = variable_buffer_output (o, buffer, i);
  434.           }
  435.           }
  436.  
  437.         free (argv[0]);
  438.         free ((char *) argv);
  439.         free (buffer);
  440.       }
  441.  
  442.     pop_signals_blocked_p ();
  443.  
  444. #endif /* atarist */
  445.     free (text);
  446.     break;
  447.       }
  448.  
  449.     case function_origin:
  450.       /* Expand the argument.  */
  451.       text = expand_argument (text, end);
  452.  
  453.       {
  454.     register struct variable *v = lookup_variable (text, strlen (text));
  455.     if (v == 0)
  456.       o = variable_buffer_output (o, "undefined", 9);
  457.     else
  458.       switch (v->origin)
  459.         {
  460.         default:
  461.         case o_invalid:
  462.           abort ();
  463.           break;
  464.         case o_default:
  465.           o = variable_buffer_output (o, "default", 7);
  466.           break;
  467.         case o_env:
  468.           o = variable_buffer_output (o, "environment", 11);
  469.           break;
  470.         case o_file:
  471.           o = variable_buffer_output (o, "file", 4);
  472.           break;
  473.         case o_env_override:
  474.           o = variable_buffer_output (o, "environment override", 20);
  475.           break;
  476.         case o_command:
  477.           o = variable_buffer_output (o, "command line", 12);
  478.           break;
  479.         case o_override:
  480.           o = variable_buffer_output (o, "override", 8);
  481.           break;
  482.         case o_automatic:
  483.           o = variable_buffer_output (o, "automatic", 9);
  484.           break;
  485.         }
  486.       }
  487.  
  488.       free (text);
  489.       break;
  490.       
  491.     case function_sort:
  492.       /* Expand the argument.  */
  493.       text = expand_argument (text, end);
  494.  
  495.       {
  496.     char **words = (char **) xmalloc (10 * sizeof (char *));
  497.     unsigned int nwords = 10;
  498.     register unsigned int wordi = 0;
  499.     char *t;
  500.  
  501.     /* Chop TEXT into words and put them in WORDS.  */
  502.     t = text;
  503.     while (p = find_next_token (&t, &len))
  504.       {
  505.         if (wordi >= nwords - 1)
  506.           {
  507.         nwords += 5;
  508.         words = (char **) xrealloc ((char *) words,
  509.                         nwords * sizeof (char *));
  510.           }    
  511.         words[wordi++] = savestring (p, len);
  512.       }
  513.  
  514.     if (wordi > 0)
  515.       {
  516.         /* Now sort the list of words.  */
  517.         qsort ((char *) words, wordi, sizeof (char *), alpha_compare);
  518.  
  519.         /* Now write the sorted list.  */
  520.         for (i = 0; i < wordi; ++i)
  521.           {
  522.         len = strlen (words[i]);
  523.         if (i == wordi - 1 || strlen (words[i + 1]) != len
  524.             || strcmp (words[i], words[i + 1]))
  525.           {
  526.             o = variable_buffer_output (o, words[i], len);
  527.             o = variable_buffer_output (o, " ", 1);
  528.           }
  529.         free (words[i]);
  530.           }
  531.         /* Kill the last space.  */
  532.         --o;
  533.       }
  534.  
  535.     free ((char *) words);
  536.       }
  537.  
  538.       free (text);
  539.       break;
  540.       
  541.     case function_foreach:
  542.       {
  543.     /* Get three comma-separated arguments but
  544.        expand only the first two.  */
  545.     char *var, *list;
  546.     register struct variable *v;
  547.  
  548.     count = 0;
  549.     for (p = text; p < end; ++p)
  550.       {
  551.         if (*p == startparen)
  552.           ++count;
  553.         else if (*p == endparen)
  554.           --count;
  555.         else if (*p == ',' && count <= 0)
  556.           break;
  557.       }
  558.     if (p == end)
  559.       BADARGS ("foreach");
  560.     var = expand_argument (text, p);
  561.  
  562.     p2 = p + 1;
  563.     count = 0;
  564.     for (p = p2; p < end; ++p)
  565.       {
  566.         if (*p == startparen)
  567.           ++count;
  568.         else if (*p == endparen)
  569.           --count;
  570.         else if (*p == ',' && count <= 0)
  571.           break;
  572.       }
  573.     if (p == end)
  574.       BADARGS ("foreach");
  575.     list = expand_argument (p2, p);
  576.  
  577.     ++p;
  578.     text = savestring (p, end - p);
  579.  
  580.     push_new_variable_scope ();
  581.     v = define_variable (var, strlen (var), "", o_automatic, 0);
  582.     p3 = list;
  583.     while ((p = find_next_token (&p3, &len)) != 0)
  584.       {
  585.         char *result;
  586.         char save = p[len];
  587.         p[len] = '\0';
  588.         v->value = p;
  589.         result = allocated_variable_expand (text);
  590.         p[len] = save;
  591.  
  592.         o = variable_buffer_output (o, result, strlen (result));
  593.         o = variable_buffer_output (o, " ", 1);
  594.         doneany = 1;
  595.         free (result);
  596.       }
  597.     if (doneany)
  598.       /* Kill the last space.  */
  599.       --o;
  600.  
  601.     pop_variable_scope ();
  602.  
  603.     free (var);
  604.     free (list);
  605.     free (text);
  606.       }
  607.       break;
  608.  
  609.     case function_filter:
  610.     case function_filter_out:
  611.       {
  612.     char **words;
  613.     unsigned int nwords;
  614.     register unsigned int wordi;
  615.     
  616.     /* Get two comma-separated arguments and expand each one.  */
  617.     count = 0;
  618.     for (p = text; p < end; ++p)
  619.       {
  620.         if (*p == startparen)
  621.           ++count;
  622.         else if (*p == endparen)
  623.           --count;
  624.         else if (*p == ',' && count <= 0)
  625.           break;
  626.       }
  627.     if (p == end)
  628.       BADARGS (function == function_filter ? "filter" : "filter-out");
  629.     p2 = expand_argument (text, p);
  630.     
  631.     text = expand_argument (p + 1, end);
  632.  
  633.     /* Chop TEXT up into words and then run each pattern through.  */
  634.     nwords = 10;
  635.     words = (char **) xmalloc (10 * sizeof (char *));
  636.     wordi = 0;
  637.     p3 = text;
  638.     while ((p = find_next_token (&p3, &len)) != 0)
  639.       {
  640.         if (wordi == nwords - 1)
  641.           {
  642.         nwords += 10;
  643.         words = (char **) xrealloc ((char *) words,
  644.                         nwords * sizeof (char *));
  645.           }
  646.         if (*p3 != '\0')
  647.           ++p3;
  648.         p[len] = '\0';
  649.         words[wordi++] = p;
  650.       }
  651.  
  652.     /* Run each pattern through the words, killing words.  */
  653.     p3 = p2;
  654.     while ((p = find_next_token (&p3, &len)) != 0)
  655.       {
  656.         char *percent;
  657.         char save = p[len];
  658.         p[len] = '\0';
  659.  
  660.         percent = find_percent (p);
  661.         for (i = 0; i < wordi; ++i)
  662.           if (words[i] != 0 &&
  663.           (percent == 0 ? streq (p, words[i])
  664.            : pattern_matches (p, percent, words[i]))
  665.           == (function == function_filter_out))
  666.         words[i] = 0;
  667.         p[len] = save;
  668.       }
  669.  
  670.     /* Output the words that remain.  */
  671.     for (i = 0; i < wordi; ++i)
  672.       if (words[i] != 0)
  673.         {
  674.           o = variable_buffer_output (o, words[i], strlen (words[i]));
  675.           o = variable_buffer_output (o, " ", 1);
  676.           doneany = 1;
  677.         }
  678.     if (doneany)
  679.       /* Kill the last space.  */
  680.       --o;
  681.  
  682.     free ((char *) words);
  683.     free (p2);
  684.     free (text);
  685.       }
  686.       break;
  687.       
  688.     case function_patsubst:
  689.       /* Get three comma-separated arguments and expand each one.  */
  690.       count = 0;
  691.       for (p = text; p < end; ++p)
  692.     {
  693.       if (*p == startparen)
  694.         ++count;
  695.       else if (*p == endparen)
  696.         --count;
  697.       else if (*p == ',' && count <= 0)
  698.         break;
  699.     }
  700.       if (p == end)
  701.     BADARGS ("patsubst");
  702.  
  703.       p2 = p;
  704.       count = 0;
  705.       for (++p; p < end; ++p)
  706.     {
  707.       if (*p == startparen)
  708.         ++count;
  709.       else if (*p == endparen)
  710.         --count;
  711.       else if (*p == ',' && count <= 0)
  712.         break;
  713.     }
  714.       if (p == end)
  715.     BADARGS ("patsubst");
  716.  
  717.       text = expand_argument (text, p2);
  718.       p3 = expand_argument (p2 + 1, p);
  719.       p2 = expand_argument (p + 1, end);
  720.       
  721.       o = patsubst_expand (o, p2, text, p3, (char *) 0, (char *) 0);
  722.       
  723.       free (text);
  724.       free (p3);
  725.       free (p2);
  726.       break;
  727.  
  728.     case function_join:
  729.       /* Get two comma-separated arguments and expand each one.  */
  730.       count = 0;
  731.       for (p = text; p < end; ++p)
  732.     {
  733.       if (*p == startparen)
  734.         ++count;
  735.       else if (*p == endparen)
  736.         --count;
  737.       else if (*p == ',' && count <= 0)
  738.         break;
  739.     }
  740.       if (p == end)
  741.     BADARGS ("join");
  742.       text = expand_argument (text, p);
  743.  
  744.       p = expand_argument (p + 1, end);
  745.       
  746.       {
  747.     /* Write each word of the first argument directly followed
  748.        by the corresponding word of the second argument.
  749.        If the two arguments have a different number of words,
  750.        the excess words are just output separated by blanks.  */
  751.     register char *tp, *pp;
  752.     p2 = text;
  753.     p3 = p;
  754.     do
  755.       {
  756.         unsigned int tlen, plen;
  757.  
  758.         tp = find_next_token (&p2, &tlen);
  759.         if (tp != 0)
  760.           o = variable_buffer_output (o, tp, tlen);
  761.         
  762.         pp = find_next_token (&p3, &plen);
  763.         if (pp != 0)
  764.           o = variable_buffer_output (o, pp, plen);
  765.         
  766.         if (tp != 0 || pp != 0)
  767.           {
  768.         o = variable_buffer_output (o, " ", 1);
  769.         doneany = 1;
  770.           }
  771.       }
  772.     while (tp != 0 || pp != 0);
  773.     if (doneany)
  774.       /* Kill the last blank.  */
  775.       --o;
  776.       }
  777.       
  778.       free (text);
  779.       free (p);
  780.       break;
  781.       
  782.     case function_strip:
  783.       /* Expand the argument.  */
  784.       text = expand_argument (text, end);
  785.  
  786.       p2 = text;
  787.       while ((p = find_next_token (&p2, &i)) != 0)
  788.     {
  789.       o = variable_buffer_output (o, p, i);
  790.       o = variable_buffer_output (o, " ", 1);
  791.       doneany = 1;
  792.     }
  793.       if (doneany)
  794.     /* Kill the last space.  */
  795.     --o;
  796.       
  797.       free (text);
  798.       break;
  799.       
  800.     case function_wildcard:
  801.       text = expand_argument (text, end);
  802.       
  803.       p = string_glob (text);
  804.       o = variable_buffer_output (o, p, strlen (p));
  805.       
  806.       free (text);
  807.       break;
  808.       
  809.     case function_subst:
  810.       /* Get three comma-separated arguments and expand each one.  */
  811.       count = 0;
  812.       for (p = text; p < end; ++p)
  813.     {
  814.       if (*p == startparen)
  815.         ++count;
  816.       else if (*p == endparen)
  817.         --count;
  818.       else if (*p == ',' && count <= 0)
  819.         break;
  820.     }
  821.       if (p == end)
  822.     BADARGS ("subst");
  823.  
  824.       p2 = p;
  825.       count = 0;
  826.       for (++p; p < end; ++p)
  827.     {
  828.       if (*p == startparen)
  829.         ++count;
  830.       else if (*p == endparen)
  831.         --count;
  832.       else if (*p == ',' && count <= 0)
  833.         break;
  834.     }
  835.       if (p == end)
  836.     BADARGS ("subst");
  837.  
  838.       text = expand_argument (text, p2);
  839.       p3 = expand_argument (p2 + 1, p);
  840.       p2 = expand_argument (p + 1, end);
  841.       
  842.       o = subst_expand (o, p2, text, p3, strlen (text), strlen (p3), 0, 0);
  843.       
  844.       free (text);
  845.       free (p3);
  846.       free (p2);
  847.       break;
  848.       
  849.     case function_firstword:
  850.       /* Expand the argument.  */
  851.       text = expand_argument (text, end);
  852.  
  853.       /* Find the first word in TEXT.  */
  854.       p2 = text;
  855.       p = find_next_token (&p2, &i);
  856.       if (p != 0)
  857.     o = variable_buffer_output (o, p, i);
  858.       
  859.       free (text);
  860.       break;
  861.       
  862.     case function_word:
  863.       /* Get two comma-separated arguments and expand each one.  */
  864.       count = 0;
  865.       for (p = text; p < end; ++p)
  866.     {
  867.       if (*p == startparen)
  868.         ++count;
  869.       else if (*p == endparen)
  870.         --count;
  871.       else if (*p == ',' && count <= 0)
  872.         break;
  873.     }
  874.       if (p == end)
  875.     BADARGS ("word");
  876.       text = expand_argument (text, p);
  877.  
  878.       p3 = expand_argument (p + 1, end);
  879.  
  880.       /* Check the first argument.  */
  881.       for (p2 = text; *p2 != '\0'; ++p2)
  882.     if (*p2 < '0' || *p2 > '9')
  883.       {
  884.         if (reading_filename != 0)
  885.           fatal ("%s:%u: non-numeric first argument to `word' function",
  886.              reading_filename, *reading_lineno_ptr);
  887.         else
  888.           fatal ("non-numeric first argument to `word' function");
  889.       }
  890.  
  891.       i = (unsigned int) atoi (text);
  892.       if (i == 0)
  893.     {
  894.       if (reading_filename != 0)
  895.         fatal ("%s:%u: the `word' function takes a one-origin \
  896. index argument",
  897.            reading_filename, *reading_lineno_ptr);
  898.       else
  899.         fatal ("the `word' function takes a one-origin index argument");
  900.     }
  901.  
  902.       p2 = p3;
  903.       while ((p = find_next_token (&p2, &len)) != 0)
  904.     if (--i == 0)
  905.       break;
  906.       if (i == 0)
  907.     o = variable_buffer_output (o, p, len);
  908.  
  909.       free (text);
  910.       free (p3);
  911.       break;
  912.  
  913.     case function_words:
  914.       /* Expand the argument.  */
  915.       text = expand_argument (text, end);
  916.  
  917.       i = 0;
  918.       p2 = text;
  919.       while (find_next_token (&p2, (unsigned int *) 0) != 0)
  920.     ++i;
  921.  
  922.       {
  923.     char buf[20];
  924.     sprintf (buf, "%d", i);
  925.     o = variable_buffer_output (o, buf, strlen (buf));
  926.       }
  927.  
  928.       free (text);
  929.       break;
  930.  
  931.     case function_findstring:
  932.       /* Get two comma-separated arguments and expand each one.  */
  933.       count = 0;
  934.       for (p = text; p < end; ++p)
  935.     {
  936.       if (*p == startparen)
  937.         ++count;
  938.       else if (*p == endparen)
  939.         --count;
  940.       else if (*p == ',' && count <= 0)
  941.         break;
  942.     }
  943.       if (p == end)
  944.     BADARGS ("findstring");
  945.       text = expand_argument (text, p);
  946.  
  947.       p = expand_argument (p + 1, end);
  948.  
  949.       /* Find the first occurrence of the first string in the second.  */
  950.       i = strlen (text);
  951.       if (sindex (p, 0, text, i) != 0)
  952.     o = variable_buffer_output (o, text, i);
  953.       
  954.       free (p);
  955.       free (text);
  956.       break;
  957.       
  958.     case function_addsuffix:
  959.     case function_addprefix:
  960.       /* Get two comma-separated arguments and expand each one.  */
  961.       count = 0;
  962.       for (p = text; p < end; ++p)
  963.     {
  964.       if (*p == startparen)
  965.         ++count;
  966.       else if (*p == endparen)
  967.         --count;
  968.       else if (*p == ',' && count <= 0)
  969.         break;
  970.     }
  971.       if (p == end)
  972.     BADARGS (function == function_addsuffix ? "addsuffix" : "addprefix");
  973.       text = expand_argument (text, p);
  974.       i = strlen (text);
  975.  
  976.       p2 = expand_argument (p + 1, end);
  977.       
  978.       p3 = p2;
  979.       while ((p = find_next_token (&p3, &len)) != 0)
  980.     {
  981.       if (function == function_addprefix)
  982.         o = variable_buffer_output (o, text, i);
  983.       o = variable_buffer_output (o, p, len);
  984.       if (function == function_addsuffix)
  985.         o = variable_buffer_output (o, text, i);
  986.       o = variable_buffer_output (o, " ", 1);
  987.       doneany = 1;
  988.     }
  989.       if (doneany)
  990.     /* Kill last space.  */
  991.     --o;
  992.       
  993.       free (p2);
  994.       free (text);
  995.       break;
  996.       
  997.     case function_dir:
  998.     case function_basename:
  999.       /* Expand the argument.  */
  1000.       text = expand_argument (text, end);
  1001.  
  1002.       p3 = text;
  1003.       while ((p2 = find_next_token (&p3, &len)) != 0)
  1004.     {
  1005.       p = p2 + len;
  1006.       while (p >= p2 && *p != (function == function_dir ? '/' : '.'))
  1007.         --p;
  1008.       if (p >= p2)
  1009.         {
  1010.           if (function == function_dir)
  1011.         ++p;
  1012.           o = variable_buffer_output (o, p2, p - p2);
  1013.         }
  1014.       else if (function == function_dir)
  1015.             o = variable_buffer_output (o, "./", 2);
  1016.       else
  1017.         /* The entire name is the basename.  */
  1018.         o = variable_buffer_output (o, p2, len);
  1019.  
  1020.       o = variable_buffer_output (o, " ", 1);
  1021.       doneany = 1;
  1022.     }
  1023.       if (doneany)
  1024.     /* Kill last space.  */
  1025.     --o;
  1026.       
  1027.       free (text);
  1028.       break;
  1029.       
  1030.     case function_notdir:
  1031.     case function_suffix:
  1032.       /* Expand the argument.  */
  1033.       text = expand_argument (text, end);
  1034.  
  1035.       p3 = text;
  1036.       while ((p2 = find_next_token (&p3, &len)) != 0)
  1037.     {
  1038.       p = p2 + len;
  1039.       while (p >= p2 && *p != (function == function_notdir ? '/' : '.'))
  1040.         --p;
  1041.       if (p >= p2)
  1042.         {
  1043.           if (function == function_notdir)
  1044.         ++p;
  1045.           o = variable_buffer_output (o, p, len - (p - p2));
  1046.         }
  1047.       else if (function == function_notdir)
  1048.         o = variable_buffer_output (o, p2, len);
  1049.  
  1050.       if (function == function_notdir || p >= p2)
  1051.         {
  1052.           o = variable_buffer_output (o, " ", 1);
  1053.           doneany = 1;
  1054.         }
  1055.     }
  1056.       if (doneany)
  1057.     /* Kill last space.  */
  1058.     --o;
  1059.  
  1060.       free (text);
  1061.       break;
  1062.     }
  1063.  
  1064.   return o;
  1065. }
  1066.  
  1067. /* Check for a function invocation in *STRINGP.  *STRINGP points at the
  1068.    opening ( or { and is not null-terminated.  If a function invocation
  1069.    is found, expand it into the buffer at *OP, updating *OP, incrementing
  1070.    *STRINGP past the reference and returning nonzero.  If not, return zero.  */
  1071.  
  1072. int
  1073. handle_function (op, stringp)
  1074.      char **op;
  1075.      char **stringp;
  1076.  
  1077. {
  1078.   register unsigned int code;
  1079.   unsigned int maxlen;
  1080.   char *beg = *stringp + 1;
  1081.   char *endref;
  1082.  
  1083.   endref = lindex (beg, beg + MAXFUNCTIONLEN, '\0');
  1084.   maxlen = endref != 0 ? endref - beg : MAXFUNCTIONLEN;
  1085.  
  1086.   for (code = 0; function_table[code].name != 0; ++code)
  1087.     {
  1088.       if (maxlen < function_table[code].len)
  1089.     continue;
  1090.       endref = beg + function_table[code].len;
  1091.       if ((*endref == ' ' || *endref == '\t')
  1092.       && !strncmp (function_table[code].name, beg,
  1093.                function_table[code].len))
  1094.     break;
  1095.     }
  1096.   if (function_table[code].name != 0)
  1097.     {
  1098.       /* We have found a call to an expansion-time function.
  1099.      Find the end of the arguments, and do the function.  */
  1100.  
  1101.       char openparen = beg[-1], closeparen = openparen == '(' ? ')' : '}';
  1102.       int count = 0;
  1103.       char *argbeg;
  1104.       register char *p;
  1105.  
  1106.       /* Space after function name isn't part of the args.  */
  1107.       p = next_token (endref);
  1108.       argbeg = p;
  1109.  
  1110.       /* Count nested use of whichever kind of parens we use,
  1111.      so that nested calls and variable refs work.  */
  1112.  
  1113.       for (; *p != '\0'; ++p)
  1114.     {
  1115.       if (*p == openparen)
  1116.         ++count;
  1117.       else if (*p == closeparen && --count < 0)
  1118.         break;
  1119.     }
  1120.  
  1121.       /* We found the end; expand the function call.  */
  1122.  
  1123.       *op = expand_function (*op, function_table[code].function, argbeg, p);
  1124.       *stringp = p;
  1125.       return 1;
  1126.     }
  1127.  
  1128.   return 0;
  1129. }
  1130.  
  1131. /* Glob-expand LINE.  The returned pointer is
  1132.    only good until the next call to string_glob.  */
  1133.  
  1134. static char *
  1135. string_glob (line)
  1136.      char *line;
  1137. {
  1138.   static char *result = 0;
  1139.   static unsigned int length;
  1140.   register struct nameseq *chain;
  1141.   register unsigned int idx;
  1142.  
  1143.   chain = multi_glob (parse_file_seq (&line, '\0', sizeof (struct nameseq)),
  1144.               sizeof (struct nameseq));
  1145.  
  1146.   if (result == 0)
  1147.     {
  1148.       length = 100;
  1149.       result = (char *) xmalloc (100);
  1150.     }
  1151.  
  1152.   idx = 0;
  1153.   while (chain != 0)
  1154.     {
  1155.       register char *name = chain->name;
  1156.       unsigned int len = strlen (name);
  1157.  
  1158.       struct nameseq *next = chain->next;
  1159.       free ((char *) chain);
  1160.       chain = next;
  1161.  
  1162.       /* multi_glob will pass names without globbing metacharacters
  1163.      through as is, but we want only files that actually exist.  */
  1164.       if (file_exists_p (name))
  1165.     {
  1166.       if (idx + len + 1 > length)
  1167.         {
  1168.           length += (len + 1) * 2;
  1169.           result = (char *) xrealloc (result, length);
  1170.         }
  1171.       bcopy (name, &result[idx], len);
  1172.       idx += len;
  1173.       result[idx++] = ' ';
  1174.     }
  1175.  
  1176.       free (name);
  1177.     }
  1178.  
  1179.   /* Kill the last space and terminate the string.  */
  1180.   if (idx == 0)
  1181.     result[0] = '\0';
  1182.   else
  1183.     result[idx - 1] = '\0';
  1184.  
  1185.   return result;
  1186. }
  1187.