static const char sys_search_path[] = LTDL_SYSSEARCHPATH;
#endif
-static const char unknown_error[] = "unknown error";
-static const char dlopen_not_supported_error[] = "dlopen support not available";
-static const char invalid_type_error[] = "invalid dltype";
-static const char init_type_error[] = "dltype initialization failed";
-static const char file_not_found_error[] = "file not found";
-static const char deplib_not_found_error[] = "dependency library not found";
-static const char no_symbols_error[] = "no symbols defined";
-static const char cannot_open_error[] = "can't open the module";
-static const char cannot_close_error[] = "can't close the module";
-static const char symbol_error[] = "symbol not found";
-static const char memory_error[] = "not enough memory";
-static const char invalid_handle_error[] = "invalid handle";
-static const char buffer_overflow_error[] = "internal buffer overflow";
-static const char shutdown_error[] = "library already shutdown";
+/* Extract the diagnostic strings from the error table macro in the same
+ order as the enumberated indices in ltdl.h. */
+#define LTDL_ERROR(name, diagnostic) (diagnostic),
+static const char *ltdl_error_strings[] = {
+ ltdl_error_table
+ 0
+};
+#undef LTDL_ERROR
+
+#ifdef __STDC__
+# define LT_DLSTRERROR(name) ltdl_error_strings[LTDL_ERROR_##name]
+#else
+# define LT_DLSTRERROR(name) ltdl_error_strings[LTDL_ERROR_/**/name]
+#endif
static const char *last_error = 0;
#if HAVE_DLERROR
last_error = dlerror();
#else
- last_error = cannot_open_error;
+ last_error = LT_DLSTRERROR(CANNOT_OPEN);
#endif
}
return handle;
#if HAVE_DLERROR
last_error = dlerror();
#else
- last_error = cannot_close_error;
+ last_error = LT_DLSTRERROR(CANNOT_CLOSE);
#endif
return 1;
}
#if HAVE_DLERROR
last_error = dlerror();
#else
- last_error = symbol_error;
+ last_error = LT_DLSTRERROR(SYMBOL_NOT_FOUND);
#endif
return address;
}
{
lt_syshandle handle = shl_load(filename, LTDL_BIND_FLAGS, 0L);
if (!handle) {
- last_error = cannot_open_error;
+ last_error = LT_DLSTRERROR(CANNOT_OPEN);
}
return handle;
}
lt_syshandle handle;
{
if (shl_unload((shl_t) (handle)) != 0) {
- last_error = cannot_close_error;
+ last_error = LT_DLSTRERROR(CANNOT_CLOSE);
return 1;
}
return 0;
symbol, TYPE_UNDEFINED, &address) == 0)
if (address)
return address;
- last_error = symbol_error;
+ last_error = LT_DLSTRERROR(SYMBOL_NOT_FOUND);
return 0;
}
{
lt_syshandle handle = strdup(filename);
if (!handle) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 0;
}
if (dld_link(filename) != 0) {
- last_error = cannot_open_error;
+ last_error = LT_DLSTRERROR(CANNOT_OPEN);
lt_dlfree(handle);
- return 0;
+ return 0;
}
return handle;
}
lt_syshandle handle;
{
if (dld_unlink_by_file((char*)(handle), 1) != 0) {
- last_error = cannot_close_error;
+ last_error = LT_DLSTRERROR(CANNOT_CLOSE);
return 1;
}
lt_dlfree(handle);
lt_ptr_t address = dld_get_func(symbol);
if (!address)
- last_error = symbol_error;
+ last_error = LT_DLSTRERROR(SYMBOL_NOT_FOUND);
return address;
}
implicit `.dll' extension. */
searchname = (char*)lt_dlmalloc(2+ strlen(filename));
if (!searchname) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 0;
}
strcpy(searchname, filename);
strcat(searchname, ".");
}
-
+
handle = LoadLibrary(searchname);
lt_dlfree(searchname);
}
if (cur || !handle) {
- last_error = cannot_open_error;
+ last_error = LT_DLSTRERROR(CANNOT_OPEN);
return 0;
}
lt_syshandle handle;
{
if (FreeLibrary(handle) == 0) {
- last_error = cannot_close_error;
+ last_error = LT_DLSTRERROR(CANNOT_CLOSE);
return 1;
}
return 0;
lt_ptr_t address = GetProcAddress(handle, symbol);
if (!address)
- last_error = symbol_error;
+ last_error = LT_DLSTRERROR(SYMBOL_NOT_FOUND);
return address;
}
image = load_add_on(info.name);
}
if (image <= 0) {
- last_error = cannot_open_error;
- return 0;
+ last_error = LT_DLSTRERROR(CANNOT_OPEN);
+ return 0;
}
return (lt_syshandle) image;
lt_syshandle handle;
{
if (unload_add_on((image_id)handle) != B_OK) {
- last_error = cannot_close_error;
+ last_error = LT_DLSTRERROR(CANNOT_CLOSE);
return 1;
}
return 0;
if (get_image_symbol(image, symbol, B_SYMBOL_TYPE_ANY,
&address) != B_OK) {
- last_error = symbol_error;
+ last_error = LT_DLSTRERROR(SYMBOL_NOT_FOUND);
return 0;
}
return address;
tmp = (lt_dlsymlists_t*) lt_dlmalloc(sizeof(lt_dlsymlists_t));
if (!tmp) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 1;
}
tmp->syms = preloaded;
lt_dlsymlists_t *lists = preloaded_symbols;
if (!lists) {
- last_error = no_symbols_error;
+ last_error = LT_DLSTRERROR(NO_SYMBOLS);
return 0;
}
if (!filename)
}
lists = lists->next;
}
- last_error = file_not_found_error;
+ last_error = LT_DLSTRERROR(FILE_NOT_FOUND);
return 0;
}
return syms->address;
syms++;
}
- last_error = symbol_error;
+ last_error = LT_DLSTRERROR(SYMBOL_NOT_FOUND);
return 0;
}
}
}
if (typecount == 0) {
- last_error = dlopen_not_supported_error;
+ last_error = LT_DLSTRERROR(DLOPEN_NOT_SUPPORTED);
return 1;
}
last_error = 0;
lt_dltype_t *type = types;
if (dltype == 0) { /* diagnose null parameters */
- last_error = invalid_type_error;
+ last_error = LT_DLSTRERROR(INVALID_TYPE);
return 1;
}
if (dltype->next != 0) { /* diagnose invalid contents */
- last_error = invalid_type_error;
+ last_error = LT_DLSTRERROR(INVALID_TYPE);
return 1;
}
new type here. */
if (initialized && dltype->mod_init)
if ((*dltype->mod_init)()) {
- last_error = init_type_error;
+ last_error = LT_DLSTRERROR(INIT_TYPE);
return 1;
}
lt_dltype_t *dltypes;
{
if (dltypes == 0) { /* diagnose null parameters */
- last_error = invalid_type_error;
+ last_error = LT_DLSTRERROR(INVALID_TYPE);
return 1;
}
types = dltypes;
int errors, level;
if (!initialized) {
- last_error = shutdown_error;
+ last_error = LT_DLSTRERROR(SHUTDOWN);
return 1;
}
if (initialized != 1) { /* shut down only at last call. */
if (filename) {
cur->info.filename = strdup(filename);
if (!cur->info.filename) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 1;
}
} else
filename = (char*)
lt_dlmalloc(strlen(libdir)+1+strlen(dlname)+1);
if (!filename) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 1;
}
sprintf (filename, "%s/%s", libdir, dlname);
lt_dlmalloc((dir ? strlen(dir) : 0)
+ strlen(objdir) + strlen(dlname) + 1);
if (!filename) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 1;
}
if (dir)
char *canonical = 0, *next = 0;
if (!search_path || !*search_path) {
- last_error = file_not_found_error;
+ last_error = LT_DLSTRERROR(FILE_NOT_FOUND);
return 0;
}
canonical = canonicalize_path (search_path);
if (!canonical) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
goto cleanup;
}
next = canonical;
filenamesize = lendir + 1 + lenbase + 1;
filename = (char*) lt_dlmalloc(filenamesize);
if (!filename) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
goto cleanup;
}
}
}
}
}
- last_error = file_not_found_error;
+ last_error = LT_DLSTRERROR(FILE_NOT_FOUND);
cleanup:
if (filename)
lt_dlfree(filename);
return 0;
save_search_path = strdup(user_search_path);
if (user_search_path && !save_search_path) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 1;
}
p = deplibs;
int j;
for (j = 0; j < i; j++)
lt_dlclose(handles[j]);
- last_error = deplib_not_found_error;
+ last_error = LT_DLSTRERROR(DEPLIB_NOT_FOUND);
goto cleanup_names;
}
handles[i] = handle;
if (len > 3 && str[0] == '\'') {
tmp = (char*) lt_dlmalloc(end - str);
if (!tmp) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 1;
}
strncpy(tmp, &str[1], (end - str) - 1);
if (!filename) {
handle = (lt_dlhandle) lt_dlmalloc(sizeof(lt_dlhandle_t));
if (!handle) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 0;
}
handle->info.ref_count = 0;
}
canonical = canonicalize_path (filename);
if (!canonical) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
if (handle)
lt_dlfree(handle);
return 0;
basename++;
dir = (char*) lt_dlmalloc(basename - canonical + 1);
if (!dir) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
handle = 0;
goto cleanup;
}
/* extract the module name from the file name */
name = (char*) lt_dlmalloc(ext - basename + 1);
if (!name) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
handle = 0;
goto cleanup;
}
/* now try to open the .la file */
file = fopen(filename, LTDL_READTEXT_MODE);
if (!file)
- last_error = file_not_found_error;
+ last_error = LT_DLSTRERROR(FILE_NOT_FOUND);
if (!file && !dir) {
/* try other directories */
file = (FILE*) find_file(basename,
line = (char*) lt_dlmalloc(LTDL_FILENAME_MAX);
if (!line) {
fclose(file);
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
handle = 0;
goto cleanup;
}
if (handle)
lt_dlfree(handle);
if (!error)
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
free_vars(dlname, old_name, libdir, deplibs);
/* handle is already set to 0 */
goto cleanup;
/* not a libtool module */
handle = (lt_dlhandle) lt_dlmalloc(sizeof(lt_dlhandle_t));
if (!handle) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
/* handle is already set to 0 */
goto cleanup;
}
return lt_dlopen(filename);
len = strlen(filename);
if (!len) {
- last_error = file_not_found_error;
+ last_error = LT_DLSTRERROR(FILE_NOT_FOUND);
return 0;
}
/* try the normal file name */
/* try "filename.la" */
tmp = (char*) lt_dlmalloc(len+4);
if (!tmp) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 0;
}
strcpy(tmp, filename);
lt_dlfree(tmp);
tmp = (char*) lt_dlmalloc(len + strlen(shlib_ext) + 1);
if (!tmp) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 0;
}
strcpy(tmp, filename);
return handle;
}
#endif
- last_error = file_not_found_error;
+ last_error = LT_DLSTRERROR(FILE_NOT_FOUND);
lt_dlfree(tmp);
return 0;
}
cur = cur->next;
}
if (!cur) {
- last_error = invalid_handle_error;
+ last_error = LT_DLSTRERROR(INVALID_HANDLE);
return 1;
}
handle->info.ref_count--;
lt_ptr_t address;
if (!handle) {
- last_error = invalid_handle_error;
+ last_error = LT_DLSTRERROR(INVALID_HANDLE);
return 0;
}
if (!symbol) {
- last_error = symbol_error;
+ last_error = LT_DLSTRERROR(SYMBOL_NOT_FOUND);
return 0;
}
lensym = strlen(symbol);
else
sym = (char*) lt_dlmalloc(lensym + LTDL_SYMBOL_OVERHEAD + 1);
if (!sym) {
- last_error = buffer_overflow_error;
+ last_error = LT_DLSTRERROR(BUFFER_OVERFLOW);
return 0;
}
if (handle->info.name) {
if (!user_search_path) {
user_search_path = strdup(search_dir);
if (!user_search_path) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 1;
}
} else {
lt_dlmalloc(strlen(user_search_path) +
strlen(search_dir) + 2); /* ':' + '\0' == 2 */
if (!new_search_path) {
- last_error = memory_error;
+ last_error = LT_DLSTRERROR(NO_MEMORY);
return 1;
}
sprintf (new_search_path, "%s%c%s", user_search_path,
lt_ptr_t data;
{
if (!handle) {
- last_error = invalid_handle_error;
+ last_error = LT_DLSTRERROR(INVALID_HANDLE);
return 1;
}
handle->app_private = data;
lt_dlhandle handle;
{
if (!handle) {
- last_error = invalid_handle_error;
+ last_error = LT_DLSTRERROR(INVALID_HANDLE);
return 0;
}
return handle->app_private;
lt_dlhandle handle;
{
if (!handle) {
- last_error = invalid_handle_error;
+ last_error = LT_DLSTRERROR(INVALID_HANDLE);
return 0;
}
return &(handle->info);
}
return 0;
}
+
+static const char **user_error_strings = 0;
+static int errorcode = LTDL_ERROR_MAX;
+
+int
+lt_dladderror (diagnostic)
+ const char *diagnostic;
+{
+ int index = errorcode - LTDL_ERROR_MAX;
+
+ if (user_error_strings == 0)
+ user_error_strings = (const char **) lt_dlmalloc
+ ((1+index) * sizeof(const char*));
+ else
+ user_error_strings = (const char **) lt_dlrealloc
+ (user_error_strings, (1+index) * sizeof(const char*));
+
+ if (user_error_strings == 0) {
+ last_error = LT_DLSTRERROR(NO_MEMORY);
+ return -1;
+ }
+
+ user_error_strings[index] = diagnostic;
+ return errorcode++;
+}
+
+int
+lt_dlseterror (index)
+ int index;
+{
+ if (index >= errorcode) {
+ last_error = LT_DLSTRERROR(INVALID_ERRORCODE);
+ return 1;
+ }
+
+ if (index < LTDL_ERROR_MAX)
+ last_error = ltdl_error_strings[errorcode];
+ else
+ last_error = user_error_strings[errorcode - LTDL_ERROR_MAX];
+
+ return 0;
+}