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