Mercurial > hg > xemacs-beta
diff 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 |
line wrap: on
line diff
--- a/src/lread.c Tue Nov 26 22:52:59 2002 +0000 +++ b/src/lread.c Wed Nov 27 07:15:36 2002 +0000 @@ -89,6 +89,14 @@ int load_warn_when_source_only; /* Whether Fload_internal() should ignore .elc files when no suffix is given */ int load_ignore_elc_files; +/* Whether Fload_internal() should ignore out-of-date .elc files when no + suffix is given */ +int load_ignore_out_of_date_elc_files; +/* Always display messages showing when a file is loaded, regardless of + whether the flag to `load' tries to suppress them. */ +int load_always_display_messages; +/* Show the full path in loading messages. */ +int load_show_full_path_in_messages; /* Search path for files to be loaded. */ Lisp_Object Vload_path; @@ -199,6 +207,7 @@ static int saved_doc_string_position; #endif +static int locate_file_open_or_access_file (Ibyte *fn, int access_mode); EXFUN (Fread_from_string, 3); /* When errors are signaled, the actual readcharfun should not be used @@ -482,18 +491,22 @@ int fd = -1; int speccount = specpdl_depth (); int source_only = 0; + /* NEWER and OLDER are filenames w/o directory, used in loading messages + to e.g. warn of newer .el files when the .elc is being loaded. */ Lisp_Object newer = Qnil; + Lisp_Object older = Qnil; Lisp_Object handler = Qnil; Lisp_Object found = Qnil; - struct gcpro gcpro1, gcpro2, gcpro3; + struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; int reading_elc = 0; int from_require = EQ (nomessage, Qrequire); - int message_p = NILP (nomessage) || from_require; + int message_p = + NILP (nomessage) || from_require || load_always_display_messages; /*#ifdef DEBUG_XEMACS*/ static Lisp_Object last_file_loaded; /*#endif*/ struct stat s1, s2; - GCPRO3 (file, newer, found); + GCPRO4 (file, newer, older, found); CHECK_STRING (file); @@ -551,10 +564,9 @@ /* The omniscient JWZ thinks this is worthless, but I beg to differ. --ben */ if (load_ignore_elc_files) - { - newer = Ffile_name_nondirectory (found); - } - else if (load_warn_when_source_newer && + newer = Ffile_name_nondirectory (found); + else if ((load_warn_when_source_newer || + load_ignore_out_of_date_elc_files) && !memcmp (".elc", foundstr + foundlen - 4, 4)) { if (! qxe_fstat (fd, &s1)) /* can't fail, right? */ @@ -565,14 +577,28 @@ result = qxe_stat (foundstr, &s2); if (result >= 0 && (unsigned) s1.st_mtime < (unsigned) s2.st_mtime) - { - Lisp_Object newer_name = make_string (foundstr, - foundlen - 1); - struct gcpro nngcpro1; - NNGCPRO1 (newer_name); - newer = Ffile_name_nondirectory (newer_name); - NNUNGCPRO; - } + { + /* .elc exists and is out-of-date wrt .el */ + Lisp_Object el_name = make_string (foundstr, foundlen - 1); + struct gcpro nngcpro1; + NNGCPRO1 (el_name); + newer = Ffile_name_nondirectory (el_name); + if (load_ignore_out_of_date_elc_files) + { + int newfd = + locate_file_open_or_access_file + (XSTRING_DATA (el_name), -1); + + if (newfd >= 0) + { + older = Ffile_name_nondirectory (found); + found = el_name; + retry_close (fd); + fd = newfd; + } + } + NNUNGCPRO; + } /* put the 'c' back on (kludge-o-rama) */ foundstr[foundlen - 1] = 'c'; } @@ -584,30 +610,43 @@ memcmp (".el", XSTRING_DATA (file) + XSTRING_LENGTH (file) - 3, 3)) - { - source_only = 1; - } + source_only = 1; if (!memcmp (".elc", foundstr + foundlen - 4, 4)) reading_elc = 1; } -#define PRINT_LOADING_MESSAGE_1(loading, done) do { \ - if (load_ignore_elc_files) \ - { \ - if (message_p) \ - message (loading done, XSTRING_DATA (newer)); \ - } \ - else if (!NILP (newer)) \ - message (loading done " (file %s is newer)", \ - XSTRING_DATA (file), \ - XSTRING_DATA (newer)); \ - else if (source_only) \ - message (loading done " (file %s.elc does not exist)", \ - XSTRING_DATA (file), \ - XSTRING_DATA (Ffile_name_nondirectory (file))); \ - else if (message_p) \ - message (loading done, XSTRING_DATA (file)); \ +#define PRINT_LOADING_MESSAGE_1(loading, done) \ + do { \ + if (load_ignore_elc_files) \ + { \ + if (message_p) \ + message (loading done, \ + XSTRING_DATA (load_show_full_path_in_messages ? \ + found : newer)); \ + } \ + else if (!NILP (older)) \ + { \ + assert (load_ignore_out_of_date_elc_files); \ + message (loading done " (file %s is out-of-date)", \ + XSTRING_DATA (load_show_full_path_in_messages ? \ + found : newer), \ + XSTRING_DATA (older)); \ + } \ + else if (!NILP (newer)) \ + message (loading done " (file %s is newer)", \ + XSTRING_DATA (load_show_full_path_in_messages ? \ + found : file), \ + XSTRING_DATA (newer)); \ + else if (source_only) \ + message (loading done " (file %s.elc does not exist)", \ + XSTRING_DATA (load_show_full_path_in_messages ? \ + found : file), \ + XSTRING_DATA (Ffile_name_nondirectory (file))); \ + else if (message_p) \ + message (loading done, \ + XSTRING_DATA (load_show_full_path_in_messages ? \ + found : file)); \ } while (0) #define PRINT_LOADING_MESSAGE(done) \ @@ -694,10 +733,8 @@ /* via `load-path' search. */ Lisp_Object name = file; - if (!NILP(Ffile_name_absolute_p(file))) - { - name = Ffile_name_nondirectory(file); - } + if (!NILP (Ffile_name_absolute_p (file))) + name = Ffile_name_nondirectory (file); { struct gcpro ngcpro1; @@ -718,13 +755,13 @@ } } -/*#ifdef DEBUG_XEMACS*/ +/* #ifdef DEBUG_XEMACS */ if (purify_flag && noninteractive) { if (!EQ (last_file_loaded, file)) message ("Loading %s ...done", XSTRING_DATA (file)); } -/*#endif / * DEBUG_XEMACS */ +/* #endif / * DEBUG_XEMACS */ if (!noninteractive) PRINT_LOADING_MESSAGE ("done"); @@ -948,6 +985,35 @@ int mode; }; +/* open() or access() a file to be returned by locate_file(). if + ACCESS_MODE >= 0, do an access() with that mode, else open(). Does + various magic, e.g. opening the file read-only and binary and setting + the close-on-exec flag on the file. */ + +static int +locate_file_open_or_access_file (Ibyte *fn, int access_mode) +{ + int val; + + /* Check that we can access or open it. */ + if (access_mode >= 0) + val = qxe_access (fn, access_mode); + else + { + val = qxe_open (fn, O_RDONLY | OPEN_BINARY, 0); + +#ifndef WIN32_NATIVE + if (val >= 0) + /* If we actually opened the file, set close-on-exec flag + on the new descriptor so that subprocesses can't whack + at it. */ + (void) fcntl (val, F_SETFD, FD_CLOEXEC); +#endif + } + + return val; +} + static int locate_file_in_directory_mapper (Ibyte *fn, void *arg) { @@ -960,10 +1026,7 @@ && (st.st_mode & S_IFMT) != S_IFDIR) { /* Check that we can access or open it. */ - if (closure->mode >= 0) - closure->fd = qxe_access (fn, closure->mode); - else - closure->fd = qxe_open (fn, O_RDONLY | OPEN_BINARY, 0); + closure->fd = locate_file_open_or_access_file (fn, closure->mode); if (closure->fd >= 0) { @@ -971,14 +1034,6 @@ if (closure->storeptr) *closure->storeptr = build_intstring (fn); -#ifndef WIN32_NATIVE - /* If we actually opened the file, set close-on-exec flag - on the new descriptor so that subprocesses can't whack - at it. */ - if (closure->mode < 0) - (void) fcntl (closure->fd, F_SETFD, FD_CLOEXEC); -#endif - return 1; } } @@ -3078,6 +3133,30 @@ */ ); load_ignore_elc_files = 0; + DEFVAR_BOOL ("load-ignore-out-of-date-elc-files", + &load_ignore_out_of_date_elc_files /* +*Whether `load' should ignore out-of-date `.elc' files when no suffix is given. +This is normally used when compiling packages of elisp files that may have +complex dependencies. Ignoring all elc files with `load-ignore-elc-files' +would also be safe, but much slower. +*/ ); + load_ignore_out_of_date_elc_files = 0; + + DEFVAR_BOOL ("load-always-display-messages", + &load_always_display_messages /* +*Whether `load' should always display loading messages. +If this is true, every file loaded will be shown, regardless of the setting +of the NOMESSAGE parameter, and even when files are loaded indirectly, e.g. +due to `requre'. +*/ ); + load_always_display_messages = 0; + + DEFVAR_BOOL ("load-show-full-path-in-messages", + &load_show_full_path_in_messages /* +*Whether `load' should show the full path in all loading messages. +*/ ); + load_show_full_path_in_messages = 0; + #ifdef LOADHIST DEFVAR_LISP ("load-history", &Vload_history /* Alist mapping source file names to symbols and features.