Mercurial > hg > xemacs-beta
comparison src/lread.c @ 1123:37bdd24225ef
[xemacs-hg @ 2002-11-27 07:15:02 by ben]
bug fixes, profiling debugging improvements
configure.in: Check for GCC version and only use -Wpacked in v3.
.cvsignore: Add .idb, .ilk for MS Windows VC++.
cl-macs.el: Document better.
cmdloop.el: Removed.
Remove nonworking breakpoint-on-error now that debug-on-error
works as documented.
help.el: Extract out with-displaying-help-buffer into a more general
mechanism.
lib-complete.el: Support thunks in find-library-source-path.
startup.el: Don't catch errors when noninteractive, because that makes
stack traces from stack-trace-on-error useless.
.cvsignore: Windows shit.
alloc.c: Better redisplay-related assert.
elhash.c: Comment change.
eval.c: Don't generate large warning strings (e.g. backtraces) when they will
be discarded.
Implement debug-on-error as documented -- it will enter the
debugger and crash when an uncaught signal happens noninteractively
and we are --debug.
Better redisplay-related asserts.
frame-msw.c, frame.c, lisp.h, redisplay.c, scrollbar-gtk.c, scrollbar-x.c, signal.c, sysdep.c: Fix up documentation related to QUIT (which CANNOT garbage-collect
under any circumstances), and to redisplay critical sections.
lread.c: Add load-ignore-out-of-date-elc-files,
load-always-display-messages, load-show-full-path-in-messages for
more robust package compilation and debugging.
profile.c: Overhaul profile code. Change format to include call count and be
extensible for further info. Remove call-count-profile-table.
Add set-profiling-info. See related profile.el changes (which
SHOULD ABSOLUTELY be in the core! Get rid of xemacs-devel and
xemacs-base packages *yesterday*!).
author | ben |
---|---|
date | Wed, 27 Nov 2002 07:15:36 +0000 |
parents | 8b464283e891 |
children | 465bd3c7d932 |
comparison
equal
deleted
inserted
replaced
1122:7abc2b15a990 | 1123:37bdd24225ef |
---|---|
87 int load_warn_when_source_newer; | 87 int load_warn_when_source_newer; |
88 /* Whether Fload_internal() should check whether the .elc doesn't exist */ | 88 /* Whether Fload_internal() should check whether the .elc doesn't exist */ |
89 int load_warn_when_source_only; | 89 int load_warn_when_source_only; |
90 /* Whether Fload_internal() should ignore .elc files when no suffix is given */ | 90 /* Whether Fload_internal() should ignore .elc files when no suffix is given */ |
91 int load_ignore_elc_files; | 91 int load_ignore_elc_files; |
92 /* Whether Fload_internal() should ignore out-of-date .elc files when no | |
93 suffix is given */ | |
94 int load_ignore_out_of_date_elc_files; | |
95 /* Always display messages showing when a file is loaded, regardless of | |
96 whether the flag to `load' tries to suppress them. */ | |
97 int load_always_display_messages; | |
98 /* Show the full path in loading messages. */ | |
99 int load_show_full_path_in_messages; | |
92 | 100 |
93 /* Search path for files to be loaded. */ | 101 /* Search path for files to be loaded. */ |
94 Lisp_Object Vload_path; | 102 Lisp_Object Vload_path; |
95 | 103 |
96 /* Search path for files when dumping. */ | 104 /* Search path for files when dumping. */ |
197 static int saved_doc_string_length; | 205 static int saved_doc_string_length; |
198 /* This is the file position that string came from. */ | 206 /* This is the file position that string came from. */ |
199 static int saved_doc_string_position; | 207 static int saved_doc_string_position; |
200 #endif | 208 #endif |
201 | 209 |
210 static int locate_file_open_or_access_file (Ibyte *fn, int access_mode); | |
202 EXFUN (Fread_from_string, 3); | 211 EXFUN (Fread_from_string, 3); |
203 | 212 |
204 /* When errors are signaled, the actual readcharfun should not be used | 213 /* When errors are signaled, the actual readcharfun should not be used |
205 as an argument if it is an lstream, so that lstreams don't escape | 214 as an argument if it is an lstream, so that lstreams don't escape |
206 to the Lisp level. */ | 215 to the Lisp level. */ |
480 { | 489 { |
481 /* This function can GC */ | 490 /* This function can GC */ |
482 int fd = -1; | 491 int fd = -1; |
483 int speccount = specpdl_depth (); | 492 int speccount = specpdl_depth (); |
484 int source_only = 0; | 493 int source_only = 0; |
494 /* NEWER and OLDER are filenames w/o directory, used in loading messages | |
495 to e.g. warn of newer .el files when the .elc is being loaded. */ | |
485 Lisp_Object newer = Qnil; | 496 Lisp_Object newer = Qnil; |
497 Lisp_Object older = Qnil; | |
486 Lisp_Object handler = Qnil; | 498 Lisp_Object handler = Qnil; |
487 Lisp_Object found = Qnil; | 499 Lisp_Object found = Qnil; |
488 struct gcpro gcpro1, gcpro2, gcpro3; | 500 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
489 int reading_elc = 0; | 501 int reading_elc = 0; |
490 int from_require = EQ (nomessage, Qrequire); | 502 int from_require = EQ (nomessage, Qrequire); |
491 int message_p = NILP (nomessage) || from_require; | 503 int message_p = |
504 NILP (nomessage) || from_require || load_always_display_messages; | |
492 /*#ifdef DEBUG_XEMACS*/ | 505 /*#ifdef DEBUG_XEMACS*/ |
493 static Lisp_Object last_file_loaded; | 506 static Lisp_Object last_file_loaded; |
494 /*#endif*/ | 507 /*#endif*/ |
495 struct stat s1, s2; | 508 struct stat s1, s2; |
496 GCPRO3 (file, newer, found); | 509 GCPRO4 (file, newer, older, found); |
497 | 510 |
498 CHECK_STRING (file); | 511 CHECK_STRING (file); |
499 | 512 |
500 /*#ifdef DEBUG_XEMACS*/ | 513 /*#ifdef DEBUG_XEMACS*/ |
501 if (purify_flag && noninteractive) | 514 if (purify_flag && noninteractive) |
549 foundlen = qxestrlen (foundstr); | 562 foundlen = qxestrlen (foundstr); |
550 | 563 |
551 /* The omniscient JWZ thinks this is worthless, but I beg to | 564 /* The omniscient JWZ thinks this is worthless, but I beg to |
552 differ. --ben */ | 565 differ. --ben */ |
553 if (load_ignore_elc_files) | 566 if (load_ignore_elc_files) |
554 { | 567 newer = Ffile_name_nondirectory (found); |
555 newer = Ffile_name_nondirectory (found); | 568 else if ((load_warn_when_source_newer || |
556 } | 569 load_ignore_out_of_date_elc_files) && |
557 else if (load_warn_when_source_newer && | |
558 !memcmp (".elc", foundstr + foundlen - 4, 4)) | 570 !memcmp (".elc", foundstr + foundlen - 4, 4)) |
559 { | 571 { |
560 if (! qxe_fstat (fd, &s1)) /* can't fail, right? */ | 572 if (! qxe_fstat (fd, &s1)) /* can't fail, right? */ |
561 { | 573 { |
562 int result; | 574 int result; |
563 /* temporarily hack the 'c' off the end of the filename */ | 575 /* temporarily hack the 'c' off the end of the filename */ |
564 foundstr[foundlen - 1] = '\0'; | 576 foundstr[foundlen - 1] = '\0'; |
565 result = qxe_stat (foundstr, &s2); | 577 result = qxe_stat (foundstr, &s2); |
566 if (result >= 0 && | 578 if (result >= 0 && |
567 (unsigned) s1.st_mtime < (unsigned) s2.st_mtime) | 579 (unsigned) s1.st_mtime < (unsigned) s2.st_mtime) |
568 { | 580 { |
569 Lisp_Object newer_name = make_string (foundstr, | 581 /* .elc exists and is out-of-date wrt .el */ |
570 foundlen - 1); | 582 Lisp_Object el_name = make_string (foundstr, foundlen - 1); |
571 struct gcpro nngcpro1; | 583 struct gcpro nngcpro1; |
572 NNGCPRO1 (newer_name); | 584 NNGCPRO1 (el_name); |
573 newer = Ffile_name_nondirectory (newer_name); | 585 newer = Ffile_name_nondirectory (el_name); |
574 NNUNGCPRO; | 586 if (load_ignore_out_of_date_elc_files) |
575 } | 587 { |
588 int newfd = | |
589 locate_file_open_or_access_file | |
590 (XSTRING_DATA (el_name), -1); | |
591 | |
592 if (newfd >= 0) | |
593 { | |
594 older = Ffile_name_nondirectory (found); | |
595 found = el_name; | |
596 retry_close (fd); | |
597 fd = newfd; | |
598 } | |
599 } | |
600 NNUNGCPRO; | |
601 } | |
576 /* put the 'c' back on (kludge-o-rama) */ | 602 /* put the 'c' back on (kludge-o-rama) */ |
577 foundstr[foundlen - 1] = 'c'; | 603 foundstr[foundlen - 1] = 'c'; |
578 } | 604 } |
579 } | 605 } |
580 else if (load_warn_when_source_only && | 606 else if (load_warn_when_source_only && |
582 !memcmp (".el", foundstr + foundlen - 3, 3) && | 608 !memcmp (".el", foundstr + foundlen - 3, 3) && |
583 /* `file' does not end in ".el" */ | 609 /* `file' does not end in ".el" */ |
584 memcmp (".el", | 610 memcmp (".el", |
585 XSTRING_DATA (file) + XSTRING_LENGTH (file) - 3, | 611 XSTRING_DATA (file) + XSTRING_LENGTH (file) - 3, |
586 3)) | 612 3)) |
587 { | 613 source_only = 1; |
588 source_only = 1; | |
589 } | |
590 | 614 |
591 if (!memcmp (".elc", foundstr + foundlen - 4, 4)) | 615 if (!memcmp (".elc", foundstr + foundlen - 4, 4)) |
592 reading_elc = 1; | 616 reading_elc = 1; |
593 } | 617 } |
594 | 618 |
595 #define PRINT_LOADING_MESSAGE_1(loading, done) do { \ | 619 #define PRINT_LOADING_MESSAGE_1(loading, done) \ |
596 if (load_ignore_elc_files) \ | 620 do { \ |
597 { \ | 621 if (load_ignore_elc_files) \ |
598 if (message_p) \ | 622 { \ |
599 message (loading done, XSTRING_DATA (newer)); \ | 623 if (message_p) \ |
600 } \ | 624 message (loading done, \ |
601 else if (!NILP (newer)) \ | 625 XSTRING_DATA (load_show_full_path_in_messages ? \ |
602 message (loading done " (file %s is newer)", \ | 626 found : newer)); \ |
603 XSTRING_DATA (file), \ | 627 } \ |
604 XSTRING_DATA (newer)); \ | 628 else if (!NILP (older)) \ |
605 else if (source_only) \ | 629 { \ |
606 message (loading done " (file %s.elc does not exist)", \ | 630 assert (load_ignore_out_of_date_elc_files); \ |
607 XSTRING_DATA (file), \ | 631 message (loading done " (file %s is out-of-date)", \ |
608 XSTRING_DATA (Ffile_name_nondirectory (file))); \ | 632 XSTRING_DATA (load_show_full_path_in_messages ? \ |
609 else if (message_p) \ | 633 found : newer), \ |
610 message (loading done, XSTRING_DATA (file)); \ | 634 XSTRING_DATA (older)); \ |
635 } \ | |
636 else if (!NILP (newer)) \ | |
637 message (loading done " (file %s is newer)", \ | |
638 XSTRING_DATA (load_show_full_path_in_messages ? \ | |
639 found : file), \ | |
640 XSTRING_DATA (newer)); \ | |
641 else if (source_only) \ | |
642 message (loading done " (file %s.elc does not exist)", \ | |
643 XSTRING_DATA (load_show_full_path_in_messages ? \ | |
644 found : file), \ | |
645 XSTRING_DATA (Ffile_name_nondirectory (file))); \ | |
646 else if (message_p) \ | |
647 message (loading done, \ | |
648 XSTRING_DATA (load_show_full_path_in_messages ? \ | |
649 found : file)); \ | |
611 } while (0) | 650 } while (0) |
612 | 651 |
613 #define PRINT_LOADING_MESSAGE(done) \ | 652 #define PRINT_LOADING_MESSAGE(done) \ |
614 do { \ | 653 do { \ |
615 if (from_require) \ | 654 if (from_require) \ |
692 /* #### An even more disgusting kludge. There is horrible code */ | 731 /* #### An even more disgusting kludge. There is horrible code */ |
693 /* that is relying on the fact that dumped lisp files are found */ | 732 /* that is relying on the fact that dumped lisp files are found */ |
694 /* via `load-path' search. */ | 733 /* via `load-path' search. */ |
695 Lisp_Object name = file; | 734 Lisp_Object name = file; |
696 | 735 |
697 if (!NILP(Ffile_name_absolute_p(file))) | 736 if (!NILP (Ffile_name_absolute_p (file))) |
698 { | 737 name = Ffile_name_nondirectory (file); |
699 name = Ffile_name_nondirectory(file); | |
700 } | |
701 | 738 |
702 { | 739 { |
703 struct gcpro ngcpro1; | 740 struct gcpro ngcpro1; |
704 | 741 |
705 NGCPRO1 (name); | 742 NGCPRO1 (name); |
716 Feval (tem); | 753 Feval (tem); |
717 NUNGCPRO; | 754 NUNGCPRO; |
718 } | 755 } |
719 } | 756 } |
720 | 757 |
721 /*#ifdef DEBUG_XEMACS*/ | 758 /* #ifdef DEBUG_XEMACS */ |
722 if (purify_flag && noninteractive) | 759 if (purify_flag && noninteractive) |
723 { | 760 { |
724 if (!EQ (last_file_loaded, file)) | 761 if (!EQ (last_file_loaded, file)) |
725 message ("Loading %s ...done", XSTRING_DATA (file)); | 762 message ("Loading %s ...done", XSTRING_DATA (file)); |
726 } | 763 } |
727 /*#endif / * DEBUG_XEMACS */ | 764 /* #endif / * DEBUG_XEMACS */ |
728 | 765 |
729 if (!noninteractive) | 766 if (!noninteractive) |
730 PRINT_LOADING_MESSAGE ("done"); | 767 PRINT_LOADING_MESSAGE ("done"); |
731 | 768 |
732 UNGCPRO; | 769 UNGCPRO; |
946 int fd; | 983 int fd; |
947 Lisp_Object *storeptr; | 984 Lisp_Object *storeptr; |
948 int mode; | 985 int mode; |
949 }; | 986 }; |
950 | 987 |
988 /* open() or access() a file to be returned by locate_file(). if | |
989 ACCESS_MODE >= 0, do an access() with that mode, else open(). Does | |
990 various magic, e.g. opening the file read-only and binary and setting | |
991 the close-on-exec flag on the file. */ | |
992 | |
993 static int | |
994 locate_file_open_or_access_file (Ibyte *fn, int access_mode) | |
995 { | |
996 int val; | |
997 | |
998 /* Check that we can access or open it. */ | |
999 if (access_mode >= 0) | |
1000 val = qxe_access (fn, access_mode); | |
1001 else | |
1002 { | |
1003 val = qxe_open (fn, O_RDONLY | OPEN_BINARY, 0); | |
1004 | |
1005 #ifndef WIN32_NATIVE | |
1006 if (val >= 0) | |
1007 /* If we actually opened the file, set close-on-exec flag | |
1008 on the new descriptor so that subprocesses can't whack | |
1009 at it. */ | |
1010 (void) fcntl (val, F_SETFD, FD_CLOEXEC); | |
1011 #endif | |
1012 } | |
1013 | |
1014 return val; | |
1015 } | |
1016 | |
951 static int | 1017 static int |
952 locate_file_in_directory_mapper (Ibyte *fn, void *arg) | 1018 locate_file_in_directory_mapper (Ibyte *fn, void *arg) |
953 { | 1019 { |
954 struct locate_file_in_directory_mapper_closure *closure = | 1020 struct locate_file_in_directory_mapper_closure *closure = |
955 (struct locate_file_in_directory_mapper_closure *) arg; | 1021 (struct locate_file_in_directory_mapper_closure *) arg; |
958 /* Ignore file if it's a directory. */ | 1024 /* Ignore file if it's a directory. */ |
959 if (qxe_stat (fn, &st) >= 0 | 1025 if (qxe_stat (fn, &st) >= 0 |
960 && (st.st_mode & S_IFMT) != S_IFDIR) | 1026 && (st.st_mode & S_IFMT) != S_IFDIR) |
961 { | 1027 { |
962 /* Check that we can access or open it. */ | 1028 /* Check that we can access or open it. */ |
963 if (closure->mode >= 0) | 1029 closure->fd = locate_file_open_or_access_file (fn, closure->mode); |
964 closure->fd = qxe_access (fn, closure->mode); | |
965 else | |
966 closure->fd = qxe_open (fn, O_RDONLY | OPEN_BINARY, 0); | |
967 | 1030 |
968 if (closure->fd >= 0) | 1031 if (closure->fd >= 0) |
969 { | 1032 { |
970 /* We succeeded; return this descriptor and filename. */ | 1033 /* We succeeded; return this descriptor and filename. */ |
971 if (closure->storeptr) | 1034 if (closure->storeptr) |
972 *closure->storeptr = build_intstring (fn); | 1035 *closure->storeptr = build_intstring (fn); |
973 | |
974 #ifndef WIN32_NATIVE | |
975 /* If we actually opened the file, set close-on-exec flag | |
976 on the new descriptor so that subprocesses can't whack | |
977 at it. */ | |
978 if (closure->mode < 0) | |
979 (void) fcntl (closure->fd, F_SETFD, FD_CLOEXEC); | |
980 #endif | |
981 | 1036 |
982 return 1; | 1037 return 1; |
983 } | 1038 } |
984 } | 1039 } |
985 /* Keep mapping. */ | 1040 /* Keep mapping. */ |
3076 *Whether `load' should ignore `.elc' files when a suffix is not given. | 3131 *Whether `load' should ignore `.elc' files when a suffix is not given. |
3077 This is normally used only to bootstrap the `.elc' files when building XEmacs. | 3132 This is normally used only to bootstrap the `.elc' files when building XEmacs. |
3078 */ ); | 3133 */ ); |
3079 load_ignore_elc_files = 0; | 3134 load_ignore_elc_files = 0; |
3080 | 3135 |
3136 DEFVAR_BOOL ("load-ignore-out-of-date-elc-files", | |
3137 &load_ignore_out_of_date_elc_files /* | |
3138 *Whether `load' should ignore out-of-date `.elc' files when no suffix is given. | |
3139 This is normally used when compiling packages of elisp files that may have | |
3140 complex dependencies. Ignoring all elc files with `load-ignore-elc-files' | |
3141 would also be safe, but much slower. | |
3142 */ ); | |
3143 load_ignore_out_of_date_elc_files = 0; | |
3144 | |
3145 DEFVAR_BOOL ("load-always-display-messages", | |
3146 &load_always_display_messages /* | |
3147 *Whether `load' should always display loading messages. | |
3148 If this is true, every file loaded will be shown, regardless of the setting | |
3149 of the NOMESSAGE parameter, and even when files are loaded indirectly, e.g. | |
3150 due to `requre'. | |
3151 */ ); | |
3152 load_always_display_messages = 0; | |
3153 | |
3154 DEFVAR_BOOL ("load-show-full-path-in-messages", | |
3155 &load_show_full_path_in_messages /* | |
3156 *Whether `load' should show the full path in all loading messages. | |
3157 */ ); | |
3158 load_show_full_path_in_messages = 0; | |
3159 | |
3081 #ifdef LOADHIST | 3160 #ifdef LOADHIST |
3082 DEFVAR_LISP ("load-history", &Vload_history /* | 3161 DEFVAR_LISP ("load-history", &Vload_history /* |
3083 Alist mapping source file names to symbols and features. | 3162 Alist mapping source file names to symbols and features. |
3084 Each alist element is a list that starts with a file name, | 3163 Each alist element is a list that starts with a file name, |
3085 except for one element (optional) that starts with nil and describes | 3164 except for one element (optional) that starts with nil and describes |