Index: ChangeLog
From Gary V. Vaughan
* libltdl/ltdl.c (rpl_argz_stringify): New fallback implementation.
* ltdl.m4 (AC_LTDL_FUNC_ARGZ): Test for argz_stringify in libc.
* libltdl/ltdl.c (lt_argz_insertinorder): Renamed from
lt_argz_insert to make room for...
(lt_argz_insert): Wraps argz_insert with libltdl error handling.
(lt_dlpath_insertdir): Insert new path elements into an
argzized path.
(lt_dlinsertsearchdir): New function to insert new search
directories anywhere into user_search_path using the above.
(lt_dladdsearchdir): Rewritten to use lt_dlpath_insertdir.
* libltdl/ltdl.h (lt_dlinsertsearchdir): Prototype for export.
* doc/libtool.texi (Libltdl interface): Document it.
* NEWS: Updated,
Index: ltdl.m4
===================================================================
RCS file: /cvsroot/libtool/libtool/ltdl.m4,v
retrieving revision 1.31
diff -b -u -r1.31 ltdl.m4
--- ltdl.m4 2001/08/05 12:29:40 1.31
+++ ltdl.m4 2001/08/13 02:10:08
@@ -369,5 +369,5 @@
# include
#endif])
-AC_CHECK_FUNCS([argz_append argz_create_sep argz_insert argz_next])
+AC_CHECK_FUNCS([argz_append argz_create_sep argz_insert argz_next argz_stringify])
])# AC_LTDL_FUNC_ARGZ
Index: doc/libtool.texi
===================================================================
RCS file: /cvsroot/libtool/libtool/doc/libtool.texi,v
retrieving revision 1.118
diff -b -u -r1.118 libtool.texi
--- doc/libtool.texi 2001/06/26 00:50:38 1.118
+++ doc/libtool.texi 2001/08/13 02:10:26
@@ -2735,8 +2735,9 @@
@enumerate 1
@item user-defined search path:
-This search path can be set by the program using the
-functions @code{lt_dlsetsearchpath} and @code{lt_dladdsearchdir}.
+This search path can be changed by the program using the
+functions @code{lt_dlsetsearchpath}, @code{lt_dladdsearchdir} and
address@hidden
@item libltdl's search path:
This search path is the value of the environment variable
@@ -2827,8 +2828,15 @@
@end defmac
@deftypefun int lt_dladdsearchdir (const char address@hidden)
-Add the search directory @var{search_dir} to the user-defined library
-search path. Return 0 on success.
+Append the search directory @var{search_dir} to the current user-defined
+library search path. Return 0 on success.
address@hidden deftypefun
+
address@hidden int lt_dlinsertsearchdir (@w{const char address@hidden, @w{const char address@hidden)
+Insert the search directory @var{search_dir} into the user-defined library
+search path, immediately before the element starting at address
address@hidden If @var{before} is @samp{NULL}, then @var{search_dir} is
+appending as if @code{lt_dladdsearchdir} had been called. Return 0 on success.
@end deftypefun
@deftypefun int lt_dlsetsearchpath (const char address@hidden)
Index: libltdl/ltdl.c
===================================================================
RCS file: /cvsroot/libtool/libtool/libltdl/ltdl.c,v
retrieving revision 1.144
diff -b -u -r1.144 ltdl.c
--- libltdl/ltdl.c 2001/08/05 16:01:56 1.144
+++ libltdl/ltdl.c 2001/08/13 02:10:32
@@ -597,7 +597,34 @@
+#if ! HAVE_ARGZ_STRINGIFY
+# define argz_stringify rpl_argz_stringify
+static void argz_stringify LT_PARAMS((char *argz, size_t argz_len,
+ int sep));
+
+void
+argz_stringify (argz, argz_len, sep)
+ char *argz;
+ size_t argz_len;
+ int sep;
+{
+ assert ((argz && argz_len) || (!argz && !argz_len));
+
+ if (sep)
+ {
+ while (--argz_len >= 0)
+ {
+ if (argz[argz_len] == LT_EOS_CHAR)
+ argz[argz_len] = sep;
+ }
+ }
+}
+#endif /* !HAVE_ARGZ_STRINGIFY */
+
+
+
+
/* --- TYPE DEFINITIONS -- */
@@ -1630,8 +1657,17 @@
static int tryall_dlopen LT_PARAMS((lt_dlhandle *handle,
const char *filename));
static int unload_deplibs LT_PARAMS((lt_dlhandle handle));
+static int lt_argz_insert LT_PARAMS((char **pargz,
+ size_t *pargz_len,
+ char *before,
+ const char *entry));
+static int lt_argz_insertinorder LT_PARAMS((char **pargz,
+ size_t *pargz_len,
+ const char *entry));
+static int lt_dlpath_insertdir LT_PARAMS((char **ppath,
+ char *before,
+ const char *dir));
-
static char *user_search_path= 0;
static lt_dlloader *loaders = 0;
static lt_dlhandle handles = 0;
@@ -2855,28 +2891,14 @@
return 0;
}
+
int
-lt_argz_insert (pargz, pargz_len, entry)
+lt_argz_insert (pargz, pargz_len, before, entry)
char **pargz;
size_t *pargz_len;
+ char *before;
const char *entry;
{
- char *before = 0;
-
- assert (pargz);
- assert (pargz_len);
- assert (entry && *entry);
-
- if (*pargz)
- while ((before = argz_next (*pargz, *pargz_len, before)))
- {
- int cmp = strcmp (entry, before);
-
- if (cmp < 0) break;
- if (cmp == 0) return 0; /* No duplicates! */
- }
-
- {
error_t error;
if ((error = argz_insert (pargz, pargz_len, before, entry)))
@@ -2892,12 +2914,35 @@
}
return 1;
}
- }
return 0;
}
int
+lt_argz_insertinorder (pargz, pargz_len, entry)
+ char **pargz;
+ size_t *pargz_len;
+ const char *entry;
+{
+ char *before = 0;
+
+ assert (pargz);
+ assert (pargz_len);
+ assert (entry && *entry);
+
+ if (*pargz)
+ while ((before = argz_next (*pargz, *pargz_len, before)))
+ {
+ int cmp = strcmp (entry, before);
+
+ if (cmp < 0) break;
+ if (cmp == 0) return 0; /* No duplicates! */
+ }
+
+ return lt_argz_insert (pargz, pargz_len, before, entry);
+}
+
+int
lt_argz_insertdir (pargz, pargz_len, dirnam, dp)
char **pargz;
size_t *pargz_len;
@@ -2955,7 +3000,7 @@
buf[buf_len] = LT_EOS_CHAR;
/* Try to insert (in order) into ARGZ/ARGZ_LEN. */
- if (lt_argz_insert (pargz, pargz_len, buf) != 0)
+ if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0)
++errors;
LT_DLFREE (buf);
@@ -3255,41 +3300,124 @@
}
int
-lt_dladdsearchdir (search_dir)
- const char *search_dir;
+lt_dlpath_insertdir (ppath, before, dir)
+ char **ppath;
+ char *before;
+ const char *dir;
{
int errors = 0;
+ char *canonical = 0;
+ char *argz = 0;
+ size_t argz_len = 0;
- if (!search_dir || !LT_STRLEN(search_dir))
+ assert (ppath);
+ assert (dir && *dir);
+
+ if (canonicalize_path (dir, &canonical) != 0)
+ {
+ ++errors;
+ goto cleanup;
+ }
+
+ assert (canonical && *canonical);
+
+ /* If *PPATH is empty, set it to DIR. */
+ if (*ppath == 0)
{
+ assert (!before); /* BEFORE cannot be set without PPATH. */
+ assert (dir); /* Without DIR, don't call this function! */
+
+ *ppath = lt_estrdup (dir);
+ if (*ppath == 0)
+ ++errors;
+
return errors;
}
- LT_DLMUTEX_LOCK ();
- if (!user_search_path)
+ assert (ppath && *ppath);
+
+ if (argzize_path (*ppath, &argz, &argz_len) != 0)
{
- user_search_path = lt_estrdup (search_dir);
- if (!user_search_path)
++errors;
+ goto cleanup;
}
- else
+
+ /* Convert BEFORE into an equivalent offset into ARGZ. This only works
+ if *PPATH is already canonicalized, and hence does not change length
+ with respect to ARGZ. We canonicalize each entry as it is added to
+ the search path, and don't call this function with (uncanonicalized)
+ user paths, so this is a fair assumption. */
+ if (before)
{
- size_t len = LT_STRLEN (user_search_path) + 1 + LT_STRLEN (search_dir);
- char *new_search_path = LT_EMALLOC (char, 1+ len);
+ assert (*ppath <= before);
+ assert (before - *ppath <= strlen (*ppath));
- if (!new_search_path)
+ before = before - *ppath + argz;
+ }
+
+ if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)
{
++errors;
+ goto cleanup;
}
- else
+
+ argz_stringify (argz, argz_len, LT_PATHSEP_CHAR);
+ LT_DLMEM_REASSIGN (*ppath, argz);
+
+ cleanup:
+ LT_DLFREE (canonical);
+ LT_DLFREE (argz);
+
+ return errors;
+}
+
+int
+lt_dladdsearchdir (search_dir)
+ const char *search_dir;
+{
+ int errors = 0;
+
+ if (search_dir && *search_dir)
{
- sprintf (new_search_path, "%s%c%s", user_search_path,
- LT_PATHSEP_CHAR, search_dir);
+ LT_DLMUTEX_LOCK ();
+ if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
+ ++errors;
+ LT_DLMUTEX_UNLOCK ();
+ }
- LT_DLMEM_REASSIGN (user_search_path, new_search_path);
+ return errors;
+}
+
+int
+lt_dlinsertsearchdir (before, search_dir)
+ const char *before;
+ const char *search_dir;
+{
+ int errors = 0;
+
+ if (before)
+ {
+ LT_DLMUTEX_LOCK ();
+ if ((before < user_search_path)
+ || (before >= LT_STRLEN (user_search_path)))
+ {
+ LT_DLMUTEX_UNLOCK ();
+ LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION));
+ return 1;
+ }
+ LT_DLMUTEX_UNLOCK ();
}
+
+ if (search_dir && *search_dir)
+ {
+ LT_DLMUTEX_LOCK ();
+ if (lt_dlpath_insertdir (&user_search_path,
+ (char *) before, search_dir) != 0)
+ {
+ ++errors;
}
LT_DLMUTEX_UNLOCK ();
+ }
return errors;
}
@@ -3310,8 +3438,7 @@
}
LT_DLMUTEX_LOCK ();
- user_search_path = lt_estrdup (search_path);
- if (!user_search_path)
+ if (canonicalize_path (search_path, &user_search_path) != 0)
++errors;
LT_DLMUTEX_UNLOCK ();
Index: libltdl/ltdl.h
===================================================================
RCS file: /cvsroot/libtool/libtool/libltdl/ltdl.h,v
retrieving revision 1.56
diff -b -u -r1.56 ltdl.h
--- libltdl/ltdl.h 2001/08/01 06:50:16 1.56
+++ libltdl/ltdl.h 2001/08/13 02:10:33
@@ -153,6 +153,8 @@
/* Module search path manipulation. */
extern int lt_dladdsearchdir LT_PARAMS((const char *search_dir));
+extern int lt_dlinsertsearchdir LT_PARAMS((const char *before,
+ const char *search_dir));
extern int lt_dlsetsearchpath LT_PARAMS((const char *search_path));
extern const char *lt_dlgetsearchpath LT_PARAMS((void));
extern int lt_dlforeachfile LT_PARAMS((
@@ -321,7 +323,8 @@
LT_ERROR(INVALID_ERRORCODE, "invalid errorcode") \
LT_ERROR(SHUTDOWN, "library already shutdown") \
LT_ERROR(CLOSE_RESIDENT_MODULE, "can't close resident module") \
- LT_ERROR(INVALID_MUTEX_ARGS, "invalid mutex handler registration")
+ LT_ERROR(INVALID_MUTEX_ARGS, "invalid mutex handler registration") \
+ LT_ERROR(INVALID_POSITION, "invalid search path insert position")
/* Enumerate the symbolic error names. */
enum {
Index: NEWS
===================================================================
RCS file: /cvsroot/libtool/libtool/NEWS,v
retrieving revision 1.103
diff -b -u -r1.103 NEWS
--- NEWS 2001/08/05 11:29:09 1.103
+++ NEWS 2001/08/13 02:10:59
@@ -3,6 +3,7 @@
New in 1.4d: 2001-??-??; CVS version 1.4c, Libtool team:
* Help strings display correctly again.
* Better error messages when library linking fails.
+* Better search path management in libltdl with `lt_dlinsertsearchdir' call.
* Support /lib/w32api in recent cygwin releases.
* Support cross compilation to mingw.
* Improved support for linking with gcc on aix4* and aix5*.