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