/* Fully extensible Emacs, running on Unix, intended for GNU.
- Copyright (C) 1985, 1986, 1987, 1993 Free Software Foundation, Inc.
+ Copyright (C) 1985, 1986, 1987, 1993, 1994 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <signal.h>
#include <errno.h>
-#include "config.h"
+#include <config.h>
#include <stdio.h>
#include <sys/types.h>
#include "systty.h"
#include "syssignal.h"
+#include "process.h"
#ifndef O_RDWR
#define O_RDWR 2
#endif
-#define PRIO_PROCESS 0
+extern void malloc_warning ();
+extern char *index ();
+extern char *strerror ();
/* Command line args from shell, as list of strings */
Lisp_Object Vcommand_line_args;
names discarded. */
Lisp_Object Vinvocation_name;
+/* The directory name from which Emacs was invoked. */
+Lisp_Object Vinvocation_directory;
+
+/* The directory name in which to find subdirs such as lisp and etc.
+ nil means get them only from PATH_LOADSEARCH. */
+Lisp_Object Vinstallation_directory;
+
/* Hook run by `kill-emacs' before it does really anything. */
Lisp_Object Vkill_emacs_hook;
on subsequent starts. */
int initialized;
-/* Variable whose value is symbol giving operating system type */
+/* Variable whose value is symbol giving operating system type. */
Lisp_Object Vsystem_type;
-
+
+/* Variable whose value is string giving configuration built for. */
+Lisp_Object Vsystem_configuration;
+
+/* Variable whose value is string giving configuration options,
+ for use when reporting bugs. */
+Lisp_Object Vsystem_configuration_options;
+
/* 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;
priority; Those functions have their own extern declaration. */
int emacs_priority;
-#ifdef BSD
+/* If non-zero a filter or a sentinel is running. Tested to save the match
+ data on the first attempt to change it inside asynchronous code. */
+int running_asynch_code;
+
+#ifdef BSD_PGRPS
/* See sysdep.c. */
extern int inherited_pgroup;
#endif
but nothing terrible happens if user sets this one. */
int noninteractive1;
+
+/* Save argv and argc. */
+char **initial_argv;
+int initial_argc;
+
+static void sort_args ();
\f
/* Signal code for the fatal signal that was received */
int fatal_error_code;
Remember that since we're in a signal handler, the signal we're
going to send is probably blocked, so we have to unblock it if we
want to really receive it. */
+#ifndef MSDOS
sigunblock (sigmask (fatal_error_code));
+#endif
kill (getpid (), fatal_error_code);
#endif /* not VMS */
}
+
+#ifdef SIGDANGER
+
+/* Handler for SIGDANGER. */
+SIGTYPE
+memory_warning_signal (sig)
+ int sig;
+{
+ signal (sig, memory_warning_signal);
+
+ malloc_warning ("Operating system warns that virtual memory is running low.\n");
+
+ /* It might be unsafe to call do_auto_save now. */
+ force_auto_save_soon ();
+}
+#endif
\f
/* Code for dealing with Lisp access to the Unix command line */
int skip_args;
{
register int i;
+ Lisp_Object name, dir;
+
+ initial_argv = argv;
+ initial_argc = argc;
Vinvocation_name = Ffile_name_nondirectory (build_string (argv[0]));
+ Vinvocation_directory = Ffile_name_directory (build_string (argv[0]));
+ /* If we got no directory in argv[0], search PATH to find where
+ Emacs actually came from. */
+ if (NILP (Vinvocation_directory))
+ {
+ Lisp_Object found;
+ int yes = openp (Vexec_path, Vinvocation_name,
+ EXEC_SUFFIXES, &found, 1);
+ if (yes == 1)
+ Vinvocation_directory = Ffile_name_directory (found);
+ }
+
+ Vinstallation_directory = Qnil;
+
+ if (!NILP (Vinvocation_directory))
+ {
+ dir = Vinvocation_directory;
+ name = Fexpand_file_name (Vinvocation_name, dir);
+ while (1)
+ {
+ Lisp_Object tem, lib_src_exists;
+ Lisp_Object etc_exists, info_exists;
+
+ /* See if dir contains subdirs for use by Emacs.
+ Check for the ones that would exist in a build directory,
+ not including lisp and info. */
+ tem = Fexpand_file_name (build_string ("lib-src"), dir);
+ lib_src_exists = Ffile_exists_p (tem);
+ if (!NILP (lib_src_exists))
+ {
+ tem = Fexpand_file_name (build_string ("etc"), dir);
+ etc_exists = Ffile_exists_p (tem);
+ if (!NILP (etc_exists))
+ {
+ Vinstallation_directory
+ = Ffile_name_as_directory (dir);
+ break;
+ }
+ }
+
+ /* See if dir's parent contains those subdirs. */
+ tem = Fexpand_file_name (build_string ("../lib-src"), dir);
+ lib_src_exists = Ffile_exists_p (tem);
+ if (!NILP (lib_src_exists))
+ {
+ tem = Fexpand_file_name (build_string ("../etc"), dir);
+ etc_exists = Ffile_exists_p (tem);
+ if (!NILP (etc_exists))
+ {
+ tem = Fexpand_file_name (build_string (".."), dir);
+ Vinstallation_directory
+ = Ffile_name_as_directory (tem);
+ break;
+ }
+ }
+
+ /* If the Emacs executable is actually a link,
+ next try the dir that the link points into. */
+ tem = Ffile_symlink_p (name);
+ if (!NILP (tem))
+ {
+ name = Fexpand_file_name (tem, dir);
+ dir = Ffile_name_directory (name);
+ }
+ else
+ break;
+ }
+ }
Vcommand_line_args = Qnil;
return Fcopy_sequence (Vinvocation_name);
}
+DEFUN ("invocation-directory", Finvocation_directory, Sinvocation_directory,
+ 0, 0, 0,
+ "Return the directory name in which the Emacs executable was located")
+ ()
+{
+ return Fcopy_sequence (Vinvocation_directory);
+}
+
\f
#ifdef VMS
#ifdef LINK_CRTL_SHARE
Provide dummy definitions to avoid error.
(We don't have any real constructors or destructors.) */
#ifdef __GNUC__
+#ifndef GCC_CTORS_IN_LIBC
__do_global_ctors ()
{}
__do_global_ctors_aux ()
{}
__do_global_dtors ()
{}
+/* Linux has a bug in its library; avoid an error. */
+#ifndef LINUX
char * __CTOR_LIST__[2] = { (char *) (-1), 0 };
+#endif
char * __DTOR_LIST__[2] = { (char *) (-1), 0 };
+#endif /* GCC_CTORS_IN_LIBC */
__main ()
{}
#endif /* __GNUC__ */
#endif /* ORDINARY_LINK */
+/* Test whether the next argument in ARGV matches SSTR or a prefix of
+ LSTR (at least MINLEN characters). If so, then if VALPTR is non-null
+ (the argument is supposed to have a value) store in *VALPTR either
+ the next argument or the portion of this one after the equal sign.
+ ARGV is read starting at position *SKIPPTR; this index is advanced
+ by the number of arguments used.
+
+ Too bad we can't just use getopt for all of this, but we don't have
+ enough information to do it right. */
+
+static int
+argmatch (argv, argc, sstr, lstr, minlen, valptr, skipptr)
+ char **argv;
+ int argc;
+ char *sstr;
+ char *lstr;
+ int minlen;
+ char **valptr;
+ int *skipptr;
+{
+ char *p;
+ int arglen;
+ char *arg;
+
+ /* Don't access argv[argc]; give up in advance. */
+ if (argc <= *skipptr + 1)
+ return 0;
+
+ arg = argv[*skipptr+1];
+ if (arg == NULL)
+ return 0;
+ if (strcmp (arg, sstr) == 0)
+ {
+ if (valptr != NULL)
+ {
+ *valptr = argv[*skipptr+2];
+ *skipptr += 2;
+ }
+ else
+ *skipptr += 1;
+ return 1;
+ }
+ arglen = (valptr != NULL && (p = index (arg, '=')) != NULL
+ ? p - arg : strlen (arg));
+ if (lstr == 0 || arglen < minlen || strncmp (arg, lstr, arglen) != 0)
+ return 0;
+ else if (valptr == NULL)
+ {
+ *skipptr += 1;
+ return 1;
+ }
+ else if (p != NULL)
+ {
+ *valptr = p+1;
+ *skipptr += 1;
+ return 1;
+ }
+ else if (argv[*skipptr+2] != NULL)
+ {
+ *valptr = argv[*skipptr+2];
+ *skipptr += 2;
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
/* ARGSUSED */
main (argc, argv, envp)
int argc;
int skip_args = 0;
extern int errno;
extern sys_nerr;
- extern char *sys_errlist[];
- extern void malloc_warning ();
+
+ sort_args (argc, argv);
+
+ if (argmatch (argv, argc, "-version", "--version", 3, NULL, &skip_args))
+ {
+ Lisp_Object tem;
+ tem = Fsymbol_value (intern ("emacs-version"));
+ if (!STRINGP (tem))
+ {
+ fprintf (stderr, "Invalid value of `emacs-version'\n");
+ exit (1);
+ }
+ else
+ {
+ printf ("%s\n", XSTRING (tem)->data);
+ exit (0);
+ }
+ }
/* Map in shared memory, if we are using that. */
#ifdef HAVE_SHM
- if (argc > 1 && !strcmp (argv[1], "-nl"))
+ if (argmatch (argv, argc, "-nl", "--no-shared-memory", 6, NULL, &skip_args))
{
map_in_data (0);
/* The shared memory was just restored, which clobbered this. */
printf ("malloc jumpstart failed!\n");
#endif /* NeXT */
-#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. */
- {
- int i;
-
- for (i = 1; (i < argc && ! display_arg); i++)
- if (!strcmp (argv[i], "-d") || !strcmp (argv[i], "-display"))
- display_arg = 1;
- }
-#endif
-
#ifdef VMS
/* If -map specified, map the data file in */
- if (argc > 2 && ! strcmp (argv[1], "-map"))
- {
- skip_args = 2;
- mapin_data (argv[2]);
- }
+ {
+ char *file;
+ if (argmatch (argv, argc, "-map", "--map-data", 3, &mapin_file, &skip_args))
+ mapin_data (file);
+ }
#ifdef LINK_CRTL_SHARE
#ifdef SHAREABLE_LIB_BUG
clearerr (stdin);
-#ifdef BSD
- {
- inherited_pgroup = getpgrp (0);
- setpgrp (0, getpid ());
- }
-#endif
-
-
#ifdef APOLLO
#ifndef APOLLO_SR10
/* If USE_DOMAIN_ACLS environment variable exists,
}
#endif /* not SYSTEM_MALLOC */
-#ifdef PRIO_PROCESS
+#ifdef MSDOS
+ /* We do all file input/output as binary files. When we need to translate
+ newlines, we do that manually. */
+ _fmode = O_BINARY;
+ (stdin)->_flag &= ~_IOTEXT;
+ (stdout)->_flag &= ~_IOTEXT;
+ (stderr)->_flag &= ~_IOTEXT;
+#endif /* MSDOS */
+
+#ifdef SET_EMACS_PRIORITY
if (emacs_priority)
nice (emacs_priority);
setuid (getuid ());
-#endif /* PRIO_PROCESS */
+#endif /* SET_EMACS_PRIORITY */
+
+#ifdef EXTRA_INITIALIZE
+ EXTRA_INITIALIZE;
+#endif
inhibit_window_system = 0;
/* Handle the -t switch, which specifies filename to use as terminal */
- if (skip_args + 2 < argc && !strcmp (argv[skip_args + 1], "-t"))
- {
- int result;
- skip_args += 2;
- close (0);
- close (1);
- result = open (argv[skip_args], O_RDWR, 2 );
- if (result < 0)
- {
- char *errstring;
-
- if (errno >= 0 && errno < sys_nerr)
- errstring = sys_errlist[errno];
- else
- errstring = "undocumented error code";
- fprintf (stderr, "emacs: %s: %s\n", argv[skip_args], errstring);
- exit (1);
- }
- dup (0);
- if (! isatty (0))
- {
- fprintf (stderr, "emacs: %s: not a tty\n", argv[skip_args]);
- exit (1);
- }
- fprintf (stderr, "Using %s\n", argv[skip_args]);
+ {
+ 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);
#ifdef HAVE_X_WINDOWS
- inhibit_window_system = 1; /* -t => -nw */
+ inhibit_window_system = 1; /* -t => -nw */
#endif
- }
+ }
+ }
+ if (argmatch (argv, argc, "-nw", "--no-windows", 6, NULL, &skip_args))
+ inhibit_window_system = 1;
- if (skip_args + 1 < argc
- && (!strcmp (argv[skip_args + 1], "-nw")))
+ /* Handle the -batch switch, which means don't do interactive display. */
+ noninteractive = 0;
+ if (argmatch (argv, argc, "-batch", "--batch", 5, NULL, &skip_args))
+ noninteractive = 1;
+
+ /* Handle the --help option, which gives a usage message.. */
+ if (argmatch (argv, argc, "-help", "--help", 3, NULL, &skip_args))
{
- skip_args += 1;
- inhibit_window_system = 1;
+ printf ("\
+Usage: %s [-t term] [--terminal term] [-nw] [--no-windows] [--batch]\n\
+ [-q] [--no-init-file] [-u user] [--user user] [--debug-init]\n\
+\(Arguments above this line must be first; those below may be in any order)\n\
+ [-f func] [--funcall func] [-l file] [--load file] [--insert file]\n\
+ file-to-visit [--kill]\n", argv[0]);
+ exit (0);
}
-/* Handle the -batch switch, which means don't do interactive display. */
- noninteractive = 0;
- if (skip_args + 1 < argc && !strcmp (argv[skip_args + 1], "-batch"))
+#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;
+ 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] = "-d";
+
+ /* Don't actually discard this arg. */
+ skip_args = count_before;
+ }
+#endif
+
+ if (! noninteractive)
{
- skip_args += 1;
- noninteractive = 1;
+#ifdef BSD_PGRPS
+ if (initialized)
+ {
+ inherited_pgroup = EMACS_GETPGRP (0);
+ setpgrp (0, getpid ());
+ }
+#else
+#if defined (USG5) && defined (INTERRUPT_INPUT)
+ setpgrp ();
+#endif
+#endif
}
#ifdef POSIX_SIGNALS
signal (SIGQUIT, fatal_error_signal);
signal (SIGILL, fatal_error_signal);
signal (SIGTRAP, fatal_error_signal);
+#ifdef SIGABRT
+ signal (SIGABRT, fatal_error_signal);
+#endif
+#ifdef SIGHWE
+ signal (SIGHWE, fatal_error_signal);
+#endif
+#ifdef SIGPRE
+ signal (SIGPRE, fatal_error_signal);
+#endif
+#ifdef SIGORE
+ signal (SIGORE, fatal_error_signal);
+#endif
+#ifdef SIGUME
+ signal (SIGUME, fatal_error_signal);
+#endif
+#ifdef SIGDLK
+ signal (SIGDLK, fatal_error_signal);
+#endif
+#ifdef SIGCPULIM
+ signal (SIGCPULIM, fatal_error_signal);
+#endif
#ifdef SIGIOT
/* This is missing on some systems - OS/2, for example. */
signal (SIGIOT, fatal_error_signal);
signal (SIGXFSZ, fatal_error_signal);
#endif /* SIGXFSZ */
-#ifdef AIX
- signal (SIGDANGER, fatal_error_signal);
- signal (20, fatal_error_signal);
- signal (21, fatal_error_signal);
- signal (22, fatal_error_signal);
- signal (23, fatal_error_signal);
- signal (24, fatal_error_signal);
-#ifdef SIGIO
- signal (SIGAIO, fatal_error_signal);
- signal (SIGPTY, fatal_error_signal);
+#ifdef SIGDANGER
+ /* This just means available memory is getting low. */
+ signal (SIGDANGER, memory_warning_signal);
#endif
+
+#ifdef AIX
+/* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU. */
+ signal (SIGXCPU, fatal_error_signal);
#ifndef _I386
signal (SIGIOINT, fatal_error_signal);
#endif
init_alloc ();
init_eval ();
init_data ();
+ running_asynch_code = 0;
+
+#ifdef MSDOS
+ /* Call early 'cause init_environment needs it. */
+ init_dosfns ();
+ /* Set defaults for several environment variables. */
+ if (initialized) init_environment (argc, argv, skip_args);
+#endif
/* egetenv is a pretty low-level facility, which may get called in
many circumstances; it seems flimsy to put off initializing it
until calling init_callproc. */
set_process_environment ();
+ /* 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
+ putenv ("LANG=C");
+#endif
+
+ init_buffer (); /* Init default directory of main buffer */
+ init_callproc_1 (); /* Must precede init_cmdargs and init_sys_modes. */
+ init_cmdargs (argc, argv, skip_args); /* Must precede init_lread. */
+ init_callproc (); /* Must follow init_cmdargs but not init_sys_modes. */
init_lread ();
- init_cmdargs (argc, argv, skip_args); /* Create list Vcommand_line_args */
- init_buffer (); /* Init default directory of main buffer */
if (!noninteractive)
{
#ifdef VMS
init_display (); /* Determine terminal type. init_sys_modes uses results */
}
init_keyboard (); /* This too must precede init_sys_modes */
- init_callproc (); /* And this too. */
#ifdef VMS
init_vmsproc (); /* And this too. */
#endif /* VMS */
syms_of_print ();
syms_of_eval ();
syms_of_fns ();
-#ifdef LISP_FLOAT_TYPE
syms_of_floatfns ();
-#endif
syms_of_abbrev ();
syms_of_buffer ();
syms_of_search ();
syms_of_frame ();
syms_of_syntax ();
+ syms_of_term ();
syms_of_undo ();
/* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
#endif /* HAVE_X_MENU */
#endif /* HAVE_X_WINDOWS */
+#if defined (MSDOS) && !defined (HAVE_X_WINDOWS)
+ syms_of_xfaces ();
+ syms_of_xmenu ();
+#endif
+
#ifdef SYMS_SYSTEM
SYMS_SYSTEM;
#endif
if (!initialized)
{
+ char *file;
/* Handle -l loadup-and-dump, args passed by Makefile. */
- if (argc > 2 + skip_args && !strcmp (argv[1 + skip_args], "-l"))
+ if (argmatch (argv, argc, "-l", "--load", 3, &file, &skip_args))
Vtop_level = Fcons (intern ("load"),
- Fcons (build_string (argv[2 + skip_args]), Qnil));
+ Fcons (build_string (file), Qnil));
#ifdef CANNOT_DUMP
/* Unless next switch is -nl, load "loadup.el" first thing. */
- if (!(argc > 1 + skip_args && !strcmp (argv[1 + skip_args], "-nl")))
+ if (!argmatch (argv, argc, "-nl", "--no-loadup", 6, NULL, &skip_args))
Vtop_level = Fcons (intern ("load"),
Fcons (build_string ("loadup.el"), Qnil));
#endif /* CANNOT_DUMP */
initialized = 1;
-#ifdef sun
- /* sun's localtime() has a bug. it caches the value of the time
+#if defined (sun) || defined (LOCALTIME_CACHE)
+ /* sun's localtime has a bug. it caches the value of the time
zone rather than looking it up every time. Since localtime() is
called to bolt the undumping time into the undumped emacs, this
- results in localtime() ignoring the TZ environment variable.
- This flushes the new TZ value into localtime(). */
- tzset();
-#endif /* sun */
+ results in localtime ignoring the TZ environment variable.
+ This flushes the new TZ value into localtime. */
+ tzset ();
+#endif /* defined (sun) || defined (LOCALTIME_CACHE) */
+
+ /* Handle the GNU standard option --version. */
+ if (argmatch (argv, argc, "-version", "--version", 3, NULL, &skip_args))
+ {
+ Lisp_Object ver;
+ ver = call0 (intern ("emacs-version"));
+ if (STRINGP (ver))
+ printf ("%s\n", XSTRING (ver)->data);
+ exit (0);
+ }
/* Enter editor command loop. This never returns. */
Frecursive_edit ();
/* NOTREACHED */
}
\f
+/* Sort the args so we can find the most important ones
+ at the beginning of argv. */
+
+/* First, here's a table of all the standard options. */
+
+struct standard_args
+{
+ char *name;
+ char *longname;
+ int priority;
+ int nargs;
+};
+
+struct standard_args standard_args[] =
+{
+ { "-nl", "--no-shared-memory", 100, 0 },
+ { "-map", "--map-data", 100, 0 },
+ { "-t", "--terminal", 90, 1 },
+ { "-d", "--display", 80, 1 },
+ { "-display", 0, 80, 1 },
+ { "-nw", "--no-windows", 70, 0 },
+ { "-batch", "--batch", 60, 0 },
+ { "-q", "--no-init-file", 50, 0 },
+ { "-no-init-file", 0, 50, 0 },
+ { "-no-site-file", "--no-site-file", 40, 0 },
+ { "-u", "--user", 30, 1 },
+ { "-user", 0, 30, 1 },
+ { "-debug-init", "--debug-init", 20, 0 },
+ { "-bg", "--background-color", 10, 1 },
+ { "-background", 0, 10, 1 },
+ { "-fg", "--foreground-color", 10, 1 },
+ { "-foreground", 0, 10, 1 },
+ { "-bd", "--border-color", 10, 1 },
+ { "-bw", "--border-width", 10, 1 },
+ { "-ib", "--internal-border", 10, 1 },
+ { "-ms", "--mouse-color", 10, 1 },
+ { "-cr", "--cursor-color", 10, 1 },
+ { "-fn", "--font", 10, 1 },
+ { "-font", 0, 10, 1 },
+ { "-g", "--geometry", 10, 1 },
+ { "-geometry", 0, 10, 1 },
+ { "-T", "--title", 10, 1 },
+ { "-i", "--icon-type", 10, 1 },
+ { "-itype", 0, 10, 1 },
+ { "-name", "--name", 10, 1 },
+ { "-xrm", "--xrm", 10, 1 },
+ { "-r", "--reverse-video", 5, 0 },
+ { "-rv", 0, 5, 0 },
+ { "-reverse", 0, 5, 0 },
+ { "-vb", "--vertical-scroll-bars", 5, 0 },
+ { "-iconic", "--iconic", 5, 0 },
+ /* These have the same priority as ordinary file name args,
+ so they are not reordered with respect to those. */
+ { "-l", "--load", 0, 1 },
+ { "-load", 0, 0, 1 },
+ { "-f", "--funcall", 0, 1 },
+ { "-funcall", 0, 0, 1 },
+ { "-insert", "--insert", 0, 1 },
+ { "-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. */
+
+static void
+sort_args (argc, argv)
+ int argc;
+ char **argv;
+{
+ char **new = (char **) xmalloc (sizeof (char *) * argc);
+ /* For each element of argv,
+ the corresponding element of options is:
+ 0 for an option that takes no arguments,
+ 1 for an option that takes one argument, etc.
+ -1 for an ordinary non-option argument. */
+ int *options = (int *) xmalloc (sizeof (int) * argc);
+ int *priority = (int *) xmalloc (sizeof (int) * argc);
+ int to = 1;
+ int from;
+ int i;
+
+ /* Categorize all the options,
+ and figure out which argv elts are option arguments. */
+ for (from = 1; from < argc; from++)
+ {
+ options[from] = -1;
+ priority[from] = 0;
+ if (argv[from][0] == '-')
+ {
+ int match, thislen;
+ char *equals;
+
+ /* Look for a match with a known old-fashioned option. */
+ for (i = 0; i < sizeof (standard_args) / sizeof (standard_args[0]); i++)
+ if (!strcmp (argv[from], standard_args[i].name))
+ {
+ options[from] = standard_args[i].nargs;
+ priority[from] = standard_args[i].priority;
+ from += standard_args[i].nargs;
+ goto done;
+ }
+
+ /* Look for a match with a known long option.
+ MATCH is -1 if no match so far, -2 if two or more matches so far,
+ >= 0 (the table index of the match) if just one match so far. */
+ if (argv[from][1] == '-')
+ {
+ match = -1;
+ thislen = strlen (argv[from]);
+ equals = index (argv[from], '=');
+ if (equals != 0)
+ thislen = equals - argv[from];
+
+ for (i = 0; i < sizeof (standard_args) / sizeof (standard_args[0]); i++)
+ if (!strncmp (argv[from], standard_args[i].longname, thislen))
+ {
+ if (match == -1)
+ match = i;
+ else
+ match = -2;
+ }
+
+ /* If we found exactly one match, use that. */
+ if (match >= 0)
+ {
+ options[from] = standard_args[match].nargs;
+ priority[from] = standard_args[match].priority;
+ /* If --OPTION=VALUE syntax is used,
+ this option uses just one argv element. */
+ if (equals != 0)
+ options[from] = 0;
+ from += options[from];
+ }
+ }
+ done: ;
+ }
+ }
+
+ /* Copy the arguments, in order of decreasing priority, to NEW. */
+ new[0] = argv[0];
+ while (to < argc)
+ {
+ int best = -1;
+ int best_priority = -2;
+
+ /* Find the highest priority remaining option.
+ If several have equal priority, take the first of them. */
+ for (from = 1; from < argc; from++)
+ {
+ if (argv[from] != 0 && priority[from] > best_priority)
+ {
+ best_priority = priority[from];
+ best = from;
+ }
+ /* Skip option arguments--they are tied to the options. */
+ if (options[from] > 0)
+ from += options[from];
+ }
+
+ 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];
+
+ /* Clear out this option in ARGV. */
+ argv[best] = 0;
+ for (i = 0; i < options[best]; i++)
+ argv[best + i + 1] = 0;
+ }
+
+ bcopy (new, argv, sizeof (char *) * argc);
+}
+\f
DEFUN ("kill-emacs", Fkill_emacs, Skill_emacs, 0, 1, "P",
"Exit the Emacs job and kill it.\n\
If ARG is an integer, return ARG as the exit program code.\n\
stop_vms_input ();
#endif */
- shut_down_emacs (0, 0);
+ shut_down_emacs (0, 0, STRINGP (arg) ? arg : Qnil);
- exit ((XTYPE (arg) == Lisp_Int) ? XINT (arg)
+ exit (INTEGERP (arg) ? XINT (arg)
#ifdef VMS
: 1
#else
int sig, no_x;
Lisp_Object stuff;
{
+ /* Prevent running of hooks from now on. */
+ Vrun_hooks = Qnil;
+
/* If we are controlling the terminal, reset terminal modes */
#ifdef EMACS_HAVE_TTY_PGRP
{
+ int pgrp = EMACS_GETPGRP (0);
+
int tpgrp;
if (EMACS_GET_TTY_PGRP (0, &tpgrp) != -1
- && tpgrp == getpgrp (0))
+ && tpgrp == pgrp)
{
fflush (stdout);
reset_sys_modes ();
kill_vms_processes ();
#endif
+#if 0 /* This triggers a bug in XCloseDisplay and is not needed. */
#ifdef HAVE_X_WINDOWS
- if (!noninteractive && EQ (Vwindow_system, intern ("x")) && ! no_x)
+ /* It's not safe to call intern here. Maybe we are crashing. */
+ if (!noninteractive && SYMBOLP (Vwindow_system)
+ && XSYMBOL (Vwindow_system)->name->size == 1
+ && XSYMBOL (Vwindow_system)->name->data[0] == 'x'
+ && ! no_x)
Fx_close_current_connection ();
#endif /* HAVE_X_WINDOWS */
+#endif
#ifdef SIGIO
/* There is a tendency for a SIGIO signal to arrive within exit,
{
extern int my_edata;
Lisp_Object tem;
- extern void malloc_warning ();
CHECK_STRING (intoname, 0);
intoname = Fexpand_file_name (intoname, Qnil);
{
extern int my_edata;
Lisp_Object tem;
- extern void malloc_warning ();
CHECK_STRING (intoname, 0);
intoname = Fexpand_file_name (intoname, Qnil);
/* Tell malloc where start of impure now is */
/* Also arrange for warnings when nearly out of space. */
#ifndef SYSTEM_MALLOC
+#ifndef WINDOWSNT
+ /* On Windows, this was done before dumping, and that once suffices.
+ Meanwhile, my_edata is not valid on Windows. */
memory_warnings (&my_edata, malloc_warning);
+#endif /* not WINDOWSNT */
#endif
unexec (XSTRING (intoname)->data,
!NILP (symname) ? XSTRING (symname)->data : 0, &my_edata, 0, 0);
char *evarname, *defalt;
{
register char *path, *p;
- extern char *index ();
Lisp_Object lpath;
defsubr (&Skill_emacs);
defsubr (&Sinvocation_name);
+ defsubr (&Sinvocation_directory);
DEFVAR_LISP ("command-line-args", &Vcommand_line_args,
"Args passed by shell to Emacs, as a list of strings.");
"Value is symbol indicating type of operating system you are using.");
Vsystem_type = intern (SYSTEM_TYPE);
+ DEFVAR_LISP ("system-configuration", &Vsystem_configuration,
+ "Value is string indicating configuration Emacs was built for.");
+ Vsystem_configuration = build_string (EMACS_CONFIGURATION);
+
+ DEFVAR_LISP ("system-configuration-options", &Vsystem_configuration_options,
+ "String containing the configuration options Emacs was built with.");
+ Vsystem_configuration_options = build_string (EMACS_CONFIG_OPTIONS);
+
DEFVAR_BOOL ("noninteractive", &noninteractive1,
"Non-nil means Emacs is running without interactive terminal.");
"Priority for Emacs to run at.\n\
This value is effective only if set before Emacs is dumped,\n\
and only if the Emacs executable is installed with setuid to permit\n\
-it to change priority. (Emacs sets its uid back to the real uid.)");
+it to change priority. (Emacs sets its uid back to the real uid.)\n\
+Currently, you need to define SET_EMACS_PRIORITY in `config.h'\n\
+before you compile Emacs, to enable the code for this feature.");
emacs_priority = 0;
- staticpro (&Vinvocation_name);
- Vinvocation_name = Qnil;
+ DEFVAR_LISP ("invocation-name", &Vinvocation_name,
+ "The program name that was used to run Emacs.\n\
+Any directory names are omitted.");
+
+ DEFVAR_LISP ("invocation-directory", &Vinvocation_directory,
+ "The directory in which the Emacs executable was found, to run it.\n\
+The value is nil if that directory's name is not known.");
+
+ DEFVAR_LISP ("installation-directory", &Vinstallation_directory,
+ "A directory within which to look for the `lib-src' and `etc' directories.\n\
+This is non-nil when we can't find those directories in their standard\n\
+installed locations, but we can find them\n\
+near where the Emacs executable was found.");
+ Vinstallation_directory = Qnil;
}