This commit was manufactured by cvs2svn to create branch 'utf-2000'.
[chise/xemacs-chise.git-] / src / emacs.c
1 /* XEmacs -- Fully extensible Emacs, running on Unix and other platforms.
2    Copyright (C) 1985, 1986, 1987, 1992, 1993, 1994
3    Free Software Foundation, Inc.
4    Copyright (C) 1995 Sun Microsystems, Inc.
5    Copyright (C) 2000 Ben Wing.
6    Copyright (C) 2000,2002 MORIOKA Tomohiko.
7
8 This file is part of XEmacs.
9
10 XEmacs is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published by the
12 Free Software Foundation; either version 2, or (at your option) any
13 later version.
14
15 XEmacs is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with XEmacs; see the file COPYING.  If not, write to
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA.  */
24
25 /* Synched up with: Mule 2.0, FSF 19.28. */
26
27 /* Capsule summary of the various releases of Lucid Emacs/XEmacs and
28    FSF/GNU Emacs.  Provided here for use in cross-referencing version
29    releases and dates in comments, esp. in the authorship comments at
30    the beginning of each file.  More information about history can be
31    found in the beginning of the Internals Manual and in the About page.
32
33
34 -- A time line for Lucid Emacs/XEmacs is
35
36 version 19.0 shipped with Energize 1.0, April 1992.
37 version 19.1 released June 4, 1992.
38 version 19.2 released June 19, 1992.
39 version 19.3 released September 9, 1992.
40 version 19.4 released January 21, 1993.
41 version 19.5 was a repackaging of 19.4 with a few bug fixes and
42   shipped with Energize 2.0.  Never released to the net.
43 version 19.6 released April 9, 1993.
44 version 19.7 was a repackaging of 19.6 with a few bug fixes and
45   shipped with Energize 2.1.  Never released to the net.
46 version 19.8 released September 6, 1993.
47 version 19.9 released January 12, 1994.
48 version 19.10 released May 27, 1994.
49 version 19.11 (first XEmacs) released September 13, 1994.
50 version 19.12 released June 23, 1995.
51 version 19.13 released September 1, 1995.
52 version 19.14 released June 23, 1996.
53 version 20.0 released February 9, 1997.
54 version 19.15 released March 28, 1997.
55 version 20.1 (not released to the net) April 15, 1997.
56 version 20.2 released May 16, 1997.
57 version 19.16 released October 31, 1997.
58 version 20.3 (the first stable version of XEmacs 20.x) released
59   November 30, 1997.
60 version 20.4 released February 28, 1998.
61
62
63 -- A time line for GNU Emacs version 19 is
64
65 version 19.7 (beta) (first beta release) released ??????; prob. late May 1993.
66 version 19.8 (beta) released May 27, 1993.
67 version 19.9 (beta) released May 27, 1993.
68 version 19.10 (beta) released May 30, 1993.
69 version 19.11 (beta) released June 1, 1993.
70 version 19.12 (beta) released June 2, 1993.
71 version 19.13 (beta) released June 8, 1993.
72 version 19.14 (beta) released June 17, 1993.
73 version 19.15 (beta) released June 19, 1993.
74 version 19.16 (beta) released July 6, 1993.
75 version 19.17 (beta) released late July, 1993.
76 version 19.18 (beta) released August 9, 1993.
77 version 19.19 (beta) released August 15, 1993.
78 version 19.20 (beta) released November 17, 1993.
79 version 19.21 (beta) released November 17, 1993.
80 version 19.22 (beta) released November 28, 1993.
81 version 19.23 (beta) released May 17, 1994.
82 version 19.24 (beta) released May 16, 1994.
83 version 19.25 (beta) released June 3, 1994.
84 version 19.26 (beta) released September 11, 1994.
85 version 19.27 (beta) released September 14, 1994.
86 version 19.28 (first ``official'' release) released November 1, 1994.
87 version 19.29 released June 21, 1995.
88 version 19.30 released November 24, 1995.
89 version 19.31 released May 25, 1996.
90 version 19.32 released July 31, 1996.
91 version 19.33 released August 11, 1996.
92 version 19.34 released August 21, 1996.
93 version 19.34b released September 6, 1996.
94
95
96 -- A time line for GNU Emacs version 20 is
97
98 version 20.1 released September 17, 1997.
99 version 20.2 released September 20, 1997.
100 version 20.3 released August 19, 1998.
101
102
103 -- A time line for GNU Emacs version 18 and older is
104
105 GNU Emacs version 15 (15.34) was released sometime in 1984 or 1985 and
106   shared some code with a version of Emacs written by James Gosling (the
107   same James Gosling who later created the Java language).
108 GNU Emacs version 16 (first released version was 16.56) was released on
109   July 15, 1985.  All Gosling code was removed due to potential copyright
110   problems with the code.
111 version 16.57: released on September 16, 1985.
112 versions 16.58, 16.59: released on September 17, 1985.
113 version 16.60: released on September 19, 1985.  These later version 16's
114   incorporated patches from the net, esp. for getting Emacs to work under
115   System V.
116 version 17.36 (first official v17 release) released on December 20, 1985.
117   Included a TeX-able user manual.  First official unpatched version that
118    worked on vanilla System V machines.
119 version 17.43 (second official v17 release) released on January 25, 1986.
120 version 17.45 released on January 30, 1986.
121 version 17.46 released on February 4, 1986.
122 version 17.48 released on February 10, 1986.
123 version 17.49 released on February 12, 1986.
124 version 17.55 released on March 18, 1986.
125 version 17.57 released on March 27, 1986.
126 version 17.58 released on April 4, 1986.
127 version 17.61 released on April 12, 1986.
128 version 17.63 released on May 7, 1986.
129 version 17.64 released on May 12, 1986.
130 version 18.24 (a beta version) released on October 2, 1986.
131 version 18.30 (a beta version) released on November 15, 1986.
132 version 18.31 (a beta version) released on November 23, 1986.
133 version 18.32 (a beta version) released on December 7, 1986.
134 version 18.33 (a beta version) released on December 12, 1986.
135 version 18.35 (a beta version) released on January 5, 1987.
136 version 18.36 (a beta version) released on January 21, 1987.
137 January 27, 1987: The Great Usenet Renaming.  net.emacs is now comp.emacs.
138 version 18.37 (a beta version) released on February 12, 1987.
139 version 18.38 (a beta version) released on March 3, 1987.
140 version 18.39 (a beta version) released on March 14, 1987.
141 version 18.40 (a beta version) released on March 18, 1987.
142 version 18.41 (the first ``official'' release) released on March 22, 1987.
143 version 18.45 released on June 2, 1987.
144 version 18.46 released on June 9, 1987.
145 version 18.47 released on June 18, 1987.
146 version 18.48 released on September 3, 1987.
147 version 18.49 released on September 18, 1987.
148 version 18.50 released on February 13, 1988.
149 version 18.51 released on May 7, 1988.
150 version 18.52 released on September 1, 1988.
151 version 18.53 released on February 24, 1989.
152 version 18.54 released on April 26, 1989.
153 version 18.55 released on August 23, 1989.  This is the earliest version
154   that is still available by FTP.
155 version 18.56 released on January 17, 1991.
156 version 18.57 released late January, 1991.
157 version 18.58 released ?????.
158 version 18.59 released October 31, 1992.
159
160 */
161
162 /* Note: It is necessary to specify <config.h> and not "config.h" in
163    order for the --srcdir type of compilation to work properly.
164    Otherwise the config.h from the srcdir, rather than the one from
165    the build dir, will be used. */
166
167 #include <config.h>
168 #include "lisp.h"
169
170 #include "backtrace.h" /* run-emacs-from-temacs needs this */
171 #include "buffer.h"
172 #include "commands.h"
173 #include "console.h"
174 #include "process.h"
175 #include "redisplay.h"
176 #include "frame.h"
177 #include "sysdep.h"
178
179 #include "syssignal.h" /* Always include before systty.h */
180 #include "systty.h"
181 #include "sysfile.h"
182 #include "systime.h"
183
184 #ifdef PDUMP
185 #include "dumper.h"
186 #endif
187
188 #ifndef SEPCHAR
189 #define SEPCHAR ':'
190 #endif
191
192 #ifdef QUANTIFY
193 #include <quantify.h>
194 #endif
195
196 #ifdef HAVE_SHLIB
197 #include "sysdll.h"
198 #endif
199
200 #if defined (HAVE_LOCALE_H) && \
201    (defined (I18N2) || defined (I18N3) || defined (I18N4))
202 #include <locale.h>
203 #endif
204
205 #ifdef TOOLTALK
206 #include TT_C_H_FILE
207 #endif
208
209 #if defined (WIN32_NATIVE)
210 #include "nt.h"
211 #endif
212
213 /* For PATH_EXEC */
214 #include <paths.h>
215
216 #if defined (HEAP_IN_DATA) && !defined(PDUMP)
217 void report_sheap_usage (int die_if_pure_storage_exceeded);
218 #endif
219
220 #if !defined (SYSTEM_MALLOC) && !defined (DOUG_LEA_MALLOC)
221 extern void *(*__malloc_hook)(size_t);
222 extern void *(*__realloc_hook)(void *, size_t);
223 extern void (*__free_hook)(void *);
224 #endif  /* not SYSTEM_MALLOC && not DOUG_LEA_MALLOC */
225
226 /* Command line args from shell, as list of strings */
227 Lisp_Object Vcommand_line_args;
228
229 /* Set nonzero after XEmacs has started up the first time.
230   Prevents reinitialization of the Lisp world and keymaps
231   on subsequent starts.  */
232 int initialized;
233
234 #ifdef DOUG_LEA_MALLOC
235 # include <malloc.h>
236 /* Preserves a pointer to the memory allocated that copies that
237    static data inside glibc's malloc.  */
238 static void *malloc_state_ptr;
239 #endif /* DOUG_LEA_MALLOC */
240
241 # ifdef REL_ALLOC
242 void r_alloc_reinit (void);
243 # endif
244
245 /* Variable whose value is symbol giving operating system type. */
246 Lisp_Object Vsystem_type;
247
248 /* Variable whose value is string giving configuration built for.  */
249 Lisp_Object Vsystem_configuration;
250
251 /* Variable whose value is string containing the configuration options
252    XEmacs was built with.  */
253 Lisp_Object Vsystem_configuration_options;
254
255 /* Version numbers and strings */
256 Lisp_Object Vemacs_major_version;
257 Lisp_Object Vemacs_minor_version;
258 Lisp_Object Vemacs_patch_level;
259 Lisp_Object Vemacs_beta_version;
260 Lisp_Object Vxemacs_codename;
261 #ifdef INFODOCK
262 Lisp_Object Vinfodock_major_version;
263 Lisp_Object Vinfodock_minor_version;
264 Lisp_Object Vinfodock_build_version;
265 #endif
266
267 /* The path under which XEmacs was invoked. */
268 Lisp_Object Vinvocation_path;
269
270 /* The name under which XEmacs was invoked, with any leading directory
271    names discarded.  */
272 Lisp_Object Vinvocation_name;
273
274 /* The directory name from which XEmacs was invoked.  */
275 Lisp_Object Vinvocation_directory;
276
277 #if 0 /* FSFmacs */
278 /* The directory name in which to find subdirs such as lisp and etc.
279    nil means get them only from PATH_LOADSEARCH.  */
280 Lisp_Object Vinstallation_directory;
281 #endif
282
283 Lisp_Object Vemacs_program_name, Vemacs_program_version;
284 Lisp_Object Vexec_path;
285 Lisp_Object Vexec_directory, Vconfigure_exec_directory;
286 Lisp_Object Vlisp_directory, Vconfigure_lisp_directory;
287 Lisp_Object Vmule_lisp_directory, Vconfigure_mule_lisp_directory;
288 Lisp_Object Vutf_2000_lisp_directory, Vconfigure_utf_2000_lisp_directory;
289 Lisp_Object Vmodule_directory, Vconfigure_module_directory;
290 Lisp_Object Vsite_module_directory, Vconfigure_site_module_directory;
291 Lisp_Object Vconfigure_package_path;
292 Lisp_Object Vdata_directory, Vconfigure_data_directory;
293 Lisp_Object Vdoc_directory, Vconfigure_doc_directory;
294 Lisp_Object Vconfigure_lock_directory;
295 Lisp_Object Vdata_directory_list;
296 Lisp_Object Vconfigure_info_directory;
297 Lisp_Object Vsite_directory, Vconfigure_site_directory;
298 Lisp_Object Vconfigure_info_path;
299 Lisp_Object Vinternal_error_checking;
300 Lisp_Object Vmail_lock_methods, Vconfigure_mail_lock_method;
301 Lisp_Object Vpath_separator;
302
303 /* The default base directory XEmacs is installed under. */
304 Lisp_Object Vconfigure_exec_prefix_directory, Vconfigure_prefix_directory;
305
306 /* If nonzero, set XEmacs to run at this priority.  This is also used
307    in child_setup and sys_suspend to make sure subshells run at normal
308    priority. */
309 Fixnum emacs_priority;
310
311 /* Some FSF junk with running_asynch_code, to preserve the match
312    data.  Not necessary because we don't call process filters
313    asynchronously (i.e. from within QUIT). */
314 /* #### Delete this when merging the rest of my code */
315 int running_asynch_code;
316
317 /* If non-zero, a window-system was specified on the command line. */
318 int display_arg;
319
320 /* Type of display specified.  We cannot use a Lisp symbol here because
321    Lisp symbols may not initialized at the time that we set this
322    variable. */
323 const char *display_use;
324
325 /* If non-zero, then the early error handler will only print the error
326    message and exit. */
327 int suppress_early_error_handler_backtrace;
328
329 /* An address near the bottom of the stack.
330    Tells GC how to save a copy of the stack.  */
331 char *stack_bottom;
332
333 #ifdef USG_SHARED_LIBRARIES
334 /* If nonzero, this is the place to put the end of the writable segment
335    at startup.  */
336
337 uintptr_t bss_end = 0;
338 #endif
339
340 /* Number of bytes of writable memory we can expect to be able to get */
341 unsigned int lim_data;
342
343 /* WARNING!
344
345    Some LISP-visible command-line options are set by XEmacs _before_ the
346    data is dumped in building a --pdump XEmacs, but used _after_ it is
347    restored in normal operation.  Thus the dump-time values overwrite the
348    values XEmacs is getting at runtime.  Such variables must be saved
349    before loading the dumpfile, and restored afterward.
350
351    Therefore these variables may not be initialized in vars_of_emacs().
352
353    The save/restore is done immediately before and after pdump_load() in
354    main_1().  See that function for the current list of protected variables.
355
356    Note that saving/restoring is only necessary for a few variables that are
357      o command line arguments effective at runtime (as opposed to dump-time),
358      o parsed before pdump_load, and
359      o exported to Lisp via a DEFVAR.
360 */
361
362 /* Nonzero means running XEmacs without interactive terminal.  */
363
364 int noninteractive;
365
366 /* Value of Lisp variable `noninteractive'.
367    Normally same as C variable `noninteractive'
368    but nothing terrible happens if user sets this one.
369
370    Shadowed from the pdumper by `noninteractive'. */
371
372 int noninteractive1;
373
374 /* Nonzero means don't perform site-lisp searches at startup */
375 int inhibit_site_lisp;
376
377 /* Nonzero means don't perform site-modules searches at startup */
378 int inhibit_site_modules;
379
380 /* Nonzero means don't respect early packages at startup */
381 int inhibit_early_packages;
382
383 /* Nonzero means don't load package autoloads at startup */
384 int inhibit_autoloads;
385
386 /* Nonzero means don't load the dump file (ignored if not PDUMP)  */
387
388 int nodumpfile;
389
390 /* Nonzero means print debug information about path searching */
391 int debug_paths;
392
393 /* Save argv and argc.  */
394 static Extbyte **initial_argv;  /* #### currently unused */
395 static int initial_argc;        /* #### currently unused */
396
397 static void sort_args (int argc, char **argv);
398
399 Lisp_Object Qkill_emacs_hook;
400 Lisp_Object Qsave_buffers_kill_emacs;
401
402 extern Lisp_Object Vlisp_EXEC_SUFFIXES;
403
404 \f
405
406 /* Ben's capsule summary about expected and unexpected exits from XEmacs.
407
408    Expected exits occur when the user directs XEmacs to exit, for example
409    by pressing the close button on the only frame in XEmacs, or by typing
410    C-x C-c.  This runs `save-buffers-kill-emacs', which saves any necessary
411    buffers, and then exits using the primitive `kill-emacs'.
412
413    However, unexpected exits occur in a few different ways:
414
415      -- a memory access violation or other hardware-generated exception
416         occurs.  This is the worst possible problem to deal with, because
417         the fault can occur while XEmacs is in any state whatsoever, even
418         quite unstable ones.  As a result, we need to be *extremely* careful
419         what we do.
420      -- we are using one X display (or if we've used more, we've closed the
421         others already), and some hardware or other problem happens and
422         suddenly we've lost our connection to the display.  In this situation,
423         things are not so dire as in the last one; our code itself isn't
424         trashed, so we can continue execution as normal, after having set
425         things up so that we can exit at the appropriate time.  Our exit
426         still needs to be of the emergency nature; we have no displays, so
427         any attempts to use them will fail.  We simply want to auto-save
428         (the single most important thing to do during shut-down), do minimal
429         cleanup of stuff that has an independent existence outside of XEmacs,
430         and exit.
431
432         Currently, both unexpected exit scenarios described above set
433         preparing_for_armageddon to indicate that nonessential and possibly
434         dangerous things should not be done, specifically:
435
436         -- no garbage collection.
437         -- no hooks are run.
438         -- no messages of any sort from autosaving.
439         -- autosaving tries harder, ignoring certain failures.
440         -- existing frames are not deleted.
441
442         (Also, all places that set preparing_for_armageddon also
443         set dont_check_for_quit.  This happens separately because it's
444         also necessary to set other variables to make absolutely sure
445         no quitting happens.)
446
447         In the first scenario above (the access violation), we also set
448         fatal_error_in_progress.  This causes more things to not happen:
449
450         -- assertion failures do not abort.
451         -- printing code does not do code conversion or gettext when
452            printing to stdout/stderr.
453 */
454
455 /* Nonzero if handling a fatal error already. */
456 int fatal_error_in_progress;
457
458 /* Non-nil means we're going down, so we better not run any hooks
459    or do other non-essential stuff. */
460 int preparing_for_armageddon;
461
462
463 static JMP_BUF run_temacs_catch;
464
465 static int run_temacs_argc;
466 static char **run_temacs_argv;
467 static char *run_temacs_args;
468 static size_t run_temacs_argv_size;
469 static size_t run_temacs_args_size;
470
471 static void shut_down_emacs (int sig, Lisp_Object stuff, int no_auto_save);
472
473 static void
474 ensure_no_quitting_from_now_on (void)
475 {
476   /* make sure no quitting from now on!! */
477   dont_check_for_quit = 1;
478   Vinhibit_quit = Qt;
479   Vquit_flag = Qnil;
480 }
481
482 /* Handle bus errors, illegal instruction, etc. */
483 SIGTYPE
484 fatal_error_signal (int sig)
485 {
486   fatal_error_in_progress++;
487   preparing_for_armageddon = 1;
488
489   ensure_no_quitting_from_now_on ();
490
491   /* Unblock the signal so that if the same signal gets sent in the
492      code below, we avoid a deadlock. */
493   EMACS_UNBLOCK_SIGNAL (sig);
494
495   /* Only try auto-saving first time through.  If we crash in auto-saving,
496      don't do it again. */
497   if (fatal_error_in_progress == 1)
498     {
499       Fdo_auto_save (Qt, Qnil); /* do this before anything hazardous */
500       /* Do this so that the variable has the same value of 2 regardless of
501          whether we made it through auto-saving correctly. */
502       fatal_error_in_progress++;
503     }
504   else if (fatal_error_in_progress == 2)
505     stderr_out ("WARNING: Unable to auto-save your files properly.\n"
506                 "Some or all may in fact have been auto-saved.\n"
507                 "\n");
508
509   /* Now, reset our signal handler, so the next time, we just die.
510      Don't do this before auto-saving. */
511   signal (sig, SIG_DFL);
512
513   /* Keep in mind that there's more than one signal that we can crash
514      on. */
515   /* If fatal error occurs in code below, avoid infinite recursion.  */
516   if (fatal_error_in_progress <= 2)
517     {
518       shut_down_emacs (sig, Qnil, 1);
519       stderr_out ("\nLisp backtrace follows:\n\n");
520       Fbacktrace (Qexternal_debugging_output, Qt);
521 # if 0  /* This is evil, rarely useful, and causes grief in some cases. */
522       /* Check for Sun-style stack printing via /proc */
523       {
524         const char *pstack = "/usr/proc/bin/pstack";
525         if (access (pstack, X_OK) == 0)
526           {
527             char buf[100];
528             stderr_out ("\nC backtrace follows:\n"
529                        "(A real debugger may provide better information)\n\n");
530             sprintf (buf, "%s %d >&2", pstack, (int)getpid());
531             system (buf);
532           }
533       }
534 # endif
535     }
536   /* Signal the same code; this time it will really be fatal. */
537   kill (getpid (), sig);
538   SIGRETURN;
539 }
540
541 #ifdef _MSC_VER
542
543 static DWORD
544 mswindows_handle_hardware_exceptions (DWORD code)
545 {
546   if (code != STATUS_ACCESS_VIOLATION && code != STATUS_ILLEGAL_INSTRUCTION
547       && code != STATUS_PRIVILEGED_INSTRUCTION
548       && code != STATUS_DATATYPE_MISALIGNMENT)
549     return EXCEPTION_CONTINUE_SEARCH;
550
551   /* I don't know if this filter is still wrapped in the outer __try, but
552      it doesn't hurt to have another one. --ben
553      And it lets us control more exactly what we really want to do in such
554      a situation. */
555   __try
556     {
557       fatal_error_in_progress++;
558       preparing_for_armageddon = 1;
559
560       ensure_no_quitting_from_now_on ();
561
562       /* Only try auto-saving first time through.  If we crash in auto-saving,
563          don't do it again. */
564       if (fatal_error_in_progress == 1)
565         {
566           Fdo_auto_save (Qt, Qnil); /* do this before anything hazardous */
567           /* Do this so that the variable has the same value of 2 regardless of
568              whether we made it through auto-saving correctly. */
569           fatal_error_in_progress++;
570         }
571       else if (fatal_error_in_progress == 2)
572         stderr_out ("WARNING: Unable to auto-save your files properly.\n"
573                     "Some or all may in fact have been auto-saved.\n"
574                     "\n");
575
576       /* If fatal error occurs in code below, avoid infinite recursion.  */
577       if (fatal_error_in_progress <= 2)
578         {
579           shut_down_emacs (-1, Qnil, 1);
580           stderr_out ("\nLisp backtrace follows:\n\n");
581           Fbacktrace (Qexternal_debugging_output, Qt);
582         }
583     }
584   /* VC++ documentation says that
585      GetExceptionCode() cannot be called inside the filter itself. */
586
587   /*  __except (mswindows_handle_hardware_exceptions (GetExceptionCode ())) {}
588
589      The line above is original.  Unfortunately, when an error is tripped
590      inside of the handler (e.g. during Fbacktrace()), and the handler for
591      the handler is invoked, it correctly notices that something is amiss
592      and it should just return -- but it returns EXCEPTION_CONTINUE_SEARCH,
593      which causes the debugger to be invoked debugging the handler code in
594      this function -- and WITH THE STACK UNWOUND so that you see main()
595      calling mswindows_handle_hardware_exceptions(), calling Fbacktrace(),
596      and a crash a couple of frames in -- AND NO SIGN OF THE ORIGINAL CRASH!
597
598      There's some real weirdness going on in the stack handling -- unlike
599      in Unix, where further crashes just keep adding to the stack, it seems
600      that under the structured-exception-handling, the stack can actually
601      bounce back and forth between the full stack at the location of the
602      exception and the unwound stack at the place where the __try clause was
603      established.  I don't completely understand it.  What I do know is that
604      returning EXCEPTION_EXECUTE_HANDLER on nested crash has the effect of
605      aborting execution of the handler and going back to the outer filter
606      function, which returns EXCEPTION_CONTINUE_SEARCH and everything is
607      hunky-dorey -- your debugger sees a crash at the right location with
608      the right stack.
609
610      I'm leaving in the trickier Unix-like code in the handler; someone who
611      understands better than me how the stack works in these handlers could
612      fix it up more.  As it is, it works pretty well, so I'm not likely to
613      touch it more. --ben
614   */
615
616   __except (EXCEPTION_EXECUTE_HANDLER) {}
617
618
619   /* pretend we didn't handle this, so that the debugger is invoked and/or
620      the normal GPF box appears. */
621   return EXCEPTION_CONTINUE_SEARCH;
622 }
623
624 #endif /* _MSC_VER */
625
626 \f
627
628 #ifdef SIGDANGER
629
630 /* Handler for SIGDANGER.  */
631 SIGTYPE
632 memory_warning_signal (int sig)
633 {
634   /* #### bad bad bad; this function shouldn't do anything except
635      set a flag, or weird corruption could happen. */
636   signal (sig, memory_warning_signal);
637
638   malloc_warning
639     (GETTEXT ("Operating system warns that virtual memory is running low.\n"));
640
641   /* It might be unsafe to call do_auto_save now.  */
642   force_auto_save_soon ();
643 }
644 #endif /* SIGDANGER */
645 \f
646 /* Code for dealing with Lisp access to the Unix command line */
647
648 static Lisp_Object
649 make_arg_list_1 (int argc, Extbyte **argv, int skip_args)
650 {
651   Lisp_Object result = Qnil;
652   REGISTER int i;
653
654   for (i = argc - 1; i >= 0; i--)
655     {
656       if (i == 0 || i > skip_args)
657         {
658 #ifdef WIN32_NATIVE
659           if (i == 0)
660             {
661               /* Do not trust to what crt0 has stuffed into argv[0] */
662               char full_exe_path[MAX_PATH];
663               Lisp_Object fullpath;
664
665               GetModuleFileName (NULL, full_exe_path, MAX_PATH);
666               fullpath = build_ext_string (full_exe_path, Qmswindows_tstr);
667               result = Fcons (fullpath, result);
668 #if defined(HAVE_SHLIB)
669               {
670                 Extbyte *fullpathext;
671
672                 LISP_STRING_TO_EXTERNAL (fullpath, fullpathext,
673                                   Qdll_filename_encoding);
674                 (void) dll_init (fullpathext);
675               }
676 #endif
677             }
678           else
679 #endif
680             result = Fcons (build_ext_string (argv[i],
681                                               Qcommand_argument_encoding),
682                             result);
683         }
684     }
685   return result;
686 }
687
688 Lisp_Object
689 make_arg_list (int argc, Extbyte **argv)
690 {
691   return make_arg_list_1 (argc, argv, 0);
692 }
693
694 /* Calling functions are also responsible for calling free_argc_argv
695    when they are done with the generated list. */
696 void
697 make_argc_argv (Lisp_Object argv_list, int *argc, Extbyte ***argv)
698 {
699   Lisp_Object next;
700   int n = XINT (Flength (argv_list));
701   REGISTER int i;
702   *argv = (Extbyte**) xmalloc ((n+1) * sizeof (Extbyte*));
703
704   for (i = 0, next = argv_list; i < n; i++, next = XCDR (next))
705     {
706       const Extbyte *temp;
707       CHECK_STRING (XCAR (next));
708
709       LISP_STRING_TO_EXTERNAL (XCAR (next), temp, Qcommand_argument_encoding);
710       (*argv) [i] = xstrdup (temp);
711     }
712   (*argv) [n] = 0;
713   *argc = i;
714 }
715
716 void
717 free_argc_argv (Extbyte **argv)
718 {
719   int elt = 0;
720
721   while (argv[elt])
722     {
723       xfree (argv[elt]);
724       elt++;
725     }
726   xfree (argv);
727 }
728
729 static void
730 init_cmdargs (int argc, Extbyte **argv, int skip_args)
731 {
732   initial_argv = argv;
733   initial_argc = argc;
734
735   Vcommand_line_args = make_arg_list_1 (argc, argv, skip_args);
736 }
737
738 DEFUN ("invocation-name", Finvocation_name, 0, 0, 0, /*
739 Return the program name that was used to run XEmacs.
740 Any directory names are omitted.
741 */
742        ())
743 {
744   return Fcopy_sequence (Vinvocation_name);
745 }
746
747 DEFUN ("invocation-directory", Finvocation_directory, 0, 0, 0, /*
748 Return the directory name in which the Emacs executable was located.
749 */
750        ())
751 {
752   return Fcopy_sequence (Vinvocation_directory);
753 }
754
755 \f
756 #ifdef I18N4
757                                 /* #### - don't know why I18N4 on SunOS/JLE
758                                    can't deal with this.  It's a potential
759                                    bug that needs to be looked at. */
760 # undef RUN_TIME_REMAP
761 #endif
762
763 /* Test whether the next argument in ARGV matches SSTR or a prefix of
764    LSTR (at least MINLEN characters).  If so, then if VALPTR is non-null
765    (the argument is supposed to have a value) store in *VALPTR either
766    the next argument or the portion of this one after the equal sign.
767    ARGV is read starting at position *SKIPPTR; this index is advanced
768    by the number of arguments used.
769
770    Too bad we can't just use getopt for all of this, but we don't have
771    enough information to do it right.  */
772
773 static int
774 argmatch (char **argv, int argc, char *sstr, char *lstr,
775           int minlen, char **valptr, int *skipptr)
776 {
777   char *p = NULL;
778   int arglen;
779   char *arg;
780
781   /* Don't access argv[argc]; give up in advance.  */
782   if (argc <= *skipptr + 1)
783     return 0;
784
785   arg = argv[*skipptr+1];
786   if (arg == NULL)
787     return 0;
788   if (strcmp (arg, sstr) == 0)
789     {
790       if (valptr != NULL)
791         {
792           *valptr = argv[*skipptr+2];
793           *skipptr += 2;
794         }
795       else
796         *skipptr += 1;
797       return 1;
798     }
799   arglen = (valptr != NULL && (p = strchr (arg, '=')) != NULL
800             ? p - arg : strlen (arg));
801   if (lstr == 0 || arglen < minlen || strncmp (arg, lstr, arglen) != 0)
802     return 0;
803   else if (valptr == NULL)
804     {
805       *skipptr += 1;
806       return 1;
807     }
808   else if (p != NULL)
809     {
810       *valptr = p+1;
811       *skipptr += 1;
812       return 1;
813     }
814   else if (argv[*skipptr+2] != NULL)
815     {
816       *valptr = argv[*skipptr+2];
817       *skipptr += 2;
818       return 1;
819     }
820   else
821     {
822       return 0;
823     }
824 }
825
826 /* Make stack traces always identify version + configuration */
827 #define main_1 STACK_TRACE_EYE_CATCHER
828
829 /* This function is not static, so that the compiler is less likely to
830    inline it, which would make it not show up in stack traces.
831
832    The restart argument is a flag that indicates that main_1 is now
833    being called for the second time in this invocation of xemacs; this can
834    only happen in an xemacs that is not loaded with dumped data (temacs
835    with the conventional dumper or xemacs -nd with the pdumper).   See
836    Frun_emacs_from_temacs().
837
838    restart interacts with initialized as follows (per Olivier Galibert):
839
840      It's perverted.
841
842      initialized==0 => temacs
843      initialized!=0 && restart!=0 => run-temacs
844      initialized!=0 && restart==0 => xemacs/post pdump_load()
845 */
846 DECLARE_DOESNT_RETURN (main_1 (int, char **, char **, int));
847 DOESNT_RETURN
848 main_1 (int argc, char **argv, char **envp, int restart)
849 {
850   char stack_bottom_variable;
851   int skip_args = 0;
852   Lisp_Object load_me;
853   int inhibit_window_system;
854 #ifdef NeXT
855   extern int malloc_cookie;
856 #endif
857
858 #if (!defined (SYSTEM_MALLOC) && !defined (HAVE_LIBMCHECK)      \
859      && !defined (DOUG_LEA_MALLOC))
860   /* Make sure that any libraries we link against haven't installed a
861      hook for a gmalloc of a potentially incompatible version. */
862   /* If we're using libmcheck, the hooks have already been initialized, */
863   /* don't touch them. -slb */
864   __malloc_hook = NULL;
865   __realloc_hook = NULL;
866   __free_hook = NULL;
867 #endif /* not SYSTEM_MALLOC or HAVE_LIBMCHECK or DOUG_LEA_MALLOC */
868
869   noninteractive = 0;
870
871 #ifdef NeXT
872   /* 19-Jun-1995 -baw
873    * NeXT secret magic, ripped from Emacs-for-NS by Carl Edman
874    * <cedman@princeton.edu>.  Note that even Carl doesn't know what this
875    * does; it was provided by NeXT, and it presumable makes NS's mallocator
876    * work with dumping.  But malloc_jumpstart() and malloc_freezedry() in
877    * unexnext.c are both completely undocumented, even in NS header files!
878    * But hey, it solves all NS related memory problems, so who's
879    * complaining? */
880   if (initialized && malloc_jumpstart (malloc_cookie) != 0)
881     stderr_out ("malloc jumpstart failed!\n");
882 #endif /* NeXT */
883
884   /*
885 #if defined (GNU_MALLOC) && \
886     defined (ERROR_CHECK_MALLOC) && \
887     !defined (HAVE_LIBMCHECK)
888   */
889 #if defined(LOSING_GCC_DESTRUCTOR_FREE_BUG)
890   /* Prior to XEmacs 21, this was `#if 0'ed out.  */
891   /* I'm enabling this because it is the only reliable way I've found to */
892   /* prevent a very annoying problem where GCC will attempt to free(3) */
893   /* memory at exit() and cause a coredump. */
894   init_free_hook ();
895 #endif
896
897   sort_args (argc, argv);
898
899 #if defined (WIN32_NATIVE) || defined (_SCO_DS)
900   environ = envp;
901 #endif
902
903   /* Record (approximately) where the stack begins.  */
904   stack_bottom = &stack_bottom_variable;
905
906 #ifdef USG_SHARED_LIBRARIES
907   if (bss_end)
908     brk ((void *) bss_end);
909 #endif
910
911   clearerr (stdin);
912
913 #if defined (HAVE_MMAP) && defined (REL_ALLOC)
914   /* ralloc can only be used if using the GNU memory allocator. */
915   init_ralloc ();
916 #elif defined (REL_ALLOC) && !defined(DOUG_LEA_MALLOC)
917   if (initialized)
918     init_ralloc();
919 #endif
920
921 #ifdef HAVE_SOCKS
922   if (initialized)
923     SOCKSinit (argv[0]);
924 #endif /* HAVE_SOCKS */
925
926 #ifndef SYSTEM_MALLOC
927   if (!initialized)
928     /* Arrange to get warning messages as memory fills up.  */
929     memory_warnings (0, malloc_warning);
930 #endif  /* not SYSTEM_MALLOC */
931
932 #ifdef SET_EMACS_PRIORITY
933   if (emacs_priority != 0)
934     nice (-emacs_priority);
935   setuid (getuid ());
936 #endif /* SET_EMACS_PRIORITY */
937
938 #ifdef EXTRA_INITIALIZE
939   EXTRA_INITIALIZE;
940 #endif
941
942 #ifdef HAVE_WINDOW_SYSTEM
943   inhibit_window_system = 0;
944 #else
945   inhibit_window_system = 1;
946 #endif
947
948   /* Handle the -sd/--show-dump-id switch, which means show the hex dump_id and quit */
949   if (argmatch (argv, argc, "-sd", "--show-dump-id", 9, NULL, &skip_args))
950     {
951 #ifdef PDUMP
952       printf ("%08x\n", dump_id);
953 #else
954       printf ("Portable dumper not configured; -sd just forces exit.\n");
955 #endif
956       exit (0);
957     }
958
959   /* Handle the -t switch, which specifies filename to use as terminal */
960   {
961     char *term;
962     if (argmatch (argv, argc, "-t", "--terminal", 4, &term, &skip_args))
963       {
964         close (0);
965         close (1);
966         if (open (term, O_RDWR | OPEN_BINARY, 2) < 0)
967           fatal ("%s: %s", term, strerror (errno));
968         dup (0);
969         if (! isatty (0))
970           fatal ("%s: not a tty", term);
971
972 #if 0
973         stderr_out ("Using %s", ttyname (0));
974 #endif
975         stderr_out ("Using %s", term);
976         inhibit_window_system = 1;      /* -t => -nw */
977       }
978   }
979
980   /* Handle the --no-dump-file/-nd switch, which means don't load the dump file (ignored when not using pdump) */
981   if (argmatch (argv, argc, "-nd", "--no-dump-file", 7, NULL, &skip_args))
982     {
983       nodumpfile = 1;
984     }
985
986   /* Handle -nw switch */
987   if (argmatch (argv, argc, "-nw", "--no-windows", 6, NULL, &skip_args))
988     inhibit_window_system = 1;
989
990   /* Handle the -batch switch, which means don't do interactive display.  */
991   if (argmatch (argv, argc, "-batch", "--batch", 5, NULL, &skip_args))
992     {
993 #if 0 /* I don't think this is correct. */
994       inhibit_autoloads = 1;
995 #endif
996       noninteractive = 1;
997     }
998
999   if (argmatch (argv, argc, "-debug-paths", "--debug-paths",
1000                 11, NULL, &skip_args))
1001       debug_paths = 1;
1002
1003   /* Partially handle -no-autoloads, -no-early-packages and -vanilla.  Packages */
1004   /* are searched prior to the rest of the command line being parsed in */
1005   /* startup.el */
1006   if (argmatch (argv, argc, "-no-early-packages", "--no-early-packages",
1007                 6, NULL, &skip_args))
1008     {
1009       inhibit_early_packages = 1;
1010       skip_args--;
1011     }
1012 #ifdef HAVE_SHLIB
1013   if (argmatch (argv, argc, "-no-site-modules", "--no-site-modules",
1014                 9, NULL, &skip_args))
1015     {
1016       inhibit_site_modules = 1;
1017       skip_args--;
1018     }
1019 #else
1020   inhibit_site_modules = 1;
1021 #endif
1022   if (argmatch (argv, argc, "-vanilla", "--vanilla",
1023                 7, NULL, &skip_args))
1024     {
1025       inhibit_early_packages = 1;
1026       skip_args--;
1027     }
1028
1029   if (argmatch (argv, argc, "-no-autoloads", "--no-autoloads",
1030                 7, NULL, &skip_args))
1031     {
1032       /* Inhibit everything */
1033       inhibit_autoloads = 1;
1034       skip_args--;
1035     }
1036
1037   if (argmatch (argv, argc, "-debug-paths", "--debug-paths",
1038                 6, NULL, &skip_args))
1039     {
1040       debug_paths = 1;
1041       skip_args--;
1042     }
1043
1044
1045   /* Partially handle the -version and -help switches: they imply -batch,
1046      but are not removed from the list. */
1047   if (argmatch (argv, argc, "-help", "--help",   3, NULL, &skip_args))
1048     noninteractive = 1, skip_args--;
1049
1050   if (argmatch (argv, argc, "-version", "--version", 3, NULL, &skip_args) ||
1051       argmatch (argv, argc, "-V",    0,              2, NULL, &skip_args))
1052       noninteractive = 1, skip_args--;
1053
1054   /* Now, figure out which type of console is our first console. */
1055
1056   display_arg = 0;
1057
1058   if (noninteractive)
1059     display_use = "stream";
1060   else
1061     display_use = "tty";
1062
1063 #ifndef HAVE_TTY
1064   if (inhibit_window_system)
1065     fatal ("Sorry, this XEmacs was not compiled with TTY support");
1066 #endif
1067
1068 #ifdef HAVE_WINDOW_SYSTEM
1069   /* Stupid kludge to catch command-line display spec.  We can't
1070      handle this argument entirely in window-system-dependent code
1071      because we don't even know which window-system-dependent code
1072      to run until we've recognized this argument.  */
1073   if (!inhibit_window_system && !noninteractive)
1074     {
1075 #ifdef HAVE_X_WINDOWS
1076       char *dpy = 0;
1077       int count_before = skip_args;
1078
1079       if (argmatch (argv, argc, "-d", "--display", 3, &dpy, &skip_args) ||
1080           argmatch (argv, argc, "-display", 0,     3, &dpy, &skip_args))
1081         {
1082           display_arg = 1;
1083           display_use = "x";
1084         }
1085       /* If we have the form --display=NAME,
1086          convert it into  -d name.
1087          This requires inserting a new element into argv.  */
1088       if (dpy != 0 && skip_args - count_before == 1)
1089         {
1090           char **new = (char **) xmalloc (sizeof (char *) * (argc + 2));
1091           int j;
1092
1093           for (j = 0; j < count_before + 1; j++)
1094             new[j] = argv[j];
1095           new[count_before + 1] = "-d";
1096           new[count_before + 2] = dpy;
1097           for (j = count_before + 2; j <argc; j++)
1098             new[j + 1] = argv[j];
1099           argv = new;
1100           argc++;
1101         }
1102       /* Change --display to -d, when its arg is separate.  */
1103       else if (dpy != 0 && skip_args > count_before
1104                && argv[count_before + 1][1] == '-')
1105         argv[count_before + 1] = "-d";
1106
1107       /* Don't actually discard this arg.  */
1108       skip_args = count_before;
1109
1110       /* If there is a non-empty environment var DISPLAY, set
1111          `display_use', but not `display_arg', which is only to be set
1112          if the display was specified on the command line. */
1113       if ((dpy = getenv ("DISPLAY")) && dpy[0])
1114         display_use = "x";
1115
1116 #endif /* HAVE_X_WINDOWS */
1117 #ifdef HAVE_MS_WINDOWS
1118       if (strcmp(display_use, "x") != 0)
1119         display_use = "mswindows";
1120 #endif /* HAVE_MS_WINDOWS */
1121     }
1122 #endif /* HAVE_WINDOW_SYSTEM */
1123
1124   noninteractive1 = noninteractive;
1125
1126   /****** Now initialize everything *******/
1127
1128   /* First, do really basic environment initialization -- catching signals
1129      and the like.  These functions have no dependence on any part of
1130      the Lisp engine and need to be done both at dump time and at run time. */
1131
1132   init_signals_very_early ();
1133   init_data_very_early (); /* Catch math errors. */
1134 #ifdef LISP_FLOAT_TYPE
1135   init_floatfns_very_early (); /* Catch floating-point math errors. */
1136 #endif
1137   init_process_times_very_early (); /* Initialize our process timers.
1138                                        As early as possible, of course,
1139                                        so we can be fairly accurate. */
1140   init_intl_very_early (); /* set up the locale and domain for gettext and
1141                               such. */
1142
1143   /* Now initialize the Lisp engine and the like.  Done only during
1144      dumping.  No dependence on anything that may be in the user's
1145      environment when the dumped XEmacs is run.
1146
1147      We try to do things in an order that minimizes the non-obvious
1148      dependencies between functions. */
1149
1150   /* purify_flag 1 is correct even if CANNOT_DUMP.
1151    * loadup.el will set to nil at end. */
1152
1153   purify_flag = 0;
1154 #ifdef PDUMP
1155   if (restart)
1156     initialized = 1;
1157   else if (nodumpfile) {
1158     initialized = 0;
1159     purify_flag = 1;
1160   } else {
1161
1162     /* Keep command options from getting stomped.
1163
1164        Some LISP-visible options are changed by XEmacs _after_ the data is
1165        dumped in building a --pdump XEmacs, but _before_ it is restored in
1166        normal operation.  Thus the restored values overwrite the values
1167        XEmacs is getting at run-time.  Such variables must be saved here,
1168        and restored after loading the dumped data.
1169
1170        Boy, this is ugly, but how else to do it?
1171     */
1172
1173     /* noninteractive1 is saved in noninteractive, which isn't LISP-visible */
1174     int inhibit_early_packages_save = inhibit_early_packages;
1175     int inhibit_autoloads_save      = inhibit_autoloads;
1176     int debug_paths_save            = debug_paths;
1177     /* #### Give inhibit-site-lisp a command switch?  If so, uncomment: */
1178     /* int inhibit_site_lisp_save      = inhibit_site_lisp; */
1179     int inhibit_site_modules_save   = inhibit_site_modules;
1180
1181     initialized = pdump_load (argv[0]);
1182
1183     /* Now unstomp everything */
1184     noninteractive1        = noninteractive;
1185     inhibit_early_packages = inhibit_early_packages_save;
1186     inhibit_autoloads      = inhibit_autoloads_save;
1187     debug_paths            = debug_paths_save;
1188     /* #### Give inhibit-site-lisp a command switch?  If so, uncomment: */
1189     /* inhibit_site_lisp      = inhibit_site_lisp_save; */
1190     inhibit_site_modules   = inhibit_site_modules_save;
1191
1192     if (initialized)
1193       run_temacs_argc = -1;
1194     else
1195       purify_flag = 1;
1196   }
1197 #else
1198   if (!initialized)
1199     purify_flag = 1;
1200 #endif
1201
1202   if (!initialized)
1203     {
1204       /* Initialize things so that new Lisp objects
1205          can be created and objects can be staticpro'd.
1206          Must be basically the very first thing done
1207          because pretty much all of the initialization
1208          routines below create new objects. */
1209       init_alloc_once_early ();
1210
1211       /* Initialize Qnil, Qt, Qunbound, and the
1212          obarray.  After this, symbols can be
1213          interned.  This depends on init_alloc_once_early(). */
1214       init_symbols_once_early ();
1215
1216       /* Declare the basic symbols pertaining to errors,
1217          So that DEFERROR*() can be called. */
1218       init_errors_once_early ();
1219
1220       /* Make sure that opaque pointers can be created. */
1221       init_opaque_once_early ();
1222
1223       /* Now declare all the symbols and define all the Lisp primitives.
1224
1225          The *only* thing that the syms_of_*() functions are allowed to do
1226          is call one of the following:
1227
1228          INIT_LRECORD_IMPLEMENTATION()
1229          defsymbol(), DEFSYMBOL(), or DEFSYMBOL_MULTIWORD_PREDICATE()
1230          defsubr() (i.e. DEFSUBR)
1231          deferror(), DEFERROR(), or DEFERROR_STANDARD()
1232          defkeyword() or DEFKEYWORD()
1233
1234          Order does not matter in these functions.
1235          */
1236
1237       syms_of_abbrev ();
1238       syms_of_alloc ();
1239       syms_of_buffer ();
1240       syms_of_bytecode ();
1241       syms_of_callint ();
1242       syms_of_callproc ();
1243       syms_of_casefiddle ();
1244       syms_of_casetab ();
1245       syms_of_chartab ();
1246       syms_of_cmdloop ();
1247       syms_of_cmds ();
1248       syms_of_console ();
1249       syms_of_data ();
1250 #ifdef DEBUG_XEMACS
1251       syms_of_debug ();
1252       syms_of_tests ();
1253 #endif /* DEBUG_XEMACS */
1254       syms_of_device ();
1255 #ifdef HAVE_DIALOGS
1256       syms_of_dialog ();
1257 #endif
1258       syms_of_dired ();
1259       syms_of_doc ();
1260       syms_of_editfns ();
1261       syms_of_elhash ();
1262       syms_of_emacs ();
1263       syms_of_eval ();
1264 #ifdef HAVE_X_WINDOWS
1265       syms_of_event_Xt ();
1266 #endif
1267 #ifdef HAVE_DRAGNDROP
1268       syms_of_dragdrop ();
1269 #endif
1270       syms_of_event_stream ();
1271       syms_of_events ();
1272       syms_of_extents ();
1273       syms_of_faces ();
1274       syms_of_fileio ();
1275 #ifdef CLASH_DETECTION
1276       syms_of_filelock ();
1277 #endif /* CLASH_DETECTION */
1278       syms_of_floatfns ();
1279       syms_of_fns ();
1280       syms_of_font_lock ();
1281       syms_of_frame ();
1282       syms_of_general ();
1283       syms_of_glyphs ();
1284       syms_of_glyphs_eimage ();
1285       syms_of_glyphs_widget ();
1286       syms_of_gui ();
1287       syms_of_gutter ();
1288       syms_of_indent ();
1289       syms_of_intl ();
1290       syms_of_keymap ();
1291       syms_of_lread ();
1292       syms_of_macros ();
1293       syms_of_marker ();
1294       syms_of_md5 ();
1295 #ifdef HAVE_DATABASE
1296       syms_of_database ();
1297 #endif
1298 #ifdef HAVE_MENUBARS
1299       syms_of_menubar ();
1300 #endif
1301       syms_of_minibuf ();
1302 #ifdef HAVE_SHLIB
1303       syms_of_module ();
1304 #endif
1305       syms_of_objects ();
1306       syms_of_print ();
1307 #if !defined (NO_SUBPROCESSES)
1308       syms_of_process ();
1309 #ifdef HAVE_WIN32_PROCESSES
1310       syms_of_process_nt ();
1311 #endif
1312 #endif
1313       syms_of_profile ();
1314 #if defined (HAVE_MMAP) && defined (REL_ALLOC) && !defined(DOUG_LEA_MALLOC)
1315       syms_of_ralloc ();
1316 #endif /* HAVE_MMAP && REL_ALLOC */
1317       syms_of_rangetab ();
1318       syms_of_redisplay ();
1319       syms_of_search ();
1320       syms_of_select ();
1321       syms_of_signal ();
1322       syms_of_sound ();
1323       syms_of_specifier ();
1324       syms_of_symbols ();
1325       syms_of_syntax ();
1326 #ifdef HAVE_SCROLLBARS
1327       syms_of_scrollbar ();
1328 #endif
1329 #ifdef HAVE_TOOLBARS
1330       syms_of_toolbar ();
1331 #endif
1332       syms_of_undo ();
1333       syms_of_widget ();
1334       syms_of_window ();
1335
1336 #ifdef HAVE_TTY
1337       syms_of_console_tty ();
1338       syms_of_device_tty ();
1339       syms_of_objects_tty ();
1340 #endif
1341
1342 #ifdef HAVE_X_WINDOWS
1343 #ifdef HAVE_BALLOON_HELP
1344       syms_of_balloon_x ();
1345 #endif
1346       syms_of_device_x ();
1347 #ifdef HAVE_DIALOGS
1348       syms_of_dialog_x ();
1349 #endif
1350       syms_of_frame_x ();
1351       syms_of_glyphs_x ();
1352       syms_of_objects_x ();
1353 #ifdef HAVE_MENUBARS
1354       syms_of_menubar_x ();
1355 #endif
1356       syms_of_select_x ();
1357 #if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS)
1358       syms_of_gui_x ();
1359 #endif
1360 #ifdef HAVE_XIM
1361 #ifdef XIM_XLIB
1362       syms_of_input_method_xlib ();
1363 #endif
1364 #endif /* HAVE_XIM */
1365 #endif /* HAVE_X_WINDOWS */
1366
1367 #ifdef HAVE_MS_WINDOWS
1368       syms_of_console_mswindows ();
1369       syms_of_device_mswindows ();
1370       syms_of_dialog_mswindows ();
1371       syms_of_frame_mswindows ();
1372       syms_of_objects_mswindows ();
1373       syms_of_select_mswindows ();
1374       syms_of_glyphs_mswindows ();
1375       syms_of_gui_mswindows ();
1376 #ifdef HAVE_MENUBARS
1377       syms_of_menubar_mswindows ();
1378 #endif
1379 #ifdef HAVE_SCROLLBARS
1380       syms_of_scrollbar_mswindows ();
1381 #endif
1382 #endif  /* HAVE_MS_WINDOWS */
1383 #ifdef HAVE_MSW_C_DIRED
1384       syms_of_dired_mswindows ();
1385 #endif
1386 #ifdef WIN32_NATIVE
1387       syms_of_ntproc ();
1388 #endif
1389 #if defined (WIN32_NATIVE) || defined (CYGWIN)
1390       syms_of_win32 ();
1391 #endif
1392
1393 #ifdef MULE
1394       syms_of_mule ();
1395       syms_of_mule_ccl ();
1396       syms_of_mule_charset ();
1397 #endif
1398 #ifdef FILE_CODING
1399       syms_of_file_coding ();
1400 #endif
1401 #ifdef MULE
1402 #ifdef HAVE_WNN
1403       syms_of_mule_wnn ();
1404 #endif
1405 #ifdef HAVE_CANNA
1406       syms_of_mule_canna ();
1407 #endif /* HAVE_CANNA */
1408 #endif /* MULE */
1409
1410 #ifdef SYMS_SYSTEM
1411       SYMS_SYSTEM;
1412 #endif
1413
1414 #ifdef SYMS_MACHINE
1415       SYMS_MACHINE;
1416 #endif
1417
1418       /*
1419 #if defined (GNU_MALLOC) && \
1420     defined (ERROR_CHECK_MALLOC) && \
1421     !defined (HAVE_LIBMCHECK)
1422       */
1423       /* Prior to XEmacs 21, this was `#if 0'ed out. -slb */
1424 #if defined (LOSING_GCC_DESTRUCTOR_FREE_BUG)
1425       syms_of_free_hook ();
1426 #endif
1427
1428 #ifdef TOOLTALK
1429       syms_of_tooltalk ();
1430 #endif
1431
1432 #ifdef SUNPRO
1433       syms_of_sunpro ();
1434 #endif
1435
1436 #ifdef HAVE_LDAP
1437       syms_of_eldap ();
1438 #endif
1439
1440 #ifdef HAVE_GPM
1441       syms_of_gpmevent ();
1442 #endif
1443
1444 #ifdef HAVE_POSTGRESQL
1445       syms_of_postgresql ();
1446 #endif
1447
1448       /* Now create the subtypes for the types that have them.
1449          We do this before the vars_*() because more symbols
1450          may get initialized here. */
1451
1452       /* Now initialize the console types and associated symbols.
1453          Other than the first function below, the functions may
1454          make exactly the following function/macro calls:
1455
1456          INITIALIZE_CONSOLE_TYPE()
1457          CONSOLE_HAS_METHOD()
1458
1459          For any given console type, the former macro must be called
1460          before the any calls to the latter macro. */
1461
1462       console_type_create ();
1463
1464       console_type_create_stream ();
1465
1466 #ifdef HAVE_TTY
1467       console_type_create_tty ();
1468       console_type_create_device_tty ();
1469       console_type_create_frame_tty ();
1470       console_type_create_objects_tty ();
1471       console_type_create_redisplay_tty ();
1472 #endif
1473
1474 #ifdef HAVE_X_WINDOWS
1475       console_type_create_x ();
1476       console_type_create_device_x ();
1477       console_type_create_frame_x ();
1478       console_type_create_glyphs_x ();
1479       console_type_create_select_x ();
1480 #ifdef HAVE_MENUBARS
1481       console_type_create_menubar_x ();
1482 #endif
1483       console_type_create_objects_x ();
1484       console_type_create_redisplay_x ();
1485 #ifdef HAVE_SCROLLBARS
1486       console_type_create_scrollbar_x ();
1487 #endif
1488 #ifdef HAVE_TOOLBARS
1489       console_type_create_toolbar_x ();
1490 #endif
1491 #ifdef HAVE_DIALOGS
1492       console_type_create_dialog_x ();
1493 #endif
1494 #endif /* HAVE_X_WINDOWS */
1495
1496 #ifdef HAVE_MS_WINDOWS
1497       console_type_create_mswindows ();
1498       console_type_create_device_mswindows ();
1499       console_type_create_frame_mswindows ();
1500       console_type_create_objects_mswindows ();
1501       console_type_create_redisplay_mswindows ();
1502       console_type_create_glyphs_mswindows ();
1503       console_type_create_select_mswindows ();
1504 # ifdef HAVE_SCROLLBARS
1505       console_type_create_scrollbar_mswindows ();
1506 # endif
1507 #ifdef HAVE_MENUBARS
1508       console_type_create_menubar_mswindows ();
1509 #endif
1510 #ifdef HAVE_TOOLBARS
1511       console_type_create_toolbar_mswindows ();
1512 #endif
1513 #ifdef HAVE_DIALOGS
1514       console_type_create_dialog_mswindows ();
1515 #endif
1516 #endif
1517
1518       /* Now initialize the specifier types and associated symbols.
1519          Other than the first function below, the functions may
1520          make exactly the following function/macro calls:
1521
1522          INITIALIZE_SPECIFIER_TYPE()
1523          SPECIFIER_HAS_METHOD()
1524
1525          For any given specifier type, the former macro must be called
1526          before the any calls to the latter macro. */
1527
1528       specifier_type_create ();
1529
1530       specifier_type_create_image ();
1531       specifier_type_create_gutter ();
1532       specifier_type_create_objects ();
1533 #ifdef HAVE_TOOLBARS
1534       specifier_type_create_toolbar ();
1535 #endif
1536
1537       /* Now initialize the structure types and associated symbols.
1538          Other than the first function below, the functions may
1539          make exactly the following function/macro calls:
1540
1541          define_structure_type()
1542          define_structure_type_keyword()
1543
1544          */
1545
1546       structure_type_create ();
1547
1548       structure_type_create_chartab ();
1549       structure_type_create_faces ();
1550       structure_type_create_rangetab ();
1551       structure_type_create_hash_table ();
1552
1553       /* Now initialize the image instantiator formats and associated symbols.
1554          Other than the first function below, the functions may
1555          make exactly the following function/macro calls:
1556
1557          INITIALIZE_IMAGE_INSTANTIATOR_FORMAT()
1558          IIFORMAT_HAS_METHOD()
1559          IIFORMAT_VALID_KEYWORD()
1560
1561          For any given image instantiator format, the first macro must be
1562          called before the any calls to the other macros. */
1563
1564       image_instantiator_format_create ();
1565       image_instantiator_format_create_glyphs_eimage ();
1566       image_instantiator_format_create_glyphs_widget ();
1567 #ifdef HAVE_TTY
1568       image_instantiator_format_create_glyphs_tty ();
1569 #endif
1570 #ifdef HAVE_X_WINDOWS
1571       image_instantiator_format_create_glyphs_x ();
1572 #endif /* HAVE_X_WINDOWS */
1573 #ifdef HAVE_MS_WINDOWS
1574       image_instantiator_format_create_glyphs_mswindows ();
1575 #endif /* HAVE_MSWINDOWS_WINDOWS */
1576
1577       /* Now initialize the lstream types and associated symbols.
1578          Other than the first function below, the functions may
1579          make exactly the following function/macro calls:
1580
1581          LSTREAM_HAS_METHOD()
1582
1583          */
1584
1585       lstream_type_create ();
1586 #ifdef FILE_CODING
1587       lstream_type_create_file_coding ();
1588 #endif
1589 #if defined (HAVE_MS_WINDOWS) && !defined(HAVE_MSG_SELECT)
1590       lstream_type_create_mswindows_selectable ();
1591 #endif
1592
1593       /* Initialize processes implementation.
1594          The functions may make exactly the following function/macro calls:
1595
1596          PROCESS_HAS_METHOD()
1597       */
1598 #ifdef HAVE_UNIX_PROCESSES
1599       process_type_create_unix ();
1600 #endif
1601 #ifdef HAVE_WIN32_PROCESSES
1602       process_type_create_nt ();
1603 #endif
1604
1605       /* Now initialize most variables.
1606
1607          These functions may do exactly the following:
1608
1609          DEFVAR_INT()
1610          DEFVAR_LISP()
1611          DEFVAR_BOOL()
1612          DEFER_GETTEXT()
1613          Dynarr_*()
1614          Blocktype_*()
1615          staticpro()
1616          Fprovide(symbol)
1617          intern()
1618          Fput()
1619          xmalloc()
1620          defsymbol(), if it's absolutely necessary and you're sure that
1621            the symbol isn't referenced anywhere else in the initialization
1622            code
1623          Fset() on a symbol that is unbound
1624          assigning a symbol or constant value to a variable
1625          using a global variable that has been initialized
1626            earlier on in the same function
1627
1628          Any of the object-creating functions in alloc.c: e.g.
1629
1630          make_pure_*()
1631          make_string()
1632          build_string()
1633          make_vector()
1634          make_int()
1635          make_extent()
1636          alloc_lcrecord()
1637          Fcons()
1638          listN()
1639          make_opaque_ptr()
1640
1641          perhaps a few others.
1642
1643          NB:  Initialization or assignment should not be done here to certain
1644            variables settable from the command line.  See the comment above
1645            the call to pdump_load() in main_1().  This caveat should only
1646            apply to vars_of_emacs().
1647        */
1648
1649       /* Now allow Fprovide() statements to be made. */
1650       init_provide_once ();
1651
1652       /* Do that before any specifier creation (esp. vars_of_glyphs()) */
1653       vars_of_specifier ();
1654
1655       vars_of_abbrev ();
1656       vars_of_alloc ();
1657       vars_of_buffer ();
1658       vars_of_bytecode ();
1659       vars_of_callint ();
1660       vars_of_callproc ();
1661       vars_of_chartab ();
1662       vars_of_cmdloop ();
1663       vars_of_cmds ();
1664       vars_of_console ();
1665       vars_of_data ();
1666 #ifdef DEBUG_XEMACS
1667       vars_of_debug ();
1668       vars_of_tests ();
1669 #endif
1670       vars_of_console_stream ();
1671       vars_of_device ();
1672 #ifdef HAVE_DIALOGS
1673       vars_of_dialog ();
1674 #endif
1675       vars_of_dired ();
1676       vars_of_doc ();
1677 #ifdef HAVE_DRAGNDROP
1678       vars_of_dragdrop ();
1679 #endif
1680       vars_of_editfns ();
1681       vars_of_elhash ();
1682       vars_of_emacs ();
1683       vars_of_eval ();
1684
1685 #ifdef HAVE_X_WINDOWS
1686       vars_of_event_Xt ();
1687 #endif
1688 #if defined(HAVE_TTY) && (defined (DEBUG_TTY_EVENT_STREAM) || !defined (HAVE_X_WINDOWS))
1689       vars_of_event_tty ();
1690 #endif
1691 #ifdef HAVE_MS_WINDOWS
1692       vars_of_event_mswindows ();
1693 #endif
1694       vars_of_event_stream ();
1695
1696       vars_of_events ();
1697       vars_of_extents ();
1698       vars_of_faces ();
1699       vars_of_fileio ();
1700 #ifdef CLASH_DETECTION
1701       vars_of_filelock ();
1702 #endif
1703       vars_of_floatfns ();
1704       vars_of_font_lock ();
1705       vars_of_frame ();
1706       vars_of_glyphs ();
1707       vars_of_glyphs_eimage ();
1708       vars_of_glyphs_widget ();
1709       vars_of_gui ();
1710       vars_of_gutter ();
1711       vars_of_indent ();
1712       vars_of_insdel ();
1713       vars_of_intl ();
1714 #ifdef HAVE_XIM
1715 #ifdef XIM_MOTIF
1716       vars_of_input_method_motif ();
1717 #else /* XIM_XLIB */
1718       vars_of_input_method_xlib ();
1719 #endif
1720 #endif /* HAVE_XIM */
1721       vars_of_keymap ();
1722       vars_of_lread ();
1723       vars_of_lstream ();
1724       vars_of_macros ();
1725       vars_of_md5 ();
1726 #ifdef HAVE_DATABASE
1727       vars_of_database ();
1728 #endif
1729 #ifdef HAVE_MENUBARS
1730       vars_of_menubar ();
1731 #endif
1732       vars_of_minibuf ();
1733 #ifdef HAVE_SHLIB
1734       vars_of_module ();
1735 #endif
1736 #ifdef WIN32_NATIVE
1737       vars_of_nt ();
1738       vars_of_ntproc ();
1739 #endif
1740       vars_of_objects ();
1741       vars_of_print ();
1742
1743 #ifndef NO_SUBPROCESSES
1744       vars_of_process ();
1745 #ifdef HAVE_UNIX_PROCESSES
1746       vars_of_process_unix ();
1747 #endif
1748 #ifdef HAVE_WIN32_PROCESSES
1749       vars_of_process_nt ();
1750 #endif
1751 #endif
1752
1753       vars_of_profile ();
1754 #if defined (HAVE_MMAP) && defined (REL_ALLOC) && !defined(DOUG_LEA_MALLOC)
1755       vars_of_ralloc ();
1756 #endif /* HAVE_MMAP && REL_ALLOC */
1757       vars_of_redisplay ();
1758 #ifdef HAVE_SCROLLBARS
1759       vars_of_scrollbar ();
1760 #endif
1761       vars_of_search ();
1762       vars_of_select ();
1763       vars_of_sound ();
1764       vars_of_symbols ();
1765       vars_of_syntax ();
1766 #ifdef HAVE_TOOLBARS
1767       vars_of_toolbar ();
1768 #endif
1769       vars_of_undo ();
1770       vars_of_window ();
1771
1772 #ifdef HAVE_TTY
1773       vars_of_console_tty ();
1774       vars_of_frame_tty ();
1775       vars_of_objects_tty ();
1776 #endif
1777
1778 #ifdef HAVE_X_WINDOWS
1779 #ifdef HAVE_BALLOON_HELP
1780       vars_of_balloon_x ();
1781 #endif
1782       vars_of_device_x ();
1783 #ifdef HAVE_DIALOGS
1784       vars_of_dialog_x ();
1785 #endif
1786       vars_of_frame_x ();
1787       vars_of_glyphs_x ();
1788 #ifdef HAVE_MENUBARS
1789       vars_of_menubar_x ();
1790 #endif
1791       vars_of_objects_x ();
1792       vars_of_select_x ();
1793 #ifdef HAVE_SCROLLBARS
1794       vars_of_scrollbar_x ();
1795 #endif
1796 #if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS)
1797       vars_of_gui_x ();
1798 #endif
1799 #endif /* HAVE_X_WINDOWS */
1800
1801 #ifdef HAVE_MS_WINDOWS
1802       vars_of_device_mswindows ();
1803       vars_of_console_mswindows ();
1804       vars_of_frame_mswindows ();
1805       vars_of_objects_mswindows ();
1806       vars_of_select_mswindows ();
1807       vars_of_glyphs_mswindows ();
1808 #ifdef HAVE_SCROLLBARS
1809       vars_of_scrollbar_mswindows ();
1810 #endif
1811 #ifdef HAVE_MENUBARS
1812       vars_of_menubar_mswindows ();
1813 #endif
1814 #ifdef HAVE_MSW_C_DIRED
1815       vars_of_dired_mswindows ();
1816 #endif
1817 #ifdef HAVE_DIALOGS
1818       vars_of_dialog_mswindows ();
1819 #endif
1820 #endif  /* HAVE_MS_WINDOWS */
1821
1822 #ifdef MULE
1823       vars_of_mule ();
1824       vars_of_mule_ccl ();
1825       vars_of_mule_charset ();
1826 #endif
1827 #ifdef FILE_CODING
1828       vars_of_file_coding ();
1829 #endif
1830 #ifdef MULE
1831 #ifdef HAVE_WNN
1832       vars_of_mule_wnn ();
1833 #endif
1834 #ifdef HAVE_CANNA
1835       vars_of_mule_canna ();
1836 #endif /* HAVE_CANNA */
1837 #endif /* MULE */
1838
1839 #ifdef TOOLTALK
1840       vars_of_tooltalk ();
1841 #endif
1842
1843 #ifdef SUNPRO
1844       vars_of_sunpro ();
1845 #endif
1846
1847 #ifdef HAVE_LDAP
1848       vars_of_eldap ();
1849 #endif
1850
1851 #ifdef HAVE_POSTGRESQL
1852       vars_of_postgresql();
1853 #endif
1854
1855 #ifdef HAVE_GPM
1856       vars_of_gpmevent ();
1857 #endif
1858
1859       /* Now initialize any specifier variables.  We do this later
1860          because it has some dependence on the vars initialized
1861          above.
1862
1863          These functions should *only* initialize specifier variables,
1864          and may make use of the following functions/macros in addition
1865          to the ones listed above:
1866
1867          DEFVAR_SPECIFIER()
1868          Fmake_specifier()
1869          set_specifier_fallback()
1870          set_specifier_caching()
1871          */
1872
1873       specifier_vars_of_glyphs ();
1874       specifier_vars_of_gutter ();
1875 #ifdef HAVE_MENUBARS
1876       specifier_vars_of_menubar ();
1877 #endif
1878       specifier_vars_of_redisplay ();
1879 #ifdef HAVE_SCROLLBARS
1880       specifier_vars_of_scrollbar ();
1881 #endif
1882 #ifdef HAVE_TOOLBARS
1883       specifier_vars_of_toolbar ();
1884 #endif
1885       specifier_vars_of_window ();
1886
1887       /* Now comes all the rest of the variables that couldn't
1888          be handled above.  There may be dependencies on variables
1889          initialized above, and dependencies between one complex_vars_()
1890          function and another. */
1891
1892       /* Calls Fmake_range_table(). */
1893       complex_vars_of_regex ();
1894       /* Calls Fmake_range_table(). */
1895       complex_vars_of_search ();
1896
1897       /* Calls make_lisp_hash_table(). */
1898       complex_vars_of_extents ();
1899
1900       /* Depends on hash tables and specifiers. */
1901       complex_vars_of_faces ();
1902
1903 #ifdef MULE
1904       /* These two depend on hash tables and various variables declared
1905          earlier.  The second may also depend on the first. */
1906       complex_vars_of_mule_charset ();
1907 #endif
1908 #ifdef FILE_CODING
1909       complex_vars_of_file_coding ();
1910 #endif
1911
1912       /* This calls allocate_glyph(), which creates specifiers
1913          and also relies on a variable (Vthe_nothing_vector) initialized
1914          above.  It also calls make_ext_string(), which under Mule
1915          could require that the charsets be initialized. */
1916       complex_vars_of_glyphs ();
1917
1918       /* These rely on the glyphs just created in the previous function,
1919          and call Fadd_spec_to_specifier(), which relies on various
1920          variables initialized above. */
1921 #ifdef HAVE_X_WINDOWS
1922       complex_vars_of_glyphs_x ();
1923 #endif
1924 #ifdef HAVE_MS_WINDOWS
1925       complex_vars_of_glyphs_mswindows ();
1926 #endif
1927
1928       /* This calls Fmake_glyph_internal(). */
1929       complex_vars_of_alloc ();
1930
1931       /* This calls Fmake_glyph_internal(). */
1932 #ifdef HAVE_MENUBARS
1933       complex_vars_of_menubar ();
1934 #endif
1935
1936       /* This calls Fmake_glyph_internal(). */
1937 #ifdef HAVE_SCROLLBARS
1938       complex_vars_of_scrollbar ();
1939 #endif
1940
1941       /* This calls allocate_glyph(). */
1942       complex_vars_of_frame ();
1943
1944       /* This calls Fcopy_category_table() under Mule, which calls who
1945          knows what. */
1946       complex_vars_of_chartab ();
1947
1948       /* This calls set_string_char(), which (under Mule) depends on the
1949          charsets being initialized. */
1950       complex_vars_of_casetab ();
1951
1952       /* This calls Fcopy_syntax_table(), which relies on char tables. */
1953       complex_vars_of_syntax ();
1954
1955       /* This initializes buffer-local variables, sets things up so
1956          that buffers can be created, and creates a couple of basic
1957          buffers.  This depends on Vstandard_syntax_table and
1958          Vstandard_category_table (initialized in the previous
1959          functions), as well as a whole horde of variables that may
1960          have been initialized above. */
1961       complex_vars_of_buffer ();
1962
1963       /* This initializes console-local variables. */
1964       complex_vars_of_console ();
1965
1966       /* This creates a couple more buffers, and depends on the
1967          previous function. */
1968       complex_vars_of_minibuf ();
1969
1970       /* These two might call Ffile_name_as_directory(), which
1971          might depend on all sorts of things; I'm not sure. */
1972       complex_vars_of_emacs ();
1973
1974       /* This creates a couple of basic keymaps and depends on Lisp
1975          hash tables and Ffset() (both of which depend on some variables
1976          initialized in the vars_of_*() section) and possibly other
1977          stuff. */
1978       complex_vars_of_keymap ();
1979
1980       /* Calls make_lisp_hash_table() and creates a keymap */
1981       complex_vars_of_event_stream ();
1982
1983 #ifdef ERROR_CHECK_GC
1984       {
1985         extern int always_gc;
1986         if (always_gc)                /* purification debugging hack */
1987           garbage_collect_1 ();
1988       }
1989 #endif
1990 #ifdef PDUMP
1991     } else if (!restart) {            /* after successful pdump_load() */
1992       reinit_alloc_once_early ();
1993       reinit_symbols_once_early ();
1994       reinit_opaque_once_early ();
1995
1996       reinit_console_type_create_stream ();
1997 #ifdef HAVE_TTY
1998       reinit_console_type_create_tty ();
1999 #endif
2000 #ifdef HAVE_X_WINDOWS
2001       reinit_console_type_create_x ();
2002       reinit_console_type_create_device_x ();
2003 #endif
2004 #ifdef HAVE_MS_WINDOWS
2005       reinit_console_type_create_mswindows ();
2006 #endif
2007
2008       reinit_specifier_type_create ();
2009       reinit_specifier_type_create_image ();
2010       reinit_specifier_type_create_gutter ();
2011       reinit_specifier_type_create_objects ();
2012 #ifdef HAVE_TOOLBARS
2013       reinit_specifier_type_create_toolbar ();
2014 #endif
2015
2016       structure_type_create ();
2017
2018       structure_type_create_chartab ();
2019       structure_type_create_faces ();
2020       structure_type_create_rangetab ();
2021       structure_type_create_hash_table ();
2022
2023       lstream_type_create ();
2024 #ifdef FILE_CODING
2025       lstream_type_create_file_coding ();
2026 #endif
2027 #if defined (HAVE_MS_WINDOWS) && !defined(HAVE_MSG_SELECT)
2028       lstream_type_create_mswindows_selectable ();
2029 #endif
2030 #ifdef HAVE_UNIX_PROCESSES
2031       process_type_create_unix ();
2032 #endif
2033 #ifdef HAVE_WIN32_PROCESSES
2034       process_type_create_nt ();
2035 #endif
2036
2037       reinit_vars_of_buffer ();
2038       reinit_vars_of_console ();
2039 #ifdef DEBUG_XEMACS
2040       reinit_vars_of_debug ();
2041 #endif
2042       reinit_vars_of_device ();
2043       reinit_vars_of_eval ();
2044 #ifdef HAVE_X_WINDOWS
2045       reinit_vars_of_event_Xt ();
2046 #endif
2047 #if defined(HAVE_TTY) && (defined (DEBUG_TTY_EVENT_STREAM) || !defined (HAVE_X_WINDOWS))
2048       reinit_vars_of_event_tty ();
2049 #endif
2050 #ifdef HAVE_MS_WINDOWS
2051       reinit_vars_of_event_mswindows ();
2052 #endif
2053       reinit_vars_of_event_stream ();
2054       reinit_vars_of_events ();
2055       reinit_vars_of_extents ();
2056       reinit_vars_of_fileio ();
2057       reinit_vars_of_font_lock ();
2058       reinit_vars_of_glyphs ();
2059       reinit_vars_of_glyphs_widget ();
2060       reinit_vars_of_insdel ();
2061       reinit_vars_of_lread ();
2062       reinit_vars_of_lstream ();
2063       reinit_vars_of_minibuf ();
2064 #ifdef HAVE_SHLIB
2065       reinit_vars_of_module ();
2066 #endif
2067       reinit_vars_of_objects ();
2068       reinit_vars_of_print ();
2069       reinit_vars_of_search ();
2070       reinit_vars_of_undo ();
2071       reinit_vars_of_window ();
2072
2073 #ifdef HAVE_MS_WINDOWS
2074       reinit_vars_of_frame_mswindows ();
2075 #endif
2076
2077 #ifdef HAVE_X_WINDOWS
2078       reinit_vars_of_device_x ();
2079 #ifdef HAVE_SCROLLBARS
2080       reinit_vars_of_scrollbar_x ();
2081 #endif
2082 #ifdef HAVE_MENUBARS
2083       reinit_vars_of_menubar_x ();
2084 #endif
2085       reinit_vars_of_select_x ();
2086 #if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS)
2087       reinit_vars_of_gui_x ();
2088 #endif
2089 #endif /* HAVE_X_WINDOWS */
2090
2091 #if defined(MULE) && defined(HAVE_WNN)
2092       reinit_vars_of_mule_wnn ();
2093 #endif
2094
2095       reinit_complex_vars_of_buffer ();
2096       reinit_complex_vars_of_console ();
2097       reinit_complex_vars_of_minibuf ();
2098 #endif /* PDUMP */
2099     }
2100
2101
2102   /* CONGRATULATIONS!!!  We have successfully initialized the Lisp
2103      engine. */
2104
2105   if (initialized)
2106     {
2107       /* Stuff that should not be done at dump time, including stuff that
2108          needs to be reset at run time.  Order below should not matter.
2109
2110          Many initializations taken from the environment should go here. */
2111       reinit_alloc ();
2112       reinit_eval ();
2113 #ifdef MULE_REGEXP
2114       reinit_mule_category ();
2115 #endif
2116 #ifdef HAVE_POSTGRESQL
2117       init_postgresql_from_environment();
2118 #endif
2119     }
2120
2121   /* Now do further initialization/setup of stuff that is not needed by the
2122      syms_of_() routines.  This involves stuff that only is enabled in
2123      an interactive run (redisplay, user input, etc.) and stuff that is
2124      not needed until we start loading Lisp code (the reader).  A lot
2125      of this stuff involves querying the current environment and needs
2126      to be done both at dump time and at run time. */
2127
2128   init_initial_directory();             /* get the directory to use for the
2129                                            "*scratch*" buffer, etc. */
2130
2131 #ifdef WIN32_NATIVE
2132   /*
2133    * For Win32, call init_environment() now, so that environment/registry
2134    * variables will be properly entered into Vprocess_environment.
2135    */
2136   init_environment();
2137 #endif
2138
2139   init_callproc ();     /* Set up the process environment (so that egetenv
2140                            works), the basic directory variables
2141                            (exec-directory and so on), and stuff
2142                            related to subprocesses.  This should be
2143                            first because many of the functions below
2144                            call egetenv() to get environment variables. */
2145   init_lread ();        /* Set up the Lisp reader. */
2146   init_cmdargs (argc, (Extbyte **) argv,
2147                 skip_args);     /* Create list Vcommand_line_args */
2148   init_buffer ();       /* Set default directory of *scratch* buffer */
2149
2150 #ifdef WIN32_NATIVE
2151   init_ntproc();
2152 #endif
2153
2154   init_redisplay ();      /* Determine terminal type.
2155                              init_sys_modes uses results */
2156   init_frame ();
2157   init_event_stream (); /* Set up so we can get user input. */
2158   init_macros (); /* set up so we can run macros. */
2159   init_editfns (); /* Determine the name of the user we're running as */
2160   init_xemacs_process (); /* set up for calling subprocesses */
2161 #ifdef SUNPRO
2162   init_sunpro (); /* Set up Sunpro usage tracking */
2163 #endif
2164 #if defined (WIN32_NATIVE) || defined (CYGWIN)
2165   init_win32 ();
2166 #endif
2167 #if defined (HAVE_NATIVE_SOUND) && defined (hp9000s800)
2168   init_hpplay ();
2169 #endif
2170 #ifdef HAVE_TTY
2171   init_device_tty ();
2172 #endif
2173   init_console_stream (restart); /* Create the first console */
2174
2175   /* try to get the actual pathname of the exec file we are running */
2176   if (!restart)
2177   {
2178     Vinvocation_name = Fcar (Vcommand_line_args);
2179     if (XSTRING_DATA(Vinvocation_name)[0] == '-')
2180       {
2181         /* XEmacs as a login shell, oh goody! */
2182         Vinvocation_name = build_string(getenv("SHELL"));
2183       }
2184     Vinvocation_directory = Vinvocation_name;
2185
2186     if (!NILP (Ffile_name_directory (Vinvocation_name)))
2187       {
2188         /* invocation-name includes a directory component -- presumably it
2189            is relative to cwd, not $PATH */
2190         Vinvocation_directory = Fexpand_file_name (Vinvocation_name,
2191                                                    Qnil);
2192         Vinvocation_path = Qnil;
2193       }
2194     else
2195       {
2196         Vinvocation_path = decode_env_path ("PATH", NULL);
2197         locate_file (Vinvocation_path, Vinvocation_name,
2198                      Vlisp_EXEC_SUFFIXES,
2199                      &Vinvocation_directory, X_OK);
2200       }
2201
2202     if (NILP (Vinvocation_directory))
2203       Vinvocation_directory = Vinvocation_name;
2204
2205     Vinvocation_name = Ffile_name_nondirectory (Vinvocation_directory);
2206     Vinvocation_directory = Ffile_name_directory (Vinvocation_directory);
2207   }
2208
2209 #if defined(HAVE_SHLIB) && !defined(WIN32_NATIVE)
2210   /* This is Unix only.  MS Windows NT has a library call that does
2211      The Right Thing on that system.  Rumor has it, this must be
2212      called for GNU dld in temacs and xemacs.  */
2213   {
2214     char *buf = (char *)alloca (XSTRING_LENGTH (Vinvocation_directory)
2215                                 + XSTRING_LENGTH (Vinvocation_name)
2216                                 + 2);
2217     sprintf (buf, "%s/%s", XSTRING_DATA (Vinvocation_directory),
2218              XSTRING_DATA (Vinvocation_name));
2219
2220     /* All we can do is cry if an error happens, so ignore it. */
2221     (void) dll_init (buf);
2222   }
2223 #endif
2224
2225 #if defined (LOCALTIME_CACHE) && defined (HAVE_TZSET)
2226   /* sun's localtime() has a bug.  it caches the value of the time
2227      zone rather than looking it up every time.  Since localtime() is
2228      called to bolt the undumping time into the undumped emacs, this
2229      results in localtime() ignoring the TZ environment variable.
2230      This flushes the new TZ value into localtime(). */
2231   tzset ();
2232 #endif /* LOCALTIME_CACHE and TZSET */
2233
2234   load_me = Qnil;
2235   if (!initialized)
2236     {
2237       /* Handle -l loadup-and-dump, args passed by Makefile. */
2238       if (argc > 2 + skip_args && !strcmp (argv[1 + skip_args], "-l"))
2239         load_me = build_string (argv[2 + skip_args]);
2240 #if 0 /* CANNOT_DUMP - this can never be right in XEmacs --andyp */
2241       /* Unless next switch is -nl, load "loadup.el" first thing.  */
2242       if (!(argc > 1 + skip_args && !strcmp (argv[1 + skip_args], "-nl")))
2243         load_me = build_string ("loadup.el");
2244 #endif /* CANNOT_DUMP */
2245     }
2246
2247 #ifdef QUANTIFY
2248   if (initialized)
2249     quantify_start_recording_data ();
2250 #endif /* QUANTIFY */
2251
2252   initialized = 1;
2253
2254   /* This never returns.  */
2255   initial_command_loop (load_me);
2256   /* NOTREACHED */
2257 }
2258
2259 \f
2260 /* Sort the args so we can find the most important ones
2261    at the beginning of argv.  */
2262
2263 /* First, here's a table of all the standard options.  */
2264
2265 struct standard_args
2266 {
2267   const char *name;
2268   const char *longname;
2269   int priority;
2270   int nargs;
2271 };
2272
2273 static const struct standard_args standard_args[] =
2274 {
2275   /* Handled by main_1 above: */
2276   { "-sd", "--show-dump-id", 105, 0 },
2277   { "-t", "--terminal", 100, 1 },
2278   { "-nd", "--no-dump-file", 95, 0 },
2279   { "-nw", "--no-windows", 90, 0 },
2280   { "-batch", "--batch", 85, 0 },
2281   { "-debug-paths", "--debug-paths", 82, 0 },
2282   { "-help", "--help", 80, 0 },
2283   { "-version", "--version", 75, 0 },
2284   { "-V", 0, 75, 0 },
2285   { "-d", "--display", 80, 1 },
2286   { "-display", 0, 80, 1 },
2287   { "-NXHost",  0, 79, 0 },
2288   { "-MachLaunch", 0, 79, 0},
2289
2290   /* Handled by command-line-early in startup.el: */
2291   { "-q", "--no-init-file", 50, 0 },
2292   { "-unmapped", 0, 50, 0 },
2293   { "-no-init-file", 0, 50, 0 },
2294   { "-vanilla", "--vanilla", 50, 0 },
2295   { "-no-autoloads", "--no-autoloads", 50, 0 },
2296   { "-no-site-file", "--no-site-file", 40, 0 },
2297   { "-no-early-packages", "--no-early-packages", 35, 0 },
2298   { "-u", "--user", 30, 1 },
2299   { "-user", 0, 30, 1 },
2300   { "-debug-init", "--debug-init", 20, 0 },
2301   { "-debug-paths", "--debug-paths", 20, 0 },
2302
2303   /* Xt options: */
2304   { "-i", "--icon-type", 15, 0 },
2305   { "-itype", 0, 15, 0 },
2306   { "-iconic", "--iconic", 15, 0 },
2307   { "-bg", "--background-color", 10, 1 },
2308   { "-background", 0, 10, 1 },
2309   { "-fg", "--foreground-color", 10, 1 },
2310   { "-foreground", 0, 10, 1 },
2311   { "-bd", "--border-color", 10, 1 },
2312   { "-bw", "--border-width", 10, 1 },
2313   { "-ib", "--internal-border", 10, 1 },
2314   { "-ms", "--mouse-color", 10, 1 },
2315   { "-cr", "--cursor-color", 10, 1 },
2316   { "-fn", "--font", 10, 1 },
2317   { "-font", 0, 10, 1 },
2318   { "-g", "--geometry", 10, 1 },
2319   { "-geometry", 0, 10, 1 },
2320   { "-T", "--title", 10, 1 },
2321   { "-title", 0, 10, 1 },
2322   { "-name", "--name", 10, 1 },
2323   { "-xrm", "--xrm", 10, 1 },
2324   { "-r", "--reverse-video", 5, 0 },
2325   { "-rv", 0, 5, 0 },
2326   { "-reverse", 0, 5, 0 },
2327   { "-hb", "--horizontal-scroll-bars", 5, 0 },
2328   { "-vb", "--vertical-scroll-bars", 5, 0 },
2329
2330   /* These have the same priority as ordinary file name args,
2331      so they are not reordered with respect to those.  */
2332   { "-L", "--directory", 0, 1 },
2333   { "-directory", 0, 0, 1 },
2334   { "-l", "--load", 0, 1 },
2335   { "-load", 0, 0, 1 },
2336   { "-f", "--funcall", 0, 1 },
2337   { "-funcall", 0, 0, 1 },
2338   { "-eval", "--eval", 0, 1 },
2339   { "-insert", "--insert", 0, 1 },
2340   /* This should be processed after ordinary file name args and the like.  */
2341   { "-kill", "--kill", -10, 0 },
2342 };
2343
2344 /* Reorder the elements of ARGV (assumed to have ARGC elements)
2345    so that the highest priority ones come first.
2346    Do not change the order of elements of equal priority.
2347    If an option takes an argument, keep it and its argument together.  */
2348
2349 static void
2350 sort_args (int argc, char **argv)
2351 {
2352   char **new_argv = xnew_array (char *, argc);
2353   /* For each element of argv,
2354      the corresponding element of options is:
2355      0 for an option that takes no arguments,
2356      1 for an option that takes one argument, etc.
2357      -1 for an ordinary non-option argument.  */
2358   int *options  = xnew_array (int, argc);
2359   int *priority = xnew_array (int, argc);
2360   int to = 1;
2361   int from;
2362   int i;
2363   int end_of_options_p = 0;
2364
2365   /* Categorize all the options,
2366      and figure out which argv elts are option arguments.  */
2367   for (from = 1; from < argc; from++)
2368     {
2369       options[from] = -1;
2370       priority[from] = 0;
2371       /* Pseudo options "--" and "run-temacs" indicate end of options */
2372       if (!strcmp (argv[from], "--") ||
2373           !strcmp (argv[from], "run-temacs"))
2374         end_of_options_p = 1;
2375       if (!end_of_options_p && argv[from][0] == '-')
2376         {
2377           int match, thislen;
2378           char *equals;
2379
2380           /* Look for a match with a known old-fashioned option.  */
2381           for (i = 0; i < countof (standard_args); i++)
2382             if (!strcmp (argv[from], standard_args[i].name))
2383               {
2384                 options[from]  = standard_args[i].nargs;
2385                 priority[from] = standard_args[i].priority;
2386                 if (from + standard_args[i].nargs >= argc)
2387                   fatal ("Option `%s' requires an argument\n", argv[from]);
2388                 from += standard_args[i].nargs;
2389                 goto done;
2390               }
2391
2392           /* Look for a match with a known long option.
2393              MATCH is -1 if no match so far, -2 if two or more matches so far,
2394              >= 0 (the table index of the match) if just one match so far.  */
2395           if (argv[from][1] == '-')
2396             {
2397               match = -1;
2398               thislen = strlen (argv[from]);
2399               equals = strchr (argv[from], '=');
2400               if (equals != 0)
2401                 thislen = equals - argv[from];
2402
2403               for (i = 0; i < countof (standard_args); i++)
2404                 if (standard_args[i].longname
2405                     && !strncmp (argv[from], standard_args[i].longname,
2406                                  thislen))
2407                   {
2408                     if (match == -1)
2409                       match = i;
2410                     else
2411                       match = -2;
2412                   }
2413
2414               /* If we found exactly one match, use that.  */
2415               if (match >= 0)
2416                 {
2417                   options[from]  = standard_args[match].nargs;
2418                   priority[from] = standard_args[match].priority;
2419                   /* If --OPTION=VALUE syntax is used,
2420                      this option uses just one argv element.  */
2421                   if (equals != 0)
2422                     options[from] = 0;
2423                   if (from + options[from] >= argc)
2424                     fatal ("Option `%s' requires an argument\n", argv[from]);
2425                   from += options[from];
2426                 }
2427             }
2428         done: ;
2429         }
2430     }
2431
2432   /* Copy the arguments, in order of decreasing priority, to NEW_ARGV.  */
2433   new_argv[0] = argv[0];
2434   while (to < argc)
2435     {
2436       int best = -1;
2437       int best_priority = -9999;
2438
2439       /* Find the highest priority remaining option.
2440          If several have equal priority, take the first of them.  */
2441       for (from = 1; from < argc; from++)
2442         {
2443           if (argv[from] != 0 && priority[from] > best_priority)
2444             {
2445               best_priority = priority[from];
2446               best = from;
2447             }
2448           /* Skip option arguments--they are tied to the options.  */
2449           if (options[from] > 0)
2450             from += options[from];
2451         }
2452
2453       if (best < 0)
2454         abort ();
2455
2456       /* Copy the highest priority remaining option, with its args, to NEW_ARGV.  */
2457       new_argv[to++] = argv[best];
2458       for (i = 0; i < options[best]; i++)
2459         new_argv[to++] = argv[best + i + 1];
2460
2461       /* Clear out this option in ARGV.  */
2462       argv[best] = 0;
2463       for (i = 0; i < options[best]; i++)
2464         argv[best + i + 1] = 0;
2465     }
2466
2467   memcpy (argv, new_argv, sizeof (char *) * argc);
2468   xfree (new_argv);
2469   xfree (options);
2470   xfree (priority);
2471 }
2472
2473 DEFUN ("running-temacs-p", Frunning_temacs_p, 0, 0, 0, /*
2474 True if running temacs.  This means we are in the dumping stage.
2475 This is false during normal execution of the `xemacs' program, and
2476 becomes false once `run-emacs-from-temacs' is run.
2477 */
2478        ())
2479 {
2480   return run_temacs_argc >= 0 ? Qt : Qnil;
2481 }
2482
2483 DEFUN ("run-emacs-from-temacs", Frun_emacs_from_temacs, 0, MANY, 0, /*
2484 Do not call this.  It will reinitialize your XEmacs.  You'll be sorry.
2485 */
2486 /* If this function is called from startup.el, it will be possible to run
2487    temacs as an editor using 'temacs -batch -l loadup.el run-temacs', instead
2488    of having to dump an emacs and then run that (when debugging emacs itself,
2489    this can be much faster)). [Actually, the speed difference isn't that
2490    much as long as your filesystem is local, and you don't end up with
2491    a dumped version in case you want to rerun it.  This function is most
2492    useful when used as part of the `make all-elc' command. --ben]
2493    This will "restart" emacs with the specified command-line arguments.
2494
2495    Martin thinks this function is most useful when using debugging
2496    tools like Purify or tcov that get confused by XEmacs' dumping.  */
2497      (int nargs, Lisp_Object *args))
2498 {
2499   int ac;
2500   const Extbyte *wampum;
2501   int namesize;
2502   int total_len;
2503   Lisp_Object orig_invoc_name = Fcar (Vcommand_line_args);
2504   const Extbyte **wampum_all = alloca_array (const Extbyte *, nargs);
2505   int *wampum_all_len  = alloca_array (int, nargs);
2506
2507   assert (!gc_in_progress);
2508
2509   if (run_temacs_argc < 0)
2510     error ("I've lost my temacs-hood.");
2511
2512   /* Need to convert the orig_invoc_name and all of the arguments
2513      to external format. */
2514
2515   TO_EXTERNAL_FORMAT (LISP_STRING, orig_invoc_name,
2516                       ALLOCA, (wampum, namesize),
2517                       Qnative);
2518   namesize++;
2519
2520   for (ac = 0, total_len = namesize; ac < nargs; ac++)
2521     {
2522       CHECK_STRING (args[ac]);
2523       TO_EXTERNAL_FORMAT (LISP_STRING, args[ac],
2524                           ALLOCA, (wampum_all[ac], wampum_all_len[ac]),
2525                           Qnative);
2526       wampum_all_len[ac]++;
2527       total_len += wampum_all_len[ac];
2528     }
2529   DO_REALLOC (run_temacs_args, run_temacs_args_size, total_len, char);
2530   DO_REALLOC (run_temacs_argv, run_temacs_argv_size, nargs+2, char *);
2531
2532   memcpy (run_temacs_args, wampum, namesize);
2533   run_temacs_argv [0] = run_temacs_args;
2534   for (ac = 0; ac < nargs; ac++)
2535     {
2536       memcpy (run_temacs_args + namesize,
2537               wampum_all[ac], wampum_all_len[ac]);
2538       run_temacs_argv [ac + 1] = run_temacs_args + namesize;
2539       namesize += wampum_all_len[ac];
2540     }
2541   run_temacs_argv [nargs + 1] = 0;
2542   catchlist = NULL; /* Important!  Otherwise free_cons() calls in
2543                        condition_case_unwind() may lead to GC death. */
2544   unbind_to (0, Qnil); /* this closes loadup.el */
2545   purify_flag = 0;
2546   run_temacs_argc = nargs + 1;
2547 #if defined (HEAP_IN_DATA) && !defined(PDUMP)
2548   report_sheap_usage (0);
2549 #endif
2550   LONGJMP (run_temacs_catch, 1);
2551   return Qnil; /* not reached; warning suppression */
2552 }
2553
2554 /* ARGSUSED */
2555 int
2556 main (int argc, char **argv, char **envp)
2557 {
2558
2559 #ifdef _MSC_VER
2560   /* Under VC++, access violations and the like are not sent through
2561      the standard signal() mechanism.  Rather, they need to be handled
2562      using the Microsoft "structured exception handling" mechanism,
2563      which vaguely resembles the C++ mechanisms. */
2564   __try
2565   {
2566 #endif
2567
2568   int     volatile vol_argc = argc;
2569   char ** volatile vol_argv = argv;
2570   char ** volatile vol_envp = envp;
2571   /* This is hairy.  We need to compute where the XEmacs binary was invoked
2572      from because temacs initialization requires it to find the lisp
2573      directories.  The code that recomputes the path is guarded by the
2574      restarted flag.  There are three possible paths I've found so far
2575      through this:
2576
2577      temacs -- When running temacs for basic build stuff, the first main_1
2578       will be the only one invoked.  It must compute the path else there
2579       will be a very ugly bomb in startup.el (can't find obvious location
2580       for doc-directory data-directory, etc.).
2581
2582      temacs w/ run-temacs on the command line -- This is run to bytecompile
2583       all the out of date dumped lisp.  It will execute both of the main_1
2584       calls and the second one must not touch the first computation because
2585       argc/argv are hosed the second time through.
2586
2587      xemacs -- Only the second main_1 is executed.  The invocation path must
2588       computed but this only matters when running in place or when running
2589       as a login shell.
2590
2591      As a bonus for straightening this out, XEmacs can now be run in place
2592      as a login shell.  This never used to work.
2593
2594      As another bonus, we can now guarantee that
2595      (concat invocation-directory invocation-name) contains the filename
2596      of the XEmacs binary we are running.  This can now be used in a
2597      definite test for out of date dumped files.  -slb */
2598   int restarted = 0;
2599 #ifdef QUANTIFY
2600   quantify_stop_recording_data ();
2601   quantify_clear_data ();
2602 #endif /* QUANTIFY */
2603
2604   suppress_early_error_handler_backtrace = 0;
2605   lim_data = 0; /* force reinitialization of this variable */
2606
2607   /* Lisp_Object must fit in a word; check VALBITS and GCTYPEBITS */
2608   assert (sizeof (Lisp_Object) == sizeof (void *));
2609
2610 #ifdef LINUX_SBRK_BUG
2611   sbrk (1);
2612 #endif
2613
2614   if (!initialized)
2615     {
2616 #ifdef DOUG_LEA_MALLOC
2617       mallopt (M_MMAP_MAX, 0);
2618 #endif
2619       run_temacs_argc = 0;
2620       if (! SETJMP (run_temacs_catch))
2621         {
2622           main_1 (vol_argc, vol_argv, vol_envp, 0);
2623         }
2624       /* run-emacs-from-temacs called */
2625       restarted = 1;
2626       vol_argc = run_temacs_argc;
2627       vol_argv = run_temacs_argv;
2628 #ifdef _SCO_DS
2629       /* This makes absolutely no sense to anyone involved.  There are
2630          several people using this stuff.  We've compared versions on
2631          everything we can think of.  We can find no difference.
2632          However, on both my systems environ is a plain old global
2633          variable initialized to zero.  _environ is the one that
2634          contains pointers to the actual environment.
2635
2636          Since we can't figure out the difference (and we're hours
2637          away from a release), this takes a very cowardly approach and
2638          is bracketed with both a system specific preprocessor test
2639          and a runtime "do you have this problem" test
2640
2641          06/20/96 robertl@dgii.com */
2642       {
2643         extern char **_environ;
2644         if ((unsigned) environ == 0)
2645           environ=_environ;
2646       }
2647 #endif /* _SCO_DS */
2648       vol_envp = environ;
2649     }
2650 #if defined (RUN_TIME_REMAP) && ! defined (PDUMP)
2651   else
2652     /* obviously no-one uses this because where it was before initialized was
2653      *always* true */
2654     run_time_remap (argv[0]);
2655 #endif
2656
2657 #ifdef DOUG_LEA_MALLOC
2658   if (initialized && (malloc_state_ptr != NULL))
2659     {
2660       int rc = malloc_set_state (malloc_state_ptr);
2661       if (rc != 0)
2662         {
2663           stderr_out ("malloc_set_state failed, rc = %d\n", rc);
2664           abort ();
2665         }
2666 #if 0
2667       free (malloc_state_ptr);
2668 #endif
2669       /* mmap works in glibc-2.1, glibc-2.0 (Non-Mule only) and Linux libc5 */
2670 #if (defined(__GLIBC__) && __GLIBC_MINOR__ >= 1) || \
2671     defined(_NO_MALLOC_WARNING_) || \
2672     (defined(__GLIBC__) && __GLIBC_MINOR__ < 1 && !defined(MULE)) || \
2673     defined(DEBUG_DOUG_LEA_MALLOC)
2674       mallopt (M_MMAP_MAX, 64);
2675 #endif
2676 #ifdef REL_ALLOC
2677       r_alloc_reinit ();
2678 #endif
2679     }
2680 #endif /* DOUG_LEA_MALLOC */
2681
2682   run_temacs_argc = -1;
2683
2684   main_1 (vol_argc, vol_argv, vol_envp, restarted);
2685
2686 #ifdef _MSC_VER
2687   }
2688   /* VC++ documentation says that
2689      GetExceptionCode() cannot be called inside the filter itself. */
2690   __except (mswindows_handle_hardware_exceptions (GetExceptionCode ())) {}
2691 #endif
2692
2693   return 0; /* unreached */
2694 }
2695
2696 \f
2697 /* Dumping apparently isn't supported by versions of GCC >= 2.8. */
2698 /* The following needs conditionalization on whether either XEmacs or */
2699 /* various system shared libraries have been built and linked with */
2700 /* GCC >= 2.8.  -slb */
2701 #if defined(GNU_MALLOC)
2702 static void
2703 voodoo_free_hook (void *mem)
2704 {
2705   /* Disable all calls to free() when XEmacs is exiting and it doesn't */
2706   /* matter. */
2707   __free_hook =
2708 #ifdef __GNUC__ /* prototype of __free_hook varies with glibc version */
2709     (__typeof__ (__free_hook))
2710 #endif
2711     voodoo_free_hook;
2712 }
2713 #endif /* GNU_MALLOC */
2714
2715 DEFUN ("kill-emacs", Fkill_emacs, 0, 1, "P", /*
2716 Exit the XEmacs job and kill it.  Ask for confirmation, without argument.
2717 If ARG is an integer, return ARG as the exit program code.
2718 If ARG is a string, stuff it as keyboard input.
2719
2720 The value of `kill-emacs-hook', if not void,
2721 is a list of functions (of no args),
2722 all of which are called before XEmacs is actually killed.
2723 */
2724        (arg))
2725 {
2726   /* This function can GC */
2727   struct gcpro gcpro1;
2728
2729   GCPRO1 (arg);
2730
2731   if (feof (stdin))
2732     arg = Qt;
2733
2734   if (!preparing_for_armageddon && !noninteractive)
2735     run_hook (Qkill_emacs_hook);
2736
2737   ensure_no_quitting_from_now_on ();
2738
2739   if (!preparing_for_armageddon)
2740     {
2741       Lisp_Object concons, nextcons;
2742
2743       /* Normally, go ahead and delete all the consoles now.
2744          Some unmentionably lame window systems (MS Wwwww...... eek,
2745          I can't even say it) don't properly clean up after themselves,
2746          and even for those that do, it might be cleaner this way.
2747          If we're going down, however, we don't do this (might
2748          be too dangerous), and if we get a crash somewhere within
2749          this loop, we'll still autosave and won't try this again. */
2750
2751       LIST_LOOP_DELETING (concons, nextcons, Vconsole_list)
2752         {
2753           /* There is very little point in deleting the stream console.
2754              It uses stdio, which should flush any buffered output and
2755              something can only go wrong. -slb */
2756           /* I changed my mind.  There's a stupid hack in close to add
2757              a trailing newline. */
2758           /*if (!CONSOLE_STREAM_P (XCONSOLE (XCAR (concons))))*/
2759             delete_console_internal (XCONSOLE (XCAR (concons)), 1, 1, 0);
2760         }
2761     }
2762
2763   UNGCPRO;
2764
2765 #ifdef HAVE_MS_WINDOWS
2766   /* If we displayed a message on the console, then we must allow the
2767      user to see this message.  This may be unnecessary, but can't hurt,
2768      and we can't necessarily check arg; e.g. xemacs --help kills with
2769      argument 0. */
2770   if (mswindows_message_outputted)
2771     Fmswindows_message_box (build_string ("Messages outputted.  XEmacs is exiting."),
2772                             Qnil, Qnil);
2773 #endif
2774
2775   shut_down_emacs (0, STRINGP (arg) ? arg : Qnil, 0);
2776
2777 #if defined(GNU_MALLOC)
2778   __free_hook =
2779 #ifdef __GNUC__ /* prototype of __free_hook varies with glibc version */
2780     (__typeof__ (__free_hook))
2781 #endif
2782     voodoo_free_hook;
2783 #endif
2784
2785   exit (INTP (arg) ? XINT (arg) : 0);
2786   /* NOTREACHED */
2787   return Qnil; /* I'm sick of the compiler warning */
2788 }
2789
2790 /* Perform an orderly shutdown of XEmacs.  Autosave any modified
2791    buffers, kill any child processes, clean up the terminal modes (if
2792    we're in the foreground), and other stuff like that.  Don't perform
2793    any redisplay; this may be called when XEmacs is shutting down in
2794    the background, or after its X connection has died.
2795
2796    If SIG is a signal number, print a message for it.
2797
2798    This is called by fatal signal handlers and Fkill_emacs.  It used to
2799    be called by X protocol error handlers, but instead they now call
2800    Fkill_emacs. */
2801 static void
2802 shut_down_emacs (int sig, Lisp_Object stuff, int no_auto_save)
2803 {
2804   /* This function can GC */
2805   /* Prevent running of hooks and other non-essential stuff
2806      from now on.  */
2807   preparing_for_armageddon = 1;
2808
2809   ensure_no_quitting_from_now_on ();
2810
2811 #ifdef QUANTIFY
2812   quantify_stop_recording_data ();
2813 #endif /* QUANTIFY */
2814
2815   /* This is absolutely the most important thing to do, so make sure
2816      we do it now, before anything else.  We might have crashed and
2817      be in a weird inconsistent state, and potentially anything could
2818      set off another protection fault and cause us to bail out
2819      immediately. */
2820   /* Steve writes the following:
2821
2822      [[I'm not removing the code entirely, yet.  We have run up against
2823      a spate of problems in diagnosing crashes due to crashes within
2824      crashes.  It has very definitely been determined that code called
2825      during auto-saving cannot work if XEmacs crashed inside of GC.
2826      We already auto-save on an itimer so there cannot be too much
2827      unsaved stuff around, and if we get better crash reports we might
2828      be able to get more problems fixed so I'm disabling this.  -slb]]
2829
2830      and DISABLES AUTO-SAVING ENTIRELY during crashes!  Way way bad idea.
2831
2832      Instead let's just be more intelligent about avoiding crashing
2833      when possible, esp. nested crashes.
2834   */
2835   if (!no_auto_save)
2836     Fdo_auto_save (Qt, Qnil); /* do this before anything hazardous */
2837
2838   fflush (stdout);
2839   reset_all_consoles ();
2840   if (sig && sig != SIGTERM)
2841     {
2842       if (sig == -1)
2843         stderr_out ("\nFatal error.\n\n");
2844       else
2845         stderr_out ("\nFatal error (%d).\n\n", sig);
2846       stderr_out
2847         ("Your files have been auto-saved.\n"
2848          "Use `M-x recover-session' to recover them.\n"
2849          "\n"
2850          "If you have access to the PROBLEMS file that came with your\n"
2851          "version of XEmacs, please check to see if your crash is described\n"
2852          "there, as there may be a workaround available.\n"
2853 #ifdef INFODOCK
2854          "Otherwise, please report this bug by selecting `Report-Bug'\n"
2855          "in the InfoDock menu.\n"
2856 #else
2857          "Otherwise, please report this bug by running the send-pr\n"
2858          "script included with XEmacs, or selecting `Send Bug Report'\n"
2859          "from the help menu.\n"
2860          "As a last resort send ordinary email to `crashes@xemacs.org'.\n"
2861 #endif
2862          "*MAKE SURE* to include the information in the command\n"
2863          "M-x describe-installation.\n"
2864 #ifndef _MSC_VER
2865          "\n"
2866          "If at all possible, *please* try to obtain a C stack backtrace;\n"
2867          "it will help us immensely in determining what went wrong.\n"
2868          "To do this, locate the core file that was produced as a result\n"
2869          "of this crash (it's usually called `core' and is located in the\n"
2870          "directory in which you started the editor, or maybe in your home\n"
2871          "directory), and type\n"
2872          "\n"
2873          "  gdb "
2874 #endif
2875          );
2876 #ifndef _MSC_VER
2877       {
2878         const char *name;
2879         char *dir = 0;
2880
2881         /* Now try to determine the actual path to the executable,
2882            to try to make the backtrace-determination process as foolproof
2883            as possible. */
2884         if (STRINGP (Vinvocation_name))
2885           name = (char *) XSTRING_DATA (Vinvocation_name);
2886         else
2887           name = "xemacs";
2888         if (STRINGP (Vinvocation_directory))
2889           dir = (char *) XSTRING_DATA (Vinvocation_directory);
2890         if (!dir || dir[0] != '/')
2891           stderr_out ("`which %s`", name);
2892         else if (dir[strlen (dir) - 1] != '/')
2893           stderr_out ("%s/%s", dir, name);
2894         else
2895           stderr_out ("%s%s", dir, name);
2896       }
2897       stderr_out
2898         (" core\n\n"
2899          "then type `where' when the debugger prompt comes up.\n"
2900          "(If you don't have GDB on your system, you might have DBX,\n"
2901          "or XDB, or SDB.  A similar procedure should work for all of\n"
2902          "these.  Ask your system administrator if you need more help.)\n");
2903 #endif /* _MSC_VER */
2904     }
2905
2906   stuff_buffered_input (stuff);
2907
2908   kill_buffer_processes (Qnil);
2909
2910 #ifdef CLASH_DETECTION
2911   unlock_all_files ();
2912 #endif
2913
2914 #ifdef TOOLTALK
2915   tt_session_quit (tt_default_session ());
2916 #if 0
2917   /* The following crashes when built on X11R5 and run on X11R6 */
2918   tt_close ();
2919 #endif
2920 #endif /* TOOLTALK */
2921
2922 }
2923
2924 \f
2925 #ifndef CANNOT_DUMP
2926
2927 #if !defined(PDUMP) || !defined(SYSTEM_MALLOC)
2928 extern char my_edata[];
2929 #endif
2930
2931 extern void disable_free_hook (void);
2932
2933 DEFUN ("dump-emacs", Fdump_emacs, 2, 2, 0, /*
2934 Dump current state of XEmacs into executable file FILENAME.
2935 Take symbols from SYMFILE (presumably the file you executed to run XEmacs).
2936 This is used in the file `loadup.el' when building XEmacs.
2937
2938 Remember to set `command-line-processed' to nil before dumping
2939 if you want the dumped XEmacs to process its command line
2940 and announce itself normally when it is run.
2941 */
2942        (filename, symfile))
2943 {
2944   /* This function can GC */
2945   struct gcpro gcpro1, gcpro2;
2946   int opurify;
2947
2948   GCPRO2 (filename, symfile);
2949
2950 #ifdef FREE_CHECKING
2951   Freally_free (Qnil);
2952
2953   /* When we're dumping, we can't use the debugging free() */
2954   disable_free_hook ();
2955 #endif
2956
2957   CHECK_STRING (filename);
2958   filename = Fexpand_file_name (filename, Qnil);
2959   if (!NILP (symfile))
2960     {
2961       CHECK_STRING (symfile);
2962       if (XSTRING_LENGTH (symfile) > 0)
2963         symfile = Fexpand_file_name (symfile, Qnil);
2964       else
2965         symfile = Qnil;
2966     }
2967
2968   opurify = purify_flag;
2969   purify_flag = 0;
2970
2971 #if defined (HEAP_IN_DATA) && !defined(PDUMP)
2972   report_sheap_usage (1);
2973 #endif
2974
2975   clear_message ();
2976
2977   fflush (stderr);
2978   fflush (stdout);
2979
2980   disksave_object_finalization ();
2981   release_breathing_space ();
2982
2983   /* Tell malloc where start of impure now is */
2984   /* Also arrange for warnings when nearly out of space.  */
2985 #ifndef SYSTEM_MALLOC
2986   memory_warnings (my_edata, malloc_warning);
2987 #endif
2988
2989   UNGCPRO;
2990
2991   {
2992     char *filename_ext;
2993     char *symfile_ext;
2994
2995     LISP_STRING_TO_EXTERNAL (filename, filename_ext, Qfile_name);
2996
2997     if (STRINGP (symfile))
2998       LISP_STRING_TO_EXTERNAL (symfile, symfile_ext, Qfile_name);
2999     else
3000       symfile_ext = 0;
3001
3002     garbage_collect_1 ();
3003
3004 #ifdef PDUMP
3005     pdump ();
3006 #else
3007
3008 #ifdef DOUG_LEA_MALLOC
3009     malloc_state_ptr = malloc_get_state ();
3010 #endif
3011   /* here we break our rule that the filename conversion should
3012      be performed at the actual time that the system call is made.
3013      It's a whole lot easier to do the conversion here than to
3014      modify all the unexec routines to ensure that filename
3015      conversion is applied everywhere.  Don't worry about memory
3016      leakage because this call only happens once. */
3017     unexec (filename_ext, symfile_ext, (uintptr_t) my_edata, 0, 0);
3018 #ifdef DOUG_LEA_MALLOC
3019     free (malloc_state_ptr);
3020 #endif
3021 #endif /* not PDUMP */
3022   }
3023
3024   purify_flag = opurify;
3025
3026   return Qnil;
3027 }
3028
3029 #endif /* not CANNOT_DUMP */
3030 \f
3031
3032 /* Split STRING into a list of substrings.  The substrings are the
3033    parts of original STRING separated by SEPCHAR.  */
3034 static Lisp_Object
3035 split_string_by_emchar_1 (const Bufbyte *string, Bytecount size,
3036                           Emchar sepchar)
3037 {
3038   Lisp_Object result = Qnil;
3039   const Bufbyte *end = string + size;
3040
3041   while (1)
3042     {
3043       const Bufbyte *p = string;
3044       while (p < end)
3045         {
3046           if (charptr_emchar (p) == sepchar)
3047             break;
3048           INC_CHARPTR (p);
3049         }
3050       result = Fcons (make_string (string, p - string), result);
3051       if (p < end)
3052         {
3053           string = p;
3054           INC_CHARPTR (string); /* skip sepchar */
3055         }
3056       else
3057         break;
3058     }
3059   return Fnreverse (result);
3060 }
3061
3062 /* The same as the above, except PATH is an external C string (it is
3063    converted using Qfile_name), and sepchar is hardcoded to SEPCHAR
3064    (':' or whatever).  */
3065 Lisp_Object
3066 decode_path (const char *path)
3067 {
3068   Bytecount newlen;
3069   Bufbyte *newpath;
3070   if (!path)
3071     return Qnil;
3072
3073   TO_INTERNAL_FORMAT (C_STRING, path, ALLOCA, (newpath, newlen), Qfile_name);
3074
3075   /* #### Does this make sense?  It certainly does for
3076      decode_env_path(), but it looks dubious here.  Does any code
3077      depend on decode_path("") returning nil instead of an empty
3078      string?  */
3079   if (!newlen)
3080     return Qnil;
3081
3082   return split_string_by_emchar_1 (newpath, newlen, SEPCHAR);
3083 }
3084
3085 Lisp_Object
3086 decode_env_path (const char *evarname, const char *default_)
3087 {
3088   const char *path = 0;
3089   if (evarname)
3090     path = egetenv (evarname);
3091   if (!path)
3092     path = default_;
3093   return decode_path (path);
3094 }
3095
3096 /* Ben thinks this function should not exist or be exported to Lisp.
3097    We use it to define split-path-string in subr.el (not!).  */
3098
3099 DEFUN ("split-string-by-char", Fsplit_string_by_char, 1, 2, 0, /*
3100 Split STRING into a list of substrings originally separated by SEPCHAR.
3101 */
3102        (string, sepchar))
3103 {
3104   CHECK_STRING (string);
3105   CHECK_CHAR (sepchar);
3106   return split_string_by_emchar_1 (XSTRING_DATA (string),
3107                                    XSTRING_LENGTH (string),
3108                                    XCHAR (sepchar));
3109 }
3110
3111 /* #### This was supposed to be in subr.el, but is used VERY early in
3112    the bootstrap process, so it goes here.  Damn.  */
3113
3114 DEFUN ("split-path", Fsplit_path, 1, 1, 0, /*
3115 Explode a search path into a list of strings.
3116 The path components are separated with the characters specified
3117 with `path-separator'.
3118 */
3119        (path))
3120 {
3121   CHECK_STRING (path);
3122
3123   while (!STRINGP (Vpath_separator)
3124          || (XSTRING_CHAR_LENGTH (Vpath_separator) != 1))
3125     Vpath_separator = signal_simple_continuable_error
3126       ("`path-separator' should be set to a single-character string",
3127        Vpath_separator);
3128
3129   return (split_string_by_emchar_1
3130           (XSTRING_DATA (path), XSTRING_LENGTH (path),
3131            charptr_emchar (XSTRING_DATA (Vpath_separator))));
3132 }
3133 \f
3134 DEFUN ("noninteractive", Fnoninteractive, 0, 0, 0, /*
3135 Non-nil return value means XEmacs is running without interactive terminal.
3136 */
3137        ())
3138 {
3139   return noninteractive ? Qt : Qnil;
3140 }
3141
3142 /* This flag is useful to define if you're under a debugger; this way, you
3143    can put a breakpoint of assert_failed() and debug multiple problems
3144    in one session without having to recompile. */
3145 /* #define ASSERTIONS_DONT_ABORT */
3146
3147 #ifdef USE_ASSERTIONS
3148 /* This highly dubious kludge ... shut up Jamie, I'm tired of your slagging. */
3149
3150 static int in_assert_failed;
3151 static const char *assert_failed_file;
3152 static int assert_failed_line;
3153 static const char *assert_failed_expr;
3154
3155 #ifdef fprintf
3156 #undef fprintf
3157 #endif
3158
3159 #undef abort    /* avoid infinite #define loop... */
3160
3161 #if defined (WIN32_NATIVE) && defined (DEBUG_XEMACS)
3162 #define enter_debugger() DebugBreak ()
3163 #else
3164 #define enter_debugger()
3165 #endif
3166
3167 void
3168 assert_failed (const char *file, int line, const char *expr)
3169 {
3170   /* If we're already crashing, let's not crash again.  This might be
3171      critical to getting auto-saving working properly. */
3172   if (fatal_error_in_progress)
3173     return;
3174
3175   /* We are extremely paranoid so we sensibly deal with recursive
3176      assertion failures. */
3177   in_assert_failed++;
3178
3179   if (in_assert_failed >= 4)
3180     _exit (-1);
3181   else if (in_assert_failed == 3)
3182     {
3183       enter_debugger ();
3184       _exit (-1);
3185     }
3186   else if (in_assert_failed == 2)
3187     {
3188       /* Not stderr_out(), which does additional things and may trigger
3189          a recursive assertion failure.  fprintf was undeffed above, in
3190          case it was encapsulated. */
3191       fprintf (stderr,
3192                "Fatal error: recursive assertion failure, "
3193                "file %s, line %d, %s\n",
3194                file, line, expr);
3195       fprintf (stderr,
3196                "Original assertion failure: file %s, line %d, %s\n",
3197                assert_failed_file, assert_failed_line, assert_failed_expr);
3198     }
3199   else
3200     {
3201       assert_failed_file = file;
3202       assert_failed_line = line;
3203       assert_failed_expr = expr;
3204
3205       if (!initialized)
3206         fprintf (stderr,
3207                  "Fatal error: assertion failed, file %s, line %d, %s\n",
3208                  file, line, expr);
3209       else
3210         stderr_out ("Fatal error: assertion failed, file %s, line %d, %s\n",
3211                     file, line, expr);
3212     }
3213
3214   enter_debugger ();
3215 #if !defined (ASSERTIONS_DONT_ABORT)
3216   abort ();
3217 #endif
3218   in_assert_failed = 0;
3219 }
3220 #endif /* USE_ASSERTIONS */
3221
3222 #ifdef QUANTIFY
3223 DEFUN ("quantify-start-recording-data", Fquantify_start_recording_data,
3224        0, 0, "", /*
3225 Start recording Quantify data.
3226 */
3227        ())
3228 {
3229   quantify_start_recording_data ();
3230   return Qnil;
3231 }
3232
3233 DEFUN ("quantify-stop-recording-data", Fquantify_stop_recording_data,
3234        0, 0, "", /*
3235 Stop recording Quantify data.
3236 */
3237        ())
3238 {
3239   quantify_stop_recording_data ();
3240   return Qnil;
3241 }
3242
3243 DEFUN ("quantify-clear-data", Fquantify_clear_data, 0, 0, "", /*
3244 Clear all Quantify data.
3245 */
3246        ())
3247 {
3248   quantify_clear_data ();
3249   return Qnil;
3250 }
3251 #endif /* QUANTIFY */
3252
3253 void
3254 syms_of_emacs (void)
3255 {
3256 #ifndef CANNOT_DUMP
3257   DEFSUBR (Fdump_emacs);
3258 #endif /* !CANNOT_DUMP */
3259
3260   DEFSUBR (Frun_emacs_from_temacs);
3261   DEFSUBR (Frunning_temacs_p);
3262   DEFSUBR (Finvocation_name);
3263   DEFSUBR (Finvocation_directory);
3264   DEFSUBR (Fkill_emacs);
3265   DEFSUBR (Fnoninteractive);
3266
3267 #ifdef QUANTIFY
3268   DEFSUBR (Fquantify_start_recording_data);
3269   DEFSUBR (Fquantify_stop_recording_data);
3270   DEFSUBR (Fquantify_clear_data);
3271 #endif /* QUANTIFY */
3272
3273   DEFSUBR (Fsplit_string_by_char);
3274   DEFSUBR (Fsplit_path);        /* #### */
3275
3276   defsymbol (&Qkill_emacs_hook, "kill-emacs-hook");
3277   defsymbol (&Qsave_buffers_kill_emacs, "save-buffers-kill-emacs");
3278 }
3279
3280 void
3281 vars_of_emacs (void)
3282 {
3283   DEFVAR_BOOL ("suppress-early-error-handler-backtrace",
3284                &suppress_early_error_handler_backtrace /*
3285 Non-nil means early error handler shouldn't print a backtrace.
3286 */ );
3287
3288   DEFVAR_LISP ("command-line-args", &Vcommand_line_args /*
3289 Args passed by shell to XEmacs, as a list of strings.
3290 */ );
3291
3292   DEFVAR_LISP ("invocation-name", &Vinvocation_name /*
3293 The program name that was used to run XEmacs.
3294 Any directory names are omitted.
3295 */ );
3296
3297   DEFVAR_LISP ("invocation-directory", &Vinvocation_directory /*
3298 The directory in which the XEmacs executable was found, to run it.
3299 The value is simply the program name if that directory's name is not known.
3300 */ );
3301
3302   DEFVAR_LISP ("invocation-path", &Vinvocation_path /*
3303 The path in which the XEmacs executable was found, to run it.
3304 The value is simply the value of environment variable PATH on startup
3305 if XEmacs was found there.
3306 */ );
3307
3308 #if 0 /* FSFmacs */
3309   xxDEFVAR_LISP ("installation-directory", &Vinstallation_directory,
3310     "A directory within which to look for the `lib-src' and `etc' directories.\n"
3311 "This is non-nil when we can't find those directories in their standard\n"
3312 "installed locations, but we can find them\n"
3313 "near where the XEmacs executable was found.");
3314 #endif
3315
3316   DEFVAR_LISP ("system-type", &Vsystem_type /*
3317 Symbol indicating type of operating system you are using.
3318 */ );
3319   Vsystem_type = intern (SYSTEM_TYPE);
3320   Fprovide (intern(SYSTEM_TYPE));
3321
3322 #ifndef EMACS_CONFIGURATION
3323 # define EMACS_CONFIGURATION "UNKNOWN"
3324 #endif
3325   DEFVAR_LISP ("system-configuration", &Vsystem_configuration /*
3326 String naming the configuration XEmacs was built for.
3327 */ );
3328   Vsystem_configuration = build_string (EMACS_CONFIGURATION);
3329
3330 #ifndef EMACS_CONFIG_OPTIONS
3331 # define EMACS_CONFIG_OPTIONS "UNKNOWN"
3332 #endif
3333   DEFVAR_LISP ("system-configuration-options", &Vsystem_configuration_options /*
3334 String containing the configuration options XEmacs was built with.
3335 */ );
3336   Vsystem_configuration_options = build_string (EMACS_CONFIG_OPTIONS);
3337
3338   DEFVAR_LISP ("emacs-major-version", &Vemacs_major_version /*
3339 Major version number of this version of Emacs, as an integer.
3340 Warning: this variable did not exist in Emacs versions earlier than:
3341   FSF Emacs:   19.23
3342   XEmacs:      19.10
3343 */ );
3344   Vemacs_major_version = make_int (EMACS_MAJOR_VERSION);
3345
3346   DEFVAR_LISP ("emacs-minor-version", &Vemacs_minor_version /*
3347 Minor version number of this version of Emacs, as an integer.
3348 Warning: this variable did not exist in Emacs versions earlier than:
3349   FSF Emacs:   19.23
3350   XEmacs:      19.10
3351 */ );
3352   Vemacs_minor_version = make_int (EMACS_MINOR_VERSION);
3353
3354   DEFVAR_LISP ("emacs-patch-level", &Vemacs_patch_level /*
3355 The patch level of this version of Emacs, as an integer.
3356 The value is non-nil if this version of XEmacs is part of a series of
3357 stable XEmacsen, but has bug fixes applied.
3358 Warning: this variable does not exist in FSF Emacs or in XEmacs versions
3359 earlier than 21.1.1
3360 */ );
3361 #ifdef EMACS_PATCH_LEVEL
3362   Vemacs_patch_level = make_int (EMACS_PATCH_LEVEL);
3363 #else
3364   Vemacs_patch_level = Qnil;
3365 #endif
3366
3367     DEFVAR_LISP ("emacs-beta-version", &Vemacs_beta_version /*
3368 Beta number of this version of Emacs, as an integer.
3369 The value is nil if this is an officially released version of XEmacs.
3370 Warning: this variable does not exist in FSF Emacs or in XEmacs versions
3371 earlier than 20.3.
3372 */ );
3373 #ifdef EMACS_BETA_VERSION
3374   Vemacs_beta_version = make_int (EMACS_BETA_VERSION);
3375 #else
3376   Vemacs_beta_version = Qnil;
3377 #endif
3378
3379 #ifdef INFODOCK
3380   DEFVAR_LISP ("infodock-major-version", &Vinfodock_major_version /*
3381 Major version number of this InfoDock release.
3382 */ );
3383   Vinfodock_major_version = make_int (INFODOCK_MAJOR_VERSION);
3384
3385   DEFVAR_LISP ("infodock-minor-version", &Vinfodock_minor_version /*
3386 Minor version number of this InfoDock release.
3387 */ );
3388   Vinfodock_minor_version = make_int (INFODOCK_MINOR_VERSION);
3389
3390   DEFVAR_LISP ("infodock-build-version", &Vinfodock_build_version /*
3391 Build version of this InfoDock release.
3392 */ );
3393   Vinfodock_build_version = make_int (INFODOCK_BUILD_VERSION);
3394 #endif
3395
3396   DEFVAR_LISP ("xemacs-codename", &Vxemacs_codename /*
3397 Codename of this version of Emacs (a string).
3398 */ );
3399 #ifndef XEMACS_CODENAME
3400 #define XEMACS_CODENAME "Noname"
3401 #endif
3402 #ifdef MULE
3403   {
3404     char dest[129];
3405     char src[64] = XEMACS_CODENAME;
3406     unsigned char* sp = (unsigned char*)src;
3407     int i = 0, chr;
3408
3409     while ( (chr = *sp++) && (i < 128) )
3410       {
3411         if (chr <= 0x7F)
3412           dest[i++] = chr;
3413         else
3414           {
3415 #ifdef UTF2000
3416             dest[i++] = (chr >> 6) | 0xC0;
3417             dest[i++] = (chr & 0x3F) | 0x80;
3418 #else
3419             dest[i++] = LEADING_BYTE_LATIN_ISO8859_1;
3420             dest[i++] = chr;
3421 #endif
3422           }
3423       }
3424     dest[i] = 0;
3425     Vxemacs_codename = build_string (dest);
3426   }
3427 #else  
3428   Vxemacs_codename = build_string (XEMACS_CODENAME);
3429 #endif
3430
3431   /* Lisp variables which contain command line flags.
3432
3433      The portable dumper stomps on these; they must be saved and restored
3434      if they are processed before the call to pdump_load() in main_1().
3435   */
3436   DEFVAR_BOOL ("noninteractive", &noninteractive1 /*
3437 Non-nil means XEmacs is running without interactive terminal.
3438 */ );
3439
3440   DEFVAR_BOOL ("inhibit-early-packages", &inhibit_early_packages /*
3441 Set to non-nil when the early packages should not be respected at startup.
3442 */ );
3443
3444   DEFVAR_BOOL ("inhibit-autoloads", &inhibit_autoloads /*
3445 Set to non-nil when autoloads should not be loaded at startup.
3446 */ );
3447
3448   DEFVAR_BOOL ("debug-paths", &debug_paths /*
3449 Set to non-nil when debug information about paths should be printed.
3450 */ );
3451
3452   DEFVAR_BOOL ("inhibit-site-lisp", &inhibit_site_lisp /*
3453 Set to non-nil when the site-lisp should not be searched at startup.
3454 */ );
3455 #ifdef INHIBIT_SITE_LISP
3456   inhibit_site_lisp = 1;
3457 #endif
3458
3459   DEFVAR_BOOL ("inhibit-site-modules", &inhibit_site_modules /*
3460 Set to non-nil when site-modules should not be searched at startup.
3461 */ );
3462 #ifdef INHIBIT_SITE_MODULES
3463   inhibit_site_modules = 1;
3464 #endif
3465
3466   DEFVAR_INT ("emacs-priority", &emacs_priority /*
3467 Priority for XEmacs to run at.
3468 This value is effective only if set before XEmacs is dumped,
3469 and only if the XEmacs executable is installed with setuid to permit
3470 it to change priority.  (XEmacs sets its uid back to the real uid.)
3471 Currently, you need to define SET_EMACS_PRIORITY in `config.h'
3472 before you compile XEmacs, to enable the code for this feature.
3473 */ );
3474   emacs_priority = 0;
3475
3476   DEFVAR_CONST_LISP ("internal-error-checking", &Vinternal_error_checking /*
3477 Internal error checking built-in into this instance of XEmacs.
3478 This is a list of symbols, initialized at build-time.  Legal symbols
3479 are:
3480
3481 extents         - check extents prior to each extent change;
3482 typecheck       - check types strictly, aborting in case of error;
3483 malloc          - check operation of malloc;
3484 gc              - check garbage collection;
3485 bufpos          - check buffer positions.
3486
3487 quick-build     - user has requested the "quick-build" configure option.
3488 */ );
3489   Vinternal_error_checking = Qnil;
3490 #ifdef ERROR_CHECK_EXTENTS
3491   Vinternal_error_checking = Fcons (intern ("extents"),
3492                                     Vinternal_error_checking);
3493 #endif
3494 #ifdef ERROR_CHECK_TYPECHECK
3495   Vinternal_error_checking = Fcons (intern ("typecheck"),
3496                                     Vinternal_error_checking);
3497 #endif
3498 #ifdef ERROR_CHECK_MALLOC
3499   Vinternal_error_checking = Fcons (intern ("malloc"),
3500                                     Vinternal_error_checking);
3501 #endif
3502 #ifdef ERROR_CHECK_GC
3503   Vinternal_error_checking = Fcons (intern ("gc"),
3504                                     Vinternal_error_checking);
3505 #endif
3506 #ifdef ERROR_CHECK_BUFPOS
3507   Vinternal_error_checking = Fcons (intern ("bufpos"),
3508                                     Vinternal_error_checking);
3509 #endif
3510 #ifdef QUICK_BUILD
3511   Vinternal_error_checking = Fcons (intern ("quick-build"),
3512                                     Vinternal_error_checking);
3513 #endif
3514
3515   DEFVAR_CONST_LISP ("mail-lock-methods", &Vmail_lock_methods /*
3516 Mail spool locking methods supported by this instance of XEmacs.
3517 This is a list of symbols.  Each of the symbols is one of the
3518 following: dot, lockf, flock, locking, mmdf.
3519 */ );
3520   {
3521     Vmail_lock_methods = Qnil;
3522     Vmail_lock_methods = Fcons (intern ("dot"), Vmail_lock_methods);
3523 #ifdef HAVE_LOCKF
3524     Vmail_lock_methods = Fcons (intern ("lockf"), Vmail_lock_methods);
3525 #endif
3526 #ifdef HAVE_FLOCK
3527     Vmail_lock_methods = Fcons (intern ("flock"), Vmail_lock_methods);
3528 #endif
3529 #ifdef HAVE_MMDF
3530     Vmail_lock_methods = Fcons (intern ("mmdf"), Vmail_lock_methods);
3531 #endif
3532 #ifdef HAVE_LOCKING
3533     Vmail_lock_methods = Fcons (intern ("locking"), Vmail_lock_methods);
3534 #endif
3535   }
3536
3537   DEFVAR_CONST_LISP ("configure-mail-lock-method", &Vconfigure_mail_lock_method /*
3538 Mail spool locking method suggested by configure.  This is one
3539 of the symbols in MAIL-LOCK-METHODS.
3540 */ );
3541   {
3542 #if defined(MAIL_LOCK_FLOCK) && defined(HAVE_FLOCK)
3543     Vconfigure_mail_lock_method = intern("flock");
3544 #elif defined(MAIL_LOCK_LOCKF) && defined(HAVE_LOCKF)
3545     Vconfigure_mail_lock_method = intern("lockf");
3546 #elif defined(MAIL_LOCK_MMDF) && defined(HAVE_MMDF)
3547     Vconfigure_mail_lock_method = intern("mmdf");
3548 #elif defined(MAIL_LOCK_LOCKING) && defined(HAVE_LOCKING)
3549     Vconfigure_mail_lock_method = intern("locking");
3550 #else
3551     Vconfigure_mail_lock_method = intern("dot");
3552 #endif
3553   }
3554
3555   DEFVAR_LISP ("path-separator", &Vpath_separator /*
3556 The directory separator in search paths, as a string.
3557 */ );
3558   {
3559     char c = SEPCHAR;
3560     Vpath_separator = make_string ((Bufbyte *)&c, 1);
3561   }
3562 }
3563
3564 void
3565 complex_vars_of_emacs (void)
3566 {
3567   /* This is all related to path searching. */
3568
3569   DEFVAR_LISP ("emacs-program-name", &Vemacs_program_name /*
3570 *Name of the Emacs variant.
3571 For example, this may be \"xemacs\" or \"infodock\".
3572 This is mainly meant for use in path searching.
3573 */ );
3574   Vemacs_program_name = build_string ((char *) PATH_PROGNAME);
3575
3576   DEFVAR_LISP ("emacs-program-version", &Vemacs_program_version /*
3577 *Version of the Emacs variant.
3578 This typically has the form NN.NN-bNN.
3579 This is mainly meant for use in path searching.
3580 */ );
3581   Vemacs_program_version = build_string ((char *) PATH_VERSION);
3582
3583   DEFVAR_LISP ("exec-path", &Vexec_path /*
3584 *List of directories to search programs to run in subprocesses.
3585 Each element is a string (directory name) or nil (try default directory).
3586 */ );
3587   Vexec_path = Qnil;
3588
3589   DEFVAR_LISP ("exec-directory", &Vexec_directory /*
3590 *Directory of architecture-dependent files that come with XEmacs,
3591 especially executable programs intended for XEmacs to invoke.
3592 */ );
3593   Vexec_directory = Qnil;
3594
3595   DEFVAR_LISP ("configure-exec-directory", &Vconfigure_exec_directory /*
3596 For internal use by the build procedure only.
3597 configure's idea of what `exec-directory' will be.
3598 */ );
3599 #ifdef PATH_EXEC
3600   Vconfigure_exec_directory = Ffile_name_as_directory
3601     (build_string ((char *) PATH_EXEC));
3602 #else
3603   Vconfigure_exec_directory = Qnil;
3604 #endif
3605
3606   DEFVAR_LISP ("lisp-directory", &Vlisp_directory /*
3607 *Directory of core Lisp files that come with XEmacs.
3608 */ );
3609   Vlisp_directory = Qnil;
3610
3611   DEFVAR_LISP ("configure-lisp-directory", &Vconfigure_lisp_directory /*
3612 For internal use by the build procedure only.
3613 configure's idea of what `lisp-directory' will be.
3614 */ );
3615 #ifdef PATH_LOADSEARCH
3616   Vconfigure_lisp_directory = Ffile_name_as_directory
3617     (build_string ((char *) PATH_LOADSEARCH));
3618 #else
3619   Vconfigure_lisp_directory = Qnil;
3620 #endif
3621
3622   DEFVAR_LISP ("mule-lisp-directory", &Vmule_lisp_directory /*
3623 *Directory of Mule Lisp files that come with XEmacs.
3624 */ );
3625   Vmule_lisp_directory = Qnil;
3626
3627   DEFVAR_LISP ("configure-mule-lisp-directory", &Vconfigure_mule_lisp_directory /*
3628 For internal use by the build procedure only.
3629 configure's idea of what `mule-lisp-directory' will be.
3630 */ );
3631 #ifdef PATH_MULELOADSEARCH
3632   Vconfigure_mule_lisp_directory = Ffile_name_as_directory
3633     (build_string ((char *) PATH_MULELOADSEARCH));
3634 #else
3635   Vconfigure_mule_lisp_directory = Qnil;
3636 #endif
3637
3638   DEFVAR_LISP ("utf-2000-lisp-directory", &Vutf_2000_lisp_directory /*
3639 *Directory of UTF-2000 Lisp files that come with XEmacs.
3640 */ );
3641   Vutf_2000_lisp_directory = Qnil;
3642
3643   DEFVAR_LISP ("configure-utf-2000-lisp-directory",
3644                &Vconfigure_utf_2000_lisp_directory /*
3645 For internal use by the build procedure only.
3646 configure's idea of what `utf-2000-lisp-directory' will be.
3647 */ );
3648 #ifdef PATH_UTF2000LOADSEARCH
3649   Vconfigure_utf_2000_lisp_directory = Ffile_name_as_directory
3650     (build_string ((char *) PATH_UTF2000LOADSEARCH));
3651 #else
3652   Vconfigure_utf_2000_lisp_directory = Qnil;
3653 #endif
3654
3655   DEFVAR_LISP ("module-directory", &Vmodule_directory /*
3656 *Directory of core dynamic modules that come with XEmacs.
3657 */ );
3658   Vmodule_directory = Qnil;
3659
3660   DEFVAR_LISP ("configure-module-directory", &Vconfigure_module_directory /*
3661 For internal use by the build procedure only.
3662 configure's idea of what `module-directory' will be.
3663 */ );
3664 #ifdef PATH_MODULESEARCH
3665   Vconfigure_module_directory = Ffile_name_as_directory
3666     (build_string ((char *) PATH_MODULESEARCH));
3667 #else
3668   Vconfigure_module_directory = Qnil;
3669 #endif
3670
3671   DEFVAR_LISP ("configure-package-path", &Vconfigure_package_path /*
3672 For internal use by the build procedure only.
3673 configure's idea of what the package path will be.
3674 */ );
3675 #ifdef PATH_PACKAGEPATH
3676   Vconfigure_package_path = decode_path (PATH_PACKAGEPATH);
3677 #else
3678   Vconfigure_package_path = Qnil;
3679 #endif
3680
3681   DEFVAR_LISP ("data-directory", &Vdata_directory /*
3682 *Directory of architecture-independent files that come with XEmacs,
3683 intended for XEmacs to use.
3684 Use of this variable in new code is almost never correct.  See the
3685 functions `locate-data-file' and `locate-data-directory' and the variable
3686 `data-directory-list'.
3687 */ );
3688   Vdata_directory = Qnil;
3689
3690   DEFVAR_LISP ("configure-data-directory", &Vconfigure_data_directory /*
3691 For internal use by the build procedure only.
3692 configure's idea of what `data-directory' will be.
3693 */ );
3694 #ifdef PATH_DATA
3695   Vconfigure_data_directory = Ffile_name_as_directory
3696     (build_string ((char *) PATH_DATA));
3697 #else
3698   Vconfigure_data_directory = Qnil;
3699 #endif
3700
3701   DEFVAR_LISP ("data-directory-list", &Vdata_directory_list /*
3702 *List of directories of architecture-independent files that come with XEmacs
3703 or were installed as packages, and are intended for XEmacs to use.
3704 */ );
3705   Vdata_directory_list = Qnil;
3706
3707   DEFVAR_LISP ("site-directory", &Vsite_directory /*
3708 *Directory of site-specific Lisp files that come with XEmacs.
3709 */ );
3710   Vsite_directory = Qnil;
3711
3712   DEFVAR_LISP ("configure-site-directory", &Vconfigure_site_directory /*
3713 For internal use by the build procedure only.
3714 configure's idea of what `site-directory' will be.
3715 */ );
3716 #ifdef PATH_SITE
3717   Vconfigure_site_directory = Ffile_name_as_directory
3718     (build_string ((char *) PATH_SITE));
3719 #else
3720   Vconfigure_site_directory = Qnil;
3721 #endif
3722
3723   DEFVAR_LISP ("site-module-directory", &Vsite_module_directory /*
3724 *Directory of site-specific loadable modules that come with XEmacs.
3725 */ );
3726   Vsite_module_directory = Qnil;
3727
3728   DEFVAR_LISP ("configure-site-module-directory", &Vconfigure_site_module_directory /*
3729 For internal use by the build procedure only.
3730 configure's idea of what `site-directory' will be.
3731 */ );
3732 #ifdef PATH_SITE_MODULES
3733   Vconfigure_site_module_directory = Ffile_name_as_directory
3734     (build_string ((char *) PATH_SITE_MODULES));
3735 #else
3736   Vconfigure_site_module_directory = Qnil;
3737 #endif
3738
3739   DEFVAR_LISP ("doc-directory", &Vdoc_directory /*
3740 *Directory containing the DOC file that comes with XEmacs.
3741 This is usually the same as `exec-directory'.
3742 */ );
3743   Vdoc_directory = Qnil;
3744
3745   DEFVAR_LISP ("configure-doc-directory", &Vconfigure_doc_directory /*
3746 For internal use by the build procedure only.
3747 configure's idea of what `doc-directory' will be.
3748 */ );
3749 #ifdef PATH_DOC
3750   Vconfigure_doc_directory = Ffile_name_as_directory
3751     (build_string ((char *) PATH_DOC));
3752 #else
3753   Vconfigure_doc_directory = Qnil;
3754 #endif
3755
3756   DEFVAR_LISP ("configure-exec-prefix-directory", &Vconfigure_exec_prefix_directory /*
3757 For internal use by the build procedure only.
3758 configure's idea of what `exec-prefix-directory' will be.
3759 */ );
3760 #ifdef PATH_EXEC_PREFIX
3761   Vconfigure_exec_prefix_directory = Ffile_name_as_directory
3762     (build_string ((char *) PATH_EXEC_PREFIX));
3763 #else
3764   Vconfigure_exec_prefix_directory = Qnil;
3765 #endif
3766
3767   DEFVAR_LISP ("configure-prefix-directory", &Vconfigure_prefix_directory /*
3768 For internal use by the build procedure only.
3769 configure's idea of what `prefix-directory' will be.
3770 */ );
3771 #ifdef PATH_PREFIX
3772   Vconfigure_prefix_directory = Ffile_name_as_directory
3773     (build_string ((char *) PATH_PREFIX));
3774 #else
3775   Vconfigure_prefix_directory = Qnil;
3776 #endif
3777
3778   DEFVAR_LISP ("configure-info-directory", &Vconfigure_info_directory /*
3779 For internal use by the build procedure only.
3780 This is the name of the directory in which the build procedure installed
3781 Emacs's info files; the default value for Info-default-directory-list
3782 includes this.
3783 */ );
3784 #ifdef PATH_INFO
3785   Vconfigure_info_directory =
3786     Ffile_name_as_directory (build_string (PATH_INFO));
3787 #else
3788   Vconfigure_info_directory = Qnil;
3789 #endif
3790
3791   DEFVAR_LISP ("configure-info-path", &Vconfigure_info_path /*
3792 The configured initial path for info documentation.
3793 */ );
3794 #ifdef PATH_INFOPATH
3795   Vconfigure_info_path = decode_path (PATH_INFOPATH);
3796 #else
3797   Vconfigure_info_path = Qnil;
3798 #endif
3799 }
3800
3801 #if defined(__sgi) && !defined(PDUMP)
3802 /* This is so tremendously ugly I'd puke. But then, it works.
3803  * The target is to override the static constructor from the
3804  * libiflPNG.so library which is masquerading as libz, and
3805  * cores on us when re-started from the dumped executable.
3806  * This will have to go for 21.1  -- OG.
3807  */
3808 void __sti__iflPNGFile_c___ (void);
3809 void
3810 __sti__iflPNGFile_c___ (void)
3811 {
3812 }
3813
3814 #endif