* buffer.c (syms_of_buffer) <local-abbrev-table>: Move from abbrev.c.
[bpt/emacs.git] / src / lread.c
index 9142e0c..189fcc0 100644 (file)
@@ -1,13 +1,13 @@
 /* Lisp parsing and input streams.
    Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994, 1995,
                  1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-                 2005, 2006 Free Software Foundation, Inc.
+                 2005, 2006, 2007 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -38,6 +38,7 @@ Boston, MA 02110-1301, USA.  */
 #include "frame.h"
 #include "termhooks.h"
 #include "coding.h"
+#include "blockinput.h"
 
 #ifdef lint
 #include <sys/inode.h>
@@ -94,7 +95,7 @@ Lisp_Object Qfile_truename, Qdo_after_load_evaluation; /* ACM 2006/5/16 */
 extern Lisp_Object Qevent_symbol_element_mask;
 extern Lisp_Object Qfile_exists_p;
 
-/* non-zero iff inside `load' */
+/* non-zero if inside `load' */
 int load_in_progress;
 
 /* Directory in which the sources were found.  */
@@ -194,6 +195,7 @@ static file_offset prev_saved_doc_string_position;
    Fread initializes this to zero, so we need not specbind it
    or worry about what happens to it when there is an error.  */
 static int new_backquote_flag;
+static Lisp_Object Vold_style_backquotes, Qold_style_backquotes;
 
 /* A list of file names for files being loaded in Fload.  Used to
    check for recursive loads.  */
@@ -326,16 +328,20 @@ readchar (readcharfun)
 
   if (EQ (readcharfun, Qget_file_char))
     {
+      BLOCK_INPUT;
       c = getc (instream);
 #ifdef EINTR
       /* Interrupted reads have been observed while reading over the network */
       while (c == EOF && ferror (instream) && errno == EINTR)
        {
+         UNBLOCK_INPUT;
          QUIT;
+         BLOCK_INPUT;
          clearerr (instream);
          c = getc (instream);
        }
 #endif
+      UNBLOCK_INPUT;
       return c;
     }
 
@@ -416,7 +422,11 @@ unreadchar (readcharfun, c)
   else if (EQ (readcharfun, Qlambda))
     read_bytecode_char (1);
   else if (EQ (readcharfun, Qget_file_char))
-    ungetc (c, instream);
+    {
+      BLOCK_INPUT;
+      ungetc (c, instream);
+      UNBLOCK_INPUT;
+    }
   else
     call1 (readcharfun, make_number (c));
 }
@@ -492,7 +502,7 @@ read_filtered_event (no_switch_frame, ascii_required, error_nonascii,
 
 /* Read until we get an acceptable event.  */
  retry:
-  do 
+  do
     val = read_char (0, 0, 0, (input_method ? Qnil : Qt), 0,
                     NUMBERP (seconds) ? &end_time : NULL);
   while (INTEGERP (val) && XINT (val) == -2); /* wrong_kboard_jmpbuf */
@@ -627,13 +637,15 @@ DEFUN ("get-file-char", Fget_file_char, Sget_file_char, 0, 0, 0,
      ()
 {
   register Lisp_Object val;
+  BLOCK_INPUT;
   XSETINT (val, getc (instream));
+  UNBLOCK_INPUT;
   return val;
 }
 
 
 \f
-/* Value is non-zero if the file asswociated with file descriptor FD
+/* Value is non-zero if the file associated with file descriptor FD
    is a compiled Lisp file that's safe to load.  Only files compiled
    with Emacs are safe to load.  Files compiled with XEmacs can lead
    to a crash in Fbyte_code because of an incompatible change in the
@@ -689,6 +701,20 @@ load_error_handler (data)
   return Qnil;
 }
 
+static Lisp_Object
+load_warn_old_style_backquotes (file)
+     Lisp_Object file;
+{
+  if (!NILP (Vold_style_backquotes))
+    {
+      Lisp_Object args[2];
+      args[0] = build_string ("Loading `%s': old-style backquotes detected!");
+      args[1] = file;
+      Fmessage (2, args);
+    }
+  return Qnil;
+}
+
 DEFUN ("get-load-suffixes", Fget_load_suffixes, Sget_load_suffixes, 0, 0, 0,
        doc: /* Return the suffixes that `load' should try if a suffix is \
 required.
@@ -715,7 +741,7 @@ DEFUN ("load", Fload, Sload, 1, 5, 0,
        doc: /* Execute a file of Lisp code named FILE.
 First try FILE with `.elc' appended, then try with `.el',
 then try FILE unmodified (the exact suffixes in the exact order are
-determined by  `load-suffixes').  Environment variable references in
+determined by `load-suffixes').  Environment variable references in
 FILE are replaced with their values by calling `substitute-in-file-name'.
 This function searches the directories in `load-path'.
 
@@ -753,7 +779,6 @@ Return t if the file exists and loads successfully.  */)
   register FILE *stream;
   register int fd = -1;
   int count = SPECPDL_INDEX ();
-  Lisp_Object temp;
   struct gcpro gcpro1, gcpro2, gcpro3;
   Lisp_Object found, efound, hist_file_name;
   /* 1 means we printed the ".el is newer" message.  */
@@ -887,6 +912,10 @@ Return t if the file exists and loads successfully.  */)
                                    tmp))
                     : found) ;
 
+  /* Check for the presence of old-style quotes and warn about them.  */
+  specbind (Qold_style_backquotes, Qnil);
+  record_unwind_protect (load_warn_old_style_backquotes, file);
+
   if (!bcmp (SDATA (found) + SBYTES (found) - 4,
             ".elc", 4))
     /* Load .elc files directly, but not when they are
@@ -1046,7 +1075,11 @@ load_unwind (arg)  /* used as unwind-protect function in load */
 {
   FILE *stream = (FILE *) XSAVE_VALUE (arg)->pointer;
   if (stream != NULL)
-    fclose (stream);
+    {
+      BLOCK_INPUT;
+      fclose (stream);
+      UNBLOCK_INPUT;
+    }
   if (--load_in_progress < 0) load_in_progress = 0;
   return Qnil;
 }
@@ -1113,7 +1146,7 @@ in which case file-name-handlers are ignored.  */)
    On success, returns a file descriptor.  On failure, returns -1.
 
    SUFFIXES is a list of strings containing possible suffixes.
-   The empty suffix is automatically added iff the list is empty.
+   The empty suffix is automatically added if the list is empty.
 
    PREDICATE non-nil means don't open the files,
    just look for one that satisfies the predicate.  In this case,
@@ -1186,7 +1219,7 @@ openp (path, str, suffixes, storeptr, predicate)
        fn = (char *) alloca (fn_size = 100 + want_size);
 
       /* Loop over suffixes.  */
-      for (tail = NILP (suffixes) ? Fcons (build_string (""), Qnil) : suffixes;
+      for (tail = NILP (suffixes) ? Fcons (empty_unibyte_string, Qnil) : suffixes;
           CONSP (tail); tail = XCDR (tail))
        {
          int lsuffix = SBYTES (XCAR (tail));
@@ -1368,8 +1401,6 @@ readevalloop_1 (old)
 static void
 end_of_file_error ()
 {
-  Lisp_Object data;
-
   if (STRINGP (Vload_file_name))
     xsignal1 (Qend_of_file, Vload_file_name);
 
@@ -1488,7 +1519,8 @@ readevalloop (readcharfun, stream, sourcename, evalfun,
        }
 
       /* Ignore whitespace here, so we can detect eof.  */
-      if (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\r')
+      if (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\r'
+         || c == 0x8a0)  /* NBSP */
        goto read_next;
 
       if (!NILP (Vpurify_flag) && c == '(')
@@ -1881,7 +1913,7 @@ read_escape (readcharfun, stringp, byterep)
 
     case 's':
       c = READCHAR;
-      if (c != '-')
+      if (stringp || c != '-')
        {
          UNREAD (c);
          return ' ';
@@ -2429,7 +2461,10 @@ read1 (readcharfun, pch, first_in_list)
 
     case '`':
       if (first_in_list)
-       goto default_label;
+       {
+         Vold_style_backquotes = Qt;
+         goto default_label;
+       }
       else
        {
          Lisp_Object value;
@@ -2464,7 +2499,10 @@ read1 (readcharfun, pch, first_in_list)
          return Fcons (comma_type, Fcons (value, Qnil));
        }
       else
-       goto default_label;
+       {
+         Vold_style_backquotes = Qt;
+         goto default_label;
+       }
 
     case '?':
       {
@@ -2681,6 +2719,8 @@ read1 (readcharfun, pch, first_in_list)
     default:
     default_label:
       if (c <= 040) goto retry;
+      if (c == 0x8a0) /* NBSP */
+       goto retry;
       {
        char *p = read_buffer;
        int quoted = 0;
@@ -2689,6 +2729,7 @@ read1 (readcharfun, pch, first_in_list)
          char *end = read_buffer + read_buffer_size;
 
          while (c > 040
+                && c != 0x8a0 /* NBSP */
                 && (c >= 0200
                     || (!index ("\"';()[]#", c)
                         && !(!first_in_list && c == '`')
@@ -3705,37 +3746,6 @@ defvar_lisp (namestring, address)
   staticpro (address);
 }
 
-/* Similar but define a variable whose value is the Lisp Object stored in
-   the current buffer.  address is the address of the slot in the buffer
-   that is current now. */
-
-void
-defvar_per_buffer (namestring, address, type, doc)
-     char *namestring;
-     Lisp_Object *address;
-     Lisp_Object type;
-     char *doc;
-{
-  Lisp_Object sym, val;
-  int offset;
-
-  sym = intern (namestring);
-  val = allocate_misc ();
-  offset = (char *)address - (char *)current_buffer;
-
-  XMISCTYPE (val) = Lisp_Misc_Buffer_Objfwd;
-  XBUFFER_OBJFWD (val)->offset = offset;
-  SET_SYMBOL_VALUE (sym, val);
-  PER_BUFFER_SYMBOL (offset) = sym;
-  PER_BUFFER_TYPE (offset) = type;
-
-  if (PER_BUFFER_IDX (offset) == 0)
-    /* Did a DEFVAR_PER_BUFFER without initializing the corresponding
-       slot of buffer_local_flags */
-    abort ();
-}
-
-
 /* Similar but define a variable whose value is the Lisp Object stored
    at a particular offset in the current kboard object.  */
 
@@ -3832,7 +3842,7 @@ init_lread ()
                    Vload_path = Fcons (tem, Vload_path);
                }
 
-             /* Add site-list under the installation dir, if it exists.  */
+             /* Add site-lisp under the installation dir, if it exists.  */
              tem = Fexpand_file_name (build_string ("site-lisp"),
                                       Vinstallation_directory);
              tem1 = Ffile_exists_p (tem);
@@ -3892,7 +3902,7 @@ init_lread ()
       /* NORMAL refers to the lisp dir in the source directory.  */
       /* We used to add ../lisp at the front here, but
         that caused trouble because it was copied from dump_path
-        into Vload_path, aboe, when Vinstallation_directory was non-nil.
+        into Vload_path, above, when Vinstallation_directory was non-nil.
         It should be unnecessary.  */
       Vload_path = decode_env_path (0, normal);
       dump_path = Vload_path;
@@ -3951,7 +3961,7 @@ init_lread ()
 }
 
 /* Print a warning, using format string FORMAT, that directory DIRNAME
-   does not exist.  Print it on stderr and put it in *Message*.  */
+   does not exist.  Print it on stderr and put it in *Messages*.  */
 
 void
 dir_warning (format, dirname)
@@ -4057,11 +4067,10 @@ and, if so, which suffixes they should try to append to the file name
 in order to do so.  However, if you want to customize which suffixes
 the loading functions recognize as compression suffixes, you should
 customize `jka-compr-load-suffixes' rather than the present variable.  */);
-  /* We don't use empty_string because it's not initialized yet.  */
-  Vload_file_rep_suffixes = Fcons (build_string (""), Qnil);
+  Vload_file_rep_suffixes = Fcons (empty_unibyte_string, Qnil);
 
   DEFVAR_BOOL ("load-in-progress", &load_in_progress,
-              doc: /* Non-nil iff inside of `load'.  */);
+              doc: /* Non-nil if inside of `load'.  */);
 
   DEFVAR_LISP ("after-load-alist", &Vafter_load_alist,
               doc: /* An alist of expressions to be evalled when particular files are loaded.
@@ -4089,10 +4098,10 @@ contain symbolic links) of the loaded file.
 
 The remaining elements of each list are symbols defined as variables
 and cons cells of the form `(provide . FEATURE)', `(require . FEATURE)',
-`(defun . FUNCTION)', `(autoload . SYMBOL)', and `(t . SYMBOL)'.
-An element `(t . SYMBOL)' precedes an entry `(defun . FUNCTION)',
-and means that SYMBOL was an autoload before this file redefined it
-as a function.
+`(defun . FUNCTION)', `(autoload . SYMBOL)', `(defface . SYMBOL)'
+and `(t . SYMBOL)'.  An element `(t . SYMBOL)' precedes an entry
+`(defun . FUNCTION)', and means that SYMBOL was an autoload before
+this file redefined it as a function.
 
 During preloading, the file name recorded is relative to the main Lisp
 directory.  These file names are converted to absolute at startup.  */);
@@ -4106,7 +4115,9 @@ directory.  These file names are converted to absolute at startup.  */);
               doc: /* File name, including directory, of user's initialization file.
 If the file loaded had extension `.elc', and the corresponding source file
 exists, this variable contains the name of source file, suitable for use
-by functions like `custom-save-all' which edit the init file.  */);
+by functions like `custom-save-all' which edit the init file.
+While Emacs loads and evaluates the init file, value is the real name
+of the file, regardless of whether or not it has the `.elc' extension.  */);
   Vuser_init_file = Qnil;
 
   DEFVAR_LISP ("current-load-list", &Vcurrent_load_list,
@@ -4173,6 +4184,12 @@ to load.  See also `load-dangerous-libraries'.  */);
               doc: /* List of buffers being read from by calls to `eval-buffer' and `eval-region'.  */);
   Veval_buffer_list = Qnil;
 
+  DEFVAR_LISP ("old-style-backquotes", &Vold_style_backquotes,
+              doc: /* Set to non-nil when `read' encounters an old-style backquote.  */);
+  Vold_style_backquotes = Qnil;
+  Qold_style_backquotes = intern ("old-style-backquotes");
+  staticpro (&Qold_style_backquotes);
+
   /* Vsource_directory was initialized in init_lread.  */
 
   load_descriptor_list = Qnil;