* validate.h
[bpt/guile.git] / libguile / extensions.c
1 /* extensions.c - registering and loading extensions.
2 *
3 * Copyright (C) 2001 Free Software Foundation, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program 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
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this software; see the file COPYING. If not, write to
17 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307 USA
19 *
20 * As a special exception, the Free Software Foundation gives permission
21 * for additional uses of the text contained in its release of GUILE.
22 *
23 * The exception is that, if you link the GUILE library with other files
24 * to produce an executable, this does not by itself cause the
25 * resulting executable to be covered by the GNU General Public License.
26 * Your use of that executable is in no way restricted on account of
27 * linking the GUILE library code into it.
28 *
29 * This exception does not however invalidate any other reasons why
30 * the executable file might be covered by the GNU General Public License.
31 *
32 * This exception applies only to the code released by the
33 * Free Software Foundation under the name GUILE. If you copy
34 * code from other Free Software Foundation releases into a copy of
35 * GUILE, as the General Public License permits, the exception does
36 * not apply to the code that you add in this way. To avoid misleading
37 * anyone as to the status of such modified files, you must delete
38 * this exception notice from them.
39 *
40 * If you write modifications of your own for GUILE, it is your choice
41 * whether to permit this exception to apply to your modifications.
42 * If you do not wish that, delete this exception notice. */
43
44 #include "libguile/_scm.h"
45 #include "libguile/strings.h"
46 #include "libguile/gc.h"
47 #include "libguile/dynl.h"
48
49 #include "libguile/extensions.h"
50
51 typedef struct extension_t
52 {
53 struct extension_t *next;
54 const char *lib;
55 const char *init;
56 void (*func)(void *);
57 void *data;
58 } extension_t;
59
60 static extension_t *registered_extensions;
61
62 void
63 scm_c_register_extension (const char *lib, const char *init,
64 void (*func) (void *), void *data)
65 {
66 extension_t *ext = scm_must_malloc (sizeof(extension_t),
67 "scm_register_extension");
68 ext->lib = scm_must_strdup (lib);
69 ext->init = scm_must_strdup (init);
70 ext->func = func;
71 ext->data = data;
72
73 ext->next = registered_extensions;
74 registered_extensions = ext;
75 }
76
77 static void
78 load_extension (SCM lib, SCM init)
79 {
80 /* Search the registry. */
81 {
82 extension_t *ext;
83
84 for (ext = registered_extensions; ext; ext = ext->next)
85 if (!strcmp (ext->lib, SCM_STRING_CHARS (lib))
86 && !strcmp (ext->init, SCM_STRING_CHARS (init)))
87 {
88 ext->func (ext->data);
89 return;
90 }
91 }
92
93 /* Dynamically link the library. */
94
95 scm_dynamic_call (init, scm_dynamic_link (lib));
96 }
97
98 void
99 scm_c_load_extension (const char *lib, const char *init)
100 {
101 load_extension (scm_makfrom0str (lib), scm_makfrom0str (init));
102 }
103
104 SCM_DEFINE (scm_load_extension, "load-extension", 2, 0, 0,
105 (SCM lib, SCM init),
106 "Load and initilize the extension designated by LIB and INIT."
107 "When there is no pre-registered function for LIB/INIT, this is "
108 "equivalent to "
109 " "
110 " (dynamic-call INIT (dynamic-link LIB)) "
111 " "
112 "When there is a pre-registered function, that function is called "
113 "instead. "
114 " "
115 "Normally, there is no pre-registered function. This option exists "
116 "only for situations where dynamic linking is unavailable or unwanted. "
117 "In that case, you would statically link your program with the desired "
118 "library, and register its init function right after Guile has been "
119 "initialized. "
120 " "
121 "LIB should be a string denoting a shared library without any file type "
122 "suffix such as \".so\". The suffix is provided automatically. It "
123 "should also not contain any directory components. Libraries that "
124 "implement Guile Extensions should be put into the normal locations for "
125 "shared libraries. We recommend to use the naming convention "
126 "libguile-bla-blum for a extension related to a module `(bla blum)'. "
127 " "
128 "The normal way for a extension to be used is to write a small Scheme "
129 "file that defines a module, and to load the extension into this "
130 "module. When the module is auto-loaded, the extension is loaded as "
131 "well. For example, "
132 " "
133 " (define-module (bla blum)) "
134 " "
135 " (load-extension \"libguile-bla-blum\" \"bla_init_blum\")")
136 #define FUNC_NAME s_scm_load_extension
137 {
138 SCM_VALIDATE_STRING (1, lib);
139 SCM_VALIDATE_STRING (2, init);
140 load_extension (lib, init);
141 return SCM_UNSPECIFIED;
142 }
143 #undef FUNC_NAME
144
145 void
146 scm_init_extensions ()
147 {
148 registered_extensions = NULL;
149 #ifndef SCM_MAGIC_SNARFER
150 #include "libguile/extensions.x"
151 #endif
152 }
153
154 /*
155 Local Variables:
156 c-file-style: "gnu"
157 End:
158 */