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*.