Hi,

Recently (when I wrote the testcase for error reporting
in the loadlibrary loader) I found that the documentation
for the dlloader section of the api was a wee bit lacking
in accuracy...

So, I set out to update it, see attached patch.

When going through this, I found it strange that
lt_dlloader_add didn't call vtable->dlloader_init. Isn't
that desirable? I'll send an additional patch to show what
I mean...

Cheers,
Peter

2010-01-22  Peter Rosin  <p...@lysator.liu.se>

        Update dlloader api documentation.
        * doc/libtool.texi (Module loaders for libltdl): Update
        to reflect reality.

diff --git a/doc/libtool.texi b/doc/libtool.texi
index 482e635..a5582c5 100644
--- a/doc/libtool.texi
+++ b/doc/libtool.texi
@@ -4282,16 +4282,24 @@ can be recognised by @code{lt_dlloader_find} and 
removed with
 already in use by libltdl's builtin loaders:
 
 @table @asis
-...@item "dlopen"
+...@item "lt_dlopen"
 The system dynamic library loader, if one exists.
-...@item "dld"
+...@item "lt_dld_link"
 The @sc{gnu} dld loader, if @file{libdld} was installed when libltdl was
 built.
-...@item "dlpreload"
-The loader for @code{lt_dlopen}ing of preloaded static modules.
+...@item "lt_preopen"
+The loader for @code{lt_dlopen}ing of preopened static modules.
+...@item "lt_dyld"
+The Darwin / OS X dynamic library loader.
+...@item "lt_load_add_on"
+The BeOS dynamic library loader.
+...@item "lt_loadlibrary"
+The Win32 dynamic library loader.
+...@item "lt_shl_load"
+The HP/UX dynamic library loader.
 @end table
 
-The prefix "dl" is reserved for loaders supplied with future versions of
+The prefix "lt_" is reserved for loaders supplied with future versions of
 libltdl, so you should not use that for your own loader names.
 
 @noindent
@@ -4311,7 +4319,11 @@ level types.
 @code{lt_user_data} is used for specifying loader instance data.
 @end deftp
 
-...@deftypefn {Type} {struct} lt_user_dlloader @{...@w{const char 
*...@var{sym_prefix};} @w{lt_module_open *...@var{module_open};} 
@w{lt_module_close *...@var{module_close};} @w{lt_find_sym *...@var{find_sym};} 
@w{lt_dlloader_exit *...@var{dlloader_exit};} @}
+...@deftp {Type} lt_dlloader_priority
+...@code{lt_dlloader_priority} is used for specifying the loader priority.
+...@end deftp
+
+...@deftypefn {Type} {struct} lt_dlvtable @{...@w{const char *...@var{name};} 
@w{const char *...@var{sym_prefix};} @w{lt_module_open *...@var{module_open};} 
@w{lt_module_close *...@var{module_close};} @w{lt_find_sym *...@var{find_sym};} 
@w{lt_dlloader_init *...@var{dlloader_init};} @w{lt_dlloader_exit 
*...@var{dlloader_exit};} @w{lt_user_data @var{dlloader_data};} 
@w{lt_dlloader_priority @var{priority};} @}
 If you want to define a new way to open dynamic modules, and have the
 @code{lt_dlopen} @sc{api} use it, you need to instantiate one of these
 structures and pass it to @code{lt_dlloader_add}.  You can pass whatever
@@ -4346,6 +4358,15 @@ Implementation of such a function should return the 
address of the named
 with @code{lt_dlseterror} and return @code{NULL} if lookup fails.
 @end deftypefn
 
+...@deftypefn {Type} int lt_dlloader_init (@w{lt_user_data @var{loader_data}})
+The type of the initialisation function for a user defined module
+loader. Implementation of such a function should locate and initialize
+any resources needed for the loader to function correctly. If
+n...@code{null}, the function will be called by @code{lt_dlinit}.
+If the function fails for some reason, set the error message with
+...@code{lt_dlseterror} and return non-zero.
+...@end deftypefn
+
 @deftypefn {Type} int lt_dlloader_exit (@w{lt_user_data @var{loader_data}})
 The type of the finalisation function for a user defined module loader.
 Implementation of such a function should free any resources associated
@@ -4361,22 +4382,36 @@ For example:
 int
 register_myloader (void)
 @{
-  lt_user_dlloader dlloader;
+  lt_dlvtable *myloader;
+
+  myloader = malloc (sizeof (*myloader));
+  if (!myloader)
+    return MEMORY_ERROR;
 
   /* User modules are responsible for their own initialisation. */
   if (myloader_init () != 0)
-    return MYLOADER_INIT_ERROR;
+    @{
+      free (myloader);
+      return MYLOADER_INIT_ERROR;
+    @}
 
-  dlloader.sym_prefix    = NULL;
-  dlloader.module_open   = myloader_open;
-  dlloader.module_close  = myloader_close;
-  dlloader.find_sym      = myloader_find_sym;
-  dlloader.dlloader_exit = myloader_exit;
-  dlloader.dlloader_data = (lt_user_data)myloader_function;
+  myloader->name          = "myloader";
+  myloader->sym_prefix    = NULL;
+  myloader->module_open   = myloader_open;
+  myloader->module_close  = myloader_close;
+  myloader->find_sym      = myloader_find_sym;
+  myloader->dlloader_init = NULL; /* not called by lt_dlloader_add */
+  myloader->dlloader_exit = myloader_exit;
+  myloader->dlloader_data = (lt_user_data)myloader_function;
+  myloader->priority      = LT_DLLOADER_PREPEND;
 
   /* Add my loader as the default module loader. */
-  if (lt_dlloader_add (lt_dlloader_next (NULL), &dlloader, "myloader") != 0)
-    return ERROR;
+  if (lt_dlloader_add (myloader) != 0)
+    @{
+      myloader_exit (myloader->dlloader_data);
+      free (myloader);
+      return ERROR;
+    @}
 
   return OK;
 @}
@@ -4395,55 +4430,61 @@ during the initialisation phase.
 libltdl provides the following functions for writing your own module
 loaders:
 
-...@deftypefun int lt_dlloader_add (@w{lt_dlloader *...@var{place},} 
@w{lt_user_dlloader *...@var{dlloader},} @w{const char *...@var{loader_name}})
+...@deftypefun int lt_dlloader_add (@w{lt_dlvtable *...@var{dlloader}})
 Add a new module loader to the list of all loaders, either as the
-last loader (if @var{place} is @code{NULL}), else immediately before the
-loader passed as @var{place}.  @var{loader_name} will be returned by
-...@code{lt_dlloader_name} if it is subsequently passed a newly
-registered loader.  These @var{loader_name}s must be unique, or
-...@code{lt_dlloader_remove} and @code{lt_dlloader_find} cannot
-work.  Returns 0 for success.
+last loader (if @var{priority} in @var{dlloader} is set to
+...@code{lt_dlloader_append}), else the first loader (if it is set
+to @code{LT_DLLOADER_PREPEND}).  The @var{loader_name} given in
+...@var{dlloader} will be returned by @code{lt_dlloader_name} if it
+is subsequently passed a newly registered loader.  These
+...@var{loader_name}s must be unique, or @code{lt_dlloader_remove}
+and @code{lt_dlloader_find} cannot work.  Returns 0 for success.
 
 @example
 /* Make myloader be the last one. */
-if (lt_dlloader_add (NULL, myloader) != 0)
-  perror (lt_dlerror ());
+myloader.priority = LT_DLLOADER_APPEND;
+if (lt_dlloader_add (&myloader) != 0)
+  fprintf (stderr, "lt_dlloader_add failed: %s\n", lt_dlerror ());
 @end example
 @end deftypefun
 
-...@deftypefun int lt_dlloader_remove (@w{const char *...@var{loader_name}})
+...@deftypefun {lt_dlvtable *}lt_dlloader_remove (@w{const char 
*...@var{loader_name}})
 Remove the loader identified by the unique name, @var{loader_name}.
 Before this can succeed, all modules opened by the named loader must
-have been closed.  Returns 0 for success, otherwise an error message can
-be obtained from @code{lt_dlerror}.
+have been closed.  Returns the vtable of the removed loader for success,
+otherwise @code{NULL} in which case an error message can be obtained
+from @code{lt_dlerror}. The caller is responible for @code{free}ing the
+returned @var{vtable}, if that is needed.
 
 @example
 /* Remove myloader. */
-if (lt_dlloader_remove ("myloader") != 0)
-  perror (lt_dlerror ());
+lt_dlvtable *myloader = lt_dlloader_remove ("myloader");
+if (myloader)
+  free (myloader);
+else
+  fprintf (stderr, "lt_dlloader_remove failed: %s\n", lt_dlerror ());
+myloader = NULL;
 @end example
 @end deftypefun
 
-...@deftypefun {lt_dlloader *}lt_dlloader_next (@w{lt_dlloader 
*...@var{place}})
-Iterate over the module loaders, returning the first loader if @var{place} is
-...@code{null}, and the next one on subsequent calls.  The handle is for use 
with
-...@code{lt_dlloader_add}.
+...@deftypefun lt_dlloader lt_dlloader_next (@w{const lt_dlloader 
@var{loader}})
+Iterate over the module loaders, returning the first loader if @var{loader} is
+...@code{null}, and the next one on subsequent calls, or @code{NULL} if at the
+end of the list.  The handle is for use with @code{lt_dlloader_get}.
 
 @example
-/* Make myloader be the first one. */
-if (lt_dlloader_add (lt_dlloader_next (NULL), myloader) != 0)
-  return ERROR;
+/* Print the name of the first loader. */
+puts (lt_dlloader_get (lt_dlloader_next (NULL))->name);
 @end example
 @end deftypefun
 
-...@deftypefun {lt_dlloader *}lt_dlloader_find (@w{const char 
*...@var{loader_name}})
+...@deftypefun {const lt_dlvtable *}lt_dlloader_find (@w{const char 
*...@var{loader_name}})
 Return the first loader with a matching @var{loader_name} identifier, or else
 @code{NULL}, if the identifier is not found.
 
 The identifiers that may be used by libltdl itself, if the host
-architecture supports them are @dfn{dlop...@footnote{this is used for
-the host dependent module loading @sc{api} -- @code{shl_load} and
-...@code{loadlibrary} for example}, @dfn{dld} and @dfn{dlpreload}.
+architecture supports them are e.g. @dfn{lt_dlopen}, @dfn{lt_dld_link},
+...@dfn{lt_preopen}, @dfn{lt_dyld} and @dfn{lt_loadlibrary}.
 
 @example
 /* Add a user loader as the next module loader to be tried if
@@ -4453,20 +4494,13 @@ if (lt_dlloader_add (lt_dlloader_find ("dlopen"), 
myloader) != 0)
 @end example
 @end deftypefun
 
-...@deftypefun {const char *}lt_dlloader_name (@w{lt_dlloader *...@var{place}})
-Return the identifying name of @var{PLACE}, as obtained from
-...@code{lt_dlloader_next} or @code{lt_dlloader_find}.  If this function fails,
-it will return @code{NULL} and set an error for retrieval with
+...@deftypefun {const lt_dlvtable *}lt_dlloader_get (@w{lt_dlloader 
@var{loader}})
+This function returns the @var{vtable} associated with the @var{loader},
+as obtained from @code{lt_dlloader_next}.  If this function fails, it
+will return @code{NULL} and set an error for retrieval with
 @code{lt_dlerror}.
 @end deftypefun
 
-...@deftypefun {lt_user_data *}lt_dlloader_data (@w{lt_dlloader 
*...@var{place}})
-Return the address of the @code{dlloader_data} of @var{PLACE}, as
-obtained from @code{lt_dlloader_next} or @code{lt_dlloader_find}.  If
-this function fails, it will return @code{NULL} and set an error for
-retrieval with @code{lt_dlerror}.
-...@end deftypefun
-
 @subsection Error handling within user module loaders
 
 @deftypefun int lt_dladderror (@w{const char *...@var{diagnostic}})
@@ -4480,7 +4514,7 @@ If the allocation of an identifier fails, this function 
returns -1.
 @example
 int myerror = lt_dladderror ("Doh!");
 if (myerror < 0)
-  perror (lt_dlerror ());
+  fprintf (stderr, "lt_dladderror failed: %s\n", lt_dlerror ());
 @end example
 @end deftypefun
 
@@ -4493,7 +4527,7 @@ interface.  All of the standard errors used by libltdl 
are declared in
 
 @example
 if (lt_dlseterror (LTDL_ERROR_NO_MEMORY) != 0)
-  perror (lt_dlerror ());
+  fprintf (stderr, "lt_dlseterror failed: %s\n", lt_dlerror ());
 @end example
 @end deftypefun
 

Reply via email to