XEmacs 21.2-b2
[chise/xemacs-chise.git.1] / src / emacs.c
1 /* XEmacs -- Fully extensible Emacs, running on Unix and other platforms.
2    Copyright (C) 1985, 1986, 1987, 1992, 1993, 1994
3    Free Software Foundation, Inc.
4    Copyright (C) 1995 Sun Microsystems, Inc.
5
6 This file is part of XEmacs.
7
8 XEmacs is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
11 later version.
12
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with XEmacs; see the file COPYING.  If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.  */
22
23 /* Synched up with: Mule 2.0, FSF 19.28. */
24
25 /* Note: It is necessary to specify <config.h> and not "config.h" in
26    order for the --srcdir type of compilation to work properly.
27    Otherwise the config.h from the srcdir, rather than the one from
28    the build dir, will be used. */
29
30 #include <config.h>
31 #include "lisp.h"
32
33 #include "backtrace.h" /* run-emacs-from-temacs needs this */
34 #include "buffer.h"
35 #include "commands.h"
36 #include "console.h"
37 #include "process.h"
38 #include "sysdep.h"
39
40 #include <setjmp.h>
41 #include "syssignal.h" /* Always include before systty.h */
42 #include "systty.h"
43 #include "sysfile.h"
44 #include "systime.h"
45
46 #ifdef HAVE_SHLIB
47 #include "sysdll.h"
48 #endif
49
50 #if defined (HAVE_LOCALE_H) && \
51    (defined (I18N2) || defined (I18N3) || defined (I18N4))
52 #include <locale.h>
53 #endif
54
55 #ifdef TOOLTALK
56 #include TT_C_H_PATH
57 #endif
58
59 #ifdef APOLLO
60 #ifndef APOLLO_SR10
61 #include <default_acl.h>
62 #endif
63 #endif
64
65 #if defined (WINDOWSNT)
66 #include <windows.h>
67 #endif
68
69 /* For PATH_EXEC */
70 #include <paths.h>
71
72 #if !defined SYSTEM_MALLOC && !defined DOUG_LEA_MALLOC
73 extern void *(*__malloc_hook)(size_t);
74 extern void *(*__realloc_hook)(void *, size_t);
75 extern void (*__free_hook)(void *);
76 #endif  /* not SYSTEM_MALLOC && not DOUG_LEA_MALLOC */
77
78 /* Command line args from shell, as list of strings */
79 Lisp_Object Vcommand_line_args;
80
81 /* Set nonzero after XEmacs has started up the first time.
82   Prevents reinitialization of the Lisp world and keymaps
83   on subsequent starts.  */
84 int initialized;
85
86 #ifdef DOUG_LEA_MALLOC
87 # include <malloc.h>
88 /* Preserves a pointer to the memory allocated that copies that
89    static data inside glibc's malloc.  */
90 static void *malloc_state_ptr;
91 #endif /* DOUG_LEA_MALLOC */
92
93 # ifdef REL_ALLOC
94 void r_alloc_reinit (void);
95 # endif
96
97 /* Variable whose value is symbol giving operating system type. */
98 Lisp_Object Vsystem_type;
99
100 /* Variable whose value is string giving configuration built for.  */
101 Lisp_Object Vsystem_configuration;
102
103 /* Variable whose value is string containing the configuration options
104    XEmacs was built with.  */
105 Lisp_Object Vsystem_configuration_options;
106
107 /* Version numbers and strings */
108 Lisp_Object Vemacs_major_version;
109 Lisp_Object Vemacs_minor_version;
110 Lisp_Object Vemacs_beta_version;
111 Lisp_Object Vxemacs_codename;
112 #ifdef INFODOCK
113 Lisp_Object Vinfodock_major_version;
114 Lisp_Object Vinfodock_minor_version;
115 Lisp_Object Vinfodock_build_version;
116 #endif
117
118 /* The path under which XEmacs was invoked. */
119 Lisp_Object Vinvocation_path;
120
121 /* The name under which XEmacs was invoked, with any leading directory
122    names discarded.  */
123 Lisp_Object Vinvocation_name;
124
125 /* The directory name from which XEmacs was invoked.  */
126 Lisp_Object Vinvocation_directory;
127
128 #if 0 /* FSFmacs */
129 /* The directory name in which to find subdirs such as lisp and etc.
130    nil means get them only from PATH_LOADSEARCH.  */
131 Lisp_Object Vinstallation_directory;
132 #endif
133
134 Lisp_Object Vemacs_program_name, Vemacs_program_version;
135 Lisp_Object Vexec_path;
136 Lisp_Object Vexec_directory, Vconfigure_exec_directory;
137 Lisp_Object Vlisp_directory, Vconfigure_lisp_directory;
138 Lisp_Object Vconfigure_package_path;
139 Lisp_Object Vdata_directory, Vconfigure_data_directory;
140 Lisp_Object Vdoc_directory, Vconfigure_doc_directory;
141 Lisp_Object Vconfigure_lock_directory;
142 Lisp_Object Vdata_directory_list;
143 Lisp_Object Vinfo_directory, Vconfigure_info_directory;
144 Lisp_Object Vsite_directory, Vconfigure_site_directory;
145 Lisp_Object Vconfigure_info_path;
146 Lisp_Object Vinternal_error_checking;
147 Lisp_Object Vpath_separator;
148
149 /* The default base directory XEmacs is installed under. */
150 Lisp_Object Vconfigure_exec_prefix_directory, Vconfigure_prefix_directory;
151
152 /* If nonzero, set XEmacs to run at this priority.  This is also used
153    in child_setup and sys_suspend to make sure subshells run at normal
154    priority. */
155 int emacs_priority;
156
157 /* If non-zero a filter or a sentinel is running.  Tested to save the match
158    data on the first attempt to change it inside asynchronous code. */
159 int running_asynch_code;
160
161 /* If non-zero, a window-system was specified on the command line. */
162 int display_arg;
163
164 /* Type of display specified.  We cannot use a Lisp symbol here because
165    Lisp symbols may not initialized at the time that we set this
166    variable. */
167 CONST char *display_use;
168
169 /* If non-zero, then the early error handler will only print the error
170    message and exit. */
171 int suppress_early_error_handler_backtrace;
172
173 /* An address near the bottom of the stack.
174    Tells GC how to save a copy of the stack.  */
175 char *stack_bottom;
176
177 #ifdef USG_SHARED_LIBRARIES
178 /* If nonzero, this is the place to put the end of the writable segment
179    at startup.  */
180
181 uintptr_t bss_end = 0;
182 #endif
183
184 /* Number of bytes of writable memory we can expect to be able to get */
185 unsigned int lim_data;
186
187 /* Nonzero means running XEmacs without interactive terminal.  */
188
189 int noninteractive;
190
191 /* Value of Lisp variable `noninteractive'.
192    Normally same as C variable `noninteractive'
193    but nothing terrible happens if user sets this one.  */
194
195 int noninteractive1;
196
197 /* Nonzero means don't perform site-lisp searches at startup */
198 int inhibit_site_lisp;
199
200 /* Nonzero means don't respect early packages at startup */
201 int inhibit_early_packages;
202
203 /* Nonzero means don't load package autoloads at startup */
204 int inhibit_autoloads;
205
206 /* Nonzero means print debug information about path searching */
207 int debug_paths;
208
209 /* Save argv and argc.  */
210 char **initial_argv;
211 int initial_argc;
212
213 static void sort_args (int argc, char **argv);
214
215 extern int always_gc;           /* hack */
216
217 Lisp_Object Qkill_emacs_hook;
218 Lisp_Object Qsave_buffers_kill_emacs;
219
220 \f
221 /* Signal code for the fatal signal that was received */
222 static int fatal_error_code;
223
224 /* Nonzero if handling a fatal error already */
225 static int fatal_error_in_progress;
226
227 static void shut_down_emacs (int sig, Lisp_Object stuff);
228
229 /* Handle bus errors, illegal instruction, etc. */
230 SIGTYPE
231 fatal_error_signal (int sig)
232 {
233   fatal_error_code = sig;
234   signal (sig, SIG_DFL);
235   /* Unblock the signal so that if the same signal gets sent in the
236      code below, we avoid a deadlock. */
237   EMACS_UNBLOCK_SIGNAL (fatal_error_code);
238
239   /* If fatal error occurs in code below, avoid infinite recursion.  */
240   if (! fatal_error_in_progress)
241     {
242       fatal_error_in_progress = dont_check_for_quit = 1;
243       shut_down_emacs (sig, Qnil);
244       stderr_out ("\nLisp backtrace follows:\n\n");
245       Fbacktrace (Qexternal_debugging_output, Qt);
246 # if 0  /* This is evil, rarely useful, and causes grief in some cases. */
247       /* Check for Sun-style stack printing via /proc */
248       {
249         CONST char *pstack = "/usr/proc/bin/pstack";
250         if (access (pstack, X_OK) == 0)
251           {
252             char buf[100];
253             stderr_out ("\nC backtrace follows:\n"
254                        "(A real debugger may provide better information)\n\n");
255             sprintf (buf, "%s %d >&2", pstack, (int)getpid());
256             system (buf);
257           }
258       }
259 # endif
260     }
261   /* Signal the same code; this time it will really be fatal. */
262   kill (getpid (), fatal_error_code);
263   SIGRETURN;
264 }
265 \f
266
267 DOESNT_RETURN
268 fatal (CONST char *fmt, ...)
269 {
270   va_list args;
271   va_start (args, fmt);
272
273   fprintf (stderr, "\nXEmacs: ");
274   vfprintf (stderr, GETTEXT (fmt), args);
275   fprintf (stderr, "\n");
276
277   va_end (args);
278   fflush (stderr);
279   exit (1);
280 }
281
282 /* #### The following two functions should be replaced with
283    calls to emacs_doprnt_*() functions, with STREAM set to send out
284    to stdout or stderr.  This is the only way to ensure that
285    I18N3 works properly (many implementations of the *printf()
286    functions, including the ones included in glibc, do not implement
287    the %###$ argument-positioning syntax). */
288
289 /* exactly equivalent to fprintf (stderr, fmt, ...) except that it calls
290    GETTEXT on the format string. */
291
292 int
293 stderr_out (CONST char *fmt, ...)
294 {
295   int retval;
296   va_list args;
297   va_start (args, fmt);
298
299   retval = vfprintf (stderr, GETTEXT (fmt), args);
300
301   va_end (args);
302   /* fflush (stderr); */
303   return retval;
304 }
305
306 /* exactly equivalent to fprintf (stdout, fmt, ...) except that it calls
307    GETTEXT on the format string. */
308
309 int
310 stdout_out (CONST char *fmt, ...)
311 {
312   int retval;
313   va_list args;
314   va_start (args, fmt);
315
316   retval = vfprintf (stdout, GETTEXT (fmt), args);
317
318   va_end (args);
319   return retval;
320 }
321
322 #ifdef SIGDANGER
323
324 /* Handler for SIGDANGER.  */
325 SIGTYPE
326 memory_warning_signal (int sig)
327 {
328   /* #### bad bad bad; this function shouldn't do anything except
329      set a flag, or weird corruption could happen. */
330   signal (sig, memory_warning_signal);
331
332   malloc_warning
333     (GETTEXT ("Operating system warns that virtual memory is running low.\n"));
334
335   /* It might be unsafe to call do_auto_save now.  */
336   force_auto_save_soon ();
337 }
338 #endif /* SIGDANGER */
339 \f
340 /* Code for dealing with Lisp access to the Unix command line */
341
342 static Lisp_Object
343 make_arg_list_1 (int argc, char **argv, int skip_args)
344 {
345   Lisp_Object result = Qnil;
346   REGISTER int i;
347
348   for (i = argc - 1; i >= 0; i--)
349     {
350       if (i == 0 || i > skip_args)
351         {
352 #ifdef WINDOWSNT
353           if (i == 0)
354             {
355               /* Do not trust to what crt0 has stuffed into argv[0] */
356               char full_exe_path [MAX_PATH];
357               GetModuleFileName (NULL, full_exe_path, MAX_PATH);
358               result = Fcons (build_ext_string (full_exe_path, FORMAT_FILENAME),
359                               result);
360 #if defined(HAVE_SHLIB)
361               (void)dll_init(full_exe_path);
362 #endif
363             }
364           else
365 #endif
366             result = Fcons (build_ext_string (argv [i], FORMAT_FILENAME), result);
367         }
368     }
369   return result;
370 }
371
372 Lisp_Object
373 make_arg_list (int argc, char **argv)
374 {
375   return make_arg_list_1 (argc, argv, 0);
376 }
377
378 /* Calling functions are also responsible for calling free_argc_argv
379    when they are done with the generated list. */
380 void
381 make_argc_argv (Lisp_Object argv_list, int *argc, char ***argv)
382 {
383   Lisp_Object next;
384   int n = XINT (Flength (argv_list));
385   REGISTER int i;
386   *argv = (char**) xmalloc ((n+1) * sizeof (char*));
387
388   for (i = 0, next = argv_list; i < n; i++, next = XCDR (next))
389     {
390       CONST char *temp;
391       CHECK_STRING (XCAR (next));
392
393       GET_C_STRING_EXT_DATA_ALLOCA (XCAR (next), FORMAT_OS, temp);
394       (*argv) [i] = xstrdup (temp);
395     }
396   (*argv) [n] = 0;
397   *argc = i;
398 }
399
400 void
401 free_argc_argv (char **argv)
402 {
403   int elt = 0;
404
405   while (argv[elt])
406     {
407       xfree (argv[elt]);
408       elt++;
409     }
410   xfree (argv);
411 }
412
413 static void
414 init_cmdargs (int argc, char **argv, int skip_args)
415 {
416   initial_argv = argv;
417   initial_argc = argc;
418
419   Vcommand_line_args = make_arg_list_1 (argc, argv, skip_args);
420 }
421
422 DEFUN ("invocation-name", Finvocation_name, 0, 0, 0, /*
423 Return the program name that was used to run XEmacs.
424 Any directory names are omitted.
425 */
426        ())
427 {
428   return Fcopy_sequence (Vinvocation_name);
429 }
430
431 DEFUN ("invocation-directory", Finvocation_directory, 0, 0, 0, /*
432 Return the directory name in which the Emacs executable was located.
433 */
434        ())
435 {
436   return Fcopy_sequence (Vinvocation_directory);
437 }
438
439 \f
440 #ifdef I18N4
441                                 /* #### - don't know why I18N4 on SunOS/JLE
442                                    can't deal with this.  It's a potential
443                                    bug that needs to be looked at. */
444 # undef RUN_TIME_REMAP
445 #endif
446
447 #if defined (MULE) && defined (MSDOS) && defined (EMX)
448 /* Setup all of files be input/output'ed with binary translation mdoe. */
449 asm ("  .text");
450 asm ("L_setbinmode:");
451 asm ("  movl    $1, __fmode_bin");
452 asm ("  ret");
453 asm ("  .stabs  \"___CTOR_LIST__\", 23, 0, 0, L_setbinmode");
454 #endif
455
456 /* Test whether the next argument in ARGV matches SSTR or a prefix of
457    LSTR (at least MINLEN characters).  If so, then if VALPTR is non-null
458    (the argument is supposed to have a value) store in *VALPTR either
459    the next argument or the portion of this one after the equal sign.
460    ARGV is read starting at position *SKIPPTR; this index is advanced
461    by the number of arguments used.
462
463    Too bad we can't just use getopt for all of this, but we don't have
464    enough information to do it right.  */
465
466 static int
467 argmatch (char **argv, int argc, char *sstr, char *lstr,
468           int minlen, char **valptr, int *skipptr)
469 {
470   char *p = NULL;
471   int arglen;
472   char *arg;
473
474   /* Don't access argv[argc]; give up in advance.  */
475   if (argc <= *skipptr + 1)
476     return 0;
477
478   arg = argv[*skipptr+1];
479   if (arg == NULL)
480     return 0;
481   if (strcmp (arg, sstr) == 0)
482     {
483       if (valptr != NULL)
484         {
485           *valptr = argv[*skipptr+2];
486           *skipptr += 2;
487         }
488       else
489         *skipptr += 1;
490       return 1;
491     }
492   arglen = (valptr != NULL && (p = strchr (arg, '=')) != NULL
493             ? p - arg : strlen (arg));
494   if (lstr == 0 || arglen < minlen || strncmp (arg, lstr, arglen) != 0)
495     return 0;
496   else if (valptr == NULL)
497     {
498       *skipptr += 1;
499       return 1;
500     }
501   else if (p != NULL)
502     {
503       *valptr = p+1;
504       *skipptr += 1;
505       return 1;
506     }
507   else if (argv[*skipptr+2] != NULL)
508     {
509       *valptr = argv[*skipptr+2];
510       *skipptr += 2;
511       return 1;
512     }
513   else
514     {
515       return 0;
516     }
517 }
518
519 /* Make stack traces always identify version + configuration */
520 #define main_1 STACK_TRACE_EYE_CATCHER
521
522 static DOESNT_RETURN
523 main_1 (int argc, char **argv, char **envp, int restart)
524 {
525   char stack_bottom_variable;
526   int skip_args = 0;
527   Lisp_Object load_me;
528   int inhibit_window_system;
529 #ifdef NeXT
530   extern int malloc_cookie;
531 #endif
532
533 #if !defined(SYSTEM_MALLOC) && !defined(HAVE_LIBMCHECK)
534   /* Make sure that any libraries we link against haven't installed a
535      hook for a gmalloc of a potentially incompatible version. */
536   /* If we're using libmcheck, the hooks have already been initialized, */
537   /* don't touch them. -slb */
538   __malloc_hook = NULL;
539   __realloc_hook = NULL;
540   __free_hook = NULL;
541 #endif /* not SYSTEM_MALLOC */
542
543   noninteractive = 0;
544
545 #ifdef NeXT
546   /* 19-Jun-1995 -baw
547    * NeXT secret magic, ripped from Emacs-for-NS by Carl Edman
548    * <cedman@princeton.edu>.  Note that even Carl doesn't know what this
549    * does; it was provided by NeXT, and it presumable makes NS's mallocator
550    * work with dumping.  But malloc_jumpstart() and malloc_freezedry() in
551    * unexnext.c are both completely undocumented, even in NS header files!
552    * But hey, it solves all NS related memory problems, so who's
553    * complaining? */
554   if (initialized && malloc_jumpstart (malloc_cookie) != 0)
555     fprintf (stderr, "malloc jumpstart failed!\n");
556 #endif /* NeXT */
557
558   /*
559 #if defined (GNU_MALLOC) && \
560     defined (ERROR_CHECK_MALLOC) && \
561     !defined (HAVE_LIBMCHECK)
562   */
563 #if defined(LOSING_GCC_DESTRUCTOR_FREE_BUG)
564   /* Prior to XEmacs 21, this was `#if 0'ed out.  */
565   /* I'm enabling this because it is the only reliable way I've found to */
566   /* prevent a very annoying problem where GCC will attempt to free(3) */
567   /* memory at exit() and cause a coredump. */
568   init_free_hook ();
569 #endif
570
571   sort_args (argc, argv);
572
573   /* Map in shared memory, if we are using that.  */
574 #ifdef HAVE_SHM
575   if (argmatch (argv, argc, "-nl", "--no-shared-memory", 6, NULL, &skip_args))
576     {
577       map_in_data (0);
578       /* The shared memory was just restored, which clobbered this.  */
579       skip_args = 1;
580     }
581   else
582     {
583       map_in_data (1);
584       /* The shared memory was just restored, which clobbered this.  */
585       skip_args = 0;
586     }
587 #endif /* HAVE_SHM */
588
589 #if (defined (MSDOS) && defined (EMX)) || defined (WIN32) || defined (_SCO_DS)
590   environ = envp;
591 #endif
592
593   /* Record (approximately) where the stack begins.  */
594   stack_bottom = &stack_bottom_variable;
595
596 #ifdef USG_SHARED_LIBRARIES
597   if (bss_end)
598     brk ((void *) bss_end);
599 #endif
600
601   clearerr (stdin);
602
603 #ifdef APOLLO
604 #ifndef APOLLO_SR10
605   /* If USE_DOMAIN_ACLS environment variable exists,
606      use ACLs rather than UNIX modes. */
607   if (egetenv ("USE_DOMAIN_ACLS"))
608     default_acl (USE_DEFACL);
609 #endif
610 #endif /* APOLLO */
611
612 #if defined (HAVE_MMAP) && defined (REL_ALLOC)
613   /* ralloc can only be used if using the GNU memory allocator. */
614   init_ralloc ();
615 #elif defined (REL_ALLOC) && !defined(DOUG_LEA_MALLOC)
616   if (initialized)
617     init_ralloc();
618 #endif
619
620 #ifdef HAVE_SOCKS
621   if (initialized)
622     SOCKSinit (argv[0]);
623 #endif /* HAVE_SOCKS */
624
625 #ifndef SYSTEM_MALLOC
626   if (!initialized)
627     /* Arrange to get warning messages as memory fills up.  */
628     memory_warnings (0, malloc_warning);
629 #endif  /* not SYSTEM_MALLOC */
630
631 #ifdef MSDOS
632   /* We do all file input/output as binary files.  When we need to translate
633      newlines, we do that manually.  */
634   _fmode = O_BINARY;
635   (stdin) ->_flag &= ~_IOTEXT;
636   (stdout)->_flag &= ~_IOTEXT;
637   (stderr)->_flag &= ~_IOTEXT;
638 #endif /* MSDOS */
639
640 #ifdef SET_EMACS_PRIORITY
641   if (emacs_priority != 0)
642     nice (-emacs_priority);
643   setuid (getuid ());
644 #endif /* SET_EMACS_PRIORITY */
645
646 #ifdef EXTRA_INITIALIZE
647   EXTRA_INITIALIZE;
648 #endif
649
650 #ifdef HAVE_WINDOW_SYSTEM
651   inhibit_window_system = 0;
652 #else
653   inhibit_window_system = 1;
654 #endif
655
656   /* Handle the -t switch, which specifies filename to use as terminal */
657   {
658     char *term;
659     if (argmatch (argv, argc, "-t", "--terminal", 4, &term, &skip_args))
660       {
661         close (0);
662         close (1);
663         if (open (term, O_RDWR | OPEN_BINARY, 2) < 0)
664           fatal ("%s: %s", term, strerror (errno));
665         dup (0);
666         if (! isatty (0))
667           fatal ("%s: not a tty", term);
668
669 #if 0
670         stderr_out ("Using %s", ttyname (0));
671 #endif
672         stderr_out ("Using %s", term);
673         inhibit_window_system = 1;      /* -t => -nw */
674       }
675   }
676
677   /* Handle -nw switch */
678   if (argmatch (argv, argc, "-nw", "--no-windows", 6, NULL, &skip_args))
679     inhibit_window_system = 1;
680
681   /* Handle the -batch switch, which means don't do interactive display.  */
682   if (argmatch (argv, argc, "-batch", "--batch", 5, NULL, &skip_args))
683     {
684 #if 0 /* I don't think this is correct. */
685       inhibit_autoloads = 1;
686 #endif
687       noninteractive = 1;
688     }
689
690   if (argmatch (argv, argc, "-debug-paths", "--debug-paths",
691                 11, NULL, &skip_args))
692       debug_paths = 1;
693
694   /* Partially handle -no-autoloads, -no-early-packages and -vanilla.  Packages */
695   /* are searched prior to the rest of the command line being parsed in */
696   /* startup.el */
697   if (argmatch (argv, argc, "-no-early-packages", "--no-early-packages",
698                 6, NULL, &skip_args))
699     {
700       inhibit_early_packages = 1;
701       skip_args--;
702     }
703   if (argmatch (argv, argc, "-vanilla", "--vanilla",
704                 7, NULL, &skip_args))
705     {
706       inhibit_early_packages = 1;
707       skip_args--;
708     }
709
710   if (argmatch (argv, argc, "-no-autoloads", "--no-autoloads",
711                 7, NULL, &skip_args))
712     {
713       /* Inhibit everything */
714       inhibit_autoloads = 1;
715       skip_args--;
716     }
717
718   if (argmatch (argv, argc, "-debug-paths", "--debug-paths",
719                 6, NULL, &skip_args))
720     {
721       debug_paths = 1;
722       skip_args--;
723     }
724
725
726   /* Partially handle the -version and -help switches: they imply -batch,
727      but are not removed from the list. */
728   if (argmatch (argv, argc, "-help", "--help",   3, NULL, &skip_args))
729     noninteractive = 1, skip_args--;
730
731   if (argmatch (argv, argc, "-version", "--version", 3, NULL, &skip_args) ||
732       argmatch (argv, argc, "-V",    0,              2, NULL, &skip_args))
733       noninteractive = 1, skip_args--;
734
735   /* Now, figure out which type of console is our first console. */
736
737   display_arg = 0;
738
739   if (noninteractive)
740     display_use = "stream";
741   else
742     display_use = "tty";
743
744 #ifndef HAVE_TTY
745   if (inhibit_window_system)
746     fatal ("Sorry, this XEmacs was not compiled with TTY support");
747 #endif
748
749 #ifdef HAVE_WINDOW_SYSTEM
750   /* Stupid kludge to catch command-line display spec.  We can't
751      handle this argument entirely in window-system-dependent code
752      because we don't even know which window-system-dependent code
753      to run until we've recognized this argument.  */
754   if (!inhibit_window_system && !noninteractive)
755     {
756 #ifdef HAVE_X_WINDOWS
757       char *dpy = 0;
758       int count_before = skip_args;
759
760       if (argmatch (argv, argc, "-d", "--display", 3, &dpy, &skip_args) ||
761           argmatch (argv, argc, "-display", 0,     3, &dpy, &skip_args))
762         {
763           display_arg = 1;
764           display_use = "x";
765         }
766       /* If we have the form --display=NAME,
767          convert it into  -d name.
768          This requires inserting a new element into argv.  */
769       if (dpy != 0 && skip_args - count_before == 1)
770         {
771           char **new = (char **) xmalloc (sizeof (char *) * (argc + 2));
772           int j;
773
774           for (j = 0; j < count_before + 1; j++)
775             new[j] = argv[j];
776           new[count_before + 1] = "-d";
777           new[count_before + 2] = dpy;
778           for (j = count_before + 2; j <argc; j++)
779             new[j + 1] = argv[j];
780           argv = new;
781           argc++;
782         }
783       /* Change --display to -d, when its arg is separate.  */
784       else if (dpy != 0 && skip_args > count_before
785                && argv[count_before + 1][1] == '-')
786         argv[count_before + 1] = "-d";
787
788       /* Don't actually discard this arg.  */
789       skip_args = count_before;
790
791       /* If there is a non-empty environment var DISPLAY, set
792          `display_use', but not `display_arg', which is only to be set
793          if the display was specified on the command line. */
794       if ((dpy = getenv ("DISPLAY")) && dpy[0])
795         display_use = "x";
796
797 #endif /* HAVE_X_WINDOWS */
798 #ifdef HAVE_MS_WINDOWS
799       if (strcmp(display_use, "x") != 0)
800         display_use = "mswindows";
801 #endif /* HAVE_MS_WINDOWS */
802     }
803 #endif /* HAVE_WINDOW_SYSTEM */
804
805   noninteractive1 = noninteractive;
806
807   /****** Now initialize everything *******/
808
809   /* First, do really basic environment initialization -- catching signals
810      and the like.  These functions have no dependence on any part of
811      the Lisp engine and need to be done both at dump time and at run time. */
812
813   init_signals_very_early ();
814   init_data_very_early (); /* Catch math errors. */
815 #ifdef LISP_FLOAT_TYPE
816   init_floatfns_very_early (); /* Catch floating-point math errors. */
817 #endif
818   init_process_times_very_early (); /* Initialize our process timers.
819                                        As early as possible, of course,
820                                        so we can be fairly accurate. */
821   init_intl_very_early (); /* set up the locale and domain for gettext and
822                               such. */
823
824   /* Now initialize the Lisp engine and the like.  Done only during
825      dumping.  No dependence on anything that may be in the user's
826      environment when the dumped XEmacs is run.
827
828      We try to do things in an order that minimizes the non-obvious
829      dependencies between functions. */
830
831   if (!initialized)
832     {
833       /* Initialize things so that new Lisp objects
834          can be created and objects can be staticpro'd.
835          Must be basically the very first thing done
836          because pretty much all of the initialization
837          routines below create new objects. */
838       init_alloc_once_early ();
839
840       /* Initialize Qnil, Qt, Qunbound, and the
841          obarray.  After this, symbols can be
842          interned.  This depends on init_alloc_once(). */
843       init_symbols_once_early ();
844
845       /* Declare the basic symbols pertaining to errors,
846          So that deferror() can be called. */
847       init_errors_once_early ();
848
849       /* Make sure that opaque pointers can be created. */
850       init_opaque_once_early ();
851
852       /* Now declare all the symbols and define all the Lisp primitives.
853
854          The *only* thing that the syms_of_*() functions are allowed to do
855          is call one of the following three functions:
856
857          defsymbol()
858          defsubr() (i.e. DEFSUBR)
859          deferror()
860          defkeyword()
861
862          Order does not matter in these functions.
863          */
864
865       syms_of_abbrev ();
866       syms_of_alloc ();
867 #ifdef HAVE_X_WINDOWS
868       syms_of_balloon_x ();
869 #endif
870       syms_of_buffer ();
871       syms_of_bytecode ();
872       syms_of_callint ();
873       syms_of_callproc ();
874       syms_of_casefiddle ();
875       syms_of_casetab ();
876       syms_of_chartab ();
877       syms_of_cmdloop ();
878       syms_of_cmds ();
879       syms_of_console ();
880       syms_of_data ();
881 #ifdef DEBUG_XEMACS
882       syms_of_debug ();
883 #endif /* DEBUG_XEMACS */
884       syms_of_device ();
885 #ifdef HAVE_DIALOGS
886       syms_of_dialog ();
887 #endif
888       syms_of_dired ();
889 #ifdef HAVE_SHLIB
890       syms_of_dll ();
891 #endif
892       syms_of_doc ();
893       syms_of_editfns ();
894       syms_of_elhash ();
895       syms_of_emacs ();
896       syms_of_eval ();
897 #ifdef HAVE_DRAGNDROP
898       syms_of_dragdrop ();
899 #endif
900       syms_of_event_stream ();
901       syms_of_events ();
902       syms_of_extents ();
903       syms_of_faces ();
904       syms_of_fileio ();
905 #ifdef CLASH_DETECTION
906       syms_of_filelock ();
907 #endif /* CLASH_DETECTION */
908       syms_of_floatfns ();
909       syms_of_fns ();
910       syms_of_font_lock ();
911       syms_of_frame ();
912       syms_of_general ();
913       syms_of_glyphs ();
914       syms_of_glyphs_eimage ();
915 #if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS)
916       syms_of_gui ();
917 #endif
918       syms_of_indent ();
919       syms_of_intl ();
920       syms_of_keymap ();
921       syms_of_lread ();
922       syms_of_macros ();
923       syms_of_marker ();
924       syms_of_md5 ();
925 #ifdef HAVE_DATABASE
926       syms_of_database ();
927 #endif
928 #ifdef HAVE_MENUBARS
929       syms_of_menubar ();
930 #endif
931       syms_of_minibuf ();
932       syms_of_objects ();
933       syms_of_print ();
934 #if !defined (NO_SUBPROCESSES)
935       syms_of_process ();
936 #ifdef HAVE_WIN32_PROCESSES
937       syms_of_process_nt ();
938 #endif
939 #endif
940       syms_of_profile ();
941 #if defined (HAVE_MMAP) && defined (REL_ALLOC) && !defined(DOUG_LEA_MALLOC)
942       syms_of_ralloc ();
943 #endif /* HAVE_MMAP && REL_ALLOC */
944       syms_of_rangetab ();
945       syms_of_redisplay ();
946       syms_of_search ();
947       syms_of_signal ();
948       syms_of_sound ();
949       syms_of_specifier ();
950       syms_of_symbols ();
951       syms_of_syntax ();
952 #ifdef HAVE_SCROLLBARS
953       syms_of_scrollbar ();
954 #endif
955 #ifdef HAVE_TOOLBARS
956       syms_of_toolbar ();
957 #endif
958       syms_of_undo ();
959       syms_of_widget ();
960       syms_of_window ();
961
962 #ifdef HAVE_TTY
963       syms_of_console_tty ();
964       syms_of_device_tty ();
965       syms_of_objects_tty ();
966 #endif
967 #ifdef HAVE_X_WINDOWS
968       syms_of_device_x ();
969 #ifdef HAVE_DIALOGS
970       syms_of_dialog_x ();
971 #endif
972       syms_of_event_Xt ();
973       syms_of_frame_x ();
974       syms_of_glyphs_x ();
975       syms_of_objects_x ();
976 #ifdef HAVE_MENUBARS
977       syms_of_menubar_x ();
978 #endif
979       syms_of_xselect ();
980 #if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS)
981       syms_of_gui_x ();
982 #endif
983 #endif /* HAVE_X_WINDOWS */
984
985 #ifdef HAVE_MS_WINDOWS
986       syms_of_console_mswindows ();
987       syms_of_device_mswindows ();
988       syms_of_event_mswindows ();
989       syms_of_frame_mswindows ();
990       syms_of_objects_mswindows ();
991       syms_of_select_mswindows ();
992       syms_of_glyphs_mswindows ();
993 #ifdef HAVE_MENUBARS
994       syms_of_menubar_mswindows ();
995 #endif
996 #ifdef HAVE_SCROLLBARS
997       syms_of_scrollbar_mswindows ();
998 #endif
999 #ifdef HAVE_MSW_C_DIRED
1000       syms_of_dired_mswindows ();
1001 #endif
1002 #endif  /* HAVE_MS_WINDOWS */
1003
1004 #ifdef MULE
1005       syms_of_mule ();
1006       syms_of_mule_ccl ();
1007       syms_of_mule_charset ();
1008 #endif
1009 #ifdef FILE_CODING
1010       syms_of_mule_coding ();
1011 #endif
1012 #ifdef MULE
1013 #ifdef HAVE_WNN
1014       syms_of_mule_wnn ();
1015 #endif
1016 #ifdef HAVE_CANNA
1017       syms_of_mule_canna ();
1018 #endif /* HAVE_CANNA */
1019 #endif /* MULE */
1020
1021 #ifdef SYMS_SYSTEM
1022       SYMS_SYSTEM;
1023 #endif
1024
1025 #ifdef SYMS_MACHINE
1026       SYMS_MACHINE;
1027 #endif
1028
1029 #ifdef EMACS_BTL
1030       syms_of_btl ();
1031 #endif
1032
1033       /*
1034 #if defined (GNU_MALLOC) && \
1035     defined (ERROR_CHECK_MALLOC) && \
1036     !defined (HAVE_LIBMCHECK)
1037       */
1038       /* Prior to XEmacs 21, this was `#if 0'ed out. -slb */
1039 #if defined (LOSING_GCC_DESTRUCTOR_FREE_BUG)
1040       syms_of_free_hook ();
1041 #endif
1042
1043 #ifdef TOOLTALK
1044       syms_of_tooltalk ();
1045 #endif
1046
1047 #ifdef SUNPRO
1048       syms_of_sunpro ();
1049 #endif
1050
1051 #ifdef HAVE_LDAP
1052       syms_of_eldap ();
1053 #endif
1054
1055       /* Now create the subtypes for the types that have them.
1056          We do this before the vars_*() because more symbols
1057          may get initialized here. */
1058
1059       /* Now initialize the console types and associated symbols.
1060          Other than the first function below, the functions may
1061          make exactly the following function/macro calls:
1062
1063          INITIALIZE_CONSOLE_TYPE()
1064          CONSOLE_HAS_METHOD()
1065
1066          For any given console type, the former macro must be called
1067          before the any calls to the latter macro. */
1068
1069       console_type_create ();
1070
1071       console_type_create_stream ();
1072
1073 #ifdef HAVE_TTY
1074       console_type_create_tty ();
1075       console_type_create_device_tty ();
1076       console_type_create_frame_tty ();
1077       console_type_create_objects_tty ();
1078       console_type_create_redisplay_tty ();
1079 #endif
1080
1081 #ifdef HAVE_X_WINDOWS
1082       console_type_create_x ();
1083       console_type_create_device_x ();
1084       console_type_create_frame_x ();
1085       console_type_create_glyphs_x ();
1086 #ifdef HAVE_MENUBARS
1087       console_type_create_menubar_x ();
1088 #endif
1089       console_type_create_objects_x ();
1090       console_type_create_redisplay_x ();
1091 #ifdef HAVE_SCROLLBARS
1092       console_type_create_scrollbar_x ();
1093 #endif
1094 #ifdef HAVE_TOOLBARS
1095       console_type_create_toolbar_x ();
1096 #endif
1097 #ifdef HAVE_DIALOGS
1098       console_type_create_dialog_x ();
1099 #endif
1100 #endif /* HAVE_X_WINDOWS */
1101
1102 #ifdef HAVE_MS_WINDOWS
1103       console_type_create_mswindows ();
1104       console_type_create_device_mswindows ();
1105       console_type_create_frame_mswindows ();
1106       console_type_create_objects_mswindows ();
1107       console_type_create_redisplay_mswindows ();
1108       console_type_create_glyphs_mswindows ();
1109 # ifdef HAVE_SCROLLBARS
1110       console_type_create_scrollbar_mswindows ();
1111 # endif
1112 #ifdef HAVE_MENUBARS
1113       console_type_create_menubar_mswindows ();
1114 #endif
1115 #ifdef HAVE_TOOLBARS
1116       console_type_create_toolbar_mswindows ();
1117 #endif
1118 #ifdef HAVE_DIALOGS
1119       console_type_create_dialog_mswindows ();
1120 #endif
1121 #endif
1122
1123       /* Now initialize the specifier types and associated symbols.
1124          Other than the first function below, the functions may
1125          make exactly the following function/macro calls:
1126
1127          INITIALIZE_SPECIFIER_TYPE()
1128          SPECIFIER_HAS_METHOD()
1129
1130          For any given specifier type, the former macro must be called
1131          before the any calls to the latter macro. */
1132
1133       specifier_type_create ();
1134
1135       specifier_type_create_image ();
1136       specifier_type_create_objects ();
1137 #ifdef HAVE_TOOLBARS
1138       specifier_type_create_toolbar ();
1139 #endif
1140
1141       /* Now initialize the structure types and associated symbols.
1142          Other than the first function below, the functions may
1143          make exactly the following function/macro calls:
1144
1145          define_structure_type()
1146          define_structure_type_keyword()
1147
1148          */
1149
1150       structure_type_create ();
1151
1152       structure_type_create_chartab ();
1153       structure_type_create_faces ();
1154       structure_type_create_rangetab ();
1155       structure_type_create_hashtable ();
1156
1157       /* Now initialize the image instantiator formats and associated symbols.
1158          Other than the first function below, the functions may
1159          make exactly the following function/macro calls:
1160
1161          INITIALIZE_IMAGE_INSTANTIATOR_FORMAT()
1162          IIFORMAT_HAS_METHOD()
1163          IIFORMAT_VALID_KEYWORD()
1164
1165          For any given image instantiator format, the first macro must be
1166          called before the any calls to the other macros. */
1167
1168       image_instantiator_format_create ();
1169       image_instantiator_format_create_glyphs_eimage ();
1170 #ifdef HAVE_X_WINDOWS
1171       image_instantiator_format_create_glyphs_x ();
1172 #endif /* HAVE_X_WINDOWS */
1173 #ifdef HAVE_MS_WINDOWS
1174       image_instantiator_format_create_glyphs_mswindows ();
1175 #endif /* HAVE_MSWINDOWS_WINDOWS */
1176
1177       /* Now initialize the lstream types and associated symbols.
1178          Other than the first function below, the functions may
1179          make exactly the following function/macro calls:
1180
1181          LSTREAM_HAS_METHOD()
1182
1183          */
1184
1185       lstream_type_create ();
1186 #ifdef FILE_CODING
1187       lstream_type_create_mule_coding ();
1188 #endif
1189 #if defined (HAVE_MS_WINDOWS) && !defined(HAVE_MSG_SELECT)
1190       lstream_type_create_mswindows_selectable ();
1191 #endif
1192       
1193       /* Initialize processes implementation.
1194          The functions may make exactly the following function/macro calls:
1195
1196          PROCESS_HAS_METHOD()
1197       */
1198 #ifdef HAVE_UNIX_PROCESSES
1199       process_type_create_unix ();
1200 #endif
1201 #ifdef HAVE_WIN32_PROCESSES
1202       process_type_create_nt ();
1203 #endif
1204
1205       /* Now initialize most variables.
1206
1207          These functions may do exactly the following:
1208
1209          DEFVAR_INT()
1210          DEFVAR_LISP()
1211          DEFVAR_BOOL()
1212          DEFER_GETTEXT()
1213          Dynarr_*()
1214          Blocktype_*()
1215          staticpro()
1216          Fprovide(symbol)
1217          intern()
1218          pure_put()
1219          xmalloc()
1220          defsymbol(), if it's absolutely necessary and you're sure that
1221            the symbol isn't referenced anywhere else in the initialization
1222            code
1223          Fset() on a symbol that is unbound
1224          assigning a symbol or constant value to a variable
1225          using a global variable that has been initialized
1226            earlier on in the same function
1227
1228          Any of the object-creating functions on alloc.c: e.g.
1229
1230          make_pure_*()
1231          Fpurecopy()
1232          make_string()
1233          build_string()
1234          make_vector()
1235          make_int()
1236          make_extent()
1237          alloc_lcrecord()
1238          Fcons()
1239          listN()
1240          make_opaque_ptr()
1241          make_opaque_long()
1242
1243          perhaps a few others.
1244        */
1245
1246       /* Now allow Fprovide() statements to be made. */
1247       init_provide_once ();
1248
1249       vars_of_abbrev ();
1250       vars_of_alloc ();
1251 #ifdef HAVE_X_WINDOWS
1252       vars_of_balloon_x ();
1253 #endif
1254       vars_of_buffer ();
1255       vars_of_bytecode ();
1256       vars_of_callint ();
1257       vars_of_callproc ();
1258       vars_of_cmdloop ();
1259       vars_of_cmds ();
1260       vars_of_console ();
1261       vars_of_data ();
1262 #ifdef DEBUG_XEMACS
1263       vars_of_debug ();
1264 #endif
1265       vars_of_console_stream ();
1266       vars_of_device ();
1267 #ifdef HAVE_DIALOGS
1268       vars_of_dialog ();
1269 #endif
1270       vars_of_dired ();
1271       vars_of_doc ();
1272 #ifdef HAVE_DRAGNDROP
1273       vars_of_dragdrop ();
1274 #endif
1275       vars_of_editfns ();
1276       vars_of_elhash ();
1277       vars_of_emacs ();
1278       vars_of_eval ();
1279       vars_of_event_stream ();
1280       vars_of_events ();
1281       vars_of_extents ();
1282       vars_of_faces ();
1283       vars_of_fileio ();
1284       vars_of_floatfns ();
1285       vars_of_font_lock ();
1286       vars_of_frame ();
1287       vars_of_glyphs ();
1288       vars_of_glyphs_eimage ();
1289 #if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS)
1290       vars_of_gui ();
1291 #endif
1292       vars_of_indent ();
1293       vars_of_insdel ();
1294       vars_of_intl ();
1295 #ifdef HAVE_XIM
1296 #ifdef XIM_MOTIF
1297       vars_of_input_method_motif ();
1298 #else /* XIM_XLIB */
1299       vars_of_input_method_xlib ();
1300 #endif
1301 #endif /* HAVE_XIM */
1302       vars_of_keymap ();
1303       vars_of_lread ();
1304       vars_of_lstream ();
1305       vars_of_macros ();
1306       vars_of_md5 ();
1307 #ifdef HAVE_DATABASE
1308       vars_of_database ();
1309 #endif
1310 #ifdef HAVE_MENUBARS
1311       vars_of_menubar ();
1312 #endif
1313       vars_of_minibuf ();
1314       vars_of_objects ();
1315       vars_of_print ();
1316
1317 #ifndef NO_SUBPROCESSES
1318       vars_of_process ();
1319 #ifdef HAVE_UNIX_PROCESSES
1320       vars_of_process_unix ();
1321 #endif
1322 #ifdef HAVE_WIN32_PROCESSES
1323       vars_of_process_nt ();
1324 #endif
1325 #endif
1326
1327       vars_of_profile ();
1328 #if defined (HAVE_MMAP) && defined (REL_ALLOC) && !defined(DOUG_LEA_MALLOC)
1329       vars_of_ralloc ();
1330 #endif /* HAVE_MMAP && REL_ALLOC */
1331       vars_of_redisplay ();
1332 #ifdef HAVE_SCROLLBARS
1333       vars_of_scrollbar ();
1334 #endif
1335       vars_of_search ();
1336       vars_of_sound ();
1337       vars_of_specifier ();
1338       vars_of_symbols ();
1339       vars_of_syntax ();
1340 #ifdef HAVE_TOOLBARS
1341       vars_of_toolbar ();
1342 #endif
1343       vars_of_undo ();
1344       vars_of_window ();
1345
1346 #ifdef HAVE_TTY
1347       vars_of_console_tty ();
1348       vars_of_event_tty ();
1349       vars_of_frame_tty ();
1350       vars_of_objects_tty ();
1351 #endif
1352
1353 #ifdef HAVE_X_WINDOWS
1354       vars_of_device_x ();
1355 #ifdef HAVE_DIALOGS
1356       vars_of_dialog_x ();
1357 #endif
1358       vars_of_event_Xt ();
1359       vars_of_frame_x ();
1360       vars_of_glyphs_x ();
1361 #ifdef HAVE_MENUBARS
1362       vars_of_menubar_x ();
1363 #endif
1364       vars_of_objects_x ();
1365       vars_of_xselect ();
1366 #ifdef HAVE_SCROLLBARS
1367       vars_of_scrollbar_x ();
1368 #endif
1369 #if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS)
1370       vars_of_gui_x ();
1371 #endif
1372 #endif
1373
1374 #ifdef HAVE_MS_WINDOWS
1375       vars_of_device_mswindows ();
1376       vars_of_console_mswindows ();
1377       vars_of_event_mswindows ();
1378       vars_of_frame_mswindows ();
1379       vars_of_objects_mswindows ();
1380       vars_of_select_mswindows ();
1381       vars_of_glyphs_mswindows ();
1382 #ifdef HAVE_SCROLLBARS
1383       vars_of_scrollbar_mswindows ();
1384 #endif
1385 #ifdef HAVE_MENUBARS
1386       vars_of_menubar_mswindows ();
1387 #endif
1388 #ifdef HAVE_MSW_C_DIRED
1389       vars_of_dired_mswindows ();
1390 #endif
1391 #ifdef HAVE_DIALOGS
1392       vars_of_dialog_mswindows ();
1393 #endif
1394 #endif  /* HAVE_MS_WINDOWS */
1395
1396 #ifdef MULE
1397       vars_of_mule ();
1398       vars_of_mule_charset ();
1399 #endif
1400 #ifdef FILE_CODING
1401       vars_of_mule_coding ();
1402 #endif
1403 #ifdef MULE
1404 #ifdef HAVE_WNN
1405       vars_of_mule_wnn ();
1406 #endif
1407 #ifdef HAVE_CANNA
1408       vars_of_mule_canna ();
1409 #endif /* HAVE_CANNA */
1410 #endif /* MULE */
1411
1412 #ifdef TOOLTALK
1413       vars_of_tooltalk ();
1414 #endif
1415
1416 #ifdef SUNPRO
1417       vars_of_sunpro ();
1418 #endif
1419
1420 #ifdef HAVE_LDAP
1421       vars_of_eldap ();
1422 #endif
1423
1424       /* Now initialize any specifier variables.  We do this later
1425          because it has some dependence on the vars initialized
1426          above.
1427
1428          These functions should *only* initialize specifier variables,
1429          and may make use of the following functions/macros in addition
1430          to the ones listed above:
1431
1432          DEFVAR_SPECIFIER()
1433          Fmake_specifier()
1434          set_specifier_fallback()
1435          set_specifier_caching()
1436          */
1437
1438       specifier_vars_of_glyphs ();
1439 #ifdef HAVE_MENUBARS
1440       specifier_vars_of_menubar ();
1441 #endif
1442       specifier_vars_of_redisplay ();
1443 #ifdef HAVE_SCROLLBARS
1444       specifier_vars_of_scrollbar ();
1445 #endif
1446 #ifdef HAVE_TOOLBARS
1447       specifier_vars_of_toolbar ();
1448 #endif
1449       specifier_vars_of_window ();
1450
1451       /* Now comes all the rest of the variables that couldn't
1452          be handled above.  There may be dependencies on variables
1453          initialized above, and dependencies between one complex_vars_()
1454          function and another. */
1455
1456       /* Calls Fmake_range_table(). */
1457       complex_vars_of_regex ();
1458       /* Calls Fmake_range_table(). */
1459       complex_vars_of_search ();
1460
1461       /* Calls make_lisp_hashtable(). */
1462       complex_vars_of_extents ();
1463
1464       /* Depends on hashtables and specifiers. */
1465       complex_vars_of_faces ();
1466
1467 #ifdef MULE
1468       /* These two depend on hashtables and various variables declared
1469          earlier.  The second may also depend on the first. */
1470       complex_vars_of_mule_charset ();
1471 #endif
1472 #if defined(FILE_CODING)
1473       complex_vars_of_mule_coding ();
1474 #endif
1475
1476       /* This calls allocate_glyph(), which creates specifiers
1477          and also relies on a variable (Vthe_nothing_vector) initialized
1478          above.  It also calls make_ext_string(), which under Mule
1479          could require that the charsets be initialized. */
1480       complex_vars_of_glyphs ();
1481
1482       /* These rely on the glyphs just created in the previous function,
1483          and call Fadd_spec_to_specifier(), which relies on various
1484          variables initialized above. */
1485 #ifdef HAVE_X_WINDOWS
1486       complex_vars_of_glyphs_x ();
1487 #endif
1488 #ifdef HAVE_MS_WINDOWS
1489       complex_vars_of_glyphs_mswindows ();
1490 #endif
1491
1492       /* This calls Fmake_glyph_internal(). */
1493       complex_vars_of_alloc ();
1494
1495       /* This calls Fmake_glyph_internal(). */
1496 #ifdef HAVE_MENUBARS
1497       complex_vars_of_menubar ();
1498 #endif
1499
1500       /* This calls Fmake_glyph_internal(). */
1501 #ifdef HAVE_SCROLLBARS
1502       complex_vars_of_scrollbar ();
1503 #endif
1504
1505       /* This calls allocate_glyph(). */
1506       complex_vars_of_frame ();
1507
1508       /* This calls Fcopy_category_table() under Mule, which calls who
1509          knows what. */
1510       complex_vars_of_chartab ();
1511
1512       /* This calls set_string_char(), which (under Mule) depends on the
1513          charsets being initialized. */
1514       complex_vars_of_casetab ();
1515
1516       /* This calls Fcopy_syntax_table(), which relies on char tables. */
1517       complex_vars_of_syntax ();
1518
1519       /* This initializes buffer-local variables, sets things up so
1520          that buffers can be created, and creates a couple of basic
1521          buffers.  This depends on Vstandard_syntax_table and
1522          Vstandard_category_table (initialized in the previous
1523          functions), as well as a whole horde of variables that may
1524          have been initialized above. */
1525       complex_vars_of_buffer ();
1526
1527       /* This initializes console-local variables. */
1528       complex_vars_of_console ();
1529
1530       /* This creates a couple more buffers, and depends on the
1531          previous function. */
1532       complex_vars_of_minibuf ();
1533
1534       /* These two might call Ffile_name_as_directory(), which
1535          might depend on all sorts of things; I'm not sure. */
1536       complex_vars_of_emacs ();
1537
1538       /* This creates a couple of basic keymaps and depends on Lisp
1539          hashtables and Ffset() (both of which depend on some variables
1540          initialized in the vars_of_*() section) and possibly other
1541          stuff. */
1542       complex_vars_of_keymap ();
1543       /* Calls Fmake_hashtable() and creates a keymap */
1544       complex_vars_of_event_stream ();
1545
1546       if (always_gc)                /* purification debugging hack */
1547         garbage_collect_1 ();
1548     }
1549
1550   /* CONGRATULATIONS!!!  We have successfully initialized the Lisp
1551      engine. */
1552
1553   if (initialized)
1554     {
1555       /* Stuff that needs to be reset at run time.  Order below should
1556          not matter. */
1557       reinit_alloc ();
1558       reinit_eval ();
1559 #ifdef MULE_REGEXP
1560       reinit_mule_category ();
1561 #endif
1562     }
1563
1564   /* Now do further initialization/setup of stuff that is not needed by the
1565      syms_of_() routines.  This involves stuff that only is enabled in
1566      an interactive run (redisplay, user input, etc.) and stuff that is
1567      not needed until we start loading Lisp code (the reader).  A lot
1568      of this stuff involves querying the current environment and needs
1569      to be done both at dump time and at run time. */
1570
1571   init_initial_directory();             /* get the directory to use for the
1572                                            "*scratch*" buffer, etc. */
1573
1574 #ifdef WINDOWSNT
1575   /*
1576    * For Win32, call init_environment() now, so that environment/registry
1577    * variables will be properly entered into Vprocess_envonment.
1578    */
1579   init_environment();
1580 #endif
1581
1582   init_callproc ();     /* Set up the process environment (so that egetenv
1583                            works), the basic directory variables
1584                            (exec-directory and so on), and stuff
1585                            related to subprocesses.  This should be
1586                            first because many of the functions below
1587                            call egetenv() to get environment variables. */
1588   init_lread ();        /* Set up the Lisp reader. */
1589 #ifdef MSDOS
1590   /* Call early 'cause init_environment needs it.  */
1591   init_dosfns ();
1592   /* Set defaults for several environment variables.  */
1593   init_environment (argc, argv, skip_args);
1594 #endif
1595   init_cmdargs (argc, argv, skip_args); /* Create list Vcommand_line_args */
1596   init_buffer ();       /* Set default directory of *scratch* buffer */
1597
1598 #ifdef WINDOWSNT
1599   init_ntproc();
1600 #endif
1601
1602   init_redisplay ();      /* Determine terminal type.
1603                              init_sys_modes uses results */
1604   init_event_stream (); /* Set up so we can get user input. */
1605   init_macros (); /* set up so we can run macros. */
1606   init_editfns (); /* Determine the name of the user we're running as */
1607   init_xemacs_process (); /* set up for calling subprocesses */
1608 #ifdef SUNPRO
1609   init_sunpro (); /* Set up Sunpro usage tracking */
1610 #endif
1611 #if defined (HAVE_NATIVE_SOUND) && defined (hp9000s800)
1612   init_hpplay ();
1613 #endif
1614 #ifdef HAVE_TTY
1615   init_device_tty ();
1616 #endif
1617   init_console_stream (); /* Create the first console */
1618
1619   /* try to get the actual pathname of the exec file we are running */
1620   if (!restart)
1621   {
1622     Vinvocation_name = Fcar (Vcommand_line_args);
1623     if (XSTRING_DATA(Vinvocation_name)[0] == '-')
1624       {
1625         /* XEmacs as a login shell, oh goody! */
1626         Vinvocation_name = build_string(getenv("SHELL"));
1627       }
1628     Vinvocation_directory = Vinvocation_name;
1629
1630     if (!NILP (Ffile_name_directory (Vinvocation_name)))
1631       {
1632         /* invocation-name includes a directory component -- presumably it
1633            is relative to cwd, not $PATH */
1634         Vinvocation_directory = Fexpand_file_name (Vinvocation_name,
1635                                                    Qnil);
1636         Vinvocation_path = Qnil;
1637       }
1638     else
1639       {
1640         Vinvocation_path = decode_env_path ("PATH", NULL);
1641         locate_file (Vinvocation_path, Vinvocation_name, EXEC_SUFFIXES,
1642                      &Vinvocation_directory, X_OK);
1643       }
1644
1645     if (NILP (Vinvocation_directory))
1646       Vinvocation_directory = Vinvocation_name;
1647
1648     Vinvocation_name = Ffile_name_nondirectory (Vinvocation_directory);
1649     Vinvocation_directory = Ffile_name_directory (Vinvocation_directory);
1650   }
1651
1652 #if defined(HAVE_SHLIB) && !defined(WINDOWSNT)
1653   /* This is Unix only.  MS Windows NT has a library call that does
1654      The Right Thing on that system.  Rumor has it, this must be
1655      called for GNU dld in temacs and xemacs.  */
1656   {
1657     char *buf = (char *)alloca (XSTRING_LENGTH (Vinvocation_directory)
1658                                 + XSTRING_LENGTH (Vinvocation_name)
1659                                 + 2);
1660     sprintf (buf, "%s/%s", XSTRING_DATA(Vinvocation_directory),
1661              XSTRING_DATA(Vinvocation_name));
1662
1663     /* All we can do is cry if an error happens, so ignore it. */
1664     (void)dll_init(buf);
1665   }
1666 #endif
1667
1668 #if defined (LOCALTIME_CACHE) && defined (HAVE_TZSET)
1669   /* sun's localtime() has a bug.  it caches the value of the time
1670      zone rather than looking it up every time.  Since localtime() is
1671      called to bolt the undumping time into the undumped emacs, this
1672      results in localtime() ignoring the TZ environment variable.
1673      This flushes the new TZ value into localtime(). */
1674   tzset ();
1675 #endif /* LOCALTIME_CACHE and TZSET */
1676
1677   load_me = Qnil;
1678   if (!initialized)
1679     {
1680       /* Handle -l loadup-and-dump, args passed by Makefile. */
1681       if (argc > 2 + skip_args && !strcmp (argv[1 + skip_args], "-l"))
1682         load_me = build_string (argv[2 + skip_args]);
1683 #if 0 /* CANNOT_DUMP - this can never be right in XEmacs --andyp */
1684       /* Unless next switch is -nl, load "loadup.el" first thing.  */
1685       if (!(argc > 1 + skip_args && !strcmp (argv[1 + skip_args], "-nl")))
1686         load_me = build_string ("loadup.el");
1687 #endif /* CANNOT_DUMP */
1688     }
1689
1690 #ifdef QUANTIFY
1691   if (initialized)
1692     quantify_start_recording_data ();
1693 #endif /* QUANTIFY */
1694
1695   initialized = 1;
1696
1697   /* This never returns.  */
1698   initial_command_loop (load_me);
1699   /* NOTREACHED */
1700 }
1701
1702 \f
1703 /* Sort the args so we can find the most important ones
1704    at the beginning of argv.  */
1705
1706 /* First, here's a table of all the standard options.  */
1707
1708 struct standard_args
1709 {
1710   CONST char * CONST name;
1711   CONST char * CONST longname;
1712   int priority;
1713   int nargs;
1714 };
1715
1716 static struct standard_args standard_args[] =
1717 {
1718   /* Handled by main_1 above: */
1719   { "-nl", "--no-shared-memory", 100, 0 },
1720   { "-t", "--terminal", 95, 1 },
1721   { "-nw", "--no-windows", 90, 0 },
1722   { "-batch", "--batch", 85, 0 },
1723   { "-debug-paths", "--debug-paths", 82, 0 },
1724   { "-help", "--help", 80, 0 },
1725   { "-version", "--version", 75, 0 },
1726   { "-V", 0, 75, 0 },
1727   { "-d", "--display", 80, 1 },
1728   { "-display", 0, 80, 1 },
1729   { "-NXHost",  0, 79, 0 },
1730   { "-MachLaunch", 0, 79, 0},
1731
1732   /* Handled by command-line-early in startup.el: */
1733   { "-q", "--no-init-file", 50, 0 },
1734   { "-unmapped", 0, 50, 0 },
1735   { "-no-init-file", 0, 50, 0 },
1736   { "-vanilla", "--vanilla", 50, 0 },
1737   { "-no-autoloads", "--no-autoloads", 50, 0 },
1738   { "-no-site-file", "--no-site-file", 40, 0 },
1739   { "-no-early-packages", "--no-early-packages", 35, 0 },
1740   { "-u", "--user", 30, 1 },
1741   { "-user", 0, 30, 1 },
1742   { "-debug-init", "--debug-init", 20, 0 },
1743   { "-debug-paths", "--debug-paths", 20, 0 },
1744
1745   /* Xt options: */
1746   { "-i", "--icon-type", 15, 0 },
1747   { "-itype", 0, 15, 0 },
1748   { "-iconic", "--iconic", 15, 0 },
1749   { "-bg", "--background-color", 10, 1 },
1750   { "-background", 0, 10, 1 },
1751   { "-fg", "--foreground-color", 10, 1 },
1752   { "-foreground", 0, 10, 1 },
1753   { "-bd", "--border-color", 10, 1 },
1754   { "-bw", "--border-width", 10, 1 },
1755   { "-ib", "--internal-border", 10, 1 },
1756   { "-ms", "--mouse-color", 10, 1 },
1757   { "-cr", "--cursor-color", 10, 1 },
1758   { "-fn", "--font", 10, 1 },
1759   { "-font", 0, 10, 1 },
1760   { "-g", "--geometry", 10, 1 },
1761   { "-geometry", 0, 10, 1 },
1762   { "-T", "--title", 10, 1 },
1763   { "-title", 0, 10, 1 },
1764   { "-name", "--name", 10, 1 },
1765   { "-xrm", "--xrm", 10, 1 },
1766   { "-r", "--reverse-video", 5, 0 },
1767   { "-rv", 0, 5, 0 },
1768   { "-reverse", 0, 5, 0 },
1769   { "-hb", "--horizontal-scroll-bars", 5, 0 },
1770   { "-vb", "--vertical-scroll-bars", 5, 0 },
1771
1772   /* These have the same priority as ordinary file name args,
1773      so they are not reordered with respect to those.  */
1774   { "-L", "--directory", 0, 1 },
1775   { "-directory", 0, 0, 1 },
1776   { "-l", "--load", 0, 1 },
1777   { "-load", 0, 0, 1 },
1778   { "-f", "--funcall", 0, 1 },
1779   { "-funcall", 0, 0, 1 },
1780   { "-eval", "--eval", 0, 1 },
1781   { "-insert", "--insert", 0, 1 },
1782   /* This should be processed after ordinary file name args and the like.  */
1783   { "-kill", "--kill", -10, 0 },
1784 };
1785
1786 /* Reorder the elements of ARGV (assumed to have ARGC elements)
1787    so that the highest priority ones come first.
1788    Do not change the order of elements of equal priority.
1789    If an option takes an argument, keep it and its argument together.  */
1790
1791 static void
1792 sort_args (int argc, char **argv)
1793 {
1794   char **new = xnew_array (char *, argc);
1795   /* For each element of argv,
1796      the corresponding element of options is:
1797      0 for an option that takes no arguments,
1798      1 for an option that takes one argument, etc.
1799      -1 for an ordinary non-option argument.  */
1800   int *options  = xnew_array (int, argc);
1801   int *priority = xnew_array (int, argc);
1802   int to = 1;
1803   int from;
1804   int i;
1805   int end_of_options_p = 0;
1806
1807   /* Categorize all the options,
1808      and figure out which argv elts are option arguments.  */
1809   for (from = 1; from < argc; from++)
1810     {
1811       options[from] = -1;
1812       priority[from] = 0;
1813       /* Pseudo options "--" and "run-temacs" indicate end of options */
1814       if (!strcmp (argv[from], "--") ||
1815           !strcmp (argv[from], "run-temacs"))
1816         end_of_options_p = 1;
1817       if (!end_of_options_p && argv[from][0] == '-')
1818         {
1819           int match, thislen;
1820           char *equals;
1821
1822           /* Look for a match with a known old-fashioned option.  */
1823           for (i = 0; i < countof (standard_args); i++)
1824             if (!strcmp (argv[from], standard_args[i].name))
1825               {
1826                 options[from]  = standard_args[i].nargs;
1827                 priority[from] = standard_args[i].priority;
1828                 if (from + standard_args[i].nargs >= argc)
1829                   fatal ("Option `%s' requires an argument\n", argv[from]);
1830                 from += standard_args[i].nargs;
1831                 goto done;
1832               }
1833
1834           /* Look for a match with a known long option.
1835              MATCH is -1 if no match so far, -2 if two or more matches so far,
1836              >= 0 (the table index of the match) if just one match so far.  */
1837           if (argv[from][1] == '-')
1838             {
1839               match = -1;
1840               thislen = strlen (argv[from]);
1841               equals = strchr (argv[from], '=');
1842               if (equals != 0)
1843                 thislen = equals - argv[from];
1844
1845               for (i = 0; i < countof (standard_args); i++)
1846                 if (standard_args[i].longname
1847                     && !strncmp (argv[from], standard_args[i].longname,
1848                                  thislen))
1849                   {
1850                     if (match == -1)
1851                       match = i;
1852                     else
1853                       match = -2;
1854                   }
1855
1856               /* If we found exactly one match, use that.  */
1857               if (match >= 0)
1858                 {
1859                   options[from]  = standard_args[match].nargs;
1860                   priority[from] = standard_args[match].priority;
1861                   /* If --OPTION=VALUE syntax is used,
1862                      this option uses just one argv element.  */
1863                   if (equals != 0)
1864                     options[from] = 0;
1865                   if (from + options[from] >= argc)
1866                     fatal ("Option `%s' requires an argument\n", argv[from]);
1867                   from += options[from];
1868                 }
1869             }
1870         done: ;
1871         }
1872     }
1873
1874   /* Copy the arguments, in order of decreasing priority, to NEW.  */
1875   new[0] = argv[0];
1876   while (to < argc)
1877     {
1878       int best = -1;
1879       int best_priority = -9999;
1880
1881       /* Find the highest priority remaining option.
1882          If several have equal priority, take the first of them.  */
1883       for (from = 1; from < argc; from++)
1884         {
1885           if (argv[from] != 0 && priority[from] > best_priority)
1886             {
1887               best_priority = priority[from];
1888               best = from;
1889             }
1890           /* Skip option arguments--they are tied to the options.  */
1891           if (options[from] > 0)
1892             from += options[from];
1893         }
1894
1895       if (best < 0)
1896         abort ();
1897
1898       /* Copy the highest priority remaining option, with its args, to NEW.  */
1899       new[to++] = argv[best];
1900       for (i = 0; i < options[best]; i++)
1901         new[to++] = argv[best + i + 1];
1902
1903       /* Clear out this option in ARGV.  */
1904       argv[best] = 0;
1905       for (i = 0; i < options[best]; i++)
1906         argv[best + i + 1] = 0;
1907     }
1908
1909   memcpy (argv, new, sizeof (char *) * argc);
1910 }
1911
1912 static JMP_BUF run_temacs_catch;
1913
1914 static int run_temacs_argc;
1915 static char **run_temacs_argv;
1916 static char *run_temacs_args;
1917 static size_t run_temacs_argv_size;
1918 static size_t run_temacs_args_size;
1919
1920 DEFUN ("running-temacs-p", Frunning_temacs_p, 0, 0, 0, /*
1921 True if running temacs.  This means we are in the dumping stage.
1922 This is false during normal execution of the `xemacs' program, and
1923 becomes false once `run-emacs-from-temacs' is run.
1924 */
1925        ())
1926 {
1927   return run_temacs_argc >= 0 ? Qt : Qnil;
1928 }
1929
1930 DEFUN ("run-emacs-from-temacs", Frun_emacs_from_temacs, 0, MANY, 0, /*
1931 Do not call this.  It will reinitialize your XEmacs.  You'll be sorry.
1932 */
1933 /* If this function is called from startup.el, it will be possible to run
1934    temacs as an editor using 'temacs -batch -l loadup.el run-temacs', instead
1935    of having to dump an emacs and then run that (when debugging emacs itself,
1936    this can be much faster)). [Actually, the speed difference isn't that
1937    much as long as your filesystem is local, and you don't end up with
1938    a dumped version in case you want to rerun it.  This function is most
1939    useful when used as part of the `make all-elc' command. --ben]
1940    This will "restart" emacs with the specified command-line arguments.
1941  */
1942      (int nargs, Lisp_Object *args))
1943 {
1944   int ac;
1945   CONST Extbyte *wampum;
1946   int namesize;
1947   int total_len;
1948   Lisp_Object orig_invoc_name = Fcar (Vcommand_line_args);
1949   CONST Extbyte **wampum_all = alloca_array (CONST Extbyte *, nargs);
1950   int *wampum_all_len  = alloca_array (int, nargs);
1951
1952   assert (!gc_in_progress);
1953
1954   if (run_temacs_argc < 0)
1955     error ("I've lost my temacs-hood.");
1956
1957   /* Need to convert the orig_invoc_name and all of the arguments
1958      to external format. */
1959
1960   GET_STRING_EXT_DATA_ALLOCA (orig_invoc_name, FORMAT_OS, wampum,
1961                               namesize);
1962   namesize++;
1963
1964   for (ac = 0, total_len = namesize; ac < nargs; ac++)
1965     {
1966       CHECK_STRING (args[ac]);
1967       GET_STRING_EXT_DATA_ALLOCA (args[ac], FORMAT_OS,
1968                                   wampum_all[ac],
1969                                   wampum_all_len[ac]);
1970       wampum_all_len[ac]++;
1971       total_len += wampum_all_len[ac];
1972     }
1973   DO_REALLOC (run_temacs_args, run_temacs_args_size, total_len, char);
1974   DO_REALLOC (run_temacs_argv, run_temacs_argv_size, nargs+1, char *);
1975
1976   memcpy (run_temacs_args, wampum, namesize);
1977   run_temacs_argv [0] = run_temacs_args;
1978   for (ac = 0; ac < nargs; ac++)
1979     {
1980       memcpy (run_temacs_args + namesize,
1981               wampum_all[ac], wampum_all_len[ac]);
1982       run_temacs_argv [ac + 1] = run_temacs_args + namesize;
1983       namesize += wampum_all_len[ac];
1984     }
1985   run_temacs_argv [nargs + 1] = 0;
1986   catchlist = NULL; /* Important!  Otherwise free_cons() calls in
1987                        condition_case_unwind() may lead to GC death. */
1988   unbind_to (0, Qnil); /* this closes loadup.el */
1989   purify_flag = 0;
1990   run_temacs_argc = nargs + 1;
1991 #ifdef REPORT_PURE_USAGE
1992   report_pure_usage (1, 0);
1993 #else
1994   report_pure_usage (0, 0);
1995 #endif
1996   LONGJMP (run_temacs_catch, 1);
1997   return Qnil; /* not reached; warning suppression */
1998 }
1999
2000 /* ARGSUSED */
2001 int
2002 main (int argc, char **argv, char **envp)
2003 {
2004   int     volatile vol_argc = argc;
2005   char ** volatile vol_argv = argv;
2006   char ** volatile vol_envp = envp;
2007   /* This is hairy.  We need to compute where the XEmacs binary was invoked */
2008   /* from because temacs initialization requires it to find the lisp */
2009   /* directories.  The code that recomputes the path is guarded by the */
2010   /* restarted flag.  There are three possible paths I've found so far */
2011   /* through this: */
2012   /* temacs -- When running temacs for basic build stuff, the first main_1 */
2013   /*  will be the only one invoked.  It must compute the path else there */
2014   /*  will be a very ugly bomb in startup.el (can't find obvious location */
2015   /*  for doc-directory data-directory, etc.).  */
2016   /* temacs w/ run-temacs on the command line -- This is run to bytecompile */
2017   /*  all the out of date dumped lisp.  It will execute both of the main_1 */
2018   /*  calls and the second one must not touch the first computation because */
2019   /*  argc/argv are hosed the second time through. */
2020   /* xemacs -- Only the second main_1 is executed.  The invocation path must */
2021   /*  computed but this only matters when running in place or when running */
2022   /*  as a login shell. */
2023   /* As a bonus for straightening this out, XEmacs can now be run in place */
2024   /*  as a login shell.  This never used to work. */
2025   /* As another bonus, we can now guarantee that */
2026   /* (concat invocation-directory invocation-name) contains the filename */
2027   /* of the XEmacs binary we are running.  This can now be used in a */
2028   /* definite test for out of date dumped files.  -slb */
2029   int restarted = 0;
2030 #ifdef QUANTIFY
2031   quantify_stop_recording_data ();
2032   quantify_clear_data ();
2033 #endif /* QUANTIFY */
2034
2035   suppress_early_error_handler_backtrace = 0;
2036   lim_data = 0; /* force reinitialization of this variable */
2037
2038   /* Lisp_Object must fit in a word; check VALBITS and GCTYPEBITS */
2039   assert (sizeof (Lisp_Object) == sizeof (void *));
2040
2041 #ifdef LINUX_SBRK_BUG
2042   sbrk (1);
2043 #endif
2044
2045   if (!initialized)
2046     {
2047 #ifdef DOUG_LEA_MALLOC
2048       mallopt (M_MMAP_MAX, 0);
2049 #endif
2050       run_temacs_argc = 0;
2051       if (! SETJMP (run_temacs_catch))
2052         {
2053           main_1 (vol_argc, vol_argv, vol_envp, 0);
2054         }
2055       /* run-emacs-from-temacs called */
2056       restarted = 1;
2057       vol_argc = run_temacs_argc;
2058       vol_argv = run_temacs_argv;
2059 #ifdef _SCO_DS
2060       /* This makes absolutely no sense to anyone involved.  There are
2061          several people using this stuff.  We've compared versions on
2062          everything we can think of.  We can find no difference.
2063          However, on both my systems environ is a plain old global
2064          variable initialized to zero.  _environ is the one that
2065          contains pointers to the actual environment.
2066
2067          Since we can't figure out the difference (and we're hours
2068          away from a release), this takes a very cowardly approach and
2069          is bracketed with both a system specific preprocessor test
2070          and a runtime "do you have this problem" test
2071
2072          06/20/96 robertl@dgii.com */
2073       {
2074         extern char *_environ;
2075         if ((unsigned) environ == 0)
2076           environ=_environ;
2077       }
2078 #endif /* _SCO_DS */
2079       vol_envp = environ;
2080     }
2081 #ifdef RUN_TIME_REMAP
2082   else
2083     /* obviously no-one uses this because where it was before initalized was
2084      *always* true */
2085     run_time_remap (argv[0]);
2086 #endif
2087
2088 #ifdef DOUG_LEA_MALLOC
2089   if (initialized && (malloc_state_ptr != NULL))
2090     {
2091       int rc = malloc_set_state (malloc_state_ptr);
2092       if (rc != 0)
2093         {
2094           fprintf (stderr, "malloc_set_state failed, rc = %d\n", rc);
2095           abort ();
2096         }
2097 #if 0
2098       free (malloc_state_ptr);
2099 #endif
2100       /* mmap works in glibc-2.1, glibc-2.0 (Non-Mule only) and Linux libc5 */
2101 #if (defined(__GLIBC__) && __GLIBC_MINOR__ >= 1) || \
2102     defined(_NO_MALLOC_WARNING_) || \
2103     (defined(__GLIBC__) && __GLIBC_MINOR__ < 1 && !defined(MULE)) || \
2104     defined(DEBUG_DOUG_LEA_MALLOC)
2105       mallopt (M_MMAP_MAX, 64);
2106 #endif
2107 #ifdef REL_ALLOC
2108       r_alloc_reinit ();
2109 #endif
2110     }
2111 #endif /* DOUG_LEA_MALLOC */
2112
2113   run_temacs_argc = -1;
2114
2115   main_1 (vol_argc, vol_argv, vol_envp, restarted);
2116   return 0; /* unreached */
2117 }
2118
2119 \f
2120 /* Dumping apparently isn't supported by versions of GCC >= 2.8. */
2121 /* The following needs conditionalization on whether either XEmacs or */
2122 /* various system shared libraries have been built and linked with */
2123 /* GCC >= 2.8.  -slb */
2124 #if defined(GNU_MALLOC)
2125 static void
2126 voodoo_free_hook(void *mem)
2127 {
2128   /* Disable all calls to free() when XEmacs is exiting and it doesn't */
2129   /* matter. */
2130   __free_hook = voodoo_free_hook;
2131 }
2132 #endif
2133
2134 DEFUN ("kill-emacs", Fkill_emacs, 0, 1, "P", /*
2135 Exit the XEmacs job and kill it.  Ask for confirmation, without argument.
2136 If ARG is an integer, return ARG as the exit program code.
2137 If ARG is a string, stuff it as keyboard input.
2138
2139 The value of `kill-emacs-hook', if not void,
2140 is a list of functions (of no args),
2141 all of which are called before XEmacs is actually killed.
2142 */
2143        (arg))
2144 {
2145   /* This function can GC */
2146   struct gcpro gcpro1;
2147
2148   GCPRO1 (arg);
2149
2150   if (feof (stdin))
2151     arg = Qt;
2152
2153   if (!preparing_for_armageddon && !noninteractive)
2154     run_hook (Qkill_emacs_hook);
2155
2156   /* make sure no quitting from now on!! */
2157   dont_check_for_quit = 1;
2158   Vinhibit_quit = Qt;
2159
2160   if (!preparing_for_armageddon)
2161     {
2162       Lisp_Object concons, nextcons;
2163
2164       /* Normally, go ahead and delete all the consoles now.
2165          Some unmentionably lame window systems (MS Wwwww...... eek,
2166          I can't even say it) don't properly clean up after themselves,
2167          and even for those that do, it might be cleaner this way.
2168          If we're going down, however, we don't do this (might
2169          be too dangerous), and if we get a crash somewhere within
2170          this loop, we'll still autosave and won't try this again. */
2171
2172       LIST_LOOP_DELETING(concons, nextcons, Vconsole_list)
2173         {
2174           /* There is very little point in deleting the stream console.
2175              It uses stdio, which should flush any buffered output and
2176              something can only go wrong. -slb */
2177           /* I changed my mind.  There's a stupid hack in close to add
2178              a trailing newline. */
2179           /*if (!CONSOLE_STREAM_P (XCONSOLE (XCAR (concons))))*/
2180             delete_console_internal (XCONSOLE (XCAR (concons)), 1, 1, 0);
2181         }
2182     }
2183
2184   UNGCPRO;
2185
2186   shut_down_emacs (0, ((STRINGP (arg)) ? arg : Qnil));
2187
2188 #if defined(GNU_MALLOC)
2189   __free_hook = voodoo_free_hook;
2190 #endif
2191
2192   exit ((INTP (arg)) ? XINT (arg) : 0);
2193   /* NOTREACHED */
2194   return Qnil; /* I'm sick of the compiler warning */
2195 }
2196
2197 /* Perform an orderly shutdown of XEmacs.  Autosave any modified
2198    buffers, kill any child processes, clean up the terminal modes (if
2199    we're in the foreground), and other stuff like that.  Don't perform
2200    any redisplay; this may be called when XEmacs is shutting down in
2201    the background, or after its X connection has died.
2202
2203    If SIG is a signal number, print a message for it.
2204
2205    This is called by fatal signal handlers, X protocol error handlers,
2206    and Fkill_emacs.  */
2207 static void
2208 shut_down_emacs (int sig, Lisp_Object stuff)
2209 {
2210   /* This function can GC */
2211   /* Prevent running of hooks and other non-essential stuff
2212      from now on.  */
2213   preparing_for_armageddon = 1;
2214
2215   /* In case frames or windows are screwed up, avoid assertion
2216      failures here */
2217   Vinhibit_quit = Qt;
2218
2219 #ifdef QUANTIFY
2220   quantify_stop_recording_data ();
2221 #endif /* QUANTIFY */
2222
2223 #if 0
2224   /* This is absolutely the most important thing to do, so make sure
2225      we do it now, before anything else.  We might have crashed and
2226      be in a weird inconsistent state, and potentially anything could
2227      set off another protection fault and cause us to bail out
2228      immediately. */
2229   /* I'm not removing the code entirely, yet.  We have run up against
2230      a spate of problems in diagnosing crashes due to crashes within
2231      crashes.  It has very definitely been determined that code called
2232      during auto-saving cannot work if XEmacs crashed inside of GC.
2233      We already auto-save on an itimer so there cannot be too much
2234      unsaved stuff around, and if we get better crash reports we might
2235      be able to get more problems fixed so I'm disabling this.  -slb */
2236   Fdo_auto_save (Qt, Qnil); /* do this before anything hazardous */
2237 #endif
2238
2239   fflush (stdout);
2240   reset_all_consoles ();
2241   if (sig && sig != SIGTERM)
2242     {
2243       stderr_out ("\nFatal error (%d).\n", sig);
2244       stderr_out
2245         ("Your files have been auto-saved.\n"
2246          "Use `M-x recover-session' to recover them.\n"
2247          "\n"
2248 #ifdef INFODOCK
2249          "Please report this bug by selecting `Report-Bug' in the InfoDock\n"
2250          "menu.\n"
2251 #else
2252          "Please report this bug by running the send-pr script included\n"
2253          "with XEmacs, or selecting `Send Bug Report' from the help menu.\n"
2254          "As a last resort send ordinary email to `crashes@xemacs.org'.\n"
2255 #endif
2256          "*MAKE SURE* to include the information in the command\n"
2257          "M-x describe-installation.\n"
2258          "\n"
2259          "If at all possible, *please* try to obtain a C stack backtrace;\n"
2260          "it will help us immensely in determining what went wrong.\n"
2261          "To do this, locate the core file that was produced as a result\n"
2262          "of this crash (it's usually called `core' and is located in the\n"
2263          "directory in which you started the editor, or maybe in your home\n"
2264          "directory), and type\n"
2265          "\n"
2266          "  gdb ");
2267       {
2268         CONST char *name;
2269         char *dir = 0;
2270
2271         /* Now try to determine the actual path to the executable,
2272            to try to make the backtrace-determination process as foolproof
2273            as possible. */
2274         if (GC_STRINGP (Vinvocation_name))
2275           name = (char *) XSTRING_DATA (Vinvocation_name);
2276         else
2277           name = "xemacs";
2278         if (GC_STRINGP (Vinvocation_directory))
2279           dir = (char *) XSTRING_DATA (Vinvocation_directory);
2280         if (!dir || dir[0] != '/')
2281           stderr_out ("`which %s`", name);
2282         else if (dir[strlen (dir) - 1] != '/')
2283           stderr_out ("%s/%s", dir, name);
2284         else
2285           stderr_out ("%s%s", dir, name);
2286       }
2287       stderr_out
2288         (" core\n\n"
2289          "then type `where' when the debugger prompt comes up.\n"
2290          "(If you don't have GDB on your system, you might have DBX,\n"
2291          "or XDB, or SDB.  A similar procedure should work for all of\n"
2292          "these.  Ask your system administrator if you need more help.)\n");
2293     }
2294
2295   stuff_buffered_input (stuff);
2296
2297   kill_buffer_processes (Qnil);
2298
2299 #ifdef CLASH_DETECTION
2300   unlock_all_files ();
2301 #endif
2302
2303 #ifdef TOOLTALK
2304   tt_session_quit (tt_default_session ());
2305 #if 0
2306   /* The following crashes when built on X11R5 and run on X11R6 */
2307   tt_close ();
2308 #endif
2309 #endif /* TOOLTALK */
2310
2311 }
2312
2313 \f
2314 #ifndef CANNOT_DUMP
2315 /* Nothing like this can be implemented on an Apollo.
2316    What a loss!  */
2317
2318 extern char my_edata[];
2319
2320 #ifdef HAVE_SHM
2321
2322 DEFUN ("dump-emacs-data", Fdump_emacs_data, 1, 1, 0, /*
2323 Dump current state of XEmacs into data file FILENAME.
2324 This function exists on systems that use HAVE_SHM.
2325 */
2326        (intoname))
2327 {
2328   /* This function can GC */
2329   int opurify;
2330   struct gcpro gcpro1;
2331   GCPRO1 (intoname);
2332
2333   CHECK_STRING (intoname);
2334   intoname = Fexpand_file_name (intoname, Qnil);
2335
2336   opurify = purify_flag;
2337   purify_flag = 0;
2338
2339   fflush (stderr);
2340   fflush (stdout);
2341
2342   disksave_object_finalization ();
2343   release_breathing_space ();
2344
2345   /* Tell malloc where start of impure now is */
2346   /* Also arrange for warnings when nearly out of space.  */
2347 #ifndef SYSTEM_MALLOC
2348   memory_warnings (my_edata, malloc_warning);
2349 #endif
2350   UNGCPRO;
2351   map_out_data (XSTRING_DATA (intoname));
2352
2353   purify_flag = opurify;
2354
2355   return Qnil;
2356 }
2357
2358 #else /* not HAVE_SHM */
2359 extern void disable_free_hook (void);
2360
2361 DEFUN ("dump-emacs", Fdump_emacs, 2, 2, 0, /*
2362 Dump current state of XEmacs into executable file FILENAME.
2363 Take symbols from SYMFILE (presumably the file you executed to run XEmacs).
2364 This is used in the file `loadup.el' when building XEmacs.
2365
2366 Remember to set `command-line-processed' to nil before dumping
2367 if you want the dumped XEmacs to process its command line
2368 and announce itself normally when it is run.
2369 */
2370        (intoname, symname))
2371 {
2372   /* This function can GC */
2373   struct gcpro gcpro1, gcpro2;
2374   int opurify;
2375
2376   GCPRO2 (intoname, symname);
2377
2378 #ifdef FREE_CHECKING
2379   Freally_free (Qnil);
2380
2381   /* When we're dumping, we can't use the debugging free() */
2382   disable_free_hook ();
2383 #endif
2384 #if 1 /* martin */
2385 #endif
2386
2387   CHECK_STRING (intoname);
2388   intoname = Fexpand_file_name (intoname, Qnil);
2389   if (!NILP (symname))
2390     {
2391       CHECK_STRING (symname);
2392       if (XSTRING_LENGTH (symname) > 0)
2393         symname = Fexpand_file_name (symname, Qnil);
2394       else
2395         symname = Qnil;
2396     }
2397
2398   opurify = purify_flag;
2399   purify_flag = 0;
2400
2401 #ifdef DEBUG_XEMACS
2402   report_pure_usage (1, 1);
2403 #else
2404   report_pure_usage (0, 1);
2405 #endif
2406
2407   fflush (stderr);
2408   fflush (stdout);
2409
2410   disksave_object_finalization ();
2411   release_breathing_space ();
2412
2413   /* Tell malloc where start of impure now is */
2414   /* Also arrange for warnings when nearly out of space.  */
2415 #ifndef SYSTEM_MALLOC
2416   memory_warnings (my_edata, malloc_warning);
2417 #endif
2418
2419   UNGCPRO;
2420
2421 #if defined (MSDOS) && defined (EMX)
2422   {
2423     int fd = open ((char *) XSTRING_DATA (intoname),
2424                    O_WRONLY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE);
2425     if (!fd) {
2426       error ("Failure operating on %s", XSTRING_DATA (intoname));
2427     } else {
2428       _core (fd);
2429       close (fd);
2430     }
2431   }
2432 #else /* not MSDOS and EMX */
2433   {
2434     char *intoname_ext;
2435     char *symname_ext;
2436
2437     GET_C_STRING_FILENAME_DATA_ALLOCA (intoname, intoname_ext);
2438     if (STRINGP (symname))
2439       GET_C_STRING_FILENAME_DATA_ALLOCA (symname, symname_ext);
2440     else
2441       symname_ext = 0;
2442
2443     garbage_collect_1 ();
2444 #ifdef DOUG_LEA_MALLOC
2445     malloc_state_ptr = malloc_get_state ();
2446 #endif
2447   /* here we break our rule that the filename conversion should
2448      be performed at the actual time that the system call is made.
2449      It's a whole lot easier to do the conversion here than to
2450      modify all the unexec routines to ensure that filename
2451      conversion is applied everywhere.  Don't worry about memory
2452      leakage because this call only happens once. */ 
2453  unexec (intoname_ext, symname_ext, (uintptr_t) my_edata, 0, 0);
2454 #ifdef DOUG_LEA_MALLOC
2455   free (malloc_state_ptr);
2456 #endif
2457   }
2458 #endif /* not MSDOS and EMX */
2459
2460   purify_flag = opurify;
2461
2462   return Qnil;
2463 }
2464
2465 #endif /* not HAVE_SHM */
2466
2467 #endif /* not CANNOT_DUMP */
2468 \f
2469 #ifndef SEPCHAR
2470 #define SEPCHAR ':'
2471 #endif
2472
2473 /* Split STRING into a list of substrings.  The substrings are the
2474    parts of original STRING separated by SEPCHAR.  */
2475 static Lisp_Object
2476 split_string_by_emchar_1 (CONST Bufbyte *string, Bytecount size,
2477                           Emchar sepchar)
2478 {
2479   Lisp_Object result = Qnil;
2480   CONST Bufbyte *end = string + size;
2481
2482   while (1)
2483     {
2484       CONST Bufbyte *p = string;
2485       while (p < end)
2486         {
2487           if (charptr_emchar (p) == sepchar)
2488             break;
2489           INC_CHARPTR (p);
2490         }
2491       result = Fcons (make_string (string, p - string), result);
2492       if (p < end)
2493         {
2494           string = p;
2495           INC_CHARPTR (string); /* skip sepchar */
2496         }
2497       else
2498         break;
2499     }
2500   return Fnreverse (result);
2501 }
2502
2503 /* The same as the above, except PATH is an external C string (it is
2504    converted as FORMAT_FILENAME), and sepchar is hardcoded to SEPCHAR
2505    (':' or whatever).  */
2506 Lisp_Object
2507 decode_path (CONST char *path)
2508 {
2509   int len;
2510   Bufbyte *newpath;
2511   if (!path)
2512     return Qnil;
2513
2514   GET_C_CHARPTR_INT_FILENAME_DATA_ALLOCA (path, newpath);
2515
2516   len = strlen (newpath);
2517   /* #### Does this make sense?  It certainly does for
2518      decode_env_path(), but it looks dubious here.  Does any code
2519      depend on decode_path("") returning nil instead of an empty
2520      string?  */
2521   if (!len)
2522     return Qnil;
2523
2524   return split_string_by_emchar_1 (newpath, (Bytecount)len, SEPCHAR);
2525 }
2526
2527 Lisp_Object
2528 decode_env_path (CONST char *evarname, CONST char *default_)
2529 {
2530   CONST char *path = 0;
2531   if (evarname)
2532     path = egetenv (evarname);
2533   if (!path)
2534     path = default_;
2535   return decode_path (path);
2536 }
2537
2538 /* Ben thinks this function should not exist or be exported to Lisp.
2539    We use it to define split-path-string in subr.el (not!).  */
2540
2541 DEFUN ("split-string-by-char", Fsplit_string_by_char, 1, 2, 0, /*
2542 Split STRING into a list of substrings originally separated by SEPCHAR.
2543 */
2544        (string, sepchar))
2545 {
2546   CHECK_STRING (string);
2547   CHECK_CHAR (sepchar);
2548   return split_string_by_emchar_1 (XSTRING_DATA (string),
2549                                    XSTRING_LENGTH (string),
2550                                    XCHAR (sepchar));
2551 }
2552
2553 /* #### This was supposed to be in subr.el, but is used VERY early in
2554    the bootstrap process, so it goes here.  Damn.  */
2555
2556 DEFUN ("split-path", Fsplit_path, 1, 1, 0, /*
2557 Explode a search path into a list of strings.
2558 The path components are separated with the characters specified
2559 with `path-separator'.
2560 */
2561        (path))
2562 {
2563   CHECK_STRING (path);
2564
2565   while (!STRINGP (Vpath_separator)
2566          || (XSTRING_CHAR_LENGTH (Vpath_separator) != 1))
2567     Vpath_separator = signal_simple_continuable_error
2568       ("`path-separator' should be set to a single-character string",
2569        Vpath_separator);
2570
2571   return (split_string_by_emchar_1
2572           (XSTRING_DATA (path), XSTRING_LENGTH (path),
2573            charptr_emchar (XSTRING_DATA (Vpath_separator))));
2574 }
2575 \f
2576 DEFUN ("noninteractive", Fnoninteractive, 0, 0, 0, /*
2577 Non-nil return value means XEmacs is running without interactive terminal.
2578 */
2579        ())
2580 {
2581   return noninteractive ? Qt : Qnil;
2582 }
2583
2584 /* This flag is useful to define if you're under a debugger; this way, you
2585    can put a breakpoint of assert_failed() and debug multiple problems
2586    in one session without having to recompile. */
2587 /* #define ASSERTIONS_DONT_ABORT */
2588
2589 #ifdef USE_ASSERTIONS
2590 /* This highly dubious kludge ... shut up Jamie, I'm tired of your slagging. */
2591
2592 DOESNT_RETURN
2593 assert_failed (CONST char *file, int line, CONST char *expr)
2594 {
2595   stderr_out ("Fatal error: assertion failed, file %s, line %d, %s\n",
2596               file, line, expr);
2597 #undef abort    /* avoid infinite #define loop... */
2598 #if defined (WINDOWSNT) && defined (DEBUG_XEMACS)
2599   DebugBreak ();
2600 #elif !defined (ASSERTIONS_DONT_ABORT)
2601   abort ();
2602 #endif
2603 }
2604 #endif /* USE_ASSERTIONS */
2605
2606 #ifdef QUANTIFY
2607 DEFUN ("quantify-start-recording-data", Fquantify_start_recording_data,
2608        0, 0, 0, /*
2609 Start recording Quantify data.
2610 */
2611        ())
2612 {
2613   quantify_start_recording_data ();
2614   return Qnil;
2615 }
2616
2617 DEFUN ("quantify-stop-recording-data", Fquantify_stop_recording_data,
2618        0, 0, 0, /*
2619 Stop recording Quantify data.
2620 */
2621        ())
2622 {
2623   quantify_stop_recording_data ();
2624   return Qnil;
2625 }
2626
2627 DEFUN ("quantify-clear-data", Fquantify_clear_data, 0, 0, 0, /*
2628 Clear all Quantify data.
2629 */
2630        ())
2631 {
2632   quantify_clear_data ();
2633   return Qnil;
2634 }
2635 #endif /* QUANTIFY */
2636
2637 void
2638 syms_of_emacs (void)
2639 {
2640 #ifndef CANNOT_DUMP
2641 #ifdef HAVE_SHM
2642   DEFSUBR (Fdump_emacs_data);
2643 #else
2644   DEFSUBR (Fdump_emacs);
2645 #endif
2646 #endif /* !CANNOT_DUMP */
2647
2648   DEFSUBR (Frun_emacs_from_temacs);
2649   DEFSUBR (Frunning_temacs_p);
2650   DEFSUBR (Finvocation_name);
2651   DEFSUBR (Finvocation_directory);
2652   DEFSUBR (Fkill_emacs);
2653   DEFSUBR (Fnoninteractive);
2654
2655 #ifdef QUANTIFY
2656   DEFSUBR (Fquantify_start_recording_data);
2657   DEFSUBR (Fquantify_stop_recording_data);
2658   DEFSUBR (Fquantify_clear_data);
2659 #endif /* QUANTIFY */
2660
2661   DEFSUBR (Fsplit_string_by_char);
2662   DEFSUBR (Fsplit_path);        /* #### */
2663
2664   defsymbol (&Qkill_emacs_hook, "kill-emacs-hook");
2665   defsymbol (&Qsave_buffers_kill_emacs, "save-buffers-kill-emacs");
2666 }
2667
2668 void
2669 vars_of_emacs (void)
2670 {
2671   DEFVAR_BOOL ("suppress-early-error-handler-backtrace",
2672                &suppress_early_error_handler_backtrace /*
2673 Non-nil means early error handler shouldn't print a backtrace.
2674 */ );
2675
2676   DEFVAR_LISP ("command-line-args", &Vcommand_line_args /*
2677 Args passed by shell to XEmacs, as a list of strings.
2678 */ );
2679
2680   DEFVAR_LISP ("invocation-name", &Vinvocation_name /*
2681 The program name that was used to run XEmacs.
2682 Any directory names are omitted.
2683 */ );
2684
2685   DEFVAR_LISP ("invocation-directory", &Vinvocation_directory /*
2686 The directory in which the XEmacs executable was found, to run it.
2687 The value is simply the program name if that directory's name is not known.
2688 */ );
2689
2690   DEFVAR_LISP ("invocation-path", &Vinvocation_path /*
2691 The path in which the XEmacs executable was found, to run it.
2692 The value is simply the value of environment variable PATH on startup
2693 if XEmacs was found there.
2694 */ );
2695
2696 #if 0 /* FSFmacs */
2697   xxDEFVAR_LISP ("installation-directory", &Vinstallation_directory,
2698     "A directory within which to look for the `lib-src' and `etc' directories.\n"
2699 "This is non-nil when we can't find those directories in their standard\n"
2700 "installed locations, but we can find them\n"
2701 "near where the XEmacs executable was found.");
2702 #endif
2703
2704   DEFVAR_LISP ("system-type", &Vsystem_type /*
2705 Symbol indicating type of operating system you are using.
2706 */ );
2707   Vsystem_type = intern (SYSTEM_TYPE);
2708   Fprovide (intern(SYSTEM_TYPE));
2709
2710 #ifndef EMACS_CONFIGURATION
2711 # define EMACS_CONFIGURATION "UNKNOWN"
2712 #endif
2713   DEFVAR_LISP ("system-configuration", &Vsystem_configuration /*
2714 String naming the configuration XEmacs was built for.
2715 */ );
2716   Vsystem_configuration = Fpurecopy (build_string (EMACS_CONFIGURATION));
2717
2718 #ifndef EMACS_CONFIG_OPTIONS
2719 # define EMACS_CONFIG_OPTIONS "UNKNOWN"
2720 #endif
2721   DEFVAR_LISP ("system-configuration-options", &Vsystem_configuration_options /*
2722 String containing the configuration options XEmacs was built with.
2723 */ );
2724   Vsystem_configuration_options = Fpurecopy (build_string
2725                                              (EMACS_CONFIG_OPTIONS));
2726
2727   DEFVAR_LISP ("emacs-major-version", &Vemacs_major_version /*
2728 Major version number of this version of Emacs, as an integer.
2729 Warning: this variable did not exist in Emacs versions earlier than:
2730   FSF Emacs:   19.23
2731   XEmacs:      19.10
2732 */ );
2733   Vemacs_major_version = make_int (EMACS_MAJOR_VERSION);
2734
2735   DEFVAR_LISP ("emacs-minor-version", &Vemacs_minor_version /*
2736 Minor version number of this version of Emacs, as an integer.
2737 Warning: this variable did not exist in Emacs versions earlier than:
2738   FSF Emacs:   19.23
2739   XEmacs:      19.10
2740 */ );
2741   Vemacs_minor_version = make_int (EMACS_MINOR_VERSION);
2742
2743   DEFVAR_LISP ("emacs-beta-version", &Vemacs_beta_version /*
2744 Beta number of this version of Emacs, as an integer.
2745 The value is nil if this is an officially released version of XEmacs.
2746 Warning: this variable does not exist in FSF Emacs or in XEmacs versions
2747 earlier than 20.3.
2748 */ );
2749 #ifdef EMACS_BETA_VERSION
2750   Vemacs_beta_version = make_int (EMACS_BETA_VERSION);
2751 #else
2752   Vemacs_beta_version = Qnil;
2753 #endif
2754
2755 #ifdef INFODOCK
2756   DEFVAR_LISP ("infodock-major-version", &Vinfodock_major_version /*
2757 Major version number of this InfoDock release.
2758 */ );
2759   Vinfodock_major_version = make_int (INFODOCK_MAJOR_VERSION);
2760
2761   DEFVAR_LISP ("infodock-minor-version", &Vinfodock_minor_version /*
2762 Minor version number of this InfoDock release.
2763 */ );
2764   Vinfodock_minor_version = make_int (INFODOCK_MINOR_VERSION);
2765
2766   DEFVAR_LISP ("infodock-build-version", &Vinfodock_build_version /*
2767 Build version of this InfoDock release.
2768 */ );
2769   Vinfodock_build_version = make_int (INFODOCK_BUILD_VERSION);
2770 #endif
2771
2772   DEFVAR_LISP ("xemacs-codename", &Vxemacs_codename /*
2773 Codename of this version of Emacs (a string).
2774 */ );
2775 #ifndef XEMACS_CODENAME
2776 #define XEMACS_CODENAME "Noname"
2777 #endif
2778   Vxemacs_codename = Fpurecopy (build_string (XEMACS_CODENAME));
2779
2780   DEFVAR_BOOL ("noninteractive", &noninteractive1 /*
2781 Non-nil means XEmacs is running without interactive terminal.
2782 */ );
2783
2784   DEFVAR_BOOL ("inhibit-early-packages", &inhibit_early_packages /*
2785 Set to non-nil when the early packages should not be respected at startup.
2786 */ );
2787
2788   DEFVAR_BOOL ("inhibit-autoloads", &inhibit_autoloads /*
2789 Set to non-nil when autoloads should not be loaded at startup.
2790 */ );
2791
2792   DEFVAR_BOOL ("debug-paths", &debug_paths /*
2793 Set to non-nil when debug information about paths should be printed.
2794 */ );
2795
2796   DEFVAR_BOOL ("inhibit-site-lisp", &inhibit_site_lisp /*
2797 Set to non-nil when the site-lisp should not be searched at startup.
2798 */ );
2799 #ifdef INHIBIT_SITE_LISP
2800   inhibit_site_lisp = 1;
2801 #endif
2802
2803   DEFVAR_INT ("emacs-priority", &emacs_priority /*
2804 Priority for XEmacs to run at.
2805 This value is effective only if set before XEmacs is dumped,
2806 and only if the XEmacs executable is installed with setuid to permit
2807 it to change priority.  (XEmacs sets its uid back to the real uid.)
2808 Currently, you need to define SET_EMACS_PRIORITY in `config.h'
2809 before you compile XEmacs, to enable the code for this feature.
2810 */ );
2811   emacs_priority = 0;
2812
2813   DEFVAR_CONST_LISP ("internal-error-checking", &Vinternal_error_checking /*
2814 Internal error checking built-in into this instance of XEmacs.
2815 This is a list of symbols, initialized at build-time.  Legal symbols
2816 are:
2817
2818 extents         - check extents prior to each extent change;
2819 typecheck       - check types strictly, aborting in case of error;
2820 malloc          - check operation of malloc;
2821 gc              - check garbage collection;
2822 bufpos          - check buffer positions.
2823 */ );
2824   Vinternal_error_checking = Qnil;
2825 #ifdef ERROR_CHECK_EXTENTS
2826   Vinternal_error_checking = Fcons (intern ("extents"),
2827                                     Vinternal_error_checking);
2828 #endif
2829 #ifdef ERROR_CHECK_TYPECHECK
2830   Vinternal_error_checking = Fcons (intern ("typecheck"),
2831                                     Vinternal_error_checking);
2832 #endif
2833 #ifdef ERROR_CHECK_MALLOC
2834   Vinternal_error_checking = Fcons (intern ("malloc"),
2835                                     Vinternal_error_checking);
2836 #endif
2837 #ifdef ERROR_CHECK_GC
2838   Vinternal_error_checking = Fcons (intern ("gc"),
2839                                     Vinternal_error_checking);
2840 #endif
2841 #ifdef ERROR_CHECK_BUFPOS
2842   Vinternal_error_checking = Fcons (intern ("bufpos"),
2843                                     Vinternal_error_checking);
2844 #endif
2845   Vinternal_error_checking = Fpurecopy (Vinternal_error_checking);
2846
2847   DEFVAR_LISP ("path-separator", &Vpath_separator /*
2848 The directory separator in search paths, as a string.
2849 */ );
2850   {
2851     char c = SEPCHAR;
2852     Vpath_separator = make_string ((Bufbyte *)&c, 1);
2853   }
2854 }
2855
2856 void
2857 complex_vars_of_emacs (void)
2858 {
2859   /* This is all related to path searching. */
2860   
2861   DEFVAR_LISP ("emacs-program-name", &Vemacs_program_name /*
2862 *Name of the Emacs variant.
2863 For example, this may be \"xemacs\" or \"infodock\".
2864 This is mainly meant for use in path searching.
2865 */ );
2866   Vemacs_program_name = build_string ((char *) PATH_PROGNAME);
2867
2868   DEFVAR_LISP ("emacs-program-version", &Vemacs_program_version /*
2869 *Version of the Emacs variant.
2870 This typically has the form XX.XX[-bXX].
2871 This is mainly meant for use in path searching.
2872 */ );
2873   Vemacs_program_version = build_string ((char *) PATH_VERSION);
2874
2875   DEFVAR_LISP ("exec-path", &Vexec_path /*
2876 *List of directories to search programs to run in subprocesses.
2877 Each element is a string (directory name) or nil (try default directory).
2878 */ );
2879   Vexec_path = Qnil;
2880
2881   DEFVAR_LISP ("exec-directory", &Vexec_directory /*
2882 *Directory of architecture-dependent files that come with XEmacs,
2883 especially executable programs intended for XEmacs to invoke.
2884 */ );
2885   Vexec_directory = Qnil;
2886
2887   DEFVAR_LISP ("configure-exec-directory", &Vconfigure_exec_directory /*
2888 For internal use by the build procedure only.
2889 configure's idea of what EXEC-DIRECTORY will be.
2890 */ );
2891 #ifdef PATH_EXEC
2892   Vconfigure_exec_directory = Ffile_name_as_directory
2893     (build_string ((char *) PATH_EXEC));
2894 #else
2895   Vconfigure_exec_directory = Qnil;
2896 #endif
2897
2898   DEFVAR_LISP ("lisp-directory", &Vlisp_directory /*
2899 *Directory of core Lisp files that come with XEmacs.
2900 */ );
2901   Vlisp_directory = Qnil;
2902
2903   DEFVAR_LISP ("configure-lisp-directory", &Vconfigure_lisp_directory /*
2904 For internal use by the build procedure only.
2905 configure's idea of what LISP-DIRECTORY will be.
2906 */ );
2907 #ifdef PATH_LOADSEARCH
2908   Vconfigure_lisp_directory = Ffile_name_as_directory
2909     (build_string ((char *) PATH_LOADSEARCH));
2910 #else
2911   Vconfigure_lisp_directory = Qnil;
2912 #endif
2913
2914   DEFVAR_LISP ("configure-package-path", &Vconfigure_package_path /*
2915 For internal use by the build procedure only.
2916 configure's idea of what the package path will be.
2917 */ );
2918 #ifdef PATH_PACKAGEPATH
2919   Vconfigure_package_path = decode_path (PATH_PACKAGEPATH);
2920 #else
2921   Vconfigure_package_path = Qnil;
2922 #endif
2923
2924   DEFVAR_LISP ("data-directory", &Vdata_directory /*
2925 *Directory of architecture-independent files that come with XEmacs,
2926 intended for XEmacs to use.
2927 Use of this variable in new code is almost never correct.  See the
2928 function `locate-data-directory' and the variable `data-directory-list'.
2929 */ );
2930   Vdata_directory = Qnil;
2931
2932   DEFVAR_LISP ("configure-data-directory", &Vconfigure_data_directory /*
2933 For internal use by the build procedure only.
2934 configure's idea of what DATA-DIRECTORY will be.
2935 */ );
2936 #ifdef PATH_DATA
2937   Vconfigure_data_directory = Ffile_name_as_directory
2938     (build_string ((char *) PATH_DATA));
2939 #else
2940   Vconfigure_data_directory = Qnil;
2941 #endif
2942
2943   DEFVAR_LISP ("data-directory-list", &Vdata_directory_list /*
2944 *List of directories of architecture-independent files that come with XEmacs
2945 or were installed as packages, and are intended for XEmacs to use.
2946 */ );
2947   Vdata_directory_list = Qnil;
2948
2949 #ifdef CLASH_DETECTION
2950   DEFVAR_LISP ("configure-lock-directory", &Vconfigure_lock_directory /*
2951 For internal use by the build procedure only.
2952 configure's idea of what LOCK-DIRECTORY will be.
2953 */ );
2954 #ifdef PATH_LOCK
2955   Vconfigure_lock_directory = Ffile_name_as_directory
2956     (build_string ((char *) PATH_LOCK));
2957 #else
2958   Vconfigure_lock_directory = Qnil;
2959 #endif
2960 #endif /* CLASH_DETECTION */
2961
2962   DEFVAR_LISP ("site-directory", &Vsite_directory /*
2963 *Directory of site-specific Lisp files that come with XEmacs.
2964 */ );
2965   Vsite_directory = Qnil;
2966
2967   DEFVAR_LISP ("configure-site-directory", &Vconfigure_site_directory /*
2968 For internal use by the build procedure only.
2969 configure's idea of what SITE-DIRECTORY will be.
2970 */ );
2971 #ifdef PATH_SITE
2972   Vconfigure_site_directory = Ffile_name_as_directory
2973     (build_string ((char *) PATH_SITE));
2974 #else
2975   Vconfigure_site_directory = Qnil;
2976 #endif
2977
2978   DEFVAR_LISP ("doc-directory", &Vdoc_directory /*
2979 *Directory containing the DOC file that comes with XEmacs.
2980 This is usually the same as exec-directory.
2981 */ );
2982   Vdoc_directory = Qnil;
2983
2984   DEFVAR_LISP ("configure-doc-directory", &Vconfigure_doc_directory /*
2985 For internal use by the build procedure only.
2986 configure's idea of what DOC-DIRECTORY will be.
2987 */ );
2988 #ifdef PATH_DOC
2989   Vconfigure_doc_directory = Ffile_name_as_directory
2990     (build_string ((char *) PATH_DOC));
2991 #else
2992   Vconfigure_doc_directory = Qnil;
2993 #endif
2994
2995   DEFVAR_LISP ("configure-exec-prefix-directory", &Vconfigure_exec_prefix_directory /*
2996 For internal use by the build procedure only.
2997 configure's idea of what EXEC-PREFIX-DIRECTORY will be.
2998 */ );
2999 #ifdef PATH_EXEC_PREFIX
3000   Vconfigure_exec_prefix_directory = Ffile_name_as_directory
3001     (build_string ((char *) PATH_EXEC_PREFIX));
3002 #else
3003   Vconfigure_exec_prefix_directory = Qnil;
3004 #endif
3005
3006   DEFVAR_LISP ("configure-prefix-directory", &Vconfigure_prefix_directory /*
3007 For internal use by the build procedure only.
3008 configure's idea of what PREFIX-DIRECTORY will be.
3009 */ );
3010 #ifdef PATH_PREFIX
3011   Vconfigure_prefix_directory = Ffile_name_as_directory
3012     (build_string ((char *) PATH_PREFIX));
3013 #else
3014   Vconfigure_prefix_directory = Qnil;
3015 #endif
3016
3017   DEFVAR_LISP ("configure-info-directory", &Vconfigure_info_directory /*
3018 For internal use by the build procedure only.
3019 This is the name of the directory in which the build procedure installed
3020 Emacs's info files; the default value for Info-default-directory-list
3021 includes this.
3022 */ );
3023 #ifdef PATH_INFO
3024   Vconfigure_info_directory =
3025     Ffile_name_as_directory (build_string (PATH_INFO));
3026 #else
3027   Vconfigure_info_directory = Qnil;
3028 #endif
3029
3030   DEFVAR_LISP ("configure-info-path", &Vconfigure_info_path /*
3031 The configured initial path for info documentation.
3032 */ );
3033 #ifdef PATH_INFOPATH
3034   Vconfigure_info_path = decode_path (PATH_INFOPATH);
3035 #else
3036   Vconfigure_info_path = Qnil;
3037 #endif
3038 }
3039
3040 #ifdef __sgi
3041 /* This is so tremendously ugly I'd puke. But then, it works.
3042  * The target is to override the static constructor from the
3043  * libiflPNG.so library which is maskerading as libz, and
3044  * cores on us when re-started from the dumped executable.
3045  * This will have to go for 21.1  -- OG.
3046  */
3047 void __sti__iflPNGFile_c___()
3048 {
3049 }
3050
3051 #endif