diff src/emacs.c @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children ac2d302a0011
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/emacs.c	Mon Aug 13 08:45:50 2007 +0200
@@ -0,0 +1,1950 @@
+/* XEmacs -- Fully extensible Emacs, running on Unix and other platforms.
+   Copyright (C) 1985, 1986, 1987, 1992, 1993, 1994
+   Free Software Foundation, Inc.
+   Copyright (C) 1995 Sun Microsystems, Inc.
+
+This file is part of XEmacs.
+
+XEmacs is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with XEmacs; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* Synched up with: Mule 2.0, FSF 19.28. */
+
+/* Note: It is necessary to specify <config.h> 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
+   the build dir, will be used. */
+
+#include <config.h>
+#include "lisp.h"
+
+#include "backtrace.h" /* run-emacs-from-temacs needs this */
+#include "buffer.h"
+#include "commands.h"
+#include "console.h"
+#include "process.h"
+#include "sysdep.h"
+
+#include <setjmp.h>
+#include "syssignal.h" /* Always include before systty.h */
+#include "systty.h"
+#include "sysfile.h"
+#include "systime.h"
+
+#if defined (I18N2) || defined (I18N3) || defined (I18N4)
+#include <locale.h>
+#endif
+
+#ifdef TOOLTALK
+#include <tt_c.h>
+#endif
+
+#ifdef VMS
+#include <ssdef.h>
+#endif
+
+#ifdef APOLLO
+#ifndef APOLLO_SR10
+#include <default_acl.h>
+#endif
+#endif
+
+extern void memory_warnings (void *, void (*warnfun) (CONST char *));
+
+/* Command line args from shell, as list of strings */
+Lisp_Object Vcommand_line_args;
+
+/* Set nonzero after XEmacs has started up the first time.
+  Prevents reinitialization of the Lisp world and keymaps
+  on subsequent starts.  */
+int initialized;
+
+/* Variable whose value is symbol giving operating system type. */
+Lisp_Object Vsystem_type;
+
+/* Variable whose value is string giving configuration built for.  */
+Lisp_Object Vsystem_configuration;
+  
+/* The name under which XEmacs was invoked, with any leading directory
+   names discarded.  */
+Lisp_Object Vinvocation_name;
+
+/* The directory name from which XEmacs was invoked.  */
+Lisp_Object Vinvocation_directory;
+
+#if 0 /* FSFmacs */
+/* The directory name in which to find subdirs such as lisp and etc.
+   nil means get them only from PATH_LOADSEARCH.  */
+Lisp_Object Vinstallation_directory;
+#endif
+
+/* 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;
+
+/* 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. */
+int running_asynch_code;
+
+/* If non-zero, a window-system was specified on the command line. */
+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;
+
+/* If non-zero, then the early error handler will only print the error
+   message and exit. */
+int suppress_early_backtrace;
+
+/* An address near the bottom of the stack.
+   Tells GC how to save a copy of the stack.  */
+char *stack_bottom;
+
+#ifdef USG_SHARED_LIBRARIES
+/* If nonzero, this is the place to put the end of the writable segment
+   at startup.  */
+
+unsigned int bss_end = 0;
+#endif
+
+/* Number of bytes of writable memory we can expect to be able to get */
+unsigned int lim_data;
+
+/* 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.  */
+
+int noninteractive1;
+
+/* Save argv and argc.  */
+char **initial_argv;
+int initial_argc;
+
+extern int always_gc;           /* hack */
+
+Lisp_Object Qkill_emacs_hook;
+Lisp_Object Qsave_buffers_kill_emacs;
+
+
+/* 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;
+
+static void shut_down_emacs (int sig, Lisp_Object stuff);
+
+/* Handle bus errors, illegal instruction, etc. */
+SIGTYPE
+fatal_error_signal (int sig)
+{
+  fatal_error_code = sig;
+  signal (sig, SIG_DFL);
+  /* 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);
+
+  /* If fatal error occurs in code below, avoid infinite recursion.  */
+  if (! fatal_error_in_progress)
+    {
+      fatal_error_in_progress = 1;
+      shut_down_emacs (sig, Qnil);
+#ifdef DEBUG_XEMACS
+      stderr_out("\nLisp backtrace follows:\n\n");
+      Fbacktrace(Qexternal_debugging_output, Qt);
+      
+      /* Check for Sun-style stack printing via /proc */
+      {
+        char *pstack = "/usr/proc/bin/pstack";
+        if (access(pstack, X_OK) == 0)
+          {
+            char buf[100];
+            stderr_out("\nC backtrace follows:\n"
+                       "(A real debugger may provide better information)\n\n");
+            sprintf(buf, "%s %d >&2", pstack, (int)getpid());
+            system(buf);
+          }
+      }
+#endif
+    }
+#ifdef VMS
+  LIB$STOP (SS$_ABORT);
+#else
+  /* Signal the same code; this time it will really be fatal. */
+  kill (getpid (), fatal_error_code);
+#endif /* not VMS */
+  SIGRETURN;
+}
+
+
+DOESNT_RETURN
+fatal (CONST char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+
+  fprintf (stderr, "\nXEmacs: ");
+  vfprintf (stderr, GETTEXT (fmt), args);
+  fprintf (stderr, "\n");
+
+  va_end (args);
+  fflush (stderr);
+  exit (1);
+}
+
+/* #### 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). */
+
+/* exactly equivalent to fprintf (stderr, fmt, ...) except that it calls
+   GETTEXT on the format string. */
+
+int
+stderr_out (CONST char *fmt, ...)
+{
+  int retval;
+  va_list args;
+  va_start (args, fmt);
+
+  retval = vfprintf (stderr, GETTEXT (fmt), args);
+
+  va_end (args);
+  /* fflush (stderr); */
+  return retval;
+}
+
+/* exactly equivalent to fprintf (stdout, fmt, ...) except that it calls
+   GETTEXT on the format string. */
+
+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
+
+/* Handler for SIGDANGER.  */
+SIGTYPE
+memory_warning_signal (int sig)
+{
+  /* #### bad bad bad; this function shouldn't do anything except
+     set a flag, or weird corruption could happen. */
+  signal (sig, memory_warning_signal);
+
+  malloc_warning
+    (GETTEXT ("Operating system warns that virtual memory is running low.\n"));
+
+  /* It might be unsafe to call do_auto_save now.  */
+  force_auto_save_soon ();
+}
+#endif
+
+/* 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)
+{
+  Lisp_Object result = Qnil;
+  REGISTER int i;
+
+  for (i = argc - 1; i >= 0; i--)
+    {
+      if (i == 0 || i > skip_args)
+	result = Fcons (build_ext_string (argv [i], FORMAT_OS), result);
+    }
+  return result;
+}
+
+Lisp_Object
+make_arg_list (int argc, char **argv)
+{
+  return make_arg_list_1 (argc, argv, 0);
+}
+
+/* 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)
+{
+  Lisp_Object next;
+  int n = XINT (Flength (argv_list));
+  REGISTER int i;
+  *argv = (char**) xmalloc ((n+1) * sizeof (char*));
+
+  for (i = 0, next = argv_list; i < n; i++, next = XCDR (next))
+    {
+      CONST char *temp;
+      CHECK_STRING (XCAR (next));
+      
+      GET_C_STRING_EXT_DATA_ALLOCA (XCAR (next), FORMAT_OS, temp);
+      (*argv) [i] = xstrdup (temp);
+    }
+  (*argv) [n] = 0;
+  *argc = i;
+}
+
+void
+free_argc_argv (char **argv)
+{
+  int elt = 0;
+
+  while (argv[elt])
+    {
+      xfree (argv[elt]);
+      elt++;
+    }
+  xfree (argv);
+}
+
+static void
+init_cmdargs (int argc, char **argv, int skip_args)
+{
+  initial_argv = argv;
+  initial_argc = argc;
+
+  Vcommand_line_args = make_arg_list_1 (argc, argv, skip_args);
+}
+
+DEFUN ("invocation-name", Finvocation_name, Sinvocation_name, 0, 0, 0 /*
+Return the program name that was used to run XEmacs.
+Any directory names are omitted.
+*/ )
+  ()
+{
+  return Fcopy_sequence (Vinvocation_name);
+}
+
+
+#ifdef I18N4
+				/* #### - don't know why I18N4 on SunOS/JLE
+				   can't deal with this.  It's a potential
+				   bug that needs to be looked at. */
+# undef RUN_TIME_REMAP
+#endif
+
+static DOESNT_RETURN
+main_1 (int argc, char **argv, char **envp)
+{
+  char stack_bottom_variable;
+  int skip_args = 0;
+  Lisp_Object load_me;
+  int inhibit_window_system;
+
+#ifdef NeXT
+  extern int malloc_cookie;
+  
+  /* 19-Jun-1995 -baw
+   * NeXT secret magic, ripped from Emacs-for-NS by Carl Edman
+   * <cedman@princton.edu>.  Note that even Carl doesn't know what this
+   * does; it was provided by NeXT, and it presumable makes NS's mallocator
+   * work with dumping.  But malloc_jumpstart() and malloc_freezedry() in
+   * unexnext.c are both completely undocumented, even in NS header files!
+   * But hey, it solves all NS related memory problems, so who's
+   * complaining?
+   */
+  if (initialized)
+    if (malloc_jumpstart (malloc_cookie) != 0)
+      printf ("malloc jumpstart failed!\n");
+#endif /* NeXT */
+
+#if defined (GNU_MALLOC) && defined (ERROR_CHECK_MALLOC)
+#if 0
+  if (!initialized)
+    init_free_hook ();
+#endif
+#endif
+
+  /* Map in shared memory, if we are using that.  */
+#ifdef HAVE_SHM
+  if (argc > 1 && !strcmp (argv[1], "-nl"))
+    {
+      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
+
+#ifdef VMS
+  /* If -map specified, map the data file in */
+  if (argc > 2 && ! strcmp (argv[1], "-map"))
+    {
+      skip_args = 2;
+      mapin_data (argv[2]);
+    }
+
+#ifdef LINK_CRTL_SHARE
+#ifdef SHAREABLE_LIB_BUG
+  /* Bletcherous shared libraries! */
+  if (!stdin)
+    stdin = fdopen (0, "r");
+  if (!stdout)
+    stdout = fdopen (1, "w");
+  if (!stderr)
+    stderr = fdopen (2, "w");
+  if (!environ)
+    environ = envp;
+#endif /* SHAREABLE_LIB_BUG */
+#endif /* LINK_CRTL_SHARE */
+#endif /* VMS */
+#if (defined (MSDOS) && defined (EMX)) || defined (WIN32) || defined (_SCO_DS)
+  environ = envp;
+#endif
+
+  /* Record (approximately) where the stack begins.  */
+  stack_bottom = &stack_bottom_variable;
+
+#ifdef RUN_TIME_REMAP
+  if (initialized)
+    run_time_remap (argv[0]);
+#endif
+
+#ifdef USG_SHARED_LIBRARIES
+  if (bss_end)
+    brk ((void *) bss_end);
+#endif
+
+  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 ();
+#endif
+
+#ifdef HAVE_SOCKS
+  if (initialized)
+    SOCKSinit (argv[0]);
+#endif /* HAVE_SOCKS */
+
+#ifndef SYSTEM_MALLOC
+
+  if (!initialized)
+    {
+      /* Arrange to get warning messages as memory fills up.  */
+      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);
+  setuid (getuid ());
+#endif /* SET_EMACS_PRIORITY */
+
+#ifdef EXTRA_INITIALIZE
+  EXTRA_INITIALIZE;
+#endif
+
+#ifdef HAVE_WINDOW_SYSTEM
+  inhibit_window_system = 0;
+#else
+  inhibit_window_system = 1;
+#endif
+
+  /* Handle the -t switch, which specifies filename to use as terminal */
+  if (skip_args + 2 < argc && !strcmp (argv[skip_args + 1], "-t"))
+    {
+      int result;
+
+      skip_args += 2;
+      close (0);
+      close (1);
+      result = open (argv[skip_args], O_RDWR, 2 );
+      if (result < 0)
+	{
+	  fatal ("%s: %s", argv[skip_args], strerror (errno));
+	}
+      dup (0);
+      if (! isatty (0))
+	fatal ("%s: not a tty", argv[skip_args]);
+
+      stderr_out ("Using %s", ttyname (0));
+#if 0
+      stderr_out ("Using %s", argv[skip_args]);
+#endif
+      inhibit_window_system = 1;	/* -t => -nw */
+    }
+
+  if (skip_args + 1 < argc
+      && (!strcmp (argv[skip_args + 1], "-nw")))
+    {
+      skip_args += 1;
+      inhibit_window_system = 1;
+    }
+
+  /* Handle the -batch switch, which means don't do interactive display.  */
+  noninteractive = 0;
+  if (skip_args + 1 < argc &&
+      (!strcmp (argv[skip_args + 1], "-batch") ||
+       !strcmp (argv[skip_args + 1], "--batch")))
+    {
+      skip_args += 1;
+      noninteractive = 1;
+    }
+
+  /* Partially handle the -version and -help switches: they imply -batch,
+     but are not removed from the list.
+   */
+  if (skip_args + 1 < argc &&
+      (!strcmp (argv[skip_args + 1], "-version") ||
+       !strcmp (argv[skip_args + 1], "--version") ||
+       !strcmp (argv[skip_args + 1], "-help") ||
+       !strcmp (argv[skip_args + 1], "--help")))
+    noninteractive = 1;
+
+  /* Now, figure out which type of console is our first console. */
+
+  display_arg = 0;
+
+  if (noninteractive)
+    display_use = "stream";
+  else
+    display_use = "tty";
+
+#ifndef HAVE_TTY
+  if (inhibit_window_system)
+    fatal ("Sorry, this XEmacs was not compiled with TTY support");
+#endif
+
+#ifdef HAVE_WINDOW_SYSTEM
+  /* Stupid kludge to catch command-line display spec.  We can't
+     handle this argument entirely in window system dependent code
+     because we don't even know which window system dependent code
+     to run until we've recognized this argument.  */
+  if (!inhibit_window_system && !noninteractive)
+    {
+      int i;
+      char *disp;
+      
+      for (i = 1; (i < argc && !display_arg); i++)
+	{
+#ifdef HAVE_X_WINDOWS
+	  if (!strcmp (argv[i], "-d") || !strcmp (argv[i], "-display"))
+	    {
+	      display_arg = 1;
+	      display_use = "x";
+	    }
+#endif /* HAVE_X_WINDOWS */
+#ifdef HAVE_NEXTSTEP
+	  if (!strcmp (argv[i], "-NXHost") || !strcmp (argv[i], "-MachLaunch"))
+	    {
+	      display_arg = 1;
+	      display_use = "ns";
+	    }
+#endif /* HAVE_NEXTSTEP */
+	}
+      
+#ifdef HAVE_X_WINDOWS
+      disp = getenv ("DISPLAY");
+
+      /* null string doesn't count as a display */
+      if (disp && disp[0])
+	display_use = "x";
+
+      /* Do not set display_arg here.  It is only to be set if the display
+	 was specified on the command line. */
+#endif
+    }
+#endif /* HAVE_WINDOW_SYSTEM */
+
+  noninteractive1 = noninteractive;
+
+  /****** Now initialize everything *******/
+
+  /* First, do really basic environment initialization -- catching signals
+     and the like.  These functions have no dependence on any part of
+     the Lisp engine and need to be done both at dump time and at run time. */
+
+  init_signals_very_early ();
+  init_data_very_early (); /* Catch math errors. */
+#ifdef LISP_FLOAT_TYPE
+  init_floatfns_very_early (); /* Catch floating-point math errors. */
+#endif
+  init_process_times_very_early (); /* Initialize our process timers.
+				       As early as possible, of course,
+				       so we can be fairly accurate. */
+  init_intl_very_early (); /* set up the locale and domain for gettext and
+			      such. */
+
+  /* Now initialize the Lisp engine and the like.  Done only during
+     dumping.  No dependence on anything that may be in the user's
+     environment when the dumped XEmacs is run.
+
+     We try to do things in an order that minimizes the non-obvious
+     dependencies between functions. */
+
+  if (!initialized)
+    {
+      /* Initialize things so that new Lisp objects
+	 can be created and objects can be staticpro'd.
+	 Must be basically the very first thing done
+	 because pretty much all of the initialization
+	 routines below create new objects. */
+      init_alloc_once_early ();
+
+      /* Initialize Qnil, Qt, Qunbound, and the
+	 obarray.  After this, symbols can be
+	 interned.  This depends on init_alloc_once(). */
+      init_symbols_once_early ();
+
+      /* Declare the basic symbols pertaining to errors,
+	 So that deferror() can be called. */
+      init_errors_once_early ();
+
+      /* Make sure that opaque pointers can be created. */
+      init_opaque_once_early ();
+
+      /* 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:
+
+	 defsymbol()
+	 defsubr()
+	 deferror()
+	 defkeyword()
+
+	 Order does not matter in these functions.
+	 */
+
+      syms_of_abbrev ();
+      syms_of_alloc ();
+      syms_of_buffer ();
+      syms_of_bytecode ();
+      syms_of_callint ();
+      syms_of_callproc ();
+      syms_of_casefiddle ();
+      syms_of_casetab ();
+      syms_of_cmdloop ();
+      syms_of_cmds ();
+      syms_of_console ();
+      syms_of_data ();
+#ifdef DEBUG_XEMACS
+      syms_of_debug ();
+#endif /* DEBUG_XEMACS */
+      syms_of_device ();
+#ifdef HAVE_DIALOGS
+      syms_of_dialog ();
+#endif
+      syms_of_dired ();
+      syms_of_doc ();
+      syms_of_editfns ();
+      syms_of_elhash ();
+      syms_of_emacs ();
+      syms_of_eval ();
+      syms_of_event_stream ();
+      syms_of_events ();
+      syms_of_extents ();
+      syms_of_faces ();
+      syms_of_fileio ();
+#ifdef CLASH_DETECTION
+      syms_of_filelock ();
+#endif /* CLASH_DETECTION */
+      syms_of_floatfns ();
+      syms_of_fns ();
+      syms_of_font_lock ();
+      syms_of_frame ();
+      syms_of_general ();
+      syms_of_glyphs ();
+#if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS)
+      syms_of_gui ();
+#endif
+      syms_of_indent ();
+      syms_of_intl ();
+      syms_of_keymap ();
+      syms_of_lread ();
+      syms_of_macros ();
+      syms_of_marker ();
+      syms_of_md5 ();
+#ifdef HAVE_DATABASE
+      syms_of_dbm ();
+#endif
+#ifdef HAVE_MENUBARS
+      syms_of_menubar ();
+#endif
+      syms_of_minibuf ();
+#ifdef MOCKLISP_SUPPORT
+      syms_of_mocklisp ();
+#endif
+      syms_of_objects ();
+      syms_of_print ();
+#if !defined (NO_SUBPROCESSES)
+      syms_of_process ();
+#endif
+      syms_of_profile ();
+#if defined (HAVE_MMAP) && defined (REL_ALLOC)
+      syms_of_ralloc ();
+#endif /* HAVE_MMAP && REL_ALLOC */
+      syms_of_rangetab ();
+      syms_of_redisplay ();
+      syms_of_search ();
+      syms_of_signal ();
+      syms_of_sound ();
+      syms_of_specifier ();
+      syms_of_symbols ();
+      syms_of_syntax ();
+#ifdef HAVE_SCROLLBARS
+      syms_of_scrollbar ();
+#endif
+#ifdef HAVE_TOOLBARS
+      syms_of_toolbar ();
+#endif
+      syms_of_undo ();
+      syms_of_window ();
+#ifdef HAVE_TTY
+      syms_of_console_tty ();
+      syms_of_device_tty ();
+      syms_of_objects_tty ();
+#endif
+#ifdef HAVE_X_WINDOWS
+      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 ();
+#ifdef EPOCH
+      syms_of_epoch ();
+#endif
+#if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS)
+      syms_of_gui_x ();
+#endif
+#endif /* HAVE_X_WINDOWS */
+
+#ifdef HAVE_NEXTSTEP
+      syms_of_device_ns ();
+      syms_of_frame_ns ();
+      syms_of_glyphs_ns ();
+      syms_of_objects_ns ();
+#ifdef HAVE_MENUBARS
+      syms_of_menubar_ns ();
+#endif
+      syms_of_nsselect ();
+#ifdef HAVE_SCROLLBARS
+      syms_of_scrollbar_ns ();
+#endif
+#endif /* HAVE_NEXTSTEP */
+
+#ifdef SYMS_SYSTEM
+      SYMS_SYSTEM;
+#endif
+
+#ifdef SYMS_MACHINE
+      SYMS_MACHINE;
+#endif
+
+#ifdef EMACS_BTL
+      syms_of_btl (); 
+#endif
+
+#ifdef ENERGIZE
+      syms_of_energize ();
+#endif
+
+#if defined (GNU_MALLOC) && defined (ERROR_CHECK_MALLOC)
+#if 0
+      syms_of_free_hook ();
+#endif
+#endif
+
+#ifdef TOOLTALK
+      syms_of_tooltalk ();
+#endif
+
+#ifdef SUNPRO
+      syms_of_sunpro ();
+#endif
+
+      /* Now create the subtypes for the types that have them.
+	 We do this before the vars_*() because more symbols
+	 may get initialized here. */
+
+      /* Now initialize the console types and associated symbols.
+         Other than the first function below, the functions may
+	 make exactly the following function/macro calls:
+
+	 INITIALIZE_CONSOLE_TYPE()
+	 CONSOLE_HAS_METHOD()
+
+	 For any given console type, the former macro must be called
+	 before the any calls to the latter macro. */
+
+      console_type_create ();
+
+      console_type_create_stream ();
+
+#ifdef HAVE_TTY
+      console_type_create_tty ();
+      console_type_create_device_tty ();
+      console_type_create_frame_tty ();
+      console_type_create_objects_tty ();
+      console_type_create_redisplay_tty ();
+#endif
+
+#ifdef HAVE_X_WINDOWS
+      console_type_create_x ();
+      console_type_create_device_x ();
+      console_type_create_frame_x ();
+      console_type_create_glyphs_x ();
+#ifdef HAVE_MENUBARS
+      console_type_create_menubar_x ();
+#endif
+      console_type_create_objects_x ();
+      console_type_create_redisplay_x ();
+#ifdef HAVE_SCROLLBARS
+      console_type_create_scrollbar_x ();
+#endif
+#ifdef HAVE_TOOLBARS
+      console_type_create_toolbar_x ();
+#endif
+#endif /* HAVE_X_WINDOWS */
+
+      /* Now initialize the specifier types and associated symbols.
+         Other than the first function below, the functions may
+	 make exactly the following function/macro calls:
+
+	 INITIALIZE_SPECIFIER_TYPE()
+	 SPECIFIER_HAS_METHOD()
+
+	 For any given specifier type, the former macro must be called
+	 before the any calls to the latter macro. */
+
+      specifier_type_create ();
+
+      specifier_type_create_image ();
+      specifier_type_create_objects ();
+#ifdef HAVE_TOOLBARS
+      specifier_type_create_toolbar ();
+#endif
+
+      /* Now initialize the structure types and associated symbols.
+	 Other than the first function below, the functions may
+	 make exactly the following function/macro calls:
+
+	 define_structure_type()
+	 define_structure_type_keyword()
+
+	 */
+
+      structure_type_create ();
+
+      structure_type_create_faces ();
+      structure_type_create_rangetab ();
+
+      /* Now initialize the image instantiator formats and associated symbols.
+         Other than the first function below, the functions may
+	 make exactly the following function/macro calls:
+
+	 INITIALIZE_IMAGE_INSTANTIATOR_FORMAT()
+	 IIFORMAT_HAS_METHOD()
+	 IIFORMAT_VALID_KEYWORD()
+
+	 For any given image instantiator format, the first macro must be
+	 called before the any calls to the other macros. */
+
+      image_instantiator_format_create ();
+#ifdef HAVE_X_WINDOWS
+      image_instantiator_format_create_glyphs_x ();
+#endif /* HAVE_X_WINDOWS */
+
+      /* Now initialize the lstream types and associated symbols.
+	 Other than the first function below, the functions may
+	 make exactly the following function/macro calls:
+
+	 LSTREAM_HAS_METHOD()
+
+	 */
+
+      lstream_type_create ();
+      lstream_type_create_print ();
+
+      /* Now initialize most variables.
+
+	 These functions may do exactly the following:
+
+	 DEFVAR_INT()
+	 DEFVAR_LISP()
+	 DEFVAR_BOOL()
+	 DEFER_GETTEXT()
+	 Dynarr_*()
+	 Blocktype_*()
+	 staticpro()
+	 Fprovide(symbol)
+	 intern()
+	 pure_put()
+	 xmalloc()
+	 defsymbol(), if it's absolutely necessary and you're sure that
+	   the symbol isn't referenced anywhere else in the initialization
+	   code
+	 Fset() on a symbol that is unbound
+	 assigning a symbol or constant value to a variable
+	 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.
+
+	 make_pure_*()
+	 Fpurecopy()
+	 make_string()
+	 build_string()
+	 make_vector()
+	 make_int()
+	 make_extent()
+	 alloc_lcrecord()
+	 Fcons()
+	 listN()
+	 make_opaque_ptr()
+	 make_opaque_long()
+
+	 perhaps a few others.
+       */
+
+      /* Now allow Fprovide() statements to be made. */
+      init_provide_once ();
+
+      vars_of_abbrev ();
+      vars_of_alloc ();
+      vars_of_buffer ();
+      vars_of_bytecode ();
+      vars_of_callint ();
+      vars_of_callproc ();
+      vars_of_cmdloop ();
+      vars_of_cmds ();
+      vars_of_console ();
+      vars_of_data ();
+#ifdef DEBUG_XEMACS
+      vars_of_debug ();
+#endif
+      vars_of_console_stream ();
+      vars_of_device ();
+#ifdef HAVE_DIALOGS
+      vars_of_dialog ();
+#endif
+      vars_of_dired ();
+      vars_of_doc ();
+      vars_of_editfns ();
+      vars_of_elhash ();
+      vars_of_emacs ();
+      vars_of_eval ();
+      vars_of_event_stream ();
+      vars_of_events ();
+      vars_of_extents ();
+      vars_of_faces ();
+      vars_of_fileio ();
+#ifdef CLASH_DETECTION
+      vars_of_filelock ();
+#endif
+      vars_of_floatfns ();
+      vars_of_font_lock ();
+      vars_of_frame ();
+      vars_of_glyphs ();
+#if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS)
+      vars_of_gui ();
+#endif
+      vars_of_indent ();
+      vars_of_insdel ();
+      vars_of_intl ();
+      vars_of_keymap ();
+      vars_of_lread ();
+      vars_of_lstream ();
+      vars_of_macros ();
+      vars_of_md5 ();
+#ifdef HAVE_DATABASE
+      vars_of_dbm ();
+#endif
+#ifdef HAVE_MENUBARS
+      vars_of_menubar ();
+#endif
+      vars_of_minibuf ();
+#ifdef MOCKLISP_SUPPORT
+      vars_of_mocklisp ();
+#endif
+      vars_of_objects ();
+      vars_of_print ();
+#ifndef NO_SUBPROCESSES
+      vars_of_process ();
+#endif
+      vars_of_profile ();
+#if defined (HAVE_MMAP) && defined (REL_ALLOC)
+      vars_of_ralloc ();
+#endif /* HAVE_MMAP && REL_ALLOC */
+      vars_of_redisplay ();
+#ifdef HAVE_SCROLLBARS
+      vars_of_scrollbar ();
+#endif
+      vars_of_search ();
+      vars_of_sound ();
+      vars_of_specifier ();
+      vars_of_symbols ();
+      vars_of_syntax ();
+#ifdef HAVE_TOOLBARS
+      vars_of_toolbar ();
+#endif
+      vars_of_undo ();
+      vars_of_window ();
+
+#ifdef HAVE_TTY
+      vars_of_console_tty ();
+      vars_of_event_tty ();
+      vars_of_frame_tty ();
+      vars_of_objects_tty ();
+#endif
+
+#ifdef HAVE_X_WINDOWS
+      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 ();
+#ifdef EPOCH
+      vars_of_epoch ();
+#endif
+#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
+
+#ifdef ENERGIZE
+      vars_of_energize ();
+#endif
+
+#ifdef TOOLTALK
+      vars_of_tooltalk ();
+#endif
+
+#ifdef SUNPRO
+      vars_of_sunpro ();
+#endif
+
+      /* Now initialize any specifier variables.  We do this later
+	 because it has some dependence on the vars initialized
+	 above.
+
+	 These functions should *only* initialize specifier variables,
+	 and may make use of the following functions/macros in addition
+	 to the ones listed above:
+
+	 DEFVAR_SPECIFIER()
+	 Fmake_specifier()
+	 set_specifier_fallback()
+	 set_specifier_caching()
+	 */
+
+      specifier_vars_of_glyphs ();
+#ifdef HAVE_MENUBARS
+      specifier_vars_of_menubar ();
+#endif
+      specifier_vars_of_redisplay ();
+#ifdef HAVE_SCROLLBARS
+      specifier_vars_of_scrollbar ();
+#endif
+#ifdef HAVE_TOOLBARS
+      specifier_vars_of_toolbar ();
+#endif
+      specifier_vars_of_window ();
+
+      /* Now comes all the rest of the variables that couldn't
+	 be handled above.  There may be dependencies on variables
+	 initialized above, and dependencies between one complex_vars_()
+	 function and another. */
+
+      /* Calls Fmake_range_table(). */
+      complex_vars_of_regex ();
+      /* Calls Fmake_range_table(). */
+      complex_vars_of_search ();
+
+      /* Calls Fmake_hashtable(). */
+      complex_vars_of_event_stream ();
+      /* Calls make_lisp_hashtable(). */
+      complex_vars_of_extents ();
+      
+      /* Depends on hashtables and specifiers. */
+      complex_vars_of_faces ();
+
+      /* This calls allocate_glyph(), which creates specifiers
+	 and also relies on a variable (Vthe_nothing_vector) initialized
+	 above. */
+      complex_vars_of_glyphs ();
+
+      /* This relies on the glyphs just created in the previous function,
+	 and calls Fadd_spec_to_specifier(), which relies on various
+	 variables initialized above. */
+#ifdef HAVE_X_WINDOWS
+      complex_vars_of_glyphs_x ();
+#endif
+
+      /* This calls Fmake_glyph_internal(). */
+      complex_vars_of_alloc ();
+
+      /* This calls Fmake_glyph_internal(). */
+#ifdef HAVE_MENUBARS
+      complex_vars_of_menubar ();
+#endif
+
+      /* This calls Fmake_glyph_internal(). */
+#ifdef HAVE_SCROLLBARS
+      complex_vars_of_scrollbar ();
+#endif
+
+      /* This calls allocate_glyph(). */
+      complex_vars_of_frame ();
+
+      /* Depends on hashtables. */
+#ifdef ENERGIZE
+      complex_vars_of_energize ();
+#endif
+
+      /* This calls set_string_char(), which (under Mule) depends on the
+	 charsets being initialized. */
+      complex_vars_of_casetab ();
+
+      /* This calls Fcopy_syntax_table(), which relies on char tables. */
+      complex_vars_of_syntax ();
+
+      /* This initializes buffer-local variables, sets things up so
+	 that buffers can be created, and creates a couple of basic
+	 buffers.  This depends on Vstandard_syntax_table and
+	 Vstandard_category_table (initialized in the previous
+	 functions), as well as a whole horde of variables that may
+	 have been initialized above. */
+      complex_vars_of_buffer ();
+
+      /* This initializes console-local variables. */
+      complex_vars_of_console ();
+
+      /* This creates a couple more buffers, and depends on the
+	 previous function. */
+      complex_vars_of_minibuf ();
+
+      /* These two might call Ffile_name_as_directory(), which
+	 might depend on all sorts of things; I'm not sure. */
+      complex_vars_of_callproc ();
+#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
+	 initialized in the vars_of_*() section) and possibly other
+	 stuff. */
+      complex_vars_of_keymap ();
+
+      if (always_gc)                /* purification debugging hack */
+	garbage_collect_1 ();
+    }
+
+  /* CONGRATULATIONS!!!  We have successfully initialized the Lisp
+     engine. */
+
+  if (initialized)
+    {
+      /* Stuff that needs to be reset at run time.  Order below should
+	 not matter. */
+      reinit_alloc ();
+      reinit_eval ();
+    }
+
+  /* Now do further initialization/setup of stuff that is not needed by the
+     syms_of_() routines.  This involves stuff that only is enabled in
+     an interactive run (redisplay, user input, etc.) and stuff that is
+     not needed until we start loading Lisp code (the reader).  A lot
+     of this stuff involves querying the current environment and needs
+     to be done both at dump time and at run time. */
+
+  init_callproc ();	/* Set up the process environment (so that egetenv
+			   works), the basic directory variables
+			   (exec-directory and so on), and stuff
+			   related to subprocesses.  This should be
+			   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_buffer (); /* Init default directory of *scratch* buffer */
+#ifdef VMS
+  init_vms_input ();	/* init_redisplay calls get_tty_device_size,
+			   that needs this */
+#endif /* VMS */
+  init_redisplay ();      /* Determine terminal type.
+			     init_sys_modes uses results */
+#ifdef VMS
+  init_vmsproc ();
+  init_vmsfns ();
+#endif /* VMS */
+  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 */
+  init_xemacs_process (); /* set up for calling subprocesses */
+#ifdef SUNPRO
+  init_sunpro (); /* Set up Sunpro usage tracking */
+#endif
+#if defined (HAVE_NATIVE_SOUND) && defined (hp9000s800)
+  init_hpplay ();
+#endif
+#ifdef HAVE_TTY
+  init_device_tty ();
+#endif
+#ifdef HAVE_GIF
+  init_gif_err ();
+#endif
+  init_console_stream (); /* Create the first console */
+
+  /* try to get the actually pathname of the exec file we are running */
+  {
+    Vinvocation_name = Fcar (Vcommand_line_args);
+    Vinvocation_directory = Vinvocation_name;
+
+    if (!NILP (Ffile_name_directory (Vinvocation_name)))
+      /* invocation-name includes a directory component -- presumably it
+         is relative to cwd, not $PATH */
+      Vinvocation_directory = Fexpand_file_name (Vinvocation_name,
+					   Qnil);
+    else
+      locate_file (Vexec_path, Vinvocation_name, EXEC_SUFFIXES,
+		   &Vinvocation_directory, X_OK);
+
+    if (NILP (Vinvocation_directory))
+      Vinvocation_directory = Vinvocation_name;
+
+    Vinvocation_name = Ffile_name_nondirectory (Vinvocation_directory);
+    Vinvocation_directory = Ffile_name_directory (Vinvocation_directory);
+  }
+
+#if defined (LOCALTIME_CACHE) && defined (HAVE_TZSET)
+  /* sun's localtime() has a bug.  it caches the value of the time
+     zone rather than looking it up every time.  Since localtime() is
+     called to bolt the undumping time into the undumped emacs, this
+     results in localtime() ignoring the TZ environment variable.
+     This flushes the new TZ value into localtime(). */
+  tzset ();
+#endif /* LOCALTIME_CACHE and TZSET */
+
+  load_me = Qnil;
+  if (!initialized)
+    {
+      /* Handle -l loadup-and-dump, args passed by Makefile. */
+      if (argc > 2 + skip_args && !strcmp (argv[1 + skip_args], "-l"))
+        load_me = build_string (argv[2 + skip_args]);
+#ifdef CANNOT_DUMP
+      /* Unless next switch is -nl, load "loadup.el" first thing.  */
+      if (!(argc > 1 + skip_args && !strcmp (argv[1 + skip_args], "-nl")))
+	load_me = build_string ("loadup.el");
+#endif /* CANNOT_DUMP */
+    }
+
+#ifdef QUANTIFY
+  if (initialized)
+    quantify_start_recording_data ();
+#endif /* QUANTIFY */
+
+  initialized = 1;
+
+  /* This never returns.  */
+  initial_command_loop (load_me);
+  /* NOTREACHED */
+}
+
+static JMP_BUF run_temacs_catch;
+
+static int run_temacs_argc;
+static char **run_temacs_argv;
+static char *run_temacs_args;
+static int run_temacs_argv_size;
+static int run_temacs_args_size;
+
+extern int gc_in_progress;
+
+DEFUN ("running-temacs-p",
+       Frunning_temacs_p, Srunning_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
+becomes false once `run-emacs-from-temacs' is run.
+*/ )
+  ()
+{
+  return run_temacs_argc >= 0 ? Qt : Qnil;
+}
+
+DEFUN ("run-emacs-from-temacs",
+       Frun_emacs_from_temacs, Srun_emacs_from_temacs, 0, MANY, 0 /*
+Do not call this.  It will reinitialize your XEmacs.  You'll be sorry.
+*/ )
+/* If this function is called from startup.el, it will be possible to run
+   temacs as an editor using 'temacs -batch -l loadup.el run-temacs', instead
+   of having to dump an emacs and then run that (when debugging emacs itself,
+   this can be much faster). [Actually, the speed difference isn't that
+   much as long as your filesystem is local, and you don't end up with
+   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.
+ */
+    (nargs, args)
+    int nargs;
+    Lisp_Object *args;
+{
+  int ac;
+  Extbyte *wampum;
+  int namesize;
+  int total_len;
+  Lisp_Object orig_invoc_name = Fcar (Vcommand_line_args);
+  Extbyte **wampum_all = (Extbyte **) alloca (nargs * sizeof (Extbyte *));
+  int *wampum_all_len = (int *) alloca (nargs * sizeof (int));
+
+  assert (!gc_in_progress);
+
+  if (run_temacs_argc < 0)
+    error ("I've lost my temacs-hood.");
+
+  /* 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);
+  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]);
+      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 *);
+
+  memcpy (run_temacs_args, wampum, namesize);
+  run_temacs_argv [0] = run_temacs_args;
+  for (ac = 0; ac < nargs; ac++)
+    {
+      memcpy (run_temacs_args + namesize,
+	      wampum_all[ac], wampum_all_len[ac]);
+      run_temacs_argv [ac + 1] = run_temacs_args + namesize;
+      namesize += wampum_all_len[ac];
+    }
+  run_temacs_argv [nargs + 1] = 0;
+  catchlist = NULL; /* Important!  Otherwise free_cons() calls in
+		       condition_case_unwind() may lead to GC death. */
+  unbind_to (0, Qnil); /* this closes loadup.el */
+  purify_flag = 0;
+  run_temacs_argc = nargs + 1;
+  report_pure_usage (1, 0);
+  LONGJMP (run_temacs_catch, 1);
+  return Qnil; /* not reached; warning suppression */
+}
+
+/* ARGSUSED */
+DOESNT_RETURN
+main (int argc, char **argv, char **envp)
+{
+#ifdef QUANTIFY
+  quantify_stop_recording_data ();
+  quantify_clear_data ();
+#endif /* QUANTIFY */
+
+  suppress_early_backtrace = 0;
+  lim_data = 0; /* force reinitialization of this variable */
+
+  if (sizeof (Lisp_Object) != sizeof (void *))
+    abort (); /* Lisp_Object must fit in a word;
+		 check VALBITS and GCTYPEBITS */
+  if (!initialized)
+  {
+    run_temacs_argc = 0;
+    if (! SETJMP (run_temacs_catch))
+      main_1 (argc, argv, envp);
+    /* run-emacs-from-temacs called */
+    argc = run_temacs_argc;
+    run_temacs_argc = 0;
+    argv = run_temacs_argv;
+#ifdef _SCO_DS
+    /*
+    This makes absolutely no sense to anyone involved.
+    There are several people using this stuff.  We've
+    compared versions on everything we can think of.  We
+    can find no difference.  However, on both my systems
+    environ is a plain old global variable initialized to
+    zero.  _environ is the one that contains pointers to
+    the actual environment.
+    Since we can't figure out the difference (and we're
+    hours away from a release), this takes a very cowardly
+    approach and is bracketed with both a system specific
+    preprocessor test and a runtime "do you have this
+    problem" test
+    06/20/96 robertl@dgii.com
+    */
+    {
+    extern char *_environ ;
+    if ((unsigned) environ == 0)
+      environ=_environ;
+    }
+#endif
+    envp = environ;
+  }
+  run_temacs_argc = -1;
+
+  main_1 (argc, argv, envp);
+}
+
+
+DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 1, "P" /*
+Exit the XEmacs job and kill it.  Ask for confirmation, without argument.
+If ARG is an integer, return ARG as the exit program code.
+If ARG is a string, stuff it as keyboard input.
+
+The value of `kill-emacs-hook', if not void,
+is a list of functions (of no args),
+all of which are called before XEmacs is actually killed.
+*/ )
+  (arg)
+     Lisp_Object arg;
+{
+  /* This function can GC */
+  struct gcpro gcpro1;
+
+  GCPRO1 (arg);
+
+  if (feof (stdin))
+    arg = Qt;
+
+  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;
+
+  if (!preparing_for_armageddon)
+    {
+      Lisp_Object concons;
+
+      /* Normally, go ahead and delete all the consoles now.
+	 Some unmentionably lame window systems (MS Wwwww...... eek,
+	 I can't even say it) don't properly clean up after themselves,
+	 and even for those that do, it might be cleaner this way.
+	 If we're going down, however, we don't do this (might
+	 be too dangerous), and if we get a crash somewhere within
+	 this loop, we'll still autosave and won't try this again. */
+      CONSOLE_LOOP (concons)
+	delete_console_internal (XCONSOLE (XCAR (concons)), 1, 1, 0);
+    }
+
+  UNGCPRO;
+
+  shut_down_emacs (0, ((STRINGP (arg)) ? arg : Qnil));
+
+  exit ((INTP (arg)) ? XINT (arg)
+#ifdef VMS
+	: 1
+#else
+	: 0
+#endif
+	);
+  /* NOTREACHED */
+  return Qnil; /* I'm sick of the compiler warning */
+}
+
+/* Perform an orderly shutdown of XEmacs.  Autosave any modified
+   buffers, kill any child processes, clean up the terminal modes (if
+   we're in the foreground), and other stuff like that.  Don't perform
+   any redisplay; this may be called when XEmacs is shutting down in
+   the background, or after its X connection has died.
+
+   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.  */
+static void
+shut_down_emacs (int sig, Lisp_Object stuff)
+{
+  /* 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;
+
+#ifdef QUANTIFY
+  quantify_stop_recording_data ();
+#endif /* QUANTIFY */
+
+  /* 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. */
+  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);
+      stderr_out
+	("Your files have been auto-saved.\n"
+	 "Use `M-x recover-session' to recover them.\n"
+	 "\n"
+	 "Please report this bug to the address `crashes@xemacs.org'.\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 XEmacs, or maybe in your home\n"
+	 "directory), and type\n"
+	 "\n"
+	 "  gdb ");
+      {
+	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))
+	  name = (char *) string_data (XSTRING (Vinvocation_name));
+	else
+	  name = "xemacs";
+	if (GC_STRINGP (Vinvocation_directory))
+	  dir = (char *) string_data (XSTRING (Vinvocation_directory));
+	if (!dir || dir[0] != '/')
+	  stderr_out ("`which %s`", name);
+	else if (dir[strlen (dir) - 1] != '/')
+	  stderr_out ("%s/%s", dir, name);
+	else
+	  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");
+    }
+
+  stuff_buffered_input (stuff);
+
+  kill_buffer_processes (Qnil);
+
+#ifdef CLASH_DETECTION
+  unlock_all_files ();
+#endif
+
+#ifdef TOOLTALK
+  tt_session_quit (tt_default_session ());
+  tt_close ();
+#endif
+
+#ifdef VMS
+  kill_vms_processes ();
+#endif
+}
+
+
+#ifndef CANNOT_DUMP
+/* Nothing like this can be implemented on an Apollo.
+   What a loss!  */
+
+extern int my_edata;
+
+#ifdef HAVE_SHM
+
+DEFUN ("dump-emacs-data", Fdump_emacs_data, Sdump_emacs_data, 1, 1, 0 /*
+Dump current state of XEmacs into data file FILENAME.
+This function exists on systems that use HAVE_SHM.
+*/ )
+  (intoname)
+     Lisp_Object 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 (string_data (XSTRING (intoname)));
+
+  purify_flag = opurify;
+
+  return Qnil;
+}
+
+#else /* not HAVE_SHM */
+
+DEFUN ("dump-emacs", Fdump_emacs, Sdump_emacs, 2, 2, 0 /*
+Dump current state of XEmacs into executable file FILENAME.
+Take symbols from SYMFILE (presumably the file you executed to run XEmacs).
+This is used in the file `loadup.el' when building XEmacs.
+
+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)
+     Lisp_Object intoname, symname;
+{
+  /* This function can GC */
+  struct gcpro gcpro1, gcpro2;
+  int opurify;
+
+  GCPRO2 (intoname, symname);
+
+#ifdef FREE_CHECKING
+  Freally_free (Qnil);
+
+  /* When we're dumping, we can't use the debugging free() */
+
+  disable_free_hook ();
+#endif
+
+  CHECK_STRING (intoname);
+  intoname = Fexpand_file_name (intoname, Qnil);
+  if (!NILP (symname))
+    {
+      CHECK_STRING (symname);
+      if (string_length (XSTRING (symname)) > 0)
+	symname = Fexpand_file_name (symname, Qnil);
+      else
+	symname = Qnil;
+    }
+
+  opurify = purify_flag;
+  purify_flag = 0;
+
+  report_pure_usage (1, 1);
+
+  fflush (stderr);
+  fflush (stdout);
+
+  disksave_object_finalization ();
+  release_breathing_space ();
+
+#ifdef VMS
+  mapout_data (string_data (XSTRING (intoname)));
+#else
+  /* 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;
+
+#if defined (MSDOS) && defined (EMX)
+  {
+    int fd = open ((char *) string_data (XSTRING (intoname)),
+                   O_WRONLY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE);
+    if (!fd) {
+      error ("Failure operating on %s", string_data (XSTRING (intoname)));
+    } else {
+      _core (fd);
+      close (fd);
+    }
+  }
+#else /* not MSDOS and EMX */
+  {
+    CONST char *intoname_ext;
+    CONST char *symname_ext;
+
+    GET_C_STRING_FILENAME_DATA_ALLOCA (intoname, intoname_ext);
+    if (STRINGP (symname))
+      GET_C_STRING_FILENAME_DATA_ALLOCA (symname, symname_ext);
+    else
+      symname_ext = 0;
+    /* here we break our rule that the filename conversion should
+       be performed at the actual time that the system call is made.
+       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 ((char *) intoname_ext, (char *) symname_ext,
+	    (unsigned int) &my_edata,
+	    0, 0);
+  }
+#endif /* not MSDOS and EMX */
+#endif /* not VMS */
+
+  purify_flag = opurify;
+
+  return Qnil;
+}
+
+#endif /* not HAVE_SHM */
+
+#endif /* not CANNOT_DUMP */
+
+#ifndef SEPCHAR
+#define SEPCHAR ':'
+#endif
+
+Lisp_Object
+decode_env_path (CONST char *evarname, CONST char *defalt)
+{
+  REGISTER CONST char *path = 0;
+  REGISTER CONST char *p;
+  Lisp_Object lpath = Qnil;
+
+  if (evarname)
+    path = (char *) egetenv (evarname);
+  if (!path)
+    path = defalt;
+  if (!path)
+    return (Qnil);
+
+#if defined (MSDOS) || defined (WIN32)
+  dostounix_filename (path);
+#endif
+
+  while (1)
+    {
+      p = strchr (path, SEPCHAR);
+      if (!p) p = path + strlen (path);
+      lpath = Fcons (((p != path)
+                      ? make_string ((CONST Bufbyte *) path, p - path)
+                      : Qnil),
+                     lpath);
+      if (*p)
+	path = p + 1;
+      else
+	break;
+    }
+  return Fnreverse (lpath);
+}
+
+DEFUN ("noninteractive", Fnoninteractive, Snoninteractive, 0, 0, 0 /*
+Non-nil return value means XEmacs is running without interactive terminal.
+*/ )
+  ()
+{
+  return ((noninteractive) ? Qt : Qnil);
+}
+
+/* This flag is useful to define if you're under a debugger; this way, you
+   can put a breakpoint of assert_failed() and debug multiple problems
+   in one session without having to recompile. */
+/* #define ASSERTIONS_DONT_ABORT */
+
+#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);
+#undef abort	/* avoid infinite #define loop... */
+#ifndef ASSERTIONS_DONT_ABORT
+  abort ();
+#endif
+}
+#endif /* USE_ASSERTIONS */
+
+#ifdef QUANTIFY
+DEFUN ("quantify-start-recording-data", Fquantify_start_recording_data,
+       Squantify_start_recording_data, 0, 0, 0 /*
+Start recording Quantify data.
+*/)
+  ()
+{
+  quantify_start_recording_data ();
+  return Qnil;
+}
+
+DEFUN ("quantify-stop-recording-data", Fquantify_stop_recording_data,
+       Squantify_stop_recording_data, 0, 0, 0 /*
+Stop recording Quantify data.
+*/)
+  ()
+{
+  quantify_stop_recording_data ();
+  return Qnil;
+}
+
+DEFUN ("quantify-clear-data", Fquantify_clear_data,
+       Squantify_clear_data, 0, 0, 0 /*
+Clear all Quantify data.
+*/)
+  ()
+{
+  quantify_clear_data ();
+  return Qnil;
+}
+#endif /* QUANTIFY */
+
+void
+syms_of_emacs (void)
+{
+#ifndef CANNOT_DUMP
+#ifdef HAVE_SHM
+  defsubr (&Sdump_emacs_data);
+#else
+  defsubr (&Sdump_emacs);
+#endif
+#endif /* !CANNOT_DUMP */
+
+  defsubr (&Srun_emacs_from_temacs);
+  defsubr (&Srunning_temacs_p);
+  defsubr (&Sinvocation_name);
+  defsubr (&Skill_emacs);
+  defsubr (&Snoninteractive);
+
+#ifdef QUANTIFY
+  defsubr (&Squantify_start_recording_data);
+  defsubr (&Squantify_stop_recording_data);
+  defsubr (&Squantify_clear_data);
+#endif /* QUANTIFY */
+
+  defsymbol (&Qkill_emacs_hook, "kill-emacs-hook");
+  defsymbol (&Qsave_buffers_kill_emacs, "save-buffers-kill-emacs");
+}
+
+void
+vars_of_emacs (void)
+{
+  DEFVAR_BOOL ("suppress-early-error-handler-backtrace",
+	       &suppress_early_backtrace /*
+Non-nil means early error handler shouldn't print a backtrace
+*/ );
+
+  DEFVAR_LISP ("command-line-args", &Vcommand_line_args /*
+Args passed by shell to XEmacs, as a list of strings.
+*/ );
+
+  DEFVAR_LISP ("invocation-name", &Vinvocation_name /*
+The program name that was used to run XEmacs.
+Any directory names are omitted.
+*/ );
+
+  DEFVAR_LISP ("invocation-directory", &Vinvocation_directory /*
+The directory in which the XEmacs executable was found, to run it.
+The value is simply the program name if that directory's name is not known.
+*/ );
+
+#if 0 /* FSFmacs */
+  xxDEFVAR_LISP ("installation-directory", &Vinstallation_directory,
+    "A directory within which to look for the `lib-src' and `etc' directories.\n"
+"This is non-nil when we can't find those directories in their standard\n"
+"installed locations, but we can find them\n"
+"near where the XEmacs executable was found.");
+#endif
+
+  DEFVAR_LISP ("system-type", &Vsystem_type /*
+Value is symbol indicating type of operating system you are using.
+*/ );
+  Vsystem_type = intern (SYSTEM_TYPE);
+
+#ifndef EMACS_CONFIGURATION
+# define EMACS_CONFIGURATION "UNKNOWN"
+#endif
+  DEFVAR_LISP ("system-configuration", &Vsystem_configuration /*
+Value is string indicating configuration XEmacs was built for.
+*/ );
+  Vsystem_configuration = Fpurecopy (build_string (EMACS_CONFIGURATION));
+
+  DEFVAR_BOOL ("noninteractive", &noninteractive1 /*
+Non-nil means XEmacs is running without interactive terminal.
+*/ );
+
+  DEFVAR_INT ("emacs-priority", &emacs_priority /*
+Priority for XEmacs to run at.
+This value is effective only if set before XEmacs is dumped,
+and only if the XEmacs executable is installed with setuid to permit
+it to change priority.  (XEmacs sets its uid back to the real uid.)
+Currently, you need to define SET_EMACS_PRIORITY in `config.h'
+before you compile XEmacs, to enable the code for this feature.
+*/ );
+  emacs_priority = 0;
+}