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