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