]> code.delx.au - gnu-emacs/blobdiff - src/emacs.c
(adjust_markers_for_delete): Fix last change.
[gnu-emacs] / src / emacs.c
index cad3a5ca7dad923ea4a165bccb13e96f5db9d5b6..521225687dfdfeedab75e145e8b1b2239cf0015e 100644 (file)
@@ -1,5 +1,5 @@
 /* Fully extensible Emacs, running on Unix, intended for GNU.
-   Copyright (C) 1985,86,87,93,94,95,97,1998 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.
 
@@ -19,10 +19,9 @@ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
 
+#include <config.h>
 #include <signal.h>
 #include <errno.h>
-
-#include <config.h>
 #include <stdio.h>
 
 #include <sys/types.h>
@@ -32,6 +31,10 @@ Boston, MA 02111-1307, USA.  */
 #include <ssdef.h>
 #endif
 
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
 #ifdef BSD_SYSTEM
 #include <sys/ioctl.h>
 #endif
@@ -45,8 +48,13 @@ Boston, MA 02111-1307, USA.  */
 #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>
 #include <sys/resource.h>
@@ -59,7 +67,18 @@ Boston, MA 02111-1307, USA.  */
 extern void malloc_warning ();
 extern void set_time_zone_rule ();
 extern char *index ();
-extern char *strerror ();
+
+/* 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;
@@ -102,6 +121,9 @@ void *malloc_state_ptr;
 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.  */
@@ -116,6 +138,12 @@ Lisp_Object Vsystem_configuration_options;
 
 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;
@@ -180,40 +208,38 @@ int fatal_error_code;
 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;
-    }
+  struct input_event buf;
+
+  buf.kind = user_signal;
+  buf.code = 0;
+  buf.frame_or_window = selected_frame;
+  buf.modifiers = 0;
+  buf.timestamp = 0;
+
+  kbd_buffer_store_event (&buf);
 }
+#endif /* SIGUSR1 */
 
 #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;
-    }
+  struct input_event buf;
+
+  buf.kind = user_signal;
+  buf.code = 1;
+  buf.frame_or_window = selected_frame;
+  buf.modifiers = 0;
+  buf.timestamp = 0;
+
+  kbd_buffer_store_event (&buf);
 }
-#endif
-#endif 
+#endif /* SIGUSR2 */
 
 /* Handle bus errors, illegal instruction, etc. */
 SIGTYPE
@@ -268,7 +294,12 @@ memory_warning_signal (sig)
    MSDOS has its own definition on msdos.c  */
 
 #if ! defined (DOS_NT) && ! defined (NO_ABORT)
-void
+
+#ifndef ABORT_RETURN_TYPE
+#define ABORT_RETURN_TYPE void
+#endif
+
+ABORT_RETURN_TYPE
 abort ()
 {
   kill (getpid (), SIGABRT);
@@ -543,6 +574,47 @@ argmatch (argv, argc, sstr, lstr, minlen, valptr, skipptr)
     }
 }
 
+#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 ()
+{
+  extern char **environ;
+
+  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)
@@ -551,6 +623,7 @@ main (argc, argv, envp)
      char **envp;
 {
   char stack_bottom_variable;
+  int do_initial_setlocale;
   int skip_args = 0;
   extern int errno;
   extern int sys_nerr;
@@ -563,16 +636,6 @@ main (argc, argv, envp)
   __sbrk (1);
 #endif
 
-#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]);
@@ -597,7 +660,7 @@ main (argc, argv, envp)
       else
        {
          printf ("GNU Emacs %s\n", XSTRING (tem)->data);
-         printf ("Copyright (C) 1998 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");
@@ -707,15 +770,15 @@ main (argc, argv, envp)
   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
@@ -744,6 +807,20 @@ main (argc, argv, envp)
   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
@@ -757,9 +834,9 @@ main (argc, argv, envp)
       if (argmatch (argv, argc, "-t", "--terminal", 4, &term, &skip_args))
        {
          int result;
-         close (0);
-         close (1);
-         result = open (term, O_RDWR, 2 );
+         emacs_close (0);
+         emacs_close (1);
+         result = emacs_open (term, O_RDWR, 0);
          if (result < 0)
            {
              char *errstring = strerror (errno);
@@ -793,10 +870,12 @@ main (argc, argv, envp)
   if (argmatch (argv, argc, "-help", "--help", 3, NULL, &skip_args))
     {
       printf ("\
-Usage: %s [-t term] [--terminal term]  [-nw] [--no-windows]  [--batch]\n\
+Usage: %s [--batch]  [-t term] [--terminal term]\n\
+      [-d display] [--display display]  [-nw] [--no-windows]\n\
       [-q] [--no-init-file]  [-u user] [--user user]  [--debug-init]\n\
       [--unibyte] [--multibyte] [--version] [--no-site-file]\n\
-      [-f func] [--funcall func]  [-l file] [--load file]  [--insert file]\n\
+      [-f func] [--funcall func]  [-l file] [--load file]  [--eval expr]\n\
+      [--execute expr] [--visit file] [--file file] [--insert file]\n\
       [+linenum] file-to-visit  [--kill]\n\
 Report bugs to bug-gnu-emacs@gnu.org.  First, please see\n\
 the Bugs section of the Emacs manual or the file BUGS.\n", argv[0]);
@@ -818,9 +897,7 @@ the Bugs section of the Emacs manual or the file BUGS.\n", argv[0]);
 #endif
     }
 
-#ifdef POSIX_SIGNALS
   init_signals ();
-#endif
 
   /* Don't catch SIGHUP if dumping.  */
   if (1
@@ -937,14 +1014,35 @@ the Bugs section of the Emacs manual or the file BUGS.\n", argv[0]);
       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.  */
+#ifndef HAVE_NTGUI
+      syms_of_xfaces ();
+#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_coding ();
   init_data ();
+#ifdef CLASH_DETECTION
+  init_filelock ();;
+#endif
   running_asynch_code = 0;
 
   /* Handle --unibyte and the EMACS_UNIBYTE envvar,
@@ -968,6 +1066,12 @@ the Bugs section of the Emacs manual or the file BUGS.\n", argv[0]);
         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))
@@ -988,11 +1092,11 @@ the Bugs section of the Emacs manual or the file BUGS.\n", argv[0]);
            }
 
          for (tail = Vbuffer_alist; CONSP (tail);
-              tail = XCONS (tail)->cdr)
+              tail = XCDR (tail))
            {
              Lisp_Object buffer;
 
-             buffer = Fcdr (XCONS (tail)->car);
+             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)))
@@ -1014,7 +1118,6 @@ the Bugs section of the Emacs manual or the file BUGS.\n", argv[0]);
      to run until we've recognized this argument.  */
   {
     char *displayname = 0;
-    int i;
     int count_before = skip_args;
 
     /* Skip any number of -d options, but only use the last one.  */
@@ -1075,7 +1178,7 @@ the Bugs section of the Emacs manual or the file BUGS.\n", argv[0]);
 
 #ifdef WINDOWSNT
   /* Initialize environment from registry settings.  */
-  init_environment ();
+  init_environment (argv);
   init_ntproc ();      /* must precede init_editfns */
 #endif
 
@@ -1086,7 +1189,8 @@ the Bugs section of the Emacs manual or the file BUGS.\n", argv[0]);
   /* 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
 
@@ -1161,8 +1265,10 @@ the Bugs section of the Emacs manual or the file BUGS.\n", argv[0]);
       syms_of_syntax ();
       syms_of_term ();
       syms_of_undo ();
+#ifdef HAVE_SOUND
+      syms_of_sound ();
+#endif
 
-      /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
       syms_of_textprop ();
 #ifdef VMS
       syms_of_vmsproc ();
@@ -1182,7 +1288,6 @@ the Bugs section of the Emacs manual or the file BUGS.\n", argv[0]);
 #endif /* HAVE_X_WINDOWS */
 
 #ifndef HAVE_NTGUI
-      syms_of_xfaces ();
       syms_of_xmenu ();
 #endif
 
@@ -1192,6 +1297,7 @@ the Bugs section of the Emacs manual or the file BUGS.\n", argv[0]);
       syms_of_w32faces ();
       syms_of_w32select ();
       syms_of_w32menu ();
+      syms_of_fontset ();
 #endif /* HAVE_NTGUI */
 
 #ifdef SYMS_SYSTEM
@@ -1225,6 +1331,10 @@ the Bugs section of the Emacs manual or the file BUGS.\n", argv[0]);
   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 ();
@@ -1235,6 +1345,9 @@ the Bugs section of the Emacs manual or the file BUGS.\n", argv[0]);
   init_vmsfns ();
 #endif /* VMS */
   init_process ();
+#ifdef HAVE_SOUND
+  init_sound ();
+#endif
 
   if (!initialized)
     {
@@ -1274,20 +1387,22 @@ the Bugs section of the Emacs manual or the file BUGS.\n", argv[0]);
   /* 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);
+      // atexit (dump_opcode_frequencies);
+      /* 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);
@@ -1387,8 +1502,10 @@ struct standard_args standard_args[] =
   { "-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 },
@@ -1419,7 +1536,6 @@ sort_args (argc, argv)
   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.  */
@@ -1540,6 +1656,10 @@ sort_args (argc, argv)
        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);
@@ -1557,8 +1677,6 @@ all of which are called before Emacs is actually killed.")
   (arg)
      Lisp_Object arg;
 {
-  Lisp_Object hook, hook1;
-  int i;
   struct gcpro gcpro1;
 
   GCPRO1 (arg);
@@ -1670,6 +1788,9 @@ shut_down_emacs (sig, no_x, stuff)
   term_ntproc ();
 #endif
 
+  check_glyph_memory ();
+  check_message_stack ();
+
 #ifdef MSDOS
   dos_cleanup ();
 #endif
@@ -1786,6 +1907,53 @@ You must run Emacs in batch mode in order to dump it.")
 
 #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
@@ -1930,4 +2098,21 @@ 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;
+
+  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;
 }