(gettext): Make sure this is always defined, even #if emacs.
[bpt/emacs.git] / src / emacs.c
1 /* Fully extensible Emacs, running on Unix, intended for GNU.
2 Copyright (C) 1985, 1986, 1987, 1993, 1994 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21 #include <signal.h>
22 #include <errno.h>
23
24 #include <config.h>
25 #include <stdio.h>
26
27 #include <sys/types.h>
28 #include <sys/file.h>
29
30 #ifdef VMS
31 #include <ssdef.h>
32 #endif
33
34 #ifdef BSD
35 #include <sys/ioctl.h>
36 #endif
37
38 #ifdef APOLLO
39 #ifndef APOLLO_SR10
40 #include <default_acl.h>
41 #endif
42 #endif
43
44 #include "lisp.h"
45 #include "commands.h"
46 #include "intervals.h"
47
48 #include "systty.h"
49 #include "syssignal.h"
50 #include "process.h"
51
52 #ifndef O_RDWR
53 #define O_RDWR 2
54 #endif
55
56 extern void malloc_warning ();
57 extern char *index ();
58 extern char *strerror ();
59
60 /* Command line args from shell, as list of strings */
61 Lisp_Object Vcommand_line_args;
62
63 /* The name under which Emacs was invoked, with any leading directory
64 names discarded. */
65 Lisp_Object Vinvocation_name;
66
67 /* The directory name from which Emacs was invoked. */
68 Lisp_Object Vinvocation_directory;
69
70 /* The directory name in which to find subdirs such as lisp and etc.
71 nil means get them only from PATH_LOADSEARCH. */
72 Lisp_Object Vinstallation_directory;
73
74 /* Hook run by `kill-emacs' before it does really anything. */
75 Lisp_Object Vkill_emacs_hook;
76
77 /* Set nonzero after Emacs has started up the first time.
78 Prevents reinitialization of the Lisp world and keymaps
79 on subsequent starts. */
80 int initialized;
81
82 /* Variable whose value is symbol giving operating system type. */
83 Lisp_Object Vsystem_type;
84
85 /* Variable whose value is string giving configuration built for. */
86 Lisp_Object Vsystem_configuration;
87
88 /* Variable whose value is string giving configuration options,
89 for use when reporting bugs. */
90 Lisp_Object Vsystem_configuration_options;
91
92 /* If non-zero, emacs should not attempt to use an window-specific code,
93 but instead should use the virtual terminal under which it was started */
94 int inhibit_window_system;
95
96 /* If nonzero, set Emacs to run at this priority. This is also used
97 in child_setup and sys_suspend to make sure subshells run at normal
98 priority; Those functions have their own extern declaration. */
99 int emacs_priority;
100
101 /* If non-zero a filter or a sentinel is running. Tested to save the match
102 data on the first attempt to change it inside asynchronous code. */
103 int running_asynch_code;
104
105 #ifdef BSD_PGRPS
106 /* See sysdep.c. */
107 extern int inherited_pgroup;
108 #endif
109
110 #ifdef HAVE_X_WINDOWS
111 /* If non-zero, -d was specified, meaning we're using some window system. */
112 int display_arg;
113 #endif
114
115 /* An address near the bottom of the stack.
116 Tells GC how to save a copy of the stack. */
117 char *stack_bottom;
118
119 #ifdef HAVE_X_WINDOWS
120 extern Lisp_Object Vwindow_system;
121 #endif /* HAVE_X_WINDOWS */
122
123 #ifdef USG_SHARED_LIBRARIES
124 /* If nonzero, this is the place to put the end of the writable segment
125 at startup. */
126
127 unsigned int bss_end = 0;
128 #endif
129
130 /* Nonzero means running Emacs without interactive terminal. */
131
132 int noninteractive;
133
134 /* Value of Lisp variable `noninteractive'.
135 Normally same as C variable `noninteractive'
136 but nothing terrible happens if user sets this one. */
137
138 int noninteractive1;
139
140 /* Save argv and argc. */
141 char **initial_argv;
142 int initial_argc;
143
144 static void sort_args ();
145 \f
146 /* Signal code for the fatal signal that was received */
147 int fatal_error_code;
148
149 /* Nonzero if handling a fatal error already */
150 int fatal_error_in_progress;
151
152 /* Handle bus errors, illegal instruction, etc. */
153 SIGTYPE
154 fatal_error_signal (sig)
155 int sig;
156 {
157 fatal_error_code = sig;
158 signal (sig, SIG_DFL);
159
160 /* If fatal error occurs in code below, avoid infinite recursion. */
161 if (! fatal_error_in_progress)
162 {
163 fatal_error_in_progress = 1;
164
165 shut_down_emacs (sig, 0, Qnil);
166 }
167
168 #ifdef VMS
169 LIB$STOP (SS$_ABORT);
170 #else
171 /* Signal the same code; this time it will really be fatal.
172 Remember that since we're in a signal handler, the signal we're
173 going to send is probably blocked, so we have to unblock it if we
174 want to really receive it. */
175 #ifndef MSDOS
176 sigunblock (sigmask (fatal_error_code));
177 #endif
178 kill (getpid (), fatal_error_code);
179 #endif /* not VMS */
180 }
181
182 #ifdef SIGDANGER
183
184 /* Handler for SIGDANGER. */
185 SIGTYPE
186 memory_warning_signal (sig)
187 int sig;
188 {
189 signal (sig, memory_warning_signal);
190
191 malloc_warning ("Operating system warns that virtual memory is running low.\n");
192
193 /* It might be unsafe to call do_auto_save now. */
194 force_auto_save_soon ();
195 }
196 #endif
197 \f
198 /* Code for dealing with Lisp access to the Unix command line */
199
200 static
201 init_cmdargs (argc, argv, skip_args)
202 int argc;
203 char **argv;
204 int skip_args;
205 {
206 register int i;
207 Lisp_Object name, dir;
208
209 initial_argv = argv;
210 initial_argc = argc;
211
212 Vinvocation_name = Ffile_name_nondirectory (build_string (argv[0]));
213 Vinvocation_directory = Ffile_name_directory (build_string (argv[0]));
214 /* If we got no directory in argv[0], search PATH to find where
215 Emacs actually came from. */
216 if (NILP (Vinvocation_directory))
217 {
218 Lisp_Object found;
219 int yes = openp (Vexec_path, Vinvocation_name,
220 EXEC_SUFFIXES, &found, 1);
221 if (yes == 1)
222 Vinvocation_directory = Ffile_name_directory (found);
223 }
224
225 Vinstallation_directory = Qnil;
226
227 if (!NILP (Vinvocation_directory))
228 {
229 dir = Vinvocation_directory;
230 name = Fexpand_file_name (Vinvocation_name, dir);
231 while (1)
232 {
233 Lisp_Object tem, lib_src_exists;
234 Lisp_Object etc_exists, info_exists;
235
236 /* See if dir contains subdirs for use by Emacs.
237 Check for the ones that would exist in a build directory,
238 not including lisp and info. */
239 tem = Fexpand_file_name (build_string ("lib-src"), dir);
240 lib_src_exists = Ffile_exists_p (tem);
241 if (!NILP (lib_src_exists))
242 {
243 tem = Fexpand_file_name (build_string ("etc"), dir);
244 etc_exists = Ffile_exists_p (tem);
245 if (!NILP (etc_exists))
246 {
247 Vinstallation_directory
248 = Ffile_name_as_directory (dir);
249 break;
250 }
251 }
252
253 /* See if dir's parent contains those subdirs. */
254 tem = Fexpand_file_name (build_string ("../lib-src"), dir);
255 lib_src_exists = Ffile_exists_p (tem);
256 if (!NILP (lib_src_exists))
257 {
258 tem = Fexpand_file_name (build_string ("../etc"), dir);
259 etc_exists = Ffile_exists_p (tem);
260 if (!NILP (etc_exists))
261 {
262 tem = Fexpand_file_name (build_string (".."), dir);
263 Vinstallation_directory
264 = Ffile_name_as_directory (tem);
265 break;
266 }
267 }
268
269 /* If the Emacs executable is actually a link,
270 next try the dir that the link points into. */
271 tem = Ffile_symlink_p (name);
272 if (!NILP (tem))
273 {
274 name = Fexpand_file_name (tem, dir);
275 dir = Ffile_name_directory (name);
276 }
277 else
278 break;
279 }
280 }
281
282 Vcommand_line_args = Qnil;
283
284 for (i = argc - 1; i >= 0; i--)
285 {
286 if (i == 0 || i > skip_args)
287 Vcommand_line_args
288 = Fcons (build_string (argv[i]), Vcommand_line_args);
289 }
290 }
291
292 DEFUN ("invocation-name", Finvocation_name, Sinvocation_name, 0, 0, 0,
293 "Return the program name that was used to run Emacs.\n\
294 Any directory names are omitted.")
295 ()
296 {
297 return Fcopy_sequence (Vinvocation_name);
298 }
299
300 DEFUN ("invocation-directory", Finvocation_directory, Sinvocation_directory,
301 0, 0, 0,
302 "Return the directory name in which the Emacs executable was located")
303 ()
304 {
305 return Fcopy_sequence (Vinvocation_directory);
306 }
307
308 \f
309 #ifdef VMS
310 #ifdef LINK_CRTL_SHARE
311 #ifdef SHAREABLE_LIB_BUG
312 extern noshare char **environ;
313 #endif /* SHAREABLE_LIB_BUG */
314 #endif /* LINK_CRTL_SHARE */
315 #endif /* VMS */
316
317 #ifndef ORDINARY_LINK
318 /* We don't include crtbegin.o and crtend.o in the link,
319 so these functions and variables might be missed.
320 Provide dummy definitions to avoid error.
321 (We don't have any real constructors or destructors.) */
322 #ifdef __GNUC__
323 #ifndef GCC_CTORS_IN_LIBC
324 __do_global_ctors ()
325 {}
326 __do_global_ctors_aux ()
327 {}
328 __do_global_dtors ()
329 {}
330 /* Linux has a bug in its library; avoid an error. */
331 #ifndef LINUX
332 char * __CTOR_LIST__[2] = { (char *) (-1), 0 };
333 #endif
334 char * __DTOR_LIST__[2] = { (char *) (-1), 0 };
335 #endif /* GCC_CTORS_IN_LIBC */
336 __main ()
337 {}
338 #endif /* __GNUC__ */
339 #endif /* ORDINARY_LINK */
340
341 /* Test whether the next argument in ARGV matches SSTR or a prefix of
342 LSTR (at least MINLEN characters). If so, then if VALPTR is non-null
343 (the argument is supposed to have a value) store in *VALPTR either
344 the next argument or the portion of this one after the equal sign.
345 ARGV is read starting at position *SKIPPTR; this index is advanced
346 by the number of arguments used.
347
348 Too bad we can't just use getopt for all of this, but we don't have
349 enough information to do it right. */
350
351 static int
352 argmatch (argv, sstr, lstr, minlen, valptr, skipptr)
353 char **argv;
354 char *sstr;
355 char *lstr;
356 int minlen;
357 char **valptr;
358 int *skipptr;
359 {
360 char *p;
361 int arglen;
362 char *arg = argv[*skipptr+1];
363 if (arg == NULL)
364 return 0;
365 if (strcmp (arg, sstr) == 0)
366 {
367 if (valptr != NULL)
368 {
369 *valptr = argv[*skipptr+2];
370 *skipptr += 2;
371 }
372 else
373 *skipptr += 1;
374 return 1;
375 }
376 arglen = (valptr != NULL && (p = index (arg, '=')) != NULL
377 ? p - arg : strlen (arg));
378 if (arglen < minlen || strncmp (arg, lstr, arglen) != 0)
379 return 0;
380 else if (valptr == NULL)
381 {
382 *skipptr += 1;
383 return 1;
384 }
385 else if (p != NULL)
386 {
387 *valptr = p+1;
388 *skipptr += 1;
389 return 1;
390 }
391 else if (argv[*skipptr+2] != NULL)
392 {
393 *valptr = argv[*skipptr+2];
394 *skipptr += 2;
395 return 1;
396 }
397 else
398 {
399 return 0;
400 }
401 }
402
403 /* ARGSUSED */
404 main (argc, argv, envp)
405 int argc;
406 char **argv;
407 char **envp;
408 {
409 char stack_bottom_variable;
410 int skip_args = 0;
411 extern int errno;
412 extern sys_nerr;
413
414 sort_args (argc, argv);
415
416 /* Map in shared memory, if we are using that. */
417 #ifdef HAVE_SHM
418 if (argmatch (argv, "-nl", "--no-shared-memory", 6, NULL, &skip_args))
419 {
420 map_in_data (0);
421 /* The shared memory was just restored, which clobbered this. */
422 skip_args = 1;
423 }
424 else
425 {
426 map_in_data (1);
427 /* The shared memory was just restored, which clobbered this. */
428 skip_args = 0;
429 }
430 #endif
431
432 #ifdef NeXT
433 extern int malloc_cookie;
434
435 /* This helps out unexnext.c. */
436 if (initialized)
437 if (malloc_jumpstart (malloc_cookie) != 0)
438 printf ("malloc jumpstart failed!\n");
439 #endif /* NeXT */
440
441 #ifdef VMS
442 /* If -map specified, map the data file in */
443 {
444 char *file;
445 if (argmatch (argv, "-map", "--map-data", 3, &mapin_file, &skip_args))
446 mapin_data (file);
447 }
448
449 #ifdef LINK_CRTL_SHARE
450 #ifdef SHAREABLE_LIB_BUG
451 /* Bletcherous shared libraries! */
452 if (!stdin)
453 stdin = fdopen (0, "r");
454 if (!stdout)
455 stdout = fdopen (1, "w");
456 if (!stderr)
457 stderr = fdopen (2, "w");
458 if (!environ)
459 environ = envp;
460 #endif /* SHAREABLE_LIB_BUG */
461 #endif /* LINK_CRTL_SHARE */
462 #endif /* VMS */
463
464 /* Record (approximately) where the stack begins. */
465 stack_bottom = &stack_bottom_variable;
466
467 #ifdef RUN_TIME_REMAP
468 if (initialized)
469 run_time_remap (argv[0]);
470 #endif
471
472 #ifdef USG_SHARED_LIBRARIES
473 if (bss_end)
474 brk (bss_end);
475 #endif
476
477 clearerr (stdin);
478
479 #ifdef APOLLO
480 #ifndef APOLLO_SR10
481 /* If USE_DOMAIN_ACLS environment variable exists,
482 use ACLs rather than UNIX modes. */
483 if (egetenv ("USE_DOMAIN_ACLS"))
484 default_acl (USE_DEFACL);
485 #endif
486 #endif /* APOLLO */
487
488 #ifndef SYSTEM_MALLOC
489 if (! initialized)
490 {
491 /* Arrange to get warning messages as memory fills up. */
492 memory_warnings (0, malloc_warning);
493
494 /* Arrange to disable interrupt input while malloc and friends are
495 running. */
496 uninterrupt_malloc ();
497 }
498 #endif /* not SYSTEM_MALLOC */
499
500 #ifdef MSDOS
501 /* We do all file input/output as binary files. When we need to translate
502 newlines, we do that manually. */
503 _fmode = O_BINARY;
504 (stdin)->_flag &= ~_IOTEXT;
505 (stdout)->_flag &= ~_IOTEXT;
506 (stderr)->_flag &= ~_IOTEXT;
507 #endif /* MSDOS */
508
509 #ifdef SET_EMACS_PRIORITY
510 if (emacs_priority)
511 nice (emacs_priority);
512 setuid (getuid ());
513 #endif /* SET_EMACS_PRIORITY */
514
515 #ifdef EXTRA_INITIALIZE
516 EXTRA_INITIALIZE;
517 #endif
518
519 inhibit_window_system = 0;
520
521 /* Handle the -t switch, which specifies filename to use as terminal */
522 {
523 char *term;
524 if (argmatch (argv, "-t", "--terminal", 4, &term, &skip_args))
525 {
526 int result;
527 close (0);
528 close (1);
529 result = open (term, O_RDWR, 2 );
530 if (result < 0)
531 {
532 char *errstring = strerror (errno);
533 fprintf (stderr, "emacs: %s: %s\n", term, errstring);
534 exit (1);
535 }
536 dup (0);
537 if (! isatty (0))
538 {
539 fprintf (stderr, "emacs: %s: not a tty\n", term);
540 exit (1);
541 }
542 fprintf (stderr, "Using %s\n", term);
543 #ifdef HAVE_X_WINDOWS
544 inhibit_window_system = 1; /* -t => -nw */
545 #endif
546 }
547 }
548 if (argmatch (argv, "-nw", "--no-windows", 6, NULL, &skip_args))
549 inhibit_window_system = 1;
550
551 /* Handle the -batch switch, which means don't do interactive display. */
552 noninteractive = 0;
553 if (argmatch (argv, "-batch", "--batch", 5, NULL, &skip_args))
554 noninteractive = 1;
555
556 /* Handle the --help option, which gives a usage message.. */
557 if (argmatch (argv, "-help", "--help", 3, NULL, &skip_args))
558 {
559 printf ("\
560 Usage: %s [-t term] [--terminal term] [-nw] [--no-windows] [--batch]\n\
561 [-q] [--no-init-file] [-u user] [--user user] [--debug-init]\n\
562 \(Arguments above this line must be first; those below may be in any order)\n\
563 [-f func] [--funcall func] [-l file] [--load file] [--insert file]\n\
564 file-to-visit [--kill]\n", argv[0]);
565 exit (0);
566 }
567
568 #ifdef HAVE_X_WINDOWS
569 /* Stupid kludge to catch command-line display spec. We can't
570 handle this argument entirely in window system dependent code
571 because we don't even know which window system dependent code
572 to run until we've recognized this argument. */
573 {
574 char *displayname;
575 int i;
576 int count_before = skip_args;
577
578 if (argmatch (argv, "-d", "--display", 3, &displayname, &skip_args))
579 display_arg = 1;
580 else if (argmatch (argv, "-display", 0, 3, &displayname, &skip_args))
581 display_arg = 1;
582
583 /* If we have the form --display=NAME,
584 convert it into -d name.
585 This requires inserting a new element into argv. */
586 if (displayname != 0 && skip_args - count_before == 1)
587 {
588 char **new = (char **) xmalloc (sizeof (char *) * (argc + 2));
589 int j;
590
591 for (j = 0; j < count_before + 1; j++)
592 new[j] = argv[j];
593 new[count_before + 1] = "-d";
594 new[count_before + 2] = displayname;
595 for (j = count_before + 2; j <argc; j++)
596 new[j + 1] = argv[j];
597 argv = new;
598 argc++;
599 }
600 else if (displayname != 0 && argv[count_before + 1][1] == '-')
601 argv[count_before] = "-d";
602
603 /* Don't actually discard this arg. */
604 skip_args = count_before;
605 }
606 #endif
607
608 if (! noninteractive)
609 {
610 #ifdef BSD_PGRPS
611 if (initialized)
612 {
613 inherited_pgroup = EMACS_GETPGRP (0);
614 setpgrp (0, getpid ());
615 }
616 #else
617 #if defined (USG5) && defined (INTERRUPT_INPUT)
618 setpgrp ();
619 #endif
620 #endif
621 }
622
623 #ifdef POSIX_SIGNALS
624 init_signals ();
625 #endif
626
627 if (
628 #ifndef CANNOT_DUMP
629 ! noninteractive || initialized
630 #else
631 1
632 #endif
633 )
634 {
635 /* Don't catch these signals in batch mode if not initialized.
636 On some machines, this sets static data that would make
637 signal fail to work right when the dumped Emacs is run. */
638 signal (SIGHUP, fatal_error_signal);
639 signal (SIGQUIT, fatal_error_signal);
640 signal (SIGILL, fatal_error_signal);
641 signal (SIGTRAP, fatal_error_signal);
642 #ifdef SIGIOT
643 /* This is missing on some systems - OS/2, for example. */
644 signal (SIGIOT, fatal_error_signal);
645 #endif
646 #ifdef SIGEMT
647 signal (SIGEMT, fatal_error_signal);
648 #endif
649 signal (SIGFPE, fatal_error_signal);
650 #ifdef SIGBUS
651 signal (SIGBUS, fatal_error_signal);
652 #endif
653 signal (SIGSEGV, fatal_error_signal);
654 #ifdef SIGSYS
655 signal (SIGSYS, fatal_error_signal);
656 #endif
657 signal (SIGTERM, fatal_error_signal);
658 #ifdef SIGXCPU
659 signal (SIGXCPU, fatal_error_signal);
660 #endif
661 #ifdef SIGXFSZ
662 signal (SIGXFSZ, fatal_error_signal);
663 #endif /* SIGXFSZ */
664
665 #ifdef SIGDANGER
666 /* This just means available memory is getting low. */
667 signal (SIGDANGER, memory_warning_signal);
668 #endif
669
670 #ifdef AIX
671 /* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU. */
672 signal (SIGXCPU, fatal_error_signal);
673 #ifndef _I386
674 signal (SIGIOINT, fatal_error_signal);
675 #endif
676 signal (SIGGRANT, fatal_error_signal);
677 signal (SIGRETRACT, fatal_error_signal);
678 signal (SIGSOUND, fatal_error_signal);
679 signal (SIGMSG, fatal_error_signal);
680 #endif /* AIX */
681 }
682
683 noninteractive1 = noninteractive;
684
685 /* Perform basic initializations (not merely interning symbols) */
686
687 if (!initialized)
688 {
689 init_alloc_once ();
690 init_obarray ();
691 init_eval_once ();
692 init_syntax_once (); /* Create standard syntax table. */
693 /* Must be done before init_buffer */
694 init_casetab_once ();
695 init_buffer_once (); /* Create buffer table and some buffers */
696 init_minibuf_once (); /* Create list of minibuffers */
697 /* Must precede init_window_once */
698 init_window_once (); /* Init the window system */
699 }
700
701 init_alloc ();
702 init_eval ();
703 init_data ();
704 running_asynch_code = 0;
705
706 #ifdef MSDOS
707 /* Call early 'cause init_environment needs it. */
708 init_dosfns ();
709 /* Set defaults for several environment variables. */
710 if (initialized) init_environment (argc, argv, skip_args);
711 #endif
712
713 /* egetenv is a pretty low-level facility, which may get called in
714 many circumstances; it seems flimsy to put off initializing it
715 until calling init_callproc. */
716 set_process_environment ();
717 /* AIX crashes are reported in system versions 3.2.3 and 3.2.4
718 if this is not done. Do it after set_process_environment so that we
719 don't pollute Vprocess_environment. */
720 #ifdef AIX
721 putenv ("LANG=C");
722 #endif
723
724 init_buffer (); /* Init default directory of main buffer */
725
726 init_callproc_1 (); /* Must precede init_cmdargs and init_sys_modes. */
727 init_cmdargs (argc, argv, skip_args); /* Must precede init_lread. */
728 init_callproc (); /* Must follow init_cmdargs but not init_sys_modes. */
729 init_lread ();
730
731 if (!noninteractive)
732 {
733 #ifdef VMS
734 init_vms_input ();/* init_display calls get_frame_size, that needs this */
735 #endif /* VMS */
736 init_display (); /* Determine terminal type. init_sys_modes uses results */
737 }
738 init_keyboard (); /* This too must precede init_sys_modes */
739 #ifdef VMS
740 init_vmsproc (); /* And this too. */
741 #endif /* VMS */
742 init_sys_modes (); /* Init system terminal modes (RAW or CBREAK, etc.) */
743 init_xdisp ();
744 init_macros ();
745 init_editfns ();
746 #ifdef LISP_FLOAT_TYPE
747 init_floatfns ();
748 #endif
749 #ifdef VMS
750 init_vmsfns ();
751 #endif /* VMS */
752 init_process ();
753 #ifdef CLASH_DETECTION
754 init_filelock ();
755 #endif /* CLASH_DETECTION */
756
757 /* Intern the names of all standard functions and variables; define standard keys */
758
759 if (!initialized)
760 {
761 /* The basic levels of Lisp must come first */
762 /* And data must come first of all
763 for the sake of symbols like error-message */
764 syms_of_data ();
765 syms_of_alloc ();
766 syms_of_lread ();
767 syms_of_print ();
768 syms_of_eval ();
769 syms_of_fns ();
770 syms_of_floatfns ();
771
772 syms_of_abbrev ();
773 syms_of_buffer ();
774 syms_of_bytecode ();
775 syms_of_callint ();
776 syms_of_casefiddle ();
777 syms_of_casetab ();
778 syms_of_callproc ();
779 syms_of_cmds ();
780 #ifndef NO_DIR_LIBRARY
781 syms_of_dired ();
782 #endif /* not NO_DIR_LIBRARY */
783 syms_of_display ();
784 syms_of_doc ();
785 syms_of_editfns ();
786 syms_of_emacs ();
787 syms_of_fileio ();
788 #ifdef CLASH_DETECTION
789 syms_of_filelock ();
790 #endif /* CLASH_DETECTION */
791 syms_of_indent ();
792 syms_of_keyboard ();
793 syms_of_keymap ();
794 syms_of_macros ();
795 syms_of_marker ();
796 syms_of_minibuf ();
797 syms_of_mocklisp ();
798 syms_of_process ();
799 syms_of_search ();
800 syms_of_frame ();
801 syms_of_syntax ();
802 syms_of_term ();
803 syms_of_undo ();
804
805 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
806 syms_of_textprop ();
807 #ifdef VMS
808 syms_of_vmsproc ();
809 #endif /* VMS */
810 syms_of_window ();
811 syms_of_xdisp ();
812 #ifdef HAVE_X_WINDOWS
813 syms_of_xterm ();
814 syms_of_xfns ();
815 syms_of_xfaces ();
816 #ifdef HAVE_X11
817 syms_of_xselect ();
818 #endif
819 #ifdef HAVE_X_MENU
820 syms_of_xmenu ();
821 #endif /* HAVE_X_MENU */
822 #endif /* HAVE_X_WINDOWS */
823
824 #if defined (MSDOS) && !defined (HAVE_X_WINDOWS)
825 syms_of_xfaces ();
826 syms_of_xmenu ();
827 #endif
828
829 #ifdef SYMS_SYSTEM
830 SYMS_SYSTEM;
831 #endif
832
833 #ifdef SYMS_MACHINE
834 SYMS_MACHINE;
835 #endif
836
837 keys_of_casefiddle ();
838 keys_of_cmds ();
839 keys_of_buffer ();
840 keys_of_keyboard ();
841 keys_of_keymap ();
842 keys_of_macros ();
843 keys_of_minibuf ();
844 keys_of_window ();
845 keys_of_frame ();
846 }
847
848 if (!initialized)
849 {
850 char *file;
851 /* Handle -l loadup-and-dump, args passed by Makefile. */
852 if (argmatch (argv, "-l", "--load", 3, &file, &skip_args))
853 Vtop_level = Fcons (intern ("load"),
854 Fcons (build_string (file), Qnil));
855 #ifdef CANNOT_DUMP
856 /* Unless next switch is -nl, load "loadup.el" first thing. */
857 if (!argmatch (argv, "-nl", "--no-loadup", 6, NULL, &skip_args))
858 Vtop_level = Fcons (intern ("load"),
859 Fcons (build_string ("loadup.el"), Qnil));
860 #endif /* CANNOT_DUMP */
861 }
862
863 initialized = 1;
864
865 #if defined (sun) || defined (LOCALTIME_CACHE)
866 /* sun's localtime has a bug. it caches the value of the time
867 zone rather than looking it up every time. Since localtime() is
868 called to bolt the undumping time into the undumped emacs, this
869 results in localtime ignoring the TZ environment variable.
870 This flushes the new TZ value into localtime. */
871 tzset ();
872 #endif /* defined (sun) || defined (LOCALTIME_CACHE) */
873
874 /* Handle the GNU standard option --version. */
875 if (argmatch (argv, "-version", "--version", 3, NULL, &skip_args))
876 {
877 Lisp_Object ver;
878 ver = call0 (intern ("emacs-version"));
879 if (STRINGP (ver))
880 printf ("%s\n", XSTRING (ver)->data);
881 exit (0);
882 }
883
884 /* Enter editor command loop. This never returns. */
885 Frecursive_edit ();
886 /* NOTREACHED */
887 }
888 \f
889 /* Sort the args so we can find the most important ones
890 at the beginning of argv. */
891
892 /* First, here's a table of all the standard options. */
893
894 struct standard_args
895 {
896 char *name;
897 char *longname;
898 int priority;
899 int nargs;
900 };
901
902 struct standard_args standard_args[] =
903 {
904 { "-nl", "--no-shared-memory", 100, 0 },
905 { "-map", "--map-data", 100, 0 },
906 { "-t", "--terminal", 90, 1 },
907 { "-d", "--display", 80, 1 },
908 { "-display", 0, 80, 1 },
909 { "-nw", "--no-windows", 70, 0 },
910 { "-batch", "--batch", 60, 0 },
911 { "-q", "--no-init-file", 50, 0 },
912 { "-no-init-file", 0, 50, 0 },
913 { "-no-site-file", "--no-site-file", 40, 0 },
914 { "-u", "--user", 30, 1 },
915 { "-user", 0, 30, 1 },
916 { "-debug-init", "--debug-init", 20, 0 },
917 { "-l", "--load", 10, 1 },
918 { "-load", 0, 10, 1 },
919 { "-f", "--funcall", 10, 1 },
920 { "-funcall", 0, 10, 1 },
921 { "-insert", "--insert", 10, 1 },
922 { "-bg", "--background-color", 10, 1 },
923 { "-background", 0, 10, 1 },
924 { "-fg", "--foreground-color", 10, 1 },
925 { "-foreground", 0, 10, 1 },
926 { "-bd", "--border-color", 10, 1 },
927 { "-bw", "--border-width", 10, 1 },
928 { "-ib", "--internal-border", 10, 1 },
929 { "-ms", "--mouse-color", 10, 1 },
930 { "-cr", "--cursor-color", 10, 1 },
931 { "-fn", "--font", 10, 1 },
932 { "-font", 0, 10, 1 },
933 { "-g", "--geometry", 10, 1 },
934 { "-geometry", 0, 10, 1 },
935 { "-T", "--title", 10, 1 },
936 { "-i", "--icon-type", 10, 1 },
937 { "-itype", 0, 10, 1 },
938 { "-name", "--name", 10, 1 },
939 { "-xrm", "--xrm", 10, 1 },
940 { "-r", "--reverse-video", 0, 0 },
941 { "-rv", 0, 0, 0 },
942 { "-reverse", 0, 0, 0 },
943 { "-vb", "--vertical-scroll-bars", 0, 0 },
944 { "-iconic", "--iconic", 0, 0 },
945 { "-kill", "--kill", 0, 0 },
946 };
947
948 /* Reorder the elements of ARGV (assumed to have ARGC elements)
949 so that the highest priority ones come first.
950 Do not change the order of elements of equal priority.
951 If an option takes an argument, keep it and its argument together. */
952
953 static void
954 sort_args (argc, argv)
955 int argc;
956 char **argv;
957 {
958 char **new = (char **) xmalloc (sizeof (char *) * argc);
959 /* For each element of argv,
960 the corresponding element of options is:
961 0 for an option that takes no arguments,
962 1 for an option that takes one argument, etc.
963 -1 for an ordinary non-option argument. */
964 char *options = (char *) xmalloc (argc);
965 int *priority = (int *) xmalloc (sizeof (int) * argc);
966 int to = 1;
967 int from;
968 int i;
969
970 /* Categorize all the options,
971 and figure out which argv elts are option arguments. */
972 for (from = 1; from < argc; from++)
973 {
974 options[from] = -1;
975 priority[from] = -1;
976 if (argv[from][0] == '-')
977 {
978 int match, thislen;
979 char *equals;
980
981 /* Look for a match with a known old-fashioned option. */
982 for (i = 0; i < sizeof (standard_args) / sizeof (standard_args[0]); i++)
983 if (!strcmp (argv[from], standard_args[i].name))
984 {
985 options[from] = standard_args[i].nargs;
986 priority[from] = standard_args[i].priority;
987 from += standard_args[i].nargs;
988 goto done;
989 }
990
991 /* Look for a match with a known long option.
992 MATCH is -1 if no match so far, -2 if two or more matches so far,
993 >= 0 (the table index of the match) if just one match so far. */
994 if (argv[from][1] == '-')
995 {
996 match = -1;
997 thislen = strlen (argv[from]);
998 equals = index (argv[from], '=');
999 if (equals != 0)
1000 thislen = equals - argv[from];
1001
1002 for (i = 0; i < sizeof (standard_args) / sizeof (standard_args[0]); i++)
1003 if (!strncmp (argv[from], standard_args[i].longname, thislen))
1004 {
1005 if (match == -1)
1006 match = i;
1007 else
1008 match = -2;
1009 }
1010
1011 /* If we found exactly one match, use that. */
1012 if (match >= 0)
1013 {
1014 options[from] = standard_args[match].nargs;
1015 priority[from] = standard_args[match].priority;
1016 /* If --OPTION=VALUE syntax is used,
1017 this option uses just one argv element. */
1018 if (equals != 0)
1019 options[from] = 0;
1020 from += options[from];
1021 }
1022 }
1023 done: ;
1024 }
1025 }
1026
1027 /* Copy the arguments, in order of decreasing priority, to NEW. */
1028 new[0] = argv[0];
1029 while (to < argc)
1030 {
1031 int best = -1;
1032 int best_priority = -2;
1033
1034 /* Find the highest priority remaining option.
1035 If several have equal priority, take the first of them. */
1036 for (from = 1; from < argc; from++)
1037 {
1038 if (argv[from] != 0 && priority[from] > best_priority)
1039 {
1040 best_priority = priority[from];
1041 best = from;
1042 }
1043 /* Skip option arguments--they are tied to the options. */
1044 if (options[from] > 0)
1045 from += options[from];
1046 }
1047
1048 if (best < 0)
1049 abort ();
1050
1051 /* Copy the highest priority remaining option, with its args, to NEW. */
1052 new[to++] = argv[best];
1053 for (i = 0; i < options[best]; i++)
1054 new[to++] = argv[best + i + 1];
1055
1056 /* Clear out this option in ARGV. */
1057 argv[best] = 0;
1058 for (i = 0; i < options[best]; i++)
1059 argv[best + i + 1] = 0;
1060 }
1061
1062 bcopy (new, argv, sizeof (char *) * (argc + 1));
1063 }
1064 \f
1065 DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 1, "P",
1066 "Exit the Emacs job and kill it.\n\
1067 If ARG is an integer, return ARG as the exit program code.\n\
1068 If ARG is a string, stuff it as keyboard input.\n\n\
1069 The value of `kill-emacs-hook', if not void,\n\
1070 is a list of functions (of no args),\n\
1071 all of which are called before Emacs is actually killed.")
1072 (arg)
1073 Lisp_Object arg;
1074 {
1075 Lisp_Object hook, hook1;
1076 int i;
1077 struct gcpro gcpro1;
1078
1079 GCPRO1 (arg);
1080
1081 if (feof (stdin))
1082 arg = Qt;
1083
1084 if (!NILP (Vrun_hooks) && !noninteractive)
1085 call1 (Vrun_hooks, intern ("kill-emacs-hook"));
1086
1087 UNGCPRO;
1088
1089 /* Is it really necessary to do this deassign
1090 when we are going to exit anyway? */
1091 /* #ifdef VMS
1092 stop_vms_input ();
1093 #endif */
1094
1095 shut_down_emacs (0, 0, STRINGP (arg) ? arg : Qnil);
1096
1097 exit (INTEGERP (arg) ? XINT (arg)
1098 #ifdef VMS
1099 : 1
1100 #else
1101 : 0
1102 #endif
1103 );
1104 /* NOTREACHED */
1105 }
1106
1107
1108 /* Perform an orderly shutdown of Emacs. Autosave any modified
1109 buffers, kill any child processes, clean up the terminal modes (if
1110 we're in the foreground), and other stuff like that. Don't perform
1111 any redisplay; this may be called when Emacs is shutting down in
1112 the background, or after its X connection has died.
1113
1114 If SIG is a signal number, print a message for it.
1115
1116 This is called by fatal signal handlers, X protocol error handlers,
1117 and Fkill_emacs. */
1118
1119 void
1120 shut_down_emacs (sig, no_x, stuff)
1121 int sig, no_x;
1122 Lisp_Object stuff;
1123 {
1124 /* Prevent running of hooks from now on. */
1125 Vrun_hooks = Qnil;
1126
1127 /* If we are controlling the terminal, reset terminal modes */
1128 #ifdef EMACS_HAVE_TTY_PGRP
1129 {
1130 int pgrp = EMACS_GETPGRP (0);
1131
1132 int tpgrp;
1133 if (EMACS_GET_TTY_PGRP (0, &tpgrp) != -1
1134 && tpgrp == pgrp)
1135 {
1136 fflush (stdout);
1137 reset_sys_modes ();
1138 if (sig && sig != SIGTERM)
1139 fprintf (stderr, "Fatal error (%d).", sig);
1140 }
1141 }
1142 #else
1143 fflush (stdout);
1144 reset_sys_modes ();
1145 #endif
1146
1147 stuff_buffered_input (stuff);
1148
1149 kill_buffer_processes (Qnil);
1150 Fdo_auto_save (Qt, Qnil);
1151
1152 #ifdef CLASH_DETECTION
1153 unlock_all_files ();
1154 #endif
1155
1156 #ifdef VMS
1157 kill_vms_processes ();
1158 #endif
1159
1160 #if 0 /* This triggers a bug in XCloseDisplay and is not needed. */
1161 #ifdef HAVE_X_WINDOWS
1162 /* It's not safe to call intern here. Maybe we are crashing. */
1163 if (!noninteractive && SYMBOLP (Vwindow_system)
1164 && XSYMBOL (Vwindow_system)->name->size == 1
1165 && XSYMBOL (Vwindow_system)->name->data[0] == 'x'
1166 && ! no_x)
1167 Fx_close_current_connection ();
1168 #endif /* HAVE_X_WINDOWS */
1169 #endif
1170
1171 #ifdef SIGIO
1172 /* There is a tendency for a SIGIO signal to arrive within exit,
1173 and cause a SIGHUP because the input descriptor is already closed. */
1174 unrequest_sigio ();
1175 signal (SIGIO, SIG_IGN);
1176 #endif
1177 }
1178
1179
1180 \f
1181 #ifndef CANNOT_DUMP
1182 /* Nothing like this can be implemented on an Apollo.
1183 What a loss! */
1184
1185 #ifdef HAVE_SHM
1186
1187 DEFUN ("dump-emacs-data", Fdump_emacs_data, Sdump_emacs_data, 1, 1, 0,
1188 "Dump current state of Emacs into data file FILENAME.\n\
1189 This function exists on systems that use HAVE_SHM.")
1190 (intoname)
1191 Lisp_Object intoname;
1192 {
1193 extern int my_edata;
1194 Lisp_Object tem;
1195
1196 CHECK_STRING (intoname, 0);
1197 intoname = Fexpand_file_name (intoname, Qnil);
1198
1199 tem = Vpurify_flag;
1200 Vpurify_flag = Qnil;
1201
1202 fflush (stdout);
1203 /* Tell malloc where start of impure now is */
1204 /* Also arrange for warnings when nearly out of space. */
1205 #ifndef SYSTEM_MALLOC
1206 memory_warnings (&my_edata, malloc_warning);
1207 #endif
1208 map_out_data (XSTRING (intoname)->data);
1209
1210 Vpurify_flag = tem;
1211
1212 return Qnil;
1213 }
1214
1215 #else /* not HAVE_SHM */
1216
1217 DEFUN ("dump-emacs", Fdump_emacs, Sdump_emacs, 2, 2, 0,
1218 "Dump current state of Emacs into executable file FILENAME.\n\
1219 Take symbols from SYMFILE (presumably the file you executed to run Emacs).\n\
1220 This is used in the file `loadup.el' when building Emacs.\n\
1221 \n\
1222 Bind `command-line-processed' to nil before dumping,\n\
1223 if you want the dumped Emacs to process its command line\n\
1224 and announce itself normally when it is run.")
1225 (intoname, symname)
1226 Lisp_Object intoname, symname;
1227 {
1228 extern int my_edata;
1229 Lisp_Object tem;
1230
1231 CHECK_STRING (intoname, 0);
1232 intoname = Fexpand_file_name (intoname, Qnil);
1233 if (!NILP (symname))
1234 {
1235 CHECK_STRING (symname, 0);
1236 if (XSTRING (symname)->size)
1237 symname = Fexpand_file_name (symname, Qnil);
1238 }
1239
1240 tem = Vpurify_flag;
1241 Vpurify_flag = Qnil;
1242
1243 fflush (stdout);
1244 #ifdef VMS
1245 mapout_data (XSTRING (intoname)->data);
1246 #else
1247 /* Tell malloc where start of impure now is */
1248 /* Also arrange for warnings when nearly out of space. */
1249 #ifndef SYSTEM_MALLOC
1250 #ifndef WINDOWSNT
1251 /* On Windows, this was done before dumping, and that once suffices.
1252 Meanwhile, my_edata is not valid on Windows. */
1253 memory_warnings (&my_edata, malloc_warning);
1254 #endif /* not WINDOWSNT */
1255 #endif
1256 unexec (XSTRING (intoname)->data,
1257 !NILP (symname) ? XSTRING (symname)->data : 0, &my_edata, 0, 0);
1258 #endif /* not VMS */
1259
1260 Vpurify_flag = tem;
1261
1262 return Qnil;
1263 }
1264
1265 #endif /* not HAVE_SHM */
1266
1267 #endif /* not CANNOT_DUMP */
1268 \f
1269 #ifndef SEPCHAR
1270 #define SEPCHAR ':'
1271 #endif
1272
1273 Lisp_Object
1274 decode_env_path (evarname, defalt)
1275 char *evarname, *defalt;
1276 {
1277 register char *path, *p;
1278
1279 Lisp_Object lpath;
1280
1281 /* It's okay to use getenv here, because this function is only used
1282 to initialize variables when Emacs starts up, and isn't called
1283 after that. */
1284 if (evarname != 0)
1285 path = (char *) getenv (evarname);
1286 else
1287 path = 0;
1288 if (!path)
1289 path = defalt;
1290 lpath = Qnil;
1291 while (1)
1292 {
1293 p = index (path, SEPCHAR);
1294 if (!p) p = path + strlen (path);
1295 lpath = Fcons (p - path ? make_string (path, p - path) : Qnil,
1296 lpath);
1297 if (*p)
1298 path = p + 1;
1299 else
1300 break;
1301 }
1302 return Fnreverse (lpath);
1303 }
1304
1305 syms_of_emacs ()
1306 {
1307 #ifndef CANNOT_DUMP
1308 #ifdef HAVE_SHM
1309 defsubr (&Sdump_emacs_data);
1310 #else
1311 defsubr (&Sdump_emacs);
1312 #endif
1313 #endif
1314
1315 defsubr (&Skill_emacs);
1316
1317 defsubr (&Sinvocation_name);
1318 defsubr (&Sinvocation_directory);
1319
1320 DEFVAR_LISP ("command-line-args", &Vcommand_line_args,
1321 "Args passed by shell to Emacs, as a list of strings.");
1322
1323 DEFVAR_LISP ("system-type", &Vsystem_type,
1324 "Value is symbol indicating type of operating system you are using.");
1325 Vsystem_type = intern (SYSTEM_TYPE);
1326
1327 DEFVAR_LISP ("system-configuration", &Vsystem_configuration,
1328 "Value is string indicating configuration Emacs was built for.");
1329 Vsystem_configuration = build_string (EMACS_CONFIGURATION);
1330
1331 DEFVAR_LISP ("system-configuration-options", &Vsystem_configuration_options,
1332 "String containing the configuration options Emacs was built with.");
1333 Vsystem_configuration_options = build_string (EMACS_CONFIG_OPTIONS);
1334
1335 DEFVAR_BOOL ("noninteractive", &noninteractive1,
1336 "Non-nil means Emacs is running without interactive terminal.");
1337
1338 DEFVAR_LISP ("kill-emacs-hook", &Vkill_emacs_hook,
1339 "Hook to be run whenever kill-emacs is called.\n\
1340 Since kill-emacs may be invoked when the terminal is disconnected (or\n\
1341 in other similar situations), functions placed on this hook should not\n\
1342 expect to be able to interact with the user.");
1343 Vkill_emacs_hook = Qnil;
1344
1345 DEFVAR_INT ("emacs-priority", &emacs_priority,
1346 "Priority for Emacs to run at.\n\
1347 This value is effective only if set before Emacs is dumped,\n\
1348 and only if the Emacs executable is installed with setuid to permit\n\
1349 it to change priority. (Emacs sets its uid back to the real uid.)\n\
1350 Currently, you need to define SET_EMACS_PRIORITY in `config.h'\n\
1351 before you compile Emacs, to enable the code for this feature.");
1352 emacs_priority = 0;
1353
1354 DEFVAR_LISP ("invocation-name", &Vinvocation_name,
1355 "The program name that was used to run Emacs.\n\
1356 Any directory names are omitted.");
1357
1358 DEFVAR_LISP ("invocation-directory", &Vinvocation_directory,
1359 "The directory in which the Emacs executable was found, to run it.\n\
1360 The value is nil if that directory's name is not known.");
1361
1362 DEFVAR_LISP ("installation-directory", &Vinstallation_directory,
1363 "A directory within which to look for the `lib-src' and `etc' directories.\n\
1364 This is non-nil when we can't find those directories in their standard\n\
1365 installed locations, but we can find them\n\
1366 near where the Emacs executable was found.");
1367 Vinstallation_directory = Qnil;
1368 }