/[make]/make/read.c
ViewVC logotype

Diff of /make/read.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.135 by bosk, Tue Oct 5 16:56:14 2004 UTC revision 1.136 by bosk, Sun Feb 27 21:40:24 2005 UTC
# Line 134  static int conditional_line PARAMS ((cha Line 134  static int conditional_line PARAMS ((cha
134  static void record_files PARAMS ((struct nameseq *filenames, char *pattern, char *pattern_percent,  static void record_files PARAMS ((struct nameseq *filenames, char *pattern, char *pattern_percent,
135                          struct dep *deps, unsigned int cmds_started, char *commands,                          struct dep *deps, unsigned int cmds_started, char *commands,
136                          unsigned int commands_idx, int two_colon,                          unsigned int commands_idx, int two_colon,
                         int have_sysv_atvar,  
137                          const struct floc *flocp, int set_default));                          const struct floc *flocp, int set_default));
138  static void record_target_var PARAMS ((struct nameseq *filenames, char *defn,  static void record_target_var PARAMS ((struct nameseq *filenames, char *defn,
139                                         enum variable_origin origin,                                         enum variable_origin origin,
# Line 457  eval (struct ebuffer *ebuf, int set_defa Line 456  eval (struct ebuffer *ebuf, int set_defa
456    unsigned int cmds_started, tgts_started;    unsigned int cmds_started, tgts_started;
457    int ignoring = 0, in_ignored_define = 0;    int ignoring = 0, in_ignored_define = 0;
458    int no_targets = 0;           /* Set when reading a rule without targets.  */    int no_targets = 0;           /* Set when reading a rule without targets.  */
   int have_sysv_atvar = 0;  
459    struct nameseq *filenames = 0;    struct nameseq *filenames = 0;
460    struct dep *deps = 0;    struct dep *deps = 0;
461    long nlines = 0;    long nlines = 0;
# Line 474  eval (struct ebuffer *ebuf, int set_defa Line 472  eval (struct ebuffer *ebuf, int set_defa
472            fi.lineno = tgts_started;                                           \            fi.lineno = tgts_started;                                           \
473            record_files (filenames, pattern, pattern_percent, deps,            \            record_files (filenames, pattern, pattern_percent, deps,            \
474                          cmds_started, commands, commands_idx, two_colon,      \                          cmds_started, commands, commands_idx, two_colon,      \
475                          have_sysv_atvar, &fi, set_default);                   \                          &fi, set_default);                                    \
476          }                                                                     \          }                                                                     \
477        filenames = 0;                                                          \        filenames = 0;                                                          \
478        commands_idx = 0;                                                       \        commands_idx = 0;                                                       \
# Line 869  eval (struct ebuffer *ebuf, int set_defa Line 867  eval (struct ebuffer *ebuf, int set_defa
867          char *cmdleft, *semip, *lb_next;          char *cmdleft, *semip, *lb_next;
868          unsigned int len, plen = 0;          unsigned int len, plen = 0;
869          char *colonp;          char *colonp;
870            const char *end, *beg; /* Helpers for whitespace stripping. */
871    
872          /* Record the previous rule.  */          /* Record the previous rule.  */
873    
# Line 917  eval (struct ebuffer *ebuf, int set_defa Line 916  eval (struct ebuffer *ebuf, int set_defa
916            }            }
917    
918          p2 = variable_expand_string(NULL, lb_next, len);          p2 = variable_expand_string(NULL, lb_next, len);
919    
920          while (1)          while (1)
921            {            {
922              lb_next += len;              lb_next += len;
# Line 1094  eval (struct ebuffer *ebuf, int set_defa Line 1094  eval (struct ebuffer *ebuf, int set_defa
1094                }                }
1095            }            }
1096    
         /* Do any of the prerequisites appear to have $@ etc.?  */  
         have_sysv_atvar = 0;  
         if (!posix_pedantic)  
           for (p = strchr (p2, '$'); p != 0; p = strchr (p+1, '$'))  
             if (p[1] == '@' || ((p[1] == '(' || p[1] == '{') && p[2] == '@'))  
               {  
                 have_sysv_atvar = 1;  
                 break;  
               }  
   
1097          /* Is this a static pattern rule: `target: %targ: %dep; ...'?  */          /* Is this a static pattern rule: `target: %targ: %dep; ...'?  */
1098          p = strchr (p2, ':');          p = strchr (p2, ':');
1099          while (p != 0 && p[-1] == '\\')          while (p != 0 && p[-1] == '\\')
# Line 1168  eval (struct ebuffer *ebuf, int set_defa Line 1158  eval (struct ebuffer *ebuf, int set_defa
1158          else          else
1159            pattern = 0;            pattern = 0;
1160    
1161          /* Parse the dependencies.  */          /* Strip leading and trailing whitespaces. */
1162          deps = (struct dep *)          beg = p2;
1163            multi_glob (parse_file_seq (&p2, '|', sizeof (struct dep), 1),          end = beg + strlen (beg) - 1;
1164                        sizeof (struct dep));          strip_whitespace (&beg, &end);
1165          if (*p2)  
1166            if (beg <= end && *beg != '\0')
1167            {            {
1168              /* Files that follow '|' are special prerequisites that              deps = (struct dep*) xmalloc (sizeof (struct dep));
1169                 need only exist in order to satisfy the dependency.              deps->next = 0;
1170                 Their modification times are irrelevant.  */              deps->name = savestring (beg, end - beg + 1);
1171              struct dep **deps_ptr = &deps;              deps->file = 0;
             struct dep *d;  
             for (deps_ptr = &deps; *deps_ptr; deps_ptr = &(*deps_ptr)->next)  
               ;  
             ++p2;  
             *deps_ptr = (struct dep *)  
               multi_glob (parse_file_seq (&p2, '\0', sizeof (struct dep), 1),  
                           sizeof (struct dep));  
             for (d = *deps_ptr; d != 0; d = d->next)  
               d->ignore_mtime = 1;  
1172            }            }
1173            else
1174              deps = 0;
1175    
1176          commands_idx = 0;          commands_idx = 0;
1177          if (cmdleft != 0)          if (cmdleft != 0)
# Line 1753  static void Line 1737  static void
1737  record_files (struct nameseq *filenames, char *pattern, char *pattern_percent,  record_files (struct nameseq *filenames, char *pattern, char *pattern_percent,
1738                struct dep *deps, unsigned int cmds_started, char *commands,                struct dep *deps, unsigned int cmds_started, char *commands,
1739                unsigned int commands_idx, int two_colon,                unsigned int commands_idx, int two_colon,
1740                int have_sysv_atvar, const struct floc *flocp, int set_default)                const struct floc *flocp, int set_default)
1741  {  {
1742    struct nameseq *nextf;    struct nameseq *nextf;
1743    int implicit = 0;    int implicit = 0;
# Line 1846  record_files (struct nameseq *filenames, Line 1830  record_files (struct nameseq *filenames,
1830                /* We use patsubst_expand to do the work of translating                /* We use patsubst_expand to do the work of translating
1831                   the target pattern, the target's name and the dependencies'                   the target pattern, the target's name and the dependencies'
1832                   patterns into plain dependency names.  */                   patterns into plain dependency names.  */
               char *buffer = variable_expand ("");  
1833    
1834                for (d = this; d != 0; d = d->next)                if (find_percent (this->name) != 0)
1835                  {                  {
1836                    char *o;                    char stem[PATH_MAX];
1837                    char *percent = find_percent (d->name);                    char *o;
1838                    if (percent == 0)                    char *buffer = variable_expand ("");
1839                      continue;  
1840                    o = patsubst_expand (buffer, name, pattern, d->name,                    o = patsubst_expand (buffer, name, pattern, "%",
1841                                         pattern_percent+1, percent+1);                                         pattern_percent + 1, 0);
1842    
1843    
1844                      strncpy (stem, buffer, o - buffer);
1845                      stem[o - buffer] = '\0';
1846    
1847                      o = subst_expand (buffer, this->name, "%", stem,
1848                                        1, strlen (stem), 0);
1849    
1850                    /* If the name expanded to the empty string, that's                    /* If the name expanded to the empty string, that's
1851                       illegal.  */                       illegal.  */
1852                    if (o == buffer)                    if (o == buffer)
1853                      fatal (flocp,                      fatal (flocp,
1854                             _("target `%s' leaves prerequisite pattern empty"),                             _("target `%s' leaves prerequisite pattern empty"),
1855                             name);                             name);
1856                    free (d->name);                    free (this->name);
1857                    d->name = savestring (buffer, o - buffer);                    this->name = savestring (buffer, o - buffer);
1858                  }                  }
1859              }              }
1860          }          }
1861    
       /* If at least one of the dependencies uses $$@ etc. deal with that.  
          It would be very nice and very simple to just expand everything, but  
          it would break a lot of backward compatibility.  Maybe that's OK  
          since we're just emulating a SysV function, and if we do that then  
          why not emulate it completely (that's what SysV make does: it  
          re-expands the entire prerequisite list, all the time, with $@  
          etc. in scope).  But, it would be a pain indeed to document this  
          ("iff you use $$@, your prerequisite lists is expanded twice...")  
          Ouch.  Maybe better to make the code more complex.  */  
   
       if (have_sysv_atvar)  
         {  
           char *p;  
           int tlen = strlen (name);  
           char *fnp = strrchr (name, '/');  
           int dlen;  
           int flen;  
   
           if (fnp)  
             {  
               dlen = fnp - name;  
               ++fnp;  
               flen = strlen (fnp);  
             }  
           else  
             {  
               dlen = 0;  
               fnp = name;  
               flen = tlen;  
             }  
   
   
           for (d = this; d != 0; d = d->next)  
             for (p = strchr (d->name, '$'); p != 0; p = strchr (p+1, '$'))  
               {  
                 char *s = p;  
                 char *at;  
                 int atlen;  
   
                 /* If it's '$@', '$(@', or '${@', it's escaped */  
                 if ((++p)[0] == '$'  
                     && (p[1] == '@'  
                         || ((p[1] == '(' || p[1] == '{') && p[2] == '@')))  
                   {  
                     bcopy (p, s, strlen (p)+1);  
                     continue;  
                   }  
   
                 /* Maybe found one.  We like anything of any form matching @,  
                    [({]@[}):], or [({]@[DF][}):].  */  
   
                 if (! (p[0] == '@'  
                        || ((p[0] == '(' || p[0] == '{') && (++p)[0] == '@'  
                            && (((++p)[0] == ')' || p[0] == '}' || p[0] == ':')  
                                || ((p[1] == ')' || p[1] == '}' || p[1] == ':')  
                                    && (p[0] == 'D' || p[0] == 'F'))))))  
                   continue;  
   
                 /* Found one.  Compute the length and string ptr.  Move p  
                    past the variable reference.  */  
                 switch (p[0])  
                   {  
                   case 'D':  
                     atlen = dlen;  
                     at = name;  
                     p += 2;  
                     break;  
   
                   case 'F':  
                     atlen = flen;  
                     at = fnp;  
                     p += 2;  
                     break;  
   
                   default:  
                     atlen = tlen;  
                     at = name;  
                     ++p;  
                     break;  
                   }  
   
                 /* Get more space.  */  
                 {  
                   int soff = s - d->name;  
                   int poff = p - d->name;  
                   d->name = (char *) xrealloc (d->name,  
                                                strlen (d->name) + atlen + 1);  
                   s = d->name + soff;  
                   p = d->name + poff;  
                 }  
   
                 /* Copy the string over.  */  
                 bcopy(p, s+atlen, strlen (p)+1);  
                 bcopy(at, s, atlen);  
                 p = s + atlen - 1;  
               }  
         }  
   
1862        if (!two_colon)        if (!two_colon)
1863          {          {
1864            /* Single-colon.  Combine these dependencies            /* Single-colon.  Combine these dependencies
# Line 2003  record_files (struct nameseq *filenames, Line 1896  record_files (struct nameseq *filenames,
1896              f->cmds = 0;              f->cmds = 0;
1897            if (cmds != 0)            if (cmds != 0)
1898              f->cmds = cmds;              f->cmds = cmds;
1899    
1900            /* Defining .SUFFIXES with no dependencies            /* Defining .SUFFIXES with no dependencies
1901               clears out the list of suffixes.  */               clears out the list of suffixes.  */
1902            if (f == suffix_file && this == 0)            if (f == suffix_file && this == 0)
# Line 2017  record_files (struct nameseq *filenames, Line 1911  record_files (struct nameseq *filenames,
1911                  }                  }
1912                f->deps = 0;                f->deps = 0;
1913              }              }
1914            else if (f->deps != 0)            else if (this != 0)
1915              {              {
1916                /* Add the file's old deps and the new ones in THIS together.  */                /* Add the file's old deps and the new ones in THIS together.  */
1917    
1918                struct dep *firstdeps, *moredeps;                if (f->deps != 0)
1919                if (cmds != 0)                  {
1920                  {                    struct dep **d_ptr = &f->deps;
                   /* This is the rule with commands, so put its deps first.  
                      The rationale behind this is that $< expands to the  
                      first dep in the chain, and commands use $< expecting  
                      to get the dep that rule specifies.  */  
                   firstdeps = this;  
                   moredeps = f->deps;  
                 }  
               else  
                 {  
                   /* Append the new deps to the old ones.  */  
                   firstdeps = f->deps;  
                   moredeps = this;  
                 }  
1921    
1922                if (firstdeps == 0)                    while ((*d_ptr)->next != 0)
1923                  firstdeps = moredeps;                      d_ptr = &(*d_ptr)->next;
1924                else  
1925                  {                    if (cmds != 0)
1926                    d = firstdeps;                      {
1927                    while (d->next != 0)                        /* This is the rule with commands, so put its deps
1928                      d = d->next;                           last. The rationale behind this is that $< expands
1929                    d->next = moredeps;                           to the first dep in the chain, and commands use $<
1930                  }                           expecting to get the dep that rule specifies.
1931                             However the second expansion algorithm reverses
1932                             the order thus we need to make it last here.  */
1933    
1934                f->deps = firstdeps;                        (*d_ptr)->next = this;
1935                        }
1936                      else
1937                        {
1938                          /* This is the rule without commands. Put its
1939                             dependencies at the end but before dependencies
1940                             from the rule with commands (if any). This way
1941                             everyhting appears in makefile order.  */
1942    
1943                          if (f->cmds != 0)
1944                            {
1945                              this->next = *d_ptr;
1946                              *d_ptr = this;
1947                            }
1948                          else
1949                            (*d_ptr)->next = this;
1950                        }
1951                    }
1952                  else
1953                    f->deps = this;
1954    
1955                  /* This is a hack. I need a way to communicate to snap_deps()
1956                     that the last dependency line in this file came with commands
1957                     (so that logic in snap_deps() can put it in front and all
1958                     this $< -logic works). I cannot's simply rely oon file->cmds
1959                     being not 0 because of the cases like the following:
1960    
1961                     foo: bar
1962                     foo:
1963                         ...
1964    
1965                     I am going to temporarily "borrow" UPDATING member in
1966                     `struct file' for this.   */
1967    
1968                  if (cmds != 0)
1969                    f->updating = 1;
1970              }              }
           else  
             f->deps = this;  
1971    
1972            /* If this is a static pattern rule, set the file's stem to            /* If this is a static pattern rule, set the file's stem to
1973               the part of its name that matched the `%' in the pattern,               the part of its name that matched the `%' in the pattern,
# Line 2135  record_files (struct nameseq *filenames, Line 2051  record_files (struct nameseq *filenames,
2051              }              }
2052    
2053            if (!reject)            if (!reject)
2054              default_goal_file = f;              default_goal_file = f;
2055          }          }
2056      }      }
2057    

Legend:
Removed from v.1.135  
changed lines
  Added in v.1.136

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26