XEmacs 21.2.36 "Notos"
[chise/xemacs-chise.git.1] / src / emacs.c
index e1208f2..abc8bfe 100644 (file)
@@ -206,8 +206,8 @@ version 18.59 released October 31, 1992.
 #include TT_C_H_FILE
 #endif
 
-#if defined (WINDOWSNT)
-#include <windows.h>
+#if defined (WIN32_NATIVE)
+#include "nt.h"
 #endif
 
 /* For PATH_EXEC */
@@ -338,13 +338,30 @@ 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 restored values overwrite the
+   values XEmacs is getting at run-time.  Such variables must be saved
+   before loading the dumpfile, and restored afterward.
+
+   This is done immediately before and after pdump_load() in main_1().
+   See that function for the current list of protected variables.
+
+   Note that if the variable is never DEFVAR'd, saving/restoring is not
+   needed.
+*/
+
 /* 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;
 
@@ -368,7 +385,7 @@ int nodumpfile;
 int debug_paths;
 
 /* Save argv and argc.  */
-static char **initial_argv;
+static Extbyte **initial_argv;
 static int initial_argc;
 
 static void sort_args (int argc, char **argv);
@@ -526,7 +543,9 @@ mswindows_handle_hardware_exceptions (DWORD code)
     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 */
+     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++;
@@ -558,7 +577,38 @@ mswindows_handle_hardware_exceptions (DWORD code)
     }
   /* VC++ documentation says that
      GetExceptionCode() cannot be called inside the filter itself. */
-  __except (mswindows_handle_hardware_exceptions (GetExceptionCode ())) {}
+
+  /*  __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
+  */
+
+  __except (EXCEPTION_EXECUTE_HANDLER) {}
+
 
   /* pretend we didn't handle this, so that the debugger is invoked and/or
      the normal GPF box appears. */
@@ -590,7 +640,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;
@@ -599,21 +649,30 @@ 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, Qfile_name),
-                             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], Qfile_name),
+           result = Fcons (build_ext_string (argv[i],
+                                             Qcommand_argument_encoding),
                            result);
        }
     }
@@ -621,7 +680,7 @@ make_arg_list_1 (int argc, char **argv, int skip_args)
 }
 
 Lisp_Object
-make_arg_list (int argc, char **argv)
+make_arg_list (int argc, Extbyte **argv)
 {
   return make_arg_list_1 (argc, argv, 0);
 }
@@ -629,21 +688,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));
 
-      TO_EXTERNAL_FORMAT (LISP_STRING, XCAR (next),
-                         C_STRING_ALLOCA, temp,
-                         Qnative);
+      LISP_STRING_TO_EXTERNAL (XCAR (next), temp, Qcommand_argument_encoding);
       (*argv) [i] = xstrdup (temp);
     }
   (*argv) [n] = 0;
@@ -651,7 +708,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;
 
@@ -664,7 +721,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;
@@ -697,15 +754,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 mode. */
-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
@@ -827,7 +875,7 @@ main_1 (int argc, char **argv, char **envp, int restart)
 
   sort_args (argc, argv);
 
-#if (defined (MSDOS) && defined (EMX)) || defined (WIN32) || defined (_SCO_DS)
+#if defined (WIN32_NATIVE) || defined (_SCO_DS)
   environ = envp;
 #endif
 
@@ -860,15 +908,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);
@@ -1098,7 +1137,44 @@ main_1 (int argc, char **argv, char **envp, int restart)
     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 protected by noninteractive, which is not
+       LISP-visible */
+    int inhibit_early_packages_save = inhibit_early_packages;
+    int inhibit_autoloads_save      = inhibit_autoloads;
+    int debug_paths_save            = debug_paths;
+#ifdef INHIBIT_SITE_LISP
+    int inhibit_site_lisp_save      = inhibit_site_lisp;
+#endif
+#ifdef INHIBIT_SITE_MODULES
+    int inhibit_site_modules_save   = inhibit_site_modules;
+#endif
+
     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;
+#ifdef INHIBIT_SITE_LISP
+    inhibit_site_lisp      = inhibit_site_lisp_save;
+#endif
+#ifdef INHIBIT_SITE_MODULES
+    inhibit_site_modules   = inhibit_site_modules_save;
+#endif
+
     if (initialized)
       run_temacs_argc = -1;
     else
@@ -1124,7 +1200,7 @@ main_1 (int argc, char **argv, char **envp, int restart)
       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. */
@@ -1133,13 +1209,13 @@ 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:
 
         INIT_LRECORD_IMPLEMENTATION()
-        defsymbol()
+        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.
         */
@@ -1250,7 +1326,9 @@ main_1 (int argc, char **argv, char **envp, int restart)
 #endif
 
 #ifdef HAVE_X_WINDOWS
+#ifdef HAVE_BALLOON_HELP
       syms_of_balloon_x ();
+#endif
       syms_of_device_x ();
 #ifdef HAVE_DIALOGS
       syms_of_dialog_x ();
@@ -1275,6 +1353,7 @@ main_1 (int argc, char **argv, char **envp, int restart)
 #ifdef HAVE_MS_WINDOWS
       syms_of_console_mswindows ();
       syms_of_device_mswindows ();
+      syms_of_dialog_mswindows ();
       syms_of_frame_mswindows ();
       syms_of_objects_mswindows ();
       syms_of_select_mswindows ();
@@ -1286,13 +1365,16 @@ main_1 (int argc, char **argv, char **envp, int restart)
 #ifdef HAVE_SCROLLBARS
       syms_of_scrollbar_mswindows ();
 #endif
+#endif /* HAVE_MS_WINDOWS */
 #ifdef HAVE_MSW_C_DIRED
       syms_of_dired_mswindows ();
 #endif
-#ifdef WINDOWSNT
+#ifdef WIN32_NATIVE
       syms_of_ntproc ();
 #endif
-#endif /* HAVE_MS_WINDOWS */
+#if defined (WIN32_NATIVE) || defined (CYGWIN)
+      syms_of_win32 ();
+#endif
 
 #ifdef MULE
       syms_of_mule ();
@@ -1342,7 +1424,7 @@ main_1 (int argc, char **argv, char **envp, int restart)
 #endif
 
 #ifdef HAVE_GPM
-         syms_of_gpmevent ();
+      syms_of_gpmevent ();
 #endif
 
 #ifdef HAVE_POSTGRESQL
@@ -1629,7 +1711,7 @@ main_1 (int argc, char **argv, char **envp, int restart)
 #ifdef HAVE_SHLIB
       vars_of_module ();
 #endif
-#ifdef WINDOWSNT
+#ifdef WIN32_NATIVE
       vars_of_nt ();
       vars_of_ntproc ();
 #endif
@@ -1672,7 +1754,9 @@ main_1 (int argc, char **argv, char **envp, int restart)
 #endif
 
 #ifdef HAVE_X_WINDOWS
+#ifdef HAVE_BALLOON_HELP
       vars_of_balloon_x ();
+#endif
       vars_of_device_x ();
 #ifdef HAVE_DIALOGS
       vars_of_dialog_x ();
@@ -1747,7 +1831,7 @@ main_1 (int argc, char **argv, char **envp, int restart)
 #endif
 
 #ifdef HAVE_GPM
-         vars_of_gpmevent ();
+      vars_of_gpmevent ();
 #endif
 
       /* Now initialize any specifier variables.  We do this later
@@ -2017,7 +2101,7 @@ 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_environment.
@@ -2032,16 +2116,11 @@ 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
 
@@ -2055,6 +2134,9 @@ 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
@@ -2097,7 +2179,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.  */
@@ -2531,7 +2613,7 @@ 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;
       }
@@ -2639,7 +2721,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
@@ -2653,6 +2735,16 @@ all of which are called before XEmacs is actually killed.
 
   UNGCPRO;
 
+#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. */
+  if (mswindows_message_outputted)
+    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)
@@ -2869,30 +2961,14 @@ 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;
 
-    TO_EXTERNAL_FORMAT (LISP_STRING, intoname,
-                       C_STRING_ALLOCA, intoname_ext,
-                       Qfile_name);
+    LISP_STRING_TO_EXTERNAL (intoname, intoname_ext, Qfile_name);
 
     if (STRINGP (symname))
-      TO_EXTERNAL_FORMAT (LISP_STRING, symname,
-                         C_STRING_ALLOCA, symname_ext,
-                         Qfile_name);
+      LISP_STRING_TO_EXTERNAL (symname, symname_ext, Qfile_name);
     else
       symname_ext = 0;
 
@@ -2917,7 +2993,6 @@ and announce itself normally when it is run.
 #endif
 #endif /* not PDUMP */
   }
-#endif /* not MSDOS and EMX */
 
   purify_flag = opurify;
 
@@ -3056,7 +3131,7 @@ static const char *assert_failed_expr;
 
 #undef abort   /* avoid infinite #define loop... */
 
-#if defined (WINDOWSNT) && defined (DEBUG_XEMACS)
+#if defined (WIN32_NATIVE) && defined (DEBUG_XEMACS)
 #define enter_debugger() DebugBreak ()
 #else
 #define enter_debugger()
@@ -3099,7 +3174,7 @@ assert_failed (const char *file, int line, const char *expr)
       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",
@@ -3299,6 +3374,11 @@ Codename of this version of Emacs (a string).
 #endif
   Vxemacs_codename = build_string (XEMACS_CODENAME);
 
+  /* 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.
 */ );
@@ -3634,7 +3714,7 @@ The configured initial path for info documentation.
 #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.
  */