Mercurial > hg > xemacs-beta
annotate src/emodules.c @ 4899:aa8197436fdb
Make #'find-function behave better with dumped functions, installed XEmacs
2010-01-30 Aidan Kehoe <kehoea@parhasard.net>
* loadup.el:
If any filename in load-history starts with the value of
source-lisp, delete that part of the string, so that
#'find-function works better with dumped functions in an installed
XEmacs (it will look in lisp-directory instead, where it will
probably succeed).
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Sat, 30 Jan 2010 15:47:37 +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 } |