/* Fully extensible Emacs, running on Unix, intended for GNU.
- Copyright (C) 1985, 86, 87, 93, 94, 95 Free Software Foundation, Inc.
+ Copyright (C) 1985,86,87,93,94,95,97,98,1999 Free Software Foundation, Inc.
This file is part of GNU Emacs.
Boston, MA 02111-1307, USA. */
+#include <config.h>
#include <signal.h>
#include <errno.h>
-
-#include <config.h>
#include <stdio.h>
#include <sys/types.h>
#include <ssdef.h>
#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
#ifdef BSD_SYSTEM
#include <sys/ioctl.h>
#endif
#include "lisp.h"
#include "commands.h"
#include "intervals.h"
+#include "buffer.h"
#include "systty.h"
#include "blockinput.h"
#include "syssignal.h"
#include "process.h"
+#include "termhooks.h"
+#include "keyboard.h"
+
+#ifdef HAVE_SETLOCALE
+#include <locale.h>
+#endif
#ifdef HAVE_SETRLIMIT
#include <sys/time.h>
#define O_RDWR 2
#endif
-extern void malloc_warning ();
-extern void set_time_zone_rule ();
-extern char *index ();
-extern char *strerror ();
+#ifdef HAVE_SETPGID
+#if !defined (USG) || defined (BSD_PGRPS)
+#undef setpgrp
+#define setpgrp setpgid
+#endif
+#endif
+
+extern void malloc_warning P_ ((char *));
+extern void set_time_zone_rule P_ ((char *));
+#ifdef HAVE_INDEX
+extern char *index P_ ((const char *, int));
+#endif
+
+/* Make these values available in GDB, which doesn't see macros. */
+
+EMACS_INT gdb_valbits = VALBITS;
+EMACS_INT gdb_gctypebits = GCTYPEBITS;
+EMACS_INT gdb_emacs_intbits = sizeof (EMACS_INT) * BITS_PER_CHAR;
+#ifdef DATA_SEG_BITS
+EMACS_INT gdb_data_seg_bits = DATA_SEG_BITS;
+#else
+EMACS_INT gdb_data_seg_bits = 0;
+#endif
+EMACS_INT PVEC_FLAG = PSEUDOVECTOR_FLAG;
/* Command line args from shell, as list of strings */
Lisp_Object Vcommand_line_args;
/* Hook run by `kill-emacs' before it does really anything. */
Lisp_Object Vkill_emacs_hook;
+#ifdef SIGUSR1
+/* Hooks for signal USR1 and USR2 handing */
+Lisp_Object Vsignal_USR1_hook;
+#ifdef SIGUSR2
+Lisp_Object Vsignal_USR2_hook;
+#endif
+#endif
+
+/* Search path separator. */
+Lisp_Object Vpath_separator;
+
/* Set nonzero after Emacs has started up the first time.
Prevents reinitialization of the Lisp world and keymaps
on subsequent starts. */
extern void *malloc_get_state ();
/* From glibc, a routine that overwrites the malloc internal state. */
extern void malloc_set_state ();
+/* Non-zero if the MALLOC_CHECK_ enviroment variable was set while
+ dumping. Used to work around a bug in glibc's malloc. */
+int malloc_using_checking;
#endif
/* Variable whose value is symbol giving operating system type. */
Lisp_Object Qfile_name_handler_alist;
+/* Current and previous system locales for messages and time. */
+Lisp_Object Vsystem_messages_locale;
+Lisp_Object Vprevious_system_messages_locale;
+Lisp_Object Vsystem_time_locale;
+Lisp_Object Vprevious_system_time_locale;
+
/* If non-zero, emacs should not attempt to use an window-specific code,
but instead should use the virtual terminal under which it was started */
int inhibit_window_system;
int initial_argc;
static void sort_args ();
+void syms_of_emacs ();
+
+#define USAGE1 "\
+Usage: %s [OPTION-OR-FILENAME]...\n\
+\n\
+Run Emacs, the extensible, customizable, self-documenting real-time\n\
+display editor. The recommended way to start Emacs for normal editing\n\
+is with no options at all.\n\
+\n\
+Run M-x info RET m emacs RET m command arguments RET inside Emacs to\n\
+read the main documentation for these command-line arguments.\n\
+\n\
+Initialization options:\n\
+\n\
+--batch do not do interactive display; implies -q\n\
+--debug-init enable Emacs Lisp debugger during init file\n\
+--help display this help message and exit\n\
+--multibyte, --no-unibyte run Emacs in multibyte mode\n\
+--no-init-file, -q load neither ~/.emacs nor default.el\n\
+--no-shared-memory, -nl do not use shared memory\n\
+--no-site-file do not load site-start.el\n\
+--no-windows, -nw don't communicate with X, ignoring $DISPLAY\n\
+--terminal, -t DEVICE use DEVICE for terminal I/O\n\
+--unibyte, --no-multibyte run Emacs in unibyte mode\n\
+--user, -u USER load ~USER/.emacs instead of your own\n\
+--version display version information and exit\n\
+\n\
+Action options:\n\
+\n\
+FILE visit FILE using find-file\n\
++LINENUM FILE visit FILE using find-file, then go to line LINENUM\n\
+--directory, -L DIR add DIR to variable load-path\n\
+--eval EXPR evaluate Emacs Lisp expression EXPR\n\
+--execute EXPR evaluate Emacs Lisp expression EXPR\n\
+--find-file FILE visit FILE\n\
+--funcall, -f FUNC call Emacs function FUNC with no arguments\n\
+--insert FILE insert contents of FILE into current buffer\n\
+--kill exit without asking for confirmation\n\
+--load, -l FILE load FILE of Emacs Lisp code using the load function\n\
+--visit FILE visit FILE\n\
+\n"
+
+#define USAGE2 "\
+Display options:\n\
+\n\
+--background-color, -bg COLOR window background color\n\
+--border-color, -bd COLOR main border color\n\
+--border-width, -bw WIDTH width of main border\n\
+--cursor-color, -cr COLOR color of the Emacs cursor indicating point\n\
+--display, -d DISPLAY use X server DISPLAY\n\
+--font, -fn FONT default font; must be fixed-widthp\n\
+--foreground-color, -fg COLOR window foreground color\n\
+--geometry, -g GEOMETRY window geometry\n\
+--iconic start Emacs in iconified state\n\
+--icon-type, -i use picture of gnu for Emacs icon\n\
+--internal-border, -ib WIDTH width between text and main border\n\
+--line-spacing, -lsp PIXELS additional space to put between lines\n\
+--mouse-color, -ms COLOR mouse cursor color in Emacs window\n\
+--name NAME title of main Emacs window\n\
+--reverse-video, -r, -rv switch foreground and background\n\
+--title, -T, -wn, TITLE title for Emacs windows\n\
+--vertical-scroll-bars, -vb enable vertical scroll bars\n\
+--xrm XRESOURCES set additional X resources\n\
+\n\
+You can generally also specify long option names with a single -; for\n\
+example, -batch as well as --batch. You can use any unambiguous\n\
+abbreviation for a --option.\n\
+\n\
+Various environment variables and window system resources also affect\n\
+Emacs' operation. See the main documentation.\n\
+\n\
+Report bugs to bug-gnu-emacs@gnu.org. First, please see the Bugs\n\
+section of the Emacs manual or the file BUGS.\n"
+
\f
/* Signal code for the fatal signal that was received */
int fatal_error_code;
/* Nonzero if handling a fatal error already */
int fatal_error_in_progress;
-/* Handle bus errors, illegal instruction, etc. */
+#ifdef SIGUSR1
+SIGTYPE
+handle_USR1_signal (sig)
+ int sig;
+{
+ struct input_event buf;
+
+ bzero (&buf, sizeof buf);
+ buf.kind = USER_SIGNAL_EVENT;
+ buf.frame_or_window = selected_frame;
+
+ kbd_buffer_store_event (&buf);
+}
+#endif /* SIGUSR1 */
+
+#ifdef SIGUSR2
+SIGTYPE
+handle_USR2_signal (sig)
+ int sig;
+{
+ struct input_event buf;
+
+ bzero (&buf, sizeof buf);
+ buf.kind = USER_SIGNAL_EVENT;
+ buf.code = 1;
+ buf.frame_or_window = selected_frame;
+
+ kbd_buffer_store_event (&buf);
+}
+#endif /* SIGUSR2 */
+
+/* Handle bus errors, invalid instruction, etc. */
SIGTYPE
fatal_error_signal (sig)
int sig;
force_auto_save_soon ();
}
#endif
+
+/* We define abort, rather than using it from the library,
+ so that GDB can return from a breakpoint here.
+ MSDOS has its own definition on msdos.c */
+
+#if ! defined (DOS_NT) && ! defined (NO_ABORT)
+
+#ifndef ABORT_RETURN_TYPE
+#define ABORT_RETURN_TYPE void
+#endif
+
+ABORT_RETURN_TYPE
+abort ()
+{
+ kill (getpid (), SIGABRT);
+ /* This shouldn't be executed, but it prevents a warning. */
+ exit (1);
+}
+#endif
+
\f
/* Code for dealing with Lisp access to the Unix command line */
-static
+static void
init_cmdargs (argc, argv, skip_args)
int argc;
char **argv;
(We don't have any real constructors or destructors.) */
#ifdef __GNUC__
#ifndef GCC_CTORS_IN_LIBC
-__do_global_ctors ()
+void __do_global_ctors ()
{}
-__do_global_ctors_aux ()
+void __do_global_ctors_aux ()
{}
-__do_global_dtors ()
+void __do_global_dtors ()
{}
/* Linux has a bug in its library; avoid an error. */
#ifndef LINUX
#endif
char * __DTOR_LIST__[2] = { (char *) (-1), 0 };
#endif /* GCC_CTORS_IN_LIBC */
-__main ()
+void __main ()
{}
#endif /* __GNUC__ */
#endif /* ORDINARY_LINK */
char **valptr;
int *skipptr;
{
- char *p;
+ char *p = NULL;
int arglen;
char *arg;
}
}
+#ifdef DOUG_LEA_MALLOC
+
+/* malloc can be invoked even before main (e.g. by the dynamic
+ linker), so the dumped malloc state must be restored as early as
+ possible using this special hook. */
+
+static void
+malloc_initialize_hook ()
+{
+#ifndef USE_CRT_DLL
+ extern char **environ;
+#endif
+
+ if (initialized)
+ {
+ if (!malloc_using_checking)
+ /* Work around a bug in glibc's malloc. MALLOC_CHECK_ must be
+ ignored if the heap to be restored was constructed without
+ malloc checking. Can't use unsetenv, since that calls malloc. */
+ {
+ char **p;
+
+ for (p = environ; *p; p++)
+ if (strncmp (*p, "MALLOC_CHECK_=", 14) == 0)
+ {
+ do
+ *p = p[1];
+ while (*++p);
+ break;
+ }
+ }
+
+ malloc_set_state (malloc_state_ptr);
+ free (malloc_state_ptr);
+ }
+ else
+ malloc_using_checking = getenv ("MALLOC_CHECK_") != NULL;
+}
+
+void (*__malloc_initialize_hook) () = malloc_initialize_hook;
+
+#endif /* DOUG_LEA_MALLOC */
+
/* ARGSUSED */
+int
main (argc, argv, envp)
int argc;
char **argv;
char **envp;
{
+#if GC_MARK_STACK
+ Lisp_Object dummy;
+#endif
char stack_bottom_variable;
+ int do_initial_setlocale;
int skip_args = 0;
+#ifndef USE_CRT_DLL
extern int errno;
- extern sys_nerr;
+ extern int sys_nerr;
+#endif
#ifdef HAVE_SETRLIMIT
struct rlimit rlim;
#endif
+ int no_loadup = 0;
+
+#if GC_MARK_STACK
+ extern Lisp_Object *stack_base;
+ stack_base = &dummy;
+#endif
#ifdef LINUX_SBRK_BUG
__sbrk (1);
#endif
-#ifdef DOUG_LEA_MALLOC
+#ifdef RUN_TIME_REMAP
if (initialized)
- {
- malloc_set_state (malloc_state_ptr);
- free (malloc_state_ptr);
- r_alloc_reinit ();
- }
+ run_time_remap (argv[0]);
#endif
sort_args (argc, argv);
+ argc = 0;
+ while (argv[argc]) argc++;
- if (argmatch (argv, argc, "-version", "--version", 3, NULL, &skip_args))
+ if (argmatch (argv, argc, "-version", "--version", 3, NULL, &skip_args)
+ /* We don't know the version number unless this is a dumped Emacs.
+ So ignore --version otherwise. */
+ && initialized)
{
Lisp_Object tem;
tem = Fsymbol_value (intern ("emacs-version"));
else
{
printf ("GNU Emacs %s\n", XSTRING (tem)->data);
- printf ("Copyright (C) 1996 Free Software Foundation, Inc.\n");
+ printf ("Copyright (C) 1999 Free Software Foundation, Inc.\n");
printf ("GNU Emacs comes with ABSOLUTELY NO WARRANTY.\n");
printf ("You may redistribute copies of Emacs\n");
printf ("under the terms of the GNU General Public License.\n");
printf ("For more information about these matters, ");
- printf ("see the files named COPYING.\n");
+ printf ("see the file named COPYING.\n");
exit (0);
}
}
#endif /* VMS */
#if defined (HAVE_SETRLIMIT) && defined (RLIMIT_STACK)
- /* Extend the stack space available. */
- if (!getrlimit (RLIMIT_STACK, &rlim))
+ /* Extend the stack space available.
+ Don't do that if dumping, since some systems (e.g. DJGPP)
+ might define a smaller stack limit at that time. */
+ if (1
+#ifndef CANNOT_DUMP
+ && (!noninteractive || initialized)
+#endif
+ && !getrlimit (RLIMIT_STACK, &rlim))
{
long newlim;
- /* Approximate the amount regex.c needs, plus some more. */
- newlim = 800000 * sizeof (char *);
+ extern int re_max_failures;
+ /* Approximate the amount regex.c needs per unit of re_max_failures. */
+ int ratio = 20 * sizeof (char *);
+ /* Then add 33% to cover the size of the smaller stacks that regex.c
+ successively allocates and discards, on its way to the maximum. */
+ ratio += ratio / 3;
+ /* Add in some extra to cover
+ what we're likely to use for other reasons. */
+ newlim = re_max_failures * ratio + 200000;
#ifdef __NetBSD__
/* NetBSD (at least NetBSD 1.2G and former) has a bug in its
stack allocation routine for new process that the allocation
newlim = (newlim + getpagesize () - 1) / getpagesize () * getpagesize();
#endif
if (newlim > rlim.rlim_max)
- newlim = rlim.rlim_max;
+ {
+ newlim = rlim.rlim_max;
+ /* Don't let regex.c overflow the stack we have. */
+ re_max_failures = (newlim - 200000) / ratio;
+ }
if (rlim.rlim_cur < newlim)
rlim.rlim_cur = newlim;
/* Record (approximately) where the stack begins. */
stack_bottom = &stack_bottom_variable;
-#ifdef RUN_TIME_REMAP
- if (initialized)
- run_time_remap (argv[0]);
-#endif
-
#ifdef USG_SHARED_LIBRARIES
if (bss_end)
brk ((void *)bss_end);
clearerr (stdin);
#ifndef SYSTEM_MALLOC
- if (! initialized)
- {
- /* Arrange to get warning messages as memory fills up. */
- memory_warnings (0, malloc_warning);
+ /* Arrange to get warning messages as memory fills up. */
+ memory_warnings (0, malloc_warning);
- /* Arrange to disable interrupt input while malloc and friends are
- running. */
- uninterrupt_malloc ();
- }
+ /* Call malloc at least once, to run the initial __malloc_hook.
+ Also call realloc and free for consistency. */
+ free (realloc (malloc (4), 4));
+
+ /* Arrange to disable interrupt input inside malloc etc. */
+ uninterrupt_malloc ();
#endif /* not SYSTEM_MALLOC */
#ifdef MSDOS
setuid (getuid ());
#endif /* SET_EMACS_PRIORITY */
+ /* Skip initial setlocale if LC_ALL is "C", as it's not needed in that case.
+ The build procedure uses this while dumping, to ensure that the
+ dumped Emacs does not have its system locale tables initialized,
+ as that might cause screwups when the dumped Emacs starts up. */
+ {
+ char *lc_all = getenv ("LC_ALL");
+ do_initial_setlocale = ! lc_all || strcmp (lc_all, "C");
+ }
+
+ /* Set locale now, so that initial error messages are localized properly.
+ fixup_locale must wait until later, since it builds strings. */
+ if (do_initial_setlocale)
+ setlocale (LC_ALL, "");
+
#ifdef EXTRA_INITIALIZE
EXTRA_INITIALIZE;
#endif
inhibit_window_system = 0;
/* Handle the -t switch, which specifies filename to use as terminal */
- {
- char *term;
- if (argmatch (argv, argc, "-t", "--terminal", 4, &term, &skip_args))
- {
- int result;
- close (0);
- close (1);
- result = open (term, O_RDWR, 2 );
- if (result < 0)
- {
- char *errstring = strerror (errno);
- fprintf (stderr, "emacs: %s: %s\n", term, errstring);
- exit (1);
- }
- dup (0);
- if (! isatty (0))
- {
- fprintf (stderr, "emacs: %s: not a tty\n", term);
- exit (1);
- }
- fprintf (stderr, "Using %s\n", term);
+ while (1)
+ {
+ char *term;
+ if (argmatch (argv, argc, "-t", "--terminal", 4, &term, &skip_args))
+ {
+ int result;
+ emacs_close (0);
+ emacs_close (1);
+ result = emacs_open (term, O_RDWR, 0);
+ if (result < 0)
+ {
+ char *errstring = strerror (errno);
+ fprintf (stderr, "emacs: %s: %s\n", term, errstring);
+ exit (1);
+ }
+ dup (0);
+ if (! isatty (0))
+ {
+ fprintf (stderr, "emacs: %s: not a tty\n", term);
+ exit (1);
+ }
+ fprintf (stderr, "Using %s\n", term);
#ifdef HAVE_WINDOW_SYSTEM
- inhibit_window_system = 1; /* -t => -nw */
+ inhibit_window_system = 1; /* -t => -nw */
#endif
- }
- }
+ }
+ else
+ break;
+ }
+
if (argmatch (argv, argc, "-nw", "--no-windows", 6, NULL, &skip_args))
inhibit_window_system = 1;
/* Handle the --help option, which gives a usage message.. */
if (argmatch (argv, argc, "-help", "--help", 3, NULL, &skip_args))
{
- printf ("\
-Usage: %s [-t term] [--terminal term] [-nw] [--no-windows] [--batch]\n\
- [-q] [--no-init-file] [-u user] [--user user] [--debug-init]\n\
- [--version] [--no-site-file]\n\
- [-f func] [--funcall func] [-l file] [--load file] [--insert file]\n\
- [+linenum] file-to-visit [--kill]\n\
-Report bugs to bug-gnu-emacs@prep.ai.mit.edu. First, please see\n\
-the Bugs section of the Emacs manual or the file BUGS.\n", argv[0]);
+ printf (USAGE1, argv[0]);
+ printf (USAGE2);
exit (0);
}
-#ifdef HAVE_X_WINDOWS
- /* Stupid kludge to catch command-line display spec. We can't
- handle this argument entirely in window system dependent code
- because we don't even know which window system dependent code
- to run until we've recognized this argument. */
- {
- char *displayname = 0;
- int i;
- int count_before = skip_args;
-
- if (argmatch (argv, argc, "-d", "--display", 3, &displayname, &skip_args))
- display_arg = 1;
- else if (argmatch (argv, argc, "-display", 0, 3, &displayname, &skip_args))
- display_arg = 1;
-
- /* If we have the form --display=NAME,
- convert it into -d name.
- This requires inserting a new element into argv. */
- if (displayname != 0 && skip_args - count_before == 1)
- {
- char **new = (char **) xmalloc (sizeof (char *) * (argc + 2));
- int j;
-
- for (j = 0; j < count_before + 1; j++)
- new[j] = argv[j];
- new[count_before + 1] = "-d";
- new[count_before + 2] = displayname;
- for (j = count_before + 2; j <argc; j++)
- new[j + 1] = argv[j];
- argv = new;
- argc++;
- }
- /* Change --display to -d, when its arg is separate. */
- else if (displayname != 0 && skip_args > count_before
- && argv[count_before + 1][1] == '-')
- argv[count_before + 1] = "-d";
-
- /* Don't actually discard this arg. */
- skip_args = count_before;
- }
-#endif
-
if (! noninteractive)
{
#ifdef BSD_PGRPS
#endif
}
-#ifdef POSIX_SIGNALS
init_signals ();
-#endif
/* Don't catch SIGHUP if dumping. */
if (1
signal (SIGQUIT, fatal_error_signal);
signal (SIGILL, fatal_error_signal);
signal (SIGTRAP, fatal_error_signal);
+#ifdef SIGUSR1
+ signal (SIGUSR1, handle_USR1_signal);
+#ifdef SIGUSR2
+ signal (SIGUSR2, handle_USR2_signal);
+#endif
+#endif
#ifdef SIGABRT
signal (SIGABRT, fatal_error_signal);
#endif
init_casetab_once ();
init_buffer_once (); /* Create buffer table and some buffers */
init_minibuf_once (); /* Create list of minibuffers */
- /* Must precede init_window_once */
+ /* Must precede init_window_once */
+
+ /* Call syms_of_xfaces before init_window_once because that
+ function creates Vterminal_frame. Termcap frames now use
+ faces, and the face implementation uses some symbols as
+ face names. */
+ syms_of_xfaces ();
+ /* Call syms_of_keyboard before init_window_once because
+ keyboard sets up symbols that include some face names that
+ the X support will want to use. This can happen when
+ CANNOT_DUMP is defined. */
+ syms_of_keyboard ();
+
+#ifdef macintosh
+ /* init_window_once calls make_terminal_frame which on Mac OS
+ creates a full-fledge output_mac type frame. This does not
+ work correctly before syms_of_textprop, syms_of_macfns,
+ syms_of_ccl, syms_of_fontset, syms_of_xterm, syms_of_search,
+ syms_of_frame, x_term_init, and init_keyboard have already
+ been called. */
+ syms_of_textprop ();
+ syms_of_macfns ();
+ syms_of_ccl ();
+ syms_of_fontset ();
+ syms_of_macterm ();
+ syms_of_macmenu ();
+ syms_of_data ();
+ syms_of_search ();
+ syms_of_frame ();
+
+ x_term_init ();
+ init_keyboard ();
+#endif
+
init_window_once (); /* Init the window system */
+ init_fileio_once (); /* Must precede any path manipulation. */
}
init_alloc ();
+
+ if (do_initial_setlocale)
+ {
+ fixup_locale ();
+ Vsystem_messages_locale = Vprevious_system_messages_locale;
+ Vsystem_time_locale = Vprevious_system_time_locale;
+ }
+
init_eval ();
init_data ();
+#ifdef CLASH_DETECTION
+ init_filelock ();;
+#endif
+ init_atimer ();
running_asynch_code = 0;
+ /* Handle --unibyte and the EMACS_UNIBYTE envvar,
+ but not while dumping. */
+ if (
+#ifndef CANNOT_DUMP
+ ! noninteractive || initialized
+#else
+ 1
+#endif
+ )
+ {
+ int inhibit_unibyte = 0;
+
+ /* --multibyte overrides EMACS_UNIBYTE. */
+ if (argmatch (argv, argc, "-no-unibyte", "--no-unibyte", 4, NULL, &skip_args)
+ || argmatch (argv, argc, "-multibyte", "--multibyte", 4, NULL, &skip_args))
+ inhibit_unibyte = 1;
+
+ /* --unibyte requests that we set up to do everything with single-byte
+ buffers and strings. We need to handle this before calling
+ init_lread, init_editfns and other places that generate Lisp strings
+ from text in the environment. */
+ /* Actually this shouldn't be needed as of 20.4 in a generally
+ unibyte environment. As handa says, environment values
+ aren't now decoded; also existing buffers are now made
+ unibyte during startup if .emacs sets unibyte. Tested with
+ 8-bit data in environment variables and /etc/passwd, setting
+ unibyte and Latin-1 in .emacs. -- Dave Love */
+ if (argmatch (argv, argc, "-unibyte", "--unibyte", 4, NULL, &skip_args)
+ || argmatch (argv, argc, "-no-multibyte", "--no-multibyte", 4, NULL, &skip_args)
+ || (getenv ("EMACS_UNIBYTE") && !inhibit_unibyte))
+ {
+ Lisp_Object old_log_max;
+ Lisp_Object symbol, tail;
+
+ symbol = intern ("default-enable-multibyte-characters");
+ Fset (symbol, Qnil);
+
+ if (initialized)
+ {
+ /* Erase pre-dump messages in *Messages* now so no abort. */
+ old_log_max = Vmessage_log_max;
+ XSETFASTINT (Vmessage_log_max, 0);
+ message_dolog ("", 0, 1, 0);
+ Vmessage_log_max = old_log_max;
+ }
+
+ for (tail = Vbuffer_alist; CONSP (tail);
+ tail = XCDR (tail))
+ {
+ Lisp_Object buffer;
+
+ buffer = Fcdr (XCAR (tail));
+ /* Verify that all buffers are empty now, as they
+ ought to be. */
+ if (BUF_Z (XBUFFER (buffer)) > BUF_BEG (XBUFFER (buffer)))
+ abort ();
+ /* It is safe to do this crudely in an empty buffer. */
+ XBUFFER (buffer)->enable_multibyte_characters = Qnil;
+ }
+ }
+ }
+
+ no_loadup
+ = argmatch (argv, argc, "-nl", "--no-loadup", 6, NULL, &skip_args);
+
+
+#ifdef HAVE_X_WINDOWS
+ /* Stupid kludge to catch command-line display spec. We can't
+ handle this argument entirely in window system dependent code
+ because we don't even know which window system dependent code
+ to run until we've recognized this argument. */
+ {
+ char *displayname = 0;
+ int count_before = skip_args;
+
+ /* Skip any number of -d options, but only use the last one. */
+ while (1)
+ {
+ int count_before_this = skip_args;
+
+ if (argmatch (argv, argc, "-d", "--display", 3, &displayname, &skip_args))
+ display_arg = 1;
+ else if (argmatch (argv, argc, "-display", 0, 3, &displayname, &skip_args))
+ display_arg = 1;
+ else
+ break;
+
+ count_before = count_before_this;
+ }
+
+ /* If we have the form --display=NAME,
+ convert it into -d name.
+ This requires inserting a new element into argv. */
+ if (displayname != 0 && skip_args - count_before == 1)
+ {
+ char **new = (char **) xmalloc (sizeof (char *) * (argc + 2));
+ int j;
+
+ for (j = 0; j < count_before + 1; j++)
+ new[j] = argv[j];
+ new[count_before + 1] = "-d";
+ new[count_before + 2] = displayname;
+ for (j = count_before + 2; j <argc; j++)
+ new[j + 1] = argv[j];
+ argv = new;
+ argc++;
+ }
+ /* Change --display to -d, when its arg is separate. */
+ else if (displayname != 0 && skip_args > count_before
+ && argv[count_before + 1][1] == '-')
+ argv[count_before + 1] = "-d";
+
+ /* Don't actually discard this arg. */
+ skip_args = count_before;
+ }
+#endif
+
+ /* argmatch must not be used after here,
+ except when bulding temacs
+ because the -d argument has not been skipped in skip_args. */
+
#ifdef MSDOS
/* Call early 'cause init_environment needs it. */
init_dosfns ();
#ifdef WINDOWSNT
/* Initialize environment from registry settings. */
- init_environment ();
+ init_environment (argv);
init_ntproc (); /* must precede init_editfns */
#endif
/* AIX crashes are reported in system versions 3.2.3 and 3.2.4
if this is not done. Do it after set_process_environment so that we
don't pollute Vprocess_environment. */
-#ifdef AIX
+ /* Setting LANG here will defeat the startup locale processing... */
+#ifdef AIX3_2
putenv ("LANG=C");
#endif
Lisp_Object old_log_max;
old_log_max = Vmessage_log_max;
XSETFASTINT (Vmessage_log_max, 0);
- message_dolog ("", 0, 1);
+ message_dolog ("", 0, 1, 0);
Vmessage_log_max = old_log_max;
}
init_callproc (); /* Must follow init_cmdargs but not init_sys_modes. */
init_lread ();
- if (!noninteractive)
- {
-#ifdef VMS
- init_vms_input ();/* init_display calls get_frame_size, that needs this */
-#endif /* VMS */
- init_display (); /* Determine terminal type. init_sys_modes uses results */
- }
- init_keyboard (); /* This too must precede init_sys_modes */
-#ifdef VMS
- init_vmsproc (); /* And this too. */
-#endif /* VMS */
- init_sys_modes (); /* Init system terminal modes (RAW or CBREAK, etc.) */
- init_xdisp ();
- init_macros ();
- init_editfns ();
-#ifdef LISP_FLOAT_TYPE
- init_floatfns ();
-#endif
-#ifdef VMS
- init_vmsfns ();
-#endif /* VMS */
- init_process ();
-
-/* Intern the names of all standard functions and variables; define standard keys */
+ /* Intern the names of all standard functions and variables;
+ define standard keys. */
if (!initialized)
{
/* The basic levels of Lisp must come first */
/* And data must come first of all
for the sake of symbols like error-message */
+#ifndef macintosh
+ /* Called before init_window_once for Mac OS. */
syms_of_data ();
+#endif
syms_of_alloc ();
syms_of_lread ();
syms_of_print ();
syms_of_casetab ();
syms_of_callproc ();
syms_of_category ();
+#ifndef macintosh
+ /* Called before init_window_once for Mac OS. */
syms_of_ccl ();
+#endif
syms_of_charset ();
syms_of_cmds ();
#ifndef NO_DIR_LIBRARY
#endif /* CLASH_DETECTION */
syms_of_indent ();
syms_of_insdel ();
- syms_of_keyboard ();
syms_of_keymap ();
syms_of_macros ();
syms_of_marker ();
syms_of_minibuf ();
syms_of_mocklisp ();
syms_of_process ();
+#ifndef macintosh
+ /* Called before init_window_once for Mac OS. */
syms_of_search ();
syms_of_frame ();
+#endif
syms_of_syntax ();
syms_of_term ();
syms_of_undo ();
-
- /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
+#ifdef HAVE_SOUND
+ syms_of_sound ();
+#endif
+#ifndef macintosh
+ /* Called before init_window_once for Mac OS. */
syms_of_textprop ();
+#endif
+ syms_of_composite ();
#ifdef VMS
syms_of_vmsproc ();
#endif /* VMS */
#endif /* HAVE_X_WINDOWS */
#ifndef HAVE_NTGUI
- syms_of_xfaces ();
+#ifndef macintosh
syms_of_xmenu ();
#endif
+#endif
#ifdef HAVE_NTGUI
syms_of_w32term ();
syms_of_w32fns ();
- syms_of_w32faces ();
syms_of_w32select ();
syms_of_w32menu ();
+ syms_of_fontset ();
#endif /* HAVE_NTGUI */
#ifdef SYMS_SYSTEM
keys_of_frame ();
}
+ if (!noninteractive)
+ {
+#ifdef VMS
+ init_vms_input ();/* init_display calls get_frame_size, that needs this */
+#endif /* VMS */
+ init_display (); /* Determine terminal type. init_sys_modes uses results */
+ }
+#ifndef macintosh
+ /* Called before init_window_once for Mac OS. */
+ init_keyboard (); /* This too must precede init_sys_modes */
+#endif
+#ifdef VMS
+ init_vmsproc (); /* And this too. */
+#endif /* VMS */
+ init_sys_modes (); /* Init system terminal modes (RAW or CBREAK, etc.) */
+#ifdef HAVE_X_WINDOWS
+ init_xfns ();
+#endif /* HAVE_X_WINDOWS */
+ init_fns ();
+ init_xdisp ();
+ init_macros ();
+ init_editfns ();
+ init_floatfns ();
+#ifdef VMS
+ init_vmsfns ();
+#endif /* VMS */
+ init_process ();
+#ifdef HAVE_SOUND
+ init_sound ();
+#endif
+ init_window ();
+
if (!initialized)
{
char *file;
- /* Handle -l loadup-and-dump, args passed by Makefile. */
+ /* Handle -l loadup, args passed by Makefile. */
if (argmatch (argv, argc, "-l", "--load", 3, &file, &skip_args))
Vtop_level = Fcons (intern ("load"),
Fcons (build_string (file), Qnil));
#ifdef CANNOT_DUMP
/* Unless next switch is -nl, load "loadup.el" first thing. */
- if (!argmatch (argv, argc, "-nl", "--no-loadup", 6, NULL, &skip_args))
+ if (! no_loadup)
Vtop_level = Fcons (intern ("load"),
Fcons (build_string ("loadup.el"), Qnil));
#endif /* CANNOT_DUMP */
/* Gerd Moellmann <gerd@acm.org> says this makes profiling work on
FreeBSD. It might work on some other systems too.
Give it a try and tell me if it works on your system. */
-#ifdef __FreeBSD__
+#if defined (__FreeBSD__) || defined (__linux)
#ifdef PROFILING
if (initialized)
{
extern void _mcleanup ();
extern char etext;
- extern Lisp_Object Fredraw_frame ();
+ extern void safe_bcopy ();
+ extern void dump_opcode_frequencies ();
+
atexit (_mcleanup);
- /* This uses Fredraw_frame because that function
- comes first in the Emacs executable.
- It might be better to use something that gives
- the start of the text segment, but start_of_text
- is not defined on all systems now. */
- monstartup (Fredraw_frame, &etext);
+ /* This uses safe_bcopy because that function comes first in the
+ Emacs executable. It might be better to use something that
+ gives the start of the text segment, but start_of_text is not
+ defined on all systems now. */
+ monstartup (safe_bcopy, &etext);
}
else
moncontrol (0);
/* Enter editor command loop. This never returns. */
Frecursive_edit ();
/* NOTREACHED */
+ return 0;
}
\f
/* Sort the args so we can find the most important ones
struct standard_args standard_args[] =
{
- { "-version", "--version", 110, 0 },
- { "-help", "--help", 110, 0 },
- { "-nl", "--no-shared-memory", 100, 0 },
+ { "-version", "--version", 150, 0 },
+#ifdef HAVE_SHM
+ { "-nl", "--no-shared-memory", 140, 0 },
+#endif
#ifdef VMS
- { "-map", "--map-data", 100, 0 },
+ { "-map", "--map-data", 130, 0 },
+#endif
+ { "-t", "--terminal", 120, 1 },
+ { "-nw", "--no-windows", 110, 0 },
+ { "-batch", "--batch", 100, 0 },
+ { "-help", "--help", 90, 0 },
+ { "-no-unibyte", "--no-unibyte", 83, 0 },
+ { "-multibyte", "--multibyte", 82, 0 },
+ { "-unibyte", "--unibyte", 81, 0 },
+ { "-no-multibyte", "--no-multibyte", 80, 0 },
+#ifdef CANNOT_DUMP
+ { "-nl", "--no-loadup", 70, 0 },
#endif
- { "-t", "--terminal", 90, 1 },
- { "-d", "--display", 80, 1 },
- { "-display", 0, 80, 1 },
- { "-nw", "--no-windows", 70, 0 },
- { "-batch", "--batch", 60, 0 },
+ /* -d must come last before the options handled in startup.el. */
+ { "-d", "--display", 60, 1 },
+ { "-display", 0, 60, 1 },
+ /* Now for the options handled in startup.el. */
{ "-q", "--no-init-file", 50, 0 },
{ "-no-init-file", 0, 50, 0 },
{ "-no-site-file", "--no-site-file", 40, 0 },
{ "-f", "--funcall", 0, 1 },
{ "-funcall", 0, 0, 1 },
{ "-eval", "--eval", 0, 1 },
+ { "-execute", "--execute", 0, 1 },
{ "-find-file", "--find-file", 0, 1 },
{ "-visit", "--visit", 0, 1 },
+ { "-file", "--file", 0, 1 },
{ "-insert", "--insert", 0, 1 },
/* This should be processed after ordinary file name args and the like. */
{ "-kill", "--kill", -10, 0 },
/* Reorder the elements of ARGV (assumed to have ARGC elements)
so that the highest priority ones come first.
Do not change the order of elements of equal priority.
- If an option takes an argument, keep it and its argument together. */
+ If an option takes an argument, keep it and its argument together.
+
+ If an option that takes no argument appears more
+ than once, eliminate all but one copy of it. */
static void
sort_args (argc, argv)
int *options = (int *) xmalloc (sizeof (int) * argc);
int *priority = (int *) xmalloc (sizeof (int) * argc);
int to = 1;
+ int incoming_used = 1;
int from;
int i;
- int end_of_options = argc;
/* Categorize all the options,
and figure out which argv elts are option arguments. */
/* Copy the arguments, in order of decreasing priority, to NEW. */
new[0] = argv[0];
- while (to < argc)
+ while (incoming_used < argc)
{
int best = -1;
int best_priority = -9999;
if (best < 0)
abort ();
- /* Copy the highest priority remaining option, with its args, to NEW. */
- new[to++] = argv[best];
- for (i = 0; i < options[best]; i++)
- new[to++] = argv[best + i + 1];
+ /* Copy the highest priority remaining option, with its args, to NEW.
+ Unless it is a duplicate of the previous one. */
+ if (! (options[best] == 0
+ && ! strcmp (new[to - 1], argv[best])))
+ {
+ new[to++] = argv[best];
+ for (i = 0; i < options[best]; i++)
+ new[to++] = argv[best + i + 1];
+ }
+
+ incoming_used += 1 + (options[best] > 0 ? options[best] : 0);
/* Clear out this option in ARGV. */
argv[best] = 0;
argv[best + i + 1] = 0;
}
+ /* If duplicate options were deleted, fill up extra space with null ptrs. */
+ while (to < argc)
+ new[to++] = 0;
+
bcopy (new, argv, sizeof (char *) * argc);
free (options);
(arg)
Lisp_Object arg;
{
- Lisp_Object hook, hook1;
- int i;
struct gcpro gcpro1;
GCPRO1 (arg);
#ifdef WINDOWSNT
term_ntproc ();
#endif
+
+ check_glyph_memory ();
+ check_message_stack ();
+
+#ifdef MSDOS
+ dos_cleanup ();
+#endif
}
#ifdef DOUG_LEA_MALLOC
malloc_state_ptr = malloc_get_state ();
#endif
+
+#ifdef USE_MMAP_FOR_BUFFERS
+ mmap_set_vars (0);
+#endif
unexec (XSTRING (filename)->data,
!NILP (symfile) ? XSTRING (symfile)->data : 0, my_edata, 0, 0);
+#ifdef USE_MMAP_FOR_BUFFERS
+ mmap_set_vars (1);
+#endif
#ifdef DOUG_LEA_MALLOC
free (malloc_state_ptr);
#endif
#endif /* not CANNOT_DUMP */
\f
+#if HAVE_SETLOCALE
+/* Recover from setlocale (LC_ALL, ""). */
+void
+fixup_locale ()
+{
+ /* The Emacs Lisp reader needs LC_NUMERIC to be "C",
+ so that numbers are read and printed properly for Emacs Lisp. */
+ setlocale (LC_NUMERIC, "C");
+}
+
+/* Set system locale CATEGORY, with previous locale *PLOCALE, to
+ DESIRED_LOCALE. */
+static void
+synchronize_locale (category, plocale, desired_locale)
+ int category;
+ Lisp_Object *plocale;
+ Lisp_Object desired_locale;
+{
+ if (! EQ (*plocale, desired_locale))
+ {
+ *plocale = desired_locale;
+ setlocale (category, (STRINGP (desired_locale)
+ ? (char *)(XSTRING (desired_locale)->data)
+ : ""));
+ }
+}
+
+/* Set system time locale to match Vsystem_time_locale, if possible. */
+void
+synchronize_system_time_locale ()
+{
+ synchronize_locale (LC_TIME, &Vprevious_system_time_locale,
+ Vsystem_time_locale);
+}
+
+/* Set system messages locale to match Vsystem_messages_locale, if
+ possible. */
+void
+synchronize_system_messages_locale ()
+{
+#ifdef LC_MESSAGES
+ synchronize_locale (LC_MESSAGES, &Vprevious_system_messages_locale,
+ Vsystem_messages_locale);
+#endif
+}
+#endif /* HAVE_SETLOCALE */
+\f
#ifndef SEPCHAR
#define SEPCHAR ':'
#endif
return Fnreverse (lpath);
}
+void
syms_of_emacs ()
{
Qfile_name_handler_alist = intern ("file-name-handler-alist");
Vsystem_type = intern (SYSTEM_TYPE);
DEFVAR_LISP ("system-configuration", &Vsystem_configuration,
- "Value is string indicating configuration Emacs was built for.");
+ "Value is string indicating configuration Emacs was built for.\n\
+On MS-Windows, the value reflects the OS flavor and version on which\n\
+Emacs is running.");
Vsystem_configuration = build_string (EMACS_CONFIGURATION);
DEFVAR_LISP ("system-configuration-options", &Vsystem_configuration_options,
see `kill-emacs-query-functions' instead.");
Vkill_emacs_hook = Qnil;
+#ifdef SIGUSR1
+ DEFVAR_LISP ("signal-USR1-hook", &Vsignal_USR1_hook,
+ "Hook to be run whenever emacs receives a USR1 signal");
+ Vsignal_USR1_hook = Qnil;
+#ifdef SIGUSR2
+ DEFVAR_LISP ("signal-USR2-hook", &Vsignal_USR2_hook,
+ "Hook to be run whenever emacs receives a USR2 signal");
+ Vsignal_USR2_hook = Qnil;
+#endif
+#endif
+
+
DEFVAR_INT ("emacs-priority", &emacs_priority,
"Priority for Emacs to run at.\n\
This value is effective only if set before Emacs is dumped,\n\
before you compile Emacs, to enable the code for this feature.");
emacs_priority = 0;
+ DEFVAR_LISP ("path-separator", &Vpath_separator,
+ "The directory separator in search paths, as a string.");
+ {
+ char c = SEPCHAR;
+ Vpath_separator = make_string (&c, 1);
+ }
+
DEFVAR_LISP ("invocation-name", &Vinvocation_name,
"The program name that was used to run Emacs.\n\
Any directory names are omitted.");
installed locations, but we can find them\n\
near where the Emacs executable was found.");
Vinstallation_directory = Qnil;
+
+ DEFVAR_LISP ("system-messages-locale", &Vsystem_messages_locale,
+ "System locale for messages.");
+ Vsystem_messages_locale = Qnil;
+
+ DEFVAR_LISP ("previous-system-messages-locale",
+ &Vprevious_system_messages_locale,
+ "Most recently used system locale for messages.");
+ Vprevious_system_messages_locale = Qnil;
+
+ DEFVAR_LISP ("system-time-locale", &Vsystem_time_locale,
+ "System locale for time.");
+ Vsystem_time_locale = Qnil;
+
+ DEFVAR_LISP ("previous-system-time-locale", &Vprevious_system_time_locale,
+ "Most recently used system locale for time.");
+ Vprevious_system_time_locale = Qnil;
}