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