Mercurial > hg > xemacs-beta
annotate src/emodules.c @ 4539:061e030e3270
Fix some bugs in load-history construction, built-in symbol file names.
lib-src/ChangeLog addition:
2008-12-27 Aidan Kehoe <kehoea@parhasard.net>
* make-docfile.c (main): Allow more than one -d argument, followed
by a directory to change to.
(put_filename): Don't strip directory information; with previous
change, allows retrieval of Lisp function and variable origin
files from #'built-in-symbol-file relative to lisp-directory.
(scan_lisp_file): Don't add an extraneous newline after the file
name, put_filename has added the newline already.
lisp/ChangeLog addition:
2008-12-27 Aidan Kehoe <kehoea@parhasard.net>
* loadup.el (load-history):
Add the contents of current-load-list to load-history before
clearing it. Move the variable declarations earlier in the file to
a format understood by make-docfile.c.
* custom.el (custom-declare-variable): Add the variable's symbol
to the current file's load history entry correctly, don't use a
cons. Eliminate a comment that we don't need to worry about, we
don't need to check the `initialized' C variable in Lisp.
* bytecomp.el (byte-compile-output-file-form):
Merge Andreas Schwab's pre-GPLv3 GNU change of 19970831 here;
treat #'custom-declare-variable correctly, generating the
docstrings in a format understood by make-docfile.c.
* loadhist.el (symbol-file): Correct behaviour for checking
autoloaded macros and functions when supplied with a TYPE
argument. Accept fully-qualified paths from
#'built-in-symbol-file; if a path is not fully-qualified, return
it relative to lisp-directory if the filename corresponds to a
Lisp file, and relative to (concat source-directory "/src/")
otherwise.
* make-docfile.el (preloaded-file-list):
Rationalise some let bindings a little. Use the "-d" argument to
make-docfile.c to supply Lisp paths relative to lisp-directory,
not absolutely. Add in loadup.el explicitly to the list of files
to be processed by make-docfile.c--it doesn't make sense to add it
to preloaded-file-list, since that is used for purposes of
byte-compilation too.
src/ChangeLog addition:
2008-12-27 Aidan Kehoe <kehoea@parhasard.net>
* doc.c (Fbuilt_in_symbol_file):
Return a subr's filename immediately if we've found it. Check for
compiled function and compiled macro docstrings in DOC too, and
return them if they exist.
The branch of the if statement focused on functions may have
executed, but we may still want to check variable bindings; an
else clause isn't appropriate.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Sat, 27 Dec 2008 14:05:50 +0000 |
parents | 726060ee587c |
children | 19a72041c5ed |
rev | line source |
---|---|
428 | 1 /* emodules.c - Support routines for dynamic module loading |
2 (C) Copyright 1998, 1999 J. Kean Johnston. All rights reserved. | |
3 | |
4 This file is part of XEmacs. | |
5 | |
6 XEmacs is free software; you can redistribute it and/or modify it | |
7 under the terms of the GNU General Public License as published by the | |
8 Free Software Foundation; either version 2, or (at your option) any | |
9 later version. | |
10 | |
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with XEmacs; see the file COPYING. If not, write to | |
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
19 Boston, MA 02111-1307, USA. */ | |
20 | |
21 #include "emodules.h" | |
22 #include "sysdll.h" | |
2078 | 23 #ifdef HAVE_LTDL |
24 #include <ltdl.h> | |
25 #endif | |
428 | 26 |
1750 | 27 /* Load path */ |
28 static Lisp_Object Vmodule_load_path; | |
29 | |
30 /* Module lFile extensions */ | |
31 static Lisp_Object Vmodule_extensions; | |
32 | |
428 | 33 #ifdef HAVE_SHLIB |
34 | |
35 /* CE-Emacs version number */ | |
36 Lisp_Object Vmodule_version; | |
37 | |
38 /* Do we do our work quietly? */ | |
39 int load_modules_quietly; | |
40 | |
996 | 41 /* Set this while unloading a module. This should NOT be made set by users, |
42 as it allows the unbinding of symbol-value-forward variables. */ | |
43 int unloading_module; | |
44 | |
564 | 45 Lisp_Object Qdll_error; |
996 | 46 Lisp_Object Qmodule, Qunload_module, module_tag; |
564 | 47 |
428 | 48 typedef struct _emodules_list |
49 { | |
996 | 50 int used; /* Is this slot used? */ |
1706 | 51 CIbyte *soname; /* Name of the shared object loaded (full path) */ |
52 CIbyte *modname; /* The name of the module */ | |
53 CIbyte *modver; /* The module version string */ | |
54 CIbyte *modtitle; /* How the module announces itself */ | |
996 | 55 void (*unload)(void); /* Module cleanup function to run before unloading */ |
56 dll_handle dlhandle; /* Dynamic lib handle */ | |
428 | 57 } emodules_list; |
58 | |
59 static int emodules_depth; | |
60 static dll_handle dlhandle; | |
61 static emodules_list *modules; | |
62 static int modnum; | |
63 | |
1706 | 64 static int find_make_module (const CIbyte *mod, const CIbyte *name, |
65 const CIbyte *ver, int make_or_find); | |
428 | 66 static Lisp_Object module_load_unwind (Lisp_Object); |
67 static void attempt_module_delete (int mod); | |
68 | |
69 DEFUN ("load-module", Fload_module, 1, 3, "FLoad dynamic module: ", /* | |
70 Load in a C Emacs Extension module named FILE. | |
71 The optional NAME and VERSION are used to identify specific modules. | |
72 | |
996 | 73 DO NOT USE THIS FUNCTION in your programs. Use `require' instead. |
74 | |
428 | 75 This function is similar in intent to `load' except that it loads in |
76 pre-compiled C or C++ code, using dynamic shared objects. If NAME is | |
77 specified, then the module is only loaded if its internal name matches | |
78 the NAME specified. If VERSION is specified, then the module is only | |
79 loaded if it matches that VERSION. This function will check to make | |
80 sure that the same module is not loaded twice. Modules are searched | |
81 for in the same way as Lisp files, except that the valid file | |
1632 | 82 extensions are `.so', `.dll', `.ell', or `.dylib'. |
428 | 83 |
84 All symbols in the shared module must be completely resolved in order | |
85 for this function to be successful. Any modules which the specified | |
86 FILE depends on will be automatically loaded. You can determine which | |
87 modules have been loaded as dynamic shared objects by examining the | |
88 return value of the function `list-modules'. | |
89 | |
996 | 90 It is possible, although unwise, to unload modules using `unload-feature'. |
442 | 91 The preferred mechanism for unloading or reloading modules is to quit |
428 | 92 XEmacs, and then reload those new or changed modules that are required. |
93 | |
94 Messages informing you of the progress of the load are displayed unless | |
95 the variable `load-modules-quietly' is non-NIL. | |
96 */ | |
444 | 97 (file, name, version)) |
428 | 98 { |
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
99 const CIbyte *mod, *mname, *mver; |
428 | 100 int speccount = specpdl_depth(); |
101 | |
102 CHECK_STRING(file); | |
103 | |
1706 | 104 mod = (CIbyte *) XSTRING_DATA (file); |
428 | 105 |
106 if (NILP (name)) | |
107 mname = ""; | |
108 else | |
1706 | 109 mname = (CIbyte *) XSTRING_DATA (name); |
428 | 110 |
111 if (NILP (version)) | |
112 mver = ""; | |
113 else | |
1706 | 114 mver = (CIbyte *) XSTRING_DATA (version); |
428 | 115 |
116 dlhandle = 0; | |
117 record_unwind_protect (module_load_unwind, make_int(modnum)); | |
118 emodules_load (mod, mname, mver); | |
771 | 119 unbind_to (speccount); |
428 | 120 |
121 return Qt; | |
122 } | |
123 | |
996 | 124 DEFUN ("unload-module", Funload_module, 1, 3, 0, /* |
125 Unload a module previously loaded with load-module. | |
428 | 126 |
996 | 127 DO NOT USE THIS FUNCTION in your programs. Use `unload-feature' instead. |
428 | 128 |
129 As with load-module, this function requires at least the module FILE, and | |
130 optionally the module NAME and VERSION to unload. It may not be possible | |
131 for the module to be unloaded from memory, as there may be Lisp objects | |
442 | 132 referring to variables inside the module code. However, once you have |
428 | 133 requested a module to be unloaded, it will be unloaded from memory as |
134 soon as the last reference to symbols within the module is destroyed. | |
135 */ | |
444 | 136 (file, name, version)) |
428 | 137 { |
138 int x; | |
4528
726060ee587c
First draft of g++ 4.3 warning removal patch. Builds. *Needs ChangeLogs.*
Stephen J. Turnbull <stephen@xemacs.org>
parents:
4522
diff
changeset
|
139 const CIbyte *mod, *mname, *mver; |
996 | 140 Lisp_Object foundname = Qnil; |
141 struct gcpro gcpro1; | |
428 | 142 |
143 CHECK_STRING(file); | |
144 | |
996 | 145 GCPRO1 (foundname); |
146 if (locate_file (Vmodule_load_path, file, Vmodule_extensions, &foundname, 0) | |
147 < 0) | |
148 return Qt; | |
1706 | 149 mod = (CIbyte *) XSTRING_DATA (foundname); |
996 | 150 UNGCPRO; |
428 | 151 |
152 if (NILP (name)) | |
153 mname = ""; | |
154 else | |
1706 | 155 mname = (CIbyte *) XSTRING_DATA (name); |
428 | 156 |
157 if (NILP (version)) | |
158 mver = ""; | |
159 else | |
1706 | 160 mver = (CIbyte *) XSTRING_DATA (version); |
428 | 161 |
162 x = find_make_module (mod, mname, mver, 1); | |
163 if (x != -1) | |
996 | 164 { |
165 if (modules[x].unload != NULL) | |
166 modules[x].unload (); | |
167 attempt_module_delete (x); | |
168 } | |
428 | 169 return Qt; |
170 } | |
171 | |
172 DEFUN ("list-modules", Flist_modules, 0, 0, "", /* | |
173 Produce a list of loaded dynamic modules. | |
174 | |
175 This function will return a list of all the loaded dynamic modules. | |
176 Each element in the list is a list in the form (SONAME NAME VER DESC), | |
177 where SONAME is the name of the shared object that was loaded, NAME | |
178 is the internal module name, VER is the version of the module, and DESC | |
179 is how the module describes itself. | |
180 | |
181 This function returns a list, so you will need to assign the return value | |
182 to a variable and then examine the variable with `describe-variable'. | |
183 For example: | |
184 | |
185 (setq mylist (list-modules)) | |
186 (describe-variable 'mylist) | |
187 | |
188 | |
189 NOTE: It is possible for the same module to be loaded more than once, | |
190 at different versions. However, you should never see the same module, | |
191 with the same name and version, loaded more than once. If you do, this | |
192 is a bug, and you are encouraged to report it. | |
193 */ | |
194 ()) | |
195 { | |
196 Lisp_Object mlist = Qnil; | |
197 int i; | |
198 | |
199 for (i = 0; i < modnum; i++) | |
200 { | |
201 if (modules[i].used == 1) | |
202 mlist = Fcons (list4 (build_string (modules[i].soname), | |
203 build_string (modules[i].modname), | |
204 build_string (modules[i].modver), | |
205 build_string (modules[i].modtitle)), mlist); | |
206 } | |
207 | |
208 return mlist; | |
209 } | |
210 | |
211 static int | |
1706 | 212 find_make_module (const CIbyte *mod, const CIbyte *name, const CIbyte *ver, |
213 int mof) | |
428 | 214 { |
215 int i, fs = -1; | |
216 | |
217 for (i = 0; i < modnum; i++) | |
218 { | |
219 if (fs == -1 && modules[i].used == 0) | |
220 fs = i; | |
221 if (strcmp (modules[i].soname, mod) == 0) | |
222 { | |
223 if (name && name[0] && strcmp (modules[i].modname, name)) | |
224 continue; | |
225 if (ver && ver[0] && strcmp (modules[i].modver, ver)) | |
226 continue; | |
227 return i; /* Found a match */ | |
228 } | |
229 } | |
230 | |
231 if (mof) | |
232 return fs; | |
233 | |
234 if (fs != -1) | |
235 return fs; /* First free slot */ | |
236 | |
237 /* | |
442 | 238 * We only get here if we haven't found a free slot and the module was |
428 | 239 * not previously loaded. |
240 */ | |
1706 | 241 if (modules == NULL) |
2367 | 242 modules = xnew (emodules_list); |
428 | 243 modnum++; |
2367 | 244 XREALLOC_ARRAY (modules, emodules_list, modnum); |
428 | 245 |
246 fs = modnum - 1; | |
2367 | 247 memset (&modules[fs], 0, sizeof (emodules_list)); |
428 | 248 return fs; |
249 } | |
250 | |
251 static void | |
252 attempt_module_delete (int mod) | |
253 { | |
254 if (dll_close (modules[mod].dlhandle) == 0) | |
255 { | |
1726 | 256 xfree (modules[mod].soname, CIbyte *); |
257 xfree (modules[mod].modname, CIbyte *); | |
258 xfree (modules[mod].modver, CIbyte *); | |
259 xfree (modules[mod].modtitle, CIbyte *); | |
428 | 260 modules[mod].dlhandle = 0; |
261 modules[mod].used = 0; | |
262 } | |
263 else if (modules[mod].used > 1) | |
264 modules[mod].used = 1; /* We couldn't delete it - it stays */ | |
265 } | |
266 | |
267 static Lisp_Object | |
268 module_load_unwind (Lisp_Object upto) | |
269 { | |
270 int x,l=0; | |
271 | |
272 /* | |
273 * First close off the current handle if it is open. | |
274 */ | |
275 if (dlhandle != 0) | |
276 dll_close (dlhandle); | |
277 dlhandle = 0; | |
278 | |
279 if (CONSP (upto)) | |
280 { | |
281 if (INTP (XCAR (upto))) | |
282 l = XINT (XCAR (upto)); | |
853 | 283 free_cons (upto); |
428 | 284 } |
285 else | |
286 l = XINT (upto); | |
287 | |
288 /* | |
289 * Here we need to go through and dlclose() (IN REVERSE ORDER!) any | |
290 * modules that were loaded as part of this load chain. We only mark | |
291 * the slots as closed if the dlclose() succeeds. | |
292 */ | |
293 for (x = modnum-1; x >= l; x--) | |
294 { | |
295 if (modules[x].used > 1) | |
296 attempt_module_delete (x); | |
297 } | |
298 emodules_depth = 0; | |
299 | |
300 return Qnil; | |
301 } | |
302 | |
303 /* | |
304 * Do the actual grunt-work of loading in a module. We first try and | |
305 * dlopen() the module. If that fails, we have an error and we bail | |
306 * out immediately. If the dlopen() succeeds, we need to check for the | |
442 | 307 * existence of certain special symbols. |
428 | 308 * |
309 * All modules will have complete access to the variables and functions | |
310 * defined within XEmacs itself. It is up to the module to declare any | |
311 * variables or functions it uses, however. Modules will also have access | |
312 * to other functions and variables in other loaded modules, unless they | |
313 * are defined as STATIC. | |
314 * | |
315 * We need to be very careful with how we load modules. If we encounter an | |
316 * error along the way, we need to back out completely to the point at | |
442 | 317 * which the user started. Since we can be called recursively, we need to |
428 | 318 * take care with marking modules as loaded. When we first start loading |
319 * modules, we set the counter to zero. As we enter the function each time, | |
442 | 320 * we increment the counter, and before we leave we decrement it. When |
428 | 321 * we get back down to 0, we know we are at the end of the chain and we |
322 * can mark all the modules in the list as loaded. | |
323 * | |
324 * When we signal an error, we need to be sure to unwind all modules loaded | |
325 * thus far (but only for this module chain). It is assumed that if any | |
326 * modules in a chain fail, then they all do. This is logical, considering | |
442 | 327 * that the only time we recurse is when we have dependent modules. So in |
428 | 328 * the error handler we take great care to close off the module chain before |
329 * we call "error" and let the Fmodule_load unwind_protect() function handle | |
330 * the cleaning up. | |
331 */ | |
332 void | |
1706 | 333 emodules_load (const CIbyte *module, const CIbyte *modname, |
334 const CIbyte *modver) | |
428 | 335 { |
2367 | 336 /* !!#### Needs serious work */ |
996 | 337 Lisp_Object old_load_list; |
428 | 338 Lisp_Object filename; |
996 | 339 Lisp_Object foundname, lisp_modname; |
340 int x, mpx; | |
1706 | 341 CIbyte *soname; |
342 const CIbyte **f; | |
442 | 343 const long *ellcc_rev; |
1706 | 344 CIbyte *mver, *mname, *mtitle, *symname; |
428 | 345 void (*modload)(void) = 0; |
346 void (*modsyms)(void) = 0; | |
347 void (*modvars)(void) = 0; | |
348 void (*moddocs)(void) = 0; | |
996 | 349 void (*modunld)(void) = 0; |
428 | 350 emodules_list *mp; |
996 | 351 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
428 | 352 |
353 filename = Qnil; | |
354 foundname = Qnil; | |
355 | |
356 emodules_depth++; | |
357 dlhandle = 0; | |
358 | |
1706 | 359 if (module == NULL || module[0] == '\0') |
563 | 360 invalid_argument ("Empty module name", Qunbound); |
428 | 361 |
996 | 362 GCPRO4(filename, foundname, old_load_list, lisp_modname); |
363 filename = build_string (module); | |
364 if (locate_file (Vmodule_load_path, filename, Vmodule_extensions, | |
365 &foundname, 0) < 0) | |
563 | 366 signal_error (Qdll_error, "Cannot open dynamic module", filename); |
428 | 367 |
1706 | 368 LISP_STRING_TO_EXTERNAL (foundname, soname, Qfile_name); |
996 | 369 lisp_modname = call1 (Qfile_name_sans_extension, |
370 Ffile_name_nondirectory (foundname)); | |
428 | 371 |
1706 | 372 dlhandle = dll_open (foundname); |
373 if (dlhandle == NULL) | |
563 | 374 { |
1811 | 375 signal_error (Qdll_error, "Opening dynamic module", dll_error ()); |
563 | 376 } |
428 | 377 |
442 | 378 ellcc_rev = (const long *)dll_variable (dlhandle, "emodule_compiler"); |
1706 | 379 if (ellcc_rev == NULL || *ellcc_rev <= 0L) |
563 | 380 signal_error (Qdll_error, "Invalid dynamic module: Missing symbol `emodule_compiler'", Qunbound); |
428 | 381 if (*ellcc_rev > EMODULES_REVISION) |
563 | 382 signal_ferror (Qdll_error, "Invalid dynamic module: Unsupported version `%ld(%ld)'", *ellcc_rev, EMODULES_REVISION); |
428 | 383 |
1706 | 384 f = (const CIbyte **) dll_variable (dlhandle, "emodule_name"); |
385 if (f == NULL || *f == NULL) | |
563 | 386 signal_error (Qdll_error, "Invalid dynamic module: Missing symbol `emodule_name'", Qunbound); |
428 | 387 |
1706 | 388 mname = (CIbyte *) ALLOCA (strlen (*f) + 1); |
428 | 389 strcpy (mname, *f); |
390 if (mname[0] == '\0') | |
563 | 391 signal_error (Qdll_error, "Invalid dynamic module: Empty value for `emodule_name'", Qunbound); |
428 | 392 |
1706 | 393 f = (const CIbyte **) dll_variable (dlhandle, "emodule_version"); |
394 if (f == NULL || *f == NULL) | |
563 | 395 signal_error (Qdll_error, "Missing symbol `emodule_version': Invalid dynamic module", Qunbound); |
428 | 396 |
1706 | 397 mver = (CIbyte *) ALLOCA (strlen (*f) + 1); |
428 | 398 strcpy (mver, *f); |
399 | |
1706 | 400 f = (const CIbyte **) dll_variable (dlhandle, "emodule_title"); |
401 if (f == NULL || *f == NULL) | |
563 | 402 signal_error (Qdll_error, "Invalid dynamic module: Missing symbol `emodule_title'", Qunbound); |
428 | 403 |
1706 | 404 mtitle = (CIbyte *) ALLOCA (strlen (*f) + 1); |
428 | 405 strcpy (mtitle, *f); |
406 | |
1706 | 407 symname = (CIbyte *) ALLOCA (strlen (mname) + 15); |
428 | 408 |
409 strcpy (symname, "modules_of_"); | |
410 strcat (symname, mname); | |
411 modload = (void (*)(void))dll_function (dlhandle, symname); | |
412 /* | |
442 | 413 * modload is optional. If the module doesn't require other modules it can |
428 | 414 * be left out. |
415 */ | |
416 | |
417 strcpy (symname, "syms_of_"); | |
418 strcat (symname, mname); | |
419 modsyms = (void (*)(void))dll_function (dlhandle, symname); | |
1706 | 420 if (modsyms == NULL) |
563 | 421 { |
422 missing_symbol: | |
423 signal_error (Qdll_error, "Invalid dynamic module: Missing symbol", | |
424 build_string (symname)); | |
425 } | |
428 | 426 |
427 strcpy (symname, "vars_of_"); | |
428 strcat (symname, mname); | |
429 modvars = (void (*)(void))dll_function (dlhandle, symname); | |
1706 | 430 if (modvars == NULL) |
563 | 431 goto missing_symbol; |
428 | 432 |
433 strcpy (symname, "docs_of_"); | |
434 strcat (symname, mname); | |
435 moddocs = (void (*)(void))dll_function (dlhandle, symname); | |
1706 | 436 if (moddocs == NULL) |
563 | 437 goto missing_symbol; |
428 | 438 |
996 | 439 /* Now look for the optional unload function. */ |
440 strcpy (symname, "unload_"); | |
441 strcat (symname, mname); | |
442 modunld = (void (*)(void))dll_function (dlhandle, symname); | |
443 | |
428 | 444 if (modname && modname[0] && strcmp (modname, mname)) |
563 | 445 signal_error (Qdll_error, "Module name mismatch", Qunbound); |
428 | 446 |
447 if (modver && modver[0] && strcmp (modver, mver)) | |
563 | 448 signal_error (Qdll_error, "Module version mismatch", Qunbound); |
428 | 449 |
450 /* | |
451 * Attempt to make a new slot for this module. If this really is the | |
452 * first time we are loading this module, the used member will be 0. | |
453 * If that is non-zero, we know that we have a previously loaded module | |
442 | 454 * of the same name and version, and we don't need to go any further. |
428 | 455 */ |
456 mpx = find_make_module (soname, mname, mver, 0); | |
457 mp = &modules[mpx]; | |
458 if (mp->used > 0) | |
459 { | |
460 emodules_depth--; | |
461 dll_close (dlhandle); | |
806 | 462 dlhandle = 0; /* Zero this out before module_load_unwind runs */ |
428 | 463 return; |
464 } | |
465 | |
466 if (!load_modules_quietly) | |
467 message ("Loading %s v%s (%s)", mname, mver, mtitle); | |
468 | |
469 /* | |
470 * We have passed the basic initialization, and can now add this | |
471 * module to the list of modules. | |
472 */ | |
473 mp->used = emodules_depth + 1; | |
474 mp->soname = xstrdup (soname); | |
475 mp->modname = xstrdup (mname); | |
476 mp->modver = xstrdup (mver); | |
477 mp->modtitle = xstrdup (mtitle); | |
478 mp->dlhandle = dlhandle; | |
996 | 479 mp->unload = modunld; |
428 | 480 dlhandle = 0; |
481 | |
996 | 482 old_load_list = Vcurrent_load_list; |
483 Vcurrent_load_list = Qnil; | |
484 LOADHIST_ATTACH (lisp_modname); | |
485 LOADHIST_ATTACH (module_tag); | |
486 | |
428 | 487 /* |
488 * Now we need to call the module init function and perform the various | |
489 * startup tasks. | |
490 */ | |
491 if (modload != 0) | |
492 (*modload)(); | |
493 | |
494 /* | |
495 * Now we can get the module to initialize its symbols, and then its | |
496 * variables, and lastly the documentation strings. | |
497 */ | |
498 (*modsyms)(); | |
499 (*modvars)(); | |
500 (*moddocs)(); | |
501 | |
502 if (!load_modules_quietly) | |
503 message ("Loaded module %s v%s (%s)", mname, mver, mtitle); | |
504 | |
996 | 505 Vload_history = Fcons (Fnreverse (Vcurrent_load_list), Vload_history); |
506 Vcurrent_load_list = old_load_list; | |
507 UNGCPRO; | |
428 | 508 |
509 emodules_depth--; | |
510 if (emodules_depth == 0) | |
511 { | |
512 /* | |
513 * We have reached the end of the load chain. We now go through the | |
514 * list of loaded modules and mark all the valid modules as just | |
515 * that. | |
516 */ | |
517 for (x = 0; x < modnum; x++) | |
518 if (modules[x].used > 1) | |
519 modules[x].used = 1; | |
520 } | |
521 } | |
522 | |
523 void | |
442 | 524 emodules_doc_subr(const char *symname, const char *doc) |
428 | 525 { |
526 Bytecount len = strlen (symname); | |
867 | 527 Lisp_Object sym = oblookup (Vobarray, (const Ibyte *)symname, len); |
440 | 528 Lisp_Subr *subr; |
428 | 529 |
1632 | 530 /* Skip autoload cookies */ |
531 if (SYMBOLP (sym) && SUBRP (XSYMBOL (sym)->function)) | |
428 | 532 { |
1632 | 533 subr = XSUBR (XSYMBOL (sym)->function); |
428 | 534 subr->doc = xstrdup (doc); |
535 } | |
536 /* | |
537 * FIXME: I wish there was some way to avoid the xstrdup(). Is it | |
538 * possible to just set a pointer to the string, or somehow create a | |
539 * symbol whose value we can point to the constant string? Can someone | |
540 * look into this? | |
541 */ | |
542 } | |
543 | |
544 void | |
442 | 545 emodules_doc_sym (const char *symname, const char *doc) |
428 | 546 { |
547 Bytecount len = strlen (symname); | |
867 | 548 Lisp_Object sym = oblookup (Vobarray, (const Ibyte *)symname, len); |
428 | 549 Lisp_Object docstr; |
550 struct gcpro gcpro1; | |
551 | |
552 if (SYMBOLP(sym)) | |
553 { | |
554 docstr = build_string (doc); | |
555 GCPRO1(docstr); | |
556 Fput (sym, Qvariable_documentation, docstr); | |
557 UNGCPRO; | |
558 } | |
559 } | |
560 | |
561 | |
562 void | |
563 syms_of_module (void) | |
564 { | |
564 | 565 DEFERROR_STANDARD (Qdll_error, Qerror); |
996 | 566 DEFSYMBOL (Qmodule); |
567 DEFSYMBOL (Qunload_module); | |
428 | 568 DEFSUBR(Fload_module); |
569 DEFSUBR(Flist_modules); | |
570 DEFSUBR(Funload_module); | |
996 | 571 module_tag = Fcons (Qmodule, Qnil); |
572 staticpro (&module_tag); | |
573 Fput (Qunload_module, Qdisabled, Qt); | |
428 | 574 } |
575 | |
576 void | |
577 reinit_vars_of_module (void) | |
578 { | |
579 emodules_depth = 0; | |
1706 | 580 modules = NULL; |
428 | 581 modnum = 0; |
582 } | |
583 | |
1750 | 584 #endif /* HAVE_SHLIB */ |
585 | |
428 | 586 void |
587 vars_of_module (void) | |
588 { | |
1750 | 589 #ifdef HAVE_SHLIB |
590 Fprovide (intern ("modules")); | |
591 | |
2078 | 592 #ifdef HAVE_LTDL |
593 lt_dlinit (); | |
594 lt_dlmalloc = (lt_ptr (*) (size_t)) xmalloc; | |
595 lt_dlrealloc = (lt_ptr (*) (lt_ptr, size_t)) xrealloc; | |
596 lt_dlfree = (void (*) (lt_ptr)) xfree_1; | |
597 #endif | |
598 | |
428 | 599 DEFVAR_LISP ("module-version", &Vmodule_version /* |
600 Emacs dynamic loading mechanism version, as a string. | |
601 | |
602 This string is in the form XX.YY.ppp, where XX is the major version | |
603 number, YY is the minor version number, and ppp is the patch level. | |
442 | 604 This variable can be used to distinguish between different versions of |
428 | 605 the dynamic loading technology used in Emacs, if required. It is not |
606 a given that this value will be the same as the Emacs version number. | |
607 */ ); | |
608 Vmodule_version = build_string (EMODULES_VERSION); | |
609 | |
610 DEFVAR_BOOL ("load-modules-quietly", &load_modules_quietly /* | |
611 *Set to t if module loading is to be silent. | |
612 | |
613 Normally, when loading dynamic modules, Emacs will inform you of its | |
614 progress, and will display the module name and version if the module | |
615 is loaded correctly. Setting this variable to `t' will suppress these | |
616 messages. This would normally only be done if `load-module' was being | |
617 called by a Lisp function. | |
618 */); | |
1733 | 619 load_modules_quietly = 0; |
428 | 620 |
1750 | 621 DEFVAR_BOOL ("unloading-module", &unloading_module /* |
622 Used internally by `unload-feature'. Do not set this variable. | |
623 Danger, danger, Will Robinson! | |
624 */); | |
625 unloading_module = 0; | |
626 | |
627 #endif /* HAVE_SHLIB */ | |
628 | |
428 | 629 DEFVAR_LISP ("module-load-path", &Vmodule_load_path /* |
630 *List of directories to search for dynamic modules to load. | |
631 Each element is a string (directory name) or nil (try default directory). | |
632 | |
633 Note that elements of this list *may not* begin with "~", so you must | |
442 | 634 call `expand-file-name' on them before adding them to this list. |
428 | 635 |
636 Initialized based on EMACSMODULEPATH environment variable, if any, otherwise | |
637 to default specified the file `paths.h' when XEmacs was built. If there | |
638 were no paths specified in `paths.h', then XEmacs chooses a default | |
639 value for this variable by looking around in the file-system near the | |
640 directory in which the XEmacs executable resides. | |
641 | |
642 Due to the nature of dynamic modules, the path names should almost always | |
442 | 643 refer to architecture-dependent directories. It is unwise to attempt to |
644 store dynamic modules in a heterogenous environment. Some environments | |
428 | 645 are similar enough to each other that XEmacs will be unable to determine |
646 the correctness of a dynamic module, which can have unpredictable results | |
647 when a dynamic module is loaded. | |
648 */); | |
1733 | 649 Vmodule_load_path = Qnil; |
428 | 650 |
1733 | 651 DEFVAR_LISP ("module-extensions", &Vmodule_extensions /* |
652 *List of filename extensions to use when searching for dynamic modules. | |
653 */); | |
654 Vmodule_extensions = list5 (build_string (".ell"), | |
996 | 655 build_string (".so"), |
1381 | 656 build_string (".dll"), |
1733 | 657 build_string (".dylib"), |
658 build_string ("")); | |
428 | 659 } |