]> code.delx.au - gnu-emacs/blobdiff - src/emacs.c
Have 'make' output better GEN names
[gnu-emacs] / src / emacs.c
index 7367e0d35ea6cbb6caa2ad4969e750a0982ee10c..d09c3c36c8a2d8c280ddabb1300667e663b8ac9a 100644 (file)
@@ -1,6 +1,6 @@
 /* Fully extensible Emacs, running on Unix, intended for GNU.
 
 /* Fully extensible Emacs, running on Unix, intended for GNU.
 
-Copyright (C) 1985-1987, 1993-1995, 1997-1999, 2001-2014 Free Software
+Copyright (C) 1985-1987, 1993-1995, 1997-1999, 2001-2015 Free Software
 Foundation, Inc.
 
 This file is part of GNU Emacs.
 Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -51,6 +51,10 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "cygw32.h"
 #endif
 
 #include "cygw32.h"
 #endif
 
+#ifdef MSDOS
+#include <binary-io.h>
+#endif
+
 #ifdef HAVE_WINDOW_SYSTEM
 #include TERM_HEADER
 #endif /* HAVE_WINDOW_SYSTEM */
 #ifdef HAVE_WINDOW_SYSTEM
 #include TERM_HEADER
 #endif /* HAVE_WINDOW_SYSTEM */
@@ -79,7 +83,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "charset.h"
 #include "composite.h"
 #include "dispextern.h"
 #include "charset.h"
 #include "composite.h"
 #include "dispextern.h"
+#include "regex.h"
 #include "syntax.h"
 #include "syntax.h"
+#include "sysselect.h"
 #include "systime.h"
 
 #include "gnutls.h"
 #include "systime.h"
 
 #include "gnutls.h"
@@ -103,8 +109,9 @@ extern void moncontrol (int mode);
 #include <sys/personality.h>
 #endif
 
 #include <sys/personality.h>
 #endif
 
-static const char emacs_version[] = VERSION;
+static const char emacs_version[] = PACKAGE_VERSION;
 static const char emacs_copyright[] = COPYRIGHT;
 static const char emacs_copyright[] = COPYRIGHT;
+static const char emacs_bugreport[] = PACKAGE_BUGREPORT;
 
 /* Empty lisp strings.  To avoid having to build any others.  */
 Lisp_Object empty_unibyte_string, empty_multibyte_string;
 
 /* Empty lisp strings.  To avoid having to build any others.  */
 Lisp_Object empty_unibyte_string, empty_multibyte_string;
@@ -119,6 +126,9 @@ Lisp_Object Vlibrary_cache;
    on subsequent starts.  */
 bool initialized;
 
    on subsequent starts.  */
 bool initialized;
 
+/* Set to true if this instance of Emacs might dump.  */
+bool might_dump;
+
 #ifdef DARWIN_OS
 extern void unexec_init_emacs_zone (void);
 #endif
 #ifdef DARWIN_OS
 extern void unexec_init_emacs_zone (void);
 #endif
@@ -130,21 +140,14 @@ static void *malloc_state_ptr;
 /* From glibc, a routine that returns a copy of the malloc internal state.  */
 extern void *malloc_get_state (void);
 /* From glibc, a routine that overwrites the malloc internal state.  */
 /* From glibc, a routine that returns a copy of the malloc internal state.  */
 extern void *malloc_get_state (void);
 /* From glibc, a routine that overwrites the malloc internal state.  */
-extern int malloc_set_state (void*);
+extern int malloc_set_state (void *);
 /* True if the MALLOC_CHECK_ environment variable was set while
    dumping.  Used to work around a bug in glibc's malloc.  */
 static bool malloc_using_checking;
 /* True if the MALLOC_CHECK_ environment variable was set while
    dumping.  Used to work around a bug in glibc's malloc.  */
 static bool malloc_using_checking;
-#elif defined HAVE_PTHREAD && !defined SYSTEM_MALLOC
+#elif defined HAVE_PTHREAD && !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
 extern void malloc_enable_thread (void);
 #endif
 
 extern void malloc_enable_thread (void);
 #endif
 
-Lisp_Object Qfile_name_handler_alist;
-
-Lisp_Object Qrisky_local_variable;
-
-Lisp_Object Qkill_emacs;
-static Lisp_Object Qkill_emacs_hook;
-
 /* If true, Emacs should not attempt to use a window-specific code,
    but instead should use the virtual terminal under which it was started.  */
 bool inhibit_window_system;
 /* If true, Emacs should not attempt to use a window-specific code,
    but instead should use the virtual terminal under which it was started.  */
 bool inhibit_window_system;
@@ -208,7 +211,7 @@ int initial_argc;
 static void sort_args (int argc, char **argv);
 static void syms_of_emacs (void);
 
 static void sort_args (int argc, char **argv);
 static void syms_of_emacs (void);
 
-/* C89 needs each string be at most 509 characters, so the usage
+/* C99 needs each string to be at most 4095 characters, and the usage
    strings below are split to not overflow this limit.  */
 static char const *const usage_message[] =
   { "\
    strings below are split to not overflow this limit.  */
 static char const *const usage_message[] =
   { "\
@@ -319,7 +322,7 @@ abbreviation for a --option.\n\
 Various environment variables and window system resources also affect\n\
 the operation of Emacs.  See the main documentation.\n\
 \n\
 Various environment variables and window system resources also affect\n\
 the operation of Emacs.  See the main documentation.\n\
 \n\
-Report bugs to bug-gnu-emacs@gnu.org.  First, please see the Bugs\n\
+Report bugs to " PACKAGE_BUGREPORT ".  First, please see the Bugs\n\
 section of the Emacs manual or the file BUGS.\n"
   };
 
 section of the Emacs manual or the file BUGS.\n"
   };
 
@@ -384,10 +387,11 @@ terminate_due_to_signal (int sig, int backtrace_limit)
 static void
 init_cmdargs (int argc, char **argv, int skip_args, char *original_pwd)
 {
 static void
 init_cmdargs (int argc, char **argv, int skip_args, char *original_pwd)
 {
-  register int i;
+  int i;
   Lisp_Object name, dir, handler;
   ptrdiff_t count = SPECPDL_INDEX ();
   Lisp_Object raw_name;
   Lisp_Object name, dir, handler;
   ptrdiff_t count = SPECPDL_INDEX ();
   Lisp_Object raw_name;
+  AUTO_STRING (slash_colon, "/:");
 
   initial_argv = argv;
   initial_argc = argc;
 
   initial_argv = argv;
   initial_argc = argc;
@@ -411,7 +415,7 @@ init_cmdargs (int argc, char **argv, int skip_args, char *original_pwd)
      if it would otherwise be treated as magic.  */
   handler = Ffind_file_name_handler (raw_name, Qt);
   if (! NILP (handler))
      if it would otherwise be treated as magic.  */
   handler = Ffind_file_name_handler (raw_name, Qt);
   if (! NILP (handler))
-    raw_name = concat2 (build_string ("/:"), raw_name);
+    raw_name = concat2 (slash_colon, raw_name);
 
   Vinvocation_name = Ffile_name_nondirectory (raw_name);
   Vinvocation_directory = Ffile_name_directory (raw_name);
 
   Vinvocation_name = Ffile_name_nondirectory (raw_name);
   Vinvocation_directory = Ffile_name_directory (raw_name);
@@ -429,7 +433,7 @@ init_cmdargs (int argc, char **argv, int skip_args, char *original_pwd)
             if it would otherwise be treated as magic.  */
          handler = Ffind_file_name_handler (found, Qt);
          if (! NILP (handler))
             if it would otherwise be treated as magic.  */
          handler = Ffind_file_name_handler (found, Qt);
          if (! NILP (handler))
-           found = concat2 (build_string ("/:"), found);
+           found = concat2 (slash_colon, found);
          Vinvocation_directory = Ffile_name_directory (found);
        }
     }
          Vinvocation_directory = Ffile_name_directory (found);
        }
     }
@@ -565,12 +569,6 @@ DEFUN ("invocation-directory", Finvocation_directory, Sinvocation_directory,
 }
 
 \f
 }
 
 \f
-#ifdef HAVE_TZSET
-/* A valid but unlikely value for the TZ environment value.
-   It is OK (though a bit slower) if the user actually chooses this value.  */
-static char const dump_tz[] = "UtC0";
-#endif
-
 /* 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
 /* 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
@@ -723,18 +721,13 @@ main (int argc, char **argv)
   stack_base = &dummy;
 #endif
 
   stack_base = &dummy;
 #endif
 
-#ifdef G_SLICE_ALWAYS_MALLOC
-  /* This is used by the Cygwin build.  It's not needed starting with
-     cygwin-1.7.24, but it doesn't do any harm.  */
-  xputenv ("G_SLICE=always-malloc");
+#ifndef CANNOT_DUMP
+  might_dump = !initialized;
 #endif
 
 #ifdef GNU_LINUX
   if (!initialized)
     {
 #endif
 
 #ifdef GNU_LINUX
   if (!initialized)
     {
-      extern char my_endbss[];
-      extern char *my_endbss_static;
-
       if (my_heap_start == 0)
         my_heap_start = sbrk (0);
 
       if (my_heap_start == 0)
         my_heap_start = sbrk (0);
 
@@ -801,10 +794,10 @@ main (int argc, char **argv)
          version = emacs_version;
          copyright = emacs_copyright;
        }
          version = emacs_version;
          copyright = emacs_copyright;
        }
-      printf ("GNU Emacs %s\n", version);
+      printf ("%s %s\n", PACKAGE_NAME, version);
       printf ("%s\n", copyright);
       printf ("%s\n", copyright);
-      printf ("GNU Emacs comes with ABSOLUTELY NO WARRANTY.\n");
-      printf ("You may redistribute copies of Emacs\n");
+      printf ("%s comes with ABSOLUTELY NO WARRANTY.\n", PACKAGE_NAME);
+      printf ("You may redistribute copies of %s\n", PACKAGE_NAME);
       printf ("under the terms of the GNU General Public License.\n");
       printf ("For more information about these matters, ");
       printf ("see the file named COPYING.\n");
       printf ("under the terms of the GNU General Public License.\n");
       printf ("For more information about these matters, ");
       printf ("see the file named COPYING.\n");
@@ -863,7 +856,6 @@ main (int argc, char **argv)
       && !getrlimit (RLIMIT_STACK, &rlim))
     {
       long newlim;
       && !getrlimit (RLIMIT_STACK, &rlim))
     {
       long newlim;
-      extern size_t 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
       /* 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
@@ -897,7 +889,7 @@ main (int argc, char **argv)
 
   clearerr (stdin);
 
 
   clearerr (stdin);
 
-#ifndef SYSTEM_MALLOC
+#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
   /* 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);
 
@@ -905,22 +897,12 @@ main (int argc, char **argv)
      Also call realloc and free for consistency.  */
   free (realloc (malloc (4), 4));
 
      Also call realloc and free for consistency.  */
   free (realloc (malloc (4), 4));
 
-#endif /* not SYSTEM_MALLOC */
-
-#if defined (MSDOS) || defined (WINDOWSNT)
-  /* We do all file input/output as binary files.  When we need to translate
-     newlines, we do that manually.  */
-  _fmode = O_BINARY;
-#endif /* MSDOS || WINDOWSNT */
+#endif /* not SYSTEM_MALLOC and not HYBRID_MALLOC */
 
 #ifdef MSDOS
 
 #ifdef MSDOS
-  if (!isatty (fileno (stdin)))
-    setmode (fileno (stdin), O_BINARY);
-  if (!isatty (fileno (stdout)))
-    {
-      fflush (stdout);
-      setmode (fileno (stdout), O_BINARY);
-    }
+  SET_BINARY (fileno (stdin));
+  fflush (stdout);
+  SET_BINARY (fileno (stdout));
 #endif /* MSDOS */
 
   /* Skip initial setlocale if LC_ALL is "C", as it's not needed in that case.
 #endif /* MSDOS */
 
   /* Skip initial setlocale if LC_ALL is "C", as it's not needed in that case.
@@ -998,7 +980,7 @@ main (int argc, char **argv)
     {
       int i;
       printf ("Usage: %s [OPTION-OR-FILENAME]...\n", argv[0]);
     {
       int i;
       printf ("Usage: %s [OPTION-OR-FILENAME]...\n", argv[0]);
-      for (i = 0; i < sizeof usage_message / sizeof *usage_message; i++)
+      for (i = 0; i < ARRAYELTS (usage_message); i++)
        fputs (usage_message[i], stdout);
       exit (0);
     }
        fputs (usage_message[i], stdout);
       exit (0);
     }
@@ -1140,12 +1122,13 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
 #endif /* DOS_NT */
     }
 
 #endif /* DOS_NT */
     }
 
-#if defined HAVE_PTHREAD && !defined SYSTEM_MALLOC && !defined DOUG_LEA_MALLOC
+#if defined HAVE_PTHREAD && !defined SYSTEM_MALLOC \
+  && !defined DOUG_LEA_MALLOC && !defined HYBRID_MALLOC
 # ifndef CANNOT_DUMP
   /* Do not make gmalloc thread-safe when creating bootstrap-emacs, as
 # ifndef CANNOT_DUMP
   /* Do not make gmalloc thread-safe when creating bootstrap-emacs, as
-     that causes an infinite recursive loop with FreeBSD.  But do make
-     it thread-safe when creating emacs, otherwise bootstrap-emacs
-     fails on Cygwin.  See Bug#14569.  */
+     that causes an infinite recursive loop with FreeBSD.  See
+     Bug#14569.  The part of this bug involving Cygwin is no longer
+     relevant, now that Cygwin defines HYBRID_MALLOC.  */
   if (!noninteractive || initialized)
 # endif
     malloc_enable_thread ();
   if (!noninteractive || initialized)
 # endif
     malloc_enable_thread ();
@@ -1366,7 +1349,8 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
   xputenv ("LANG=C");
 #endif
 
   xputenv ("LANG=C");
 #endif
 
-  init_buffer ();      /* Init default directory of main buffer.  */
+  /* Init buffer storage and default directory of main buffer.  */
+  init_buffer (initialized);
 
   init_callproc_1 ();  /* Must precede init_cmdargs and init_sys_modes.  */
 
 
   init_callproc_1 ();  /* Must precede init_cmdargs and init_sys_modes.  */
 
@@ -1547,8 +1531,23 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
 
   init_charset ();
 
 
   init_charset ();
 
-  init_editfns (); /* init_process_emacs uses Voperating_system_release. */
-  init_process_emacs (); /* init_display uses add_keyboard_wait_descriptor. */
+  /* This calls putenv and so must precede init_process_emacs.  Also,
+     it sets Voperating_system_release, which init_process_emacs uses.  */
+  init_editfns ();
+
+  /* These two call putenv.  */
+#ifdef HAVE_DBUS
+  init_dbusbind ();
+#endif
+#ifdef USE_GTK
+  init_xterm ();
+#endif
+
+  /* This can create a thread that may call getenv, so it must follow
+     all calls to putenv and setenv.  Also, this sets up
+     add_keyboard_wait_descriptor, which init_display uses.  */
+  init_process_emacs ();
+
   init_keyboard ();    /* This too must precede init_sys_modes.  */
   if (!noninteractive)
     init_display ();   /* Determine terminal type.  Calls init_sys_modes.  */
   init_keyboard ();    /* This too must precede init_sys_modes.  */
   if (!noninteractive)
     init_display ();   /* Determine terminal type.  Calls init_sys_modes.  */
@@ -1585,26 +1584,6 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
                            build_string ("loadup.el"));
     }
 
                            build_string ("loadup.el"));
     }
 
-  if (initialized)
-    {
-#ifdef HAVE_TZSET
-      {
-       /* If the execution TZ happens to be the same as the dump TZ,
-          change it to some other value and then change it back,
-          to force the underlying implementation to reload the TZ info.
-          This is needed on implementations that load TZ info from files,
-          since the TZ file contents may differ between dump and execution.  */
-       char *tz = getenv ("TZ");
-       if (tz && !strcmp (tz, dump_tz))
-         {
-           ++*tz;
-           tzset ();
-           --*tz;
-         }
-      }
-#endif
-    }
-
   /* Set up for profiling.  This is known to work on FreeBSD,
      GNU/Linux and MinGW.  It might work on some other systems too.
      Give it a try and tell us if it works on your system.  To compile
   /* Set up for profiling.  This is known to work on FreeBSD,
      GNU/Linux and MinGW.  It might work on some other systems too.
      Give it a try and tell us if it works on your system.  To compile
@@ -1629,15 +1608,6 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
 
   initialized = 1;
 
 
   initialized = 1;
 
-#ifdef LOCALTIME_CACHE
-  /* Some versions of localtime have a bug.  They cache 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 /* defined (LOCALTIME_CACHE) */
-
   /* Enter editor command loop.  This never returns.  */
   Frecursive_edit ();
   /* NOTREACHED */
   /* Enter editor command loop.  This never returns.  */
   Frecursive_edit ();
   /* NOTREACHED */
@@ -1805,7 +1775,7 @@ sort_args (int argc, char **argv)
            }
 
          /* Look for a match with a known old-fashioned option.  */
            }
 
          /* Look for a match with a known old-fashioned option.  */
-         for (i = 0; i < sizeof (standard_args) / sizeof (standard_args[0]); i++)
+         for (i = 0; i < ARRAYELTS (standard_args); i++)
            if (!strcmp (argv[from], standard_args[i].name))
              {
                options[from] = standard_args[i].nargs;
            if (!strcmp (argv[from], standard_args[i].name))
              {
                options[from] = standard_args[i].nargs;
@@ -1827,8 +1797,7 @@ sort_args (int argc, char **argv)
 
              match = -1;
 
 
              match = -1;
 
-             for (i = 0;
-                  i < sizeof (standard_args) / sizeof (standard_args[0]); i++)
+             for (i = 0; i < ARRAYELTS (standard_args); i++)
                if (standard_args[i].longname
                    && !strncmp (argv[from], standard_args[i].longname,
                                 thislen))
                if (standard_args[i].longname
                    && !strncmp (argv[from], standard_args[i].longname,
                                 thislen))
@@ -1937,7 +1906,7 @@ all of which are called before Emacs is actually killed.  */)
   /* Fsignal calls emacs_abort () if it sees that waiting_for_input is
      set.  */
   waiting_for_input = 0;
   /* Fsignal calls emacs_abort () if it sees that waiting_for_input is
      set.  */
   waiting_for_input = 0;
-  Frun_hooks (1, &Qkill_emacs_hook);
+  run_hook (Qkill_emacs_hook);
   UNGCPRO;
 
 #ifdef HAVE_X_WINDOWS
   UNGCPRO;
 
 #ifdef HAVE_X_WINDOWS
@@ -2021,9 +1990,7 @@ shut_down_emacs (int sig, Lisp_Object stuff)
   kill_buffer_processes (Qnil);
   Fdo_auto_save (Qt, Qnil);
 
   kill_buffer_processes (Qnil);
   Fdo_auto_save (Qt, Qnil);
 
-#ifdef CLASH_DETECTION
   unlock_all_files ();
   unlock_all_files ();
-#endif
 
   /* There is a tendency for a SIGIO signal to arrive within exit,
      and cause a SIGHUP because the input descriptor is already closed.  */
 
   /* There is a tendency for a SIGIO signal to arrive within exit,
      and cause a SIGHUP because the input descriptor is already closed.  */
@@ -2078,6 +2045,9 @@ You must run Emacs in batch mode in order to dump it.  */)
   if (! noninteractive)
     error ("Dumping Emacs works only in batch mode");
 
   if (! noninteractive)
     error ("Dumping Emacs works only in batch mode");
 
+  if (!might_dump)
+    error ("Emacs can be dumped only once");
+
 #ifdef GNU_LINUX
 
   /* Warn if the gap between BSS end and heap start is larger than this.  */
 #ifdef GNU_LINUX
 
   /* Warn if the gap between BSS end and heap start is larger than this.  */
@@ -2118,38 +2088,22 @@ You must run Emacs in batch mode in order to dump it.  */)
   tem = Vpurify_flag;
   Vpurify_flag = Qnil;
 
   tem = Vpurify_flag;
   Vpurify_flag = Qnil;
 
-#ifdef HAVE_TZSET
-  set_time_zone_rule (dump_tz);
-#ifndef LOCALTIME_CACHE
-  /* Force a tz reload, since set_time_zone_rule doesn't.  */
-  tzset ();
-#endif
-#endif
-
   fflush (stdout);
   /* Tell malloc where start of impure now is.  */
   /* Also arrange for warnings when nearly out of space.  */
   fflush (stdout);
   /* Tell malloc where start of impure now is.  */
   /* Also arrange for warnings when nearly out of space.  */
-#ifndef SYSTEM_MALLOC
+#if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
 #ifndef WINDOWSNT
   /* On Windows, this was done before dumping, and that once suffices.
      Meanwhile, my_edata is not valid on Windows.  */
 #ifndef WINDOWSNT
   /* On Windows, this was done before dumping, and that once suffices.
      Meanwhile, my_edata is not valid on Windows.  */
-  {
-    extern char my_edata[];
-    memory_warnings (my_edata, malloc_warning);
-  }
+  memory_warnings (my_edata, malloc_warning);
 #endif /* not WINDOWSNT */
 #endif /* not WINDOWSNT */
-#endif /* not SYSTEM_MALLOC */
+#endif /* not SYSTEM_MALLOC and not HYBRID_MALLOC */
 #ifdef DOUG_LEA_MALLOC
   malloc_state_ptr = malloc_get_state ();
 #endif
 
 #ifdef DOUG_LEA_MALLOC
   malloc_state_ptr = malloc_get_state ();
 #endif
 
-#ifdef USE_MMAP_FOR_BUFFERS
-  mmap_set_vars (0);
-#endif
   unexec (SSDATA (filename), !NILP (symfile) ? SSDATA (symfile) : 0);
   unexec (SSDATA (filename), !NILP (symfile) ? SSDATA (symfile) : 0);
-#ifdef USE_MMAP_FOR_BUFFERS
-  mmap_set_vars (1);
-#endif
+
 #ifdef DOUG_LEA_MALLOC
   free (malloc_state_ptr);
 #endif
 #ifdef DOUG_LEA_MALLOC
   free (malloc_state_ptr);
 #endif
@@ -2331,7 +2285,10 @@ decode_env_path (const char *evarname, const char *defalt, bool empty)
             }
 
           if (! NILP (tem))
             }
 
           if (! NILP (tem))
-            element = concat2 (build_string ("/:"), element);
+           {
+             AUTO_STRING (slash_colon, "/:");
+             element = concat2 (slash_colon, element);
+           }
         } /* !NILP (element) */
 
       lpath = Fcons (element, lpath);
         } /* !NILP (element) */
 
       lpath = Fcons (element, lpath);
@@ -2448,6 +2405,12 @@ Emacs is running.  */);
               doc: /* String containing the configuration options Emacs was built with.  */);
   Vsystem_configuration_options = build_string (EMACS_CONFIG_OPTIONS);
 
               doc: /* String containing the configuration options Emacs was built with.  */);
   Vsystem_configuration_options = build_string (EMACS_CONFIG_OPTIONS);
 
+  DEFVAR_LISP ("system-configuration-features", Vsystem_configuration_features,
+              doc: /* String listing some of the main features this Emacs was compiled with.
+An element of the form \"FOO\" generally means that HAVE_FOO was
+defined during the build.  */);
+  Vsystem_configuration_features = build_string (EMACS_CONFIG_FEATURES);
+
   DEFVAR_BOOL ("noninteractive", noninteractive1,
               doc: /* Non-nil means Emacs is running without interactive terminal.  */);
 
   DEFVAR_BOOL ("noninteractive", noninteractive1,
               doc: /* Non-nil means Emacs is running without interactive terminal.  */);
 
@@ -2525,6 +2488,10 @@ This is nil during initialization.  */);
               doc: /* Version numbers of this version of Emacs.  */);
   Vemacs_version = build_string (emacs_version);
 
               doc: /* Version numbers of this version of Emacs.  */);
   Vemacs_version = build_string (emacs_version);
 
+  DEFVAR_LISP ("report-emacs-bug-address", Vreport_emacs_bug_address,
+              doc: /* Address of mailing list for GNU Emacs bugs.  */);
+  Vreport_emacs_bug_address = build_string (emacs_bugreport);
+
   DEFVAR_LISP ("dynamic-library-alist", Vdynamic_library_alist,
     doc: /* Alist of dynamic libraries vs external files implementing them.
 Each element is a list (LIBRARY FILE...), where the car is a symbol
   DEFVAR_LISP ("dynamic-library-alist", Vdynamic_library_alist,
     doc: /* Alist of dynamic libraries vs external files implementing them.
 Each element is a list (LIBRARY FILE...), where the car is a symbol