Mercurial > emacs
comparison src/lread.c @ 39808:98efaf9813f4
(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.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Fri, 12 Oct 2001 03:18:05 +0000 |
parents | ee9c4218a600 |
children | 57070445ceac |
comparison
equal
deleted
inserted
replaced
39807:71e0ffb0d376 | 39808:98efaf9813f4 |
---|---|
89 int load_in_progress; | 89 int load_in_progress; |
90 | 90 |
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; |
99 | 99 |
100 /* This is the user-visible association list that maps features to | 100 /* This is the user-visible association list that maps features to |
644 #endif /* DOS_NT */ | 644 #endif /* DOS_NT */ |
645 | 645 |
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, |
659 since it would try to load a directory as a Lisp file */ | 665 since it would try to load a directory as a Lisp file */ |
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 |
666 if (! NILP (must_suffix)) | 673 if (! NILP (must_suffix)) |
667 { | 674 { |
677 else if (! NILP (Ffile_name_directory (file))) | 684 else if (! NILP (Ffile_name_directory (file))) |
678 must_suffix = Qnil; | 685 must_suffix = Qnil; |
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 } |
688 | 697 |
689 if (fd == -1) | 698 if (fd == -1) |
916 ); | 925 ); |
917 } | 926 } |
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. |
931 | |
932 SUFFIXES is a list of strings containing possible suffixes. | |
933 The empty suffix is automatically added iff the list is empty. | |
923 | 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. |
927 | 938 |
932 If the file we find is remote, return -2 | 943 If the file we find is remote, return -2 |
933 but store the found remote file name in *STOREPTR. | 944 but store the found remote file name in *STOREPTR. |
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 { |
943 register int fd; | 954 register int fd; |
944 int fn_size = 100; | 955 int fn_size = 100; |
946 register char *fn = buf; | 957 register char *fn = buf; |
947 int absolute = 0; | 958 int absolute = 0; |
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; |
959 | 978 |
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 |
971 default-directory to be something non-absolute... */ | 988 default-directory to be something non-absolute... */ |
972 { | 989 { |
976 continue; | 993 continue; |
977 } | 994 } |
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. |
995 If the directory starts with /:, remove that. */ | 1010 If the directory starts with /:, remove that. */ |
996 if (XSTRING (filename)->size > 2 | 1011 if (XSTRING (filename)->size > 2 |
1007 STRING_BYTES (XSTRING (filename))); | 1022 STRING_BYTES (XSTRING (filename))); |
1008 fn[STRING_BYTES (XSTRING (filename))] = 0; | 1023 fn[STRING_BYTES (XSTRING (filename))] = 0; |
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) |
1031 { | 1048 { |
1032 /* We succeeded; return this descriptor and filename. */ | 1049 /* We succeeded; return this descriptor and filename. */ |
1056 UNGCPRO; | 1073 UNGCPRO; |
1057 return fd; | 1074 return fd; |
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; |
1069 } | 1081 } |
1070 | 1082 |
2452 } | 2464 } |
2453 | 2465 |
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); |
2470 | 2482 |
2471 traverse_intervals (root_interval, 1, 0, | 2483 traverse_intervals (root_interval, 1, 0, |
3529 "*List of directories to search for files to load.\n\ | 3541 "*List of directories to search for files to load.\n\ |
3530 Each element is a string (directory name) or nil (try default directory).\n\ | 3542 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 |
3537 DEFVAR_LISP ("after-load-alist", &Vafter_load_alist, | 3557 DEFVAR_LISP ("after-load-alist", &Vafter_load_alist, |
3538 "An alist of expressions to be evalled when particular files are loaded.\n\ | 3558 "An alist of expressions to be evalled when particular files are loaded.\n\ |