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 }