* New feature: .LIBPATTERNS controls the way -lfoo dependencies are expanded.
authorPaul Smith <psmith@gnu.org>
Mon, 22 Feb 1999 07:23:30 +0000 (07:23 +0000)
committerPaul Smith <psmith@gnu.org>
Mon, 22 Feb 1999 07:23:30 +0000 (07:23 +0000)
* A few tweaks to the system glob test, after trying it on a system where
  it's true.
* Installed patches to archive handling for AIX 4.3 big archives.
* Fix a memory stomp in target-specific variables.
* Fix a memory leak in foreach functions.

ChangeLog
NEWS
arscan.c
configure.in
default.c
function.c
make.texinfo
read.c
remake.c
variable.c

index cd2d73b..01108a2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+1999-02-22  Paul D. Smith  <psmith@gnu.org>
+
+       * NEWS: Mention new .LIBPATTERNS feature.
+
+       * make.texinfo (Libraries/Search): Describe the use and
+       ramifications of the new .LIBPATTERNS variable.
+
+       * remake.c (library_search): Instead of searching only for the
+       hardcoded expansion "libX.a" for a library reference "-lX", we
+       obtain a list of patterns from the .LIBPATTERNS variable and
+       search those in order.
+
+       * default.c: Added a new default variable .LIBPATTERNS.  The
+       default for UNIX is "lib%.so lib%.a".  Amiga and DOS values are
+       also provided.
+
+       * read.c: Remove bogus HAVE_GLOB_H references; always include
+       vanilla glob.h.
+
+1999-02-21  Paul D. Smith  <psmith@gnu.org>
+
+       * function.c (expand_function): Set value to 0 to avoid freeing it.
+       * variable.c (pop_variable_scope): Free the value of the variable.
+       (try_variable_definition): For simple variables, use
+       allocated_variable_expand() to avoid stomping on the variable
+       buffer when we still need it for other things.
+
+       * arscan.c: Modified to support AIX 4.3 big archives.  The changes
+       are based on information provided by Phil Adams
+       <padams@austin.ibm.com>; thanks!
+
 1999-02-19  Paul D. Smith  <psmith@gnu.org>
 
        * configure.in: Check to see if the GNU glob library is already
diff --git a/NEWS b/NEWS
index 5bc2974..fcff5f2 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,12 +1,21 @@
 GNU make NEWS                                               -*-indented-text-*-
   History of user-visible changes.
-  19 May 1998
+  22 Feb 1999
 
-Copyright (C) 1992,1993,1994,1995,1996,1997,1998 Free Software Foundation, Inc.
+Copyright (C) 1992,93,94,95,96,97,98,1999 Free Software Foundation, Inc.
 See the end for copying conditions.
 
+All changes mentioned here are more fully described in the GNU make
+manual, which is contained in this distribution as the file make.texinfo.
+
 Please send GNU make bug reports to bug-make@gnu.org.
 \f
+Version 3.78
+
+* Make defines a new variable, .LIBPATTERNS.  This variable controls how
+  the link library dependency expansion (dependencies like ``-lfoo'') is
+  performed.
+\f
 Version 3.77
 
 * Implement BSD make's "?=" variable assignment operator.  The variable
@@ -659,17 +668,14 @@ Version 3.05
 ----------------------------------------------------------------------
 Copyright information:
 
-Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
-
    Permission is granted to anyone to make or distribute verbatim copies
    of this document as received, in any medium, provided that the
-   copyright notice and this permission notice are preserved,
-   thus giving the recipient permission to redistribute in turn.
+   copyright notice and this permission notice are preserved, thus
+   giving the recipient permission to redistribute in turn.
 
-   Permission is granted to distribute modified versions
-   of this document, or of portions of it,
-   under the above conditions, provided also that they
-   carry prominent notices stating who last changed them.
+   Permission is granted to distribute modified versions of this
+   document, or of portions of it, under the above conditions, provided
+   also that they carry prominent notices stating who last changed them.
 \f
 Local variables:
 version-control: never
index 558cc52..09d01ad 100644 (file)
--- a/arscan.c
+++ b/arscan.c
@@ -213,11 +213,28 @@ ar_scan (archive, function, arg)
 #endif
 #endif
 
+/* On AIX, define these symbols to be sure to get both archive formats.
+   AIX 4.3 introduced the "big" archive format to support 64-bit object
+   files, so on AIX 4.3 systems we need to support both the "normal" and
+   "big" archive formats.  An archive's format is indicated in the
+   "fl_magic" field of the "FL_HDR" structure.  For a normal archive,
+   this field will be the string defined by the AIAMAG symbol.  For a
+   "big" archive, it will be the string defined by the AIAMAGBIG symbol
+   (at least on AIX it works this way).
+
+   Note: we'll define these symbols regardless of which AIX version
+   we're compiling on, but this is okay since we'll use the new symbols
+   only if they're present.  */
+#ifdef _AIX
+# define __AR_SMALL__
+# define __AR_BIG__
+#endif
+
 #include <ar.h>
 
 /* Cray's <ar.h> apparently defines this.  */
 #ifndef        AR_HDR_SIZE
-#define        AR_HDR_SIZE     (sizeof (struct ar_hdr))
+# define   AR_HDR_SIZE (sizeof (struct ar_hdr))
 #endif
 \f
 /* Takes three arguments ARCHIVE, FUNCTION and ARG.
@@ -255,6 +272,10 @@ ar_scan (archive, function, arg)
 {
 #ifdef AIAMAG
   FL_HDR fl_header;
+#ifdef AIAMAGBIG
+  int big_archive = 0;
+  FL_HDR_BIG fl_header_big;
+#endif
 #else
   int long_name = 0;
 #endif
@@ -276,11 +297,42 @@ ar_scan (archive, function, arg)
 #ifdef AIAMAG
   {
     register int nread = read (desc, (char *) &fl_header, FL_HSZ);
-    if (nread != FL_HSZ || bcmp (fl_header.fl_magic, AIAMAG, SAIAMAG))
+
+    if (nread != FL_HSZ)
       {
        (void) close (desc);
        return -2;
       }
+#ifdef AIAMAGBIG
+    /* If this is a "big" archive, then set the flag and
+       re-read the header into the "big" structure. */
+    if (!bcmp (fl_header.fl_magic, AIAMAGBIG, SAIAMAG))
+      {
+       big_archive = 1;
+
+       /* seek back to beginning of archive */
+       if (lseek (desc, 0, 0) < 0)
+         {
+           (void) close (desc);
+           return -2;
+         }
+
+       /* re-read the header into the "big" structure */
+       nread = read (desc, (char *) &fl_header_big, FL_HSZ_BIG);
+       if (nread != FL_HSZ_BIG)
+         {
+           (void) close (desc);
+           return -2;
+         }
+      }
+    else
+#endif
+       /* Check to make sure this is a "normal" archive. */
+      if (bcmp (fl_header.fl_magic, AIAMAG, SAIAMAG))
+       {
+          (void) close (desc);
+          return -2;
+       }
   }
 #else
   {
@@ -308,8 +360,18 @@ ar_scan (archive, function, arg)
     long int member_offset;
     long int last_member_offset;
 
-    sscanf (fl_header.fl_fstmoff, "%12ld", &member_offset);
-    sscanf (fl_header.fl_lstmoff, "%12ld", &last_member_offset);
+#ifdef AIAMAGBIG
+    if ( big_archive )
+      {
+       sscanf (fl_header_big.fl_fstmoff, "%20ld", &member_offset);
+       sscanf (fl_header_big.fl_lstmoff, "%20ld", &last_member_offset);
+      }
+    else
+#endif
+      {
+       sscanf (fl_header.fl_fstmoff, "%12ld", &member_offset);
+       sscanf (fl_header.fl_lstmoff, "%12ld", &last_member_offset);
+      }
 
     if (member_offset == 0)
       {
@@ -330,6 +392,9 @@ ar_scan (archive, function, arg)
       {
        register int nread;
        struct ar_hdr member_header;
+#ifdef AIAMAGBIG
+       struct ar_hdr_big member_header_big;
+#endif
 #ifdef AIAMAG
        char name[256];
        int name_len;
@@ -352,34 +417,73 @@ ar_scan (archive, function, arg)
          }
 
 #ifdef AIAMAG
-#define        AR_MEMHDR       (AR_HDR_SIZE - sizeof (member_header._ar_name))
-       nread = read (desc, (char *) &member_header, AR_MEMHDR);
+#define       AR_MEMHDR_SZ(x) (sizeof(x) - sizeof (x._ar_name))
 
-       if (nread != AR_MEMHDR)
+#ifdef AIAMAGBIG
+       if (big_archive)
          {
-           (void) close (desc);
-           return -2;
+           nread = read (desc, (char *) &member_header_big,
+                         AR_MEMHDR_SZ(member_header_big) );
+
+           if (nread != AR_MEMHDR_SZ(member_header_big))
+             {
+               (void) close (desc);
+               return -2;
+             }
+
+           sscanf (member_header_big.ar_namlen, "%4d", &name_len);
+           nread = read (desc, name, name_len);
+
+           if (nread != name_len)
+             {
+               (void) close (desc);
+               return -2;
+             }
+
+           name[name_len] = 0;
+
+           sscanf (member_header_big.ar_date, "%12ld", &dateval);
+           sscanf (member_header_big.ar_uid, "%12d", &uidval);
+           sscanf (member_header_big.ar_gid, "%12d", &gidval);
+           sscanf (member_header_big.ar_mode, "%12o", &eltmode);
+           sscanf (member_header_big.ar_size, "%20ld", &eltsize);
+
+           data_offset = (member_offset + AR_MEMHDR_SZ(member_header_big)
+                          + name_len + 2);
          }
-
-       sscanf (member_header.ar_namlen, "%4d", &name_len);
-       nread = read (desc, name, name_len);
-
-       if (nread != name_len)
+       else
+#endif
          {
-           (void) close (desc);
-           return -2;
+           nread = read (desc, (char *) &member_header,
+                         AR_MEMHDR_SZ(member_header) );
+
+           if (nread != AR_MEMHDR_SZ(member_header))
+             {
+               (void) close (desc);
+               return -2;
+             }
+
+           sscanf (member_header.ar_namlen, "%4d", &name_len);
+           nread = read (desc, name, name_len);
+
+           if (nread != name_len)
+             {
+               (void) close (desc);
+               return -2;
+             }
+
+           name[name_len] = 0;
+
+           sscanf (member_header.ar_date, "%12ld", &dateval);
+           sscanf (member_header.ar_uid, "%12d", &uidval);
+           sscanf (member_header.ar_gid, "%12d", &gidval);
+           sscanf (member_header.ar_mode, "%12o", &eltmode);
+           sscanf (member_header.ar_size, "%12ld", &eltsize);
+
+           data_offset = (member_offset + AR_MEMHDR_SZ(member_header)
+                          + name_len + 2);
          }
-
-       name[name_len] = 0;
-
-       sscanf (member_header.ar_date, "%12ld", &dateval);
-       sscanf (member_header.ar_uid, "%12d", &uidval);
-       sscanf (member_header.ar_gid, "%12d", &gidval);
-       sscanf (member_header.ar_mode, "%12o", &eltmode);
-       sscanf (member_header.ar_size, "%12ld", &eltsize);
-
-       if ((data_offset = member_offset + AR_MEMHDR + name_len + 2) % 2)
-           ++data_offset;
+       data_offset += data_offset % 2;
 
        fnval =
          (*function) (desc, name, 0,
@@ -493,7 +597,12 @@ ar_scan (archive, function, arg)
          /* End of the chain.  */
          break;
 
-       sscanf (member_header.ar_nxtmem, "%12ld", &member_offset);
+#ifdef AIAMAGBIG
+       if (big_archive)
+          sscanf (member_header_big.ar_nxtmem, "%20ld", &member_offset);
+       else
+#endif
+         sscanf (member_header.ar_nxtmem, "%12ld", &member_offset);
 
        if (lseek (desc, member_offset, 0) != member_offset)
          {
@@ -562,37 +671,6 @@ ar_name_equal (name, mem, truncated)
   if (p != 0)
     name = p + 1;
 
-  /* We no longer use this kludge, since we
-     now support long archive member names.  */
-
-#if 0 && !defined (AIAMAG) && !defined (APOLLO)
-
-  {
-    /* `reallylongname.o' matches `reallylongnam.o'.
-       If member names have a trailing slash, that's `reallylongna.o'.  */
-
-    struct ar_hdr h;
-    unsigned int max = sizeof (h.ar_name);
-    unsigned int namelen, memlen;
-
-    if (strncmp (name, mem, max - 3))
-      return 0;
-
-    namelen = strlen (name);
-    memlen = strlen (mem);
-
-    if (namelen > memlen && memlen >= max - 1
-       && name[namelen - 2] == '.' && name[namelen - 1] == 'o'
-       && mem[memlen - 2] == '.' && mem[memlen - 1] == 'o')
-      return 1;
-
-    if (namelen != memlen)
-      return 0;
-
-    return (namelen < max - 3 || !strcmp (name + max - 3, mem + max - 3));
-  }
-
-#else  /* AIX or APOLLO.  */
 #ifndef VMS
   if (truncated)
     {
@@ -611,8 +689,6 @@ ar_name_equal (name, mem, truncated)
 #endif /* !VMS */
 
   return !strcmp (name, mem);
-
-#endif
 }
 \f
 #ifndef VMS
index be51781..bc72d7d 100644 (file)
@@ -154,17 +154,20 @@ rm -f s.conftest conftoast
 AC_MSG_CHECKING(if system libc has GNU glob)
 AC_CACHE_VAL(make_cv_sys_gnu_glob, [
  AC_TRY_CPP([
+#include <features.h>
 #include <glob.h>
 #include <fnmatch.h>
 
 #define GLOB_INTERFACE_VERSION 1
-#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
+#if defined _LIBC || !defined __GNU_LIBRARY__ || __GNU_LIBRARY__ <= 1
+# error no gnu glob
+#else
 # include <gnu-versions.h>
-# if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION
-#  error have gnu glob
+# if _GNU_GLOB_INTERFACE_VERSION != GLOB_INTERFACE_VERSION
+#  error no gnu glob
 # endif
 #endif
- ], make_cv_sys_gnu_glob=no, make_cv_sys_gnu_glob=yes)])
+ ], make_cv_sys_gnu_glob=yes, make_cv_sys_gnu_glob=no)])
 case "$make_cv_sys_gnu_glob" in
   yes) AC_MSG_RESULT(yes) ;;
   no)  AC_MSG_RESULT([no; using local copy])
index 06f56fa..76a3232 100644 (file)
--- a/default.c
+++ b/default.c
@@ -425,6 +425,16 @@ static char *default_variables[] =
     "SCCS_OUTPUT_OPTION", "-G$@",
 #endif
 
+#ifdef _AMIGA
+    ".LIBPATTERNS", "%.lib",
+#else
+#ifdef __MSDOS__
+    ".LIBPATTERNS", "lib%.a $(DJDIR)/lib/lib%.a",
+#else
+    ".LIBPATTERNS", "lib%.so lib%.a",
+#endif
+#endif
+
 #endif /* !VMS */
     0, 0
   };
index 13196eb..a04a467 100644 (file)
@@ -876,6 +876,7 @@ expand_function (o, function, text, end)
          /* Kill the last space.  */
          --o;
 
+       v->value = 0;
        pop_variable_scope ();
 
        free (var);
index e7b3bbf..246707c 100644 (file)
@@ -1971,16 +1971,19 @@ directory search with no extra effort.
 @cindex @code{VPATH}, and link libraries
 @cindex search path for dependencies (@code{VPATH}), and link libraries
 @cindex @code{-l} (library search)
+@cindex link libraries, patterns matching
+@cindex @code{.LIBPATTERNS}, and link libraries
+@vindex .LIBPATTERNS
 
 Directory search applies in a special way to libraries used with the
 linker.  This special feature comes into play when you write a dependency
 whose name is of the form @samp{-l@var{name}}.  (You can tell something
 strange is going on here because the dependency is normally the name of a
-file, and the @emph{file name} of the library looks like
+file, and the @emph{file name} of a library generally looks like
 @file{lib@var{name}.a}, not like @samp{-l@var{name}}.)@refill
 
 When a dependency's name has the form @samp{-l@var{name}}, @code{make}
-handles it specially by searching for the file @file{lib@var{name}.a} in
+handles it specially by searching for the file @file{lib@var{name}.so} in
 the current directory, in directories specified by matching @code{vpath}
 search paths and the @code{VPATH} search path, and then in the
 directories @file{/lib}, @file{/usr/lib}, and @file{@var{prefix}/lib}
@@ -1988,7 +1991,11 @@ directories @file{/lib}, @file{/usr/lib}, and @file{@var{prefix}/lib}
 @code{make} behave as if @var{prefix} is defined to be the root of the
 DJGPP installation tree).
 
-For example,
+If that file is not found, then the file @file{lib@var{name}.a} is
+searched for, in the same directories as above.
+
+For example, if there is a @file{/usr/lib/libcurses.a} library on your
+system (and no @file{/usr/lib/libcurses.so} file), then
 
 @example
 @group
@@ -2002,6 +2009,21 @@ would cause the command @samp{cc foo.c /usr/lib/libcurses.a -o foo} to
 be executed when @file{foo} is older than @file{foo.c} or than
 @file{/usr/lib/libcurses.a}.@refill
 
+Although the default set of files to be searched for is
+@file{lib@var{name}.so} and @file{lib@var{name}.a}, this is customizable
+via the @code{.LIBPATTERNS} variable.  Each word in the value of this
+variable is a pattern string.  When a dependency like
+@samp{-l@var{name}} is seen, @code{make} will replace the percent in
+each pattern in the list with @var{name} and perform the above directory
+searches using that library filename.  If no library is found, the next
+word in the list will be used.
+
+The default value for @code{.LIBPATTERNS} is ``@samp{lib%.so lib%.a}'',
+which provides the default behavior described above.
+
+You can turn off link library expansion completely by setting this
+variable to an empty value.
+
 @node Phony Targets, Force Targets, Directory Search, Rules
 @section Phony Targets
 @cindex phony targets
diff --git a/read.c b/read.c
index b5efca2..3303ba9 100644 (file)
--- a/read.c
+++ b/read.c
@@ -18,6 +18,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include <assert.h>
 
+#include <glob.h>
+
 #include "make.h"
 #include "dep.h"
 #include "filedef.h"
@@ -26,12 +28,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "variable.h"
 #include "rule.h"
 
-/* This is POSIX.2, but most systems using -DPOSIX probably don't have it.  */
-#ifdef HAVE_GLOB_H
-#include <glob.h>
-#else
-#include "glob/glob.h"
-#endif
 
 #ifndef WINDOWS32
 #ifndef _AMIGA
@@ -1564,9 +1560,7 @@ record_files (filenames, pattern, pattern_percent, deps, cmds_started,
        if (!pattern_matches (pattern, pattern_percent, name))
          {
            /* Give a warning if the rule is meaningless.  */
-           error (flocp,
-                           "target `%s' doesn't match the target pattern",
-                           name);
+           error (flocp,"target `%s' doesn't match the target pattern", name);
            this = 0;
          }
        else
index d312321..fdd868a 100644 (file)
--- a/remake.c
+++ b/remake.c
@@ -21,6 +21,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "job.h"
 #include "commands.h"
 #include "dep.h"
+#include "variable.h"
+
 #include <assert.h>
 
 #ifdef HAVE_FCNTL_H
@@ -1188,82 +1190,111 @@ library_search (lib, mtime_ptr)
       0
     };
 
+  static char *libpatterns = NULL;
+
   char *libname = &(*lib)[2];  /* Name without the `-l'.  */
   FILE_TIMESTAMP mtime;
 
-  /* Buffer to construct possible names in.  */
-  char *buf = xmalloc (sizeof (LIBDIR) + 8 + strlen (libname) + 4 + 2 + 1);
-  char *file, **dp;
+  /* Loop variables for the libpatterns value.  */
+  char *p, *p2;
+  int len;
 
-  /* Look first for `libNAME.a' in the current directory.  */
+  char *file, **dp;
 
-#ifndef _AMIGA
-  sprintf (buf, "lib%s.a", libname);
-#else
-  sprintf (buf, "%s.lib", libname);
-#endif
-  mtime = name_mtime (buf);
-  if (mtime != (FILE_TIMESTAMP) -1)
+  /* If we don't have libpatterns, get it.  */
+  if (!libpatterns)
     {
-      *lib = buf;
-      if (mtime_ptr != 0)
-       *mtime_ptr = mtime;
-      return 1;
-    }
+      int save = warn_undefined_variables_flag;
+      warn_undefined_variables_flag = 0;
 
-  /* Now try VPATH search on that.  */
+      libpatterns = strdup (variable_expand ("$(strip $(.LIBPATTERNS))"));
 
-  file = buf;
-  if (vpath_search (&file, mtime_ptr))
-    {
-      free (buf);
-      *lib = file;
-      return 1;
+      warn_undefined_variables_flag = save;
     }
 
-  /* Now try the standard set of directories.  */
-
-#ifdef  __MSDOS__
-  {
-    /* The default library directory is at ${DJDIR}/lib.  */
-    struct variable *djdir = lookup_variable ("DJDIR", 5);
+  /* Loop through all the patterns in .LIBPATTERNS, and search on each one.  */
+  p2 = libpatterns;
+  while ((p = find_next_token (&p2, &len)) != 0)
+    {
+      static char *buf = NULL;
+      static int buflen = 0;
+      static int libdir_maxlen = -1;
+      char *libbuf = variable_expand ("");
 
-    if (djdir)
+      /* Expand the pattern using LIBNAME as a replacement.  */
       {
-       size_t djdir_len = strlen (djdir->value);
+       char c = p[len];
+       char *p3, *p4;
 
-       if (djdir_len > sizeof(LIBDIR) + 8 + strlen(libname) + 4 + 2)
-         buf = (char *) xrealloc (djdir_len + 1);
-       sprintf (buf, "%s/lib/lib%s.a", djdir->value, libname);
-       mtime = name_mtime (buf);
-       if (mtime != (FILE_TIMESTAMP) -1)
+       p[len] = '\0';
+       p3 = find_percent (p);
+       if (!p3)
          {
-           *lib = buf;
-           if (mtime_ptr != 0)
-             *mtime_ptr = mtime;
-           return 1;
+           /* Give a warning if there is no pattern, then remove the
+              pattern so it's ignored next time.  */
+           error (NILF, ".LIBPATTERNS element `%s' is not a pattern", p);
+           for (; len; --len, ++p)
+             *p = ' ';
+           *p = c;
+           continue;
          }
+       p4 = variable_buffer_output (libbuf, p, p3-p);
+       p4 = variable_buffer_output (p4, libname, strlen (libname));
+       p4 = variable_buffer_output (p4, p3+1, len - (p3-p));
+       p[len] = c;
       }
-  }
-#endif
 
-  for (dp = dirs; *dp != 0; ++dp)
-    {
-#ifndef _AMIGA
-      sprintf (buf, "%s/lib%s.a", *dp, libname);
-#else
-      sprintf (buf, "%s/%s.lib", *dp, libname);
-#endif
-      mtime = name_mtime (buf);
+      /* Look first for `libNAME.a' in the current directory.  */
+      mtime = name_mtime (libbuf);
       if (mtime != (FILE_TIMESTAMP) -1)
        {
-         *lib = buf;
+         *lib = strdup (libbuf);
          if (mtime_ptr != 0)
            *mtime_ptr = mtime;
          return 1;
        }
+
+      /* Now try VPATH search on that.  */
+
+      file = libbuf;
+      if (vpath_search (&file, mtime_ptr))
+       {
+         *lib = file;
+         return 1;
+       }
+
+      /* Now try the standard set of directories.  */
+
+      if (!buflen)
+       {
+         for (dp = dirs; *dp != 0; ++dp)
+           {
+             int l = strlen (*dp);
+             if (l > libdir_maxlen)
+               libdir_maxlen = l;
+           }
+         buflen = strlen (libbuf);
+         buf = xmalloc(libdir_maxlen + buflen + 2);
+       }
+      else if (buflen < strlen (libbuf))
+       {
+         buflen = strlen (libbuf);
+         buf = xrealloc (buf, libdir_maxlen + buflen + 2);
+       }
+
+      for (dp = dirs; *dp != 0; ++dp)
+       {
+         sprintf (buf, "%s/%s", *dp, libbuf);
+         mtime = name_mtime (buf);
+         if (mtime != (FILE_TIMESTAMP) -1)
+           {
+             *lib = strdup (buf);
+             if (mtime_ptr != 0)
+               *mtime_ptr = mtime;
+             return 1;
+           }
+       }
     }
 
-  free (buf);
   return 0;
 }
index 85987db..648f82b 100644 (file)
@@ -265,6 +265,8 @@ pop_variable_scope ()
          next = v->next;
 
          free (v->name);
+         if (v->value)
+           free (v->value);
          free ((char *) v);
        }
     }
@@ -687,7 +689,7 @@ try_variable_definition (flocp, line, origin)
   register char *end;
   enum { f_bogus,
          f_simple, f_recursive, f_append, f_conditional } flavor = f_bogus;
-  char *name, *expanded_name, *value;
+  char *name, *expanded_name, *value, *alloc_value=NULL;
   struct variable *v;
 
   while (1)
@@ -775,8 +777,11 @@ try_variable_definition (flocp, line, origin)
       /* Should not be possible.  */
       abort ();
     case f_simple:
-      /* A simple variable definition "var := value".  Expand the value.  */
-      value = variable_expand (p);
+      /* A simple variable definition "var := value".  Expand the value.
+         We have to allocate memory since otherwise it'll clobber the
+        variable buffer, and we still need that.  */
+      alloc_value = allocated_variable_expand (p);
+      value = alloc_value;
       break;
     case f_conditional:
       /* A conditional variable definition "var ?= value".
@@ -931,6 +936,8 @@ try_variable_definition (flocp, line, origin)
   v = define_variable (expanded_name, strlen (expanded_name),
                       value, origin, flavor == f_recursive);
 
+  if (alloc_value)
+    free (alloc_value);
   free (expanded_name);
 
   return v;