Replace bcopy, bzero, bcmp by memcpy, memmove, memset, memcmp
[bpt/emacs.git] / src / syntax.c
index f50649e..7f3557f 100644 (file)
@@ -1,6 +1,6 @@
 /* GNU Emacs routines to deal with syntax tables; also word and list parsing.
    Copyright (C) 1985, 1987, 1993, 1994, 1995, 1997, 1998, 1999, 2001,
-                 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+                 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
                  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -21,6 +21,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include <ctype.h>
+#include <setjmp.h>
 #include "lisp.h"
 #include "commands.h"
 #include "buffer.h"
@@ -97,18 +98,18 @@ static EMACS_INT find_start_begv;
 static int find_start_modiff;
 
 
-static Lisp_Object skip_chars P_ ((int, Lisp_Object, Lisp_Object, int));
-static Lisp_Object skip_syntaxes P_ ((int, Lisp_Object, Lisp_Object));
-static Lisp_Object scan_lists P_ ((EMACS_INT, EMACS_INT, EMACS_INT, int));
-static void scan_sexps_forward P_ ((struct lisp_parse_state *,
-                                   EMACS_INT, EMACS_INT, EMACS_INT, int,
-                                   int, Lisp_Object, int));
-static int in_classes P_ ((int, Lisp_Object));
+static Lisp_Object skip_chars (int, Lisp_Object, Lisp_Object, int);
+static Lisp_Object skip_syntaxes (int, Lisp_Object, Lisp_Object);
+static Lisp_Object scan_lists (EMACS_INT, EMACS_INT, EMACS_INT, int);
+static void scan_sexps_forward (struct lisp_parse_state *,
+                                EMACS_INT, EMACS_INT, EMACS_INT, int,
+                                int, Lisp_Object, int);
+static int in_classes (int, Lisp_Object);
 \f
 
 struct gl_state_s gl_state;            /* Global state of syntax parser.  */
 
-INTERVAL interval_of ();
+INTERVAL interval_of (int, Lisp_Object);
 #define INTERVALS_AT_ONCE 10           /* 1 + max-number of intervals
                                           to scan to property-change.  */
 
@@ -126,9 +127,7 @@ INTERVAL interval_of ();
    start/end of OBJECT.  */
 
 void
-update_syntax_table (charpos, count, init, object)
-     int charpos, count, init;
-     Lisp_Object object;
+update_syntax_table (int charpos, int count, int init, Lisp_Object object)
 {
   Lisp_Object tmp_table;
   int cnt = 0, invalidate = 1;
@@ -317,8 +316,7 @@ char_quoted (EMACS_INT charpos, EMACS_INT bytepos)
    We assume that BYTEPOS is not at the end of the buffer.  */
 
 INLINE EMACS_INT
-inc_bytepos (bytepos)
-     EMACS_INT bytepos;
+inc_bytepos (EMACS_INT bytepos)
 {
   if (NILP (current_buffer->enable_multibyte_characters))
     return bytepos + 1;
@@ -331,8 +329,7 @@ inc_bytepos (bytepos)
    We assume that BYTEPOS is not at the start of the buffer.  */
 
 INLINE EMACS_INT
-dec_bytepos (bytepos)
-     EMACS_INT bytepos;
+dec_bytepos (EMACS_INT bytepos)
 {
   if (NILP (current_buffer->enable_multibyte_characters))
     return bytepos - 1;
@@ -341,7 +338,7 @@ dec_bytepos (bytepos)
   return bytepos;
 }
 \f
-/* Return a defun-start position before before POS and not too far before.
+/* Return a defun-start position before POS and not too far before.
    It should be the last one before POS, or nearly the last.
 
    When open_paren_in_column_0_is_defun_start is nonzero,
@@ -356,8 +353,7 @@ dec_bytepos (bytepos)
    update the global data.  */
 
 static EMACS_INT
-find_defun_start (pos, pos_byte)
-     EMACS_INT pos, pos_byte;
+find_defun_start (EMACS_INT pos, EMACS_INT pos_byte)
 {
   EMACS_INT opoint = PT, opoint_byte = PT_BYTE;
 
@@ -384,8 +380,7 @@ find_defun_start (pos, pos_byte)
   /* We optimize syntax-table lookup for rare updates.  Thus we accept
      only those `^\s(' which are good in global _and_ text-property
      syntax-tables.  */
-  gl_state.current_syntax_table = current_buffer->syntax_table;
-  gl_state.use_global = 0;
+  SETUP_BUFFER_SYNTAX_TABLE ();
   while (PT > BEGV)
     {
       int c;
@@ -400,8 +395,7 @@ find_defun_start (pos, pos_byte)
          if (SYNTAX (c) == Sopen)
            break;
          /* Now fallback to the default value.  */
-         gl_state.current_syntax_table = current_buffer->syntax_table;
-         gl_state.use_global = 0;
+         SETUP_BUFFER_SYNTAX_TABLE ();
        }
       /* Move to beg of previous line.  */
       scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -2, 1);
@@ -423,8 +417,7 @@ find_defun_start (pos, pos_byte)
 /* Return the SYNTAX_COMEND_FIRST of the character before POS, POS_BYTE.  */
 
 static int
-prev_char_comend_first (pos, pos_byte)
-     int pos, pos_byte;
+prev_char_comend_first (int pos, int pos_byte)
 {
   int c, val;
 
@@ -466,10 +459,7 @@ prev_char_comend_first (pos, pos_byte)
    the returned value (or at FROM, if the search was not successful).  */
 
 static int
-back_comment (from, from_byte, stop, comnested, comstyle, charpos_ptr, bytepos_ptr)
-     EMACS_INT from, from_byte, stop;
-     int comnested, comstyle;
-     EMACS_INT *charpos_ptr, *bytepos_ptr;
+back_comment (EMACS_INT from, EMACS_INT from_byte, EMACS_INT stop, int comnested, int comstyle, EMACS_INT *charpos_ptr, EMACS_INT *bytepos_ptr)
 {
   /* Look back, counting the parity of string-quotes,
      and recording the comment-starters seen.
@@ -741,8 +731,7 @@ Currently, any char-table counts as a syntax table.  */)
 }
 
 static void
-check_syntax_table (obj)
-     Lisp_Object obj;
+check_syntax_table (Lisp_Object obj)
 {
   CHECK_TYPE (CHAR_TABLE_P (obj) && EQ (XCHAR_TABLE (obj)->purpose, Qsyntax_table),
              Qsyntax_table_p, obj);
@@ -851,19 +840,17 @@ static Lisp_Object Vsyntax_code_object;
 \f
 DEFUN ("char-syntax", Fchar_syntax, Schar_syntax, 1, 1, 0,
        doc: /* Return the syntax code of CHARACTER, described by a character.
-For example, if CHARACTER is a word constituent,
-the character `w' is returned.
+For example, if CHARACTER is a word constituent, the
+character `w' (119) is returned.
 The characters that correspond to various syntax codes
 are listed in the documentation of `modify-syntax-entry'.  */)
      (character)
      Lisp_Object character;
 {
   int char_int;
-  gl_state.current_syntax_table = current_buffer->syntax_table;
-
-  gl_state.use_global = 0;
-  CHECK_NUMBER (character);
+  CHECK_CHARACTER (character);
   char_int = XINT (character);
+  SETUP_BUFFER_SYNTAX_TABLE ();
   return make_number (syntax_code_spec[(int) SYNTAX (char_int)]);
 }
 
@@ -873,10 +860,9 @@ DEFUN ("matching-paren", Fmatching_paren, Smatching_paren, 1, 1, 0,
      Lisp_Object character;
 {
   int char_int, code;
-  gl_state.current_syntax_table = current_buffer->syntax_table;
-  gl_state.use_global = 0;
   CHECK_NUMBER (character);
   char_int = XINT (character);
+  SETUP_BUFFER_SYNTAX_TABLE ();
   code = SYNTAX (char_int);
   if (code == Sopen || code == Sclose)
     return SYNTAX_MATCH (char_int);
@@ -910,8 +896,7 @@ text property.  */)
   if (*p)
     {
       int len;
-      int character = (STRING_CHAR_AND_LENGTH
-                      (p, SBYTES (string) - 1, len));
+      int character = STRING_CHAR_AND_LENGTH (p, len);
       XSETINT (match, character);
       if (XFASTINT (match) == ' ')
        match = Qnil;
@@ -1190,8 +1175,7 @@ Lisp_Object Vfind_word_boundary_function_table;
    COUNT negative means scan backward and stop at word beginning.  */
 
 int
-scan_words (from, count)
-     register int from, count;
+scan_words (register int from, register int count)
 {
   register int beg = BEGV;
   register int end = ZV;
@@ -1347,13 +1331,13 @@ and the function returns nil.  Field boundaries are not noticed if
   return val == orig_val ? Qt : Qnil;
 }
 \f
-Lisp_Object skip_chars ();
+Lisp_Object skip_chars (int, Lisp_Object, Lisp_Object, int);
 
 DEFUN ("skip-chars-forward", Fskip_chars_forward, Sskip_chars_forward, 1, 2, 0,
        doc: /* Move point forward, stopping before a char not in STRING, or at pos LIM.
 STRING is like the inside of a `[...]' in a regular expression
 except that `]' is never special and `\\' quotes `^', `-' or `\\'
- (but not as the end of a range; quoting is never needed there).
+ (but not at the end of a range; quoting is never needed there).
 Thus, with arg "a-zA-Z", this skips letters stopping before first nonletter.
 With arg "^a-zA-Z", skips nonletters stopping before first letter.
 Char classes, e.g. `[:alpha:]', are supported.
@@ -1400,10 +1384,7 @@ This function returns the distance traveled, either zero or negative.  */)
 }
 
 static Lisp_Object
-skip_chars (forwardp, string, lim, handle_iso_classes)
-     int forwardp;
-     Lisp_Object string, lim;
-     int handle_iso_classes;
+skip_chars (int forwardp, Lisp_Object string, Lisp_Object lim, int handle_iso_classes)
 {
   register unsigned int c;
   unsigned char fastmap[0400];
@@ -1441,7 +1422,7 @@ skip_chars (forwardp, string, lim, handle_iso_classes)
               && (XINT (lim) - PT != CHAR_TO_BYTE (XINT (lim)) - PT_BYTE));
   string_multibyte = SBYTES (string) > SCHARS (string);
 
-  bzero (fastmap, sizeof fastmap);
+  memset (fastmap, 0, sizeof fastmap);
 
   str = SDATA (string);
   size_byte = SBYTES (string);
@@ -1490,7 +1471,7 @@ skip_chars (forwardp, string, lim, handle_iso_classes)
                  || *class_end != ':' || class_end[1] != ']')
                goto not_a_class_name;
 
-             bcopy (class_beg, class_name, class_end - class_beg);
+             memcpy (class_name, class_beg, class_end - class_beg);
              class_name[class_end - class_beg] = 0;
 
              cc = re_wctype (class_name);
@@ -1551,18 +1532,18 @@ skip_chars (forwardp, string, lim, handle_iso_classes)
          unsigned char fastmap2[0400];
          int range_start_byte, range_start_char;
 
-         bcopy (fastmap2 + 0200, fastmap + 0200, 0200);
-         bzero (fastmap + 0200, 0200);
+         memcpy (fastmap + 0200, fastmap2 + 0200, 0200);
+         memset (fastmap + 0200, 0, 0200);
          /* We are sure that this loop stops.  */
          for (i = 0200; ! fastmap2[i]; i++);
-         c = unibyte_char_to_multibyte (i);
+         c = BYTE8_TO_CHAR (i);
          fastmap[CHAR_LEADING_CODE (c)] = 1;
          range_start_byte = i;
          range_start_char = c;
          char_ranges = (int *) alloca (sizeof (int) * 128 * 2);
          for (i = 129; i < 0400; i++)
            {
-             c = unibyte_char_to_multibyte (i);
+             c = BYTE8_TO_CHAR (i);
              fastmap[CHAR_LEADING_CODE (c)] = 1;
              if (i - range_start_byte != c - range_start_char)
                {
@@ -1587,12 +1568,12 @@ skip_chars (forwardp, string, lim, handle_iso_classes)
          unsigned char leading_code;
 
          leading_code = str[i_byte];
-         c = STRING_CHAR_AND_LENGTH (str + i_byte, size_byte-i_byte, len);
+         c = STRING_CHAR_AND_LENGTH (str + i_byte, len);
          i_byte += len;
 
          if (handle_iso_classes && c == '['
              && i_byte < size_byte
-             && STRING_CHAR (str + i_byte, size_byte - i_byte) == ':')
+             && STRING_CHAR (str + i_byte) == ':')
            {
              const unsigned char *class_beg = str + i_byte + 1;
              const unsigned char *class_end = class_beg;
@@ -1612,7 +1593,7 @@ skip_chars (forwardp, string, lim, handle_iso_classes)
                  || *class_end != ':' || class_end[1] != ']')
                goto not_a_class_name_multibyte;
 
-             bcopy (class_beg, class_name, class_end - class_beg);
+             memcpy (class_name, class_beg, class_end - class_beg);
              class_name[class_end - class_beg] = 0;
 
              cc = re_wctype (class_name);
@@ -1632,8 +1613,7 @@ skip_chars (forwardp, string, lim, handle_iso_classes)
                break;
 
              leading_code = str[i_byte];
-             c = STRING_CHAR_AND_LENGTH (str + i_byte,
-                                         size_byte - i_byte, len);
+             c = STRING_CHAR_AND_LENGTH (str + i_byte, len);
              i_byte += len;
            }
          /* Treat `-' as range character only if another character
@@ -1649,15 +1629,14 @@ skip_chars (forwardp, string, lim, handle_iso_classes)
 
              /* Get the end of the range.  */
              leading_code2 = str[i_byte];
-             c2 = STRING_CHAR_AND_LENGTH (str + i_byte,
-                                          size_byte - i_byte, len);
+             c2 = STRING_CHAR_AND_LENGTH (str + i_byte, len);
              i_byte += len;
 
              if (c2 == '\\'
                  && i_byte < size_byte)
                {
                  leading_code2 = str[i_byte];
-                 c2 =STRING_CHAR_AND_LENGTH (str + i_byte, size_byte-i_byte, len);
+                 c2 =STRING_CHAR_AND_LENGTH (str + i_byte, len);
                  i_byte += len;
                }
 
@@ -1699,7 +1678,7 @@ skip_chars (forwardp, string, lim, handle_iso_classes)
 
       if (! multibyte && n_char_ranges > 0)
        {
-         bzero (fastmap + 0200, 0200);
+         memset (fastmap + 0200, 0, 0200);
          for (i = 0; i < n_char_ranges; i += 2)
            {
              int c1 = char_ranges[i];
@@ -1749,6 +1728,12 @@ skip_chars (forwardp, string, lim, handle_iso_classes)
       }
 
     immediate_quit = 1;
+    /* This code may look up syntax tables using macros that rely on the
+       gl_state object.  To make sure this object is not out of date,
+       let's initialize it manually.
+       We ignore syntax-table text-properties for now, since that's
+       what we've done in the past.  */
+    SETUP_BUFFER_SYNTAX_TABLE ();
     if (forwardp)
       {
        if (multibyte)
@@ -1763,7 +1748,7 @@ skip_chars (forwardp, string, lim, handle_iso_classes)
                  p = GAP_END_ADDR;
                  stop = endp;
                }
-             c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, nbytes);
+             c = STRING_CHAR_AND_LENGTH (p, nbytes);
              if (! NILP (iso_classes) && in_classes (c, iso_classes))
                {
                  if (negate)
@@ -1834,7 +1819,7 @@ skip_chars (forwardp, string, lim, handle_iso_classes)
                }
              prev_p = p;
              while (--p >= stop && ! CHAR_HEAD_P (*p));
-             c = STRING_CHAR (p, MAX_MULTIBYTE_LENGTH);
+             c = STRING_CHAR (p);
 
              if (! NILP (iso_classes) && in_classes (c, iso_classes))
                {
@@ -1893,9 +1878,7 @@ skip_chars (forwardp, string, lim, handle_iso_classes)
 
 
 static Lisp_Object
-skip_syntaxes (forwardp, string, lim)
-     int forwardp;
-     Lisp_Object string, lim;
+skip_syntaxes (int forwardp, Lisp_Object string, Lisp_Object lim)
 {
   register unsigned int c;
   unsigned char fastmap[0400];
@@ -1924,7 +1907,7 @@ skip_syntaxes (forwardp, string, lim)
   multibyte = (!NILP (current_buffer->enable_multibyte_characters)
               && (XINT (lim) - PT != CHAR_TO_BYTE (XINT (lim)) - PT_BYTE));
 
-  bzero (fastmap, sizeof fastmap);
+  memset (fastmap, 0, sizeof fastmap);
 
   if (SBYTES (string) > SCHARS (string))
     /* As this is very rare case (syntax spec is ASCII only), don't
@@ -1988,7 +1971,7 @@ skip_syntaxes (forwardp, string, lim)
                    p = GAP_END_ADDR;
                    stop = endp;
                  }
-               c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, nbytes);
+               c = STRING_CHAR_AND_LENGTH (p, nbytes);
                if (! fastmap[(int) SYNTAX (c)])
                  break;
                p += nbytes, pos++, pos_byte += nbytes;
@@ -2031,7 +2014,7 @@ skip_syntaxes (forwardp, string, lim)
                UPDATE_SYNTAX_TABLE_BACKWARD (pos - 1);
                prev_p = p;
                while (--p >= stop && ! CHAR_HEAD_P (*p));
-               c = STRING_CHAR (p, MAX_MULTIBYTE_LENGTH);
+               c = STRING_CHAR (p);
                if (! fastmap[(int) SYNTAX (c)])
                  break;
                pos--, pos_byte -= prev_p - p;
@@ -2068,13 +2051,11 @@ skip_syntaxes (forwardp, string, lim)
    integer which is its type according to re_wctype.  */
 
 static int
-in_classes (c, iso_classes)
-     int c;
-     Lisp_Object iso_classes;
+in_classes (int c, Lisp_Object iso_classes)
 {
   int fits_class = 0;
 
-  while (! NILP (iso_classes))
+  while (CONSP (iso_classes))
     {
       Lisp_Object elt;
       elt = XCAR (iso_classes);
@@ -2112,12 +2093,10 @@ in_classes (c, iso_classes)
    remains valid for forward search starting at the returned position. */
 
 static int
-forw_comment (from, from_byte, stop, nesting, style, prev_syntax,
-             charpos_ptr, bytepos_ptr, incomment_ptr)
-     EMACS_INT from, from_byte, stop;
-     int nesting, style, prev_syntax;
-     EMACS_INT *charpos_ptr, *bytepos_ptr;
-     int *incomment_ptr;
+forw_comment (EMACS_INT from, EMACS_INT from_byte, EMACS_INT stop,
+             int nesting, int style, int prev_syntax,
+             EMACS_INT *charpos_ptr, EMACS_INT *bytepos_ptr,
+             int *incomment_ptr)
 {
   register int c, c1;
   register enum syntaxcode code;
@@ -2423,10 +2402,7 @@ between them, return t; otherwise return nil.  */)
    ? SYNTAX (c) : Ssymbol)
 
 static Lisp_Object
-scan_lists (from, count, depth, sexpflag)
-     register EMACS_INT from;
-     EMACS_INT count, depth;
-     int sexpflag;
+scan_lists (register EMACS_INT from, EMACS_INT count, EMACS_INT depth, int sexpflag)
 {
   Lisp_Object val;
   register EMACS_INT stop = count > 0 ? ZV : BEGV;
@@ -3325,19 +3301,19 @@ Sixth arg COMMENTSTOP non-nil means stop at the start of a comment.
 }
 \f
 void
-init_syntax_once ()
+init_syntax_once (void)
 {
   register int i, c;
   Lisp_Object temp;
 
   /* This has to be done here, before we call Fmake_char_table.  */
-  Qsyntax_table = intern ("syntax-table");
+  Qsyntax_table = intern_c_string ("syntax-table");
   staticpro (&Qsyntax_table);
 
-  /* Intern this now in case it isn't already done.
+  /* Intern_C_String this now in case it isn't already done.
      Setting this variable twice is harmless.
      But don't staticpro it here--that is done in alloc.c.  */
-  Qchar_table_extra_slots = intern ("char-table-extra-slots");
+  Qchar_table_extra_slots = intern_c_string ("char-table-extra-slots");
 
   /* Create objects which can be shared among syntax tables.  */
   Vsyntax_code_object = Fmake_vector (make_number (Smax), Qnil);
@@ -3415,9 +3391,9 @@ init_syntax_once ()
 }
 
 void
-syms_of_syntax ()
+syms_of_syntax (void)
 {
-  Qsyntax_table_p = intern ("syntax-table-p");
+  Qsyntax_table_p = intern_c_string ("syntax-table-p");
   staticpro (&Qsyntax_table_p);
 
   staticpro (&Vsyntax_code_object);
@@ -3430,12 +3406,12 @@ syms_of_syntax ()
   /* Defined in regex.c */
   staticpro (&re_match_object);
 
-  Qscan_error = intern ("scan-error");
+  Qscan_error = intern_c_string ("scan-error");
   staticpro (&Qscan_error);
   Fput (Qscan_error, Qerror_conditions,
-       Fcons (Qscan_error, Fcons (Qerror, Qnil)));
+       pure_cons (Qscan_error, pure_cons (Qerror, Qnil)));
   Fput (Qscan_error, Qerror_message,
-       build_string ("Scan error"));
+       make_pure_c_string ("Scan error"));
 
   DEFVAR_BOOL ("parse-sexp-ignore-comments", &parse_sexp_ignore_comments,
               doc: /* Non-nil means `forward-sexp', etc., should treat comments as whitespace.  */);