aboutsummaryrefslogtreecommitdiffstats
path: root/src/lread.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lread.c')
-rw-r--r--src/lread.c162
1 files changed, 141 insertions, 21 deletions
diff --git a/src/lread.c b/src/lread.c
index 6f71ff5f468..3a2c29a616b 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -64,6 +64,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
64#define file_tell ftell 64#define file_tell ftell
65#endif 65#endif
66 66
67#ifdef HAVE_LTDL
68#include <ltdl.h>
69#endif
70
67/* Hash table read constants. */ 71/* Hash table read constants. */
68static Lisp_Object Qhash_table, Qdata; 72static Lisp_Object Qhash_table, Qdata;
69static Lisp_Object Qtest; 73static Lisp_Object Qtest;
@@ -982,7 +986,15 @@ required.
982This uses the variables `load-suffixes' and `load-file-rep-suffixes'. */) 986This uses the variables `load-suffixes' and `load-file-rep-suffixes'. */)
983 (void) 987 (void)
984{ 988{
985 Lisp_Object lst = Qnil, suffixes = Vload_suffixes, suffix, ext; 989 Lisp_Object lst = Qnil, suffixes, suffix, ext;
990
991 /* module suffixes, then regular elisp suffixes */
992
993 Lisp_Object args[2];
994 args[0] = Vload_module_suffixes;
995 args[1] = Vload_suffixes;
996 suffixes = Fappend (2, args);
997
986 while (CONSP (suffixes)) 998 while (CONSP (suffixes))
987 { 999 {
988 Lisp_Object exts = Vload_file_rep_suffixes; 1000 Lisp_Object exts = Vload_file_rep_suffixes;
@@ -998,6 +1010,86 @@ This uses the variables `load-suffixes' and `load-file-rep-suffixes'. */)
998 return Fnreverse (lst); 1010 return Fnreverse (lst);
999} 1011}
1000 1012
1013DEFUN ("load-module", Fload_module, Sload_module, 1, 1, 0,
1014 doc: /* Dymamically load a compiled module. */)
1015 (Lisp_Object file)
1016{
1017#ifdef HAVE_LTDL
1018 static int lt_init_done = 0;
1019 lt_dlhandle handle;
1020 void (*module_init) ();
1021 void *gpl_sym;
1022 Lisp_Object doc_name, args[2];
1023
1024 /* init libtool once per emacs process */
1025 if (!lt_init_done)
1026 {
1027 int ret = lt_dlinit ();
1028 if (ret)
1029 {
1030 const char* s = lt_dlerror ();
1031 error ("ltdl init fail: %s", s);
1032 }
1033 lt_init_done = 1;
1034 }
1035
1036 CHECK_STRING (file);
1037
1038 handle = lt_dlopen (SDATA (file));
1039 if (!handle)
1040 error ("Cannot load file %s", SDATA (file));
1041
1042 gpl_sym = lt_dlsym (handle, "plugin_is_GPL_compatible");
1043 if (!gpl_sym)
1044 error ("Module %s is not GPL compatible", SDATA (file));
1045
1046 module_init = (void (*) ()) lt_dlsym (handle, "init");
1047 if (!module_init)
1048 error ("Module %s does not have an init function.", SDATA (file));
1049
1050 module_init ();
1051
1052 /* build doc file path and install it */
1053 args[0] = Fsubstring (file, make_number (0), make_number (-3));
1054 args[1] = build_string (".doc");
1055 doc_name = Fconcat (2, args);
1056 Fsnarf_documentation (doc_name, Qt);
1057
1058 return Qt;
1059#else
1060 return Qnil;
1061#endif
1062}
1063
1064
1065/* Return true if STRING ends with SUFFIX. */
1066static bool string_suffix_p (Lisp_Object string, const char *suffix)
1067{
1068 const ptrdiff_t len = strlen (suffix);
1069 return memcmp (SDATA (string) + SBYTES (string) - len, suffix, len) == 0;
1070}
1071
1072/* Return true if STRING ends with any element of SUFFIXES. */
1073static bool string_suffixes_p (Lisp_Object string, Lisp_Object suffixes)
1074{
1075 ptrdiff_t length = SBYTES (string), suflen;
1076 Lisp_Object tail, suffix;
1077
1078 for (tail = suffixes; CONSP (tail); tail = XCDR (tail))
1079 {
1080 suffix = XCAR (tail);
1081 suflen = SBYTES (suffix);
1082
1083 if (suflen <= length)
1084 {
1085 if (memcmp (SDATA (string) + length - suflen, SDATA (suffix), suflen) == 0)
1086 return true;
1087 }
1088 }
1089
1090 return false;
1091}
1092
1001DEFUN ("load", Fload, Sload, 1, 5, 0, 1093DEFUN ("load", Fload, Sload, 1, 5, 0,
1002 doc: /* Execute a file of Lisp code named FILE. 1094 doc: /* Execute a file of Lisp code named FILE.
1003First try FILE with `.elc' appended, then try with `.el', 1095First try FILE with `.elc' appended, then try with `.el',
@@ -1055,6 +1147,8 @@ Return t if the file exists and loads successfully. */)
1055 bool newer = 0; 1147 bool newer = 0;
1056 /* True means we are loading a compiled file. */ 1148 /* True means we are loading a compiled file. */
1057 bool compiled = 0; 1149 bool compiled = 0;
1150 /* True means we are loading a dynamic module. */
1151 bool module = 0;
1058 Lisp_Object handler; 1152 Lisp_Object handler;
1059 bool safe_p = 1; 1153 bool safe_p = 1;
1060 const char *fmode = "r"; 1154 const char *fmode = "r";
@@ -1105,18 +1199,14 @@ Return t if the file exists and loads successfully. */)
1105 1199
1106 if (! NILP (must_suffix)) 1200 if (! NILP (must_suffix))
1107 { 1201 {
1108 /* Don't insist on adding a suffix if FILE already ends with one. */ 1202 /* Don't insist on adding a suffix if FILE already ends with
1109 ptrdiff_t size = SBYTES (file); 1203 one or if FILE includes a directory name. */
1110 if (size > 3 1204 if (string_suffixes_p (file, Vload_module_suffixes)
1111 && !strcmp (SSDATA (file) + size - 3, ".el")) 1205 || string_suffixes_p (file, Vload_suffixes)
1112 must_suffix = Qnil; 1206 || ! NILP (Ffile_name_directory (file)))
1113 else if (size > 4 1207 {
1114 && !strcmp (SSDATA (file) + size - 4, ".elc")) 1208 must_suffix = Qnil;
1115 must_suffix = Qnil; 1209 }
1116 /* Don't insist on adding a suffix
1117 if the argument includes a directory name. */
1118 else if (! NILP (Ffile_name_directory (file)))
1119 must_suffix = Qnil;
1120 } 1210 }
1121 1211
1122 if (!NILP (nosuffix)) 1212 if (!NILP (nosuffix))
@@ -1227,7 +1317,7 @@ Return t if the file exists and loads successfully. */)
1227 specbind (Qold_style_backquotes, Qnil); 1317 specbind (Qold_style_backquotes, Qnil);
1228 record_unwind_protect (load_warn_old_style_backquotes, file); 1318 record_unwind_protect (load_warn_old_style_backquotes, file);
1229 1319
1230 if (!memcmp (SDATA (found) + SBYTES (found) - 4, ".elc", 4) 1320 if (string_suffix_p (found, ".elc")
1231 || (fd >= 0 && (version = safe_to_load_version (fd)) > 0)) 1321 || (fd >= 0 && (version = safe_to_load_version (fd)) > 0))
1232 /* Load .elc files directly, but not when they are 1322 /* Load .elc files directly, but not when they are
1233 remote and have no handler! */ 1323 remote and have no handler! */
@@ -1289,6 +1379,12 @@ Return t if the file exists and loads successfully. */)
1289 UNGCPRO; 1379 UNGCPRO;
1290 } 1380 }
1291 } 1381 }
1382#ifdef HAVE_LTDL
1383 else if (string_suffixes_p (found, Vload_module_suffixes))
1384 {
1385 module = 1;
1386 }
1387#endif
1292 else 1388 else
1293 { 1389 {
1294 /* We are loading a source file (*.el). */ 1390 /* We are loading a source file (*.el). */
@@ -1338,7 +1434,9 @@ Return t if the file exists and loads successfully. */)
1338 1434
1339 if (NILP (nomessage) || force_load_messages) 1435 if (NILP (nomessage) || force_load_messages)
1340 { 1436 {
1341 if (!safe_p) 1437 if (module)
1438 message_with_string ("Loading %s (dymamic module)...", file, 1);
1439 else if (!safe_p)
1342 message_with_string ("Loading %s (compiled; note unsafe, not compiled in Emacs)...", 1440 message_with_string ("Loading %s (compiled; note unsafe, not compiled in Emacs)...",
1343 file, 1); 1441 file, 1);
1344 else if (!compiled) 1442 else if (!compiled)
@@ -1358,7 +1456,14 @@ Return t if the file exists and loads successfully. */)
1358 if (lisp_file_lexically_bound_p (Qget_file_char)) 1456 if (lisp_file_lexically_bound_p (Qget_file_char))
1359 Fset (Qlexical_binding, Qt); 1457 Fset (Qlexical_binding, Qt);
1360 1458
1361 if (! version || version >= 22) 1459#ifdef HAVE_LTDL
1460 if (module)
1461 {
1462 /* XXX: should the fd/stream be closed before loading the module? */
1463 Fload_module (found);
1464 }
1465#endif
1466 else if (! version || version >= 22)
1362 readevalloop (Qget_file_char, stream, hist_file_name, 1467 readevalloop (Qget_file_char, stream, hist_file_name,
1363 0, Qnil, Qnil, Qnil, Qnil); 1468 0, Qnil, Qnil, Qnil, Qnil);
1364 else 1469 else
@@ -1387,7 +1492,9 @@ Return t if the file exists and loads successfully. */)
1387 1492
1388 if (!noninteractive && (NILP (nomessage) || force_load_messages)) 1493 if (!noninteractive && (NILP (nomessage) || force_load_messages))
1389 { 1494 {
1390 if (!safe_p) 1495 if (module)
1496 message_with_string ("Loading %s (dymamic module)...done", file, 1);
1497 else if (!safe_p)
1391 message_with_string ("Loading %s (compiled; note unsafe, not compiled in Emacs)...done", 1498 message_with_string ("Loading %s (compiled; note unsafe, not compiled in Emacs)...done",
1392 file, 1); 1499 file, 1);
1393 else if (!compiled) 1500 else if (!compiled)
@@ -3837,9 +3944,6 @@ intern_c_string_1 (const char *str, ptrdiff_t len)
3837 3944
3838 if (!SYMBOLP (tem)) 3945 if (!SYMBOLP (tem))
3839 { 3946 {
3840 /* Creating a non-pure string from a string literal not implemented yet.
3841 We could just use make_string here and live with the extra copy. */
3842 eassert (!NILP (Vpurify_flag));
3843 tem = intern_driver (make_pure_c_string (str, len), obarray, XINT (tem)); 3947 tem = intern_driver (make_pure_c_string (str, len), obarray, XINT (tem));
3844 } 3948 }
3845 return tem; 3949 return tem;
@@ -4094,6 +4198,7 @@ void
4094defsubr (struct Lisp_Subr *sname) 4198defsubr (struct Lisp_Subr *sname)
4095{ 4199{
4096 Lisp_Object sym, tem; 4200 Lisp_Object sym, tem;
4201 sname->doc = Qnil;
4097 sym = intern_c_string (sname->symbol_name); 4202 sym = intern_c_string (sname->symbol_name);
4098 XSETPVECTYPE (sname, PVEC_SUBR); 4203 XSETPVECTYPE (sname, PVEC_SUBR);
4099 XSETSUBR (tem, sname); 4204 XSETSUBR (tem, sname);
@@ -4491,6 +4596,7 @@ syms_of_lread (void)
4491 defsubr (&Sget_file_char); 4596 defsubr (&Sget_file_char);
4492 defsubr (&Smapatoms); 4597 defsubr (&Smapatoms);
4493 defsubr (&Slocate_file_internal); 4598 defsubr (&Slocate_file_internal);
4599 defsubr (&Sload_module);
4494 4600
4495 DEFVAR_LISP ("obarray", Vobarray, 4601 DEFVAR_LISP ("obarray", Vobarray,
4496 doc: /* Symbol table for use by `intern' and `read'. 4602 doc: /* Symbol table for use by `intern' and `read'.
@@ -4551,8 +4657,22 @@ Initialized during startup as described in Info node `(elisp)Library Search'. *
4551This list should not include the empty string. 4657This list should not include the empty string.
4552`load' and related functions try to append these suffixes, in order, 4658`load' and related functions try to append these suffixes, in order,
4553to the specified file name if a Lisp suffix is allowed or required. */); 4659to the specified file name if a Lisp suffix is allowed or required. */);
4660
4554 Vload_suffixes = list2 (build_pure_c_string (".elc"), 4661 Vload_suffixes = list2 (build_pure_c_string (".elc"),
4555 build_pure_c_string (".el")); 4662 build_pure_c_string (".el"));
4663
4664 DEFVAR_LISP ("load-module-suffixes", Vload_module_suffixes,
4665 doc: /* List of suffixes for modules files.
4666This list should not include the empty string. See `load-suffixes'. */);
4667
4668#ifdef HAVE_LTDL
4669 Vload_module_suffixes = list3 (build_pure_c_string (".dll"),
4670 build_pure_c_string (".so"),
4671 build_pure_c_string (".dylib"));
4672#else
4673 Vload_module_suffixes = Qnil;
4674#endif
4675
4556 DEFVAR_LISP ("load-file-rep-suffixes", Vload_file_rep_suffixes, 4676 DEFVAR_LISP ("load-file-rep-suffixes", Vload_file_rep_suffixes,
4557 doc: /* List of suffixes that indicate representations of \ 4677 doc: /* List of suffixes that indicate representations of \
4558the same file. 4678the same file.