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