(Qforeground_color, Qbackground_color): Declare.
[bpt/emacs.git] / src / emacs.c
index 7e6ac14..8d402f0 100644 (file)
@@ -1,5 +1,5 @@
 /* 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,1998 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -44,6 +44,7 @@ Boston, MA 02111-1307, USA.  */
 #include "blockinput.h"
 #include "syssignal.h"
 #include "process.h"
+#include "keyboard.h"
 
 #ifdef HAVE_SETRLIMIT
 #include <sys/time.h>
@@ -76,6 +77,14 @@ Lisp_Object Vinstallation_directory;
 /* 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
+
 /* Set nonzero after Emacs has started up the first time.
   Prevents reinitialization of the Lisp world and keymaps
   on subsequent starts.  */
@@ -158,6 +167,7 @@ char **initial_argv;
 int initial_argc;
 
 static void sort_args ();
+void syms_of_emacs ();
 \f
 /* Signal code for the fatal signal that was received */
 int fatal_error_code;
@@ -165,6 +175,42 @@ int fatal_error_code;
 /* Nonzero if handling a fatal error already */
 int fatal_error_in_progress;
 
+#ifdef SIGUSR1
+int SIGUSR1_in_progress=0;
+SIGTYPE
+handle_USR1_signal (sig)
+     int sig;
+{
+  if (! SIGUSR1_in_progress)
+    {
+      SIGUSR1_in_progress = 1;
+      
+      if (!NILP (Vrun_hooks) && !noninteractive)
+       call1 (Vrun_hooks, intern ("signal-USR1-hook"));
+      
+      SIGUSR1_in_progress = 0;
+    }
+}
+
+#ifdef SIGUSR2
+int SIGUSR2_in_progress=0;
+SIGTYPE
+handle_USR2_signal (sig)
+     int sig;
+{
+  if (! SIGUSR2_in_progress)
+    {
+      SIGUSR2_in_progress = 1;
+      
+      if (!NILP (Vrun_hooks) && !noninteractive)
+       call1 (Vrun_hooks, intern ("signal-USR2-hook"));
+      
+      SIGUSR2_in_progress = 0;
+    }
+}
+#endif
+#endif 
+
 /* Handle bus errors, illegal instruction, etc. */
 SIGTYPE
 fatal_error_signal (sig)
@@ -212,10 +258,23 @@ memory_warning_signal (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  */
+
+#ifndef DOS_NT
+void
+abort ()
+{
+  kill (getpid (), SIGABRT);
+}
+#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;
@@ -392,11 +451,11 @@ static char dump_tz[] = "UtC0";
    (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
@@ -404,7 +463,7 @@ char * __CTOR_LIST__[2] = { (char *) (-1), 0 };
 #endif
 char * __DTOR_LIST__[2] = { (char *) (-1), 0 };
 #endif /* GCC_CTORS_IN_LIBC */
-__main ()
+void __main ()
 {}
 #endif /* __GNUC__ */
 #endif /* ORDINARY_LINK */
@@ -479,6 +538,7 @@ argmatch (argv, argc, sstr, lstr, minlen, valptr, skipptr)
 }
 
 /* ARGSUSED */
+int
 main (argc, argv, envp)
      int argc;
      char **argv;
@@ -487,7 +547,7 @@ main (argc, argv, envp)
   char stack_bottom_variable;
   int skip_args = 0;
   extern int errno;
-  extern sys_nerr;
+  extern int sys_nerr;
 #ifdef HAVE_SETRLIMIT
   struct rlimit rlim;
 #endif
@@ -499,12 +559,18 @@ main (argc, argv, envp)
 #ifdef DOUG_LEA_MALLOC
   if (initialized)
     {
+      extern void r_alloc_reinit ();
       malloc_set_state (malloc_state_ptr);
       free (malloc_state_ptr);
       r_alloc_reinit ();
     }
 #endif
 
+#ifdef RUN_TIME_REMAP
+  if (initialized)
+    run_time_remap (argv[0]);
+#endif
+
   sort_args (argc, argv);
 
   if (argmatch (argv, argc, "-version", "--version", 3, NULL, &skip_args))
@@ -519,7 +585,7 @@ main (argc, argv, envp)
       else
        {
          printf ("GNU Emacs %s\n", XSTRING (tem)->data);
-         printf ("Copyright (C) 1996 Free Software Foundation, Inc.\n");
+         printf ("Copyright (C) 1997 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");
@@ -579,12 +645,25 @@ main (argc, argv, envp)
 #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
@@ -593,7 +672,11 @@ main (argc, argv, envp)
       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;
 
@@ -604,11 +687,6 @@ main (argc, argv, envp)
   /* 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);
@@ -660,6 +738,29 @@ main (argc, argv, envp)
 
   inhibit_window_system = 0;
 
+  {
+    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.  */
+    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 symbol;
+       symbol = intern ("default-enable-multibyte-characters");
+       Fset (symbol, Qnil);
+       Fset_default (symbol, Qnil);
+      }
+  }
+
   /* Handle the -t switch, which specifies filename to use as terminal */
   {
     char *term;
@@ -800,6 +901,12 @@ the Bugs section of the Emacs manual or the file BUGS.\n", argv[0]);
       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
@@ -926,7 +1033,7 @@ the Bugs section of the Emacs manual or the file BUGS.\n", argv[0]);
       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;
     }
 
@@ -1095,6 +1202,29 @@ the Bugs section of the Emacs manual or the file BUGS.\n", argv[0]);
 #endif
     }
 
+  /* 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__
+#ifdef PROFILING
+  if (initialized)
+    {
+      extern void _mcleanup ();       
+      extern char etext;
+      extern Lisp_Object Fredraw_frame ();
+      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);
+    }
+  else
+    moncontrol (0);
+#endif
+#endif
+
   initialized = 1;
 
 #ifdef LOCALTIME_CACHE
@@ -1132,6 +1262,10 @@ struct standard_args standard_args[] =
 #ifdef VMS
   { "-map", "--map-data", 100, 0 },
 #endif
+  { "-no-unibyte", "--no-unibyte", 96, 0 },
+  { "-multibyte", "--multibyte", 96, 0 },
+  { "-unibyte", "--unibyte", 95, 0 },
+  { "-no-multibyte", "--no-multibyte", 95, 0 },
   { "-t", "--terminal", 90, 1 },
   { "-d", "--display", 80, 1 },
   { "-display", 0, 80, 1 },
@@ -1448,6 +1582,10 @@ shut_down_emacs (sig, no_x, stuff)
 #ifdef WINDOWSNT
   term_ntproc ();
 #endif
+
+#ifdef MSDOS
+  dos_cleanup ();
+#endif
 }
 
 
@@ -1618,6 +1756,7 @@ decode_env_path (evarname, defalt)
   return Fnreverse (lpath);
 }
 
+void
 syms_of_emacs ()
 {
   Qfile_name_handler_alist = intern ("file-name-handler-alist");
@@ -1662,6 +1801,18 @@ expect to be able to interact with the user.  To ask for confirmation,\n\
 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 recieves a USR1 signal");
+  Vsignal_USR1_hook = Qnil;
+#ifdef SIGUSR2
+  DEFVAR_LISP ("signal-USR2-hook", &Vsignal_USR2_hook,
+    "Hook to be run whenever emacs recieves 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\