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