+2001-08-13 Gary V. Vaughan <gary@gnu.org>
+
+ * 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,
+
2001-08-07 Gary V. Vaughan <gary@gnu.org>
- ltmain.in [irix*]: $with_gcc is either "yes" or "" (empty string)
+ From Albert Chin <china@thewrittenword.com>:
+ * ltmain.in [irix*]: $with_gcc is either "yes" or "" (empty string)
with current autoconf, so we need to be robust to that when testing
it,
2001-08-06 Gary V. Vaughan <gary@gnu.org>
From Brad <brad@comstyle.com>:
- libtool.m4 (deplibs_check_method) [aix*]: Removed redundant setting
+ * libtool.m4 (deplibs_check_method) [aix*]: Removed redundant setting
of this variable.
2001-08-05 Gary V. Vaughan <gary@gnu.org>
@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
+@code{lt_dlinsertsearchdir}.
@item libltdl's search path:
This search path is the value of the environment variable
@end defmac
@deftypefun int lt_dladdsearchdir (const char *@var{search_dir})
-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.
+@end deftypefun
+
+@deftypefun int lt_dlinsertsearchdir (@w{const char *@var{before}}, @w{const char *@var{search_dir}})
+Insert the search directory @var{search_dir} into the user-defined library
+search path, immediately before the element starting at address
+@var{before}. 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 *@var{search_path})
+#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 */
+
+
+
\f
/* --- TYPE DEFINITIONS -- */
lt_ptr data2));
-static int 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,
+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,
+static FILE *find_file LT_PARAMS((const char *search_path,
const char *base_name,
char **pdir));
static lt_dlhandle *find_handle LT_PARAMS((const char *search_path,
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;
return 0;
}
+
+int
+lt_argz_insert (pargz, pargz_len, before, entry)
+ char **pargz;
+ size_t *pargz_len;
+ char *before;
+ const char *entry;
+{
+ error_t error;
+
+ 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;
+ }
+
+ return 0;
+}
+
int
-lt_argz_insert (pargz, pargz_len, entry)
+lt_argz_insertinorder (pargz, pargz_len, entry)
char **pargz;
size_t *pargz_len;
const char *entry;
if (cmp < 0) break;
if (cmp == 0) return 0; /* No duplicates! */
}
-
- {
- error_t error;
- 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;
- }
- }
-
- return 0;
+ return lt_argz_insert (pargz, pargz_len, before, entry);
}
int
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);
}
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;
+ int errors = 0;
+ char *canonical = 0;
+ char *argz = 0;
+ size_t argz_len = 0;
+
+ assert (ppath);
+ assert (dir && *dir);
- if (!search_dir || !LT_STRLEN(search_dir))
+ if (canonicalize_path (dir, &canonical) != 0)
{
- return errors;
+ ++errors;
+ goto cleanup;
}
- LT_DLMUTEX_LOCK ();
- if (!user_search_path)
+ assert (canonical && *canonical);
+
+ /* If *PPATH is empty, set it to DIR. */
+ if (*ppath == 0)
{
- user_search_path = lt_estrdup (search_dir);
- if (!user_search_path)
+ 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;
}
- else
+
+ assert (ppath && *ppath);
+
+ if (argzize_path (*ppath, &argz, &argz_len) != 0)
+ {
+ ++errors;
+ goto cleanup;
+ }
+
+ /* 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)
+ {
+ assert (*ppath <= before);
+ assert (before - *ppath <= strlen (*ppath));
+
+ before = before - *ppath + argz;
+ }
+
+ if (lt_argz_insert (&argz, &argz_len, before, dir) != 0)
+ {
+ ++errors;
+ goto cleanup;
+ }
+
+ 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)
{
- size_t len = LT_STRLEN (user_search_path) + 1 + LT_STRLEN (search_dir);
- char *new_search_path = LT_EMALLOC (char, 1+ len);
+ LT_DLMUTEX_LOCK ();
+ if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
+ ++errors;
+ LT_DLMUTEX_UNLOCK ();
+ }
+
+ return errors;
+}
- if (!new_search_path)
+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)))
{
- ++errors;
+ LT_DLMUTEX_UNLOCK ();
+ LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION));
+ return 1;
}
- else
- {
- sprintf (new_search_path, "%s%c%s", user_search_path,
- LT_PATHSEP_CHAR, search_dir);
+ LT_DLMUTEX_UNLOCK ();
+ }
- LT_DLMEM_REASSIGN (user_search_path, new_search_path);
+ if (search_dir && *search_dir)
+ {
+ LT_DLMUTEX_LOCK ();
+ if (lt_dlpath_insertdir (&user_search_path,
+ (char *) before, search_dir) != 0)
+ {
+ ++errors;
}
+ LT_DLMUTEX_UNLOCK ();
}
- LT_DLMUTEX_UNLOCK ();
return errors;
}
lt_dlsetsearchpath (search_path)
const char *search_path;
{
- int errors = 0;
+ int errors = 0;
LT_DLMUTEX_LOCK ();
LT_DLFREE (user_search_path);
}
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 ();
extern int lt_dlexit LT_PARAMS((void));
/* Module search path manipulation. */
-extern int lt_dladdsearchdir LT_PARAMS((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((
+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((
const char *search_path,
int (*func) (const char *filename, lt_ptr data),
lt_ptr data));
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 {