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