+2006-08-31 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+
+ Avoid mixing functions and data pointers in callback functions.
+
+ * libltdl/ltdl.c (file_worker_func): New type.
+ (lt_dlforeachfile): Instead of passing a function pointer as a
+ data pointer, pass a pointer to a file_worker_func pointer.
+ (foreach_callback_func): Adjust.
+ * tests/mdemo/main.c: Assume C89. Exercise lt_dlforeachfile.
+ (callback, try_iterate, my_dirname): New functions.
+ * tests/mdemo-exec.test: Check for its output.
+
2006-08-30 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
* libltdl/libltdl/lt__private.h (__attribute__, LT__UNUSED):
/* The type of a function used at each iteration of foreach_dirinpath(). */
typedef int foreach_callback_func (char *filename, void *data1,
void *data2);
+/* foreachfile_callback itself calls a function of this type: */
+typedef int file_worker_func (const char *filename, void *data);
static int foreach_dirinpath (const char *search_path,
const char *base_name,
static int
foreachfile_callback (char *dirname, void *data1, void *data2)
{
- int (*func) (const char *filename, void *data)
- = (int (*) (const char *filename, void *data)) data1;
+ file_worker_func *func = *(file_worker_func **) data1;
int is_done = 0;
char *argz = 0;
void *data)
{
int is_done = 0;
+ file_worker_func **fpptr = &func;
if (search_path)
{
/* If a specific path was passed, search only the directories
listed in it. */
is_done = foreach_dirinpath (search_path, 0,
- foreachfile_callback, func, data);
+ foreachfile_callback, fpptr, data);
}
else
{
/* Otherwise search the default paths. */
is_done = foreach_dirinpath (user_search_path, 0,
- foreachfile_callback, func, data);
+ foreachfile_callback, fpptr, data);
if (!is_done)
{
is_done = foreach_dirinpath (getenv(LTDL_SEARCHPATH_VAR), 0,
- foreachfile_callback, func, data);
+ foreachfile_callback, fpptr, data);
}
#if defined(LT_MODULE_PATH_VAR)
if (!is_done)
{
is_done = foreach_dirinpath (getenv(LT_MODULE_PATH_VAR), 0,
- foreachfile_callback, func, data);
+ foreachfile_callback, fpptr, data);
}
#endif
#if defined(LT_DLSEARCH_PATH)
if (!is_done && sys_dlsearch_path)
{
is_done = foreach_dirinpath (sys_dlsearch_path, 0,
- foreachfile_callback, func, data);
+ foreachfile_callback, fpptr, data);
}
#endif
}
/* main.c -- mdemo test program
- Copyright (C) 1998-2000 Free Software Foundation, Inc.
+ Copyright (C) 1998-2000, 2006 Free Software Foundation, Inc.
Originally by Thomas Tanner <tanner@ffii.org>
This file is part of GNU Libtool.
#include "foo.h"
#include "ltdl.h"
#include <stdio.h>
+#include <string.h>
int
test_dl (filename)
- char *filename;
+test_dl (char *filename)
{
lt_dlhandle handle;
const lt_dlinfo *info;
return 1;
}
- pmyfunc = (int(*)())lt_dlsym(handle, "myfunc");
+ pmyfunc = (int(*)())lt_dlsym(handle, "myfunc");
if (pmyfunc)
{
int value = (*pmyfunc) ();
return ret;
}
+static int
+callback (const char *filename, void *data)
+{
+ printf ("%s: %s\n", (char *)data, filename);
+ return 0;
+}
+
+static int
+try_iterate (const char *search_path)
+{
+ char *s = "try_iterate";
+ return lt_dlforeachfile (search_path, callback, s);
+}
+
+/* cheap dirname clone. We require a '/' separator, nonempty and large
+ enough input, not ending with '/', and we will overwrite the input. */
+static char *
+my_dirname (char *path)
+{
+ char *p = strrchr (path, '/');
+ if (p)
+ *p = '\0';
+ else
+ {
+ path[0] = '.';
+ path[1] = '\0';
+ }
+ return path;
+}
+
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
int i;
int ret = 0;
if (test_dlself())
ret = 1;
+ for (i = 1; i < argc; i++)
+ if (argv[i][0] != '\0')
+ {
+ my_dirname (argv[i]);
+ if (try_iterate (argv[i]))
+ ret = 1;
+ }
+
lt_dlexit();
return ret;
}