]> git.ipfire.org Git - thirdparty/libtool.git/commitdiff
* ltdl.m4: Bump serial number.
authorGary V. Vaughan <gary@gnu.org>
Wed, 1 Aug 2001 06:50:16 +0000 (06:50 +0000)
committerGary V. Vaughan <gary@gnu.org>
Wed, 1 Aug 2001 06:50:16 +0000 (06:50 +0000)
General reformat and tify up in line with Autoconf-2.50 support.
(AC_LTDL_FUNC_ARGZ): Test for system implementations of a
handful of argz API calls, the error_t type, and the argz.h
header.
* libltdl/configure.ac (AM_INIT_AUTOMAKE): Bump version number.
* libltdl/ltdl.c (rpl_argz_append, rpl_argz_create_sep.
rpl_argz_insert, rpl_rgz_next):  Fallback implementations of
the similarly named functions for machines that don;t use glibc.
(lt_dlrealloc):  New memory function pointer that can be set by
the client.  Defaults to rpl_realloc, which in turn uses only
lt_dlmalloc and lt_dlfree.
(LT_EMALLOC, LT_EREALLOC): Set internal out-of-memory error
inside the functions called by these new macros.  Simplified all
callers by removing explicit client error reporting.
(memmove):  Fallback implementation of overlap safe memory copy
function.
(tryall_dlopen):  Factorized common code into...
(tryall_dlopen_module): ...this new helper function.
(canonicalize_path):  Changed function signature to return success
or failure.  Updated all callers.
(foreachfile_callback):  Make use of argz API.
(LT_DLSTRLEN): Moved from here...
* libltdl/ltdl.h (LT_STRLEN): ...to here.  Updated all callers.
(lt_dlrealloc):  Declare new memory management handle.

ChangeLog
libltdl/configure.ac
libltdl/ltdl.c
libltdl/ltdl.h
ltdl.m4

index 016356b5d013d769cf6023a01e9d62638a6aea8c..12b979370890b067df445e0f03cd9d80b918db23 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,37 @@
+2001-08-01  Gary V. Vaughan  <gary@gnu.org>
+
+       * ltdl.m4: Bump serial number.
+       General reformat and tify up in line with Autoconf-2.50 support.
+       (AC_LTDL_FUNC_ARGZ): Test for system implementations of a
+       handful of argz API calls, the error_t type, and the argz.h
+       header.
+       * libltdl/configure.ac (AM_INIT_AUTOMAKE): Bump version number.
+       * libltdl/ltdl.c (rpl_argz_append, rpl_argz_create_sep.
+       rpl_argz_insert, rpl_rgz_next):  Fallback implementations of
+       the similarly named functions for machines that don;t use glibc.
+       (lt_dlrealloc):  New memory function pointer that can be set by
+       the client.  Defaults to rpl_realloc, which in turn uses only
+       lt_dlmalloc and lt_dlfree.
+       (LT_EMALLOC, LT_EREALLOC): Set internal out-of-memory error
+       inside the functions called by these new macros.  Simplified all
+       callers by removing explicit client error reporting.
+       (memmove):  Fallback implementation of overlap safe memory copy
+       function.
+       (tryall_dlopen):  Factorized common code into...
+       (tryall_dlopen_module): ...this new helper function.
+       (canonicalize_path):  Changed function signature to return success
+       or failure.  Updated all callers.
+       (foreachfile_callback):  Make use of argz API.
+       (LT_DLSTRLEN): Moved from here...
+       * libltdl/ltdl.h (LT_STRLEN): ...to here.  Updated all callers.
+       (lt_dlrealloc):  Declare new memory management handle.
+
 2001-07-31  Robert Boehne  <rboehne@ricardo-us.com>
 
        * libtool.m4 (mingw*) Revert the previous change as it was
        applied by mistake.
 
-2001-07-31  Guido Draheim  <guidod-2001q3@gmx.de>
+2001-07-31  Guido Draheim  <Guido.Draheim@tek.com>
 
        * libtool.m4 (mingw*) sys_lib_search_path_spec:
        Sets the proper path separator for cross-compiling.
index 3af0a75c2e51327634c794d09ef8a8a13cd23198..125d883e420d01185186ea241c623abf6ce69797 100644 (file)
@@ -23,7 +23,7 @@ if test -z "$enable_ltdl_install$enable_ltdl_convenience"; then
   fi
 fi
 
-AM_INIT_AUTOMAKE(libltdl,1.1,-)
+AM_INIT_AUTOMAKE(libltdl,1.2,-)
 AM_CONFIG_HEADER(config.h:config-h.in)
 AM_MAINTAINER_MODE
 
@@ -32,7 +32,7 @@ AC_C_CONST
 AC_C_INLINE
 
 AC_LIBTOOL_WIN32_DLL
-AM_PROG_LIBTOOL
+AC_PROG_LIBTOOL
 AC_SUBST(LIBTOOL_DEPS)
 
 AC_LIB_LTDL
index e75fc57e95aad78c2c9056c3dc1777ddfa216465..f4f2ccc03f567636075320b48af369d76f6836ef 100644 (file)
@@ -57,6 +57,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 #  include <memory.h>
 #endif
 
+#if HAVE_ERRNO_H
+#  include <errno.h>
+#endif
+
 #if HAVE_DIRENT_H
 #  include <dirent.h>
 #  define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name))
@@ -74,9 +78,14 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 #  endif
 #endif
 
-#include "ltdl.h"
+#if HAVE_ARGZ_H
+#  include <argz.h>
+#endif
 
-#define LT_DLSTRLEN(s) (((s) && (s)[0]) ? strlen (s) : 0)
+/* I have never seen a system without this:  */
+#include <assert.h>
+
+#include "ltdl.h"
 
 
 
@@ -113,9 +122,478 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 #undef LT_SYMBOL_LENGTH
 #define LT_SYMBOL_LENGTH       128
 
-/* This accounts for the _LTX_ separator */
-#undef LT_SYMBOL_OVERHEAD
-#define LT_SYMBOL_OVERHEAD     5
+/* This accounts for the _LTX_ separator */
+#undef LT_SYMBOL_OVERHEAD
+#define LT_SYMBOL_OVERHEAD     5
+
+
+
+\f
+/* --- MEMORY HANDLING --- */
+
+
+/* These are the functions used internally.  In addition to making
+   use of the associated function pointers above, they also perform
+   error handling.  */
+static char   *lt_estrdup      LT_PARAMS((const char *str));
+static lt_ptr lt_emalloc       LT_PARAMS((size_t size));
+static lt_ptr lt_erealloc      LT_PARAMS((lt_ptr addr, size_t size));
+
+static lt_ptr rpl_realloc      LT_PARAMS((lt_ptr ptr, size_t size));
+
+/* These are the pointers that can be changed by the caller:  */
+LT_GLOBAL_DATA lt_ptr (*lt_dlmalloc)   LT_PARAMS((size_t size))
+                       = (lt_ptr (*) LT_PARAMS((size_t))) malloc;
+LT_GLOBAL_DATA lt_ptr (*lt_dlrealloc)  LT_PARAMS((lt_ptr ptr, size_t size))
+                       = (lt_ptr (*) LT_PARAMS((lt_ptr, size_t))) rpl_realloc;
+LT_GLOBAL_DATA void   (*lt_dlfree)     LT_PARAMS((lt_ptr ptr))
+                       = (void (*) LT_PARAMS((lt_ptr))) free;
+
+/* The following macros reduce the amount of typing needed to cast
+   assigned memory.  */
+#define LT_DLMALLOC(tp, n)     ((tp *) lt_dlmalloc ((n) * sizeof(tp)))
+#define LT_DLREALLOC(tp, p, n) ((tp *) rpl_realloc ((p), (n) * sizeof(tp)))
+#define LT_DLFREE(p)                                           \
+       LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END
+
+#define LT_EMALLOC(tp, n)      ((tp *) lt_emalloc ((n) * sizeof(tp)))
+#define LT_EREALLOC(tp, p, n)  ((tp *) lt_erealloc ((p), (n) * sizeof(tp)))
+
+#define LT_DLMEM_REASSIGN(p, q)                        LT_STMT_START { \
+       if ((p) != (q)) { lt_dlfree (p); (p) = (q); (q) = 0; }  \
+                                               } LT_STMT_END
+
+\f
+/* --- REPLACEMENT FUNCTIONS --- */
+
+
+#undef strdup
+#define strdup rpl_strdup
+
+static char *strdup LT_PARAMS((const char *str));
+
+char *
+strdup(str)
+     const char *str;
+{
+  char *tmp = 0;
+
+  if (str)
+    {
+      tmp = LT_DLMALLOC (char, 1+ strlen (str));
+      if (tmp)
+       {
+         strcpy(tmp, str);
+       }
+    }
+
+  return tmp;
+}
+
+
+#if ! HAVE_STRCMP
+
+#undef strcmp
+#define strcmp rpl_strcmp
+
+static int strcmp LT_PARAMS((const char *str1, const char *str2));
+
+int
+strcmp (str1, str2)
+     const char *str1;
+     const char *str2;
+{
+  if (str1 == str2)
+    return 0;
+  if (str1 == 0)
+    return -1;
+  if (str2 == 0)
+    return 1;
+
+  for (;*str1 && *str2; ++str1, ++str2)
+    {
+      if (*str1 != *str2)
+       break;
+    }
+
+  return (int)(*str1 - *str2);
+}
+#endif
+
+
+#if ! HAVE_STRCHR
+
+#  if HAVE_INDEX
+#    define strchr index
+#  else
+#    define strchr rpl_strchr
+
+static const char *strchr LT_PARAMS((const char *str, int ch));
+
+const char*
+strchr(str, ch)
+     const char *str;
+     int ch;
+{
+  const char *p;
+
+  for (p = str; *p != (char)ch && *p != LT_EOS_CHAR; ++p)
+    /*NOWORK*/;
+
+  return (*p == (char)ch) ? p : 0;
+}
+
+#  endif
+#endif /* !HAVE_STRCHR */
+
+
+#if ! HAVE_STRRCHR
+
+#  if HAVE_RINDEX
+#    define strrchr rindex
+#  else
+#    define strrchr rpl_strrchr
+
+static const char *strrchr LT_PARAMS((const char *str, int ch));
+
+const char*
+strrchr(str, ch)
+     const char *str;
+     int ch;
+{
+  const char *p, *q = 0;
+
+  for (p = str; *p != LT_EOS_CHAR; ++p)
+    {
+      if (*p == (char) ch)
+       {
+         q = p;
+       }
+    }
+
+  return q;
+}
+
+# endif
+#endif
+
+/* NOTE:  Neither bcopy nor the memcpy implementation below can
+          reliably handle copying in overlapping areas of memory.  Use
+          memmove (for which there is a fallback implmentation below)
+         if you need that behaviour.  */
+#if ! HAVE_MEMCPY
+
+#  if HAVE_BCOPY
+#    define memcpy(dest, src, size)    bcopy (src, dest, size)
+#  else
+#    define memcpy rpl_memcpy
+
+static lt_ptr memcpy LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
+
+lt_ptr
+memcpy (dest, src, size)
+     lt_ptr dest;
+     const lt_ptr src;
+     size_t size;
+{
+  size_t i = 0;
+
+  for (i = 0; i < size; ++i)
+    {
+      dest[i] = src[i];
+    }
+
+  return dest;
+}
+
+#  endif /* !HAVE_BCOPY */
+#endif   /* !HAVE_MEMCPY */
+
+#if ! HAVE_MEMMOVE
+#  define memmove rpl_memmove
+
+static lt_ptr memmove LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size));
+
+lt_ptr
+memmove (dest, src, size)
+     lt_ptr dest;
+     const lt_ptr src;
+     size_t size;
+{
+  size_t i;
+
+  if (dest < src)
+    for (i = 0; i < size; ++i)
+      {
+       dest[i] = src[i];
+      }
+  else if (dest > src)
+    for (i = size -1; i >= 0; --i)
+      {
+       dest[i] = src[i];
+      }
+
+  return dest;
+}
+
+#endif /* !HAVE_MEMMOVE */
+
+
+/* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>,
+    ``realloc is not entirely portable''
+   In any case we want to use the allocator supplied by the user without
+   burdening them with an lt_dlrealloc function pointer to maintain.
+   Instead implement our own version (with known boundary conditions)
+   using lt_dlmalloc and lt_dlfree. */
+
+#undef realloc
+#define realloc rpl_realloc
+
+lt_ptr
+realloc (ptr, size)
+     lt_ptr ptr;
+     size_t size;
+{
+  if (size <= 0)
+    {
+      /* For zero or less bytes, free the original memory */
+      if (ptr != 0)
+       {
+         lt_dlfree (ptr);
+       }
+
+      return (lt_ptr) 0;
+    }
+  else if (ptr == 0)
+    {
+      /* Allow reallocation of a NULL pointer.  */
+      return lt_dlmalloc (size);
+    }
+  else
+    {
+      /* Allocate a new block, copy and free the old block.  */
+      lt_ptr mem = lt_dlmalloc (size);
+
+      if (mem)
+       {
+         memcpy (mem, ptr, size);
+         lt_dlfree (ptr);
+       }
+
+      /* Note that the contents of PTR are not damaged if there is
+        insufficient memory to realloc.  */
+      return mem;
+    }
+}
+
+
+#if ! HAVE_ARGZ_APPEND
+#  define argz_append rpl_argz_append
+
+static error_t argz_append LT_PARAMS((char **pargz, size_t *pargz_len,
+                                       const char *buf, size_t buf_len));
+
+error_t
+argz_append (pargz, pargz_len, buf, buf_len)
+     char **pargz;
+     size_t *pargz_len;
+     const char *buf;
+     size_t buf_len;
+{
+  size_t argz_len;
+  char  *argz;
+
+  assert (pargz);
+  assert (pargz_len);
+  assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len));
+  
+  /* If nothing needs to be appended, no more work is required.  */
+  if (buf_len == 0)
+    return 0;
+
+  /* Ensure there is enough room to append BUF_LEN.  */
+  argz_len = *pargz_len + buf_len;
+  argz = LT_DLREALLOC (char, *pargz, argz_len);
+  if (!argz)
+    return ENOMEM;
+  
+  /* Copy characters from BUF after terminating '\0' in ARGZ.  */
+  memcpy (argz + *pargz_len, buf, buf_len);
+
+  /* Assign new values.  */
+  *pargz = argz;
+  *pargz_len = argz_len;
+
+  return 0;
+}
+#endif /* !HAVE_ARGZ_APPEND */
+
+
+#if ! HAVE_ARGZ_CREATE_SEP
+#  define argz_create_sep rpl_argz_create_sep
+
+static error_t argz_create_sep LT_PARAMS((const char *str, int delim,
+                                           char **pargz, size_t *pargz_len));
+
+error_t
+argz_create_sep (str, delim, pargz, pargz_len)
+     const char *str;
+     int delim;
+     char **pargz;
+     size_t *pargz_len;
+{
+  size_t argz_len;
+  char *argz = 0;
+
+  assert (str);
+  assert (pargz);
+  assert (pargz_len);
+
+  /* Make a copy of STR, but replacing each occurence of
+     DELIM with '\0'.  */
+  argz_len = LT_STRLEN (str);
+  if (argz_len)
+    {
+      const char *p;
+      char *q;
+
+      argz = LT_DLMALLOC (char, 1+ argz_len);
+      if (!argz)
+       return ENOMEM;
+
+      for (p = str, q = argz; *p != LT_EOS_CHAR; ++p)
+       {
+         if (*p == delim)
+           {
+             /* Ignore leading delimiters, and fold consecutive
+                delimiters in STR into a single '\0' in ARGZ.  */
+             if ((q > argz) && (q[-1] != LT_EOS_CHAR))
+               *q++ = LT_EOS_CHAR;
+             else
+               --argz_len;
+           }
+         else
+           *q++ = *p;
+       }
+    }
+
+  /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory.  */
+  if (!argz_len)
+    LT_DLFREE (argz);
+      
+  /* Assign new values.  */
+  *pargz = argz;
+  *pargz_len = argz_len;
+
+  return 0;
+}
+#endif /* !HAVE_ARGZ_CREATE_SEP */
+
+
+#if ! HAVE_ARGZ_INSERT
+#  define argz_insert rpl_argz_insert
+
+static error_t argz_insert LT_PARAMS((char **pargz, size_t *pargz_len,
+                                       char *before, const char *entry));
+
+error_t
+argz_insert (pargz, pargz_len, before, entry)
+     char **pargz;
+     size_t *pargz_len;
+     char *before;
+     const char *entry;
+{
+  assert (pargz);
+  assert (pargz_len);
+  assert (entry && *entry);
+
+  /* Either PARGZ/PARGZ_LEN is empty and BEFORE is NULL,
+     or BEFORE points into an address within the ARGZ vector.  */
+  assert ((!*pargz && !*pargz_len && !before)
+         || ((*pargz <= before) && (before < (*pargz + *pargz_len))));
+
+  /* No BEFORE address indicates ENTRY should be inserted after the
+     current last element.  */
+  if (!before)
+    return argz_append (pargz, pargz_len, entry, 1+ LT_STRLEN (entry));
+
+  /* This probably indicates a programmer error, but to preserve
+     semantics, scan back to the start of an entry if BEFORE points
+     into the middle of it.  */
+  while ((before >= *pargz) && (before[-1] != LT_EOS_CHAR))
+    --before;
+
+  {
+    size_t entry_len   = 1+ LT_STRLEN (entry);
+    size_t argz_len    = *pargz_len + entry_len;
+    size_t offset      = before - *pargz;
+    char   *argz       = LT_DLREALLOC (char, *pargz, argz_len);
+
+    if (!argz)
+      return ENOMEM;
+
+    /* Make BEFORE point to the equivalent offset in ARGZ that it
+       used to have in *PARGZ incase realloc() moved the block.  */
+    before = argz + offset;
+
+    /* Move the ARGZ entries starting at BEFORE up into the new
+       space at the end -- making room to copy ENTRY into the
+       resulting gap.  */
+    memmove (before + entry_len, before, *pargz_len - offset);
+    memcpy  (before, entry, entry_len);
+
+    /* Assign new values.  */
+    *pargz = argz;
+    *pargz_len = argz_len;
+  }
+  
+  return 0;  
+}
+#endif /* !HAVE_ARGZ_INSERT */
+
+
+#if ! HAVE_ARGZ_NEXT
+#  define argz_next rpl_argz_next
+
+static char *argz_next LT_PARAMS((char *argz, size_t argz_len,
+                                   const char *entry));
+
+char *
+argz_next (argz, argz_len, entry)
+     char *argz;
+     size_t argz_len;
+     const char *entry;
+{
+  assert ((argz && argz_len) || (!argz && !argz_len));
+
+  if (entry)
+    {
+      /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address
+        within the ARGZ vector.  */
+      assert ((!argz && !argz_len)
+             || ((argz <= entry) && (entry < (argz + argz_len))));
+
+      /* Move to the char immediately after the terminating
+        '\0' of ENTRY.  */
+      entry = 1+ strchr (entry, LT_EOS_CHAR);
+
+      /* Return either the new ENTRY, or else NULL if ARGZ is
+        exhausted.  */
+      return (entry >= argz + argz_len) ? 0 : (char *) entry;
+    }
+  else
+    {
+      /* This should probably be flagged as a programmer error,
+        since starting an argz_next loop with the iterator set
+        to ARGZ is safer.  To preserve semantics, handle the NULL
+        case by returning the start of ARGZ (if any).  */
+      if (argz_len > 0)
+       return argz;
+      else
+       return 0;
+    }
+}
+#endif /* !HAVE_ARGZ_NEXT */
 
 
 
@@ -136,7 +614,7 @@ typedef struct {
 
 
 /* Extract the diagnostic strings from the error table macro in the same
-   order as the enumberated indices in ltdl.h. */
+   order as the enumerated indices in ltdl.h. */
 
 static const char *lt_dlerror_strings[] =
   {
@@ -270,29 +748,7 @@ lt_dlmutex_register (lock, unlock, seterror, geterror)
 
 
 \f
-/* --- MEMORY HANDLING --- */
-
-
-LT_GLOBAL_DATA    lt_ptr       (*lt_dlmalloc)  LT_PARAMS((size_t size))
-                                   = (lt_ptr (*) LT_PARAMS((size_t))) malloc;
-LT_GLOBAL_DATA    void         (*lt_dlfree)    LT_PARAMS((lt_ptr ptr))
-                                   = (void (*) LT_PARAMS((lt_ptr))) free;
-
-static           lt_ptr        rpl_realloc     LT_PARAMS((lt_ptr ptr,
-                                                          size_t size));
-
-#define LT_DLMALLOC(tp, n)     ((tp *) lt_dlmalloc ((n) * sizeof(tp)))
-#define LT_DLREALLOC(tp, p, n) ((tp *) rpl_realloc ((p), (n) * sizeof(tp)))
-#define LT_DLFREE(p)                                           \
-       LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END
-
-#define LT_DLMEM_REASSIGN(p, q)                        LT_STMT_START { \
-       if ((p) != (q)) { lt_dlfree (p); (p) = (q); }           \
-                                               } LT_STMT_END
-
-
-\f
-/* --- ERROR MESSAGES --- */
+/* --- ERROR HANDLING --- */
 
 
 static const char    **user_error_strings      = 0;
@@ -306,15 +762,13 @@ lt_dladderror (diagnostic)
   int          result   = -1;
   const char  **temp     = (const char **) 0;
 
+  assert (diagnostic);
+
   LT_DLMUTEX_LOCK ();
 
   errindex = errorcount - LT_ERROR_MAX;
-  temp = LT_DLREALLOC (const char *, user_error_strings, 1 + errindex);
-  if (temp == 0)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-    }
-  else
+  temp = LT_EREALLOC (const char *, user_error_strings, 1 + errindex);
+  if (temp)
     {
       user_error_strings               = temp;
       user_error_strings[errindex]     = diagnostic;
@@ -356,183 +810,35 @@ lt_dlseterror (errindex)
   return errors;
 }
 
-
-
-\f
-/* --- REPLACEMENT FUNCTIONS --- */
-
-
-#undef strdup
-#define strdup rpl_strdup
-
-static char *
-strdup(str)
-     const char *str;
-{
-  char *tmp = 0;
-
-  if (str)
-    {
-      tmp = LT_DLMALLOC (char, 1+ strlen (str));
-      if (tmp)
-       {
-         strcpy(tmp, str);
-       }
-    }
-
-  return tmp;
-}
-
-
-#if ! HAVE_STRCMP
-
-#undef strcmp
-#define strcmp rpl_strcmp
-
-static int
-strcmp (str1, str2)
-     const char *str1;
-     const char *str2;
-{
-  if (str1 == str2)
-    return 0;
-  if (str1 == 0)
-    return -1;
-  if (str2 == 0)
-    return 1;
-
-  for (;*str1 && *str2; ++str1, ++str2)
-    {
-      if (*str1 != *str2)
-       break;
-    }
-
-  return (int)(*str1 - *str2);
-}
-#endif
-
-
-#if ! HAVE_STRCHR
-
-#  if HAVE_INDEX
-#    define strchr index
-#  else
-#    define strchr rpl_strchr
-
-static const char*
-strchr(str, ch)
-     const char *str;
-     int ch;
-{
-  const char *p;
-
-  for (p = str; *p != (char)ch && *p != '\0'; ++p)
-    /*NOWORK*/;
-
-  return (*p == (char)ch) ? p : 0;
-}
-
-#  endif
-#endif /* !HAVE_STRCHR */
-
-#if ! HAVE_STRRCHR
-
-#  if HAVE_RINDEX
-#    define strrchr rindex
-#  else
-#    define strrchr rpl_strrchr
-
-static const char*
-strrchr(str, ch)
-     const char *str;
-     int ch;
+lt_ptr
+lt_emalloc (size)
+     size_t size;
 {
-  const char *p, *q = 0;
-
-  for (p = str; *p != '\0'; ++p)
-    {
-      if (*p == (char) ch)
-       {
-         q = p;
-       }
-    }
-
-  return q;
+  lt_ptr mem = lt_dlmalloc (size);
+  if (size && !mem)
+    LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
+  return mem;
 }
 
-# endif
-#endif
-
-/* NOTE:  Neither bcopy nor the memcpy implementation below can
-          reliably handle copying in overlapping areas of memory, so
-          do not rely on this behaviour when invoking memcpy later.  */
-#if ! HAVE_MEMCPY
-
-#  if HAVE_BCOPY
-#    define memcpy(dest, src, size)    bcopy (src, dest, size)
-#  else
-#    define memcpy rpl_memcpy
-
-static char *
-memcpy (dest, src, size)
-     char *dest;
-     const char *src;
+lt_ptr
+lt_erealloc (addr, size)
+     lt_ptr addr;
      size_t size;
 {
-  size_t i = 0;
-
-  for (i = 0; i < size; ++i)
-    {
-      dest[i] = src[i];
-    }
-
-  return dest;
+  lt_ptr mem = realloc (addr, size);
+  if (size && !mem)
+    LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
+  return mem;
 }
 
-#  endif
-#endif
-
-/* According to Alexandre Oliva <oliva@lsd.ic.unicamp.br>,
-    ``realloc is not entirely portable''
-   In any case we want to use the allocator supplied by the user without
-   burdening them with an lt_dlrealloc function pointer to maintain.
-   Instead implement our own version (with known boundary conditions)
-   using lt_dlmalloc and lt_dlfree. */
-static lt_ptr
-rpl_realloc (ptr, size)
-     lt_ptr ptr;
-     size_t size;
+char *
+lt_estrdup (str)
+     const char *str;
 {
-  if (size < 1)
-    {
-      /* For zero or less bytes, free the original memory */
-      if (ptr != 0)
-       {
-         lt_dlfree (ptr);
-       }
-
-      return (lt_ptr) 0;
-    }
-  else if (ptr == 0)
-    {
-      /* Allow reallocation of a NULL pointer.  */
-      return lt_dlmalloc (size);
-    }
-  else
-    {
-      /* Allocate a new block, copy and free the old block.  */
-      lt_ptr mem = lt_dlmalloc (size);
-
-      if (mem)
-       {
-         memcpy (mem, ptr, size);
-         lt_dlfree (ptr);
-       }
-
-      /* Note that the contents of PTR are not damaged if there is
-        insufficient memory to realloc.  */
-      return mem;
-    }
+  char *dup = strdup (str);
+  if (LT_STRLEN (str) && !dup)
+    LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
+  return dup;
 }
 
 
@@ -831,21 +1137,18 @@ sys_wll_open (loader_data, filename)
   if (ext)
     {
       /* FILENAME already has an extension. */
-      searchname = strdup (filename);
+      searchname = lt_estrdup (filename);
     }
   else
     {
       /* Append a `.' to stop Windows from adding an
         implicit `.dll' extension. */
-      searchname = LT_DLMALLOC (char, 2+ LT_DLSTRLEN (filename));
-      if (!searchname)
-       {
-         LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-         return 0;
-       }
-      strcpy (searchname, filename);
-      strcat (searchname, ".");
+      searchname = LT_EMALLOC (char, 2+ LT_STRLEN (filename));
+      if (searchname)
+       sprintf (searchname, "%s.", filename);
     }
+  if (!searchname)
+    return 0;
 
 #if __CYGWIN__
   {
@@ -1033,12 +1336,7 @@ sys_dld_open (loader_data, filename)
 {
   lt_module module = strdup (filename);
 
-  if (!module)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-      module = 0;
-    }
-  else if (dld_link (filename) != 0)
+  if (dld_link (filename) != 0)
     {
       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN));
       LT_DLFREE (module);
@@ -1176,20 +1474,19 @@ presym_add_symlist (preloaded)
       lists = lists->next;
     }
 
-  tmp = LT_DLMALLOC (lt_dlsymlists_t, 1);
+  tmp = LT_EMALLOC (lt_dlsymlists_t, 1);
   if (tmp)
     {
-      memset (tmp, 0, 1*sizeof(lt_dlsymlists_t));
+      memset (tmp, 0, sizeof(lt_dlsymlists_t));
       tmp->syms = preloaded;
       tmp->next = preloaded_symbols;
       preloaded_symbols = tmp;
     }
   else
     {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
       ++errors;
     }
-
+  
  done:
   LT_DLMUTEX_UNLOCK ();
   return errors;
@@ -1212,6 +1509,10 @@ presym_open (loader_data, filename)
       goto done;
     }
 
+  /* Can't use NULL as the reflective symbol header, as NULL is
+     used to mark the end of the entire symbol list.  Self-dlpreopened
+     symbols follow this magic number, chosen to be an unlikely
+     clash with a real module name.  */
   if (!filename)
     {
       filename = "@PROGRAM@";
@@ -1303,7 +1604,11 @@ static   int     foreachfile_callback  LT_PARAMS((char *filename, lt_ptr data1,
                                                 lt_ptr data2));
 
 
-static char    *canonicalize_path    LT_PARAMS((const char *path));
+static int      canonicalize_path    LT_PARAMS((const char *path,
+                                                char **pcanonical));
+static int      argzize_path         LT_PARAMS((const char *path,
+                                                char **pargz,
+                                                size_t *pargz_len));
 static FILE    *find_file            LT_PARAMS((const char *search_path,
                                                 const char *base_name,
                                                 char **pdir));
@@ -1531,10 +1836,9 @@ tryall_dlopen (handle, filename)
   cur = *handle;
   if (filename)
     {
-      cur->info.filename = strdup (filename);
+      cur->info.filename = lt_estrdup (filename);
       if (!cur->info.filename)
        {
-         LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
          ++errors;
          goto done;
        }
@@ -1565,7 +1869,7 @@ tryall_dlopen (handle, filename)
     }
 
   cur->loader  = loader;
-  lt_dllast_error      = saved_error;
+  LT_DLMUTEX_SETERROR (saved_error);
   
  done:
   LT_DLMUTEX_UNLOCK ();
@@ -1573,6 +1877,55 @@ tryall_dlopen (handle, filename)
   return errors;
 }
 
+static int
+tryall_dlopen_module (handle, prefix, dirname, dlname)
+     lt_dlhandle *handle;
+     const char *prefix;
+     const char *dirname;
+     const char *dlname;
+{
+  int      error       = 0;
+  char     *filename   = 0;
+  size_t   filename_len        = 0;
+  size_t   dirname_len = LT_STRLEN (dirname);
+
+  assert (handle);
+  assert (dirname);
+  assert (dlname);
+#ifdef LT_DIRSEP_CHAR
+  /* Only canonicalized names (i.e. with DIRSEP chars already converted)
+     should make it into this function:  */
+  assert (strchr (dirname, LT_DIRSEP_CHAR) == 0);
+#endif
+  
+  if (dirname[dirname_len -1] == '/')
+    --dirname_len;
+  filename_len = dirname_len + 1 + LT_STRLEN (dlname);
+
+  /* Allocate memory, and combine DIRNAME and MODULENAME into it.
+     The PREFIX (if any) is handled below.  */
+  filename  = LT_EMALLOC (char, dirname_len + 1 + filename_len + 1);
+  if (!filename)
+    return 1;
+
+  sprintf (filename, "%.*s/%s", dirname_len, dirname, dlname);
+
+  /* Now that we have combined DIRNAME and MODULENAME, if there is
+     also a PREFIX to contend with, simply recurse with the arguments
+     shuffled.  Otherwise, attempt to open FILENAME as a module.  */
+  if (prefix)
+    {
+      tryall_dlopen_module (handle, 0, prefix, filename);
+    }
+  else if (tryall_dlopen (handle, filename) != 0)
+    {
+      ++error;
+    }
+    
+  LT_DLFREE (filename);
+  return error;
+}
+
 static int
 find_module (handle, dir, libdir, dlname, old_name, installed)
      lt_dlhandle *handle;
@@ -1585,15 +1938,15 @@ find_module (handle, dir, libdir, dlname, old_name, installed)
   int  error;
   char *filename;
 
-  /* try to open the old library first; if it was dlpreopened,
+  /* Try to open the old library first; if it was dlpreopened,
      we want the preopened version of it, even if a dlopenable
-     module is available */
-  if (old_name && tryall_dlopen(handle, old_name) == 0)
+     module is available */
+  if (old_name && tryall_dlopen (handle, old_name) == 0)
     {
       return 0;
     }
 
-  /* try to open the dynamic library */
+  /* Try to open the dynamic library.  */
   if (dlname)
     {
       size_t len;
@@ -1601,111 +1954,120 @@ find_module (handle, dir, libdir, dlname, old_name, installed)
       /* try to open the installed module */
       if (installed && libdir)
        {
-         len       = strlen (libdir) + 1 + strlen (dlname);
-         filename  = LT_DLMALLOC (char, 1+ len);
-
-         if (!filename)
-           {
-             LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-             return 1;
-           }
-
-         sprintf (filename, "%s/%s", libdir, dlname);
-         error = (tryall_dlopen (handle, filename) != 0);
-         LT_DLFREE (filename);
-
-         if (!error)
-           {
-             return 0;
-           }
+         if (tryall_dlopen_module (handle, 0, libdir, dlname) == 0)
+           return 0;
        }
 
-      /* try to open the not-installed module */
-      if (!installed)
-       {
-         len = LT_DLSTRLEN (dir) + strlen (objdir) + strlen (dlname);
-         filename = LT_DLMALLOC (char, 1+ len);
-
-         if (!filename)
-           {
-             LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-             return 1;
-           }
-
-         if (dir)
-           {
-             strcpy (filename, dir);
-           }
-         else
-           {
-             *filename = 0;
-           }
-         strcat(filename, objdir);
-         strcat(filename, dlname);
-
-         error = tryall_dlopen (handle, filename) != 0;
-         LT_DLFREE (filename);
-         if (!error)
-           {
-             return 0;
-           }
+      /* try to open the not-installed module */
+      if (!installed)
+       {
+         if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0)
+           return 0;
        }
 
       /* maybe it was moved to another directory */
       {
-       len      = LT_DLSTRLEN (dir) + strlen (dlname);
-       filename = LT_DLMALLOC (char, 1+ len);
+         if (tryall_dlopen_module (handle, 0, dir, dlname) == 0)
+           return 0;
+      }
+    }
+
+  return 1;
+}
+
+
+static int
+canonicalize_path (path, pcanonical)
+     const char *path;
+     char **pcanonical;
+{
+  char *canonical = 0;
+  
+  assert (path && *path);
+  assert (pcanonical);
+
+  canonical = LT_EMALLOC (char, 1+ LT_STRLEN (path));
+  if (!canonical)
+    return 1;
 
-       if (dir)
+  {
+    size_t dest = 0;
+    size_t src;
+    for (src = 0; path[src] != LT_EOS_CHAR; ++src)
+      {
+       /* Path separators are not copied to the beginning or end of
+          the destination, or if another separator would follow
+          immediately.  */
+       if (path[src] == LT_PATHSEP_CHAR)
          {
-           strcpy (filename, dir);
+           if ((dest == 0)
+               || (path[1+ src] == LT_PATHSEP_CHAR)
+               || (path[1+ src] == LT_EOS_CHAR))
+             continue;
          }
-       else
+       /* Anything other than a directory separator is copied verbatim.  */
+       else if ((path[src] != '/')
+#ifdef LT_DIRSEP_CHAR
+                && (path[src] != LT_DIRSEP_CHAR)
+#endif
+                )
          {
-           *filename = 0;
+           canonical[dest++] = path[src];
          }
-       strcat(filename, dlname);
-
-       error = (tryall_dlopen (handle, filename) != 0);
-       LT_DLFREE (filename);
-       if (!error)
+       /* Directory separators are converted and copied only if they are
+          not at the end of a path -- i.e. before a path separator or
+          NULL terminator.  */
+       else if ((path[1+ src] != LT_PATHSEP_CHAR)
+                && (path[1 + src] != LT_EOS_CHAR))
          {
-           return 0;
+           canonical[dest++] = '/';
          }
       }
-    }
 
-  return 1;
+    /* Add an end-of-string marker at the end.  */
+    canonical[dest] = LT_EOS_CHAR;
+  }
+
+  /* Assign new value.  */
+  *pcanonical = canonical;
+
+  return 0;
 }
 
-static char *
-canonicalize_path (path)
+static int
+argzize_path (path, pargz, pargz_len)
      const char *path;
+     char **pargz;
+     size_t *pargz_len;
 {
-  char *canonical = 0;
+  error_t error;
+  
+  assert (path);
+  assert (pargz);
+  assert (pargz_len);
 
-  if (path && *path)
+  if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len)))
     {
-      char *ptr = strdup (path);
-      canonical = ptr;
-
-#ifdef LT_DIRSEP_CHAR
-      /* Avoid this overhead where '/' is the only separator. */
-      while (ptr = strchr (ptr, LT_DIRSEP_CHAR))
+      switch (error)
        {
-         *ptr++ = '/';
+       case ENOMEM:
+         LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
+         break;
+       default:
+         LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
+         break;
        }
-#endif
+
+      return 1;
     }
 
-  return canonical;
+  return 0;
 }
 
 /* Repeatedly call FUNC with each LT_PATHSEP_CHAR delimited element
-   of SEARCH_PATH and a copy of DATA, until FUNC returns non-zero or
-   all elements are exhausted.  If BASE_NAME is non-NULL, it is appended
-   to each SEARCH_PATH element (with a separating '/' added if
-   necessary) before FUNC is called.  */
+   of SEARCH_PATH and references to DATA1 and DATA2, until FUNC returns
+   non-zero or all elements are exhausted.  If BASE_NAME is non-NULL,
+   it is appended to each SEARCH_PATH element before FUNC is called.  */
 static int
 foreach_dirinpath (search_path, base_name, func, data1, data2)
      const char *search_path;
@@ -1716,7 +2078,7 @@ foreach_dirinpath (search_path, base_name, func, data1, data2)
 {
   int  result          = 0;
   int  filenamesize    = 0;
-  int  lenbase         = LT_DLSTRLEN (base_name);
+  int  lenbase         = LT_STRLEN (base_name);
   char *filename       = 0;
   char *canonical      = 0;
   char *next;
@@ -1729,8 +2091,7 @@ foreach_dirinpath (search_path, base_name, func, data1, data2)
       goto cleanup;
     }
 
-  canonical = canonicalize_path (search_path);
-  if (!canonical)
+  if (canonicalize_path (search_path, &canonical) != 0)
     {
       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
       goto cleanup;
@@ -1798,32 +2159,27 @@ find_file_callback (filename, data1, data2)
      lt_ptr data1;
      lt_ptr data2;
 {
-  char       **pdir    = (char **) data1;
-  FILE       **pfile   = (FILE **) data2;
-  int          is_done = 0;
+  char      **pdir     = (char **) data1;
+  FILE      **pfile    = (FILE **) data2;
+  int       is_done    = 0;
 
-  *pfile = fopen (filename, LT_READTEXT_MODE);
+  assert (filename && *filename);
+  assert (pdir);
+  assert (pfile);
 
-  if (*pfile)
+  if ((*pfile = fopen (filename, LT_READTEXT_MODE)))
     {
       char *dirend = strrchr (filename, '/');
 
       LT_DLFREE (*pdir);
-      *dirend = '\0';
-      *pdir = strdup (filename);
-      if (!*pdir)
-       {
-         /* We could have even avoided the strdup,
-            but there would be some memory overhead. */
-         *pdir = filename;
-         filename = 0; /* prevent the foreach function from freeing */
-       }
+      *pdir    = filename;
+      filename = 0;
+
+      if (dirend > filename)
+       *dirend   = LT_EOS_CHAR;
+
       is_done = 1;
     }
-  else
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
-    }
 
   return is_done;
 }
@@ -1877,7 +2233,7 @@ load_deplibs (handle, deplibs)
      char *deplibs;
 {
 #if LTDL_DLOPEN_DEPLIBS
-  char *p, *save_search_path;
+  char *p, *save_search_path = 0;
   int   depcount = 0;
   int  i;
   char **names = 0;
@@ -1894,11 +2250,11 @@ load_deplibs (handle, deplibs)
   ++errors;
 
   LT_DLMUTEX_LOCK ();
-  save_search_path = strdup (user_search_path);
-  if (user_search_path && !save_search_path)
+  if (user_search_path)
     {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-      goto cleanup;
+      save_search_path = lt_estrdup (user_search_path);
+      if (!save_search_path)
+       goto cleanup;
     }
 
   /* extract search paths and count deplibs */
@@ -1948,11 +2304,9 @@ load_deplibs (handle, deplibs)
       goto cleanup;
     }
 
-  names = LT_DLMALLOC (char *, depcount * sizeof (char*));
+  names = LT_EMALLOC (char *, depcount * sizeof (char*));
   if (!names)
-    {
-      goto cleanup;
-    }
+    goto cleanup;
 
   /* now only extract the actual deplibs */
   depcount = 0;
@@ -1978,25 +2332,17 @@ load_deplibs (handle, deplibs)
              *end = 0; /* set a temporary string terminator */
              if (strncmp(p, "-l", 2) == 0)
                {
-                 name = LT_DLMALLOC (char, 3+ /* "lib" */ strlen (p+2) + 1);
-                 if (name)
-                   {
-                     sprintf (name, "lib%s", p+2);
-                   }
+                 size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2);
+                 name = LT_EMALLOC (1+ name_len);
+                 sprintf (name, "lib%s", p+2);
                }
              else
-               {
-                 name = strdup(p);
-               }
+               name = lt_estrdup(p);
 
-             if (name)
-               {
-                 names[depcount++] = name;
-               }
-             else
-               {
-                 goto cleanup_names;
-               }
+             if (!name)
+               goto cleanup_names;
+
+             names[depcount++] = name;
              *end = save;
            }
          p = end;
@@ -2012,11 +2358,9 @@ load_deplibs (handle, deplibs)
     {
       int      j = 0;
 
-      handle->deplibs = (lt_dlhandle*) LT_DLMALLOC (lt_dlhandle *, depcount);
+      handle->deplibs = (lt_dlhandle*) LT_EMALLOC (lt_dlhandle *, depcount);
       if (!handle->deplibs)
-           {
-         goto cleanup;
-           }
+       goto cleanup;
 
       for (i = 0; i < depcount; ++i)
        {
@@ -2073,22 +2417,19 @@ trim (dest, str)
   /* remove the leading and trailing "'" from str
      and store the result in dest */
   const char *end   = strrchr (str, '\'');
-  int  len         = LT_DLSTRLEN (str);
+  int  len         = LT_STRLEN (str);
   char *tmp;
 
   LT_DLFREE (*dest);
 
   if (len > 3 && str[0] == '\'')
     {
-      tmp = LT_DLMALLOC (char, end - str);
+      tmp = LT_EMALLOC (char, end - str);
       if (!tmp)
-       {
-         lt_dllast_error = LT_DLSTRERROR (NO_MEMORY);
-         return 1;
-       }
+       return 1;
 
       strncpy(tmp, &str[1], (end - str) - 1);
-      tmp[len-3] = '\0';
+      tmp[len-3] = LT_EOS_CHAR;
       *dest = tmp;
     }
   else
@@ -2100,7 +2441,7 @@ trim (dest, str)
 }
 
 static int
-free_varsdlname, oldname, libdir, deplibs)
+free_vars (dlname, oldname, libdir, deplibs)
      char *dlname;
      char *oldname;
      char *libdir;
@@ -2123,20 +2464,22 @@ lt_dlopen (filename)
   const char *saved_error;
   char *canonical = 0, *base_name = 0, *dir = 0, *name = 0;
 
+  /* Doing this immediately allows internal functions to safely
+     assume only canonicalized paths are passed.  */
+  if (filename && (canonicalize_path (filename, &canonical) != 0))
+    return 0;
+
   LT_DLMUTEX_GETERROR (saved_error);
 
   /* dlopen self? */
   if (!filename)
     {
-      handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1);
+      handle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
       if (!handle)
-       {
-         LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-         return 0;
-       }
+       return 0;
 
       memset (handle, 0, 1*sizeof(struct lt_dlhandle_struct));
-      newhandle                        = handle;
+      newhandle        = handle;
 
       /* lt_dlclose()ing yourself is very bad!  Disallow it.  */
       LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG);
@@ -2149,35 +2492,28 @@ lt_dlopen (filename)
       goto register_handle;
     }
 
-  canonical = canonicalize_path (filename);
-  if (!canonical)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-      LT_DLFREE (handle);
-      return 0;
-    }
+  assert (filename && *filename);
 
   /* If the canonical module name is a path (relative or absolute)
      then split it into a directory part and a name part.  */
   base_name = strrchr (canonical, '/');
   if (base_name)
     {
-      ++base_name;
-      dir = LT_DLMALLOC (char, base_name - canonical + 1);
+      size_t dirlen = (1+ base_name) - canonical;
+
+      dir = LT_EMALLOC (char, 1+ dirlen);
       if (!dir)
-       {
-         LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-         handle = 0;
-         goto cleanup;
-       }
+       goto cleanup;
 
-      strncpy (dir, canonical, base_name - canonical);
-      dir[base_name - canonical] = '\0';
+      strncpy (dir, canonical, dirlen);
+      dir[dirlen] = LT_EOS_CHAR;
+
+      ++base_name;
     }
   else
-    {
-      base_name = canonical;
-    }
+    LT_DLMEM_REASSIGN (base_name, canonical);
+      
+  assert (base_name && *base_name);
 
   /* Check whether we are opening a libtool module (.la extension).  */
   ext = strrchr(base_name, '.');
@@ -2198,13 +2534,9 @@ lt_dlopen (filename)
       int      installed = 1;
 
       /* extract the module name from the file name */
-      name = LT_DLMALLOC (char, ext - base_name + 1);
+      name = LT_EMALLOC (char, ext - base_name + 1);
       if (!name)
-       {
-         LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-         handle = 0;
-         goto cleanup;
-       }
+       goto cleanup;
 
       /* canonicalize the module name */
       for (i = 0; i < ext - base_name; ++i)
@@ -2219,7 +2551,7 @@ lt_dlopen (filename)
            }
        }
 
-      name[ext - base_name] = '\0';
+      name[ext - base_name] = LT_EOS_CHAR;
 
     /* Now try to open the .la file.  If there is no directory name
        component, try to find it first in user_search_path and then other
@@ -2256,18 +2588,13 @@ lt_dlopen (filename)
        }
 
       if (!file)
-       {
-         handle = 0;
-         goto cleanup;
-       }
+       goto cleanup;
 
       line_len = LT_FILENAME_MAX;
-      line = LT_DLMALLOC (char, line_len);
+      line = LT_EMALLOC (char, line_len);
       if (!line)
        {
          fclose (file);
-         LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-         handle = 0;
          goto cleanup;
        }
 
@@ -2282,7 +2609,7 @@ lt_dlopen (filename)
 
          /* Handle the case where we occasionally need to read a line 
             that is longer than the initial buffer size.  */
-         while (line[strlen(line) -1] != '\n')
+         while (line[LT_STRLEN(line) -1] != '\n')
            {
              line = LT_DLREALLOC (char, line, line_len *2);
              if (!fgets (&line[line_len -1], line_len +1, file))
@@ -2342,17 +2669,20 @@ lt_dlopen (filename)
              char *last_libname;
              error = trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]);
              if (! error && dlname &&
-                 (last_libname = strrchr (dlname, ' ')) != NULL)
+                 (last_libname = strrchr (dlname, ' ')) != 0)
                {
-                 last_libname = strdup (last_libname + 1);
+                 last_libname = lt_estrdup (last_libname + 1);
+                 if (!last_libname)
+                   {
+                     ++error;
+                     goto cleanup;
+                   }
                  LT_DLMEM_REASSIGN (dlname, last_libname);
                }
            }
 
          if (error)
-           {
-             break;
-           }
+           break;
        }
 
       fclose (file);
@@ -2360,20 +2690,19 @@ lt_dlopen (filename)
 
       /* allocate the handle */
       handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1);
-      if (!handle || error)
-       {
-         LT_DLFREE (handle);
-         if (!error)
-           {
-             LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-           }
+      if (!handle)
+       ++error;
 
+      if (error)
+       {
          free_vars (dlname, old_name, libdir, deplibs);
-         /* handle is already set to 0 */
+         LT_DLFREE (handle);
          goto cleanup;
        }
 
-      memset (handle, 0, 1*sizeof(struct lt_dlhandle_struct));
+      assert (handle);
+
+      memset (handle, 0, sizeof(struct lt_dlhandle_struct));
       if (load_deplibs (handle, deplibs) == 0)
        {
          newhandle = handle;
@@ -2404,18 +2733,12 @@ lt_dlopen (filename)
   else
     {
       /* not a libtool module */
-      handle = (lt_dlhandle) LT_DLMALLOC (struct lt_dlhandle_struct, 1);
+      handle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1);
       if (!handle)
-       {
-         LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-         /* handle is already set to 0 */
-         goto cleanup;
-       }
-      handle->info.ref_count = 0;
-      /* non-libtool modules don't have dependencies */
-      handle->depcount    = 0;
-      handle->deplibs    = 0;
-      newhandle                  = handle;
+       goto cleanup;
+
+      memset (handle, 0, sizeof(struct lt_dlhandle_struct));
+      newhandle = handle;
 
       /* If the module has no directory name component, try to find it
         first in user_search_path and then other prescribed paths.
@@ -2444,14 +2767,12 @@ lt_dlopen (filename)
   if (handle->info.ref_count == 0)
     {
       handle->info.ref_count   = 1;
-      handle->info.name                = name;
-      handle->next             = handles;
+      LT_DLMEM_REASSIGN (handle->info.name, name);
 
       LT_DLMUTEX_LOCK ();
+      handle->next             = handles;
       handles                  = handle;
       LT_DLMUTEX_UNLOCK ();
-
-      name = 0;        /* don't free this during `cleanup' */
     }
 
   LT_DLMUTEX_SETERROR (saved_error);
@@ -2480,7 +2801,7 @@ lt_dlopenext (filename)
       return lt_dlopen (filename);
     }
 
-  len = strlen (filename);
+  len = LT_STRLEN (filename);
   if (!len)
     {
       LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND));
@@ -2488,12 +2809,10 @@ lt_dlopenext (filename)
     }
 
   /* try "filename.la" */
-  tmp = LT_DLMALLOC (char, len+4);
+  tmp = LT_EMALLOC (char, len+4);
   if (!tmp)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-      return 0;
-    }
+    return 0;
+
   strcpy (tmp, filename);
   strcat (tmp, ".la");
   handle = lt_dlopen (tmp);
@@ -2506,20 +2825,18 @@ lt_dlopenext (filename)
 
 #ifdef LTDL_SHLIB_EXT
   /* try "filename.EXT" */
-  if (strlen(shlib_ext) > 3)
+  if (LT_STRLEN(shlib_ext) > 3)
     {
       LT_DLFREE (tmp);
-      tmp = LT_DLMALLOC (char, len + strlen (shlib_ext) + 1);
+      tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1);
       if (!tmp)
-       {
-         LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-         return 0;
-       }
+       return 0;
+
       strcpy (tmp, filename);
     }
   else
     {
-      tmp[len] = '\0';
+      tmp[len] = LT_EOS_CHAR;
     }
 
   strcat(tmp, shlib_ext);
@@ -2544,75 +2861,188 @@ lt_dlopenext (filename)
   return 0;
 }
 
-/* If there are any files in DIRNAME, try to load them as modules, and if
-   successful call the verify function passed as DATA1 (with the loaded
-   module handle and DATA2 as arguments).  If that function returns
-   non-zero, then unload that module, otherwise leave it loaded.  */
-static int
-foreachfile_callback (dirname, data1, data2)
-     char *dirname;
-     lt_ptr data1;
-     lt_ptr data2;
+int
+lt_argz_insert (pargz, pargz_len, entry)
+     char **pargz;
+     size_t *pargz_len;
+     const char *entry;
 {
-  int (*func) LT_PARAMS((const char *filename, lt_ptr data))
-       = (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1;
+  char *before = 0;
 
-  char *filename       = 0;
-  int  filenamesize    = 0;
-  int  lendir          = LT_DLSTRLEN (dirname);
-  DIR  *dirp           = opendir (dirname);
-  struct dirent *direntp;
+  assert (pargz);
+  assert (pargz_len);
+  assert (entry && *entry);
 
-  if (!dirp)
-    return 0;
+  if (*pargz)
+    while ((before = argz_next (*pargz, *pargz_len, before)))
+      {
+       int cmp = strcmp (entry, before);
 
-  LT_DLMUTEX_LOCK ();
+       if (cmp < 0)  break;
+       if (cmp == 0) return 0; /* No duplicates! */
+      }
+  
+  {
+    error_t error;
 
-  rewinddir (dirp);
-  while ((direntp = readdir (dirp)))
-    {
-      /* Don't try to use `.' or `..' as useful filenames.  */
-      if ((direntp->d_name[0] == '.')
-         && (((direntp->d_name[1] == '.') && (direntp->d_name[2] == '\0'))
-             || (direntp->d_name[1] == '\0')))
-       {
-         continue;
-       }
+    if ((error = argz_insert (pargz, pargz_len, before, entry)))
+      {
+       switch (error)
+         {
+         case ENOMEM:
+           LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
+           break;
+         default:
+           LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN));
+           break;
+         }
+       return 1;
+      }
+  }
 
-      if (lendir +1 +LT_D_NAMLEN(direntp) >= filenamesize)
-       {
-         LT_DLFREE (filename);
-         filenamesize  = lendir +1 + LT_D_NAMLEN(direntp) +1;
-         filename      = LT_DLMALLOC (char, filenamesize);
+  return 0;
+}
 
-         if (!filename)
-           {
-             LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-             goto cleanup;
-           }
-       }
+int
+lt_argz_insertdir (pargz, pargz_len, dirnam, dp)
+     char **pargz;
+     size_t *pargz_len;
+     const char *dirnam;
+     struct dirent *dp;
+{
+  char   *buf      = 0;
+  size_t buf_len    = 0;
+  char   *end      = 0;
+  size_t end_offset = 0;
+  size_t dir_len    = 0;
+  int    errors            = 0;
+
+  assert (pargz);
+  assert (pargz_len);
+  assert (dp);
+
+  dir_len = LT_STRLEN (dirnam);
+  end     = dp->d_name + LT_D_NAMLEN(dp);
+
+  /* Ignore version numbers.  */
+  {
+    char *p;
+    for (p = end; p -1 > dp->d_name; --p)
+      if (strchr (".0123456789", p[-1]) == 0)
+       break;
 
-      strcpy (filename, dirname);
-      if (filename[lendir -1] != '/')
-       filename[lendir++] = '/';
-      strcpy (filename +lendir, direntp->d_name);
+    if (*p == '.')
+      end = p;
+  }
 
-      /* Call the user function for this FILENAME.  */
-      if ((*func) (filename, data2))
+  /* Ignore filename extension.  */
+  {
+    char *p;
+    for (p = end -1; p > dp->d_name; --p)
+      if (*p == '.')
        {
+         end = p;
          break;
        }
+  }
+
+  /* Prepend the directory name.  */
+  end_offset   = end - dp->d_name;
+  buf_len      = dir_len + 1+ end_offset;
+  buf          = LT_DLMALLOC (char, 1+ buf_len);
+  if (!buf)
+    return ++errors;
+    
+  assert (buf);
+
+  strcpy  (buf, dirnam);
+  strcat  (buf, "/");
+  strncat (buf, dp->d_name, end_offset);
+  buf[buf_len] = LT_EOS_CHAR;
+
+  /* Try to insert (in order) into ARGZ/ARGZ_LEN.  */
+  if (lt_argz_insert (pargz, pargz_len, buf) != 0)
+    ++errors;
+
+  LT_DLFREE (buf);
+
+  return errors; 
+}
+
+int
+list_files_by_dir (dirnam, pargz, pargz_len)
+     const char *dirnam;
+     char **pargz;
+     size_t *pargz_len;
+{
+  DIR  *dirp     = 0;
+  char *argz     = 0;
+  size_t argz_len = 0;
+  int    errors          = 0;
+  
+  assert (dirnam && *dirnam);
+  assert (pargz);
+  assert (pargz_len);
+  assert (dirnam[LT_STRLEN(dirnam) -1] != '/');
+
+  dirp = opendir (dirnam);
+  if (dirp)
+    {
+      struct dirent *dp        = 0;
+
+      while ((dp = readdir (dirp)))
+       if (dp->d_name[0] != '.')
+         if (lt_argz_insertdir (&argz, &argz_len, dirnam, dp))
+           {
+             ++errors;
+             break;
+           }
+
+      closedir (dirp);
     }
 
+  return errors;
+}
+
+
+/* If there are any files in DIRNAME, call the function passed in
+   DATA1 (with the name of each file and DATA2 as arguments).  */
+static int
+foreachfile_callback (dirname, data1, data2)
+     char *dirname;
+     lt_ptr data1;
+     lt_ptr data2;
+{
+  int (*func) LT_PARAMS((const char *filename, lt_ptr data))
+       = (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1;
+
+  int is_done = 0;
+  char *argz;
+  size_t argz_len;
+
+  if (list_files_by_dir (dirname, &argz, &argz_len) != 0)
+    goto cleanup;
+
+  {
+    char *filename = 0;
+    while ((filename = argz_next (argz, argz_len, filename)))
+      if ((is_done = (*func) (filename, data2)))
+       break;
+  }
+
  cleanup:
-  LT_DLFREE (filename);
-  closedir (dirp);
-  
-  LT_DLMUTEX_UNLOCK ();
+  LT_DLFREE (argz);
 
-  return 0;
+  return is_done;
 }
 
+
+/* Call FUNC for each unique extensionless file in SEARCH_PATH, along
+   with DATA.  The filenames passed to FUNC would be suitable for
+   passing to lt_dlopenext.  The extensions are stripped so that
+   individual modules do not generate several entries (e.g. libfoo.la,
+   libfoo.so, libfoo.so.1, libfoo.so.1.0.0).  If SEARCH_PATH is NULL,
+   then the same directories that lt_dlopen would search are examined.  */
 int
 lt_dlforeachfile (search_path, func, data)
      const char *search_path;
@@ -2746,8 +3176,8 @@ lt_dlsym (handle, symbol)
       return 0;
     }
 
-  lensym = strlen (symbol) + LT_DLSTRLEN (handle->loader->sym_prefix)
-                                       + LT_DLSTRLEN (handle->info.name);
+  lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->loader->sym_prefix)
+                                       + LT_STRLEN (handle->info.name);
 
   if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH)
     {
@@ -2755,13 +3185,12 @@ lt_dlsym (handle, symbol)
     }
   else
     {
-      sym = LT_DLMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
-    }
-
-  if (!sym)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW));
-      return 0;
+      sym = LT_EMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
+      if (!sym)
+       {
+         LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW));
+         return 0;
+       }
     }
 
   data = handle->loader->dlloader_data;
@@ -2826,7 +3255,7 @@ lt_dlerror ()
   LT_DLMUTEX_GETERROR (error);
   LT_DLMUTEX_SETERROR (0);
 
-  return error;
+  return error ? error : LT_DLSTRERROR (UNKNOWN);
 }
 
 int
@@ -2835,7 +3264,7 @@ lt_dladdsearchdir (search_dir)
 {
   int errors = 0;
 
-  if (!search_dir || !strlen(search_dir))
+  if (!search_dir || !LT_STRLEN(search_dir))
     {
       return errors;
     }
@@ -2843,21 +3272,17 @@ lt_dladdsearchdir (search_dir)
   LT_DLMUTEX_LOCK ();
   if (!user_search_path)
     {
-      user_search_path = strdup (search_dir);
+      user_search_path = lt_estrdup (search_dir);
       if (!user_search_path)
-       {
-         lt_dllast_error = LT_DLSTRERROR (NO_MEMORY);
-         ++errors;
-       }
+       ++errors;
     }
   else
     {
-      size_t len = strlen (user_search_path) + 1 + strlen (search_dir);
-      char  *new_search_path = LT_DLMALLOC (char, 1+ len);
+      size_t len = LT_STRLEN (user_search_path) + 1 + LT_STRLEN (search_dir);
+      char  *new_search_path = LT_EMALLOC (char, 1+ len);
 
       if (!new_search_path)
        {
-         LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
          ++errors;
        }
       else
@@ -2883,17 +3308,15 @@ lt_dlsetsearchpath (search_path)
   LT_DLFREE (user_search_path);
   LT_DLMUTEX_UNLOCK ();
 
-  if (!search_path || !strlen (search_path))
+  if (!search_path || !LT_STRLEN (search_path))
     {
       return errors;
     }
 
   LT_DLMUTEX_LOCK ();
-  user_search_path = strdup (search_path);
+  user_search_path = lt_estrdup (search_path);
   if (!user_search_path)
-    {
-      ++errors;
-    }
+    ++errors;
   LT_DLMUTEX_UNLOCK ();
 
   return errors;
@@ -3044,16 +3467,13 @@ lt_dlcaller_set_data (key, handle, data)
       lt_caller_data *temp
        = LT_DLREALLOC (lt_caller_data, handle->caller_data, 1+ n_elements);
 
-      if (temp == 0)
+      if (!temp)
        {
-         LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-         stale =  (lt_ptr) 0;
+         stale = 0;
          goto done;
        }
-      else
-       {
-         handle->caller_data = temp;
-       }
+
+      handle->caller_data = temp;
 
       /* We only need this if we needed to allocate a new caller_data.  */
       handle->caller_data[i].key  = key;
@@ -3124,12 +3544,9 @@ lt_dlloader_add (place, dlloader, loader_name)
     }
 
   /* Create a new dlloader node with copies of the user callbacks.  */
-  node = LT_DLMALLOC (lt_dlloader, 1);
-  if (node == 0)
-    {
-      LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY));
-      return 1;
-    }
+  node = LT_EMALLOC (lt_dlloader, 1);
+  if (!node)
+    return 1;
 
   node->next           = 0;
   node->loader_name    = loader_name;
@@ -3173,7 +3590,7 @@ lt_dlloader_add (place, dlloader, loader_name)
 
       if (ptr->next != place)
        {
-         lt_dllast_error = LT_DLSTRERROR (INVALID_LOADER);
+         LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER));
          ++errors;
        }
       else
index 82979daad4f6a17e88827e84a44d70f56d3cf41a..569b5ef0d394385ead2d82684abc9580073e482f 100644 (file)
@@ -34,6 +34,9 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 /* --- MACROS FOR PORTABILITY --- */
 
 
+/* Saves on those hard to debug '\0' typos....  */
+#define LT_EOS_CHAR    '\0'
+
 /* LTDL_BEGIN_C_DECLS should be used at the beginning of your declarations,
    so that C++ compilers don't mangle their names.  Use LTDL_END_C_DECLS at
    the end of C declarations. */
@@ -82,6 +85,8 @@ LT_BEGIN_C_DECLS
 #  define LT_CONC(s,t) s/**/t
 #endif
 
+/* LT_STRLEN can be used safely on NULL pointers.  */
+#define LT_STRLEN(s)   (((s) && (s)[0]) ? strlen (s) : 0)
 
 
 \f
@@ -189,8 +194,13 @@ extern     int     lt_dlmutex_register     LT_PARAMS((lt_dlmutex_lock *lock,
 /* --- MEMORY HANDLING --- */
 
 
-/* Pointers to memory management functions to be used by libltdl. */
+/* By default, the realloc function pointer is set to our internal
+   realloc implementation which iself uses lt_dlmalloc and lt_dlfree.
+   libltdl relies on a featureful realloc, but if you are sure yours
+   has the right semantics then you can assign it directly.  Generally,
+   it is safe to assign just a malloc() and a free() function.  */
 LT_SCOPE  lt_ptr   (*lt_dlmalloc)      LT_PARAMS((size_t size));
+LT_SCOPE  lt_ptr   (*lt_dlrealloc)     LT_PARAMS((lt_ptr ptr, size_t size));
 LT_SCOPE  void    (*lt_dlfree)         LT_PARAMS((lt_ptr ptr));
 
 
diff --git a/ltdl.m4 b/ltdl.m4
index 0b25a71cb2a408369ab5a0ce1157693becf60eb6..0d0a0b4c0a9f5f323ef69c27200fb422da653978 100644 (file)
--- a/ltdl.m4
+++ b/ltdl.m4
 ## configuration script generated by Autoconf, you may include it under
 ## the same distribution terms that you use for the rest of that program.
 
-# serial 3 AC_LIB_LTDL
+# serial 4 AC_LIB_LTDL
 
 # AC_LIB_LTDL
 # -----------
+# Perform all the checks necessary for compilation of the ltdl objects
+#  -- including compiler checks and header checks.
 AC_DEFUN([AC_LIB_LTDL],
-[AC_PREREQ(2.13)dnl
-AC_REQUIRE([AC_PROG_CC])dnl
-AC_REQUIRE([AC_C_CONST])dnl
+[AC_PREREQ(2.50)
+AC_REQUIRE([AC_PROG_CC])
+AC_REQUIRE([AC_C_CONST])
+AC_REQUIRE([AC_HEADER_STDC])
+AC_REQUIRE([AC_HEADER_DIRENT])
+AC_REQUIRE([_LT_AC_CHECK_DLFCN])
+AC_REQUIRE([AC_LTDL_ENABLE_INSTALL])
+AC_REQUIRE([AC_LTDL_SHLIBEXT])
+AC_REQUIRE([AC_LTDL_SHLIBPATH])
+AC_REQUIRE([AC_LTDL_SYSSEARCHPATH])
+AC_REQUIRE([AC_LTDL_OBJDIR])
+AC_REQUIRE([AC_LTDL_DLPREOPEN])
+AC_REQUIRE([AC_LTDL_DLLIB])
+AC_REQUIRE([AC_LTDL_SYMBOL_USCORE])
+AC_REQUIRE([AC_LTDL_DLSYM_USCORE])
+AC_REQUIRE([AC_LTDL_SYS_DLOPEN_DEPLIBS])
+AC_REQUIRE([AC_LTDL_FUNC_ARGZ])
 
-# Perform all the checks necessary for compilation of the ltdl objects
-#  -- including compiler checks (above) and header checks (below).
-AC_REQUIRE([AC_HEADER_STDC])dnl
-AC_REQUIRE([AC_HEADER_DIRENT])dnl
-AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
-
-AC_CHECK_HEADERS(malloc.h memory.h stdlib.h stdio.h ctype.h dl.h sys/dl.h dld.h)
-AC_CHECK_HEADERS(string.h strings.h, break)
-AC_CHECK_FUNCS(strchr index, break)
-AC_CHECK_FUNCS(strrchr rindex, break)
-AC_CHECK_FUNCS(memcpy bcopy, break)
-AC_CHECK_FUNCS(strcmp)
-
-AC_REQUIRE([AC_LTDL_ENABLE_INSTALL])dnl
-AC_REQUIRE([AC_LTDL_SHLIBEXT])dnl
-AC_REQUIRE([AC_LTDL_SHLIBPATH])dnl
-AC_REQUIRE([AC_LTDL_SYSSEARCHPATH])dnl
-AC_REQUIRE([AC_LTDL_OBJDIR])dnl
-AC_REQUIRE([AC_LTDL_DLPREOPEN])dnl
-AC_REQUIRE([AC_LTDL_DLLIB])dnl
-AC_REQUIRE([AC_LTDL_SYMBOL_USCORE])dnl
-AC_REQUIRE([AC_LTDL_DLSYM_USCORE])dnl
-AC_REQUIRE([AC_LTDL_SYS_DLOPEN_DEPLIBS])dnl
+AC_CHECK_HEADERS([ctype.h errno.h malloc.h memory.h stdlib.h stdio.h])
+AC_CHECK_HEADERS([dl.h sys/dl.h dld.h])
+AC_CHECK_HEADERS([string.h strings.h], [break])
+
+AC_CHECK_FUNCS([strchr index], [break])
+AC_CHECK_FUNCS([strrchr rindex], [break])
+AC_CHECK_FUNCS([memcpy bcopy], [break])
+AC_CHECK_FUNCS([memmove strcmp])
 ])# AC_LIB_LTDL
 
+
 # AC_LTDL_ENABLE_INSTALL
 # ----------------------
 AC_DEFUN([AC_LTDL_ENABLE_INSTALL],
@@ -64,116 +66,121 @@ AM_CONDITIONAL(INSTALL_LTDL, test x"${enable_ltdl_install-no}" != xno)
 AM_CONDITIONAL(CONVENIENCE_LTDL, test x"${enable_ltdl_convenience-no}" != xno)
 ])])# AC_LTDL_ENABLE_INSTALL
 
+
 # AC_LTDL_SYS_DLOPEN_DEPLIBS
 # --------------------------
 AC_DEFUN([AC_LTDL_SYS_DLOPEN_DEPLIBS],
 [AC_REQUIRE([AC_CANONICAL_HOST])
 AC_CACHE_CHECK([whether deplibs are loaded by dlopen],
-       libltdl_cv_sys_dlopen_deplibs, [dnl
-       # PORTME does your system automatically load deplibs for dlopen?
-       # or its logical equivalent (e.g. shl_load for HP-UX < 11)
-       # For now, we just catch OSes we know something about -- in the
-       # future, we'll try test this programmatically.
-       libltdl_cv_sys_dlopen_deplibs=unknown
-       case "$host_os" in
-       aix3*|aix4.1.*|aix4.2.*)
-         # Unknown whether this is true for these versions of AIX, but
-         # we want this `case' here to explicitly catch those versions.
-         libltdl_cv_sys_dlopen_deplibs=unknown
-         ;;
-       aix[45]*)
-         libltdl_cv_sys_dlopen_deplibs=yes
-         ;;
-       gnu*)
-         libltdl_cv_sys_dlopen_deplibs=yes
-         ;;
-       irix[12345]*|irix6.[01]*)
-         # Catch all versions of IRIX before 6.2, and indicate that we don't
-         # know how it worked for any of those versions.
-         libltdl_cv_sys_dlopen_deplibs=unknown
-         ;;
-       irix*)
-         # The case above catches anything before 6.2, and it's known that
-         # at 6.2 and later dlopen does load deplibs.
-         libltdl_cv_sys_dlopen_deplibs=yes
-         ;;
-       linux*)
-         libltdl_cv_sys_dlopen_deplibs=yes
-         ;;
-       netbsd*)
-         libltdl_cv_sys_dlopen_deplibs=yes
-         ;;
-       osf[1234]*)
-         # dlopen did load deplibs (at least at 4.x), but until the 5.x series,
-         # it did *not* use an RPATH in a shared library to find objects the
-         # library depends on, so we explictly say `no'.
-         libltdl_cv_sys_dlopen_deplibs=no
-         ;;
-       osf5.0|osf5.0a|osf5.1)
-         # dlopen *does* load deplibs and with the right loader patch applied
-         # it even uses RPATH in a shared library to search for shared objects
-         # that the library depends on, but there's no easy way to know if that
-         # patch is installed.  Since this is the case, all we can really
-         # say is unknown -- it depends on the patch being installed.  If
-         # it is, this changes to `yes'.  Without it, it would be `no'.
-         libltdl_cv_sys_dlopen_deplibs=unknown
-         ;;
-       osf*)
-         # the two cases above should catch all versions of osf <= 5.1.  Read
-         # the comments above for what we know about them.
-         # At > 5.1, deplibs are loaded *and* any RPATH in a shared library
-         # is used to find them so we can finally say `yes'.
-         libltdl_cv_sys_dlopen_deplibs=yes
-         ;;
-       solaris*)
-         libltdl_cv_sys_dlopen_deplibs=yes
-         ;;
-       esac
-])
+  [libltdl_cv_sys_dlopen_deplibs],
+  [# PORTME does your system automatically load deplibs for dlopen?
+  # or its logical equivalent (e.g. shl_load for HP-UX < 11)
+  # For now, we just catch OSes we know something about -- in the
+  # future, we'll try test this programmatically.
+  libltdl_cv_sys_dlopen_deplibs=unknown
+  case "$host_os" in
+  aix3*|aix4.1.*|aix4.2.*)
+    # Unknown whether this is true for these versions of AIX, but
+    # we want this `case' here to explicitly catch those versions.
+    libltdl_cv_sys_dlopen_deplibs=unknown
+    ;;
+  aix[45]*)
+    libltdl_cv_sys_dlopen_deplibs=yes
+    ;;
+  gnu*)
+    libltdl_cv_sys_dlopen_deplibs=yes
+    ;;
+  irix[12345]*|irix6.[01]*)
+    # Catch all versions of IRIX before 6.2, and indicate that we don't
+    # know how it worked for any of those versions.
+    libltdl_cv_sys_dlopen_deplibs=unknown
+    ;;
+  irix*)
+    # The case above catches anything before 6.2, and it's known that
+    # at 6.2 and later dlopen does load deplibs.
+    libltdl_cv_sys_dlopen_deplibs=yes
+    ;;
+  linux*)
+    libltdl_cv_sys_dlopen_deplibs=yes
+    ;;
+  netbsd*)
+    libltdl_cv_sys_dlopen_deplibs=yes
+    ;;
+  osf[1234]*)
+    # dlopen did load deplibs (at least at 4.x), but until the 5.x series,
+    # it did *not* use an RPATH in a shared library to find objects the
+    # library depends on, so we explictly say `no'.
+    libltdl_cv_sys_dlopen_deplibs=no
+    ;;
+  osf5.0|osf5.0a|osf5.1)
+    # dlopen *does* load deplibs and with the right loader patch applied
+    # it even uses RPATH in a shared library to search for shared objects
+    # that the library depends on, but there's no easy way to know if that
+    # patch is installed.  Since this is the case, all we can really
+    # say is unknown -- it depends on the patch being installed.  If
+    # it is, this changes to `yes'.  Without it, it would be `no'.
+    libltdl_cv_sys_dlopen_deplibs=unknown
+    ;;
+  osf*)
+    # the two cases above should catch all versions of osf <= 5.1.  Read
+    # the comments above for what we know about them.
+    # At > 5.1, deplibs are loaded *and* any RPATH in a shared library
+    # is used to find them so we can finally say `yes'.
+    libltdl_cv_sys_dlopen_deplibs=yes
+    ;;
+  solaris*)
+    libltdl_cv_sys_dlopen_deplibs=yes
+    ;;
+  esac
+  ])
 if test "$libltdl_cv_sys_dlopen_deplibs" != yes; then
- AC_DEFINE(LTDL_DLOPEN_DEPLIBS, 1,
-    [Define if the OS needs help to load dependent libraries for dlopen()])
+ AC_DEFINE([LTDL_DLOPEN_DEPLIBS], [1],
+    [Define if the OS needs help to load dependent libraries for dlopen()])
 fi
 ])# AC_LTDL_SYS_DLOPEN_DEPLIBS
 
+
 # AC_LTDL_SHLIBEXT
 # ----------------
 AC_DEFUN([AC_LTDL_SHLIBEXT],
 [AC_REQUIRE([AC_LIBTOOL_SYS_DYNAMIC_LINKER])
 AC_CACHE_CHECK([which extension is used for shared libraries],
-  libltdl_cv_shlibext,
-[ac_last=
+  [libltdl_cv_shlibext],
+  [ac_last=
   for ac_spec in $library_names_spec; do
     ac_last="$ac_spec"
   done
   echo "$ac_last" | [sed 's/\[.*\]//;s/^[^.]*//;s/\$.*$//;s/\.$//'] > conftest
-libltdl_cv_shlibext=`cat conftest`
-rm -f conftest
-])
+  libltdl_cv_shlibext=`cat conftest`
+  rm -f conftest
+  ])
 if test -n "$libltdl_cv_shlibext"; then
   AC_DEFINE_UNQUOTED(LTDL_SHLIB_EXT, "$libltdl_cv_shlibext",
     [Define to the extension used for shared libraries, say, ".so". ])
 fi
 ])# AC_LTDL_SHLIBEXT
 
+
 # AC_LTDL_SHLIBPATH
 # -----------------
 AC_DEFUN([AC_LTDL_SHLIBPATH],
 [AC_REQUIRE([AC_LIBTOOL_SYS_DYNAMIC_LINKER])
 AC_CACHE_CHECK([which variable specifies run-time library path],
-  libltdl_cv_shlibpath_var, [libltdl_cv_shlibpath_var="$shlibpath_var"])
+  [libltdl_cv_shlibpath_var], [libltdl_cv_shlibpath_var="$shlibpath_var"])
 if test -n "$libltdl_cv_shlibpath_var"; then
   AC_DEFINE_UNQUOTED(LTDL_SHLIBPATH_VAR, "$libltdl_cv_shlibpath_var",
     [Define to the name of the environment variable that determines the dynamic library search path. ])
 fi
 ])# AC_LTDL_SHLIBPATH
 
+
 # AC_LTDL_SYSSEARCHPATH
 # ---------------------
 AC_DEFUN([AC_LTDL_SYSSEARCHPATH],
 [AC_REQUIRE([AC_LIBTOOL_SYS_DYNAMIC_LINKER])
 AC_CACHE_CHECK([for the default library search path],
-  libltdl_cv_sys_search_path, [libltdl_cv_sys_search_path="$sys_lib_dlsearch_path_spec"])
+  [libltdl_cv_sys_search_path],
+  [libltdl_cv_sys_search_path="$sys_lib_dlsearch_path_spec"])
 if test -n "$libltdl_cv_sys_search_path"; then
   case "$host" in
   *-*-mingw*) pathsep=";" ;;
@@ -192,143 +199,157 @@ if test -n "$libltdl_cv_sys_search_path"; then
 fi
 ])# AC_LTDL_SYSSEARCHPATH
 
+
 # AC_LTDL_OBJDIR
 # --------------
 AC_DEFUN([AC_LTDL_OBJDIR],
 [AC_CACHE_CHECK([for objdir],
-  libltdl_cv_objdir, [libltdl_cv_objdir="$objdir"
-if test -n "$objdir"; then
-  :
-else
-  rm -f .libs 2>/dev/null
-  mkdir .libs 2>/dev/null
-  if test -d .libs; then
-    libltdl_cv_objdir=.libs
+  [libltdl_cv_objdir],
+  [libltdl_cv_objdir="$objdir"
+  if test -n "$objdir"; then
+    :
   else
-    # MS-DOS does not allow filenames that begin with a dot.
-    libltdl_cv_objdir=_libs
+    rm -f .libs 2>/dev/null
+    mkdir .libs 2>/dev/null
+    if test -d .libs; then
+      libltdl_cv_objdir=.libs
+    else
+      # MS-DOS does not allow filenames that begin with a dot.
+      libltdl_cv_objdir=_libs
+    fi
+  rmdir .libs 2>/dev/null
   fi
-rmdir .libs 2>/dev/null
-fi])
+  ])
 AC_DEFINE_UNQUOTED(LTDL_OBJDIR, "$libltdl_cv_objdir/",
   [Define to the sub-directory in which libtool stores uninstalled libraries. ])
 ])# AC_LTDL_OBJDIR
 
+
 # AC_LTDL_DLPREOPEN
 # -----------------
 AC_DEFUN([AC_LTDL_DLPREOPEN],
-[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])dnl
+[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])
 AC_CACHE_CHECK([whether libtool supports -dlopen/-dlpreopen],
-       libltdl_cv_preloaded_symbols, [dnl
-  if test -n "$global_symbol_pipe"; then
+  [libltdl_cv_preloaded_symbols],
+  [if test -n "$global_symbol_pipe"; then
     libltdl_cv_preloaded_symbols=yes
   else
     libltdl_cv_preloaded_symbols=no
   fi
-])
-if test x"$libltdl_cv_preloaded_symbols" = x"yes"; then
+  ])
+if test x"$libltdl_cv_preloaded_symbols" = xyes; then
   AC_DEFINE(HAVE_PRELOADED_SYMBOLS, 1,
     [Define if libtool can extract symbol lists from object files. ])
 fi
 ])# AC_LTDL_DLPREOPEN
 
+
 # AC_LTDL_DLLIB
 # -------------
 AC_DEFUN([AC_LTDL_DLLIB],
 [LIBADD_DL=
 AC_SUBST(LIBADD_DL)
 AC_LANG_PUSH([C])
-AC_CHECK_LIB(dl, dlopen
-    [AC_DEFINE(HAVE_LIBDL, 1,
-      [Define if you have the libdl library or equivalent. ])
-    LIBADD_DL="-ldl"],
+AC_CHECK_LIB([dl], [dlopen]
+  [AC_DEFINE([HAVE_LIBDL], [1],
+     [Define if you have the libdl library or equivalent. ])
+   LIBADD_DL="-ldl"],
   [AC_TRY_LINK([#if HAVE_DLFCN_H
 #  include <dlfcn.h>
 #endif
-], [dlopen();], 
-      [AC_DEFINE(HAVE_LIBDL, 1,
-        [Define if you have the libdl library or equivalent.])],
+    ],
+    [dlopen();], 
+    [AC_DEFINE(HAVE_LIBDL, 1,
+      [Define if you have the libdl library or equivalent. ])],
     [AC_CHECK_LIB(svld, dlopen, 
-        [AC_DEFINE(HAVE_LIBDL, 1,
-          [Define if you have the libdl library or equivalent.])
-        LIBADD_DL="-lsvld"])])])
+      [AC_DEFINE(HAVE_LIBDL, 1,
+        [Define if you have the libdl library or equivalent. ])
+      LIBADD_DL="-lsvld"
+      ])
+    ])
+  ])
 
 AC_CHECK_FUNC(shl_load,
-    [AC_DEFINE(HAVE_SHL_LOAD, 1, [Define if you have the shl_load function.])],
-  [AC_CHECK_LIB(dld, shl_load,
-      [AC_DEFINE(HAVE_SHL_LOAD, 1, [Define if you have the shl_load function.])
-      LIBADD_DL="$LIBADD_DL -ldld"])])
+  [AC_DEFINE([HAVE_SHL_LOAD], [1],
+    [Define if you have the shl_load function. ])],
+  [AC_CHECK_LIB([dld], [shl_load],
+    [AC_DEFINE([HAVE_SHL_LOAD], [1],
+      [Define if you have the shl_load function. ])
+    LIBADD_DL="$LIBADD_DL -ldld"
+    ])
+  ])
 
-AC_CHECK_LIB(dld, dld_link,
-    [AC_DEFINE(HAVE_DLD, 1, [Define if you have the GNU dld library.])
-    test "x$ac_cv_lib_dld_shl_load" = yes || LIBADD_DL="$LIBADD_DL -ldld"])
+AC_CHECK_LIB([dld], [dld_link],
+  [AC_DEFINE([HAVE_DLD], [1],
+    [Define if you have the GNU dld library.])
+  test x"$ac_cv_lib_dld_shl_load" = xyes || LIBADD_DL="$LIBADD_DL -ldld"
+  ])
 
-
-if test "x$ac_cv_func_dlopen" = xyes || test "x$ac_cv_lib_dl_dlopen" = xyes
+if test x"$ac_cv_func_dlopen" = xyes || test x"$ac_cv_lib_dl_dlopen" = xyes
 then
   lt_save_LIBS="$LIBS"
   LIBS="$LIBS $LIBADD_DL"
-  AC_CHECK_FUNCS(dlerror)
+  AC_CHECK_FUNCS([dlerror])
   LIBS="$lt_save_LIBS"
 fi
 AC_LANG_POP
 ])# AC_LTDL_DLLIB
 
+
 # AC_LTDL_SYMBOL_USCORE
 # ---------------------
+# does the compiler prefix global symbols with an underscore?
 AC_DEFUN([AC_LTDL_SYMBOL_USCORE],
-[dnl does the compiler prefix global symbols with an underscore?
-AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])dnl
-AC_MSG_CHECKING([for _ prefix in compiled symbols])
-AC_CACHE_VAL(ac_cv_sys_symbol_underscore,
-[ac_cv_sys_symbol_underscore=no
-cat > conftest.$ac_ext <<EOF
+[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])
+AC_CACHE_CHECK([for _ prefix in compiled symbols],
+  [ac_cv_sys_symbol_underscore],
+  [ac_cv_sys_symbol_underscore=no
+  cat > conftest.$ac_ext <<EOF
 void nm_test_func(){}
 int main(){nm_test_func;return 0;}
 EOF
-if AC_TRY_EVAL(ac_compile); then
-  # Now try to grab the symbols.
-  ac_nlist=conftest.nm
-  if AC_TRY_EVAL(NM conftest.$ac_objext \| $global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
-    # See whether the symbols have a leading underscore.
-    if egrep '^. _nm_test_func' "$ac_nlist" >/dev/null; then
-      ac_cv_sys_symbol_underscore=yes
-    else
-      if egrep '^. nm_test_func ' "$ac_nlist" >/dev/null; then
-       :
+  if AC_TRY_EVAL(ac_compile); then
+    # Now try to grab the symbols.
+    ac_nlist=conftest.nm
+    if AC_TRY_EVAL(NM conftest.$ac_objext \| $global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
+      # See whether the symbols have a leading underscore.
+      if egrep '^. _nm_test_func' "$ac_nlist" >/dev/null; then
+        ac_cv_sys_symbol_underscore=yes
       else
-       echo "configure: cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
+        if egrep '^. nm_test_func ' "$ac_nlist" >/dev/null; then
+         :
+        else
+         echo "configure: cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
+        fi
       fi
+    else
+      echo "configure: cannot run $global_symbol_pipe" >&AC_FD_CC
     fi
   else
-    echo "configure: cannot run $global_symbol_pipe" >&AC_FD_CC
+    echo "configure: failed program was:" >&AC_FD_CC
+    cat conftest.c >&AC_FD_CC
   fi
-else
-  echo "configure: failed program was:" >&AC_FD_CC
-  cat conftest.c >&AC_FD_CC
-fi
-rm -rf conftest*
-])
-AC_MSG_RESULT($ac_cv_sys_symbol_underscore)
+  rm -rf conftest*
+  ])
 ])# AC_LTDL_SYMBOL_USCORE
 
 
 # AC_LTDL_DLSYM_USCORE
 # --------------------
 AC_DEFUN([AC_LTDL_DLSYM_USCORE],
-[AC_REQUIRE([AC_LTDL_SYMBOL_USCORE])dnl
+[AC_REQUIRE([AC_LTDL_SYMBOL_USCORE])
 if test x"$ac_cv_sys_symbol_underscore" = xyes; then
   if test x"$ac_cv_func_dlopen" = xyes ||
      test x"$ac_cv_lib_dl_dlopen" = xyes ; then
        AC_CACHE_CHECK([whether we have to add an underscore for dlsym],
-               libltdl_cv_need_uscore, [dnl
-               libltdl_cv_need_uscore=unknown
-                save_LIBS="$LIBS"
-                LIBS="$LIBS $LIBADD_DL"
-               _LT_AC_TRY_DLOPEN_SELF(
-                 libltdl_cv_need_uscore=no, libltdl_cv_need_uscore=yes,
-                 [],                        libltdl_cv_need_uscore=cross)
-               LIBS="$save_LIBS"
+         [libltdl_cv_need_uscore],
+         [libltdl_cv_need_uscore=unknown
+          save_LIBS="$LIBS"
+          LIBS="$LIBS $LIBADD_DL"
+         _LT_AC_TRY_DLOPEN_SELF(
+           [libltdl_cv_need_uscore=no], [libltdl_cv_need_uscore=yes],
+           [],                          [libltdl_cv_need_uscore=cross])
+         LIBS="$save_LIBS"
        ])
   fi
 fi
@@ -338,3 +359,19 @@ if test x"$libltdl_cv_need_uscore" = xyes; then
     [Define if dlsym() requires a leading underscode in symbol names. ])
 fi
 ])# AC_LTDL_DLSYM_USCORE
+
+# AC_LTDL_FUNC_ARGZ
+# -----------------
+AC_DEFUN([AC_LTDL_FUNC_ARGZ],
+[AC_CHECK_HEADERS([argz.h])
+
+AC_CHECK_TYPES([error_t],
+  [],
+  [AC_DEFINE([error_t], [int],
+    [Define to a type to use for `error_t' if it is not otherwise available])],
+  [#if HAVE_ARGZ_H
+#  include <argz.h>
+#endif])
+
+AC_CHECK_FUNCS([argz_append argz_create_sep argz_insert argz_next])
+])# AC_LTDL_FUNC_ARGZ