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