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