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