diff options
Diffstat (limited to 'src/lread.c')
| -rw-r--r-- | src/lread.c | 162 |
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. */ |
| 68 | static Lisp_Object Qhash_table, Qdata; | 72 | static Lisp_Object Qhash_table, Qdata; |
| 69 | static Lisp_Object Qtest; | 73 | static Lisp_Object Qtest; |
| @@ -982,7 +986,15 @@ required. | |||
| 982 | This uses the variables `load-suffixes' and `load-file-rep-suffixes'. */) | 986 | This 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 | ||
| 1013 | DEFUN ("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. */ | ||
| 1066 | static 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. */ | ||
| 1073 | static 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 | |||
| 1001 | DEFUN ("load", Fload, Sload, 1, 5, 0, | 1093 | DEFUN ("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. |
| 1003 | First try FILE with `.elc' appended, then try with `.el', | 1095 | First 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 | |||
| 4094 | defsubr (struct Lisp_Subr *sname) | 4198 | defsubr (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'. * | |||
| 4551 | This list should not include the empty string. | 4657 | This 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, |
| 4553 | to the specified file name if a Lisp suffix is allowed or required. */); | 4659 | to 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. | ||
| 4666 | This 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 \ |
| 4558 | the same file. | 4678 | the same file. |