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