X-Git-Url: http://git.chise.org/gitweb/?p=chise%2Fxemacs-chise.git.1;a=blobdiff_plain;f=src%2Femacs.c;h=417e022d893e31e436214ead5b227c3058396a6f;hp=51143540cec9f303abcee269e43f931ea97bc3d3;hb=a5812bf2ff9a9cf40f4ff78dcb83f5b4c295bd18;hpb=ccce6217f84987dff10ed3d2b60b9f0f65d8f25a diff --git a/src/emacs.c b/src/emacs.c index 5114354..417e022 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -2,6 +2,8 @@ Copyright (C) 1985, 1986, 1987, 1992, 1993, 1994 Free Software Foundation, Inc. Copyright (C) 1995 Sun Microsystems, Inc. + Copyright (C) 2000, 2002 Ben Wing. + Copyright (C) 2000,2002 MORIOKA Tomohiko. This file is part of XEmacs. @@ -22,6 +24,141 @@ Boston, MA 02111-1307, USA. */ /* Synched up with: Mule 2.0, FSF 19.28. */ +/* Capsule summary of the various releases of Lucid Emacs/XEmacs and + FSF/GNU Emacs. Provided here for use in cross-referencing version + releases and dates in comments, esp. in the authorship comments at + the beginning of each file. More information about history can be + found in the beginning of the Internals Manual and in the About page. + + +-- A time line for Lucid Emacs/XEmacs is + +version 19.0 shipped with Energize 1.0, April 1992. +version 19.1 released June 4, 1992. +version 19.2 released June 19, 1992. +version 19.3 released September 9, 1992. +version 19.4 released January 21, 1993. +version 19.5 was a repackaging of 19.4 with a few bug fixes and + shipped with Energize 2.0. Never released to the net. +version 19.6 released April 9, 1993. +version 19.7 was a repackaging of 19.6 with a few bug fixes and + shipped with Energize 2.1. Never released to the net. +version 19.8 released September 6, 1993. +version 19.9 released January 12, 1994. +version 19.10 released May 27, 1994. +version 19.11 (first XEmacs) released September 13, 1994. +version 19.12 released June 23, 1995. +version 19.13 released September 1, 1995. +version 19.14 released June 23, 1996. +version 20.0 released February 9, 1997. +version 19.15 released March 28, 1997. +version 20.1 (not released to the net) April 15, 1997. +version 20.2 released May 16, 1997. +version 19.16 released October 31, 1997. +version 20.3 (the first stable version of XEmacs 20.x) released + November 30, 1997. +version 20.4 released February 28, 1998. + + +-- A time line for GNU Emacs version 19 is + +version 19.7 (beta) (first beta release) released ??????; prob. late May 1993. +version 19.8 (beta) released May 27, 1993. +version 19.9 (beta) released May 27, 1993. +version 19.10 (beta) released May 30, 1993. +version 19.11 (beta) released June 1, 1993. +version 19.12 (beta) released June 2, 1993. +version 19.13 (beta) released June 8, 1993. +version 19.14 (beta) released June 17, 1993. +version 19.15 (beta) released June 19, 1993. +version 19.16 (beta) released July 6, 1993. +version 19.17 (beta) released late July, 1993. +version 19.18 (beta) released August 9, 1993. +version 19.19 (beta) released August 15, 1993. +version 19.20 (beta) released November 17, 1993. +version 19.21 (beta) released November 17, 1993. +version 19.22 (beta) released November 28, 1993. +version 19.23 (beta) released May 17, 1994. +version 19.24 (beta) released May 16, 1994. +version 19.25 (beta) released June 3, 1994. +version 19.26 (beta) released September 11, 1994. +version 19.27 (beta) released September 14, 1994. +version 19.28 (first ``official'' release) released November 1, 1994. +version 19.29 released June 21, 1995. +version 19.30 released November 24, 1995. +version 19.31 released May 25, 1996. +version 19.32 released July 31, 1996. +version 19.33 released August 11, 1996. +version 19.34 released August 21, 1996. +version 19.34b released September 6, 1996. + + +-- A time line for GNU Emacs version 20 is + +version 20.1 released September 17, 1997. +version 20.2 released September 20, 1997. +version 20.3 released August 19, 1998. + + +-- A time line for GNU Emacs version 18 and older is + +GNU Emacs version 15 (15.34) was released sometime in 1984 or 1985 and + shared some code with a version of Emacs written by James Gosling (the + same James Gosling who later created the Java language). +GNU Emacs version 16 (first released version was 16.56) was released on + July 15, 1985. All Gosling code was removed due to potential copyright + problems with the code. +version 16.57: released on September 16, 1985. +versions 16.58, 16.59: released on September 17, 1985. +version 16.60: released on September 19, 1985. These later version 16's + incorporated patches from the net, esp. for getting Emacs to work under + System V. +version 17.36 (first official v17 release) released on December 20, 1985. + Included a TeX-able user manual. First official unpatched version that + worked on vanilla System V machines. +version 17.43 (second official v17 release) released on January 25, 1986. +version 17.45 released on January 30, 1986. +version 17.46 released on February 4, 1986. +version 17.48 released on February 10, 1986. +version 17.49 released on February 12, 1986. +version 17.55 released on March 18, 1986. +version 17.57 released on March 27, 1986. +version 17.58 released on April 4, 1986. +version 17.61 released on April 12, 1986. +version 17.63 released on May 7, 1986. +version 17.64 released on May 12, 1986. +version 18.24 (a beta version) released on October 2, 1986. +version 18.30 (a beta version) released on November 15, 1986. +version 18.31 (a beta version) released on November 23, 1986. +version 18.32 (a beta version) released on December 7, 1986. +version 18.33 (a beta version) released on December 12, 1986. +version 18.35 (a beta version) released on January 5, 1987. +version 18.36 (a beta version) released on January 21, 1987. +January 27, 1987: The Great Usenet Renaming. net.emacs is now comp.emacs. +version 18.37 (a beta version) released on February 12, 1987. +version 18.38 (a beta version) released on March 3, 1987. +version 18.39 (a beta version) released on March 14, 1987. +version 18.40 (a beta version) released on March 18, 1987. +version 18.41 (the first ``official'' release) released on March 22, 1987. +version 18.45 released on June 2, 1987. +version 18.46 released on June 9, 1987. +version 18.47 released on June 18, 1987. +version 18.48 released on September 3, 1987. +version 18.49 released on September 18, 1987. +version 18.50 released on February 13, 1988. +version 18.51 released on May 7, 1988. +version 18.52 released on September 1, 1988. +version 18.53 released on February 24, 1989. +version 18.54 released on April 26, 1989. +version 18.55 released on August 23, 1989. This is the earliest version + that is still available by FTP. +version 18.56 released on January 17, 1991. +version 18.57 released late January, 1991. +version 18.58 released ?????. +version 18.59 released October 31, 1992. + +*/ + /* Note: It is necessary to specify and not "config.h" in order for the --srcdir type of compilation to work properly. Otherwise the config.h from the srcdir, rather than the one from @@ -35,14 +172,27 @@ Boston, MA 02111-1307, USA. */ #include "commands.h" #include "console.h" #include "process.h" +#include "redisplay.h" +#include "frame.h" #include "sysdep.h" -#include #include "syssignal.h" /* Always include before systty.h */ #include "systty.h" #include "sysfile.h" #include "systime.h" +#ifdef PDUMP +#include "dumper.h" +#endif + +#ifndef SEPCHAR +#define SEPCHAR ':' +#endif + +#ifdef QUANTIFY +#include +#endif + #ifdef HAVE_SHLIB #include "sysdll.h" #endif @@ -53,23 +203,21 @@ Boston, MA 02111-1307, USA. */ #endif #ifdef TOOLTALK -#include TT_C_H_PATH -#endif - -#ifdef APOLLO -#ifndef APOLLO_SR10 -#include -#endif +#include TT_C_H_FILE #endif -#if defined (WINDOWSNT) -#include +#if defined (WIN32_NATIVE) +#include "nt.h" #endif /* For PATH_EXEC */ #include -#if !defined SYSTEM_MALLOC && !defined DOUG_LEA_MALLOC +#if defined (HEAP_IN_DATA) && !defined(PDUMP) +void report_sheap_usage (int die_if_pure_storage_exceeded); +#endif + +#if !defined (SYSTEM_MALLOC) && !defined (DOUG_LEA_MALLOC) extern void *(*__malloc_hook)(size_t); extern void *(*__realloc_hook)(void *, size_t); extern void (*__free_hook)(void *); @@ -94,6 +242,10 @@ static void *malloc_state_ptr; void r_alloc_reinit (void); # endif +#ifdef HAVE_GTK +void console_type_create_select_gtk(void); +#endif + /* Variable whose value is symbol giving operating system type. */ Lisp_Object Vsystem_type; @@ -107,6 +259,7 @@ Lisp_Object Vsystem_configuration_options; /* Version numbers and strings */ Lisp_Object Vemacs_major_version; Lisp_Object Vemacs_minor_version; +Lisp_Object Vemacs_patch_level; Lisp_Object Vemacs_beta_version; Lisp_Object Vxemacs_codename; #ifdef INFODOCK @@ -135,15 +288,20 @@ Lisp_Object Vemacs_program_name, Vemacs_program_version; Lisp_Object Vexec_path; Lisp_Object Vexec_directory, Vconfigure_exec_directory; Lisp_Object Vlisp_directory, Vconfigure_lisp_directory; +Lisp_Object Vmule_lisp_directory, Vconfigure_mule_lisp_directory; +Lisp_Object Vutf_2000_lisp_directory, Vconfigure_utf_2000_lisp_directory; +Lisp_Object Vmodule_directory, Vconfigure_module_directory; +Lisp_Object Vsite_module_directory, Vconfigure_site_module_directory; Lisp_Object Vconfigure_package_path; Lisp_Object Vdata_directory, Vconfigure_data_directory; Lisp_Object Vdoc_directory, Vconfigure_doc_directory; Lisp_Object Vconfigure_lock_directory; Lisp_Object Vdata_directory_list; -Lisp_Object Vinfo_directory, Vconfigure_info_directory; +Lisp_Object Vconfigure_info_directory; Lisp_Object Vsite_directory, Vconfigure_site_directory; Lisp_Object Vconfigure_info_path; Lisp_Object Vinternal_error_checking; +Lisp_Object Vmail_lock_methods, Vconfigure_mail_lock_method; Lisp_Object Vpath_separator; /* The default base directory XEmacs is installed under. */ @@ -152,10 +310,12 @@ Lisp_Object Vconfigure_exec_prefix_directory, Vconfigure_prefix_directory; /* If nonzero, set XEmacs to run at this priority. This is also used in child_setup and sys_suspend to make sure subshells run at normal priority. */ -int emacs_priority; +Fixnum emacs_priority; -/* If non-zero a filter or a sentinel is running. Tested to save the match - data on the first attempt to change it inside asynchronous code. */ +/* Some FSF junk with running_asynch_code, to preserve the match + data. Not necessary because we don't call process filters + asynchronously (i.e. from within QUIT). */ +/* #### Delete this when merging the rest of my code */ int running_asynch_code; /* If non-zero, a window-system was specified on the command line. */ @@ -164,7 +324,7 @@ int display_arg; /* Type of display specified. We cannot use a Lisp symbol here because Lisp symbols may not initialized at the time that we set this variable. */ -CONST char *display_use; +const char *display_use; /* If non-zero, then the early error handler will only print the error message and exit. */ @@ -184,69 +344,287 @@ uintptr_t bss_end = 0; /* Number of bytes of writable memory we can expect to be able to get */ unsigned int lim_data; +/* WARNING! + + Some LISP-visible command-line options are set by XEmacs _before_ the + data is dumped in building a --pdump XEmacs, but used _after_ it is + restored in normal operation. Thus the dump-time values overwrite the + values XEmacs is getting at runtime. Such variables must be saved + before loading the dumpfile, and restored afterward. + + Therefore these variables may not be initialized in vars_of_emacs(). + + The save/restore is done immediately before and after pdump_load() in + main_1(). See that function for the current list of protected variables. + + Note that saving/restoring is only necessary for a few variables that are + o command line arguments effective at runtime (as opposed to dump-time), + o parsed before pdump_load, and + o exported to Lisp via a DEFVAR. +*/ + /* Nonzero means running XEmacs without interactive terminal. */ int noninteractive; /* Value of Lisp variable `noninteractive'. Normally same as C variable `noninteractive' - but nothing terrible happens if user sets this one. */ + but nothing terrible happens if user sets this one. + + Shadowed from the pdumper by `noninteractive'. */ int noninteractive1; /* Nonzero means don't perform site-lisp searches at startup */ int inhibit_site_lisp; +/* Nonzero means don't perform site-modules searches at startup */ +int inhibit_site_modules; + /* Nonzero means don't respect early packages at startup */ int inhibit_early_packages; /* Nonzero means don't load package autoloads at startup */ int inhibit_autoloads; +/* Nonzero means don't load the dump file (ignored if not PDUMP) */ + +int nodumpfile; + /* Nonzero means print debug information about path searching */ int debug_paths; /* Save argv and argc. */ -char **initial_argv; -int initial_argc; +static Extbyte **initial_argv; /* #### currently unused */ +static int initial_argc; /* #### currently unused */ static void sort_args (int argc, char **argv); -extern int always_gc; /* hack */ - Lisp_Object Qkill_emacs_hook; Lisp_Object Qsave_buffers_kill_emacs; +extern Lisp_Object Vlisp_EXEC_SUFFIXES; + -/* Signal code for the fatal signal that was received */ -static int fatal_error_code; -/* Nonzero if handling a fatal error already */ -static int fatal_error_in_progress; +/* Ben's capsule summary about expected and unexpected exits from XEmacs. + + Expected exits occur when the user directs XEmacs to exit, for example + by pressing the close button on the only frame in XEmacs, or by typing + C-x C-c. This runs `save-buffers-kill-emacs', which saves any necessary + buffers, and then exits using the primitive `kill-emacs'. + + However, unexpected exits occur in a few different ways: + + -- a memory access violation or other hardware-generated exception + occurs. This is the worst possible problem to deal with, because + the fault can occur while XEmacs is in any state whatsoever, even + quite unstable ones. As a result, we need to be *extremely* careful + what we do. + -- we are using one X display (or if we've used more, we've closed the + others already), and some hardware or other problem happens and + suddenly we've lost our connection to the display. In this situation, + things are not so dire as in the last one; our code itself isn't + trashed, so we can continue execution as normal, after having set + things up so that we can exit at the appropriate time. Our exit + still needs to be of the emergency nature; we have no displays, so + any attempts to use them will fail. We simply want to auto-save + (the single most important thing to do during shut-down), do minimal + cleanup of stuff that has an independent existence outside of XEmacs, + and exit. + + Currently, both unexpected exit scenarios described above set + preparing_for_armageddon to indicate that nonessential and possibly + dangerous things should not be done, specifically: + + -- no garbage collection. + -- no hooks are run. + -- no messages of any sort from autosaving. + -- autosaving tries harder, ignoring certain failures. + -- existing frames are not deleted. + + (Also, all places that set preparing_for_armageddon also + set dont_check_for_quit. This happens separately because it's + also necessary to set other variables to make absolutely sure + no quitting happens.) + + In the first scenario above (the access violation), we also set + fatal_error_in_progress. This causes more things to not happen: + + -- assertion failures do not abort. + -- printing code does not do code conversion or gettext when + printing to stdout/stderr. +*/ + +/* Nonzero if handling a fatal error already. */ +int fatal_error_in_progress; -static void shut_down_emacs (int sig, Lisp_Object stuff); +/* Non-nil means we're going down, so we better not run any hooks + or do other non-essential stuff. */ +int preparing_for_armageddon; + +/* Nonzero means we're in an unstable situation and need to skip + i18n conversions and such during printing. */ +int inhibit_non_essential_printing_operations; + +static JMP_BUF run_temacs_catch; + +static int run_temacs_argc; +static char **run_temacs_argv; +static char *run_temacs_args; +static EMACS_INT run_temacs_argv_size; +static EMACS_INT run_temacs_args_size; + +static void shut_down_emacs (int sig, Lisp_Object stuff, int no_auto_save); + +/* ------------------------------- */ +/* low-level debugging functions */ +/* ------------------------------- */ + +#if defined (WIN32_NATIVE) && defined (DEBUG_XEMACS) +#define debugging_breakpoint() DebugBreak () +#else +#define debugging_breakpoint() +#endif + +void +debug_break (void) +{ + debugging_breakpoint (); +} + +#if defined (WIN32_NATIVE) || defined (CYGWIN) + +/* Return whether all bytes in the specified memory block can be read. */ +int +debug_can_access_memory (void *ptr, Bytecount len) +{ + return !IsBadReadPtr (ptr, len); +} + +#else /* !(defined (WIN32_NATIVE) || defined (CYGWIN)) */ + +/* #### There must be a better way!!!! */ + +static JMP_BUF memory_error_jump; + +static SIGTYPE +debug_memory_error (int signum) +{ + EMACS_REESTABLISH_SIGNAL (signum, debug_memory_error); + EMACS_UNBLOCK_SIGNAL (signum); + LONGJMP (memory_error_jump, 1); +} + +/* Return whether all bytes in the specified memory block can be read. */ +int +debug_can_access_memory (void *ptr, Bytecount len) +{ + /* Use volatile to protect variables from being clobbered by longjmp. */ + SIGTYPE (*volatile old_sigbus) (int); + SIGTYPE (*volatile old_sigsegv) (int); + volatile int old_errno = errno; + volatile int retval = 1; + + if (!SETJMP (memory_error_jump)) + { + old_sigbus = + (SIGTYPE (*) (int)) signal (SIGBUS, debug_memory_error); + old_sigsegv = + (SIGTYPE (*) (int)) signal (SIGSEGV, debug_memory_error); + + if (len > 1) + /* If we can, try to avoid problems with super-optimizing compilers + that might decide that memcmp (ptr, ptr, len) can be optimized + away since its result is always 1. */ + memcmp (ptr, (char *) ptr + 1, len - 1); + else + memcmp (ptr, ptr, len); + } + else + retval = 0; + signal (SIGBUS, old_sigbus); + signal (SIGSEGV, old_sigsegv); + errno = old_errno; + + return retval; +} + +#endif /* defined (WIN32_NATIVE) || defined (CYGWIN) */ + +#ifdef DEBUG_XEMACS + +DEFUN ("force-debugging-signal", Fforce_debugging_signal, 0, 1, 0, /* +Cause XEmacs to enter the debugger. +On some systems, there may be no way to do this gracefully; if so, +nothing happens unless ABORT is non-nil, in which case XEmacs will +abort() -- a sure-fire way to immediately get back to the debugger, +but also a sure-fire way to kill XEmacs (and dump core on Unix +systems)! +*/ + (abort_)) +{ + debugging_breakpoint (); + if (!NILP (abort_)) + abort (); + return Qnil; +} + +#endif /* DEBUG_XEMACS */ + +static void +ensure_no_quitting_from_now_on (void) +{ + /* make sure no quitting from now on!! */ + dont_check_for_quit = 1; + Vinhibit_quit = Qt; + Vquit_flag = Qnil; +} /* Handle bus errors, illegal instruction, etc. */ SIGTYPE fatal_error_signal (int sig) { - fatal_error_code = sig; - signal (sig, SIG_DFL); + fatal_error_in_progress++; + inhibit_non_essential_printing_operations = 1; + preparing_for_armageddon = 1; + + ensure_no_quitting_from_now_on (); + /* Unblock the signal so that if the same signal gets sent in the code below, we avoid a deadlock. */ - EMACS_UNBLOCK_SIGNAL (fatal_error_code); + EMACS_UNBLOCK_SIGNAL (sig); + + /* Only try auto-saving first time through. If we crash in auto-saving, + don't do it again. */ + if (fatal_error_in_progress == 1) + { + Fdo_auto_save (Qt, Qnil); /* do this before anything hazardous */ + /* Do this so that the variable has the same value of 2 regardless of + whether we made it through auto-saving correctly. */ + fatal_error_in_progress++; + } + else if (fatal_error_in_progress == 2) + stderr_out ("WARNING: Unable to auto-save your files properly.\n" + "Some or all may in fact have been auto-saved.\n" + "\n"); + + /* Now, reset our signal handler, so the next time, we just die. + Don't do this before auto-saving. */ + signal (sig, SIG_DFL); + /* Keep in mind that there's more than one signal that we can crash + on. */ /* If fatal error occurs in code below, avoid infinite recursion. */ - if (! fatal_error_in_progress) + if (fatal_error_in_progress <= 2) { - fatal_error_in_progress = dont_check_for_quit = 1; - shut_down_emacs (sig, Qnil); + shut_down_emacs (sig, Qnil, 1); stderr_out ("\nLisp backtrace follows:\n\n"); Fbacktrace (Qexternal_debugging_output, Qt); # if 0 /* This is evil, rarely useful, and causes grief in some cases. */ /* Check for Sun-style stack printing via /proc */ { - CONST char *pstack = "/usr/proc/bin/pstack"; + const char *pstack = "/usr/proc/bin/pstack"; if (access (pstack, X_OK) == 0) { char buf[100]; @@ -259,65 +637,97 @@ fatal_error_signal (int sig) # endif } /* Signal the same code; this time it will really be fatal. */ - kill (getpid (), fatal_error_code); + kill (getpid (), sig); SIGRETURN; } - -DOESNT_RETURN -fatal (CONST char *fmt, ...) -{ - va_list args; - va_start (args, fmt); +#ifdef _MSC_VER - fprintf (stderr, "\nXEmacs: "); - vfprintf (stderr, GETTEXT (fmt), args); - fprintf (stderr, "\n"); +static DWORD +mswindows_handle_hardware_exceptions (DWORD code) +{ + if (code != STATUS_ACCESS_VIOLATION && code != STATUS_ILLEGAL_INSTRUCTION + && code != STATUS_PRIVILEGED_INSTRUCTION + && code != STATUS_DATATYPE_MISALIGNMENT) + return EXCEPTION_CONTINUE_SEARCH; + + /* I don't know if this filter is still wrapped in the outer __try, but + it doesn't hurt to have another one. --ben + And it lets us control more exactly what we really want to do in such + a situation. */ + __try + { + fatal_error_in_progress++; + inhibit_non_essential_printing_operations = 1; + preparing_for_armageddon = 1; - va_end (args); - fflush (stderr); - exit (1); -} + ensure_no_quitting_from_now_on (); -/* #### The following two functions should be replaced with - calls to emacs_doprnt_*() functions, with STREAM set to send out - to stdout or stderr. This is the only way to ensure that - I18N3 works properly (many implementations of the *printf() - functions, including the ones included in glibc, do not implement - the %###$ argument-positioning syntax). */ + /* Only try auto-saving first time through. If we crash in auto-saving, + don't do it again. */ + if (fatal_error_in_progress == 1) + { + Fdo_auto_save (Qt, Qnil); /* do this before anything hazardous */ + /* Do this so that the variable has the same value of 2 regardless of + whether we made it through auto-saving correctly. */ + fatal_error_in_progress++; + } + else if (fatal_error_in_progress == 2) + stderr_out ("WARNING: Unable to auto-save your files properly.\n" + "Some or all may in fact have been auto-saved.\n" + "\n"); -/* exactly equivalent to fprintf (stderr, fmt, ...) except that it calls - GETTEXT on the format string. */ + /* If fatal error occurs in code below, avoid infinite recursion. */ + if (fatal_error_in_progress <= 2) + { + shut_down_emacs (-1, Qnil, 1); + stderr_out ("\nLisp backtrace follows:\n\n"); + Fbacktrace (Qexternal_debugging_output, Qt); + } + } + /* VC++ documentation says that + GetExceptionCode() cannot be called inside the filter itself. */ + + /* __except (mswindows_handle_hardware_exceptions (GetExceptionCode ())) {} + + The line above is original. Unfortunately, when an error is tripped + inside of the handler (e.g. during Fbacktrace()), and the handler for + the handler is invoked, it correctly notices that something is amiss + and it should just return -- but it returns EXCEPTION_CONTINUE_SEARCH, + which causes the debugger to be invoked debugging the handler code in + this function -- and WITH THE STACK UNWOUND so that you see main() + calling mswindows_handle_hardware_exceptions(), calling Fbacktrace(), + and a crash a couple of frames in -- AND NO SIGN OF THE ORIGINAL CRASH! + + There's some real weirdness going on in the stack handling -- unlike + in Unix, where further crashes just keep adding to the stack, it seems + that under the structured-exception-handling, the stack can actually + bounce back and forth between the full stack at the location of the + exception and the unwound stack at the place where the __try clause was + established. I don't completely understand it. What I do know is that + returning EXCEPTION_EXECUTE_HANDLER on nested crash has the effect of + aborting execution of the handler and going back to the outer filter + function, which returns EXCEPTION_CONTINUE_SEARCH and everything is + hunky-dorey -- your debugger sees a crash at the right location with + the right stack. + + I'm leaving in the trickier Unix-like code in the handler; someone who + understands better than me how the stack works in these handlers could + fix it up more. As it is, it works pretty well, so I'm not likely to + touch it more. --ben + */ -int -stderr_out (CONST char *fmt, ...) -{ - int retval; - va_list args; - va_start (args, fmt); + __except (EXCEPTION_EXECUTE_HANDLER) {} - retval = vfprintf (stderr, GETTEXT (fmt), args); - va_end (args); - /* fflush (stderr); */ - return retval; + /* pretend we didn't handle this, so that the debugger is invoked and/or + the normal GPF box appears. */ + return EXCEPTION_CONTINUE_SEARCH; } -/* exactly equivalent to fprintf (stdout, fmt, ...) except that it calls - GETTEXT on the format string. */ +#endif /* _MSC_VER */ -int -stdout_out (CONST char *fmt, ...) -{ - int retval; - va_list args; - va_start (args, fmt); - - retval = vfprintf (stdout, GETTEXT (fmt), args); - - va_end (args); - return retval; -} + #ifdef SIGDANGER @@ -340,7 +750,7 @@ memory_warning_signal (int sig) /* Code for dealing with Lisp access to the Unix command line */ static Lisp_Object -make_arg_list_1 (int argc, char **argv, int skip_args) +make_arg_list_1 (int argc, Extbyte **argv, int skip_args) { Lisp_Object result = Qnil; REGISTER int i; @@ -349,28 +759,38 @@ make_arg_list_1 (int argc, char **argv, int skip_args) { if (i == 0 || i > skip_args) { -#ifdef WINDOWSNT +#ifdef WIN32_NATIVE if (i == 0) { /* Do not trust to what crt0 has stuffed into argv[0] */ - char full_exe_path [MAX_PATH]; + char full_exe_path[MAX_PATH]; + Lisp_Object fullpath; + GetModuleFileName (NULL, full_exe_path, MAX_PATH); - result = Fcons (build_ext_string (full_exe_path, FORMAT_FILENAME), - result); + fullpath = build_ext_string (full_exe_path, Qmswindows_tstr); + result = Fcons (fullpath, result); #if defined(HAVE_SHLIB) - (void)dll_init(full_exe_path); + { + Extbyte *fullpathext; + + LISP_STRING_TO_EXTERNAL (fullpath, fullpathext, + Qdll_filename_encoding); + (void) dll_init (fullpathext); + } #endif } else #endif - result = Fcons (build_ext_string (argv [i], FORMAT_FILENAME), result); + result = Fcons (build_ext_string (argv[i], + Qcommand_argument_encoding), + result); } } return result; } Lisp_Object -make_arg_list (int argc, char **argv) +make_arg_list (int argc, Extbyte **argv) { return make_arg_list_1 (argc, argv, 0); } @@ -378,19 +798,19 @@ make_arg_list (int argc, char **argv) /* Calling functions are also responsible for calling free_argc_argv when they are done with the generated list. */ void -make_argc_argv (Lisp_Object argv_list, int *argc, char ***argv) +make_argc_argv (Lisp_Object argv_list, int *argc, Extbyte ***argv) { Lisp_Object next; int n = XINT (Flength (argv_list)); REGISTER int i; - *argv = (char**) xmalloc ((n+1) * sizeof (char*)); + *argv = (Extbyte**) xmalloc ((n+1) * sizeof (Extbyte*)); for (i = 0, next = argv_list; i < n; i++, next = XCDR (next)) { - CONST char *temp; + const Extbyte *temp; CHECK_STRING (XCAR (next)); - GET_C_STRING_EXT_DATA_ALLOCA (XCAR (next), FORMAT_OS, temp); + LISP_STRING_TO_EXTERNAL (XCAR (next), temp, Qcommand_argument_encoding); (*argv) [i] = xstrdup (temp); } (*argv) [n] = 0; @@ -398,7 +818,7 @@ make_argc_argv (Lisp_Object argv_list, int *argc, char ***argv) } void -free_argc_argv (char **argv) +free_argc_argv (Extbyte **argv) { int elt = 0; @@ -411,7 +831,7 @@ free_argc_argv (char **argv) } static void -init_cmdargs (int argc, char **argv, int skip_args) +init_cmdargs (int argc, Extbyte **argv, int skip_args) { initial_argv = argv; initial_argc = argc; @@ -444,15 +864,6 @@ Return the directory name in which the Emacs executable was located. # undef RUN_TIME_REMAP #endif -#if defined (MULE) && defined (MSDOS) && defined (EMX) -/* Setup all of files be input/output'ed with binary translation mdoe. */ -asm (" .text"); -asm ("L_setbinmode:"); -asm (" movl $1, __fmode_bin"); -asm (" ret"); -asm (" .stabs \"___CTOR_LIST__\", 23, 0, 0, L_setbinmode"); -#endif - /* Test whether the next argument in ARGV matches SSTR or a prefix of LSTR (at least MINLEN characters). If so, then if VALPTR is non-null (the argument is supposed to have a value) store in *VALPTR either @@ -490,7 +901,7 @@ argmatch (char **argv, int argc, char *sstr, char *lstr, return 1; } arglen = (valptr != NULL && (p = strchr (arg, '=')) != NULL - ? p - arg : strlen (arg)); + ? p - arg : (int) strlen (arg)); if (lstr == 0 || arglen < minlen || strncmp (arg, lstr, arglen) != 0) return 0; else if (valptr == NULL) @@ -519,7 +930,25 @@ argmatch (char **argv, int argc, char *sstr, char *lstr, /* Make stack traces always identify version + configuration */ #define main_1 STACK_TRACE_EYE_CATCHER -static DOESNT_RETURN +/* This function is not static, so that the compiler is less likely to + inline it, which would make it not show up in stack traces. + + The restart argument is a flag that indicates that main_1 is now + being called for the second time in this invocation of xemacs; this can + only happen in an xemacs that is not loaded with dumped data (temacs + with the conventional dumper or xemacs -nd with the pdumper). See + Frun_emacs_from_temacs(). + + restart interacts with initialized as follows (per Olivier Galibert): + + It's perverted. + + initialized==0 => temacs + initialized!=0 && restart!=0 => run-temacs + initialized!=0 && restart==0 => xemacs/post pdump_load() +*/ +DECLARE_DOESNT_RETURN (main_1 (int, char **, char **, int)); +DOESNT_RETURN main_1 (int argc, char **argv, char **envp, int restart) { char stack_bottom_variable; @@ -530,7 +959,8 @@ main_1 (int argc, char **argv, char **envp, int restart) extern int malloc_cookie; #endif -#if !defined(SYSTEM_MALLOC) && !defined(HAVE_LIBMCHECK) +#if (!defined (SYSTEM_MALLOC) && !defined (HAVE_LIBMCHECK) \ + && !defined (DOUG_LEA_MALLOC)) /* Make sure that any libraries we link against haven't installed a hook for a gmalloc of a potentially incompatible version. */ /* If we're using libmcheck, the hooks have already been initialized, */ @@ -538,9 +968,10 @@ main_1 (int argc, char **argv, char **envp, int restart) __malloc_hook = NULL; __realloc_hook = NULL; __free_hook = NULL; -#endif /* not SYSTEM_MALLOC */ +#endif /* not SYSTEM_MALLOC or HAVE_LIBMCHECK or DOUG_LEA_MALLOC */ noninteractive = 0; + inhibit_non_essential_printing_operations = 1; #ifdef NeXT /* 19-Jun-1995 -baw @@ -552,7 +983,7 @@ main_1 (int argc, char **argv, char **envp, int restart) * But hey, it solves all NS related memory problems, so who's * complaining? */ if (initialized && malloc_jumpstart (malloc_cookie) != 0) - fprintf (stderr, "malloc jumpstart failed!\n"); + stderr_out ("malloc jumpstart failed!\n"); #endif /* NeXT */ /* @@ -570,23 +1001,7 @@ main_1 (int argc, char **argv, char **envp, int restart) sort_args (argc, argv); - /* Map in shared memory, if we are using that. */ -#ifdef HAVE_SHM - if (argmatch (argv, argc, "-nl", "--no-shared-memory", 6, NULL, &skip_args)) - { - map_in_data (0); - /* The shared memory was just restored, which clobbered this. */ - skip_args = 1; - } - else - { - map_in_data (1); - /* The shared memory was just restored, which clobbered this. */ - skip_args = 0; - } -#endif /* HAVE_SHM */ - -#if (defined (MSDOS) && defined (EMX)) || defined (WIN32) || defined (_SCO_DS) +#if defined (WIN32_NATIVE) || defined (_SCO_DS) environ = envp; #endif @@ -600,18 +1015,12 @@ main_1 (int argc, char **argv, char **envp, int restart) clearerr (stdin); -#ifdef APOLLO -#ifndef APOLLO_SR10 - /* If USE_DOMAIN_ACLS environment variable exists, - use ACLs rather than UNIX modes. */ - if (egetenv ("USE_DOMAIN_ACLS")) - default_acl (USE_DEFACL); -#endif -#endif /* APOLLO */ - #if defined (HAVE_MMAP) && defined (REL_ALLOC) /* ralloc can only be used if using the GNU memory allocator. */ init_ralloc (); +#elif defined (REL_ALLOC) && !defined(DOUG_LEA_MALLOC) + if (initialized) + init_ralloc(); #endif #ifdef HAVE_SOCKS @@ -625,15 +1034,6 @@ main_1 (int argc, char **argv, char **envp, int restart) memory_warnings (0, malloc_warning); #endif /* not SYSTEM_MALLOC */ -#ifdef MSDOS - /* We do all file input/output as binary files. When we need to translate - newlines, we do that manually. */ - _fmode = O_BINARY; - (stdin) ->_flag &= ~_IOTEXT; - (stdout)->_flag &= ~_IOTEXT; - (stderr)->_flag &= ~_IOTEXT; -#endif /* MSDOS */ - #ifdef SET_EMACS_PRIORITY if (emacs_priority != 0) nice (-emacs_priority); @@ -650,6 +1050,17 @@ main_1 (int argc, char **argv, char **envp, int restart) inhibit_window_system = 1; #endif + /* Handle the -sd/--show-dump-id switch, which means show the hex dump_id and quit */ + if (argmatch (argv, argc, "-sd", "--show-dump-id", 9, NULL, &skip_args)) + { +#ifdef PDUMP + printf ("%08x\n", dump_id); +#else + printf ("Portable dumper not configured; -sd just forces exit.\n"); +#endif + exit (0); + } + /* Handle the -t switch, which specifies filename to use as terminal */ { char *term; @@ -671,6 +1082,12 @@ main_1 (int argc, char **argv, char **envp, int restart) } } + /* Handle the --no-dump-file/-nd switch, which means don't load the dump file (ignored when not using pdump) */ + if (argmatch (argv, argc, "-nd", "--no-dump-file", 7, NULL, &skip_args)) + { + nodumpfile = 1; + } + /* Handle -nw switch */ if (argmatch (argv, argc, "-nw", "--no-windows", 6, NULL, &skip_args)) inhibit_window_system = 1; @@ -697,6 +1114,16 @@ main_1 (int argc, char **argv, char **envp, int restart) inhibit_early_packages = 1; skip_args--; } +#ifdef HAVE_SHLIB + if (argmatch (argv, argc, "-no-site-modules", "--no-site-modules", + 9, NULL, &skip_args)) + { + inhibit_site_modules = 1; + skip_args--; + } +#else + inhibit_site_modules = 1; +#endif if (argmatch (argv, argc, "-vanilla", "--vanilla", 7, NULL, &skip_args)) { @@ -792,6 +1219,13 @@ main_1 (int argc, char **argv, char **envp, int restart) display_use = "x"; #endif /* HAVE_X_WINDOWS */ +#ifdef HAVE_GTK + { + char *dpy = getenv ("DISPLAY"); + if (dpy && dpy[0]) + display_use = "gtk"; + } +#endif #ifdef HAVE_MS_WINDOWS if (strcmp(display_use, "x") != 0) display_use = "mswindows"; @@ -817,6 +1251,11 @@ main_1 (int argc, char **argv, char **envp, int restart) so we can be fairly accurate. */ init_intl_very_early (); /* set up the locale and domain for gettext and such. */ +#ifdef HAVE_MS_WINDOWS + init_mswindows_very_early (); /* Some things - like dde need to be + initialized early so that the + client doesn't give up waiting. */ +#endif /* Now initialize the Lisp engine and the like. Done only during dumping. No dependence on anything that may be in the user's @@ -825,6 +1264,58 @@ main_1 (int argc, char **argv, char **envp, int restart) We try to do things in an order that minimizes the non-obvious dependencies between functions. */ + /* purify_flag 1 is correct even if CANNOT_DUMP. + * loadup.el will set to nil at end. */ + + purify_flag = 0; +#ifdef PDUMP + if (restart) + initialized = 1; + else if (nodumpfile) { + initialized = 0; + purify_flag = 1; + } else { + + /* Keep command options from getting stomped. + + Some LISP-visible options are changed by XEmacs _after_ the data is + dumped in building a --pdump XEmacs, but _before_ it is restored in + normal operation. Thus the restored values overwrite the values + XEmacs is getting at run-time. Such variables must be saved here, + and restored after loading the dumped data. + + Boy, this is ugly, but how else to do it? + */ + + /* noninteractive1 is saved in noninteractive, which isn't LISP-visible */ + int inhibit_early_packages_save = inhibit_early_packages; + int inhibit_autoloads_save = inhibit_autoloads; + int debug_paths_save = debug_paths; + /* #### Give inhibit-site-lisp a command switch? If so, uncomment: */ + /* int inhibit_site_lisp_save = inhibit_site_lisp; */ + int inhibit_site_modules_save = inhibit_site_modules; + + initialized = pdump_load (argv[0]); + + /* Now unstomp everything */ + noninteractive1 = noninteractive; + inhibit_early_packages = inhibit_early_packages_save; + inhibit_autoloads = inhibit_autoloads_save; + debug_paths = debug_paths_save; + /* #### Give inhibit-site-lisp a command switch? If so, uncomment: */ + /* inhibit_site_lisp = inhibit_site_lisp_save; */ + inhibit_site_modules = inhibit_site_modules_save; + + if (initialized) + run_temacs_argc = -1; + else + purify_flag = 1; + } +#else + if (!initialized) + purify_flag = 1; +#endif + if (!initialized) { /* Initialize things so that new Lisp objects @@ -836,11 +1327,11 @@ main_1 (int argc, char **argv, char **envp, int restart) /* Initialize Qnil, Qt, Qunbound, and the obarray. After this, symbols can be - interned. This depends on init_alloc_once(). */ + interned. This depends on init_alloc_once_early(). */ init_symbols_once_early (); /* Declare the basic symbols pertaining to errors, - So that deferror() can be called. */ + So that DEFERROR*() can be called. */ init_errors_once_early (); /* Make sure that opaque pointers can be created. */ @@ -849,21 +1340,19 @@ main_1 (int argc, char **argv, char **envp, int restart) /* Now declare all the symbols and define all the Lisp primitives. The *only* thing that the syms_of_*() functions are allowed to do - is call one of the following three functions: + is call one of the following: - defsymbol() + INIT_LRECORD_IMPLEMENTATION() + defsymbol(), DEFSYMBOL(), or DEFSYMBOL_MULTIWORD_PREDICATE() defsubr() (i.e. DEFSUBR) - deferror() - defkeyword() + deferror(), DEFERROR(), or DEFERROR_STANDARD() + defkeyword() or DEFKEYWORD() Order does not matter in these functions. */ syms_of_abbrev (); syms_of_alloc (); -#ifdef HAVE_X_WINDOWS - syms_of_balloon_x (); -#endif syms_of_buffer (); syms_of_bytecode (); syms_of_callint (); @@ -877,20 +1366,24 @@ main_1 (int argc, char **argv, char **envp, int restart) syms_of_data (); #ifdef DEBUG_XEMACS syms_of_debug (); + syms_of_tests (); #endif /* DEBUG_XEMACS */ syms_of_device (); #ifdef HAVE_DIALOGS syms_of_dialog (); #endif syms_of_dired (); -#ifdef HAVE_SHLIB - syms_of_dll (); -#endif syms_of_doc (); syms_of_editfns (); syms_of_elhash (); syms_of_emacs (); syms_of_eval (); +#ifdef HAVE_X_WINDOWS + syms_of_event_Xt (); +#endif +#ifdef HAVE_GTK + syms_of_event_gtk (); +#endif #ifdef HAVE_DRAGNDROP syms_of_dragdrop (); #endif @@ -909,9 +1402,9 @@ main_1 (int argc, char **argv, char **envp, int restart) syms_of_general (); syms_of_glyphs (); syms_of_glyphs_eimage (); -#if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS) + syms_of_glyphs_widget (); syms_of_gui (); -#endif + syms_of_gutter (); syms_of_indent (); syms_of_intl (); syms_of_keymap (); @@ -926,6 +1419,9 @@ main_1 (int argc, char **argv, char **envp, int restart) syms_of_menubar (); #endif syms_of_minibuf (); +#ifdef HAVE_SHLIB + syms_of_module (); +#endif syms_of_objects (); syms_of_print (); #if !defined (NO_SUBPROCESSES) @@ -941,6 +1437,7 @@ main_1 (int argc, char **argv, char **envp, int restart) syms_of_rangetab (); syms_of_redisplay (); syms_of_search (); + syms_of_select (); syms_of_signal (); syms_of_sound (); syms_of_specifier (); @@ -961,42 +1458,77 @@ main_1 (int argc, char **argv, char **envp, int restart) syms_of_device_tty (); syms_of_objects_tty (); #endif + +#ifdef HAVE_GTK + syms_of_device_gtk (); + syms_of_frame_gtk (); + syms_of_glyphs_gtk (); + syms_of_objects_gtk (); + syms_of_ui_gtk (); + syms_of_select_gtk (); +#ifdef HAVE_DIALOGS + syms_of_dialog_gtk (); +#endif +#ifdef HAVE_MENUBARS + syms_of_menubar_gtk (); +#endif + syms_of_select_gtk (); + +#if defined (HAVE_MENUBARS) || defined(HAVE_SCROLLBARS) || defined(HAVE_DIALOGS) || defined(HAVE_TOOLBARS) + syms_of_gui_gtk (); +#endif +#endif /* HAVE_GTK */ + #ifdef HAVE_X_WINDOWS +#ifdef HAVE_BALLOON_HELP + syms_of_balloon_x (); +#endif syms_of_device_x (); #ifdef HAVE_DIALOGS syms_of_dialog_x (); #endif - syms_of_event_Xt (); syms_of_frame_x (); syms_of_glyphs_x (); syms_of_objects_x (); #ifdef HAVE_MENUBARS syms_of_menubar_x (); #endif - syms_of_xselect (); + syms_of_select_x (); #if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS) syms_of_gui_x (); #endif +#ifdef HAVE_XIM +#ifdef XIM_XLIB + syms_of_input_method_xlib (); +#endif +#endif /* HAVE_XIM */ #endif /* HAVE_X_WINDOWS */ #ifdef HAVE_MS_WINDOWS syms_of_console_mswindows (); syms_of_device_mswindows (); - syms_of_event_mswindows (); + syms_of_dialog_mswindows (); syms_of_frame_mswindows (); syms_of_objects_mswindows (); syms_of_select_mswindows (); syms_of_glyphs_mswindows (); + syms_of_gui_mswindows (); #ifdef HAVE_MENUBARS syms_of_menubar_mswindows (); #endif #ifdef HAVE_SCROLLBARS syms_of_scrollbar_mswindows (); #endif +#endif /* HAVE_MS_WINDOWS */ #ifdef HAVE_MSW_C_DIRED syms_of_dired_mswindows (); #endif -#endif /* HAVE_MS_WINDOWS */ +#ifdef WIN32_NATIVE + syms_of_ntproc (); +#endif +#if defined (WIN32_NATIVE) || defined (CYGWIN) + syms_of_win32 (); +#endif #ifdef MULE syms_of_mule (); @@ -1004,7 +1536,7 @@ main_1 (int argc, char **argv, char **envp, int restart) syms_of_mule_charset (); #endif #ifdef FILE_CODING - syms_of_mule_coding (); + syms_of_file_coding (); #endif #ifdef MULE #ifdef HAVE_WNN @@ -1023,10 +1555,6 @@ main_1 (int argc, char **argv, char **envp, int restart) SYMS_MACHINE; #endif -#ifdef EMACS_BTL - syms_of_btl (); -#endif - /* #if defined (GNU_MALLOC) && \ defined (ERROR_CHECK_MALLOC) && \ @@ -1049,6 +1577,14 @@ main_1 (int argc, char **argv, char **envp, int restart) syms_of_eldap (); #endif +#ifdef HAVE_GPM + syms_of_gpmevent (); +#endif + +#ifdef HAVE_POSTGRESQL + syms_of_postgresql (); +#endif + /* Now create the subtypes for the types that have them. We do this before the vars_*() because more symbols may get initialized here. */ @@ -1075,11 +1611,34 @@ main_1 (int argc, char **argv, char **envp, int restart) console_type_create_redisplay_tty (); #endif +#ifdef HAVE_GTK + console_type_create_gtk (); + console_type_create_select_gtk (); + console_type_create_device_gtk (); + console_type_create_frame_gtk (); + console_type_create_objects_gtk (); + console_type_create_glyphs_gtk (); + console_type_create_redisplay_gtk (); +#ifdef HAVE_MENUBARS + console_type_create_menubar_gtk (); +#endif +#ifdef HAVE_SCROLLBARS + console_type_create_scrollbar_gtk (); +#endif +#ifdef HAVE_TOOLBARS + console_type_create_toolbar_gtk (); +#endif +#ifdef HAVE_DIALOGS + console_type_create_dialog_gtk (); +#endif +#endif /* HAVE_GTK */ + #ifdef HAVE_X_WINDOWS console_type_create_x (); console_type_create_device_x (); console_type_create_frame_x (); console_type_create_glyphs_x (); + console_type_create_select_x (); #ifdef HAVE_MENUBARS console_type_create_menubar_x (); #endif @@ -1103,6 +1662,7 @@ main_1 (int argc, char **argv, char **envp, int restart) console_type_create_objects_mswindows (); console_type_create_redisplay_mswindows (); console_type_create_glyphs_mswindows (); + console_type_create_select_mswindows (); # ifdef HAVE_SCROLLBARS console_type_create_scrollbar_mswindows (); # endif @@ -1130,6 +1690,7 @@ main_1 (int argc, char **argv, char **envp, int restart) specifier_type_create (); specifier_type_create_image (); + specifier_type_create_gutter (); specifier_type_create_objects (); #ifdef HAVE_TOOLBARS specifier_type_create_toolbar (); @@ -1149,7 +1710,7 @@ main_1 (int argc, char **argv, char **envp, int restart) structure_type_create_chartab (); structure_type_create_faces (); structure_type_create_rangetab (); - structure_type_create_hashtable (); + structure_type_create_hash_table (); /* Now initialize the image instantiator formats and associated symbols. Other than the first function below, the functions may @@ -1164,12 +1725,19 @@ main_1 (int argc, char **argv, char **envp, int restart) image_instantiator_format_create (); image_instantiator_format_create_glyphs_eimage (); + image_instantiator_format_create_glyphs_widget (); +#ifdef HAVE_TTY + image_instantiator_format_create_glyphs_tty (); +#endif #ifdef HAVE_X_WINDOWS image_instantiator_format_create_glyphs_x (); #endif /* HAVE_X_WINDOWS */ #ifdef HAVE_MS_WINDOWS image_instantiator_format_create_glyphs_mswindows (); #endif /* HAVE_MSWINDOWS_WINDOWS */ +#ifdef HAVE_GTK + image_instantiator_format_create_glyphs_gtk (); +#endif /* Now initialize the lstream types and associated symbols. Other than the first function below, the functions may @@ -1181,12 +1749,12 @@ main_1 (int argc, char **argv, char **envp, int restart) lstream_type_create (); #ifdef FILE_CODING - lstream_type_create_mule_coding (); + lstream_type_create_file_coding (); #endif #if defined (HAVE_MS_WINDOWS) && !defined(HAVE_MSG_SELECT) lstream_type_create_mswindows_selectable (); #endif - + /* Initialize processes implementation. The functions may make exactly the following function/macro calls: @@ -1212,7 +1780,7 @@ main_1 (int argc, char **argv, char **envp, int restart) staticpro() Fprovide(symbol) intern() - pure_put() + Fput() xmalloc() defsymbol(), if it's absolutely necessary and you're sure that the symbol isn't referenced anywhere else in the initialization @@ -1222,10 +1790,9 @@ main_1 (int argc, char **argv, char **envp, int restart) using a global variable that has been initialized earlier on in the same function - Any of the object-creating functions on alloc.c: e.g. + Any of the object-creating functions in alloc.c: e.g. make_pure_*() - Fpurecopy() make_string() build_string() make_vector() @@ -1235,29 +1802,35 @@ main_1 (int argc, char **argv, char **envp, int restart) Fcons() listN() make_opaque_ptr() - make_opaque_long() perhaps a few others. + + NB: Initialization or assignment should not be done here to certain + variables settable from the command line. See the comment above + the call to pdump_load() in main_1(). This caveat should only + apply to vars_of_emacs(). */ /* Now allow Fprovide() statements to be made. */ init_provide_once (); + /* Do that before any specifier creation (esp. vars_of_glyphs()) */ + vars_of_specifier (); + vars_of_abbrev (); vars_of_alloc (); -#ifdef HAVE_X_WINDOWS - vars_of_balloon_x (); -#endif vars_of_buffer (); vars_of_bytecode (); vars_of_callint (); vars_of_callproc (); + vars_of_chartab (); vars_of_cmdloop (); vars_of_cmds (); vars_of_console (); vars_of_data (); #ifdef DEBUG_XEMACS vars_of_debug (); + vars_of_tests (); #endif vars_of_console_stream (); vars_of_device (); @@ -1273,7 +1846,18 @@ main_1 (int argc, char **argv, char **envp, int restart) vars_of_elhash (); vars_of_emacs (); vars_of_eval (); + +#ifdef HAVE_X_WINDOWS + vars_of_event_Xt (); +#endif +#if defined(HAVE_TTY) && (defined (DEBUG_TTY_EVENT_STREAM) || !defined (HAVE_X_WINDOWS)) + vars_of_event_tty (); +#endif +#ifdef HAVE_MS_WINDOWS + vars_of_event_mswindows (); +#endif vars_of_event_stream (); + vars_of_events (); vars_of_extents (); vars_of_faces (); @@ -1286,9 +1870,9 @@ main_1 (int argc, char **argv, char **envp, int restart) vars_of_frame (); vars_of_glyphs (); vars_of_glyphs_eimage (); -#if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS) + vars_of_glyphs_widget (); vars_of_gui (); -#endif + vars_of_gutter (); vars_of_indent (); vars_of_insdel (); vars_of_intl (); @@ -1311,6 +1895,13 @@ main_1 (int argc, char **argv, char **envp, int restart) vars_of_menubar (); #endif vars_of_minibuf (); +#ifdef HAVE_SHLIB + vars_of_module (); +#endif +#ifdef WIN32_NATIVE + vars_of_nt (); + vars_of_ntproc (); +#endif vars_of_objects (); vars_of_print (); @@ -1333,8 +1924,8 @@ main_1 (int argc, char **argv, char **envp, int restart) vars_of_scrollbar (); #endif vars_of_search (); + vars_of_select (); vars_of_sound (); - vars_of_specifier (); vars_of_symbols (); vars_of_syntax (); #ifdef HAVE_TOOLBARS @@ -1345,36 +1936,59 @@ main_1 (int argc, char **argv, char **envp, int restart) #ifdef HAVE_TTY vars_of_console_tty (); - vars_of_event_tty (); vars_of_frame_tty (); vars_of_objects_tty (); #endif +#ifdef HAVE_GTK + vars_of_device_gtk (); +#ifdef HAVE_DIALOGS + vars_of_dialog_gtk (); +#endif + vars_of_event_gtk (); + vars_of_frame_gtk (); + vars_of_glyphs_gtk (); + vars_of_ui_gtk (); +#ifdef HAVE_MENUBARS + vars_of_menubar_gtk (); +#endif + vars_of_objects_gtk (); + vars_of_select_gtk (); +#ifdef HAVE_SCROLLBARS + vars_of_scrollbar_gtk (); +#endif +#if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS) + vars_of_gui_gtk (); +#endif +#endif /* HAVE_GTK */ + #ifdef HAVE_X_WINDOWS +#ifdef HAVE_BALLOON_HELP + vars_of_balloon_x (); +#endif vars_of_device_x (); #ifdef HAVE_DIALOGS vars_of_dialog_x (); #endif - vars_of_event_Xt (); vars_of_frame_x (); vars_of_glyphs_x (); #ifdef HAVE_MENUBARS vars_of_menubar_x (); #endif vars_of_objects_x (); - vars_of_xselect (); + vars_of_select_x (); #ifdef HAVE_SCROLLBARS vars_of_scrollbar_x (); #endif #if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS) vars_of_gui_x (); #endif -#endif +#endif /* HAVE_X_WINDOWS */ + #ifdef HAVE_MS_WINDOWS vars_of_device_mswindows (); vars_of_console_mswindows (); - vars_of_event_mswindows (); vars_of_frame_mswindows (); vars_of_objects_mswindows (); vars_of_select_mswindows (); @@ -1395,10 +2009,11 @@ main_1 (int argc, char **argv, char **envp, int restart) #ifdef MULE vars_of_mule (); + vars_of_mule_ccl (); vars_of_mule_charset (); #endif #ifdef FILE_CODING - vars_of_mule_coding (); + vars_of_file_coding (); #endif #ifdef MULE #ifdef HAVE_WNN @@ -1421,6 +2036,14 @@ main_1 (int argc, char **argv, char **envp, int restart) vars_of_eldap (); #endif +#ifdef HAVE_POSTGRESQL + vars_of_postgresql(); +#endif + +#ifdef HAVE_GPM + vars_of_gpmevent (); +#endif + /* Now initialize any specifier variables. We do this later because it has some dependence on the vars initialized above. @@ -1436,6 +2059,8 @@ main_1 (int argc, char **argv, char **envp, int restart) */ specifier_vars_of_glyphs (); + specifier_vars_of_glyphs_widget (); + specifier_vars_of_gutter (); #ifdef HAVE_MENUBARS specifier_vars_of_menubar (); #endif @@ -1458,19 +2083,19 @@ main_1 (int argc, char **argv, char **envp, int restart) /* Calls Fmake_range_table(). */ complex_vars_of_search (); - /* Calls make_lisp_hashtable(). */ + /* Calls make_lisp_hash_table(). */ complex_vars_of_extents (); - /* Depends on hashtables and specifiers. */ + /* Depends on hash tables and specifiers. */ complex_vars_of_faces (); #ifdef MULE - /* These two depend on hashtables and various variables declared + /* These two depend on hash tables and various variables declared earlier. The second may also depend on the first. */ complex_vars_of_mule_charset (); #endif -#if defined(FILE_CODING) - complex_vars_of_mule_coding (); +#ifdef FILE_CODING + complex_vars_of_file_coding (); #endif /* This calls allocate_glyph(), which creates specifiers @@ -1482,6 +2107,9 @@ main_1 (int argc, char **argv, char **envp, int restart) /* These rely on the glyphs just created in the previous function, and call Fadd_spec_to_specifier(), which relies on various variables initialized above. */ +#ifdef HAVE_GTK + complex_vars_of_glyphs_gtk (); +#endif #ifdef HAVE_X_WINDOWS complex_vars_of_glyphs_x (); #endif @@ -1535,34 +2163,161 @@ main_1 (int argc, char **argv, char **envp, int restart) might depend on all sorts of things; I'm not sure. */ complex_vars_of_emacs (); -#ifdef CLASH_DETECTION - complex_vars_of_filelock (); -#endif /* CLASH_DETECTION */ - /* This creates a couple of basic keymaps and depends on Lisp - hashtables and Ffset() (both of which depend on some variables + hash tables and Ffset() (both of which depend on some variables initialized in the vars_of_*() section) and possibly other stuff. */ complex_vars_of_keymap (); - /* Calls Fmake_hashtable() and creates a keymap */ + + /* Calls make_lisp_hash_table() and creates a keymap */ complex_vars_of_event_stream (); - if (always_gc) /* purification debugging hack */ - garbage_collect_1 (); +#ifdef ERROR_CHECK_GC + { + extern int always_gc; + if (always_gc) /* purification debugging hack */ + garbage_collect_1 (); + } +#endif +#ifdef PDUMP + } else if (!restart) { /* after successful pdump_load() */ + reinit_alloc_once_early (); + reinit_symbols_once_early (); + reinit_opaque_once_early (); + + reinit_console_type_create_stream (); +#ifdef HAVE_TTY + reinit_console_type_create_tty (); +#endif +#ifdef HAVE_X_WINDOWS + reinit_console_type_create_x (); + reinit_console_type_create_device_x (); +#endif +#ifdef HAVE_MS_WINDOWS + reinit_console_type_create_mswindows (); +#endif +#ifdef HAVE_GTK + reinit_console_type_create_gtk (); +#endif + + reinit_specifier_type_create (); + reinit_specifier_type_create_image (); + reinit_specifier_type_create_gutter (); + reinit_specifier_type_create_objects (); +#ifdef HAVE_TOOLBARS + reinit_specifier_type_create_toolbar (); +#endif + + structure_type_create (); + + structure_type_create_chartab (); + structure_type_create_faces (); + structure_type_create_rangetab (); + structure_type_create_hash_table (); + + lstream_type_create (); +#ifdef FILE_CODING + lstream_type_create_file_coding (); +#endif +#if defined (HAVE_MS_WINDOWS) && !defined(HAVE_MSG_SELECT) + lstream_type_create_mswindows_selectable (); +#endif +#ifdef HAVE_UNIX_PROCESSES + process_type_create_unix (); +#endif +#ifdef HAVE_WIN32_PROCESSES + process_type_create_nt (); +#endif + + reinit_vars_of_buffer (); + reinit_vars_of_console (); +#ifdef DEBUG_XEMACS + reinit_vars_of_debug (); +#endif + reinit_vars_of_device (); + reinit_vars_of_eval (); +#ifdef HAVE_X_WINDOWS + reinit_vars_of_event_Xt (); +#endif +#ifdef HAVE_GTK + reinit_vars_of_event_gtk (); +#endif +#if defined(HAVE_TTY) && (defined (DEBUG_TTY_EVENT_STREAM) || !defined (HAVE_X_WINDOWS)) + reinit_vars_of_event_tty (); +#endif +#ifdef HAVE_MS_WINDOWS + reinit_vars_of_event_mswindows (); +#endif + reinit_vars_of_event_stream (); + reinit_vars_of_events (); + reinit_vars_of_extents (); + reinit_vars_of_fileio (); + reinit_vars_of_font_lock (); + reinit_vars_of_glyphs (); + reinit_vars_of_glyphs_widget (); + reinit_vars_of_insdel (); + reinit_vars_of_lread (); + reinit_vars_of_lstream (); + reinit_vars_of_minibuf (); +#ifdef HAVE_SHLIB + reinit_vars_of_module (); +#endif + reinit_vars_of_objects (); + reinit_vars_of_print (); + reinit_vars_of_search (); + reinit_vars_of_undo (); + reinit_vars_of_window (); + +#ifdef HAVE_MS_WINDOWS + reinit_vars_of_frame_mswindows (); +#endif + +#ifdef HAVE_GTK + reinit_vars_of_menubar_gtk (); +#endif + +#ifdef HAVE_X_WINDOWS + reinit_vars_of_device_x (); +#ifdef HAVE_SCROLLBARS + reinit_vars_of_scrollbar_x (); +#endif +#ifdef HAVE_MENUBARS + reinit_vars_of_menubar_x (); +#endif + reinit_vars_of_select_x (); +#if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS) + reinit_vars_of_gui_x (); +#endif +#endif /* HAVE_X_WINDOWS */ + +#if defined(MULE) && defined(HAVE_WNN) + reinit_vars_of_mule_wnn (); +#endif + + reinit_complex_vars_of_buffer (); + reinit_complex_vars_of_console (); + reinit_complex_vars_of_minibuf (); +#endif /* PDUMP */ } + /* CONGRATULATIONS!!! We have successfully initialized the Lisp engine. */ if (initialized) { - /* Stuff that needs to be reset at run time. Order below should - not matter. */ + /* Stuff that should not be done at dump time, including stuff that + needs to be reset at run time. Order below should not matter. + + Many initializations taken from the environment should go here. */ reinit_alloc (); reinit_eval (); #ifdef MULE_REGEXP reinit_mule_category (); #endif +#ifdef HAVE_POSTGRESQL + init_postgresql_from_environment(); +#endif } /* Now do further initialization/setup of stuff that is not needed by the @@ -1575,10 +2330,10 @@ main_1 (int argc, char **argv, char **envp, int restart) init_initial_directory(); /* get the directory to use for the "*scratch*" buffer, etc. */ -#ifdef WINDOWSNT +#ifdef WIN32_NATIVE /* * For Win32, call init_environment() now, so that environment/registry - * variables will be properly entered into Vprocess_envonment. + * variables will be properly entered into Vprocess_environment. */ init_environment(); #endif @@ -1590,21 +2345,17 @@ main_1 (int argc, char **argv, char **envp, int restart) first because many of the functions below call egetenv() to get environment variables. */ init_lread (); /* Set up the Lisp reader. */ -#ifdef MSDOS - /* Call early 'cause init_environment needs it. */ - init_dosfns (); - /* Set defaults for several environment variables. */ - init_environment (argc, argv, skip_args); -#endif - init_cmdargs (argc, argv, skip_args); /* Create list Vcommand_line_args */ + init_cmdargs (argc, (Extbyte **) argv, + skip_args); /* Create list Vcommand_line_args */ init_buffer (); /* Set default directory of *scratch* buffer */ -#ifdef WINDOWSNT +#ifdef WIN32_NATIVE init_ntproc(); #endif init_redisplay (); /* Determine terminal type. init_sys_modes uses results */ + init_frame (); init_event_stream (); /* Set up so we can get user input. */ init_macros (); /* set up so we can run macros. */ init_editfns (); /* Determine the name of the user we're running as */ @@ -1612,13 +2363,16 @@ main_1 (int argc, char **argv, char **envp, int restart) #ifdef SUNPRO init_sunpro (); /* Set up Sunpro usage tracking */ #endif +#if defined (WIN32_NATIVE) || defined (CYGWIN) + init_win32 (); +#endif #if defined (HAVE_NATIVE_SOUND) && defined (hp9000s800) init_hpplay (); #endif #ifdef HAVE_TTY init_device_tty (); #endif - init_console_stream (); /* Create the first console */ + init_console_stream (restart); /* Create the first console */ /* try to get the actual pathname of the exec file we are running */ if (!restart) @@ -1642,7 +2396,8 @@ main_1 (int argc, char **argv, char **envp, int restart) else { Vinvocation_path = decode_env_path ("PATH", NULL); - locate_file (Vinvocation_path, Vinvocation_name, EXEC_SUFFIXES, + locate_file (Vinvocation_path, Vinvocation_name, + Vlisp_EXEC_SUFFIXES, &Vinvocation_directory, X_OK); } @@ -1653,7 +2408,7 @@ main_1 (int argc, char **argv, char **envp, int restart) Vinvocation_directory = Ffile_name_directory (Vinvocation_directory); } -#if defined(HAVE_SHLIB) && !defined(WINDOWSNT) +#if defined(HAVE_SHLIB) && !defined(WIN32_NATIVE) /* This is Unix only. MS Windows NT has a library call that does The Right Thing on that system. Rumor has it, this must be called for GNU dld in temacs and xemacs. */ @@ -1661,11 +2416,11 @@ main_1 (int argc, char **argv, char **envp, int restart) char *buf = (char *)alloca (XSTRING_LENGTH (Vinvocation_directory) + XSTRING_LENGTH (Vinvocation_name) + 2); - sprintf (buf, "%s/%s", XSTRING_DATA(Vinvocation_directory), - XSTRING_DATA(Vinvocation_name)); + sprintf (buf, "%s/%s", XSTRING_DATA (Vinvocation_directory), + XSTRING_DATA (Vinvocation_name)); /* All we can do is cry if an error happens, so ignore it. */ - (void)dll_init(buf); + (void) dll_init (buf); } #endif @@ -1697,6 +2452,7 @@ main_1 (int argc, char **argv, char **envp, int restart) #endif /* QUANTIFY */ initialized = 1; + inhibit_non_essential_printing_operations = 0; /* This never returns. */ initial_command_loop (load_me); @@ -1711,17 +2467,18 @@ main_1 (int argc, char **argv, char **envp, int restart) struct standard_args { - CONST char * CONST name; - CONST char * CONST longname; + const char *name; + const char *longname; int priority; int nargs; }; -static struct standard_args standard_args[] = +static const struct standard_args standard_args[] = { /* Handled by main_1 above: */ - { "-nl", "--no-shared-memory", 100, 0 }, - { "-t", "--terminal", 95, 1 }, + { "-sd", "--show-dump-id", 105, 0 }, + { "-t", "--terminal", 100, 1 }, + { "-nd", "--no-dump-file", 95, 0 }, { "-nw", "--no-windows", 90, 0 }, { "-batch", "--batch", 85, 0 }, { "-debug-paths", "--debug-paths", 82, 0 }, @@ -1795,7 +2552,7 @@ static struct standard_args standard_args[] = static void sort_args (int argc, char **argv) { - char **new = xnew_array (char *, argc); + char **new_argv = xnew_array (char *, argc); /* For each element of argv, the corresponding element of options is: 0 for an option that takes no arguments, @@ -1875,8 +2632,8 @@ sort_args (int argc, char **argv) } } - /* Copy the arguments, in order of decreasing priority, to NEW. */ - new[0] = argv[0]; + /* Copy the arguments, in order of decreasing priority, to NEW_ARGV. */ + new_argv[0] = argv[0]; while (to < argc) { int best = -1; @@ -1899,10 +2656,10 @@ sort_args (int argc, char **argv) if (best < 0) abort (); - /* Copy the highest priority remaining option, with its args, to NEW. */ - new[to++] = argv[best]; + /* Copy the highest priority remaining option, with its args, to NEW_ARGV. */ + new_argv[to++] = argv[best]; for (i = 0; i < options[best]; i++) - new[to++] = argv[best + i + 1]; + new_argv[to++] = argv[best + i + 1]; /* Clear out this option in ARGV. */ argv[best] = 0; @@ -1910,17 +2667,12 @@ sort_args (int argc, char **argv) argv[best + i + 1] = 0; } - memcpy (argv, new, sizeof (char *) * argc); + memcpy (argv, new_argv, sizeof (char *) * argc); + xfree (new_argv); + xfree (options); + xfree (priority); } -static JMP_BUF run_temacs_catch; - -static int run_temacs_argc; -static char **run_temacs_argv; -static char *run_temacs_args; -static size_t run_temacs_argv_size; -static size_t run_temacs_args_size; - DEFUN ("running-temacs-p", Frunning_temacs_p, 0, 0, 0, /* True if running temacs. This means we are in the dumping stage. This is false during normal execution of the `xemacs' program, and @@ -1942,15 +2694,17 @@ Do not call this. It will reinitialize your XEmacs. You'll be sorry. a dumped version in case you want to rerun it. This function is most useful when used as part of the `make all-elc' command. --ben] This will "restart" emacs with the specified command-line arguments. - */ + + Martin thinks this function is most useful when using debugging + tools like Purify or tcov that get confused by XEmacs' dumping. */ (int nargs, Lisp_Object *args)) { int ac; - CONST Extbyte *wampum; + const Extbyte *wampum; int namesize; int total_len; Lisp_Object orig_invoc_name = Fcar (Vcommand_line_args); - CONST Extbyte **wampum_all = alloca_array (CONST Extbyte *, nargs); + const Extbyte **wampum_all = alloca_array (const Extbyte *, nargs); int *wampum_all_len = alloca_array (int, nargs); assert (!gc_in_progress); @@ -1961,21 +2715,22 @@ Do not call this. It will reinitialize your XEmacs. You'll be sorry. /* Need to convert the orig_invoc_name and all of the arguments to external format. */ - GET_STRING_EXT_DATA_ALLOCA (orig_invoc_name, FORMAT_OS, wampum, - namesize); + TO_EXTERNAL_FORMAT (LISP_STRING, orig_invoc_name, + ALLOCA, (wampum, namesize), + Qnative); namesize++; for (ac = 0, total_len = namesize; ac < nargs; ac++) { CHECK_STRING (args[ac]); - GET_STRING_EXT_DATA_ALLOCA (args[ac], FORMAT_OS, - wampum_all[ac], - wampum_all_len[ac]); + TO_EXTERNAL_FORMAT (LISP_STRING, args[ac], + ALLOCA, (wampum_all[ac], wampum_all_len[ac]), + Qnative); wampum_all_len[ac]++; total_len += wampum_all_len[ac]; } DO_REALLOC (run_temacs_args, run_temacs_args_size, total_len, char); - DO_REALLOC (run_temacs_argv, run_temacs_argv_size, nargs+1, char *); + DO_REALLOC (run_temacs_argv, run_temacs_argv_size, nargs+2, char *); memcpy (run_temacs_args, wampum, namesize); run_temacs_argv [0] = run_temacs_args; @@ -1992,10 +2747,8 @@ Do not call this. It will reinitialize your XEmacs. You'll be sorry. unbind_to (0, Qnil); /* this closes loadup.el */ purify_flag = 0; run_temacs_argc = nargs + 1; -#ifdef REPORT_PURE_USAGE - report_pure_usage (1, 0); -#else - report_pure_usage (0, 0); +#if defined (HEAP_IN_DATA) && !defined(PDUMP) + report_sheap_usage (0); #endif LONGJMP (run_temacs_catch, 1); return Qnil; /* not reached; warning suppression */ @@ -2005,37 +2758,53 @@ Do not call this. It will reinitialize your XEmacs. You'll be sorry. int main (int argc, char **argv, char **envp) { + +#ifdef _MSC_VER + /* Under VC++, access violations and the like are not sent through + the standard signal() mechanism. Rather, they need to be handled + using the Microsoft "structured exception handling" mechanism, + which vaguely resembles the C++ mechanisms. */ + __try + { +#endif + int volatile vol_argc = argc; char ** volatile vol_argv = argv; char ** volatile vol_envp = envp; - /* This is hairy. We need to compute where the XEmacs binary was invoked */ - /* from because temacs initialization requires it to find the lisp */ - /* directories. The code that recomputes the path is guarded by the */ - /* restarted flag. There are three possible paths I've found so far */ - /* through this: */ - /* temacs -- When running temacs for basic build stuff, the first main_1 */ - /* will be the only one invoked. It must compute the path else there */ - /* will be a very ugly bomb in startup.el (can't find obvious location */ - /* for doc-directory data-directory, etc.). */ - /* temacs w/ run-temacs on the command line -- This is run to bytecompile */ - /* all the out of date dumped lisp. It will execute both of the main_1 */ - /* calls and the second one must not touch the first computation because */ - /* argc/argv are hosed the second time through. */ - /* xemacs -- Only the second main_1 is executed. The invocation path must */ - /* computed but this only matters when running in place or when running */ - /* as a login shell. */ - /* As a bonus for straightening this out, XEmacs can now be run in place */ - /* as a login shell. This never used to work. */ - /* As another bonus, we can now guarantee that */ - /* (concat invocation-directory invocation-name) contains the filename */ - /* of the XEmacs binary we are running. This can now be used in a */ - /* definite test for out of date dumped files. -slb */ + /* This is hairy. We need to compute where the XEmacs binary was invoked + from because temacs initialization requires it to find the lisp + directories. The code that recomputes the path is guarded by the + restarted flag. There are three possible paths I've found so far + through this: + + temacs -- When running temacs for basic build stuff, the first main_1 + will be the only one invoked. It must compute the path else there + will be a very ugly bomb in startup.el (can't find obvious location + for doc-directory data-directory, etc.). + + temacs w/ run-temacs on the command line -- This is run to bytecompile + all the out of date dumped lisp. It will execute both of the main_1 + calls and the second one must not touch the first computation because + argc/argv are hosed the second time through. + + xemacs -- Only the second main_1 is executed. The invocation path must + computed but this only matters when running in place or when running + as a login shell. + + As a bonus for straightening this out, XEmacs can now be run in place + as a login shell. This never used to work. + + As another bonus, we can now guarantee that + (concat invocation-directory invocation-name) contains the filename + of the XEmacs binary we are running. This can now be used in a + definite test for out of date dumped files. -slb */ int restarted = 0; #ifdef QUANTIFY quantify_stop_recording_data (); quantify_clear_data (); #endif /* QUANTIFY */ + inhibit_non_essential_printing_operations = 1; suppress_early_error_handler_backtrace = 0; lim_data = 0; /* force reinitialization of this variable */ @@ -2049,7 +2818,8 @@ main (int argc, char **argv, char **envp) if (!initialized) { #ifdef DOUG_LEA_MALLOC - mallopt (M_MMAP_MAX, 0); + if (mallopt (M_MMAP_MAX, 0) != 1) + abort(); #endif run_temacs_argc = 0; if (! SETJMP (run_temacs_catch)) @@ -2075,16 +2845,16 @@ main (int argc, char **argv, char **envp) 06/20/96 robertl@dgii.com */ { - extern char *_environ; + extern char **_environ; if ((unsigned) environ == 0) environ=_environ; } #endif /* _SCO_DS */ vol_envp = environ; } -#ifdef RUN_TIME_REMAP +#if defined (RUN_TIME_REMAP) && ! defined (PDUMP) else - /* obviously no-one uses this because where it was before initalized was + /* obviously no-one uses this because where it was before initialized was *always* true */ run_time_remap (argv[0]); #endif @@ -2095,7 +2865,7 @@ main (int argc, char **argv, char **envp) int rc = malloc_set_state (malloc_state_ptr); if (rc != 0) { - fprintf (stderr, "malloc_set_state failed, rc = %d\n", rc); + stderr_out ("malloc_set_state failed, rc = %d\n", rc); abort (); } #if 0 @@ -2106,7 +2876,8 @@ main (int argc, char **argv, char **envp) defined(_NO_MALLOC_WARNING_) || \ (defined(__GLIBC__) && __GLIBC_MINOR__ < 1 && !defined(MULE)) || \ defined(DEBUG_DOUG_LEA_MALLOC) - mallopt (M_MMAP_MAX, 64); + if(mallopt (M_MMAP_MAX, 0) != 1) + abort(); #endif #ifdef REL_ALLOC r_alloc_reinit (); @@ -2117,6 +2888,14 @@ main (int argc, char **argv, char **envp) run_temacs_argc = -1; main_1 (vol_argc, vol_argv, vol_envp, restarted); + +#ifdef _MSC_VER + } + /* VC++ documentation says that + GetExceptionCode() cannot be called inside the filter itself. */ + __except (mswindows_handle_hardware_exceptions (GetExceptionCode ())) {} +#endif + return 0; /* unreached */ } @@ -2127,13 +2906,17 @@ main (int argc, char **argv, char **envp) /* GCC >= 2.8. -slb */ #if defined(GNU_MALLOC) static void -voodoo_free_hook(void *mem) +voodoo_free_hook (void *mem) { /* Disable all calls to free() when XEmacs is exiting and it doesn't */ /* matter. */ - __free_hook = voodoo_free_hook; -} + __free_hook = +#ifdef __GNUC__ /* prototype of __free_hook varies with glibc version */ + (__typeof__ (__free_hook)) #endif + voodoo_free_hook; +} +#endif /* GNU_MALLOC */ DEFUN ("kill-emacs", Fkill_emacs, 0, 1, "P", /* Exit the XEmacs job and kill it. Ask for confirmation, without argument. @@ -2157,9 +2940,7 @@ all of which are called before XEmacs is actually killed. if (!preparing_for_armageddon && !noninteractive) run_hook (Qkill_emacs_hook); - /* make sure no quitting from now on!! */ - dont_check_for_quit = 1; - Vinhibit_quit = Qt; + ensure_no_quitting_from_now_on (); if (!preparing_for_armageddon) { @@ -2173,7 +2954,7 @@ all of which are called before XEmacs is actually killed. be too dangerous), and if we get a crash somewhere within this loop, we'll still autosave and won't try this again. */ - LIST_LOOP_DELETING(concons, nextcons, Vconsole_list) + LIST_LOOP_DELETING (concons, nextcons, Vconsole_list) { /* There is very little point in deleting the stream console. It uses stdio, which should flush any buffered output and @@ -2187,13 +2968,30 @@ all of which are called before XEmacs is actually killed. UNGCPRO; - shut_down_emacs (0, ((STRINGP (arg)) ? arg : Qnil)); +#ifdef HAVE_MS_WINDOWS + /* If we displayed a message on the console, then we must allow the + user to see this message. This may be unnecessary, but can't + hurt, and we can't necessarily check arg; e.g. xemacs --help + kills with argument 0. + + Don't do this in batch mode, it makes no sense and is more + annoying than useful. --andyp */ + if (mswindows_message_outputted && !noninteractive) + Fmswindows_message_box (build_string ("Messages outputted. XEmacs is exiting."), + Qnil, Qnil); +#endif + + shut_down_emacs (0, STRINGP (arg) ? arg : Qnil, 0); #if defined(GNU_MALLOC) - __free_hook = voodoo_free_hook; + __free_hook = +#ifdef __GNUC__ /* prototype of __free_hook varies with glibc version */ + (__typeof__ (__free_hook)) +#endif + voodoo_free_hook; #endif - exit ((INTP (arg)) ? XINT (arg) : 0); + exit (INTP (arg) ? XINT (arg) : 0); /* NOTREACHED */ return Qnil; /* I'm sick of the compiler warning */ } @@ -2206,80 +3004,95 @@ all of which are called before XEmacs is actually killed. If SIG is a signal number, print a message for it. - This is called by fatal signal handlers, X protocol error handlers, - and Fkill_emacs. */ + This is called by fatal signal handlers and Fkill_emacs. It used to + be called by X protocol error handlers, but instead they now call + Fkill_emacs. */ static void -shut_down_emacs (int sig, Lisp_Object stuff) +shut_down_emacs (int sig, Lisp_Object stuff, int no_auto_save) { /* This function can GC */ /* Prevent running of hooks and other non-essential stuff from now on. */ preparing_for_armageddon = 1; - /* In case frames or windows are screwed up, avoid assertion - failures here */ - Vinhibit_quit = Qt; + ensure_no_quitting_from_now_on (); #ifdef QUANTIFY quantify_stop_recording_data (); #endif /* QUANTIFY */ -#if 0 /* This is absolutely the most important thing to do, so make sure we do it now, before anything else. We might have crashed and be in a weird inconsistent state, and potentially anything could set off another protection fault and cause us to bail out immediately. */ - /* I'm not removing the code entirely, yet. We have run up against + /* Steve writes the following: + + [[I'm not removing the code entirely, yet. We have run up against a spate of problems in diagnosing crashes due to crashes within crashes. It has very definitely been determined that code called during auto-saving cannot work if XEmacs crashed inside of GC. We already auto-save on an itimer so there cannot be too much unsaved stuff around, and if we get better crash reports we might - be able to get more problems fixed so I'm disabling this. -slb */ - Fdo_auto_save (Qt, Qnil); /* do this before anything hazardous */ -#endif + be able to get more problems fixed so I'm disabling this. -slb]] + + and DISABLES AUTO-SAVING ENTIRELY during crashes! Way way bad idea. + + Instead let's just be more intelligent about avoiding crashing + when possible, esp. nested crashes. + */ + if (!no_auto_save) + Fdo_auto_save (Qt, Qnil); /* do this before anything hazardous */ fflush (stdout); reset_all_consoles (); if (sig && sig != SIGTERM) { - stderr_out ("\nFatal error (%d).\n", sig); + if (sig == -1) + stderr_out ("\nFatal error.\n\n"); + else + stderr_out ("\nFatal error (%d).\n\n", sig); stderr_out ("Your files have been auto-saved.\n" "Use `M-x recover-session' to recover them.\n" "\n" + "Your version of XEmacs was distributed with a PROBLEMS file that may describe\n" + "your crash, and with luck a workaround. Please check it first, but do report\n" + "the crash anyway. " #ifdef INFODOCK - "Please report this bug by selecting `Report-Bug' in the InfoDock\n" - "menu.\n" + "\n\nPlease report this bug by selecting `Report-Bug' in the InfoDock menu.\n" + "*BE SURE* to include the XEmacs configuration from M-x describe-installation,\n" + "or the file Installation in the top directory of the build tree.\n" #else - "Please report this bug by running the send-pr script included\n" - "with XEmacs, or selecting `Send Bug Report' from the help menu.\n" - "As a last resort send ordinary email to `crashes@xemacs.org'.\n" + "Please report this bug by invoking M-x report-emacs-bug,\n" + "or by selecting `Send Bug Report' from the Help menu. If necessary, send\n" + "ordinary email to `crashes@xemacs.org'. *MAKE SURE* to include the XEmacs\n" + "configuration from M-x describe-installation, or equivalently the file\n" + "Installation in the top of the build tree.\n" #endif - "*MAKE SURE* to include the information in the command\n" - "M-x describe-installation.\n" +#ifndef _MSC_VER "\n" - "If at all possible, *please* try to obtain a C stack backtrace;\n" - "it will help us immensely in determining what went wrong.\n" - "To do this, locate the core file that was produced as a result\n" - "of this crash (it's usually called `core' and is located in the\n" - "directory in which you started the editor, or maybe in your home\n" - "directory), and type\n" + "*Please* try *hard* to obtain a C stack backtrace; without it, we are unlikely\n" + "to be able to analyze the problem. Locate the core file produced as a result\n" + "of this crash (often called `core' or `core.', and located in\n" + "the directory in which you started XEmacs or your home directory), and type\n" "\n" - " gdb "); + " gdb " +#endif + ); +#ifndef _MSC_VER { - CONST char *name; + const char *name; char *dir = 0; /* Now try to determine the actual path to the executable, to try to make the backtrace-determination process as foolproof as possible. */ - if (GC_STRINGP (Vinvocation_name)) + if (STRINGP (Vinvocation_name)) name = (char *) XSTRING_DATA (Vinvocation_name); else name = "xemacs"; - if (GC_STRINGP (Vinvocation_directory)) + if (STRINGP (Vinvocation_directory)) dir = (char *) XSTRING_DATA (Vinvocation_directory); if (!dir || dir[0] != '/') stderr_out ("`which %s`", name); @@ -2289,11 +3102,13 @@ shut_down_emacs (int sig, Lisp_Object stuff) stderr_out ("%s%s", dir, name); } stderr_out - (" core\n\n" - "then type `where' when the debugger prompt comes up.\n" - "(If you don't have GDB on your system, you might have DBX,\n" - "or XDB, or SDB. A similar procedure should work for all of\n" - "these. Ask your system administrator if you need more help.)\n"); + (" core\n" + "\n" + "then type `where' at the debugger prompt. No GDB on your system? You may\n" + "have DBX, or XDB, or SDB. (Ask your system administrator if you need help.)\n" + "If no core file was produced, enable them (often with `ulimit -c unlimited'\n" + "in case of future recurrance of the crash.\n"); +#endif /* _MSC_VER */ } stuff_buffered_input (stuff); @@ -2316,50 +3131,11 @@ shut_down_emacs (int sig, Lisp_Object stuff) #ifndef CANNOT_DUMP -/* Nothing like this can be implemented on an Apollo. - What a loss! */ +#if !defined(PDUMP) || !defined(SYSTEM_MALLOC) extern char my_edata[]; - -#ifdef HAVE_SHM - -DEFUN ("dump-emacs-data", Fdump_emacs_data, 1, 1, 0, /* -Dump current state of XEmacs into data file FILENAME. -This function exists on systems that use HAVE_SHM. -*/ - (intoname)) -{ - /* This function can GC */ - int opurify; - struct gcpro gcpro1; - GCPRO1 (intoname); - - CHECK_STRING (intoname); - intoname = Fexpand_file_name (intoname, Qnil); - - opurify = purify_flag; - purify_flag = 0; - - fflush (stderr); - fflush (stdout); - - disksave_object_finalization (); - release_breathing_space (); - - /* Tell malloc where start of impure now is */ - /* Also arrange for warnings when nearly out of space. */ -#ifndef SYSTEM_MALLOC - memory_warnings (my_edata, malloc_warning); #endif - UNGCPRO; - map_out_data (XSTRING_DATA (intoname)); - - purify_flag = opurify; - - return Qnil; -} -#else /* not HAVE_SHM */ extern void disable_free_hook (void); DEFUN ("dump-emacs", Fdump_emacs, 2, 2, 0, /* @@ -2371,13 +3147,13 @@ Remember to set `command-line-processed' to nil before dumping if you want the dumped XEmacs to process its command line and announce itself normally when it is run. */ - (intoname, symname)) + (filename, symfile)) { /* This function can GC */ struct gcpro gcpro1, gcpro2; int opurify; - GCPRO2 (intoname, symname); + GCPRO2 (filename, symfile); #ifdef FREE_CHECKING Freally_free (Qnil); @@ -2385,29 +3161,27 @@ and announce itself normally when it is run. /* When we're dumping, we can't use the debugging free() */ disable_free_hook (); #endif -#if 1 /* martin */ -#endif - CHECK_STRING (intoname); - intoname = Fexpand_file_name (intoname, Qnil); - if (!NILP (symname)) + CHECK_STRING (filename); + filename = Fexpand_file_name (filename, Qnil); + if (!NILP (symfile)) { - CHECK_STRING (symname); - if (XSTRING_LENGTH (symname) > 0) - symname = Fexpand_file_name (symname, Qnil); + CHECK_STRING (symfile); + if (XSTRING_LENGTH (symfile) > 0) + symfile = Fexpand_file_name (symfile, Qnil); else - symname = Qnil; + symfile = Qnil; } opurify = purify_flag; purify_flag = 0; -#ifdef DEBUG_XEMACS - report_pure_usage (1, 1); -#else - report_pure_usage (0, 1); +#if defined (HEAP_IN_DATA) && !defined(PDUMP) + report_sheap_usage (1); #endif + clear_message (); + fflush (stderr); fflush (stdout); @@ -2422,29 +3196,23 @@ and announce itself normally when it is run. UNGCPRO; -#if defined (MSDOS) && defined (EMX) - { - int fd = open ((char *) XSTRING_DATA (intoname), - O_WRONLY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE); - if (!fd) { - error ("Failure operating on %s", XSTRING_DATA (intoname)); - } else { - _core (fd); - close (fd); - } - } -#else /* not MSDOS and EMX */ { - char *intoname_ext; - char *symname_ext; + char *filename_ext; + char *symfile_ext; + + LISP_STRING_TO_EXTERNAL (filename, filename_ext, Qfile_name); - GET_C_STRING_FILENAME_DATA_ALLOCA (intoname, intoname_ext); - if (STRINGP (symname)) - GET_C_STRING_FILENAME_DATA_ALLOCA (symname, symname_ext); + if (STRINGP (symfile)) + LISP_STRING_TO_EXTERNAL (symfile, symfile_ext, Qfile_name); else - symname_ext = 0; + symfile_ext = 0; garbage_collect_1 (); + +#ifdef PDUMP + pdump (); +#else + #ifdef DOUG_LEA_MALLOC malloc_state_ptr = malloc_get_state (); #endif @@ -2453,39 +3221,34 @@ and announce itself normally when it is run. It's a whole lot easier to do the conversion here than to modify all the unexec routines to ensure that filename conversion is applied everywhere. Don't worry about memory - leakage because this call only happens once. */ - unexec (intoname_ext, symname_ext, (uintptr_t) my_edata, 0, 0); + leakage because this call only happens once. */ + unexec (filename_ext, symfile_ext, (uintptr_t) my_edata, 0, 0); #ifdef DOUG_LEA_MALLOC - free (malloc_state_ptr); + free (malloc_state_ptr); #endif +#endif /* not PDUMP */ } -#endif /* not MSDOS and EMX */ purify_flag = opurify; return Qnil; } -#endif /* not HAVE_SHM */ - #endif /* not CANNOT_DUMP */ -#ifndef SEPCHAR -#define SEPCHAR ':' -#endif /* Split STRING into a list of substrings. The substrings are the parts of original STRING separated by SEPCHAR. */ static Lisp_Object -split_string_by_emchar_1 (CONST Bufbyte *string, Bytecount size, +split_string_by_emchar_1 (const Bufbyte *string, Bytecount size, Emchar sepchar) { Lisp_Object result = Qnil; - CONST Bufbyte *end = string + size; + const Bufbyte *end = string + size; while (1) { - CONST Bufbyte *p = string; + const Bufbyte *p = string; while (p < end) { if (charptr_emchar (p) == sepchar) @@ -2505,33 +3268,32 @@ split_string_by_emchar_1 (CONST Bufbyte *string, Bytecount size, } /* The same as the above, except PATH is an external C string (it is - converted as FORMAT_FILENAME), and sepchar is hardcoded to SEPCHAR + converted using Qfile_name), and sepchar is hardcoded to SEPCHAR (':' or whatever). */ Lisp_Object -decode_path (CONST char *path) +decode_path (const char *path) { - int len; + Bytecount newlen; Bufbyte *newpath; if (!path) return Qnil; - GET_C_CHARPTR_INT_FILENAME_DATA_ALLOCA (path, newpath); + TO_INTERNAL_FORMAT (C_STRING, path, ALLOCA, (newpath, newlen), Qfile_name); - len = strlen (newpath); /* #### Does this make sense? It certainly does for decode_env_path(), but it looks dubious here. Does any code depend on decode_path("") returning nil instead of an empty string? */ - if (!len) + if (!newlen) return Qnil; - return split_string_by_emchar_1 (newpath, (Bytecount)len, SEPCHAR); + return split_string_by_emchar_1 (newpath, newlen, SEPCHAR); } Lisp_Object -decode_env_path (CONST char *evarname, CONST char *default_) +decode_env_path (const char *evarname, const char *default_) { - CONST char *path = 0; + const char *path = 0; if (evarname) path = egetenv (evarname); if (!path) @@ -2542,7 +3304,7 @@ decode_env_path (CONST char *evarname, CONST char *default_) /* Ben thinks this function should not exist or be exported to Lisp. We use it to define split-path-string in subr.el (not!). */ -DEFUN ("split-string-by-char", Fsplit_string_by_char, 1, 2, 0, /* +DEFUN ("split-string-by-char", Fsplit_string_by_char, 2, 2, 0, /* Split STRING into a list of substrings originally separated by SEPCHAR. */ (string, sepchar)) @@ -2593,23 +3355,83 @@ Non-nil return value means XEmacs is running without interactive terminal. #ifdef USE_ASSERTIONS /* This highly dubious kludge ... shut up Jamie, I'm tired of your slagging. */ -DOESNT_RETURN -assert_failed (CONST char *file, int line, CONST char *expr) -{ - stderr_out ("Fatal error: assertion failed, file %s, line %d, %s\n", - file, line, expr); +static int in_assert_failed; +static const char *assert_failed_file; +static int assert_failed_line; +static const char *assert_failed_expr; + +#ifdef fprintf +#undef fprintf +#endif + #undef abort /* avoid infinite #define loop... */ -#if defined (WINDOWSNT) && defined (DEBUG_XEMACS) - DebugBreak (); -#elif !defined (ASSERTIONS_DONT_ABORT) + +#if defined (WIN32_NATIVE) && defined (DEBUG_XEMACS) +#define enter_debugger() DebugBreak () +#else +#define enter_debugger() +#endif + +void +assert_failed (const char *file, int line, const char *expr) +{ + /* If we're already crashing, let's not crash again. This might be + critical to getting auto-saving working properly. */ + if (fatal_error_in_progress) + return; + + /* We are extremely paranoid so we sensibly deal with recursive + assertion failures. */ + in_assert_failed++; + inhibit_non_essential_printing_operations = 1; + + if (in_assert_failed >= 4) + _exit (-1); + else if (in_assert_failed == 3) + { + enter_debugger (); + _exit (-1); + } + else if (in_assert_failed == 2) + { + /* Not stderr_out(), which does additional things and may trigger + a recursive assertion failure. fprintf was undeffed above, in + case it was encapsulated. */ + fprintf (stderr, + "Fatal error: recursive assertion failure, " + "file %s, line %d, %s\n", + file, line, expr); + fprintf (stderr, + "Original assertion failure: file %s, line %d, %s\n", + assert_failed_file, assert_failed_line, assert_failed_expr); + } + else + { + assert_failed_file = file; + assert_failed_line = line; + assert_failed_expr = expr; + + if (!initialized) + fprintf (stderr, + "Fatal error: assertion failed, file %s, line %d, %s\n", + file, line, expr); + else + stderr_out ("Fatal error: assertion failed, file %s, line %d, %s\n", + file, line, expr); + } + + enter_debugger (); +#if !defined (ASSERTIONS_DONT_ABORT) abort (); #endif + inhibit_non_essential_printing_operations = 0; + in_assert_failed = 0; } #endif /* USE_ASSERTIONS */ #ifdef QUANTIFY DEFUN ("quantify-start-recording-data", Fquantify_start_recording_data, - 0, 0, 0, /* + 0, 0, "", /* Start recording Quantify data. */ ()) @@ -2619,7 +3441,7 @@ Start recording Quantify data. } DEFUN ("quantify-stop-recording-data", Fquantify_stop_recording_data, - 0, 0, 0, /* + 0, 0, "", /* Stop recording Quantify data. */ ()) @@ -2628,7 +3450,7 @@ Stop recording Quantify data. return Qnil; } -DEFUN ("quantify-clear-data", Fquantify_clear_data, 0, 0, 0, /* +DEFUN ("quantify-clear-data", Fquantify_clear_data, 0, 0, "", /* Clear all Quantify data. */ ()) @@ -2642,11 +3464,7 @@ void syms_of_emacs (void) { #ifndef CANNOT_DUMP -#ifdef HAVE_SHM - DEFSUBR (Fdump_emacs_data); -#else DEFSUBR (Fdump_emacs); -#endif #endif /* !CANNOT_DUMP */ DEFSUBR (Frun_emacs_from_temacs); @@ -2656,6 +3474,10 @@ syms_of_emacs (void) DEFSUBR (Fkill_emacs); DEFSUBR (Fnoninteractive); +#ifdef DEBUG_XEMACS + DEFSUBR (Fforce_debugging_signal); +#endif + #ifdef QUANTIFY DEFSUBR (Fquantify_start_recording_data); DEFSUBR (Fquantify_stop_recording_data); @@ -2717,7 +3539,7 @@ Symbol indicating type of operating system you are using. DEFVAR_LISP ("system-configuration", &Vsystem_configuration /* String naming the configuration XEmacs was built for. */ ); - Vsystem_configuration = Fpurecopy (build_string (EMACS_CONFIGURATION)); + Vsystem_configuration = build_string (EMACS_CONFIGURATION); #ifndef EMACS_CONFIG_OPTIONS # define EMACS_CONFIG_OPTIONS "UNKNOWN" @@ -2725,8 +3547,7 @@ String naming the configuration XEmacs was built for. DEFVAR_LISP ("system-configuration-options", &Vsystem_configuration_options /* String containing the configuration options XEmacs was built with. */ ); - Vsystem_configuration_options = Fpurecopy (build_string - (EMACS_CONFIG_OPTIONS)); + Vsystem_configuration_options = build_string (EMACS_CONFIG_OPTIONS); DEFVAR_LISP ("emacs-major-version", &Vemacs_major_version /* Major version number of this version of Emacs, as an integer. @@ -2744,7 +3565,20 @@ Warning: this variable did not exist in Emacs versions earlier than: */ ); Vemacs_minor_version = make_int (EMACS_MINOR_VERSION); - DEFVAR_LISP ("emacs-beta-version", &Vemacs_beta_version /* + DEFVAR_LISP ("emacs-patch-level", &Vemacs_patch_level /* +The patch level of this version of Emacs, as an integer. +The value is non-nil if this version of XEmacs is part of a series of +stable XEmacsen, but has bug fixes applied. +Warning: this variable does not exist in FSF Emacs or in XEmacs versions +earlier than 21.1.1 +*/ ); +#ifdef EMACS_PATCH_LEVEL + Vemacs_patch_level = make_int (EMACS_PATCH_LEVEL); +#else + Vemacs_patch_level = Qnil; +#endif + + DEFVAR_LISP ("emacs-beta-version", &Vemacs_beta_version /* Beta number of this version of Emacs, as an integer. The value is nil if this is an officially released version of XEmacs. Warning: this variable does not exist in FSF Emacs or in XEmacs versions @@ -2779,8 +3613,40 @@ Codename of this version of Emacs (a string). #ifndef XEMACS_CODENAME #define XEMACS_CODENAME "Noname" #endif - Vxemacs_codename = Fpurecopy (build_string (XEMACS_CODENAME)); +#ifdef MULE + { + char dest[129]; + char src[64] = XEMACS_CODENAME; + unsigned char* sp = (unsigned char*)src; + int i = 0, chr; + + while ( (chr = *sp++) && (i < 128) ) + { + if (chr <= 0x7F) + dest[i++] = chr; + else + { +#ifdef UTF2000 + dest[i++] = (chr >> 6) | 0xC0; + dest[i++] = (chr & 0x3F) | 0x80; +#else + dest[i++] = LEADING_BYTE_LATIN_ISO8859_1; + dest[i++] = chr; +#endif + } + } + dest[i] = 0; + Vxemacs_codename = build_string (dest); + } +#else + Vxemacs_codename = build_string (XEMACS_CODENAME); +#endif + + /* Lisp variables which contain command line flags. + The portable dumper stomps on these; they must be saved and restored + if they are processed before the call to pdump_load() in main_1(). + */ DEFVAR_BOOL ("noninteractive", &noninteractive1 /* Non-nil means XEmacs is running without interactive terminal. */ ); @@ -2804,6 +3670,13 @@ Set to non-nil when the site-lisp should not be searched at startup. inhibit_site_lisp = 1; #endif + DEFVAR_BOOL ("inhibit-site-modules", &inhibit_site_modules /* +Set to non-nil when site-modules should not be searched at startup. +*/ ); +#ifdef INHIBIT_SITE_MODULES + inhibit_site_modules = 1; +#endif + DEFVAR_INT ("emacs-priority", &emacs_priority /* Priority for XEmacs to run at. This value is effective only if set before XEmacs is dumped, @@ -2824,6 +3697,8 @@ typecheck - check types strictly, aborting in case of error; malloc - check operation of malloc; gc - check garbage collection; bufpos - check buffer positions. + +quick-build - user has requested the "quick-build" configure option. */ ); Vinternal_error_checking = Qnil; #ifdef ERROR_CHECK_EXTENTS @@ -2846,7 +3721,50 @@ bufpos - check buffer positions. Vinternal_error_checking = Fcons (intern ("bufpos"), Vinternal_error_checking); #endif - Vinternal_error_checking = Fpurecopy (Vinternal_error_checking); +#ifdef QUICK_BUILD + Vinternal_error_checking = Fcons (intern ("quick-build"), + Vinternal_error_checking); +#endif + + DEFVAR_CONST_LISP ("mail-lock-methods", &Vmail_lock_methods /* +Mail spool locking methods supported by this instance of XEmacs. +This is a list of symbols. Each of the symbols is one of the +following: dot, lockf, flock, locking, mmdf. +*/ ); + { + Vmail_lock_methods = Qnil; + Vmail_lock_methods = Fcons (intern ("dot"), Vmail_lock_methods); +#ifdef HAVE_LOCKF + Vmail_lock_methods = Fcons (intern ("lockf"), Vmail_lock_methods); +#endif +#ifdef HAVE_FLOCK + Vmail_lock_methods = Fcons (intern ("flock"), Vmail_lock_methods); +#endif +#ifdef HAVE_MMDF + Vmail_lock_methods = Fcons (intern ("mmdf"), Vmail_lock_methods); +#endif +#ifdef HAVE_LOCKING + Vmail_lock_methods = Fcons (intern ("locking"), Vmail_lock_methods); +#endif + } + + DEFVAR_CONST_LISP ("configure-mail-lock-method", &Vconfigure_mail_lock_method /* +Mail spool locking method suggested by configure. This is one +of the symbols in MAIL-LOCK-METHODS. +*/ ); + { +#if defined(MAIL_LOCK_FLOCK) && defined(HAVE_FLOCK) + Vconfigure_mail_lock_method = intern("flock"); +#elif defined(MAIL_LOCK_LOCKF) && defined(HAVE_LOCKF) + Vconfigure_mail_lock_method = intern("lockf"); +#elif defined(MAIL_LOCK_MMDF) && defined(HAVE_MMDF) + Vconfigure_mail_lock_method = intern("mmdf"); +#elif defined(MAIL_LOCK_LOCKING) && defined(HAVE_LOCKING) + Vconfigure_mail_lock_method = intern("locking"); +#else + Vconfigure_mail_lock_method = intern("dot"); +#endif + } DEFVAR_LISP ("path-separator", &Vpath_separator /* The directory separator in search paths, as a string. @@ -2861,7 +3779,7 @@ void complex_vars_of_emacs (void) { /* This is all related to path searching. */ - + DEFVAR_LISP ("emacs-program-name", &Vemacs_program_name /* *Name of the Emacs variant. For example, this may be \"xemacs\" or \"infodock\". @@ -2871,7 +3789,7 @@ This is mainly meant for use in path searching. DEFVAR_LISP ("emacs-program-version", &Vemacs_program_version /* *Version of the Emacs variant. -This typically has the form XX.XX[-bXX]. +This typically has the form NN.NN-bNN. This is mainly meant for use in path searching. */ ); Vemacs_program_version = build_string ((char *) PATH_VERSION); @@ -2890,7 +3808,7 @@ especially executable programs intended for XEmacs to invoke. DEFVAR_LISP ("configure-exec-directory", &Vconfigure_exec_directory /* For internal use by the build procedure only. -configure's idea of what EXEC-DIRECTORY will be. +configure's idea of what `exec-directory' will be. */ ); #ifdef PATH_EXEC Vconfigure_exec_directory = Ffile_name_as_directory @@ -2906,7 +3824,7 @@ configure's idea of what EXEC-DIRECTORY will be. DEFVAR_LISP ("configure-lisp-directory", &Vconfigure_lisp_directory /* For internal use by the build procedure only. -configure's idea of what LISP-DIRECTORY will be. +configure's idea of what `lisp-directory' will be. */ ); #ifdef PATH_LOADSEARCH Vconfigure_lisp_directory = Ffile_name_as_directory @@ -2915,6 +3833,55 @@ configure's idea of what LISP-DIRECTORY will be. Vconfigure_lisp_directory = Qnil; #endif + DEFVAR_LISP ("mule-lisp-directory", &Vmule_lisp_directory /* +*Directory of Mule Lisp files that come with XEmacs. +*/ ); + Vmule_lisp_directory = Qnil; + + DEFVAR_LISP ("configure-mule-lisp-directory", &Vconfigure_mule_lisp_directory /* +For internal use by the build procedure only. +configure's idea of what `mule-lisp-directory' will be. +*/ ); +#ifdef PATH_MULELOADSEARCH + Vconfigure_mule_lisp_directory = Ffile_name_as_directory + (build_string ((char *) PATH_MULELOADSEARCH)); +#else + Vconfigure_mule_lisp_directory = Qnil; +#endif + + DEFVAR_LISP ("utf-2000-lisp-directory", &Vutf_2000_lisp_directory /* +*Directory of UTF-2000 Lisp files that come with XEmacs. +*/ ); + Vutf_2000_lisp_directory = Qnil; + + DEFVAR_LISP ("configure-utf-2000-lisp-directory", + &Vconfigure_utf_2000_lisp_directory /* +For internal use by the build procedure only. +configure's idea of what `utf-2000-lisp-directory' will be. +*/ ); +#ifdef PATH_UTF2000LOADSEARCH + Vconfigure_utf_2000_lisp_directory = Ffile_name_as_directory + (build_string ((char *) PATH_UTF2000LOADSEARCH)); +#else + Vconfigure_utf_2000_lisp_directory = Qnil; +#endif + + DEFVAR_LISP ("module-directory", &Vmodule_directory /* +*Directory of core dynamic modules that come with XEmacs. +*/ ); + Vmodule_directory = Qnil; + + DEFVAR_LISP ("configure-module-directory", &Vconfigure_module_directory /* +For internal use by the build procedure only. +configure's idea of what `module-directory' will be. +*/ ); +#ifdef PATH_MODULESEARCH + Vconfigure_module_directory = Ffile_name_as_directory + (build_string ((char *) PATH_MODULESEARCH)); +#else + Vconfigure_module_directory = Qnil; +#endif + DEFVAR_LISP ("configure-package-path", &Vconfigure_package_path /* For internal use by the build procedure only. configure's idea of what the package path will be. @@ -2929,13 +3896,14 @@ configure's idea of what the package path will be. *Directory of architecture-independent files that come with XEmacs, intended for XEmacs to use. Use of this variable in new code is almost never correct. See the -function `locate-data-directory' and the variable `data-directory-list'. +functions `locate-data-file' and `locate-data-directory' and the variable +`data-directory-list'. */ ); Vdata_directory = Qnil; DEFVAR_LISP ("configure-data-directory", &Vconfigure_data_directory /* For internal use by the build procedure only. -configure's idea of what DATA-DIRECTORY will be. +configure's idea of what `data-directory' will be. */ ); #ifdef PATH_DATA Vconfigure_data_directory = Ffile_name_as_directory @@ -2950,19 +3918,6 @@ or were installed as packages, and are intended for XEmacs to use. */ ); Vdata_directory_list = Qnil; -#ifdef CLASH_DETECTION - DEFVAR_LISP ("configure-lock-directory", &Vconfigure_lock_directory /* -For internal use by the build procedure only. -configure's idea of what LOCK-DIRECTORY will be. -*/ ); -#ifdef PATH_LOCK - Vconfigure_lock_directory = Ffile_name_as_directory - (build_string ((char *) PATH_LOCK)); -#else - Vconfigure_lock_directory = Qnil; -#endif -#endif /* CLASH_DETECTION */ - DEFVAR_LISP ("site-directory", &Vsite_directory /* *Directory of site-specific Lisp files that come with XEmacs. */ ); @@ -2970,7 +3925,7 @@ configure's idea of what LOCK-DIRECTORY will be. DEFVAR_LISP ("configure-site-directory", &Vconfigure_site_directory /* For internal use by the build procedure only. -configure's idea of what SITE-DIRECTORY will be. +configure's idea of what `site-directory' will be. */ ); #ifdef PATH_SITE Vconfigure_site_directory = Ffile_name_as_directory @@ -2979,15 +3934,31 @@ configure's idea of what SITE-DIRECTORY will be. Vconfigure_site_directory = Qnil; #endif + DEFVAR_LISP ("site-module-directory", &Vsite_module_directory /* +*Directory of site-specific loadable modules that come with XEmacs. +*/ ); + Vsite_module_directory = Qnil; + + DEFVAR_LISP ("configure-site-module-directory", &Vconfigure_site_module_directory /* +For internal use by the build procedure only. +configure's idea of what `site-directory' will be. +*/ ); +#ifdef PATH_SITE_MODULES + Vconfigure_site_module_directory = Ffile_name_as_directory + (build_string ((char *) PATH_SITE_MODULES)); +#else + Vconfigure_site_module_directory = Qnil; +#endif + DEFVAR_LISP ("doc-directory", &Vdoc_directory /* *Directory containing the DOC file that comes with XEmacs. -This is usually the same as exec-directory. +This is usually the same as `exec-directory'. */ ); Vdoc_directory = Qnil; DEFVAR_LISP ("configure-doc-directory", &Vconfigure_doc_directory /* For internal use by the build procedure only. -configure's idea of what DOC-DIRECTORY will be. +configure's idea of what `doc-directory' will be. */ ); #ifdef PATH_DOC Vconfigure_doc_directory = Ffile_name_as_directory @@ -2998,7 +3969,7 @@ configure's idea of what DOC-DIRECTORY will be. DEFVAR_LISP ("configure-exec-prefix-directory", &Vconfigure_exec_prefix_directory /* For internal use by the build procedure only. -configure's idea of what EXEC-PREFIX-DIRECTORY will be. +configure's idea of what `exec-prefix-directory' will be. */ ); #ifdef PATH_EXEC_PREFIX Vconfigure_exec_prefix_directory = Ffile_name_as_directory @@ -3009,7 +3980,7 @@ configure's idea of what EXEC-PREFIX-DIRECTORY will be. DEFVAR_LISP ("configure-prefix-directory", &Vconfigure_prefix_directory /* For internal use by the build procedure only. -configure's idea of what PREFIX-DIRECTORY will be. +configure's idea of what `prefix-directory' will be. */ ); #ifdef PATH_PREFIX Vconfigure_prefix_directory = Ffile_name_as_directory @@ -3041,14 +4012,16 @@ The configured initial path for info documentation. #endif } -#ifdef __sgi +#if defined(__sgi) && !defined(PDUMP) /* This is so tremendously ugly I'd puke. But then, it works. * The target is to override the static constructor from the - * libiflPNG.so library which is maskerading as libz, and + * libiflPNG.so library which is masquerading as libz, and * cores on us when re-started from the dumped executable. * This will have to go for 21.1 -- OG. */ -void __sti__iflPNGFile_c___() +void __sti__iflPNGFile_c___ (void); +void +__sti__iflPNGFile_c___ (void) { }