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