diff options
| author | Stefan Monnier | 2001-10-12 03:18:05 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2001-10-12 03:18:05 +0000 |
| commit | e61b9b8743d10f5f0ec9065ae365f8be015ef9d7 (patch) | |
| tree | 77d78150cfac4bda13c1220682ebf7733be06820 /src | |
| parent | f633346880be2449526dc16e3712f106769b8179 (diff) | |
| download | emacs-e61b9b8743d10f5f0ec9065ae365f8be015ef9d7.tar.gz emacs-e61b9b8743d10f5f0ec9065ae365f8be015ef9d7.zip | |
(Vload_suffixes, default_suffixes): New vars.
(openp): Take a lisp list of suffixes.
Check for file-name-handlers even if the file was absolute already.
(syms_of_lread): Declare load-suffixes.
(Fload): Fix up call to openp.
Don't bother checking for file-name-handler at the very beginning.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lread.c | 108 |
1 files changed, 64 insertions, 44 deletions
diff --git a/src/lread.c b/src/lread.c index e0720ec5dea..0daf1764cf6 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -91,8 +91,8 @@ int load_in_progress; | |||
| 91 | /* Directory in which the sources were found. */ | 91 | /* Directory in which the sources were found. */ |
| 92 | Lisp_Object Vsource_directory; | 92 | Lisp_Object Vsource_directory; |
| 93 | 93 | ||
| 94 | /* Search path for files to be loaded. */ | 94 | /* Search path and suffixes for files to be loaded. */ |
| 95 | Lisp_Object Vload_path; | 95 | Lisp_Object Vload_path, Vload_suffixes, default_suffixes; |
| 96 | 96 | ||
| 97 | /* File name of user's init file. */ | 97 | /* File name of user's init file. */ |
| 98 | Lisp_Object Vuser_init_file; | 98 | Lisp_Object Vuser_init_file; |
| @@ -646,13 +646,19 @@ Return t if file exists.") | |||
| 646 | CHECK_STRING (file, 0); | 646 | CHECK_STRING (file, 0); |
| 647 | 647 | ||
| 648 | /* If file name is magic, call the handler. */ | 648 | /* If file name is magic, call the handler. */ |
| 649 | handler = Ffind_file_name_handler (file, Qload); | 649 | /* This shouldn't be necessary any more now that `openp' handles it right. |
| 650 | if (!NILP (handler)) | 650 | handler = Ffind_file_name_handler (file, Qload); |
| 651 | return call5 (handler, Qload, file, noerror, nomessage, nosuffix); | 651 | if (!NILP (handler)) |
| 652 | return call5 (handler, Qload, file, noerror, nomessage, nosuffix); */ | ||
| 652 | 653 | ||
| 653 | /* Do this after the handler to avoid | 654 | /* Do this after the handler to avoid |
| 654 | the need to gcpro noerror, nomessage and nosuffix. | 655 | the need to gcpro noerror, nomessage and nosuffix. |
| 655 | (Below here, we care only whether they are nil or not.) */ | 656 | (Below here, we care only whether they are nil or not.) |
| 657 | The presence of this call is the result of a historical accident: | ||
| 658 | it used to be in every file-operations and when it got removed | ||
| 659 | everywhere, it accidentally stayed here. Since then, enough people | ||
| 660 | supposedly have things like (load "$PROJECT/foo.el") in their .emacs | ||
| 661 | that it seemed risky to remove. */ | ||
| 656 | file = Fsubstitute_in_file_name (file); | 662 | file = Fsubstitute_in_file_name (file); |
| 657 | 663 | ||
| 658 | /* Avoid weird lossage with null string as arg, | 664 | /* Avoid weird lossage with null string as arg, |
| @@ -660,6 +666,7 @@ Return t if file exists.") | |||
| 660 | if (XSTRING (file)->size > 0) | 666 | if (XSTRING (file)->size > 0) |
| 661 | { | 667 | { |
| 662 | int size = STRING_BYTES (XSTRING (file)); | 668 | int size = STRING_BYTES (XSTRING (file)); |
| 669 | Lisp_Object tmp[2]; | ||
| 663 | 670 | ||
| 664 | GCPRO1 (file); | 671 | GCPRO1 (file); |
| 665 | 672 | ||
| @@ -679,9 +686,11 @@ Return t if file exists.") | |||
| 679 | } | 686 | } |
| 680 | 687 | ||
| 681 | fd = openp (Vload_path, file, | 688 | fd = openp (Vload_path, file, |
| 682 | (!NILP (nosuffix) ? "" | 689 | (!NILP (nosuffix) ? Qnil |
| 683 | : ! NILP (must_suffix) ? ".elc.gz:.elc:.el.gz:.el" | 690 | : !NILP (must_suffix) ? Vload_suffixes |
| 684 | : ".elc:.elc.gz:.el.gz:.el:"), | 691 | : Fappend (2, (tmp[0] = Vload_suffixes, |
| 692 | tmp[1] = default_suffixes, | ||
| 693 | tmp))), | ||
| 685 | &found, 0); | 694 | &found, 0); |
| 686 | UNGCPRO; | 695 | UNGCPRO; |
| 687 | } | 696 | } |
| @@ -918,9 +927,11 @@ complete_filename_p (pathname) | |||
| 918 | 927 | ||
| 919 | /* Search for a file whose name is STR, looking in directories | 928 | /* Search for a file whose name is STR, looking in directories |
| 920 | in the Lisp list PATH, and trying suffixes from SUFFIX. | 929 | in the Lisp list PATH, and trying suffixes from SUFFIX. |
| 921 | SUFFIX is a string containing possible suffixes separated by colons. | ||
| 922 | On success, returns a file descriptor. On failure, returns -1. | 930 | On success, returns a file descriptor. On failure, returns -1. |
| 923 | 931 | ||
| 932 | SUFFIXES is a list of strings containing possible suffixes. | ||
| 933 | The empty suffix is automatically added iff the list is empty. | ||
| 934 | |||
| 924 | EXEC_ONLY nonzero means don't open the files, | 935 | EXEC_ONLY nonzero means don't open the files, |
| 925 | just look for one that is executable. In this case, | 936 | just look for one that is executable. In this case, |
| 926 | returns 1 on success. | 937 | returns 1 on success. |
| @@ -934,9 +945,9 @@ complete_filename_p (pathname) | |||
| 934 | We do not check for remote files if EXEC_ONLY is nonzero. */ | 945 | We do not check for remote files if EXEC_ONLY is nonzero. */ |
| 935 | 946 | ||
| 936 | int | 947 | int |
| 937 | openp (path, str, suffix, storeptr, exec_only) | 948 | openp (path, str, suffixes, storeptr, exec_only) |
| 938 | Lisp_Object path, str; | 949 | Lisp_Object path, str; |
| 939 | char *suffix; | 950 | Lisp_Object suffixes; |
| 940 | Lisp_Object *storeptr; | 951 | Lisp_Object *storeptr; |
| 941 | int exec_only; | 952 | int exec_only; |
| 942 | { | 953 | { |
| @@ -948,11 +959,19 @@ openp (path, str, suffix, storeptr, exec_only) | |||
| 948 | int want_size; | 959 | int want_size; |
| 949 | Lisp_Object filename; | 960 | Lisp_Object filename; |
| 950 | struct stat st; | 961 | struct stat st; |
| 951 | struct gcpro gcpro1, gcpro2, gcpro3; | 962 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; |
| 952 | Lisp_Object string; | 963 | Lisp_Object string, tail; |
| 964 | int max_suffix_len = 0; | ||
| 965 | |||
| 966 | for (tail = suffixes; CONSP (tail); tail = XCDR (tail)) | ||
| 967 | { | ||
| 968 | CHECK_STRING (XCAR (tail), 0); | ||
| 969 | max_suffix_len = max (max_suffix_len, | ||
| 970 | STRING_BYTES (XSTRING (XCAR (tail)))); | ||
| 971 | } | ||
| 953 | 972 | ||
| 954 | string = filename = Qnil; | 973 | string = filename = Qnil; |
| 955 | GCPRO3 (str, string, filename); | 974 | GCPRO5 (str, string, filename, path, suffixes); |
| 956 | 975 | ||
| 957 | if (storeptr) | 976 | if (storeptr) |
| 958 | *storeptr = Qnil; | 977 | *storeptr = Qnil; |
| @@ -960,11 +979,9 @@ openp (path, str, suffix, storeptr, exec_only) | |||
| 960 | if (complete_filename_p (str)) | 979 | if (complete_filename_p (str)) |
| 961 | absolute = 1; | 980 | absolute = 1; |
| 962 | 981 | ||
| 963 | for (; !NILP (path); path = Fcdr (path)) | 982 | for (; CONSP (path); path = XCDR (path)) |
| 964 | { | 983 | { |
| 965 | char *nsuffix; | 984 | filename = Fexpand_file_name (str, XCAR (path)); |
| 966 | |||
| 967 | filename = Fexpand_file_name (str, Fcar (path)); | ||
| 968 | if (!complete_filename_p (filename)) | 985 | if (!complete_filename_p (filename)) |
| 969 | /* If there are non-absolute elts in PATH (eg ".") */ | 986 | /* If there are non-absolute elts in PATH (eg ".") */ |
| 970 | /* Of course, this could conceivably lose if luser sets | 987 | /* Of course, this could conceivably lose if luser sets |
| @@ -978,17 +995,15 @@ openp (path, str, suffix, storeptr, exec_only) | |||
| 978 | 995 | ||
| 979 | /* Calculate maximum size of any filename made from | 996 | /* Calculate maximum size of any filename made from |
| 980 | this path element/specified file name and any possible suffix. */ | 997 | this path element/specified file name and any possible suffix. */ |
| 981 | want_size = strlen (suffix) + STRING_BYTES (XSTRING (filename)) + 1; | 998 | want_size = max_suffix_len + STRING_BYTES (XSTRING (filename)) + 1; |
| 982 | if (fn_size < want_size) | 999 | if (fn_size < want_size) |
| 983 | fn = (char *) alloca (fn_size = 100 + want_size); | 1000 | fn = (char *) alloca (fn_size = 100 + want_size); |
| 984 | 1001 | ||
| 985 | nsuffix = suffix; | ||
| 986 | |||
| 987 | /* Loop over suffixes. */ | 1002 | /* Loop over suffixes. */ |
| 988 | while (1) | 1003 | for (tail = NILP (suffixes) ? default_suffixes : suffixes; |
| 1004 | CONSP (tail); tail = XCDR (tail)) | ||
| 989 | { | 1005 | { |
| 990 | char *esuffix = (char *) index (nsuffix, ':'); | 1006 | int lsuffix = STRING_BYTES (XSTRING (XCAR (tail))); |
| 991 | int lsuffix = esuffix ? esuffix - nsuffix : strlen (nsuffix); | ||
| 992 | Lisp_Object handler; | 1007 | Lisp_Object handler; |
| 993 | 1008 | ||
| 994 | /* Concatenate path element/specified name with the suffix. | 1009 | /* Concatenate path element/specified name with the suffix. |
| @@ -1009,22 +1024,24 @@ openp (path, str, suffix, storeptr, exec_only) | |||
| 1009 | } | 1024 | } |
| 1010 | 1025 | ||
| 1011 | if (lsuffix != 0) /* Bug happens on CCI if lsuffix is 0. */ | 1026 | if (lsuffix != 0) /* Bug happens on CCI if lsuffix is 0. */ |
| 1012 | strncat (fn, nsuffix, lsuffix); | 1027 | strncat (fn, XSTRING (XCAR (tail))->data, lsuffix); |
| 1013 | 1028 | ||
| 1014 | /* Check that the file exists and is not a directory. */ | 1029 | /* Check that the file exists and is not a directory. */ |
| 1015 | if (absolute) | 1030 | /* We used to only check for handlers on non-absolute file names: |
| 1016 | handler = Qnil; | 1031 | if (absolute) |
| 1017 | else | 1032 | handler = Qnil; |
| 1018 | handler = Ffind_file_name_handler (filename, Qfile_exists_p); | 1033 | else |
| 1019 | if (! NILP (handler) && ! exec_only) | 1034 | handler = Ffind_file_name_handler (filename, Qfile_exists_p); |
| 1035 | It's not clear why that was the case and it breaks things like | ||
| 1036 | (load "/bar.el") where the file is actually "/bar.el.gz". */ | ||
| 1037 | handler = Ffind_file_name_handler (filename, Qfile_exists_p); | ||
| 1038 | if (!NILP (handler) && !exec_only) | ||
| 1020 | { | 1039 | { |
| 1021 | int exists; | 1040 | int exists; |
| 1022 | 1041 | ||
| 1023 | string = build_string (fn); | 1042 | string = build_string (fn); |
| 1024 | exists = ! NILP (exec_only ? Ffile_executable_p (string) | 1043 | exists = !NILP (Ffile_readable_p (string)); |
| 1025 | : Ffile_readable_p (string)); | 1044 | if (exists && !NILP (Ffile_directory_p (build_string (fn)))) |
| 1026 | if (exists | ||
| 1027 | && ! NILP (Ffile_directory_p (build_string (fn)))) | ||
| 1028 | exists = 0; | 1045 | exists = 0; |
| 1029 | 1046 | ||
| 1030 | if (exists) | 1047 | if (exists) |
| @@ -1058,11 +1075,6 @@ openp (path, str, suffix, storeptr, exec_only) | |||
| 1058 | } | 1075 | } |
| 1059 | } | 1076 | } |
| 1060 | } | 1077 | } |
| 1061 | |||
| 1062 | /* Advance to next suffix. */ | ||
| 1063 | if (esuffix == 0) | ||
| 1064 | break; | ||
| 1065 | nsuffix += lsuffix + 1; | ||
| 1066 | } | 1078 | } |
| 1067 | if (absolute) | 1079 | if (absolute) |
| 1068 | break; | 1080 | break; |
| @@ -2454,16 +2466,16 @@ substitute_object_recurse (object, placeholder, subtree) | |||
| 2454 | case Lisp_Cons: | 2466 | case Lisp_Cons: |
| 2455 | { | 2467 | { |
| 2456 | SUBSTITUTE (Fcar_safe (subtree), | 2468 | SUBSTITUTE (Fcar_safe (subtree), |
| 2457 | Fsetcar (subtree, true_value)); | 2469 | Fsetcar (subtree, true_value)); |
| 2458 | SUBSTITUTE (Fcdr_safe (subtree), | 2470 | SUBSTITUTE (Fcdr_safe (subtree), |
| 2459 | Fsetcdr (subtree, true_value)); | 2471 | Fsetcdr (subtree, true_value)); |
| 2460 | return subtree; | 2472 | return subtree; |
| 2461 | } | 2473 | } |
| 2462 | 2474 | ||
| 2463 | case Lisp_String: | 2475 | case Lisp_String: |
| 2464 | { | 2476 | { |
| 2465 | /* Check for text properties in each interval. | 2477 | /* Check for text properties in each interval. |
| 2466 | substitute_in_interval contains part of the logic. */ | 2478 | substitute_in_interval contains part of the logic. */ |
| 2467 | 2479 | ||
| 2468 | INTERVAL root_interval = XSTRING (subtree)->intervals; | 2480 | INTERVAL root_interval = XSTRING (subtree)->intervals; |
| 2469 | Lisp_Object arg = Fcons (object, placeholder); | 2481 | Lisp_Object arg = Fcons (object, placeholder); |
| @@ -3531,6 +3543,14 @@ Each element is a string (directory name) or nil (try default directory).\n\ | |||
| 3531 | Initialized based on EMACSLOADPATH environment variable, if any,\n\ | 3543 | Initialized based on EMACSLOADPATH environment variable, if any,\n\ |
| 3532 | otherwise to default specified by file `epaths.h' when Emacs was built."); | 3544 | otherwise to default specified by file `epaths.h' when Emacs was built."); |
| 3533 | 3545 | ||
| 3546 | DEFVAR_LISP ("load-suffixes", &Vload_suffixes, | ||
| 3547 | "*List of suffixes to try for files to load. | ||
| 3548 | This list should not include the empty string."); | ||
| 3549 | Vload_suffixes = Fcons (build_string (".elc"), | ||
| 3550 | Fcons (build_string (".el"), Qnil)); | ||
| 3551 | default_suffixes = Fcons (empty_string, Qnil); | ||
| 3552 | staticpro (&default_suffixes); | ||
| 3553 | |||
| 3534 | DEFVAR_BOOL ("load-in-progress", &load_in_progress, | 3554 | DEFVAR_BOOL ("load-in-progress", &load_in_progress, |
| 3535 | "Non-nil iff inside of `load'."); | 3555 | "Non-nil iff inside of `load'."); |
| 3536 | 3556 | ||