Mercurial > hg > xemacs-beta
comparison src/lread.c @ 398:74fd4e045ea6 r21-2-29
Import from CVS: tag r21-2-29
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:13:30 +0200 |
parents | 8626e4521993 |
children | a86b2b5e0111 |
comparison
equal
deleted
inserted
replaced
397:f4aeb21a5bad | 398:74fd4e045ea6 |
---|---|
61 #endif | 61 #endif |
62 Lisp_Object Qvariable_domain; /* I18N3 */ | 62 Lisp_Object Qvariable_domain; /* I18N3 */ |
63 Lisp_Object Vvalues, Vstandard_input, Vafter_load_alist; | 63 Lisp_Object Vvalues, Vstandard_input, Vafter_load_alist; |
64 Lisp_Object Qcurrent_load_list; | 64 Lisp_Object Qcurrent_load_list; |
65 Lisp_Object Qload, Qload_file_name; | 65 Lisp_Object Qload, Qload_file_name; |
66 Lisp_Object Qlocate_file_hash_table; | |
67 Lisp_Object Qfset; | 66 Lisp_Object Qfset; |
67 | |
68 /* Hash-table that maps directory names to hashes of their contents. */ | |
69 static Lisp_Object Vlocate_file_hash_table; | |
70 | |
71 Lisp_Object Qexists, Qreadable, Qwritable, Qexecutable; | |
68 | 72 |
69 /* See read_escape() for an explanation of this. */ | 73 /* See read_escape() for an explanation of this. */ |
70 #if 0 | 74 #if 0 |
71 int fail_on_bucky_bit_character_escapes; | 75 int fail_on_bucky_bit_character_escapes; |
72 #endif | 76 #endif |
116 | 120 |
117 /* The association list of objects read with the #n=object form. | 121 /* The association list of objects read with the #n=object form. |
118 Each member of the list has the form (n . object), and is used to | 122 Each member of the list has the form (n . object), and is used to |
119 look up the object for the corresponding #n# construct. | 123 look up the object for the corresponding #n# construct. |
120 It must be set to nil before all top-level calls to read0. */ | 124 It must be set to nil before all top-level calls to read0. */ |
121 Lisp_Object read_objects; | 125 Lisp_Object Vread_objects; |
122 | 126 |
123 /* Nonzero means load should forcibly load all dynamic doc strings. */ | 127 /* Nonzero means load should forcibly load all dynamic doc strings. */ |
124 /* Note that this always happens (with some special behavior) when | 128 /* Note that this always happens (with some special behavior) when |
125 purify_flag is set. */ | 129 purify_flag is set. */ |
126 static int load_force_doc_strings; | 130 static int load_force_doc_strings; |
212 ? (build_string ("internal input stream")) \ | 216 ? (build_string ("internal input stream")) \ |
213 : (x)) | 217 : (x)) |
214 | 218 |
215 | 219 |
216 static DOESNT_RETURN | 220 static DOESNT_RETURN |
217 syntax_error (CONST char *string) | 221 syntax_error (const char *string) |
218 { | 222 { |
219 signal_error (Qinvalid_read_syntax, | 223 signal_error (Qinvalid_read_syntax, |
220 list1 (build_translated_string (string))); | 224 list1 (build_translated_string (string))); |
221 } | 225 } |
222 | 226 |
223 static Lisp_Object | 227 static Lisp_Object |
224 continuable_syntax_error (CONST char *string) | 228 continuable_syntax_error (const char *string) |
225 { | 229 { |
226 return Fsignal (Qinvalid_read_syntax, | 230 return Fsignal (Qinvalid_read_syntax, |
227 list1 (build_translated_string (string))); | 231 list1 (build_translated_string (string))); |
228 } | 232 } |
229 | 233 |
437 { | 441 { |
438 struct gcpro gcpro1; | 442 struct gcpro gcpro1; |
439 Lisp_Object list = Vload_force_doc_string_list; | 443 Lisp_Object list = Vload_force_doc_string_list; |
440 Lisp_Object tail; | 444 Lisp_Object tail; |
441 int fd = XINT (XCAR (Vload_descriptor_list)); | 445 int fd = XINT (XCAR (Vload_descriptor_list)); |
442 /* NOTE: If purify_flag is true, we're in-place modifying objects that | |
443 may be in purespace (and if not, they will be). Therefore, we have | |
444 to be VERY careful to make sure that all objects that we create | |
445 are purecopied -- objects in purespace are not marked for GC, and | |
446 if we leave any impure objects inside of pure ones, we're really | |
447 screwed. */ | |
448 | 446 |
449 GCPRO1 (list); | 447 GCPRO1 (list); |
450 /* restore the old value first just in case an error occurs. */ | 448 /* restore the old value first just in case an error occurs. */ |
451 Vload_force_doc_string_list = oldlist; | 449 Vload_force_doc_string_list = oldlist; |
452 | 450 |
473 | 471 |
474 NGCPRO1 (juan); | 472 NGCPRO1 (juan); |
475 ivan = Fread (juan); | 473 ivan = Fread (juan); |
476 if (!CONSP (ivan)) | 474 if (!CONSP (ivan)) |
477 signal_simple_error ("invalid lazy-loaded byte code", ivan); | 475 signal_simple_error ("invalid lazy-loaded byte code", ivan); |
478 /* Remember to purecopy; see above. */ | 476 XCOMPILED_FUNCTION (john)->instructions = XCAR (ivan); |
479 XCOMPILED_FUNCTION (john)->instructions = Fpurecopy (XCAR (ivan)); | |
480 /* v18 or v19 bytecode file. Need to Ebolify. */ | 477 /* v18 or v19 bytecode file. Need to Ebolify. */ |
481 if (XCOMPILED_FUNCTION (john)->flags.ebolified | 478 if (XCOMPILED_FUNCTION (john)->flags.ebolified |
482 && VECTORP (XCDR (ivan))) | 479 && VECTORP (XCDR (ivan))) |
483 ebolify_bytecode_constants (XCDR (ivan)); | 480 ebolify_bytecode_constants (XCDR (ivan)); |
484 XCOMPILED_FUNCTION (john)->constants = Fpurecopy (XCDR (ivan)); | 481 XCOMPILED_FUNCTION (john)->constants = XCDR (ivan); |
485 NUNGCPRO; | 482 NUNGCPRO; |
486 } | 483 } |
487 doc = compiled_function_documentation (XCOMPILED_FUNCTION (john)); | 484 doc = compiled_function_documentation (XCOMPILED_FUNCTION (john)); |
488 if (CONSP (doc)) | 485 if (CONSP (doc)) |
489 { | 486 { |
551 struct gcpro gcpro1, gcpro2, gcpro3; | 548 struct gcpro gcpro1, gcpro2, gcpro3; |
552 int reading_elc = 0; | 549 int reading_elc = 0; |
553 int message_p = NILP (nomessage); | 550 int message_p = NILP (nomessage); |
554 /*#ifdef DEBUG_XEMACS*/ | 551 /*#ifdef DEBUG_XEMACS*/ |
555 static Lisp_Object last_file_loaded; | 552 static Lisp_Object last_file_loaded; |
556 size_t pure_usage = 0; | |
557 /*#endif*/ | 553 /*#endif*/ |
558 struct stat s1, s2; | 554 struct stat s1, s2; |
559 GCPRO3 (file, newer, found); | 555 GCPRO3 (file, newer, found); |
560 | 556 |
561 CHECK_STRING (file); | 557 CHECK_STRING (file); |
563 /*#ifdef DEBUG_XEMACS*/ | 559 /*#ifdef DEBUG_XEMACS*/ |
564 if (purify_flag && noninteractive) | 560 if (purify_flag && noninteractive) |
565 { | 561 { |
566 message_p = 1; | 562 message_p = 1; |
567 last_file_loaded = file; | 563 last_file_loaded = file; |
568 pure_usage = purespace_usage (); | |
569 } | 564 } |
570 /*#endif / * DEBUG_XEMACS */ | 565 /*#endif / * DEBUG_XEMACS */ |
571 | 566 |
572 /* If file name is magic, call the handler. */ | 567 /* If file name is magic, call the handler. */ |
573 handler = Ffind_file_name_handler (file, Qload); | 568 handler = Ffind_file_name_handler (file, Qload); |
591 { | 586 { |
592 char *foundstr; | 587 char *foundstr; |
593 int foundlen; | 588 int foundlen; |
594 | 589 |
595 fd = locate_file (Vload_path, file, | 590 fd = locate_file (Vload_path, file, |
596 ((!NILP (nosuffix)) ? "" : | 591 ((!NILP (nosuffix)) ? Qnil : |
597 load_ignore_elc_files ? ".el:" : | 592 build_string (load_ignore_elc_files ? ".el:" : |
598 ".elc:.el:"), | 593 ".elc:.el:")), |
599 &found, | 594 &found, |
600 -1); | 595 -1); |
601 | 596 |
602 if (fd < 0) | 597 if (fd < 0) |
603 { | 598 { |
679 PRINT_LOADING_MESSAGE (""); | 674 PRINT_LOADING_MESSAGE (""); |
680 | 675 |
681 { | 676 { |
682 /* Lisp_Object's must be malloc'ed, not stack-allocated */ | 677 /* Lisp_Object's must be malloc'ed, not stack-allocated */ |
683 Lisp_Object lispstream = Qnil; | 678 Lisp_Object lispstream = Qnil; |
684 CONST int block_size = 8192; | 679 const int block_size = 8192; |
685 struct gcpro ngcpro1; | 680 struct gcpro ngcpro1; |
686 | 681 |
687 NGCPRO1 (lispstream); | 682 NGCPRO1 (lispstream); |
688 lispstream = make_filedesc_input_stream (fd, 0, -1, LSTR_CLOSING); | 683 lispstream = make_filedesc_input_stream (fd, 0, -1, LSTR_CLOSING); |
689 /* 64K is used for normal files; 8K should be OK here because Lisp | 684 /* 64K is used for normal files; 8K should be OK here because Lisp |
784 } | 779 } |
785 | 780 |
786 /*#ifdef DEBUG_XEMACS*/ | 781 /*#ifdef DEBUG_XEMACS*/ |
787 if (purify_flag && noninteractive) | 782 if (purify_flag && noninteractive) |
788 { | 783 { |
789 if (EQ (last_file_loaded, file)) | 784 if (!EQ (last_file_loaded, file)) |
790 message_append (" (%ld)", | 785 message ("Loading %s ...done", XSTRING_DATA (file)); |
791 (unsigned long) (purespace_usage() - pure_usage)); | |
792 else | |
793 message ("Loading %s ...done (%ld)", XSTRING_DATA (file), | |
794 (unsigned long) (purespace_usage() - pure_usage)); | |
795 } | 786 } |
796 /*#endif / * DEBUG_XEMACS */ | 787 /*#endif / * DEBUG_XEMACS */ |
797 | 788 |
798 if (!noninteractive) | 789 if (!noninteractive) |
799 PRINT_LOADING_MESSAGE ("done"); | 790 PRINT_LOADING_MESSAGE ("done"); |
801 UNGCPRO; | 792 UNGCPRO; |
802 return Qt; | 793 return Qt; |
803 } | 794 } |
804 | 795 |
805 | 796 |
806 #if 0 /* FSFmacs */ | 797 /* ------------------------------- */ |
807 /* not used */ | 798 /* locate_file */ |
799 /* ------------------------------- */ | |
800 | |
808 static int | 801 static int |
809 complete_filename_p (Lisp_Object pathname) | 802 decode_mode_1 (Lisp_Object mode) |
810 { | 803 { |
811 REGISTER unsigned char *s = XSTRING_DATA (pathname); | 804 if (EQ (mode, Qexists)) |
812 return (IS_DIRECTORY_SEP (s[0]) | 805 return F_OK; |
813 || (XSTRING_LENGTH (pathname) > 2 | 806 else if (EQ (mode, Qexecutable)) |
814 && IS_DEVICE_SEP (s[1]) && IS_DIRECTORY_SEP (s[2])) | 807 return X_OK; |
815 #ifdef ALTOS | 808 else if (EQ (mode, Qwritable)) |
816 || *s == '@' | 809 return W_OK; |
817 #endif | 810 else if (EQ (mode, Qreadable)) |
818 ); | 811 return R_OK; |
819 } | 812 else if (INTP (mode)) |
820 #endif /* 0 */ | 813 { |
814 check_int_range (XINT (mode), 0, 7); | |
815 return XINT (mode); | |
816 } | |
817 else | |
818 signal_simple_error ("Invalid value", mode); | |
819 return 0; /* unreached */ | |
820 } | |
821 | |
822 static int | |
823 decode_mode (Lisp_Object mode) | |
824 { | |
825 if (NILP (mode)) | |
826 return R_OK; | |
827 else if (CONSP (mode)) | |
828 { | |
829 Lisp_Object tail; | |
830 int mask = 0; | |
831 EXTERNAL_LIST_LOOP (tail, mode) | |
832 mask |= decode_mode_1 (XCAR (tail)); | |
833 return mask; | |
834 } | |
835 else | |
836 return decode_mode_1 (mode); | |
837 } | |
821 | 838 |
822 DEFUN ("locate-file", Flocate_file, 2, 4, 0, /* | 839 DEFUN ("locate-file", Flocate_file, 2, 4, 0, /* |
823 Search for FILENAME through PATH-LIST, expanded by one of the optional | 840 Search for FILENAME through PATH-LIST. |
824 SUFFIXES (string of suffixes separated by ":"s), checking for access | 841 |
825 MODE (0|1|2|4 = exists|executable|writeable|readable), default readable. | 842 If SUFFIXES is non-nil, it should be a list of suffixes to append to |
843 file name when searching. | |
844 | |
845 If MODE is non-nil, it should be a symbol or a list of symbol representing | |
846 requirements. Allowed symbols are `exists', `executable', `writable', and | |
847 `readable'. If MODE is nil, it defaults to `readable'. | |
826 | 848 |
827 `locate-file' keeps hash tables of the directories it searches through, | 849 `locate-file' keeps hash tables of the directories it searches through, |
828 in order to speed things up. It tries valiantly to not get confused in | 850 in order to speed things up. It tries valiantly to not get confused in |
829 the face of a changing and unpredictable environment, but can occasionally | 851 the face of a changing and unpredictable environment, but can occasionally |
830 get tripped up. In this case, you will have to call | 852 get tripped up. In this case, you will have to call |
835 { | 857 { |
836 /* This function can GC */ | 858 /* This function can GC */ |
837 Lisp_Object tp; | 859 Lisp_Object tp; |
838 | 860 |
839 CHECK_STRING (filename); | 861 CHECK_STRING (filename); |
840 if (!NILP (suffixes)) | 862 |
863 if (LISTP (suffixes)) | |
864 { | |
865 Lisp_Object tail; | |
866 EXTERNAL_LIST_LOOP (tail, suffixes) | |
867 CHECK_STRING (XCAR (tail)); | |
868 } | |
869 else | |
841 CHECK_STRING (suffixes); | 870 CHECK_STRING (suffixes); |
842 if (!NILP (mode)) | 871 |
843 CHECK_NATNUM (mode); | 872 locate_file (path_list, filename, suffixes, &tp, decode_mode (mode)); |
844 | |
845 locate_file (path_list, | |
846 filename, | |
847 NILP (suffixes) ? "" : (char *) XSTRING_DATA (suffixes), | |
848 &tp, | |
849 NILP (mode) ? R_OK : XINT (mode)); | |
850 return tp; | 873 return tp; |
851 } | 874 } |
852 | 875 |
853 /* recalculate the hash table for the given string */ | 876 /* Recalculate the hash table for the given string. DIRECTORY should |
877 better have been through Fexpand_file_name() by now. */ | |
854 | 878 |
855 static Lisp_Object | 879 static Lisp_Object |
856 locate_file_refresh_hashing (Lisp_Object str) | 880 locate_file_refresh_hashing (Lisp_Object directory) |
857 { | 881 { |
858 Lisp_Object hash = make_directory_hash_table ((char *) XSTRING_DATA (str)); | 882 Lisp_Object hash = |
859 Fput (str, Qlocate_file_hash_table, hash); | 883 make_directory_hash_table ((char *) XSTRING_DATA (directory)); |
884 | |
885 if (!NILP (hash)) | |
886 Fputhash (directory, hash, Vlocate_file_hash_table); | |
860 return hash; | 887 return hash; |
861 } | 888 } |
862 | 889 |
863 /* find the hash table for the given string, recalculating if necessary */ | 890 /* find the hash table for the given directory, recalculating if necessary */ |
864 | 891 |
865 static Lisp_Object | 892 static Lisp_Object |
866 locate_file_find_directory_hash_table (Lisp_Object str) | 893 locate_file_find_directory_hash_table (Lisp_Object directory) |
867 { | 894 { |
868 Lisp_Object hash = Fget (str, Qlocate_file_hash_table, Qnil); | 895 Lisp_Object hash = Fgethash (directory, Vlocate_file_hash_table, Qnil); |
869 if (! HASH_TABLEP (hash)) | 896 if (NILP (hash)) |
870 return locate_file_refresh_hashing (str); | 897 return locate_file_refresh_hashing (directory); |
871 return hash; | 898 else |
872 } | 899 return hash; |
873 | 900 } |
874 /* look for STR in PATH, optionally adding suffixes in SUFFIX */ | 901 |
902 /* The SUFFIXES argument in any of the locate_file* functions can be | |
903 nil, a list, or a string (for backward compatibility), with the | |
904 following semantics: | |
905 | |
906 a) nil - no suffix, just search for file name intact | |
907 (semantically different from "empty suffix list", which | |
908 would be meaningless.) | |
909 b) list - list of suffixes to append to file name. Each of these | |
910 must be a string. | |
911 c) string - colon-separated suffixes to append to file name (backward | |
912 compatibility). | |
913 | |
914 All of this got hairy, so I decided to use a mapper. Calling a | |
915 function for each suffix shouldn't slow things down, since | |
916 locate_file is rarely called with enough suffixes for funcalls to | |
917 make any difference. */ | |
918 | |
919 /* Map FUN over SUFFIXES, as described above. FUN will be called with a | |
920 char * containing the current file name, and ARG. Mapping stops when | |
921 FUN returns non-zero. */ | |
922 static void | |
923 locate_file_map_suffixes (Lisp_Object filename, Lisp_Object suffixes, | |
924 int (*fun) (char *, void *), | |
925 void *arg) | |
926 { | |
927 /* This function can GC */ | |
928 char *fn; | |
929 int fn_len, max; | |
930 | |
931 /* Calculate maximum size of any filename made from | |
932 this path element/specified file name and any possible suffix. */ | |
933 if (CONSP (suffixes)) | |
934 { | |
935 /* We must traverse the list, so why not do it right. */ | |
936 Lisp_Object tail; | |
937 max = 0; | |
938 LIST_LOOP (tail, suffixes) | |
939 { | |
940 if (XSTRING_LENGTH (XCAR (tail)) > max) | |
941 max = XSTRING_LENGTH (XCAR (tail)); | |
942 } | |
943 } | |
944 else if (NILP (suffixes)) | |
945 max = 0; | |
946 else | |
947 /* Just take the easy way out */ | |
948 max = XSTRING_LENGTH (suffixes); | |
949 | |
950 fn_len = XSTRING_LENGTH (filename); | |
951 fn = (char *) alloca (max + fn_len + 1); | |
952 memcpy (fn, (char *) XSTRING_DATA (filename), fn_len); | |
953 | |
954 /* Loop over suffixes. */ | |
955 if (!STRINGP (suffixes)) | |
956 { | |
957 if (NILP (suffixes)) | |
958 { | |
959 /* Case a) discussed in the comment above. */ | |
960 fn[fn_len] = 0; | |
961 if ((*fun) (fn, arg)) | |
962 return; | |
963 } | |
964 else | |
965 { | |
966 /* Case b) */ | |
967 Lisp_Object tail; | |
968 LIST_LOOP (tail, suffixes) | |
969 { | |
970 memcpy (fn + fn_len, XSTRING_DATA (XCAR (tail)), | |
971 XSTRING_LENGTH (XCAR (tail))); | |
972 fn[fn_len + XSTRING_LENGTH (XCAR (tail))] = 0; | |
973 if ((*fun) (fn, arg)) | |
974 return; | |
975 } | |
976 } | |
977 } | |
978 else | |
979 { | |
980 /* Case c) */ | |
981 const char *nsuffix = (const char *) XSTRING_DATA (suffixes); | |
982 | |
983 while (1) | |
984 { | |
985 char *esuffix = (char *) strchr (nsuffix, ':'); | |
986 int lsuffix = ((esuffix) ? (esuffix - nsuffix) : strlen (nsuffix)); | |
987 | |
988 /* Concatenate path element/specified name with the suffix. */ | |
989 strncpy (fn + fn_len, nsuffix, lsuffix); | |
990 fn[fn_len + lsuffix] = 0; | |
991 | |
992 if ((*fun) (fn, arg)) | |
993 return; | |
994 | |
995 /* Advance to next suffix. */ | |
996 if (esuffix == 0) | |
997 break; | |
998 nsuffix += lsuffix + 1; | |
999 } | |
1000 } | |
1001 } | |
1002 | |
1003 struct locate_file_in_directory_mapper_closure { | |
1004 int fd; | |
1005 Lisp_Object *storeptr; | |
1006 int mode; | |
1007 }; | |
875 | 1008 |
876 static int | 1009 static int |
877 locate_file_in_directory (Lisp_Object path, Lisp_Object str, | 1010 locate_file_in_directory_mapper (char *fn, void *arg) |
878 CONST char *suffix, Lisp_Object *storeptr, | 1011 { |
1012 struct locate_file_in_directory_mapper_closure *closure = | |
1013 (struct locate_file_in_directory_mapper_closure *)arg; | |
1014 struct stat st; | |
1015 | |
1016 /* Ignore file if it's a directory. */ | |
1017 if (stat (fn, &st) >= 0 | |
1018 && (st.st_mode & S_IFMT) != S_IFDIR) | |
1019 { | |
1020 /* Check that we can access or open it. */ | |
1021 if (closure->mode >= 0) | |
1022 closure->fd = access (fn, closure->mode); | |
1023 else | |
1024 closure->fd = open (fn, O_RDONLY | OPEN_BINARY, 0); | |
1025 | |
1026 if (closure->fd >= 0) | |
1027 { | |
1028 /* We succeeded; return this descriptor and filename. */ | |
1029 if (closure->storeptr) | |
1030 *closure->storeptr = build_string (fn); | |
1031 | |
1032 #ifndef WINDOWSNT | |
1033 /* If we actually opened the file, set close-on-exec flag | |
1034 on the new descriptor so that subprocesses can't whack | |
1035 at it. */ | |
1036 if (closure->mode < 0) | |
1037 (void) fcntl (closure->fd, F_SETFD, FD_CLOEXEC); | |
1038 #endif | |
1039 | |
1040 return 1; | |
1041 } | |
1042 } | |
1043 /* Keep mapping. */ | |
1044 return 0; | |
1045 } | |
1046 | |
1047 | |
1048 /* look for STR in PATH, optionally adding SUFFIXES. DIRECTORY need | |
1049 not have been expanded. */ | |
1050 | |
1051 static int | |
1052 locate_file_in_directory (Lisp_Object directory, Lisp_Object str, | |
1053 Lisp_Object suffixes, Lisp_Object *storeptr, | |
879 int mode) | 1054 int mode) |
880 { | 1055 { |
881 /* This function can GC */ | 1056 /* This function can GC */ |
882 int fd; | 1057 struct locate_file_in_directory_mapper_closure closure; |
883 int fn_size = 100; | |
884 char buf[100]; | |
885 char *fn = buf; | |
886 int want_size; | |
887 struct stat st; | |
888 Lisp_Object filename = Qnil; | 1058 Lisp_Object filename = Qnil; |
889 struct gcpro gcpro1, gcpro2, gcpro3; | 1059 struct gcpro gcpro1, gcpro2, gcpro3; |
890 CONST char *nsuffix; | 1060 |
891 | 1061 GCPRO3 (directory, str, filename); |
892 GCPRO3 (path, str, filename); | 1062 |
893 | 1063 filename = Fexpand_file_name (str, directory); |
894 filename = Fexpand_file_name (str, path); | |
895 if (NILP (filename) || NILP (Ffile_name_absolute_p (filename))) | 1064 if (NILP (filename) || NILP (Ffile_name_absolute_p (filename))) |
896 /* If there are non-absolute elts in PATH (eg ".") */ | 1065 /* If there are non-absolute elts in PATH (eg ".") */ |
897 /* Of course, this could conceivably lose if luser sets | 1066 /* Of course, this could conceivably lose if luser sets |
898 default-directory to be something non-absolute ... */ | 1067 default-directory to be something non-absolute ... */ |
899 { | 1068 { |
903 else | 1072 else |
904 filename = Fexpand_file_name (filename, | 1073 filename = Fexpand_file_name (filename, |
905 current_buffer->directory); | 1074 current_buffer->directory); |
906 if (NILP (Ffile_name_absolute_p (filename))) | 1075 if (NILP (Ffile_name_absolute_p (filename))) |
907 { | 1076 { |
908 /* Give up on this path element! */ | 1077 /* Give up on this directory! */ |
909 UNGCPRO; | 1078 UNGCPRO; |
910 return -1; | 1079 return -1; |
911 } | 1080 } |
912 } | 1081 } |
913 /* Calculate maximum size of any filename made from | 1082 |
914 this path element/specified file name and any possible suffix. */ | 1083 closure.fd = -1; |
915 want_size = strlen (suffix) + XSTRING_LENGTH (filename) + 1; | 1084 closure.storeptr = storeptr; |
916 if (fn_size < want_size) | 1085 closure.mode = mode; |
917 fn = (char *) alloca (fn_size = 100 + want_size); | 1086 |
918 | 1087 locate_file_map_suffixes (filename, suffixes, locate_file_in_directory_mapper, |
919 nsuffix = suffix; | 1088 &closure); |
920 | |
921 /* Loop over suffixes. */ | |
922 while (1) | |
923 { | |
924 char *esuffix = (char *) strchr (nsuffix, ':'); | |
925 int lsuffix = ((esuffix) ? (esuffix - nsuffix) : strlen (nsuffix)); | |
926 | |
927 /* Concatenate path element/specified name with the suffix. */ | |
928 strncpy (fn, (char *) XSTRING_DATA (filename), | |
929 XSTRING_LENGTH (filename)); | |
930 fn[XSTRING_LENGTH (filename)] = 0; | |
931 if (lsuffix != 0) /* Bug happens on CCI if lsuffix is 0. */ | |
932 strncat (fn, nsuffix, lsuffix); | |
933 | |
934 /* Ignore file if it's a directory. */ | |
935 if (stat (fn, &st) >= 0 | |
936 && (st.st_mode & S_IFMT) != S_IFDIR) | |
937 { | |
938 /* Check that we can access or open it. */ | |
939 if (mode >= 0) | |
940 fd = access (fn, mode); | |
941 else | |
942 fd = open (fn, O_RDONLY | OPEN_BINARY, 0); | |
943 | |
944 if (fd >= 0) | |
945 { | |
946 /* We succeeded; return this descriptor and filename. */ | |
947 if (storeptr) | |
948 *storeptr = build_string (fn); | |
949 UNGCPRO; | |
950 | |
951 #ifndef WINDOWSNT | |
952 /* If we actually opened the file, set close-on-exec flag | |
953 on the new descriptor so that subprocesses can't whack | |
954 at it. */ | |
955 if (mode < 0) | |
956 (void) fcntl (fd, F_SETFD, FD_CLOEXEC); | |
957 #endif | |
958 | |
959 return fd; | |
960 } | |
961 } | |
962 | |
963 /* Advance to next suffix. */ | |
964 if (esuffix == 0) | |
965 break; | |
966 nsuffix += lsuffix + 1; | |
967 } | |
968 | 1089 |
969 UNGCPRO; | 1090 UNGCPRO; |
970 return -1; | 1091 return closure.fd; |
971 } | 1092 } |
972 | 1093 |
973 /* do the same as locate_file() but don't use any hash tables. */ | 1094 /* do the same as locate_file() but don't use any hash tables. */ |
974 | 1095 |
975 static int | 1096 static int |
976 locate_file_without_hash (Lisp_Object path, Lisp_Object str, | 1097 locate_file_without_hash (Lisp_Object path, Lisp_Object str, |
977 CONST char *suffix, Lisp_Object *storeptr, | 1098 Lisp_Object suffixes, Lisp_Object *storeptr, |
978 int mode) | 1099 int mode) |
979 { | 1100 { |
980 /* This function can GC */ | 1101 /* This function can GC */ |
981 int absolute; | 1102 int absolute = !NILP (Ffile_name_absolute_p (str)); |
982 struct gcpro gcpro1; | 1103 |
983 | 1104 EXTERNAL_LIST_LOOP (path, path) |
984 /* is this necessary? */ | 1105 { |
985 GCPRO1 (path); | 1106 int val = locate_file_in_directory (XCAR (path), str, suffixes, storeptr, |
986 | 1107 mode); |
987 absolute = !NILP (Ffile_name_absolute_p (str)); | |
988 | |
989 for (; !NILP (path); path = Fcdr (path)) | |
990 { | |
991 int val = locate_file_in_directory (Fcar (path), str, suffix, | |
992 storeptr, mode); | |
993 if (val >= 0) | 1108 if (val >= 0) |
994 { | 1109 return val; |
995 UNGCPRO; | |
996 return val; | |
997 } | |
998 if (absolute) | 1110 if (absolute) |
999 break; | 1111 break; |
1000 } | 1112 } |
1113 return -1; | |
1114 } | |
1115 | |
1116 static int | |
1117 locate_file_construct_suffixed_files_mapper (char *fn, void *arg) | |
1118 { | |
1119 Lisp_Object *tail = (Lisp_Object *)arg; | |
1120 *tail = Fcons (build_string (fn), *tail); | |
1121 return 0; | |
1122 } | |
1123 | |
1124 /* Construct a list of all files to search for. | |
1125 It makes sense to have this despite locate_file_map_suffixes() | |
1126 because we need Lisp strings to access the hash-table, and it would | |
1127 be inefficient to create them on the fly, again and again for each | |
1128 path component. See locate_file(). */ | |
1129 | |
1130 static Lisp_Object | |
1131 locate_file_construct_suffixed_files (Lisp_Object filename, | |
1132 Lisp_Object suffixes) | |
1133 { | |
1134 Lisp_Object tail = Qnil; | |
1135 struct gcpro gcpro1; | |
1136 GCPRO1 (tail); | |
1137 | |
1138 locate_file_map_suffixes (filename, suffixes, | |
1139 locate_file_construct_suffixed_files_mapper, | |
1140 &tail); | |
1001 | 1141 |
1002 UNGCPRO; | 1142 UNGCPRO; |
1003 return -1; | 1143 return Fnreverse (tail); |
1004 } | |
1005 | |
1006 /* Construct a list of all files to search for. */ | |
1007 | |
1008 static Lisp_Object | |
1009 locate_file_construct_suffixed_files (Lisp_Object str, CONST char *suffix) | |
1010 { | |
1011 int want_size; | |
1012 int fn_size = 100; | |
1013 char buf[100]; | |
1014 char *fn = buf; | |
1015 CONST char *nsuffix; | |
1016 Lisp_Object suffixtab = Qnil; | |
1017 | |
1018 /* Calculate maximum size of any filename made from | |
1019 this path element/specified file name and any possible suffix. */ | |
1020 want_size = strlen (suffix) + XSTRING_LENGTH (str) + 1; | |
1021 if (fn_size < want_size) | |
1022 fn = (char *) alloca (fn_size = 100 + want_size); | |
1023 | |
1024 nsuffix = suffix; | |
1025 | |
1026 while (1) | |
1027 { | |
1028 char *esuffix = (char *) strchr (nsuffix, ':'); | |
1029 int lsuffix = ((esuffix) ? (esuffix - nsuffix) : strlen (nsuffix)); | |
1030 | |
1031 /* Concatenate path element/specified name with the suffix. */ | |
1032 strncpy (fn, (char *) XSTRING_DATA (str), XSTRING_LENGTH (str)); | |
1033 fn[XSTRING_LENGTH (str)] = 0; | |
1034 if (lsuffix != 0) /* Bug happens on CCI if lsuffix is 0. */ | |
1035 strncat (fn, nsuffix, lsuffix); | |
1036 | |
1037 suffixtab = Fcons (build_string (fn), suffixtab); | |
1038 /* Advance to next suffix. */ | |
1039 if (esuffix == 0) | |
1040 break; | |
1041 nsuffix += lsuffix + 1; | |
1042 } | |
1043 return Fnreverse (suffixtab); | |
1044 } | 1144 } |
1045 | 1145 |
1046 DEFUN ("locate-file-clear-hashing", Flocate_file_clear_hashing, 1, 1, 0, /* | 1146 DEFUN ("locate-file-clear-hashing", Flocate_file_clear_hashing, 1, 1, 0, /* |
1047 Clear the hash records for the specified list of directories. | 1147 Clear the hash records for the specified list of directories. |
1048 `locate-file' uses a hashing scheme to speed lookup, and will correctly | 1148 `locate-file' uses a hashing scheme to speed lookup, and will correctly |
1054 -- byte-compilation of a .el file into a .elc file. | 1154 -- byte-compilation of a .el file into a .elc file. |
1055 | 1155 |
1056 `locate-file' will primarily get confused if you add a file that shadows | 1156 `locate-file' will primarily get confused if you add a file that shadows |
1057 \(i.e. has the same name as) another file further down in the directory list. | 1157 \(i.e. has the same name as) another file further down in the directory list. |
1058 In this case, you must call `locate-file-clear-hashing'. | 1158 In this case, you must call `locate-file-clear-hashing'. |
1159 | |
1160 If PATH is t, it means to fully clear all the accumulated hashes. This | |
1161 can be used if the internal tables grow too large, or when dumping. | |
1059 */ | 1162 */ |
1060 (path)) | 1163 (path)) |
1061 { | 1164 { |
1062 Lisp_Object pathtail; | 1165 if (EQ (path, Qt)) |
1063 | 1166 Fclrhash (Vlocate_file_hash_table); |
1064 for (pathtail = path; !NILP (pathtail); pathtail = Fcdr (pathtail)) | 1167 else |
1065 { | 1168 { |
1066 Lisp_Object pathel = Fcar (pathtail); | 1169 Lisp_Object pathtail; |
1067 if (!purified (pathel)) | 1170 EXTERNAL_LIST_LOOP (pathtail, path) |
1068 Fput (pathel, Qlocate_file_hash_table, Qnil); | 1171 { |
1172 Lisp_Object pathel = Fexpand_file_name (XCAR (pathtail), Qnil); | |
1173 Fremhash (pathel, Vlocate_file_hash_table); | |
1174 } | |
1069 } | 1175 } |
1070 return Qnil; | 1176 return Qnil; |
1071 } | 1177 } |
1072 | 1178 |
1073 /* Search for a file whose name is STR, looking in directories | 1179 /* Search for a file whose name is STR, looking in directories |
1074 in the Lisp list PATH, and trying suffixes from SUFFIX. | 1180 in the Lisp list PATH, and trying suffixes from SUFFIXES. |
1075 SUFFIX is a string containing possible suffixes separated by colons. | 1181 SUFFIXES is a list of possible suffixes, or (for backward |
1182 compatibility) a string containing possible suffixes separated by | |
1183 colons. | |
1076 On success, returns a file descriptor. On failure, returns -1. | 1184 On success, returns a file descriptor. On failure, returns -1. |
1077 | 1185 |
1078 MODE nonnegative means don't open the files, | 1186 MODE nonnegative means don't open the files, |
1079 just look for one for which access(file,MODE) succeeds. In this case, | 1187 just look for one for which access(file,MODE) succeeds. In this case, |
1080 returns 1 on success. | 1188 returns 1 on success. |
1084 Nil is stored there on failure. | 1192 Nil is stored there on failure. |
1085 | 1193 |
1086 Called openp() in FSFmacs. */ | 1194 Called openp() in FSFmacs. */ |
1087 | 1195 |
1088 int | 1196 int |
1089 locate_file (Lisp_Object path, Lisp_Object str, CONST char *suffix, | 1197 locate_file (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, |
1090 Lisp_Object *storeptr, int mode) | 1198 Lisp_Object *storeptr, int mode) |
1091 { | 1199 { |
1092 /* This function can GC */ | 1200 /* This function can GC */ |
1093 Lisp_Object suffixtab = Qnil; | 1201 Lisp_Object suffixtab = Qnil; |
1094 Lisp_Object pathtail; | 1202 Lisp_Object pathtail, pathel_expanded; |
1095 int val; | 1203 int val; |
1096 struct gcpro gcpro1, gcpro2, gcpro3; | 1204 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
1097 | 1205 |
1098 if (storeptr) | 1206 if (storeptr) |
1099 *storeptr = Qnil; | 1207 *storeptr = Qnil; |
1208 | |
1209 /* Is it really necessary to gcpro path and str? It shouldn't be | |
1210 unless some caller has fucked up. There are known instances that | |
1211 call us with build_string("foo:bar") as SUFFIXES, though. */ | |
1212 GCPRO4 (path, str, suffixes, suffixtab); | |
1100 | 1213 |
1101 /* if this filename has directory components, it's too complicated | 1214 /* if this filename has directory components, it's too complicated |
1102 to try and use the hash tables. */ | 1215 to try and use the hash tables. */ |
1103 if (!NILP (Ffile_name_directory (str))) | 1216 if (!NILP (Ffile_name_directory (str))) |
1104 return locate_file_without_hash (path, str, suffix, storeptr, | 1217 { |
1105 mode); | 1218 val = locate_file_without_hash (path, str, suffixes, storeptr, mode); |
1106 | 1219 UNGCPRO; |
1107 /* Is it really necessary to gcpro path and str? It shouldn't be | 1220 return val; |
1108 unless some caller has fucked up. */ | 1221 } |
1109 GCPRO3 (path, str, suffixtab); | 1222 |
1110 | 1223 suffixtab = locate_file_construct_suffixed_files (str, suffixes); |
1111 suffixtab = locate_file_construct_suffixed_files (str, suffix); | 1224 |
1112 | 1225 EXTERNAL_LIST_LOOP (pathtail, path) |
1113 for (pathtail = path; !NILP (pathtail); pathtail = Fcdr (pathtail)) | 1226 { |
1114 { | 1227 Lisp_Object pathel = XCAR (pathtail); |
1115 Lisp_Object pathel = Fcar (pathtail); | |
1116 Lisp_Object hash_table; | 1228 Lisp_Object hash_table; |
1117 Lisp_Object tail; | 1229 Lisp_Object tail; |
1118 int found; | 1230 int found = 0; |
1119 | 1231 |
1120 /* If this path element is relative, we have to look by hand. | 1232 /* If this path element is relative, we have to look by hand. */ |
1121 Can't set string property in a pure string. */ | 1233 if (NILP (Ffile_name_absolute_p (pathel))) |
1122 if (NILP (pathel) || NILP (Ffile_name_absolute_p (pathel)) || | |
1123 purified (pathel)) | |
1124 { | 1234 { |
1125 val = locate_file_in_directory (pathel, str, suffix, storeptr, | 1235 val = locate_file_in_directory (pathel, str, suffixes, storeptr, |
1126 mode); | 1236 mode); |
1127 if (val >= 0) | 1237 if (val >= 0) |
1128 { | 1238 { |
1129 UNGCPRO; | 1239 UNGCPRO; |
1130 return val; | 1240 return val; |
1131 } | 1241 } |
1132 continue; | 1242 continue; |
1133 } | 1243 } |
1134 | 1244 |
1135 hash_table = locate_file_find_directory_hash_table (pathel); | 1245 pathel_expanded = Fexpand_file_name (pathel, Qnil); |
1136 | 1246 hash_table = locate_file_find_directory_hash_table (pathel_expanded); |
1137 /* Loop over suffixes. */ | 1247 |
1138 for (tail = suffixtab, found = 0; !found && CONSP (tail); | 1248 if (!NILP (hash_table)) |
1139 tail = XCDR (tail)) | |
1140 { | 1249 { |
1141 if (!NILP (Fgethash (XCAR (tail), hash_table, Qnil))) | 1250 /* Loop over suffixes. */ |
1142 found = 1; | 1251 LIST_LOOP (tail, suffixtab) |
1252 if (!NILP (Fgethash (XCAR (tail), hash_table, Qnil))) | |
1253 { | |
1254 found = 1; | |
1255 break; | |
1256 } | |
1143 } | 1257 } |
1144 | 1258 |
1145 if (found) | 1259 if (found) |
1146 { | 1260 { |
1147 /* This is a likely candidate. Look by hand in this directory | 1261 /* This is a likely candidate. Look by hand in this directory |
1148 so we don't get thrown off if someone byte-compiles a file. */ | 1262 so we don't get thrown off if someone byte-compiles a file. */ |
1149 val = locate_file_in_directory (pathel, str, suffix, storeptr, | 1263 val = locate_file_in_directory (pathel, str, suffixes, storeptr, |
1150 mode); | 1264 mode); |
1151 if (val >= 0) | 1265 if (val >= 0) |
1152 { | 1266 { |
1153 UNGCPRO; | 1267 UNGCPRO; |
1154 return val; | 1268 return val; |
1155 } | 1269 } |
1156 | 1270 |
1157 /* Hmm ... the file isn't actually there. (Or possibly it's | 1271 /* Hmm ... the file isn't actually there. (Or possibly it's |
1158 a directory ...) So refresh our hashing. */ | 1272 a directory ...) So refresh our hashing. */ |
1159 locate_file_refresh_hashing (pathel); | 1273 locate_file_refresh_hashing (pathel_expanded); |
1160 } | 1274 } |
1161 } | 1275 } |
1162 | 1276 |
1163 /* File is probably not there, but check the hard way just in case. */ | 1277 /* File is probably not there, but check the hard way just in case. */ |
1164 val = locate_file_without_hash (path, str, suffix, storeptr, | 1278 val = locate_file_without_hash (path, str, suffixes, storeptr, mode); |
1165 mode); | |
1166 if (val >= 0) | 1279 if (val >= 0) |
1167 { | 1280 { |
1168 /* Sneaky user added a file without telling us. */ | 1281 /* Sneaky user added a file without telling us. */ |
1169 Flocate_file_clear_hashing (path); | 1282 Flocate_file_clear_hashing (path); |
1170 } | 1283 } |
1323 } | 1436 } |
1324 else | 1437 else |
1325 #else /* No "defun hack" -- Emacs 19 uses read-time syntax for bytecodes */ | 1438 #else /* No "defun hack" -- Emacs 19 uses read-time syntax for bytecodes */ |
1326 { | 1439 { |
1327 unreadchar (readcharfun, c); | 1440 unreadchar (readcharfun, c); |
1328 read_objects = Qnil; | 1441 Vread_objects = Qnil; |
1329 if (NILP (Vload_read_function)) | 1442 if (NILP (Vload_read_function)) |
1330 val = read0 (readcharfun); | 1443 val = read0 (readcharfun); |
1331 else | 1444 else |
1332 val = call1 (Vload_read_function, readcharfun); | 1445 val = call1 (Vload_read_function, readcharfun); |
1333 } | 1446 } |
1461 if (NILP (stream)) | 1574 if (NILP (stream)) |
1462 stream = Vstandard_input; | 1575 stream = Vstandard_input; |
1463 if (EQ (stream, Qt)) | 1576 if (EQ (stream, Qt)) |
1464 stream = Qread_char; | 1577 stream = Qread_char; |
1465 | 1578 |
1466 read_objects = Qnil; | 1579 Vread_objects = Qnil; |
1467 | 1580 |
1468 #ifdef COMPILED_FUNCTION_ANNOTATION_HACK | 1581 #ifdef COMPILED_FUNCTION_ANNOTATION_HACK |
1469 Vcurrent_compiled_function_annotation = Qnil; | 1582 Vcurrent_compiled_function_annotation = Qnil; |
1470 #endif | 1583 #endif |
1471 if (EQ (stream, Qread_char)) | 1584 if (EQ (stream, Qread_char)) |
1502 get_string_range_byte (string, start, end, &startval, &endval, | 1615 get_string_range_byte (string, start, end, &startval, &endval, |
1503 GB_HISTORICAL_STRING_BEHAVIOR); | 1616 GB_HISTORICAL_STRING_BEHAVIOR); |
1504 lispstream = make_lisp_string_input_stream (string, startval, | 1617 lispstream = make_lisp_string_input_stream (string, startval, |
1505 endval - startval); | 1618 endval - startval); |
1506 | 1619 |
1507 read_objects = Qnil; | 1620 Vread_objects = Qnil; |
1508 | 1621 |
1509 tem = read0 (lispstream); | 1622 tem = read0 (lispstream); |
1510 /* Yeah, it's ugly. Gonna make something of it? | 1623 /* Yeah, it's ugly. Gonna make something of it? |
1511 At least our reader is reentrant ... */ | 1624 At least our reader is reentrant ... */ |
1512 tem = | 1625 tem = |
1537 /* Use this for recursive reads, in contexts where internal tokens | 1650 /* Use this for recursive reads, in contexts where internal tokens |
1538 are not allowed. See also read1(). */ | 1651 are not allowed. See also read1(). */ |
1539 static Lisp_Object | 1652 static Lisp_Object |
1540 read0 (Lisp_Object readcharfun) | 1653 read0 (Lisp_Object readcharfun) |
1541 { | 1654 { |
1542 Lisp_Object val; | 1655 Lisp_Object val = read1 (readcharfun); |
1543 | 1656 |
1544 val = read1 (readcharfun); | |
1545 if (CONSP (val) && UNBOUNDP (XCAR (val))) | 1657 if (CONSP (val) && UNBOUNDP (XCAR (val))) |
1546 { | 1658 { |
1547 Emchar c = XCHAR (XCDR (val)); | 1659 Emchar c = XCHAR (XCDR (val)); |
1548 free_cons (XCONS (val)); | 1660 free_cons (XCONS (val)); |
1549 return Fsignal (Qinvalid_read_syntax, | 1661 return Fsignal (Qinvalid_read_syntax, |
1679 } | 1791 } |
1680 return i; | 1792 return i; |
1681 } | 1793 } |
1682 | 1794 |
1683 case 'x': | 1795 case 'x': |
1684 /* A hex escape, as in ANSI C. */ | 1796 /* A hex escape, as in ANSI C, except that we only allow latin-1 |
1797 characters to be read this way. What is "\x4e03" supposed to | |
1798 mean, anyways, if the internal representation is hidden? | |
1799 This is also consistent with the treatment of octal escapes. */ | |
1685 { | 1800 { |
1686 REGISTER Emchar i = 0; | 1801 REGISTER Emchar i = 0; |
1687 while (1) | 1802 REGISTER int count = 0; |
1803 while (++count <= 2) | |
1688 { | 1804 { |
1689 c = readchar (readcharfun); | 1805 c = readchar (readcharfun); |
1690 /* Remember, can't use isdigit(), isalpha() etc. on Emchars */ | 1806 /* Remember, can't use isdigit(), isalpha() etc. on Emchars */ |
1691 if (c >= '0' && c <= '9') i = (i << 4) + (c - '0'); | 1807 if (c >= '0' && c <= '9') i = (i << 4) + (c - '0'); |
1692 else if (c >= 'a' && c <= 'f') i = (i << 4) + (c - 'a') + 10; | 1808 else if (c >= 'a' && c <= 'f') i = (i << 4) + (c - 'a') + 10; |
1752 Lstream_flush (XLSTREAM (Vread_buffer_stream)); | 1868 Lstream_flush (XLSTREAM (Vread_buffer_stream)); |
1753 | 1869 |
1754 return Lstream_byte_count (XLSTREAM (Vread_buffer_stream)) - 1; | 1870 return Lstream_byte_count (XLSTREAM (Vread_buffer_stream)) - 1; |
1755 } | 1871 } |
1756 | 1872 |
1757 static Lisp_Object parse_integer (CONST Bufbyte *buf, Bytecount len, int base); | 1873 static Lisp_Object parse_integer (const Bufbyte *buf, Bytecount len, int base); |
1758 | 1874 |
1759 static Lisp_Object | 1875 static Lisp_Object |
1760 read_atom (Lisp_Object readcharfun, | 1876 read_atom (Lisp_Object readcharfun, |
1761 Emchar firstchar, | 1877 Emchar firstchar, |
1762 int uninterned_symbol) | 1878 int uninterned_symbol) |
1820 } | 1936 } |
1821 | 1937 |
1822 { | 1938 { |
1823 Lisp_Object sym; | 1939 Lisp_Object sym; |
1824 if (uninterned_symbol) | 1940 if (uninterned_symbol) |
1825 sym = (Fmake_symbol ((purify_flag) | 1941 sym = Fmake_symbol ( make_string ((Bufbyte *) read_ptr, len)); |
1826 ? make_pure_pname ((Bufbyte *) read_ptr, len, 0) | |
1827 : make_string ((Bufbyte *) read_ptr, len))); | |
1828 else | 1942 else |
1829 { | 1943 { |
1830 /* intern will purecopy pname if necessary */ | |
1831 Lisp_Object name = make_string ((Bufbyte *) read_ptr, len); | 1944 Lisp_Object name = make_string ((Bufbyte *) read_ptr, len); |
1832 sym = Fintern (name, Qnil); | 1945 sym = Fintern (name, Qnil); |
1833 | |
1834 if (SYMBOL_IS_KEYWORD (sym)) | |
1835 { | |
1836 /* the LISP way is to put keywords in their own package, | |
1837 but we don't have packages, so we do something simpler. | |
1838 Someday, maybe we'll have packages and then this will | |
1839 be reworked. --Stig. */ | |
1840 XSYMBOL (sym)->value = sym; | |
1841 } | |
1842 } | 1946 } |
1843 return sym; | 1947 return sym; |
1844 } | 1948 } |
1845 } | 1949 } |
1846 | 1950 |
1847 | 1951 |
1848 static Lisp_Object | 1952 static Lisp_Object |
1849 parse_integer (CONST Bufbyte *buf, Bytecount len, int base) | 1953 parse_integer (const Bufbyte *buf, Bytecount len, int base) |
1850 { | 1954 { |
1851 CONST Bufbyte *lim = buf + len; | 1955 const Bufbyte *lim = buf + len; |
1852 CONST Bufbyte *p = buf; | 1956 const Bufbyte *p = buf; |
1853 EMACS_UINT num = 0; | 1957 EMACS_UINT num = 0; |
1854 int negativland = 0; | 1958 int negativland = 0; |
1855 | 1959 |
1856 if (*p == '-') | 1960 if (*p == '-') |
1857 { | 1961 { |
1930 static Lisp_Object | 2034 static Lisp_Object |
1931 read_bit_vector (Lisp_Object readcharfun) | 2035 read_bit_vector (Lisp_Object readcharfun) |
1932 { | 2036 { |
1933 unsigned_char_dynarr *dyn = Dynarr_new (unsigned_char); | 2037 unsigned_char_dynarr *dyn = Dynarr_new (unsigned_char); |
1934 Emchar c; | 2038 Emchar c; |
2039 Lisp_Object val; | |
1935 | 2040 |
1936 while (1) | 2041 while (1) |
1937 { | 2042 { |
1938 c = readchar (readcharfun); | 2043 c = readchar (readcharfun); |
1939 if (c != '0' && c != '1') | 2044 if (c != '0' && c != '1') |
1942 } | 2047 } |
1943 | 2048 |
1944 if (c >= 0) | 2049 if (c >= 0) |
1945 unreadchar (readcharfun, c); | 2050 unreadchar (readcharfun, c); |
1946 | 2051 |
1947 return make_bit_vector_from_byte_vector (Dynarr_atp (dyn, 0), | 2052 val = make_bit_vector_from_byte_vector (Dynarr_atp (dyn, 0), |
1948 Dynarr_length (dyn)); | 2053 Dynarr_length (dyn)); |
2054 | |
2055 Dynarr_free (dyn); | |
2056 | |
2057 return val; | |
1949 } | 2058 } |
1950 | 2059 |
1951 | 2060 |
1952 | 2061 |
1953 /* structures */ | 2062 /* structures */ |
2419 { | 2528 { |
2420 n *= 10; | 2529 n *= 10; |
2421 n += c - '0'; | 2530 n += c - '0'; |
2422 c = readchar (readcharfun); | 2531 c = readchar (readcharfun); |
2423 } | 2532 } |
2424 found = assq_no_quit (make_int (n), read_objects); | 2533 found = assq_no_quit (make_int (n), Vread_objects); |
2425 if (c == '=') | 2534 if (c == '=') |
2426 { | 2535 { |
2427 /* #n=object returns object, but associates it with | 2536 /* #n=object returns object, but associates it with |
2428 n for #n#. */ | 2537 n for #n#. */ |
2429 Lisp_Object obj; | 2538 Lisp_Object obj; |
2431 return Fsignal (Qinvalid_read_syntax, | 2540 return Fsignal (Qinvalid_read_syntax, |
2432 list2 (build_translated_string | 2541 list2 (build_translated_string |
2433 ("Multiply defined symbol label"), | 2542 ("Multiply defined symbol label"), |
2434 make_int (n))); | 2543 make_int (n))); |
2435 obj = read0 (readcharfun); | 2544 obj = read0 (readcharfun); |
2436 read_objects = Fcons (Fcons (make_int (n), obj), read_objects); | 2545 Vread_objects = Fcons (Fcons (make_int (n), obj), |
2546 Vread_objects); | |
2437 return obj; | 2547 return obj; |
2438 } | 2548 } |
2439 else if (c == '#') | 2549 else if (c == '#') |
2440 { | 2550 { |
2441 /* #n# returns a previously read object. */ | 2551 /* #n# returns a previously read object. */ |
2557 that we are really going to find in lib-src/DOC.nn.nn */ | 2667 that we are really going to find in lib-src/DOC.nn.nn */ |
2558 if (purify_flag && NILP (Vinternal_doc_file_name) && cancel) | 2668 if (purify_flag && NILP (Vinternal_doc_file_name) && cancel) |
2559 return Qzero; | 2669 return Qzero; |
2560 | 2670 |
2561 Lstream_flush (XLSTREAM (Vread_buffer_stream)); | 2671 Lstream_flush (XLSTREAM (Vread_buffer_stream)); |
2562 #if 0 /* FSFmacs defun hack */ | 2672 return |
2563 if (read_pure) | 2673 make_string |
2564 return | 2674 (resizing_buffer_stream_ptr (XLSTREAM (Vread_buffer_stream)), |
2565 make_pure_string | 2675 Lstream_byte_count (XLSTREAM (Vread_buffer_stream))); |
2566 (resizing_buffer_stream_ptr (XLSTREAM (Vread_buffer_stream)), | |
2567 Lstream_byte_count (XLSTREAM (Vread_buffer_stream))); | |
2568 else | |
2569 #endif | |
2570 return | |
2571 make_string | |
2572 (resizing_buffer_stream_ptr (XLSTREAM (Vread_buffer_stream)), | |
2573 Lstream_byte_count (XLSTREAM (Vread_buffer_stream))); | |
2574 } | 2676 } |
2575 | 2677 |
2576 default: | 2678 default: |
2577 { | 2679 { |
2578 /* Ignore whitespace and control characters */ | 2680 /* Ignore whitespace and control characters */ |
2592 #define TRAIL_INT 4 | 2694 #define TRAIL_INT 4 |
2593 #define E_CHAR 8 | 2695 #define E_CHAR 8 |
2594 #define EXP_INT 16 | 2696 #define EXP_INT 16 |
2595 | 2697 |
2596 int | 2698 int |
2597 isfloat_string (CONST char *cp) | 2699 isfloat_string (const char *cp) |
2598 { | 2700 { |
2599 int state = 0; | 2701 int state = 0; |
2600 CONST Bufbyte *ucp = (CONST Bufbyte *) cp; | 2702 const Bufbyte *ucp = (const Bufbyte *) cp; |
2601 | 2703 |
2602 if (*ucp == '+' || *ucp == '-') | 2704 if (*ucp == '+' || *ucp == '-') |
2603 ucp++; | 2705 ucp++; |
2604 | 2706 |
2605 if (*ucp >= '0' && *ucp <= '9') | 2707 if (*ucp >= '0' && *ucp <= '9') |
2898 | 3000 |
2899 for (i = 0, p = &(XVECTOR_DATA (s.head)[0]); | 3001 for (i = 0, p = &(XVECTOR_DATA (s.head)[0]); |
2900 i < len; | 3002 i < len; |
2901 i++, p++) | 3003 i++, p++) |
2902 { | 3004 { |
2903 struct Lisp_Cons *otem = XCONS (tem); | 3005 Lisp_Cons *otem = XCONS (tem); |
2904 #if 0 /* FSFmacs defun hack */ | 3006 tem = Fcar (tem); |
2905 if (read_pure) | |
2906 tem = Fpurecopy (Fcar (tem)); | |
2907 else | |
2908 #endif | |
2909 tem = Fcar (tem); | |
2910 *p = tem; | 3007 *p = tem; |
2911 tem = otem->cdr; | 3008 tem = otem->cdr; |
2912 free_cons (otem); | 3009 free_cons (otem); |
2913 } | 3010 } |
2914 return s.head; | 3011 return s.head; |
2935 return | 3032 return |
2936 continuable_syntax_error ("#[...] used with wrong number of elements"); | 3033 continuable_syntax_error ("#[...] used with wrong number of elements"); |
2937 | 3034 |
2938 for (iii = 0; CONSP (stuff); iii++) | 3035 for (iii = 0; CONSP (stuff); iii++) |
2939 { | 3036 { |
2940 struct Lisp_Cons *victim = XCONS (stuff); | 3037 Lisp_Cons *victim = XCONS (stuff); |
2941 make_byte_code_args[iii] = Fcar (stuff); | 3038 make_byte_code_args[iii] = Fcar (stuff); |
2942 if ((purify_flag || load_force_doc_strings) | 3039 if ((purify_flag || load_force_doc_strings) |
2943 && CONSP (make_byte_code_args[iii]) | 3040 && CONSP (make_byte_code_args[iii]) |
2944 && EQ (XCAR (make_byte_code_args[iii]), Vload_file_name_internal)) | 3041 && EQ (XCAR (make_byte_code_args[iii]), Vload_file_name_internal)) |
2945 { | 3042 { |
3020 defsymbol (&Qstandard_input, "standard-input"); | 3117 defsymbol (&Qstandard_input, "standard-input"); |
3021 defsymbol (&Qread_char, "read-char"); | 3118 defsymbol (&Qread_char, "read-char"); |
3022 defsymbol (&Qcurrent_load_list, "current-load-list"); | 3119 defsymbol (&Qcurrent_load_list, "current-load-list"); |
3023 defsymbol (&Qload, "load"); | 3120 defsymbol (&Qload, "load"); |
3024 defsymbol (&Qload_file_name, "load-file-name"); | 3121 defsymbol (&Qload_file_name, "load-file-name"); |
3025 defsymbol (&Qlocate_file_hash_table, "locate-file-hash-table"); | |
3026 defsymbol (&Qfset, "fset"); | 3122 defsymbol (&Qfset, "fset"); |
3027 | 3123 |
3028 #ifdef LISP_BACKQUOTES | 3124 #ifdef LISP_BACKQUOTES |
3029 defsymbol (&Qbackquote, "backquote"); | 3125 defsymbol (&Qbackquote, "backquote"); |
3030 defsymbol (&Qbacktick, "`"); | 3126 defsymbol (&Qbacktick, "`"); |
3031 defsymbol (&Qcomma, ","); | 3127 defsymbol (&Qcomma, ","); |
3032 defsymbol (&Qcomma_at, ",@"); | 3128 defsymbol (&Qcomma_at, ",@"); |
3033 defsymbol (&Qcomma_dot, ",."); | 3129 defsymbol (&Qcomma_dot, ",."); |
3034 #endif | 3130 #endif |
3131 | |
3132 defsymbol (&Qexists, "exists"); | |
3133 defsymbol (&Qreadable, "readable"); | |
3134 defsymbol (&Qwritable, "writable"); | |
3135 defsymbol (&Qexecutable, "executable"); | |
3035 } | 3136 } |
3036 | 3137 |
3037 void | 3138 void |
3038 structure_type_create (void) | 3139 structure_type_create (void) |
3039 { | 3140 { |
3040 the_structure_type_dynarr = Dynarr_new (structure_type); | 3141 the_structure_type_dynarr = Dynarr_new (structure_type); |
3041 } | 3142 } |
3042 | 3143 |
3043 void | 3144 void |
3145 reinit_vars_of_lread (void) | |
3146 { | |
3147 Vread_buffer_stream = Qnil; | |
3148 staticpro_nodump (&Vread_buffer_stream); | |
3149 } | |
3150 | |
3151 void | |
3044 vars_of_lread (void) | 3152 vars_of_lread (void) |
3045 { | 3153 { |
3154 reinit_vars_of_lread (); | |
3155 | |
3046 DEFVAR_LISP ("values", &Vvalues /* | 3156 DEFVAR_LISP ("values", &Vvalues /* |
3047 List of values of all expressions which were read, evaluated and printed. | 3157 List of values of all expressions which were read, evaluated and printed. |
3048 Order is reverse chronological. | 3158 Order is reverse chronological. |
3049 */ ); | 3159 */ ); |
3050 | 3160 |
3158 | 3268 |
3159 /* This must be initialized in init_lread otherwise it may start out | 3269 /* This must be initialized in init_lread otherwise it may start out |
3160 with values saved when the image is dumped. */ | 3270 with values saved when the image is dumped. */ |
3161 staticpro (&Vload_descriptor_list); | 3271 staticpro (&Vload_descriptor_list); |
3162 | 3272 |
3163 Vread_buffer_stream = Qnil; | |
3164 staticpro (&Vread_buffer_stream); | |
3165 | |
3166 /* Initialized in init_lread. */ | 3273 /* Initialized in init_lread. */ |
3167 staticpro (&Vload_force_doc_string_list); | 3274 staticpro (&Vload_force_doc_string_list); |
3168 | 3275 |
3169 Vload_file_name_internal = Qnil; | 3276 Vload_file_name_internal = Qnil; |
3170 staticpro (&Vload_file_name_internal); | 3277 staticpro (&Vload_file_name_internal); |
3194 | 3301 |
3195 #ifdef I18N3 | 3302 #ifdef I18N3 |
3196 Vfile_domain = Qnil; | 3303 Vfile_domain = Qnil; |
3197 #endif | 3304 #endif |
3198 | 3305 |
3199 read_objects = Qnil; | 3306 Vread_objects = Qnil; |
3200 staticpro (&read_objects); | 3307 staticpro (&Vread_objects); |
3201 } | 3308 |
3309 Vlocate_file_hash_table = make_lisp_hash_table (200, | |
3310 HASH_TABLE_NON_WEAK, | |
3311 HASH_TABLE_EQUAL); | |
3312 staticpro (&Vlocate_file_hash_table); | |
3313 #ifdef DEBUG_XEMACS | |
3314 symbol_value (XSYMBOL (intern ("Vlocate-file-hash-table"))) | |
3315 = Vlocate_file_hash_table; | |
3316 #endif | |
3317 } |