]> code.delx.au - gnu-emacs/blobdiff - src/emacs.c
(adjust_markers_for_delete): Fix last change.
[gnu-emacs] / src / emacs.c
index d01f55aa393eb18de0a0c84f5ce39de1bc9fd930..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
@@ -48,6 +51,10 @@ Boston, MA 02111-1307, USA.  */
 #include "termhooks.h"
 #include "keyboard.h"
 
+#ifdef HAVE_SETLOCALE
+#include <locale.h>
+#endif
+
 #ifdef HAVE_SETRLIMIT
 #include <sys/time.h>
 #include <sys/resource.h>
@@ -60,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;
@@ -103,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.  */
@@ -117,7 +138,11 @@ Lisp_Object Vsystem_configuration_options;
 
 Lisp_Object Qfile_name_handler_alist;
 
-Lisp_Object Qusr1_signal, Qusr2_signal;
+/* 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 */
@@ -189,9 +214,9 @@ handle_USR1_signal (sig)
 {
   struct input_event buf;
 
-  buf.kind = non_ascii_keystroke;
-  buf.code = Qusr1_signal;
-  buf.frame_or_window = Fselected_frame ();
+  buf.kind = user_signal;
+  buf.code = 0;
+  buf.frame_or_window = selected_frame;
   buf.modifiers = 0;
   buf.timestamp = 0;
 
@@ -206,9 +231,9 @@ handle_USR2_signal (sig)
 {
   struct input_event buf;
 
-  buf.kind = non_ascii_keystroke;
-  buf.code = Qusr2_signal;
-  buf.frame_or_window = Fselected_frame ();
+  buf.kind = user_signal;
+  buf.code = 1;
+  buf.frame_or_window = selected_frame;
   buf.modifiers = 0;
   buf.timestamp = 0;
 
@@ -269,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);
@@ -544,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)
@@ -552,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;
@@ -564,14 +636,6 @@ main (argc, argv, envp)
   __sbrk (1);
 #endif
 
-#ifdef DOUG_LEA_MALLOC
-  if (initialized)
-    {
-      malloc_set_state (malloc_state_ptr);
-      free (malloc_state_ptr);
-    }
-#endif
-
 #ifdef RUN_TIME_REMAP
   if (initialized)
     run_time_remap (argv[0]);
@@ -743,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
@@ -756,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);
@@ -797,7 +875,8 @@ Usage: %s [--batch]  [-t term] [--terminal term]\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]  [--eval expr]\n\
-      [--insert file] [+linenum] file-to-visit  [--kill]\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]);
       exit (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,15 +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,
@@ -995,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)))
@@ -1021,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.  */
@@ -1093,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
 
@@ -1168,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 ();
@@ -1189,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
 
@@ -1233,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 ();
@@ -1243,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)
     {
@@ -1282,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);
@@ -1395,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 },
@@ -1427,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.  */
@@ -1569,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);
@@ -1682,6 +1788,9 @@ shut_down_emacs (sig, no_x, stuff)
   term_ntproc ();
 #endif
 
+  check_glyph_memory ();
+  check_message_stack ();
+
 #ifdef MSDOS
   dos_cleanup ();
 #endif
@@ -1798,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
@@ -1861,11 +2017,6 @@ syms_of_emacs ()
   Qfile_name_handler_alist = intern ("file-name-handler-alist");
   staticpro (&Qfile_name_handler_alist);
 
-  Qusr1_signal = intern ("usr1-signal");
-  staticpro (&Qusr1_signal);
-  Qusr2_signal = intern ("usr2-signal");
-  staticpro (&Qusr2_signal);
-
 #ifndef CANNOT_DUMP
 #ifdef HAVE_SHM
   defsubr (&Sdump_emacs_data);
@@ -1947,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;
 }