XEmacs 21.2.5
[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 #if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS)
924       syms_of_gui ();
925 #endif
926       syms_of_indent ();
927       syms_of_intl ();
928       syms_of_keymap ();
929       syms_of_lread ();
930       syms_of_macros ();
931       syms_of_marker ();
932       syms_of_md5 ();
933 #ifdef HAVE_DATABASE
934       syms_of_database ();
935 #endif
936 #ifdef HAVE_MENUBARS
937       syms_of_menubar ();
938 #endif
939       syms_of_minibuf ();
940       syms_of_objects ();
941       syms_of_print ();
942 #if !defined (NO_SUBPROCESSES)
943       syms_of_process ();
944 #ifdef HAVE_WIN32_PROCESSES
945       syms_of_process_nt ();
946 #endif
947 #endif
948       syms_of_profile ();
949 #if defined (HAVE_MMAP) && defined (REL_ALLOC) && !defined(DOUG_LEA_MALLOC)
950       syms_of_ralloc ();
951 #endif /* HAVE_MMAP && REL_ALLOC */
952       syms_of_rangetab ();
953       syms_of_redisplay ();
954       syms_of_search ();
955       syms_of_signal ();
956       syms_of_sound ();
957       syms_of_specifier ();
958       syms_of_symbols ();
959       syms_of_syntax ();
960 #ifdef HAVE_SCROLLBARS
961       syms_of_scrollbar ();
962 #endif
963 #ifdef HAVE_TOOLBARS
964       syms_of_toolbar ();
965 #endif
966       syms_of_undo ();
967       syms_of_widget ();
968       syms_of_window ();
969
970 #ifdef HAVE_TTY
971       syms_of_console_tty ();
972       syms_of_device_tty ();
973       syms_of_objects_tty ();
974 #endif
975
976 #ifdef HAVE_X_WINDOWS
977       syms_of_device_x ();
978 #ifdef HAVE_DIALOGS
979       syms_of_dialog_x ();
980 #endif
981       syms_of_frame_x ();
982       syms_of_glyphs_x ();
983       syms_of_objects_x ();
984 #ifdef HAVE_MENUBARS
985       syms_of_menubar_x ();
986 #endif
987       syms_of_xselect ();
988 #if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS)
989       syms_of_gui_x ();
990 #endif
991 #endif /* HAVE_X_WINDOWS */
992
993 #ifdef HAVE_MS_WINDOWS
994       syms_of_console_mswindows ();
995       syms_of_device_mswindows ();
996       syms_of_frame_mswindows ();
997       syms_of_objects_mswindows ();
998       syms_of_select_mswindows ();
999       syms_of_glyphs_mswindows ();
1000 #ifdef HAVE_MENUBARS
1001       syms_of_menubar_mswindows ();
1002 #endif
1003 #ifdef HAVE_SCROLLBARS
1004       syms_of_scrollbar_mswindows ();
1005 #endif
1006 #ifdef HAVE_MSW_C_DIRED
1007       syms_of_dired_mswindows ();
1008 #endif
1009 #endif  /* HAVE_MS_WINDOWS */
1010
1011 #ifdef MULE
1012       syms_of_mule ();
1013       syms_of_mule_ccl ();
1014       syms_of_mule_charset ();
1015 #endif
1016 #ifdef FILE_CODING
1017       syms_of_mule_coding ();
1018 #endif
1019 #ifdef MULE
1020 #ifdef HAVE_WNN
1021       syms_of_mule_wnn ();
1022 #endif
1023 #ifdef HAVE_CANNA
1024       syms_of_mule_canna ();
1025 #endif /* HAVE_CANNA */
1026 #endif /* MULE */
1027
1028 #ifdef SYMS_SYSTEM
1029       SYMS_SYSTEM;
1030 #endif
1031
1032 #ifdef SYMS_MACHINE
1033       SYMS_MACHINE;
1034 #endif
1035
1036       /*
1037 #if defined (GNU_MALLOC) && \
1038     defined (ERROR_CHECK_MALLOC) && \
1039     !defined (HAVE_LIBMCHECK)
1040       */
1041       /* Prior to XEmacs 21, this was `#if 0'ed out. -slb */
1042 #if defined (LOSING_GCC_DESTRUCTOR_FREE_BUG)
1043       syms_of_free_hook ();
1044 #endif
1045
1046 #ifdef TOOLTALK
1047       syms_of_tooltalk ();
1048 #endif
1049
1050 #ifdef SUNPRO
1051       syms_of_sunpro ();
1052 #endif
1053
1054 #ifdef HAVE_LDAP
1055       syms_of_eldap ();
1056 #endif
1057
1058       /* Now create the subtypes for the types that have them.
1059          We do this before the vars_*() because more symbols
1060          may get initialized here. */
1061
1062       /* Now initialize the console types and associated symbols.
1063          Other than the first function below, the functions may
1064          make exactly the following function/macro calls:
1065
1066          INITIALIZE_CONSOLE_TYPE()
1067          CONSOLE_HAS_METHOD()
1068
1069          For any given console type, the former macro must be called
1070          before the any calls to the latter macro. */
1071
1072       console_type_create ();
1073
1074       console_type_create_stream ();
1075
1076 #ifdef HAVE_TTY
1077       console_type_create_tty ();
1078       console_type_create_device_tty ();
1079       console_type_create_frame_tty ();
1080       console_type_create_objects_tty ();
1081       console_type_create_redisplay_tty ();
1082 #endif
1083
1084 #ifdef HAVE_X_WINDOWS
1085       console_type_create_x ();
1086       console_type_create_device_x ();
1087       console_type_create_frame_x ();
1088       console_type_create_glyphs_x ();
1089 #ifdef HAVE_MENUBARS
1090       console_type_create_menubar_x ();
1091 #endif
1092       console_type_create_objects_x ();
1093       console_type_create_redisplay_x ();
1094 #ifdef HAVE_SCROLLBARS
1095       console_type_create_scrollbar_x ();
1096 #endif
1097 #ifdef HAVE_TOOLBARS
1098       console_type_create_toolbar_x ();
1099 #endif
1100 #ifdef HAVE_DIALOGS
1101       console_type_create_dialog_x ();
1102 #endif
1103 #endif /* HAVE_X_WINDOWS */
1104
1105 #ifdef HAVE_MS_WINDOWS
1106       console_type_create_mswindows ();
1107       console_type_create_device_mswindows ();
1108       console_type_create_frame_mswindows ();
1109       console_type_create_objects_mswindows ();
1110       console_type_create_redisplay_mswindows ();
1111       console_type_create_glyphs_mswindows ();
1112 # ifdef HAVE_SCROLLBARS
1113       console_type_create_scrollbar_mswindows ();
1114 # endif
1115 #ifdef HAVE_MENUBARS
1116       console_type_create_menubar_mswindows ();
1117 #endif
1118 #ifdef HAVE_TOOLBARS
1119       console_type_create_toolbar_mswindows ();
1120 #endif
1121 #ifdef HAVE_DIALOGS
1122       console_type_create_dialog_mswindows ();
1123 #endif
1124 #endif
1125
1126       /* Now initialize the specifier types and associated symbols.
1127          Other than the first function below, the functions may
1128          make exactly the following function/macro calls:
1129
1130          INITIALIZE_SPECIFIER_TYPE()
1131          SPECIFIER_HAS_METHOD()
1132
1133          For any given specifier type, the former macro must be called
1134          before the any calls to the latter macro. */
1135
1136       specifier_type_create ();
1137
1138       specifier_type_create_image ();
1139       specifier_type_create_objects ();
1140 #ifdef HAVE_TOOLBARS
1141       specifier_type_create_toolbar ();
1142 #endif
1143
1144       /* Now initialize the structure types and associated symbols.
1145          Other than the first function below, the functions may
1146          make exactly the following function/macro calls:
1147
1148          define_structure_type()
1149          define_structure_type_keyword()
1150
1151          */
1152
1153       structure_type_create ();
1154
1155       structure_type_create_chartab ();
1156       structure_type_create_faces ();
1157       structure_type_create_rangetab ();
1158       structure_type_create_hash_table ();
1159
1160       /* Now initialize the image instantiator formats and associated symbols.
1161          Other than the first function below, the functions may
1162          make exactly the following function/macro calls:
1163
1164          INITIALIZE_IMAGE_INSTANTIATOR_FORMAT()
1165          IIFORMAT_HAS_METHOD()
1166          IIFORMAT_VALID_KEYWORD()
1167
1168          For any given image instantiator format, the first macro must be
1169          called before the any calls to the other macros. */
1170
1171       image_instantiator_format_create ();
1172       image_instantiator_format_create_glyphs_eimage ();
1173 #ifdef HAVE_X_WINDOWS
1174       image_instantiator_format_create_glyphs_x ();
1175 #endif /* HAVE_X_WINDOWS */
1176 #ifdef HAVE_MS_WINDOWS
1177       image_instantiator_format_create_glyphs_mswindows ();
1178 #endif /* HAVE_MSWINDOWS_WINDOWS */
1179
1180       /* Now initialize the lstream types and associated symbols.
1181          Other than the first function below, the functions may
1182          make exactly the following function/macro calls:
1183
1184          LSTREAM_HAS_METHOD()
1185
1186          */
1187
1188       lstream_type_create ();
1189 #ifdef FILE_CODING
1190       lstream_type_create_mule_coding ();
1191 #endif
1192 #if defined (HAVE_MS_WINDOWS) && !defined(HAVE_MSG_SELECT)
1193       lstream_type_create_mswindows_selectable ();
1194 #endif
1195
1196       /* Initialize processes implementation.
1197          The functions may make exactly the following function/macro calls:
1198
1199          PROCESS_HAS_METHOD()
1200       */
1201 #ifdef HAVE_UNIX_PROCESSES
1202       process_type_create_unix ();
1203 #endif
1204 #ifdef HAVE_WIN32_PROCESSES
1205       process_type_create_nt ();
1206 #endif
1207
1208       /* Now initialize most variables.
1209
1210          These functions may do exactly the following:
1211
1212          DEFVAR_INT()
1213          DEFVAR_LISP()
1214          DEFVAR_BOOL()
1215          DEFER_GETTEXT()
1216          Dynarr_*()
1217          Blocktype_*()
1218          staticpro()
1219          Fprovide(symbol)
1220          intern()
1221          pure_put()
1222          xmalloc()
1223          defsymbol(), if it's absolutely necessary and you're sure that
1224            the symbol isn't referenced anywhere else in the initialization
1225            code
1226          Fset() on a symbol that is unbound
1227          assigning a symbol or constant value to a variable
1228          using a global variable that has been initialized
1229            earlier on in the same function
1230
1231          Any of the object-creating functions on alloc.c: e.g.
1232
1233          make_pure_*()
1234          Fpurecopy()
1235          make_string()
1236          build_string()
1237          make_vector()
1238          make_int()
1239          make_extent()
1240          alloc_lcrecord()
1241          Fcons()
1242          listN()
1243          make_opaque_ptr()
1244          make_opaque_long()
1245
1246          perhaps a few others.
1247        */
1248
1249       /* Now allow Fprovide() statements to be made. */
1250       init_provide_once ();
1251
1252       vars_of_abbrev ();
1253       vars_of_alloc ();
1254 #ifdef HAVE_X_WINDOWS
1255       vars_of_balloon_x ();
1256 #endif
1257       vars_of_buffer ();
1258       vars_of_bytecode ();
1259       vars_of_callint ();
1260       vars_of_callproc ();
1261       vars_of_cmdloop ();
1262       vars_of_cmds ();
1263       vars_of_console ();
1264       vars_of_data ();
1265 #ifdef DEBUG_XEMACS
1266       vars_of_debug ();
1267 #endif
1268       vars_of_console_stream ();
1269       vars_of_device ();
1270 #ifdef HAVE_DIALOGS
1271       vars_of_dialog ();
1272 #endif
1273       vars_of_dired ();
1274       vars_of_doc ();
1275 #ifdef HAVE_DRAGNDROP
1276       vars_of_dragdrop ();
1277 #endif
1278       vars_of_editfns ();
1279       vars_of_elhash ();
1280       vars_of_emacs ();
1281       vars_of_eval ();
1282
1283 #ifdef HAVE_X_WINDOWS
1284       vars_of_event_Xt ();
1285 #endif
1286 #if defined(HAVE_TTY) && (defined (DEBUG_TTY_EVENT_STREAM) || !defined (HAVE_X_WINDOWS))
1287       vars_of_event_tty ();
1288 #endif
1289 #ifdef HAVE_MS_WINDOWS
1290       vars_of_event_mswindows ();
1291 #endif
1292       vars_of_event_stream ();
1293
1294       vars_of_events ();
1295       vars_of_extents ();
1296       vars_of_faces ();
1297       vars_of_fileio ();
1298       vars_of_floatfns ();
1299       vars_of_font_lock ();
1300       vars_of_frame ();
1301       vars_of_glyphs ();
1302       vars_of_glyphs_eimage ();
1303 #if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS)
1304       vars_of_gui ();
1305 #endif
1306       vars_of_indent ();
1307       vars_of_insdel ();
1308       vars_of_intl ();
1309 #ifdef HAVE_XIM
1310 #ifdef XIM_MOTIF
1311       vars_of_input_method_motif ();
1312 #else /* XIM_XLIB */
1313       vars_of_input_method_xlib ();
1314 #endif
1315 #endif /* HAVE_XIM */
1316       vars_of_keymap ();
1317       vars_of_lread ();
1318       vars_of_lstream ();
1319       vars_of_macros ();
1320       vars_of_md5 ();
1321 #ifdef HAVE_DATABASE
1322       vars_of_database ();
1323 #endif
1324 #ifdef HAVE_MENUBARS
1325       vars_of_menubar ();
1326 #endif
1327       vars_of_minibuf ();
1328       vars_of_objects ();
1329       vars_of_print ();
1330
1331 #ifndef NO_SUBPROCESSES
1332       vars_of_process ();
1333 #ifdef HAVE_UNIX_PROCESSES
1334       vars_of_process_unix ();
1335 #endif
1336 #ifdef HAVE_WIN32_PROCESSES
1337       vars_of_process_nt ();
1338 #endif
1339 #endif
1340
1341       vars_of_profile ();
1342 #if defined (HAVE_MMAP) && defined (REL_ALLOC) && !defined(DOUG_LEA_MALLOC)
1343       vars_of_ralloc ();
1344 #endif /* HAVE_MMAP && REL_ALLOC */
1345       vars_of_redisplay ();
1346 #ifdef HAVE_SCROLLBARS
1347       vars_of_scrollbar ();
1348 #endif
1349       vars_of_search ();
1350       vars_of_sound ();
1351       vars_of_specifier ();
1352       vars_of_symbols ();
1353       vars_of_syntax ();
1354 #ifdef HAVE_TOOLBARS
1355       vars_of_toolbar ();
1356 #endif
1357       vars_of_undo ();
1358       vars_of_window ();
1359
1360 #ifdef HAVE_TTY
1361       vars_of_console_tty ();
1362       vars_of_frame_tty ();
1363       vars_of_objects_tty ();
1364 #endif
1365
1366 #ifdef HAVE_X_WINDOWS
1367       vars_of_device_x ();
1368 #ifdef HAVE_DIALOGS
1369       vars_of_dialog_x ();
1370 #endif
1371       vars_of_frame_x ();
1372       vars_of_glyphs_x ();
1373 #ifdef HAVE_MENUBARS
1374       vars_of_menubar_x ();
1375 #endif
1376       vars_of_objects_x ();
1377       vars_of_xselect ();
1378 #ifdef HAVE_SCROLLBARS
1379       vars_of_scrollbar_x ();
1380 #endif
1381 #if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS)
1382       vars_of_gui_x ();
1383 #endif
1384 #endif
1385
1386 #ifdef HAVE_MS_WINDOWS
1387       vars_of_device_mswindows ();
1388       vars_of_console_mswindows ();
1389       vars_of_frame_mswindows ();
1390       vars_of_objects_mswindows ();
1391       vars_of_select_mswindows ();
1392       vars_of_glyphs_mswindows ();
1393 #ifdef HAVE_SCROLLBARS
1394       vars_of_scrollbar_mswindows ();
1395 #endif
1396 #ifdef HAVE_MENUBARS
1397       vars_of_menubar_mswindows ();
1398 #endif
1399 #ifdef HAVE_MSW_C_DIRED
1400       vars_of_dired_mswindows ();
1401 #endif
1402 #ifdef HAVE_DIALOGS
1403       vars_of_dialog_mswindows ();
1404 #endif
1405 #endif  /* HAVE_MS_WINDOWS */
1406
1407 #ifdef MULE
1408       vars_of_mule ();
1409       vars_of_mule_charset ();
1410 #endif
1411 #ifdef FILE_CODING
1412       vars_of_mule_coding ();
1413 #endif
1414 #ifdef MULE
1415 #ifdef HAVE_WNN
1416       vars_of_mule_wnn ();
1417 #endif
1418 #ifdef HAVE_CANNA
1419       vars_of_mule_canna ();
1420 #endif /* HAVE_CANNA */
1421 #endif /* MULE */
1422
1423 #ifdef TOOLTALK
1424       vars_of_tooltalk ();
1425 #endif
1426
1427 #ifdef SUNPRO
1428       vars_of_sunpro ();
1429 #endif
1430
1431 #ifdef HAVE_LDAP
1432       vars_of_eldap ();
1433 #endif
1434
1435       /* Now initialize any specifier variables.  We do this later
1436          because it has some dependence on the vars initialized
1437          above.
1438
1439          These functions should *only* initialize specifier variables,
1440          and may make use of the following functions/macros in addition
1441          to the ones listed above:
1442
1443          DEFVAR_SPECIFIER()
1444          Fmake_specifier()
1445          set_specifier_fallback()
1446          set_specifier_caching()
1447          */
1448
1449       specifier_vars_of_glyphs ();
1450 #ifdef HAVE_MENUBARS
1451       specifier_vars_of_menubar ();
1452 #endif
1453       specifier_vars_of_redisplay ();
1454 #ifdef HAVE_SCROLLBARS
1455       specifier_vars_of_scrollbar ();
1456 #endif
1457 #ifdef HAVE_TOOLBARS
1458       specifier_vars_of_toolbar ();
1459 #endif
1460       specifier_vars_of_window ();
1461
1462       /* Now comes all the rest of the variables that couldn't
1463          be handled above.  There may be dependencies on variables
1464          initialized above, and dependencies between one complex_vars_()
1465          function and another. */
1466
1467       /* Calls Fmake_range_table(). */
1468       complex_vars_of_regex ();
1469       /* Calls Fmake_range_table(). */
1470       complex_vars_of_search ();
1471
1472       /* Calls make_lisp_hash_table(). */
1473       complex_vars_of_extents ();
1474
1475       /* Depends on hash tables and specifiers. */
1476       complex_vars_of_faces ();
1477
1478 #ifdef MULE
1479       /* These two depend on hash tables and various variables declared
1480          earlier.  The second may also depend on the first. */
1481       complex_vars_of_mule_charset ();
1482 #endif
1483 #if defined(FILE_CODING)
1484       complex_vars_of_mule_coding ();
1485 #endif
1486
1487       /* This calls allocate_glyph(), which creates specifiers
1488          and also relies on a variable (Vthe_nothing_vector) initialized
1489          above.  It also calls make_ext_string(), which under Mule
1490          could require that the charsets be initialized. */
1491       complex_vars_of_glyphs ();
1492
1493       /* These rely on the glyphs just created in the previous function,
1494          and call Fadd_spec_to_specifier(), which relies on various
1495          variables initialized above. */
1496 #ifdef HAVE_X_WINDOWS
1497       complex_vars_of_glyphs_x ();
1498 #endif
1499 #ifdef HAVE_MS_WINDOWS
1500       complex_vars_of_glyphs_mswindows ();
1501 #endif
1502
1503       /* This calls Fmake_glyph_internal(). */
1504       complex_vars_of_alloc ();
1505
1506       /* This calls Fmake_glyph_internal(). */
1507 #ifdef HAVE_MENUBARS
1508       complex_vars_of_menubar ();
1509 #endif
1510
1511       /* This calls Fmake_glyph_internal(). */
1512 #ifdef HAVE_SCROLLBARS
1513       complex_vars_of_scrollbar ();
1514 #endif
1515
1516       /* This calls allocate_glyph(). */
1517       complex_vars_of_frame ();
1518
1519       /* This calls Fcopy_category_table() under Mule, which calls who
1520          knows what. */
1521       complex_vars_of_chartab ();
1522
1523       /* This calls set_string_char(), which (under Mule) depends on the
1524          charsets being initialized. */
1525       complex_vars_of_casetab ();
1526
1527       /* This calls Fcopy_syntax_table(), which relies on char tables. */
1528       complex_vars_of_syntax ();
1529
1530       /* This initializes buffer-local variables, sets things up so
1531          that buffers can be created, and creates a couple of basic
1532          buffers.  This depends on Vstandard_syntax_table and
1533          Vstandard_category_table (initialized in the previous
1534          functions), as well as a whole horde of variables that may
1535          have been initialized above. */
1536       complex_vars_of_buffer ();
1537
1538       /* This initializes console-local variables. */
1539       complex_vars_of_console ();
1540
1541       /* This creates a couple more buffers, and depends on the
1542          previous function. */
1543       complex_vars_of_minibuf ();
1544
1545       /* These two might call Ffile_name_as_directory(), which
1546          might depend on all sorts of things; I'm not sure. */
1547       complex_vars_of_emacs ();
1548
1549       /* This creates a couple of basic keymaps and depends on Lisp
1550          hash tables and Ffset() (both of which depend on some variables
1551          initialized in the vars_of_*() section) and possibly other
1552          stuff. */
1553       complex_vars_of_keymap ();
1554
1555       /* Calls make_lisp_hash_table() and creates a keymap */
1556       complex_vars_of_event_stream ();
1557
1558 #ifdef ERROR_CHECK_GC
1559       {
1560         extern int always_gc;
1561         if (always_gc)                /* purification debugging hack */
1562           garbage_collect_1 ();
1563       }
1564 #endif
1565     }
1566
1567   /* CONGRATULATIONS!!!  We have successfully initialized the Lisp
1568      engine. */
1569
1570   if (initialized)
1571     {
1572       /* Stuff that needs to be reset at run time.  Order below should
1573          not matter. */
1574       reinit_alloc ();
1575       reinit_eval ();
1576 #ifdef MULE_REGEXP
1577       reinit_mule_category ();
1578 #endif
1579     }
1580
1581   /* Now do further initialization/setup of stuff that is not needed by the
1582      syms_of_() routines.  This involves stuff that only is enabled in
1583      an interactive run (redisplay, user input, etc.) and stuff that is
1584      not needed until we start loading Lisp code (the reader).  A lot
1585      of this stuff involves querying the current environment and needs
1586      to be done both at dump time and at run time. */
1587
1588   init_initial_directory();             /* get the directory to use for the
1589                                            "*scratch*" buffer, etc. */
1590
1591 #ifdef WINDOWSNT
1592   /*
1593    * For Win32, call init_environment() now, so that environment/registry
1594    * variables will be properly entered into Vprocess_environment.
1595    */
1596   init_environment();
1597 #endif
1598
1599   init_callproc ();     /* Set up the process environment (so that egetenv
1600                            works), the basic directory variables
1601                            (exec-directory and so on), and stuff
1602                            related to subprocesses.  This should be
1603                            first because many of the functions below
1604                            call egetenv() to get environment variables. */
1605   init_lread ();        /* Set up the Lisp reader. */
1606 #ifdef MSDOS
1607   /* Call early 'cause init_environment needs it.  */
1608   init_dosfns ();
1609   /* Set defaults for several environment variables.  */
1610   init_environment (argc, argv, skip_args);
1611 #endif
1612   init_cmdargs (argc, argv, skip_args); /* Create list Vcommand_line_args */
1613   init_buffer ();       /* Set default directory of *scratch* buffer */
1614
1615 #ifdef WINDOWSNT
1616   init_ntproc();
1617 #endif
1618
1619   init_redisplay ();      /* Determine terminal type.
1620                              init_sys_modes uses results */
1621   init_event_stream (); /* Set up so we can get user input. */
1622   init_macros (); /* set up so we can run macros. */
1623   init_editfns (); /* Determine the name of the user we're running as */
1624   init_xemacs_process (); /* set up for calling subprocesses */
1625 #ifdef SUNPRO
1626   init_sunpro (); /* Set up Sunpro usage tracking */
1627 #endif
1628 #if defined (HAVE_NATIVE_SOUND) && defined (hp9000s800)
1629   init_hpplay ();
1630 #endif
1631 #ifdef HAVE_TTY
1632   init_device_tty ();
1633 #endif
1634   init_console_stream (); /* Create the first console */
1635
1636   /* try to get the actual pathname of the exec file we are running */
1637   if (!restart)
1638   {
1639     Vinvocation_name = Fcar (Vcommand_line_args);
1640     if (XSTRING_DATA(Vinvocation_name)[0] == '-')
1641       {
1642         /* XEmacs as a login shell, oh goody! */
1643         Vinvocation_name = build_string(getenv("SHELL"));
1644       }
1645     Vinvocation_directory = Vinvocation_name;
1646
1647     if (!NILP (Ffile_name_directory (Vinvocation_name)))
1648       {
1649         /* invocation-name includes a directory component -- presumably it
1650            is relative to cwd, not $PATH */
1651         Vinvocation_directory = Fexpand_file_name (Vinvocation_name,
1652                                                    Qnil);
1653         Vinvocation_path = Qnil;
1654       }
1655     else
1656       {
1657         Vinvocation_path = decode_env_path ("PATH", NULL);
1658         locate_file (Vinvocation_path, Vinvocation_name, EXEC_SUFFIXES,
1659                      &Vinvocation_directory, X_OK);
1660       }
1661
1662     if (NILP (Vinvocation_directory))
1663       Vinvocation_directory = Vinvocation_name;
1664
1665     Vinvocation_name = Ffile_name_nondirectory (Vinvocation_directory);
1666     Vinvocation_directory = Ffile_name_directory (Vinvocation_directory);
1667   }
1668
1669 #if defined(HAVE_SHLIB) && !defined(WINDOWSNT)
1670   /* This is Unix only.  MS Windows NT has a library call that does
1671      The Right Thing on that system.  Rumor has it, this must be
1672      called for GNU dld in temacs and xemacs.  */
1673   {
1674     char *buf = (char *)alloca (XSTRING_LENGTH (Vinvocation_directory)
1675                                 + XSTRING_LENGTH (Vinvocation_name)
1676                                 + 2);
1677     sprintf (buf, "%s/%s", XSTRING_DATA (Vinvocation_directory),
1678              XSTRING_DATA (Vinvocation_name));
1679
1680     /* All we can do is cry if an error happens, so ignore it. */
1681     (void) dll_init (buf);
1682   }
1683 #endif
1684
1685 #if defined (LOCALTIME_CACHE) && defined (HAVE_TZSET)
1686   /* sun's localtime() has a bug.  it caches the value of the time
1687      zone rather than looking it up every time.  Since localtime() is
1688      called to bolt the undumping time into the undumped emacs, this
1689      results in localtime() ignoring the TZ environment variable.
1690      This flushes the new TZ value into localtime(). */
1691   tzset ();
1692 #endif /* LOCALTIME_CACHE and TZSET */
1693
1694   load_me = Qnil;
1695   if (!initialized)
1696     {
1697       /* Handle -l loadup-and-dump, args passed by Makefile. */
1698       if (argc > 2 + skip_args && !strcmp (argv[1 + skip_args], "-l"))
1699         load_me = build_string (argv[2 + skip_args]);
1700 #if 0 /* CANNOT_DUMP - this can never be right in XEmacs --andyp */
1701       /* Unless next switch is -nl, load "loadup.el" first thing.  */
1702       if (!(argc > 1 + skip_args && !strcmp (argv[1 + skip_args], "-nl")))
1703         load_me = build_string ("loadup.el");
1704 #endif /* CANNOT_DUMP */
1705     }
1706
1707 #ifdef QUANTIFY
1708   if (initialized)
1709     quantify_start_recording_data ();
1710 #endif /* QUANTIFY */
1711
1712   initialized = 1;
1713
1714   /* This never returns.  */
1715   initial_command_loop (load_me);
1716   /* NOTREACHED */
1717 }
1718
1719 \f
1720 /* Sort the args so we can find the most important ones
1721    at the beginning of argv.  */
1722
1723 /* First, here's a table of all the standard options.  */
1724
1725 struct standard_args
1726 {
1727   CONST char * CONST name;
1728   CONST char * CONST longname;
1729   int priority;
1730   int nargs;
1731 };
1732
1733 static struct standard_args standard_args[] =
1734 {
1735   /* Handled by main_1 above: */
1736   { "-nl", "--no-shared-memory", 100, 0 },
1737   { "-t", "--terminal", 95, 1 },
1738   { "-nw", "--no-windows", 90, 0 },
1739   { "-batch", "--batch", 85, 0 },
1740   { "-debug-paths", "--debug-paths", 82, 0 },
1741   { "-help", "--help", 80, 0 },
1742   { "-version", "--version", 75, 0 },
1743   { "-V", 0, 75, 0 },
1744   { "-d", "--display", 80, 1 },
1745   { "-display", 0, 80, 1 },
1746   { "-NXHost",  0, 79, 0 },
1747   { "-MachLaunch", 0, 79, 0},
1748
1749   /* Handled by command-line-early in startup.el: */
1750   { "-q", "--no-init-file", 50, 0 },
1751   { "-unmapped", 0, 50, 0 },
1752   { "-no-init-file", 0, 50, 0 },
1753   { "-vanilla", "--vanilla", 50, 0 },
1754   { "-no-autoloads", "--no-autoloads", 50, 0 },
1755   { "-no-site-file", "--no-site-file", 40, 0 },
1756   { "-no-early-packages", "--no-early-packages", 35, 0 },
1757   { "-u", "--user", 30, 1 },
1758   { "-user", 0, 30, 1 },
1759   { "-debug-init", "--debug-init", 20, 0 },
1760   { "-debug-paths", "--debug-paths", 20, 0 },
1761
1762   /* Xt options: */
1763   { "-i", "--icon-type", 15, 0 },
1764   { "-itype", 0, 15, 0 },
1765   { "-iconic", "--iconic", 15, 0 },
1766   { "-bg", "--background-color", 10, 1 },
1767   { "-background", 0, 10, 1 },
1768   { "-fg", "--foreground-color", 10, 1 },
1769   { "-foreground", 0, 10, 1 },
1770   { "-bd", "--border-color", 10, 1 },
1771   { "-bw", "--border-width", 10, 1 },
1772   { "-ib", "--internal-border", 10, 1 },
1773   { "-ms", "--mouse-color", 10, 1 },
1774   { "-cr", "--cursor-color", 10, 1 },
1775   { "-fn", "--font", 10, 1 },
1776   { "-font", 0, 10, 1 },
1777   { "-g", "--geometry", 10, 1 },
1778   { "-geometry", 0, 10, 1 },
1779   { "-T", "--title", 10, 1 },
1780   { "-title", 0, 10, 1 },
1781   { "-name", "--name", 10, 1 },
1782   { "-xrm", "--xrm", 10, 1 },
1783   { "-r", "--reverse-video", 5, 0 },
1784   { "-rv", 0, 5, 0 },
1785   { "-reverse", 0, 5, 0 },
1786   { "-hb", "--horizontal-scroll-bars", 5, 0 },
1787   { "-vb", "--vertical-scroll-bars", 5, 0 },
1788
1789   /* These have the same priority as ordinary file name args,
1790      so they are not reordered with respect to those.  */
1791   { "-L", "--directory", 0, 1 },
1792   { "-directory", 0, 0, 1 },
1793   { "-l", "--load", 0, 1 },
1794   { "-load", 0, 0, 1 },
1795   { "-f", "--funcall", 0, 1 },
1796   { "-funcall", 0, 0, 1 },
1797   { "-eval", "--eval", 0, 1 },
1798   { "-insert", "--insert", 0, 1 },
1799   /* This should be processed after ordinary file name args and the like.  */
1800   { "-kill", "--kill", -10, 0 },
1801 };
1802
1803 /* Reorder the elements of ARGV (assumed to have ARGC elements)
1804    so that the highest priority ones come first.
1805    Do not change the order of elements of equal priority.
1806    If an option takes an argument, keep it and its argument together.  */
1807
1808 static void
1809 sort_args (int argc, char **argv)
1810 {
1811   char **new_argv = xnew_array (char *, argc);
1812   /* For each element of argv,
1813      the corresponding element of options is:
1814      0 for an option that takes no arguments,
1815      1 for an option that takes one argument, etc.
1816      -1 for an ordinary non-option argument.  */
1817   int *options  = xnew_array (int, argc);
1818   int *priority = xnew_array (int, argc);
1819   int to = 1;
1820   int from;
1821   int i;
1822   int end_of_options_p = 0;
1823
1824   /* Categorize all the options,
1825      and figure out which argv elts are option arguments.  */
1826   for (from = 1; from < argc; from++)
1827     {
1828       options[from] = -1;
1829       priority[from] = 0;
1830       /* Pseudo options "--" and "run-temacs" indicate end of options */
1831       if (!strcmp (argv[from], "--") ||
1832           !strcmp (argv[from], "run-temacs"))
1833         end_of_options_p = 1;
1834       if (!end_of_options_p && argv[from][0] == '-')
1835         {
1836           int match, thislen;
1837           char *equals;
1838
1839           /* Look for a match with a known old-fashioned option.  */
1840           for (i = 0; i < countof (standard_args); i++)
1841             if (!strcmp (argv[from], standard_args[i].name))
1842               {
1843                 options[from]  = standard_args[i].nargs;
1844                 priority[from] = standard_args[i].priority;
1845                 if (from + standard_args[i].nargs >= argc)
1846                   fatal ("Option `%s' requires an argument\n", argv[from]);
1847                 from += standard_args[i].nargs;
1848                 goto done;
1849               }
1850
1851           /* Look for a match with a known long option.
1852              MATCH is -1 if no match so far, -2 if two or more matches so far,
1853              >= 0 (the table index of the match) if just one match so far.  */
1854           if (argv[from][1] == '-')
1855             {
1856               match = -1;
1857               thislen = strlen (argv[from]);
1858               equals = strchr (argv[from], '=');
1859               if (equals != 0)
1860                 thislen = equals - argv[from];
1861
1862               for (i = 0; i < countof (standard_args); i++)
1863                 if (standard_args[i].longname
1864                     && !strncmp (argv[from], standard_args[i].longname,
1865                                  thislen))
1866                   {
1867                     if (match == -1)
1868                       match = i;
1869                     else
1870                       match = -2;
1871                   }
1872
1873               /* If we found exactly one match, use that.  */
1874               if (match >= 0)
1875                 {
1876                   options[from]  = standard_args[match].nargs;
1877                   priority[from] = standard_args[match].priority;
1878                   /* If --OPTION=VALUE syntax is used,
1879                      this option uses just one argv element.  */
1880                   if (equals != 0)
1881                     options[from] = 0;
1882                   if (from + options[from] >= argc)
1883                     fatal ("Option `%s' requires an argument\n", argv[from]);
1884                   from += options[from];
1885                 }
1886             }
1887         done: ;
1888         }
1889     }
1890
1891   /* Copy the arguments, in order of decreasing priority, to NEW_ARGV.  */
1892   new_argv[0] = argv[0];
1893   while (to < argc)
1894     {
1895       int best = -1;
1896       int best_priority = -9999;
1897
1898       /* Find the highest priority remaining option.
1899          If several have equal priority, take the first of them.  */
1900       for (from = 1; from < argc; from++)
1901         {
1902           if (argv[from] != 0 && priority[from] > best_priority)
1903             {
1904               best_priority = priority[from];
1905               best = from;
1906             }
1907           /* Skip option arguments--they are tied to the options.  */
1908           if (options[from] > 0)
1909             from += options[from];
1910         }
1911
1912       if (best < 0)
1913         abort ();
1914
1915       /* Copy the highest priority remaining option, with its args, to NEW_ARGV.  */
1916       new_argv[to++] = argv[best];
1917       for (i = 0; i < options[best]; i++)
1918         new_argv[to++] = argv[best + i + 1];
1919
1920       /* Clear out this option in ARGV.  */
1921       argv[best] = 0;
1922       for (i = 0; i < options[best]; i++)
1923         argv[best + i + 1] = 0;
1924     }
1925
1926   memcpy (argv, new_argv, sizeof (char *) * argc);
1927   xfree (new_argv);
1928   xfree (options);
1929   xfree (priority);
1930 }
1931
1932 static JMP_BUF run_temacs_catch;
1933
1934 static int run_temacs_argc;
1935 static char **run_temacs_argv;
1936 static char *run_temacs_args;
1937 static size_t run_temacs_argv_size;
1938 static size_t run_temacs_args_size;
1939
1940 DEFUN ("running-temacs-p", Frunning_temacs_p, 0, 0, 0, /*
1941 True if running temacs.  This means we are in the dumping stage.
1942 This is false during normal execution of the `xemacs' program, and
1943 becomes false once `run-emacs-from-temacs' is run.
1944 */
1945        ())
1946 {
1947   return run_temacs_argc >= 0 ? Qt : Qnil;
1948 }
1949
1950 DEFUN ("run-emacs-from-temacs", Frun_emacs_from_temacs, 0, MANY, 0, /*
1951 Do not call this.  It will reinitialize your XEmacs.  You'll be sorry.
1952 */
1953 /* If this function is called from startup.el, it will be possible to run
1954    temacs as an editor using 'temacs -batch -l loadup.el run-temacs', instead
1955    of having to dump an emacs and then run that (when debugging emacs itself,
1956    this can be much faster)). [Actually, the speed difference isn't that
1957    much as long as your filesystem is local, and you don't end up with
1958    a dumped version in case you want to rerun it.  This function is most
1959    useful when used as part of the `make all-elc' command. --ben]
1960    This will "restart" emacs with the specified command-line arguments.
1961
1962    Martin thinks this function is most useful when using debugging
1963    tools like Purify or tcov that get confused by XEmacs' dumping.  */
1964      (int nargs, Lisp_Object *args))
1965 {
1966   int ac;
1967   CONST Extbyte *wampum;
1968   int namesize;
1969   int total_len;
1970   Lisp_Object orig_invoc_name = Fcar (Vcommand_line_args);
1971   CONST Extbyte **wampum_all = alloca_array (CONST Extbyte *, nargs);
1972   int *wampum_all_len  = alloca_array (int, nargs);
1973
1974   assert (!gc_in_progress);
1975
1976   if (run_temacs_argc < 0)
1977     error ("I've lost my temacs-hood.");
1978
1979   /* Need to convert the orig_invoc_name and all of the arguments
1980      to external format. */
1981
1982   GET_STRING_EXT_DATA_ALLOCA (orig_invoc_name, FORMAT_OS, wampum,
1983                               namesize);
1984   namesize++;
1985
1986   for (ac = 0, total_len = namesize; ac < nargs; ac++)
1987     {
1988       CHECK_STRING (args[ac]);
1989       GET_STRING_EXT_DATA_ALLOCA (args[ac], FORMAT_OS,
1990                                   wampum_all[ac],
1991                                   wampum_all_len[ac]);
1992       wampum_all_len[ac]++;
1993       total_len += wampum_all_len[ac];
1994     }
1995   DO_REALLOC (run_temacs_args, run_temacs_args_size, total_len, char);
1996   DO_REALLOC (run_temacs_argv, run_temacs_argv_size, nargs+1, char *);
1997
1998   memcpy (run_temacs_args, wampum, namesize);
1999   run_temacs_argv [0] = run_temacs_args;
2000   for (ac = 0; ac < nargs; ac++)
2001     {
2002       memcpy (run_temacs_args + namesize,
2003               wampum_all[ac], wampum_all_len[ac]);
2004       run_temacs_argv [ac + 1] = run_temacs_args + namesize;
2005       namesize += wampum_all_len[ac];
2006     }
2007   run_temacs_argv [nargs + 1] = 0;
2008   catchlist = NULL; /* Important!  Otherwise free_cons() calls in
2009                        condition_case_unwind() may lead to GC death. */
2010   unbind_to (0, Qnil); /* this closes loadup.el */
2011   purify_flag = 0;
2012   run_temacs_argc = nargs + 1;
2013 #if 0
2014 #ifdef REPORT_PURE_USAGE
2015   report_pure_usage (1, 0);
2016 #else
2017   report_pure_usage (0, 0);
2018 #endif
2019 #endif /* 0 */
2020   LONGJMP (run_temacs_catch, 1);
2021   return Qnil; /* not reached; warning suppression */
2022 }
2023
2024 /* ARGSUSED */
2025 int
2026 main (int argc, char **argv, char **envp)
2027 {
2028   int     volatile vol_argc = argc;
2029   char ** volatile vol_argv = argv;
2030   char ** volatile vol_envp = envp;
2031   /* This is hairy.  We need to compute where the XEmacs binary was invoked
2032      from because temacs initialization requires it to find the lisp
2033      directories.  The code that recomputes the path is guarded by the
2034      restarted flag.  There are three possible paths I've found so far
2035      through this:
2036
2037      temacs -- When running temacs for basic build stuff, the first main_1
2038       will be the only one invoked.  It must compute the path else there
2039       will be a very ugly bomb in startup.el (can't find obvious location
2040       for doc-directory data-directory, etc.).
2041
2042      temacs w/ run-temacs on the command line -- This is run to bytecompile
2043       all the out of date dumped lisp.  It will execute both of the main_1
2044       calls and the second one must not touch the first computation because
2045       argc/argv are hosed the second time through.
2046
2047      xemacs -- Only the second main_1 is executed.  The invocation path must
2048       computed but this only matters when running in place or when running
2049       as a login shell.
2050
2051      As a bonus for straightening this out, XEmacs can now be run in place
2052      as a login shell.  This never used to work.
2053
2054      As another bonus, we can now guarantee that
2055      (concat invocation-directory invocation-name) contains the filename
2056      of the XEmacs binary we are running.  This can now be used in a
2057      definite test for out of date dumped files.  -slb */
2058   int restarted = 0;
2059 #ifdef QUANTIFY
2060   quantify_stop_recording_data ();
2061   quantify_clear_data ();
2062 #endif /* QUANTIFY */
2063
2064   suppress_early_error_handler_backtrace = 0;
2065   lim_data = 0; /* force reinitialization of this variable */
2066
2067   /* Lisp_Object must fit in a word; check VALBITS and GCTYPEBITS */
2068   assert (sizeof (Lisp_Object) == sizeof (void *));
2069
2070 #ifdef LINUX_SBRK_BUG
2071   sbrk (1);
2072 #endif
2073
2074   if (!initialized)
2075     {
2076 #ifdef DOUG_LEA_MALLOC
2077       mallopt (M_MMAP_MAX, 0);
2078 #endif
2079       run_temacs_argc = 0;
2080       if (! SETJMP (run_temacs_catch))
2081         {
2082           main_1 (vol_argc, vol_argv, vol_envp, 0);
2083         }
2084       /* run-emacs-from-temacs called */
2085       restarted = 1;
2086       vol_argc = run_temacs_argc;
2087       vol_argv = run_temacs_argv;
2088 #ifdef _SCO_DS
2089       /* This makes absolutely no sense to anyone involved.  There are
2090          several people using this stuff.  We've compared versions on
2091          everything we can think of.  We can find no difference.
2092          However, on both my systems environ is a plain old global
2093          variable initialized to zero.  _environ is the one that
2094          contains pointers to the actual environment.
2095
2096          Since we can't figure out the difference (and we're hours
2097          away from a release), this takes a very cowardly approach and
2098          is bracketed with both a system specific preprocessor test
2099          and a runtime "do you have this problem" test
2100
2101          06/20/96 robertl@dgii.com */
2102       {
2103         extern char *_environ;
2104         if ((unsigned) environ == 0)
2105           environ=_environ;
2106       }
2107 #endif /* _SCO_DS */
2108       vol_envp = environ;
2109     }
2110 #ifdef RUN_TIME_REMAP
2111   else
2112     /* obviously no-one uses this because where it was before initialized was
2113      *always* true */
2114     run_time_remap (argv[0]);
2115 #endif
2116
2117 #ifdef DOUG_LEA_MALLOC
2118   if (initialized && (malloc_state_ptr != NULL))
2119     {
2120       int rc = malloc_set_state (malloc_state_ptr);
2121       if (rc != 0)
2122         {
2123           fprintf (stderr, "malloc_set_state failed, rc = %d\n", rc);
2124           abort ();
2125         }
2126 #if 0
2127       free (malloc_state_ptr);
2128 #endif
2129       /* mmap works in glibc-2.1, glibc-2.0 (Non-Mule only) and Linux libc5 */
2130 #if (defined(__GLIBC__) && __GLIBC_MINOR__ >= 1) || \
2131     defined(_NO_MALLOC_WARNING_) || \
2132     (defined(__GLIBC__) && __GLIBC_MINOR__ < 1 && !defined(MULE)) || \
2133     defined(DEBUG_DOUG_LEA_MALLOC)
2134       mallopt (M_MMAP_MAX, 64);
2135 #endif
2136 #ifdef REL_ALLOC
2137       r_alloc_reinit ();
2138 #endif
2139     }
2140 #endif /* DOUG_LEA_MALLOC */
2141
2142   run_temacs_argc = -1;
2143
2144   main_1 (vol_argc, vol_argv, vol_envp, restarted);
2145   return 0; /* unreached */
2146 }
2147
2148 \f
2149 /* Dumping apparently isn't supported by versions of GCC >= 2.8. */
2150 /* The following needs conditionalization on whether either XEmacs or */
2151 /* various system shared libraries have been built and linked with */
2152 /* GCC >= 2.8.  -slb */
2153 #if defined(GNU_MALLOC)
2154 static void
2155 voodoo_free_hook(void *mem)
2156 {
2157   /* Disable all calls to free() when XEmacs is exiting and it doesn't */
2158   /* matter. */
2159   __free_hook = voodoo_free_hook;
2160 }
2161 #endif
2162
2163 DEFUN ("kill-emacs", Fkill_emacs, 0, 1, "P", /*
2164 Exit the XEmacs job and kill it.  Ask for confirmation, without argument.
2165 If ARG is an integer, return ARG as the exit program code.
2166 If ARG is a string, stuff it as keyboard input.
2167
2168 The value of `kill-emacs-hook', if not void,
2169 is a list of functions (of no args),
2170 all of which are called before XEmacs is actually killed.
2171 */
2172        (arg))
2173 {
2174   /* This function can GC */
2175   struct gcpro gcpro1;
2176
2177   GCPRO1 (arg);
2178
2179   if (feof (stdin))
2180     arg = Qt;
2181
2182   if (!preparing_for_armageddon && !noninteractive)
2183     run_hook (Qkill_emacs_hook);
2184
2185   /* make sure no quitting from now on!! */
2186   dont_check_for_quit = 1;
2187   Vinhibit_quit = Qt;
2188
2189   if (!preparing_for_armageddon)
2190     {
2191       Lisp_Object concons, nextcons;
2192
2193       /* Normally, go ahead and delete all the consoles now.
2194          Some unmentionably lame window systems (MS Wwwww...... eek,
2195          I can't even say it) don't properly clean up after themselves,
2196          and even for those that do, it might be cleaner this way.
2197          If we're going down, however, we don't do this (might
2198          be too dangerous), and if we get a crash somewhere within
2199          this loop, we'll still autosave and won't try this again. */
2200
2201       LIST_LOOP_DELETING(concons, nextcons, Vconsole_list)
2202         {
2203           /* There is very little point in deleting the stream console.
2204              It uses stdio, which should flush any buffered output and
2205              something can only go wrong. -slb */
2206           /* I changed my mind.  There's a stupid hack in close to add
2207              a trailing newline. */
2208           /*if (!CONSOLE_STREAM_P (XCONSOLE (XCAR (concons))))*/
2209             delete_console_internal (XCONSOLE (XCAR (concons)), 1, 1, 0);
2210         }
2211     }
2212
2213   UNGCPRO;
2214
2215   shut_down_emacs (0, ((STRINGP (arg)) ? arg : Qnil));
2216
2217 #if defined(GNU_MALLOC)
2218   __free_hook = voodoo_free_hook;
2219 #endif
2220
2221   exit ((INTP (arg)) ? XINT (arg) : 0);
2222   /* NOTREACHED */
2223   return Qnil; /* I'm sick of the compiler warning */
2224 }
2225
2226 /* Perform an orderly shutdown of XEmacs.  Autosave any modified
2227    buffers, kill any child processes, clean up the terminal modes (if
2228    we're in the foreground), and other stuff like that.  Don't perform
2229    any redisplay; this may be called when XEmacs is shutting down in
2230    the background, or after its X connection has died.
2231
2232    If SIG is a signal number, print a message for it.
2233
2234    This is called by fatal signal handlers, X protocol error handlers,
2235    and Fkill_emacs.  */
2236 static void
2237 shut_down_emacs (int sig, Lisp_Object stuff)
2238 {
2239   /* This function can GC */
2240   /* Prevent running of hooks and other non-essential stuff
2241      from now on.  */
2242   preparing_for_armageddon = 1;
2243
2244   /* In case frames or windows are screwed up, avoid assertion
2245      failures here */
2246   Vinhibit_quit = Qt;
2247
2248 #ifdef QUANTIFY
2249   quantify_stop_recording_data ();
2250 #endif /* QUANTIFY */
2251
2252 #if 0
2253   /* This is absolutely the most important thing to do, so make sure
2254      we do it now, before anything else.  We might have crashed and
2255      be in a weird inconsistent state, and potentially anything could
2256      set off another protection fault and cause us to bail out
2257      immediately. */
2258   /* I'm not removing the code entirely, yet.  We have run up against
2259      a spate of problems in diagnosing crashes due to crashes within
2260      crashes.  It has very definitely been determined that code called
2261      during auto-saving cannot work if XEmacs crashed inside of GC.
2262      We already auto-save on an itimer so there cannot be too much
2263      unsaved stuff around, and if we get better crash reports we might
2264      be able to get more problems fixed so I'm disabling this.  -slb */
2265   Fdo_auto_save (Qt, Qnil); /* do this before anything hazardous */
2266 #endif
2267
2268   fflush (stdout);
2269   reset_all_consoles ();
2270   if (sig && sig != SIGTERM)
2271     {
2272       stderr_out ("\nFatal error (%d).\n", sig);
2273       stderr_out
2274         ("Your files have been auto-saved.\n"
2275          "Use `M-x recover-session' to recover them.\n"
2276          "\n"
2277 #ifdef INFODOCK
2278          "Please report this bug by selecting `Report-Bug' in the InfoDock\n"
2279          "menu.\n"
2280 #else
2281          "Please report this bug by running the send-pr script included\n"
2282          "with XEmacs, or selecting `Send Bug Report' from the help menu.\n"
2283          "As a last resort send ordinary email to `crashes@xemacs.org'.\n"
2284 #endif
2285          "*MAKE SURE* to include the information in the command\n"
2286          "M-x describe-installation.\n"
2287          "\n"
2288          "If at all possible, *please* try to obtain a C stack backtrace;\n"
2289          "it will help us immensely in determining what went wrong.\n"
2290          "To do this, locate the core file that was produced as a result\n"
2291          "of this crash (it's usually called `core' and is located in the\n"
2292          "directory in which you started the editor, or maybe in your home\n"
2293          "directory), and type\n"
2294          "\n"
2295          "  gdb ");
2296       {
2297         CONST char *name;
2298         char *dir = 0;
2299
2300         /* Now try to determine the actual path to the executable,
2301            to try to make the backtrace-determination process as foolproof
2302            as possible. */
2303         if (GC_STRINGP (Vinvocation_name))
2304           name = (char *) XSTRING_DATA (Vinvocation_name);
2305         else
2306           name = "xemacs";
2307         if (GC_STRINGP (Vinvocation_directory))
2308           dir = (char *) XSTRING_DATA (Vinvocation_directory);
2309         if (!dir || dir[0] != '/')
2310           stderr_out ("`which %s`", name);
2311         else if (dir[strlen (dir) - 1] != '/')
2312           stderr_out ("%s/%s", dir, name);
2313         else
2314           stderr_out ("%s%s", dir, name);
2315       }
2316       stderr_out
2317         (" core\n\n"
2318          "then type `where' when the debugger prompt comes up.\n"
2319          "(If you don't have GDB on your system, you might have DBX,\n"
2320          "or XDB, or SDB.  A similar procedure should work for all of\n"
2321          "these.  Ask your system administrator if you need more help.)\n");
2322     }
2323
2324   stuff_buffered_input (stuff);
2325
2326   kill_buffer_processes (Qnil);
2327
2328 #ifdef CLASH_DETECTION
2329   unlock_all_files ();
2330 #endif
2331
2332 #ifdef TOOLTALK
2333   tt_session_quit (tt_default_session ());
2334 #if 0
2335   /* The following crashes when built on X11R5 and run on X11R6 */
2336   tt_close ();
2337 #endif
2338 #endif /* TOOLTALK */
2339
2340 }
2341
2342 \f
2343 #ifndef CANNOT_DUMP
2344 /* Nothing like this can be implemented on an Apollo.
2345    What a loss!  */
2346
2347 extern char my_edata[];
2348
2349 #ifdef HAVE_SHM
2350
2351 DEFUN ("dump-emacs-data", Fdump_emacs_data, 1, 1, 0, /*
2352 Dump current state of XEmacs into data file FILENAME.
2353 This function exists on systems that use HAVE_SHM.
2354 */
2355        (intoname))
2356 {
2357   /* This function can GC */
2358   int opurify;
2359   struct gcpro gcpro1;
2360   GCPRO1 (intoname);
2361
2362   CHECK_STRING (intoname);
2363   intoname = Fexpand_file_name (intoname, Qnil);
2364
2365   opurify = purify_flag;
2366   purify_flag = 0;
2367
2368   fflush (stderr);
2369   fflush (stdout);
2370
2371   disksave_object_finalization ();
2372   release_breathing_space ();
2373
2374   /* Tell malloc where start of impure now is */
2375   /* Also arrange for warnings when nearly out of space.  */
2376 #ifndef SYSTEM_MALLOC
2377   memory_warnings (my_edata, malloc_warning);
2378 #endif
2379   UNGCPRO;
2380   map_out_data (XSTRING_DATA (intoname));
2381
2382   purify_flag = opurify;
2383
2384   return Qnil;
2385 }
2386
2387 #else /* not HAVE_SHM */
2388 extern void disable_free_hook (void);
2389
2390 DEFUN ("dump-emacs", Fdump_emacs, 2, 2, 0, /*
2391 Dump current state of XEmacs into executable file FILENAME.
2392 Take symbols from SYMFILE (presumably the file you executed to run XEmacs).
2393 This is used in the file `loadup.el' when building XEmacs.
2394
2395 Remember to set `command-line-processed' to nil before dumping
2396 if you want the dumped XEmacs to process its command line
2397 and announce itself normally when it is run.
2398 */
2399        (intoname, symname))
2400 {
2401   /* This function can GC */
2402   struct gcpro gcpro1, gcpro2;
2403   int opurify;
2404
2405   GCPRO2 (intoname, symname);
2406
2407 #ifdef FREE_CHECKING
2408   Freally_free (Qnil);
2409
2410   /* When we're dumping, we can't use the debugging free() */
2411   disable_free_hook ();
2412 #endif
2413 #if 1 /* martin */
2414 #endif
2415
2416   CHECK_STRING (intoname);
2417   intoname = Fexpand_file_name (intoname, Qnil);
2418   if (!NILP (symname))
2419     {
2420       CHECK_STRING (symname);
2421       if (XSTRING_LENGTH (symname) > 0)
2422         symname = Fexpand_file_name (symname, Qnil);
2423       else
2424         symname = Qnil;
2425     }
2426
2427   opurify = purify_flag;
2428   purify_flag = 0;
2429
2430 #ifdef DEBUG_XEMACS
2431   report_pure_usage (1, 1);
2432 #else
2433   report_pure_usage (0, 1);
2434 #endif
2435
2436   fflush (stderr);
2437   fflush (stdout);
2438
2439   disksave_object_finalization ();
2440   release_breathing_space ();
2441
2442   /* Tell malloc where start of impure now is */
2443   /* Also arrange for warnings when nearly out of space.  */
2444 #ifndef SYSTEM_MALLOC
2445   memory_warnings (my_edata, malloc_warning);
2446 #endif
2447
2448   UNGCPRO;
2449
2450 #if defined (MSDOS) && defined (EMX)
2451   {
2452     int fd = open ((char *) XSTRING_DATA (intoname),
2453                    O_WRONLY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE);
2454     if (!fd) {
2455       error ("Failure operating on %s", XSTRING_DATA (intoname));
2456     } else {
2457       _core (fd);
2458       close (fd);
2459     }
2460   }
2461 #else /* not MSDOS and EMX */
2462   {
2463     char *intoname_ext;
2464     char *symname_ext;
2465
2466     GET_C_STRING_FILENAME_DATA_ALLOCA (intoname, intoname_ext);
2467     if (STRINGP (symname))
2468       GET_C_STRING_FILENAME_DATA_ALLOCA (symname, symname_ext);
2469     else
2470       symname_ext = 0;
2471
2472     garbage_collect_1 ();
2473 #ifdef DOUG_LEA_MALLOC
2474     malloc_state_ptr = malloc_get_state ();
2475 #endif
2476   /* here we break our rule that the filename conversion should
2477      be performed at the actual time that the system call is made.
2478      It's a whole lot easier to do the conversion here than to
2479      modify all the unexec routines to ensure that filename
2480      conversion is applied everywhere.  Don't worry about memory
2481      leakage because this call only happens once. */
2482     unexec (intoname_ext, symname_ext, (uintptr_t) my_edata, 0, 0);
2483 #ifdef DOUG_LEA_MALLOC
2484     free (malloc_state_ptr);
2485 #endif
2486   }
2487 #endif /* not MSDOS and EMX */
2488
2489   purify_flag = opurify;
2490
2491   return Qnil;
2492 }
2493
2494 #endif /* not HAVE_SHM */
2495
2496 #endif /* not CANNOT_DUMP */
2497 \f
2498 #ifndef SEPCHAR
2499 #define SEPCHAR ':'
2500 #endif
2501
2502 /* Split STRING into a list of substrings.  The substrings are the
2503    parts of original STRING separated by SEPCHAR.  */
2504 static Lisp_Object
2505 split_string_by_emchar_1 (CONST Bufbyte *string, Bytecount size,
2506                           Emchar sepchar)
2507 {
2508   Lisp_Object result = Qnil;
2509   CONST Bufbyte *end = string + size;
2510
2511   while (1)
2512     {
2513       CONST Bufbyte *p = string;
2514       while (p < end)
2515         {
2516           if (charptr_emchar (p) == sepchar)
2517             break;
2518           INC_CHARPTR (p);
2519         }
2520       result = Fcons (make_string (string, p - string), result);
2521       if (p < end)
2522         {
2523           string = p;
2524           INC_CHARPTR (string); /* skip sepchar */
2525         }
2526       else
2527         break;
2528     }
2529   return Fnreverse (result);
2530 }
2531
2532 /* The same as the above, except PATH is an external C string (it is
2533    converted as FORMAT_FILENAME), and sepchar is hardcoded to SEPCHAR
2534    (':' or whatever).  */
2535 Lisp_Object
2536 decode_path (CONST char *path)
2537 {
2538   int len;
2539   Bufbyte *newpath;
2540   if (!path)
2541     return Qnil;
2542
2543   GET_C_CHARPTR_INT_FILENAME_DATA_ALLOCA (path, newpath);
2544
2545   len = strlen ((const char *) newpath);
2546   /* #### Does this make sense?  It certainly does for
2547      decode_env_path(), but it looks dubious here.  Does any code
2548      depend on decode_path("") returning nil instead of an empty
2549      string?  */
2550   if (!len)
2551     return Qnil;
2552
2553   return split_string_by_emchar_1 (newpath, (Bytecount)len, SEPCHAR);
2554 }
2555
2556 Lisp_Object
2557 decode_env_path (CONST char *evarname, CONST char *default_)
2558 {
2559   CONST char *path = 0;
2560   if (evarname)
2561     path = egetenv (evarname);
2562   if (!path)
2563     path = default_;
2564   return decode_path (path);
2565 }
2566
2567 /* Ben thinks this function should not exist or be exported to Lisp.
2568    We use it to define split-path-string in subr.el (not!).  */
2569
2570 DEFUN ("split-string-by-char", Fsplit_string_by_char, 1, 2, 0, /*
2571 Split STRING into a list of substrings originally separated by SEPCHAR.
2572 */
2573        (string, sepchar))
2574 {
2575   CHECK_STRING (string);
2576   CHECK_CHAR (sepchar);
2577   return split_string_by_emchar_1 (XSTRING_DATA (string),
2578                                    XSTRING_LENGTH (string),
2579                                    XCHAR (sepchar));
2580 }
2581
2582 /* #### This was supposed to be in subr.el, but is used VERY early in
2583    the bootstrap process, so it goes here.  Damn.  */
2584
2585 DEFUN ("split-path", Fsplit_path, 1, 1, 0, /*
2586 Explode a search path into a list of strings.
2587 The path components are separated with the characters specified
2588 with `path-separator'.
2589 */
2590        (path))
2591 {
2592   CHECK_STRING (path);
2593
2594   while (!STRINGP (Vpath_separator)
2595          || (XSTRING_CHAR_LENGTH (Vpath_separator) != 1))
2596     Vpath_separator = signal_simple_continuable_error
2597       ("`path-separator' should be set to a single-character string",
2598        Vpath_separator);
2599
2600   return (split_string_by_emchar_1
2601           (XSTRING_DATA (path), XSTRING_LENGTH (path),
2602            charptr_emchar (XSTRING_DATA (Vpath_separator))));
2603 }
2604 \f
2605 DEFUN ("noninteractive", Fnoninteractive, 0, 0, 0, /*
2606 Non-nil return value means XEmacs is running without interactive terminal.
2607 */
2608        ())
2609 {
2610   return noninteractive ? Qt : Qnil;
2611 }
2612
2613 /* This flag is useful to define if you're under a debugger; this way, you
2614    can put a breakpoint of assert_failed() and debug multiple problems
2615    in one session without having to recompile. */
2616 /* #define ASSERTIONS_DONT_ABORT */
2617
2618 #ifdef USE_ASSERTIONS
2619 /* This highly dubious kludge ... shut up Jamie, I'm tired of your slagging. */
2620
2621 DOESNT_RETURN
2622 assert_failed (CONST char *file, int line, CONST char *expr)
2623 {
2624   stderr_out ("Fatal error: assertion failed, file %s, line %d, %s\n",
2625               file, line, expr);
2626 #undef abort    /* avoid infinite #define loop... */
2627 #if defined (WINDOWSNT) && defined (DEBUG_XEMACS)
2628   DebugBreak ();
2629 #elif !defined (ASSERTIONS_DONT_ABORT)
2630   abort ();
2631 #endif
2632 }
2633 #endif /* USE_ASSERTIONS */
2634
2635 #ifdef QUANTIFY
2636 DEFUN ("quantify-start-recording-data", Fquantify_start_recording_data,
2637        0, 0, "", /*
2638 Start recording Quantify data.
2639 */
2640        ())
2641 {
2642   quantify_start_recording_data ();
2643   return Qnil;
2644 }
2645
2646 DEFUN ("quantify-stop-recording-data", Fquantify_stop_recording_data,
2647        0, 0, "", /*
2648 Stop recording Quantify data.
2649 */
2650        ())
2651 {
2652   quantify_stop_recording_data ();
2653   return Qnil;
2654 }
2655
2656 DEFUN ("quantify-clear-data", Fquantify_clear_data, 0, 0, "", /*
2657 Clear all Quantify data.
2658 */
2659        ())
2660 {
2661   quantify_clear_data ();
2662   return Qnil;
2663 }
2664 #endif /* QUANTIFY */
2665
2666 void
2667 syms_of_emacs (void)
2668 {
2669 #ifndef CANNOT_DUMP
2670 #ifdef HAVE_SHM
2671   DEFSUBR (Fdump_emacs_data);
2672 #else
2673   DEFSUBR (Fdump_emacs);
2674 #endif
2675 #endif /* !CANNOT_DUMP */
2676
2677   DEFSUBR (Frun_emacs_from_temacs);
2678   DEFSUBR (Frunning_temacs_p);
2679   DEFSUBR (Finvocation_name);
2680   DEFSUBR (Finvocation_directory);
2681   DEFSUBR (Fkill_emacs);
2682   DEFSUBR (Fnoninteractive);
2683
2684 #ifdef QUANTIFY
2685   DEFSUBR (Fquantify_start_recording_data);
2686   DEFSUBR (Fquantify_stop_recording_data);
2687   DEFSUBR (Fquantify_clear_data);
2688 #endif /* QUANTIFY */
2689
2690   DEFSUBR (Fsplit_string_by_char);
2691   DEFSUBR (Fsplit_path);        /* #### */
2692
2693   defsymbol (&Qkill_emacs_hook, "kill-emacs-hook");
2694   defsymbol (&Qsave_buffers_kill_emacs, "save-buffers-kill-emacs");
2695 }
2696
2697 void
2698 vars_of_emacs (void)
2699 {
2700   DEFVAR_BOOL ("suppress-early-error-handler-backtrace",
2701                &suppress_early_error_handler_backtrace /*
2702 Non-nil means early error handler shouldn't print a backtrace.
2703 */ );
2704
2705   DEFVAR_LISP ("command-line-args", &Vcommand_line_args /*
2706 Args passed by shell to XEmacs, as a list of strings.
2707 */ );
2708
2709   DEFVAR_LISP ("invocation-name", &Vinvocation_name /*
2710 The program name that was used to run XEmacs.
2711 Any directory names are omitted.
2712 */ );
2713
2714   DEFVAR_LISP ("invocation-directory", &Vinvocation_directory /*
2715 The directory in which the XEmacs executable was found, to run it.
2716 The value is simply the program name if that directory's name is not known.
2717 */ );
2718
2719   DEFVAR_LISP ("invocation-path", &Vinvocation_path /*
2720 The path in which the XEmacs executable was found, to run it.
2721 The value is simply the value of environment variable PATH on startup
2722 if XEmacs was found there.
2723 */ );
2724
2725 #if 0 /* FSFmacs */
2726   xxDEFVAR_LISP ("installation-directory", &Vinstallation_directory,
2727     "A directory within which to look for the `lib-src' and `etc' directories.\n"
2728 "This is non-nil when we can't find those directories in their standard\n"
2729 "installed locations, but we can find them\n"
2730 "near where the XEmacs executable was found.");
2731 #endif
2732
2733   DEFVAR_LISP ("system-type", &Vsystem_type /*
2734 Symbol indicating type of operating system you are using.
2735 */ );
2736   Vsystem_type = intern (SYSTEM_TYPE);
2737   Fprovide (intern(SYSTEM_TYPE));
2738
2739 #ifndef EMACS_CONFIGURATION
2740 # define EMACS_CONFIGURATION "UNKNOWN"
2741 #endif
2742   DEFVAR_LISP ("system-configuration", &Vsystem_configuration /*
2743 String naming the configuration XEmacs was built for.
2744 */ );
2745   Vsystem_configuration = Fpurecopy (build_string (EMACS_CONFIGURATION));
2746
2747 #ifndef EMACS_CONFIG_OPTIONS
2748 # define EMACS_CONFIG_OPTIONS "UNKNOWN"
2749 #endif
2750   DEFVAR_LISP ("system-configuration-options", &Vsystem_configuration_options /*
2751 String containing the configuration options XEmacs was built with.
2752 */ );
2753   Vsystem_configuration_options = Fpurecopy (build_string
2754                                              (EMACS_CONFIG_OPTIONS));
2755
2756   DEFVAR_LISP ("emacs-major-version", &Vemacs_major_version /*
2757 Major version number of this version of Emacs, as an integer.
2758 Warning: this variable did not exist in Emacs versions earlier than:
2759   FSF Emacs:   19.23
2760   XEmacs:      19.10
2761 */ );
2762   Vemacs_major_version = make_int (EMACS_MAJOR_VERSION);
2763
2764   DEFVAR_LISP ("emacs-minor-version", &Vemacs_minor_version /*
2765 Minor version number of this version of Emacs, as an integer.
2766 Warning: this variable did not exist in Emacs versions earlier than:
2767   FSF Emacs:   19.23
2768   XEmacs:      19.10
2769 */ );
2770   Vemacs_minor_version = make_int (EMACS_MINOR_VERSION);
2771
2772   DEFVAR_LISP ("emacs-beta-version", &Vemacs_beta_version /*
2773 Beta number of this version of Emacs, as an integer.
2774 The value is nil if this is an officially released version of XEmacs.
2775 Warning: this variable does not exist in FSF Emacs or in XEmacs versions
2776 earlier than 20.3.
2777 */ );
2778 #ifdef EMACS_BETA_VERSION
2779   Vemacs_beta_version = make_int (EMACS_BETA_VERSION);
2780 #else
2781   Vemacs_beta_version = Qnil;
2782 #endif
2783
2784 #ifdef INFODOCK
2785   DEFVAR_LISP ("infodock-major-version", &Vinfodock_major_version /*
2786 Major version number of this InfoDock release.
2787 */ );
2788   Vinfodock_major_version = make_int (INFODOCK_MAJOR_VERSION);
2789
2790   DEFVAR_LISP ("infodock-minor-version", &Vinfodock_minor_version /*
2791 Minor version number of this InfoDock release.
2792 */ );
2793   Vinfodock_minor_version = make_int (INFODOCK_MINOR_VERSION);
2794
2795   DEFVAR_LISP ("infodock-build-version", &Vinfodock_build_version /*
2796 Build version of this InfoDock release.
2797 */ );
2798   Vinfodock_build_version = make_int (INFODOCK_BUILD_VERSION);
2799 #endif
2800
2801   DEFVAR_LISP ("xemacs-codename", &Vxemacs_codename /*
2802 Codename of this version of Emacs (a string).
2803 */ );
2804 #ifndef XEMACS_CODENAME
2805 #define XEMACS_CODENAME "Noname"
2806 #endif
2807   Vxemacs_codename = Fpurecopy (build_string (XEMACS_CODENAME));
2808
2809   DEFVAR_BOOL ("noninteractive", &noninteractive1 /*
2810 Non-nil means XEmacs is running without interactive terminal.
2811 */ );
2812
2813   DEFVAR_BOOL ("inhibit-early-packages", &inhibit_early_packages /*
2814 Set to non-nil when the early packages should not be respected at startup.
2815 */ );
2816
2817   DEFVAR_BOOL ("inhibit-autoloads", &inhibit_autoloads /*
2818 Set to non-nil when autoloads should not be loaded at startup.
2819 */ );
2820
2821   DEFVAR_BOOL ("debug-paths", &debug_paths /*
2822 Set to non-nil when debug information about paths should be printed.
2823 */ );
2824
2825   DEFVAR_BOOL ("inhibit-site-lisp", &inhibit_site_lisp /*
2826 Set to non-nil when the site-lisp should not be searched at startup.
2827 */ );
2828 #ifdef INHIBIT_SITE_LISP
2829   inhibit_site_lisp = 1;
2830 #endif
2831
2832   DEFVAR_INT ("emacs-priority", &emacs_priority /*
2833 Priority for XEmacs to run at.
2834 This value is effective only if set before XEmacs is dumped,
2835 and only if the XEmacs executable is installed with setuid to permit
2836 it to change priority.  (XEmacs sets its uid back to the real uid.)
2837 Currently, you need to define SET_EMACS_PRIORITY in `config.h'
2838 before you compile XEmacs, to enable the code for this feature.
2839 */ );
2840   emacs_priority = 0;
2841
2842   DEFVAR_CONST_LISP ("internal-error-checking", &Vinternal_error_checking /*
2843 Internal error checking built-in into this instance of XEmacs.
2844 This is a list of symbols, initialized at build-time.  Legal symbols
2845 are:
2846
2847 extents         - check extents prior to each extent change;
2848 typecheck       - check types strictly, aborting in case of error;
2849 malloc          - check operation of malloc;
2850 gc              - check garbage collection;
2851 bufpos          - check buffer positions.
2852 */ );
2853   Vinternal_error_checking = Qnil;
2854 #ifdef ERROR_CHECK_EXTENTS
2855   Vinternal_error_checking = Fcons (intern ("extents"),
2856                                     Vinternal_error_checking);
2857 #endif
2858 #ifdef ERROR_CHECK_TYPECHECK
2859   Vinternal_error_checking = Fcons (intern ("typecheck"),
2860                                     Vinternal_error_checking);
2861 #endif
2862 #ifdef ERROR_CHECK_MALLOC
2863   Vinternal_error_checking = Fcons (intern ("malloc"),
2864                                     Vinternal_error_checking);
2865 #endif
2866 #ifdef ERROR_CHECK_GC
2867   Vinternal_error_checking = Fcons (intern ("gc"),
2868                                     Vinternal_error_checking);
2869 #endif
2870 #ifdef ERROR_CHECK_BUFPOS
2871   Vinternal_error_checking = Fcons (intern ("bufpos"),
2872                                     Vinternal_error_checking);
2873 #endif
2874   Vinternal_error_checking = Fpurecopy (Vinternal_error_checking);
2875
2876   DEFVAR_LISP ("path-separator", &Vpath_separator /*
2877 The directory separator in search paths, as a string.
2878 */ );
2879   {
2880     char c = SEPCHAR;
2881     Vpath_separator = make_string ((Bufbyte *)&c, 1);
2882   }
2883 }
2884
2885 void
2886 complex_vars_of_emacs (void)
2887 {
2888   /* This is all related to path searching. */
2889
2890   DEFVAR_LISP ("emacs-program-name", &Vemacs_program_name /*
2891 *Name of the Emacs variant.
2892 For example, this may be \"xemacs\" or \"infodock\".
2893 This is mainly meant for use in path searching.
2894 */ );
2895   Vemacs_program_name = build_string ((char *) PATH_PROGNAME);
2896
2897   DEFVAR_LISP ("emacs-program-version", &Vemacs_program_version /*
2898 *Version of the Emacs variant.
2899 This typically has the form XX.XX[-bXX].
2900 This is mainly meant for use in path searching.
2901 */ );
2902   Vemacs_program_version = build_string ((char *) PATH_VERSION);
2903
2904   DEFVAR_LISP ("exec-path", &Vexec_path /*
2905 *List of directories to search programs to run in subprocesses.
2906 Each element is a string (directory name) or nil (try default directory).
2907 */ );
2908   Vexec_path = Qnil;
2909
2910   DEFVAR_LISP ("exec-directory", &Vexec_directory /*
2911 *Directory of architecture-dependent files that come with XEmacs,
2912 especially executable programs intended for XEmacs to invoke.
2913 */ );
2914   Vexec_directory = Qnil;
2915
2916   DEFVAR_LISP ("configure-exec-directory", &Vconfigure_exec_directory /*
2917 For internal use by the build procedure only.
2918 configure's idea of what EXEC-DIRECTORY will be.
2919 */ );
2920 #ifdef PATH_EXEC
2921   Vconfigure_exec_directory = Ffile_name_as_directory
2922     (build_string ((char *) PATH_EXEC));
2923 #else
2924   Vconfigure_exec_directory = Qnil;
2925 #endif
2926
2927   DEFVAR_LISP ("lisp-directory", &Vlisp_directory /*
2928 *Directory of core Lisp files that come with XEmacs.
2929 */ );
2930   Vlisp_directory = Qnil;
2931
2932   DEFVAR_LISP ("configure-lisp-directory", &Vconfigure_lisp_directory /*
2933 For internal use by the build procedure only.
2934 configure's idea of what LISP-DIRECTORY will be.
2935 */ );
2936 #ifdef PATH_LOADSEARCH
2937   Vconfigure_lisp_directory = Ffile_name_as_directory
2938     (build_string ((char *) PATH_LOADSEARCH));
2939 #else
2940   Vconfigure_lisp_directory = Qnil;
2941 #endif
2942
2943   DEFVAR_LISP ("configure-package-path", &Vconfigure_package_path /*
2944 For internal use by the build procedure only.
2945 configure's idea of what the package path will be.
2946 */ );
2947 #ifdef PATH_PACKAGEPATH
2948   Vconfigure_package_path = decode_path (PATH_PACKAGEPATH);
2949 #else
2950   Vconfigure_package_path = Qnil;
2951 #endif
2952
2953   DEFVAR_LISP ("data-directory", &Vdata_directory /*
2954 *Directory of architecture-independent files that come with XEmacs,
2955 intended for XEmacs to use.
2956 Use of this variable in new code is almost never correct.  See the
2957 function `locate-data-directory' and the variable `data-directory-list'.
2958 */ );
2959   Vdata_directory = Qnil;
2960
2961   DEFVAR_LISP ("configure-data-directory", &Vconfigure_data_directory /*
2962 For internal use by the build procedure only.
2963 configure's idea of what DATA-DIRECTORY will be.
2964 */ );
2965 #ifdef PATH_DATA
2966   Vconfigure_data_directory = Ffile_name_as_directory
2967     (build_string ((char *) PATH_DATA));
2968 #else
2969   Vconfigure_data_directory = Qnil;
2970 #endif
2971
2972   DEFVAR_LISP ("data-directory-list", &Vdata_directory_list /*
2973 *List of directories of architecture-independent files that come with XEmacs
2974 or were installed as packages, and are intended for XEmacs to use.
2975 */ );
2976   Vdata_directory_list = Qnil;
2977
2978 #ifdef CLASH_DETECTION
2979   DEFVAR_LISP ("configure-lock-directory", &Vconfigure_lock_directory /*
2980 For internal use by the build procedure only.
2981 configure's idea of what LOCK-DIRECTORY will be.
2982 */ );
2983 #ifdef PATH_LOCK
2984   Vconfigure_lock_directory = Ffile_name_as_directory
2985     (build_string ((char *) PATH_LOCK));
2986 #else
2987   Vconfigure_lock_directory = Qnil;
2988 #endif
2989 #endif /* CLASH_DETECTION */
2990
2991   DEFVAR_LISP ("site-directory", &Vsite_directory /*
2992 *Directory of site-specific Lisp files that come with XEmacs.
2993 */ );
2994   Vsite_directory = Qnil;
2995
2996   DEFVAR_LISP ("configure-site-directory", &Vconfigure_site_directory /*
2997 For internal use by the build procedure only.
2998 configure's idea of what SITE-DIRECTORY will be.
2999 */ );
3000 #ifdef PATH_SITE
3001   Vconfigure_site_directory = Ffile_name_as_directory
3002     (build_string ((char *) PATH_SITE));
3003 #else
3004   Vconfigure_site_directory = Qnil;
3005 #endif
3006
3007   DEFVAR_LISP ("doc-directory", &Vdoc_directory /*
3008 *Directory containing the DOC file that comes with XEmacs.
3009 This is usually the same as exec-directory.
3010 */ );
3011   Vdoc_directory = Qnil;
3012
3013   DEFVAR_LISP ("configure-doc-directory", &Vconfigure_doc_directory /*
3014 For internal use by the build procedure only.
3015 configure's idea of what DOC-DIRECTORY will be.
3016 */ );
3017 #ifdef PATH_DOC
3018   Vconfigure_doc_directory = Ffile_name_as_directory
3019     (build_string ((char *) PATH_DOC));
3020 #else
3021   Vconfigure_doc_directory = Qnil;
3022 #endif
3023
3024   DEFVAR_LISP ("configure-exec-prefix-directory", &Vconfigure_exec_prefix_directory /*
3025 For internal use by the build procedure only.
3026 configure's idea of what EXEC-PREFIX-DIRECTORY will be.
3027 */ );
3028 #ifdef PATH_EXEC_PREFIX
3029   Vconfigure_exec_prefix_directory = Ffile_name_as_directory
3030     (build_string ((char *) PATH_EXEC_PREFIX));
3031 #else
3032   Vconfigure_exec_prefix_directory = Qnil;
3033 #endif
3034
3035   DEFVAR_LISP ("configure-prefix-directory", &Vconfigure_prefix_directory /*
3036 For internal use by the build procedure only.
3037 configure's idea of what PREFIX-DIRECTORY will be.
3038 */ );
3039 #ifdef PATH_PREFIX
3040   Vconfigure_prefix_directory = Ffile_name_as_directory
3041     (build_string ((char *) PATH_PREFIX));
3042 #else
3043   Vconfigure_prefix_directory = Qnil;
3044 #endif
3045
3046   DEFVAR_LISP ("configure-info-directory", &Vconfigure_info_directory /*
3047 For internal use by the build procedure only.
3048 This is the name of the directory in which the build procedure installed
3049 Emacs's info files; the default value for Info-default-directory-list
3050 includes this.
3051 */ );
3052 #ifdef PATH_INFO
3053   Vconfigure_info_directory =
3054     Ffile_name_as_directory (build_string (PATH_INFO));
3055 #else
3056   Vconfigure_info_directory = Qnil;
3057 #endif
3058
3059   DEFVAR_LISP ("configure-info-path", &Vconfigure_info_path /*
3060 The configured initial path for info documentation.
3061 */ );
3062 #ifdef PATH_INFOPATH
3063   Vconfigure_info_path = decode_path (PATH_INFOPATH);
3064 #else
3065   Vconfigure_info_path = Qnil;
3066 #endif
3067 }
3068
3069 #ifdef __sgi
3070 /* This is so tremendously ugly I'd puke. But then, it works.
3071  * The target is to override the static constructor from the
3072  * libiflPNG.so library which is maskerading as libz, and
3073  * cores on us when re-started from the dumped executable.
3074  * This will have to go for 21.1  -- OG.
3075  */
3076 void __sti__iflPNGFile_c___()
3077 {
3078 }
3079
3080 #endif