priority; Those functions have their own extern declaration. */
int emacs_priority;
+/* 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;
/* 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;
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, sstr, lstr, minlen, valptr, skipptr)
+argmatch (argv, argc, sstr, lstr, minlen, valptr, skipptr)
char **argv;
+ int argc;
char *sstr;
char *lstr;
int minlen;
{
char *p;
int arglen;
- char *arg = argv[*skipptr+1];
+ 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)
}
arglen = (valptr != NULL && (p = index (arg, '=')) != NULL
? p - arg : strlen (arg));
- if (arglen < minlen || strncmp (arg, lstr, arglen) != 0)
+ if (lstr == 0 || arglen < minlen || strncmp (arg, lstr, arglen) != 0)
return 0;
else if (valptr == NULL)
{
extern int errno;
extern sys_nerr;
+ 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 (argmatch (argv, "-nl", "--no-shared-memory", 6, NULL, &skip_args))
+ 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;
-
- /* We don't check for a long option --display here, since the X code
- won't be able to recognize that form anyway. */
- 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 */
{
char *file;
- if (argmatch (argv, "-map", "--map-data", 3, &mapin_file, &skip_args))
+ if (argmatch (argv, argc, "-map", "--map-data", 3, &mapin_file, &skip_args))
mapin_data (file);
}
/* Handle the -t switch, which specifies filename to use as terminal */
{
char *term;
- if (argmatch (argv, "-t", "--terminal", 4, &term, &skip_args))
+ if (argmatch (argv, argc, "-t", "--terminal", 4, &term, &skip_args))
{
int result;
close (0);
#endif
}
}
- if (argmatch (argv, "-nw", "--no-windows", 6, NULL, &skip_args))
+ if (argmatch (argv, argc, "-nw", "--no-windows", 6, NULL, &skip_args))
inhibit_window_system = 1;
/* Handle the -batch switch, which means don't do interactive display. */
noninteractive = 0;
- if (argmatch (argv, "-batch", "--batch", 5, NULL, &skip_args))
+ if (argmatch (argv, argc, "-batch", "--batch", 5, NULL, &skip_args))
noninteractive = 1;
/* Handle the --help option, which gives a usage message.. */
- if (argmatch (argv, "-help", "--help", 3, NULL, &skip_args))
+ if (argmatch (argv, argc, "-help", "--help", 3, NULL, &skip_args))
{
printf ("\
Usage: %s [-t term] [--terminal term] [-nw] [--no-windows] [--batch]\n\
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;
+ 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)
{
#ifdef BSD_PGRPS
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);
init_alloc ();
init_eval ();
init_data ();
+ running_asynch_code = 0;
#ifdef MSDOS
/* Call early 'cause init_environment needs it. */
#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
{
char *file;
/* Handle -l loadup-and-dump, args passed by Makefile. */
- if (argmatch (argv, "-l", "--load", 3, &file, &skip_args))
+ 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, "-nl", "--no-loadup", 6, NULL, &skip_args))
+ 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 */
#endif /* defined (sun) || defined (LOCALTIME_CACHE) */
/* Handle the GNU standard option --version. */
- if (argmatch (argv, "-version", "--version", 3, NULL, &skip_args))
+ if (argmatch (argv, argc, "-version", "--version", 3, NULL, &skip_args))
{
Lisp_Object ver;
ver = call0 (intern ("emacs-version"));
/* 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\
/* 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);