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