Add `ChangeLog-2008' files to the distribution.
[bpt/guile.git] / libguile / extensions.c
CommitLineData
e2ab7927
MV
1/* extensions.c - registering and loading extensions.
2 *
2b829bbb 3 * Copyright (C) 2001, 2006 Free Software Foundation, Inc.
e2ab7927 4 *
73be1d9e
MV
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
e2ab7927 9 *
73be1d9e
MV
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
e2ab7927 14 *
73be1d9e
MV
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
92205699 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
73be1d9e 18 */
e2ab7927 19
c0fc1089
RB
20#if HAVE_CONFIG_H
21# include <config.h>
22#endif
23
fbbdb121
GH
24#include <string.h>
25
e2ab7927
MV
26#include "libguile/_scm.h"
27#include "libguile/strings.h"
28#include "libguile/gc.h"
29#include "libguile/dynl.h"
4695c759 30#include "libguile/dynwind.h"
e2ab7927
MV
31
32#include "libguile/extensions.h"
33
1be6b49c
ML
34typedef struct extension_t
35{
36 struct extension_t *next;
e2ab7927
MV
37 const char *lib;
38 const char *init;
39 void (*func)(void *);
40 void *data;
1be6b49c 41} extension_t;
e2ab7927 42
1be6b49c 43static extension_t *registered_extensions;
e2ab7927 44
bef38a17
MV
45/* Register a LIB/INIT pair for use by `scm_load_extension'. LIB is
46 allowed to be NULL and then only INIT is used to identify the
47 registered entry. This is useful when you don't know the library
48 name (which isn't really relevant anyway in a completely linked
49 program) and you are sure that INIT is unique (which it must be for
50 static linking). Hmm, given this reasoning, what use is LIB
51 anyway?
52*/
53
e2ab7927
MV
54void
55scm_c_register_extension (const char *lib, const char *init,
56 void (*func) (void *), void *data)
57{
4c9419ac 58 extension_t *ext = scm_malloc (sizeof(extension_t));
bef38a17 59 if (lib)
4c9419ac 60 ext->lib = scm_strdup (lib);
bef38a17
MV
61 else
62 ext->lib = NULL;
4c9419ac 63 ext->init = scm_strdup (init);
e2ab7927
MV
64 ext->func = func;
65 ext->data = data;
66
67 ext->next = registered_extensions;
68 registered_extensions = ext;
69}
70
71static void
72load_extension (SCM lib, SCM init)
73{
74 /* Search the registry. */
4695c759
MV
75 if (registered_extensions != NULL)
76 {
77 extension_t *ext;
78 char *clib, *cinit;
79
661ae7ab 80 scm_dynwind_begin (0);
4695c759
MV
81
82 clib = scm_to_locale_string (lib);
661ae7ab 83 scm_dynwind_free (clib);
4695c759 84 cinit = scm_to_locale_string (init);
661ae7ab 85 scm_dynwind_free (cinit);
4695c759
MV
86
87 for (ext = registered_extensions; ext; ext = ext->next)
88 if ((ext->lib == NULL || !strcmp (ext->lib, clib))
89 && !strcmp (ext->init, cinit))
90 {
91 ext->func (ext->data);
92 break;
93 }
94
661ae7ab 95 scm_dynwind_end ();
4695c759 96 }
e2ab7927
MV
97
98 /* Dynamically link the library. */
e2ab7927
MV
99 scm_dynamic_call (init, scm_dynamic_link (lib));
100}
101
102void
103scm_c_load_extension (const char *lib, const char *init)
104{
4695c759 105 load_extension (scm_from_locale_string (lib), scm_from_locale_string (init));
e2ab7927
MV
106}
107
108SCM_DEFINE (scm_load_extension, "load-extension", 2, 0, 0,
109 (SCM lib, SCM init),
72dd0a03 110 "Load and initialize the extension designated by LIB and INIT.\n"
9401323e
NJ
111 "When there is no pre-registered function for LIB/INIT, this is\n"
112 "equivalent to\n"
113 "\n"
114 "@lisp\n"
115 "(dynamic-call INIT (dynamic-link LIB))\n"
116 "@end lisp\n"
117 "\n"
118 "When there is a pre-registered function, that function is called\n"
119 "instead.\n"
120 "\n"
121 "Normally, there is no pre-registered function. This option exists\n"
122 "only for situations where dynamic linking is unavailable or unwanted.\n"
123 "In that case, you would statically link your program with the desired\n"
124 "library, and register its init function right after Guile has been\n"
125 "initialized.\n"
126 "\n"
127 "LIB should be a string denoting a shared library without any file type\n"
128 "suffix such as \".so\". The suffix is provided automatically. It\n"
129 "should also not contain any directory components. Libraries that\n"
130 "implement Guile Extensions should be put into the normal locations for\n"
131 "shared libraries. We recommend to use the naming convention\n"
132 "libguile-bla-blum for a extension related to a module `(bla blum)'.\n"
133 "\n"
134 "The normal way for a extension to be used is to write a small Scheme\n"
135 "file that defines a module, and to load the extension into this\n"
136 "module. When the module is auto-loaded, the extension is loaded as\n"
137 "well. For example,\n"
138 "\n"
139 "@lisp\n"
140 "(define-module (bla blum))\n"
141 "\n"
142 "(load-extension \"libguile-bla-blum\" \"bla_init_blum\")\n"
143 "@end lisp")
e2ab7927
MV
144#define FUNC_NAME s_scm_load_extension
145{
e2ab7927
MV
146 load_extension (lib, init);
147 return SCM_UNSPECIFIED;
148}
149#undef FUNC_NAME
150
151void
152scm_init_extensions ()
153{
154 registered_extensions = NULL;
e2ab7927 155#include "libguile/extensions.x"
e2ab7927
MV
156}
157
158/*
159 Local Variables:
160 c-file-style: "gnu"
161 End:
162*/