]> code.delx.au - gnu-emacs/blobdiff - src/syntax.c
[MAC_OSX] (image_load_quartz2d): Use cfstring_create_with_string.
[gnu-emacs] / src / syntax.c
index dbdac11694d529bd3ba800a7ae6aae4b96a45ed9..fa34c2433c159534c71326c8413503c5133b1f14 100644 (file)
@@ -1,5 +1,5 @@
 /* GNU Emacs routines to deal with syntax tables; also word and list parsing.
 /* GNU Emacs routines to deal with syntax tables; also word and list parsing.
-   Copyright (C) 1985, 87, 93, 94, 95, 97, 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1985, 87, 93, 94, 95, 97, 1998, 1999, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 
 This file is part of GNU Emacs.
 
@@ -26,6 +26,7 @@ Boston, MA 02111-1307, USA.  */
 #include "buffer.h"
 #include "charset.h"
 #include "keymap.h"
 #include "buffer.h"
 #include "charset.h"
 #include "keymap.h"
+#include "regex.h"
 
 /* Make syntax table lookup grant data in gl_state.  */
 #define SYNTAX_ENTRY_VIA_PROPERTY
 
 /* Make syntax table lookup grant data in gl_state.  */
 #define SYNTAX_ENTRY_VIA_PROPERTY
@@ -97,11 +98,12 @@ static int find_start_modiff;
 static int find_defun_start P_ ((int, int));
 static int back_comment P_ ((int, int, int, int, int, int *, int *));
 static int char_quoted P_ ((int, int));
 static int find_defun_start P_ ((int, int));
 static int back_comment P_ ((int, int, int, int, int, int *, int *));
 static int char_quoted P_ ((int, int));
-static Lisp_Object skip_chars P_ ((int, int, Lisp_Object, Lisp_Object));
+static Lisp_Object skip_chars P_ ((int, int, Lisp_Object, Lisp_Object, int));
 static Lisp_Object scan_lists P_ ((int, int, int, int));
 static void scan_sexps_forward P_ ((struct lisp_parse_state *,
                                    int, int, int, int,
                                    int, Lisp_Object, int));
 static Lisp_Object scan_lists P_ ((int, int, int, int));
 static void scan_sexps_forward P_ ((struct lisp_parse_state *,
                                    int, int, int, int,
                                    int, Lisp_Object, int));
+static int in_classes P_ ((int, Lisp_Object));
 \f
 
 struct gl_state_s gl_state;            /* Global state of syntax parser.  */
 \f
 
 struct gl_state_s gl_state;            /* Global state of syntax parser.  */
@@ -290,10 +292,13 @@ char_quoted (charpos, bytepos)
 
   DEC_BOTH (charpos, bytepos);
 
 
   DEC_BOTH (charpos, bytepos);
 
-  while (bytepos >= beg)
+  while (charpos >= beg)
     {
     {
+      int c;
+
       UPDATE_SYNTAX_TABLE_BACKWARD (charpos);
       UPDATE_SYNTAX_TABLE_BACKWARD (charpos);
-      code = SYNTAX (FETCH_CHAR (bytepos));
+      c = FETCH_CHAR (bytepos);
+      code = SYNTAX (c);
       if (! (code == Scharquote || code == Sescape))
        break;
 
       if (! (code == Scharquote || code == Sescape))
        break;
 
@@ -337,7 +342,7 @@ dec_bytepos (bytepos)
    It should be the last one before POS, or nearly the last.
 
    When open_paren_in_column_0_is_defun_start is nonzero,
    It should be the last one before POS, or nearly the last.
 
    When open_paren_in_column_0_is_defun_start is nonzero,
-   the beginning of every line is treated as a defun-start.
+   only the beginning of the buffer is treated as a defun-start.
 
    We record the information about where the scan started
    and what its result was, so that another call in the same area
 
    We record the information about where the scan started
    and what its result was, so that another call in the same area
@@ -353,6 +358,12 @@ find_defun_start (pos, pos_byte)
 {
   int opoint = PT, opoint_byte = PT_BYTE;
 
 {
   int opoint = PT, opoint_byte = PT_BYTE;
 
+  if (!open_paren_in_column_0_is_defun_start)
+    {
+      find_start_value_byte = BEGV_BYTE;
+      return BEGV;
+    }
+
   /* Use previous finding, if it's valid and applies to this inquiry.  */
   if (current_buffer == find_start_buffer
       /* Reuse the defun-start even if POS is a little farther on.
   /* Use previous finding, if it's valid and applies to this inquiry.  */
   if (current_buffer == find_start_buffer
       /* Reuse the defun-start even if POS is a little farther on.
@@ -372,24 +383,25 @@ find_defun_start (pos, pos_byte)
      syntax-tables.  */
   gl_state.current_syntax_table = current_buffer->syntax_table;
   gl_state.use_global = 0;
      syntax-tables.  */
   gl_state.current_syntax_table = current_buffer->syntax_table;
   gl_state.use_global = 0;
-  if (open_paren_in_column_0_is_defun_start)
+  while (PT > BEGV)
     {
     {
-      while (PT > BEGV)
+      int c;
+
+      /* Open-paren at start of line means we may have found our
+        defun-start.  */
+      c = FETCH_CHAR (PT_BYTE);
+      if (SYNTAX (c) == Sopen)
        {
        {
-         /* Open-paren at start of line means we may have found our
-            defun-start.  */
-         if (SYNTAX (FETCH_CHAR (PT_BYTE)) == Sopen)
-           {
-             SETUP_SYNTAX_TABLE (PT + 1, -1);  /* Try again... */
-             if (SYNTAX (FETCH_CHAR (PT_BYTE)) == Sopen)
-               break;
-             /* Now fallback to the default value.  */
-             gl_state.current_syntax_table = current_buffer->syntax_table;
-             gl_state.use_global = 0;
-           }
-         /* Move to beg of previous line.  */
-         scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -2, 1);
+         SETUP_SYNTAX_TABLE (PT + 1, -1);      /* Try again... */
+         c = FETCH_CHAR (PT_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;
        }
        }
+      /* Move to beg of previous line.  */
+      scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -2, 1);
     }
 
   /* Record what we found, for the next try.  */
     }
 
   /* Record what we found, for the next try.  */
@@ -661,7 +673,7 @@ back_comment (from, from_byte, stop, comnested, comstyle, charpos_ptr, bytepos_p
     {
       from = comstart_pos;
       from_byte = comstart_byte;
     {
       from = comstart_pos;
       from_byte = comstart_byte;
-      /* Globals are correct now.  */
+      UPDATE_SYNTAX_TABLE_FORWARD (from - 1);
     }
   else
     {
     }
   else
     {
@@ -974,7 +986,7 @@ text property.  */)
 DEFUN ("modify-syntax-entry", Fmodify_syntax_entry, Smodify_syntax_entry, 2, 3,
   "cSet syntax for character: \nsSet syntax for %s to: ",
        doc: /* Set syntax for character CHAR according to string NEWENTRY.
 DEFUN ("modify-syntax-entry", Fmodify_syntax_entry, Smodify_syntax_entry, 2, 3,
   "cSet syntax for character: \nsSet syntax for %s to: ",
        doc: /* Set syntax for character CHAR according to string NEWENTRY.
-The syntax is changed only for table SYNTAX_TABLE, which defaults to
+The syntax is changed only for table SYNTAX-TABLE, which defaults to
  the current buffer's syntax table.
 The first character of NEWENTRY should be one of the following:
   Space or -  whitespace syntax.    w   word constituent.
  the current buffer's syntax table.
 The first character of NEWENTRY should be one of the following:
   Space or -  whitespace syntax.    w   word constituent.
@@ -1274,25 +1286,31 @@ scan_words (from, count)
   return from;
 }
 
   return from;
 }
 
-DEFUN ("forward-word", Fforward_word, Sforward_word, 1, 1, "p",
+DEFUN ("forward-word", Fforward_word, Sforward_word, 0, 1, "p",
        doc: /* Move point forward ARG words (backward if ARG is negative).
 Normally returns t.
 If an edge of the buffer or a field boundary is reached, point is left there
 and the function returns nil.  Field boundaries are not noticed if
 `inhibit-field-text-motion' is non-nil.  */)
        doc: /* Move point forward ARG words (backward if ARG is negative).
 Normally returns t.
 If an edge of the buffer or a field boundary is reached, point is left there
 and the function returns nil.  Field boundaries are not noticed if
 `inhibit-field-text-motion' is non-nil.  */)
-     (count)
-     Lisp_Object count;
+     (arg)
+     Lisp_Object arg;
 {
 {
+  Lisp_Object tmp;
   int orig_val, val;
   int orig_val, val;
-  CHECK_NUMBER (count);
 
 
-  val = orig_val = scan_words (PT, XINT (count));
+  if (NILP (arg))
+    XSETFASTINT (arg, 1);
+  else
+    CHECK_NUMBER (arg);
+
+  val = orig_val = scan_words (PT, XINT (arg));
   if (! orig_val)
   if (! orig_val)
-    val = XINT (count) > 0 ? ZV : BEGV;
+    val = XINT (arg) > 0 ? ZV : BEGV;
 
   /* Avoid jumping out of an input field.  */
 
   /* Avoid jumping out of an input field.  */
-  val = XFASTINT (Fconstrain_to_field (make_number (val), make_number (PT),
-                                      Qt, Qnil, Qnil));
+  tmp = Fconstrain_to_field (make_number (val), make_number (PT),
+                            Qt, Qnil, Qnil);
+  val = XFASTINT (tmp);
 
   SET_PT (val);
   return val == orig_val ? Qt : Qnil;
 
   SET_PT (val);
   return val == orig_val ? Qt : Qnil;
@@ -1307,13 +1325,13 @@ except that `]' is never special and `\\' quotes `^', `-' or `\\'
  (but not as 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.
  (but not as 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.
-Returns the distance traveled, either zero or positive.
-Note that char classes, e.g. `[:alpha:]', are not currently supported;
-they will be treated as literals.  */)
+Char classes, e.g. `[:alpha:]', are supported.
+
+Returns the distance traveled, either zero or positive.  */)
      (string, lim)
      Lisp_Object string, lim;
 {
      (string, lim)
      Lisp_Object string, lim;
 {
-  return skip_chars (1, 0, string, lim);
+  return skip_chars (1, 0, string, lim, 1);
 }
 
 DEFUN ("skip-chars-backward", Fskip_chars_backward, Sskip_chars_backward, 1, 2, 0,
 }
 
 DEFUN ("skip-chars-backward", Fskip_chars_backward, Sskip_chars_backward, 1, 2, 0,
@@ -1323,7 +1341,7 @@ Returns the distance traveled, either zero or negative.  */)
      (string, lim)
      Lisp_Object string, lim;
 {
      (string, lim)
      Lisp_Object string, lim;
 {
-  return skip_chars (0, 0, string, lim);
+  return skip_chars (0, 0, string, lim, 1);
 }
 
 DEFUN ("skip-syntax-forward", Fskip_syntax_forward, Sskip_syntax_forward, 1, 2, 0,
 }
 
 DEFUN ("skip-syntax-forward", Fskip_syntax_forward, Sskip_syntax_forward, 1, 2, 0,
@@ -1335,7 +1353,7 @@ This function returns the distance traveled, either zero or positive.  */)
      (syntax, lim)
      Lisp_Object syntax, lim;
 {
      (syntax, lim)
      Lisp_Object syntax, lim;
 {
-  return skip_chars (1, 1, syntax, lim);
+  return skip_chars (1, 1, syntax, lim, 0);
 }
 
 DEFUN ("skip-syntax-backward", Fskip_syntax_backward, Sskip_syntax_backward, 1, 2, 0,
 }
 
 DEFUN ("skip-syntax-backward", Fskip_syntax_backward, Sskip_syntax_backward, 1, 2, 0,
@@ -1347,13 +1365,14 @@ This function returns the distance traveled, either zero or negative.  */)
      (syntax, lim)
      Lisp_Object syntax, lim;
 {
      (syntax, lim)
      Lisp_Object syntax, lim;
 {
-  return skip_chars (0, 1, syntax, lim);
+  return skip_chars (0, 1, syntax, lim, 0);
 }
 
 static Lisp_Object
 }
 
 static Lisp_Object
-skip_chars (forwardp, syntaxp, string, lim)
+skip_chars (forwardp, syntaxp, string, lim, handle_iso_classes)
      int forwardp, syntaxp;
      Lisp_Object string, lim;
      int forwardp, syntaxp;
      Lisp_Object string, lim;
+     int handle_iso_classes;
 {
   register unsigned int c;
   unsigned char fastmap[0400];
 {
   register unsigned int c;
   unsigned char fastmap[0400];
@@ -1369,12 +1388,14 @@ skip_chars (forwardp, syntaxp, string, lim)
   int size_byte;
   const unsigned char *str;
   int len;
   int size_byte;
   const unsigned char *str;
   int len;
+  Lisp_Object iso_classes;
 
   CHECK_STRING (string);
   char_ranges = (int *) alloca (SCHARS (string) * (sizeof (int)) * 2);
   string_multibyte = STRING_MULTIBYTE (string);
   str = SDATA (string);
   size_byte = SBYTES (string);
 
   CHECK_STRING (string);
   char_ranges = (int *) alloca (SCHARS (string) * (sizeof (int)) * 2);
   string_multibyte = STRING_MULTIBYTE (string);
   str = SDATA (string);
   size_byte = SBYTES (string);
+  iso_classes = Qnil;
 
   /* Adjust the multibyteness of the string to that of the buffer.  */
   if (multibyte != string_multibyte)
 
   /* Adjust the multibyteness of the string to that of the buffer.  */
   if (multibyte != string_multibyte)
@@ -1430,15 +1451,54 @@ skip_chars (forwardp, syntaxp, string, lim)
        fastmap[syntax_spec_code[c & 0377]] = 1;
       else
        {
        fastmap[syntax_spec_code[c & 0377]] = 1;
       else
        {
+         if (handle_iso_classes && c == '['
+             && i_byte < size_byte
+             && STRING_CHAR (str + i_byte, size_byte - i_byte) == ':')
+           {
+             const unsigned char *class_beg = str + i_byte + 1;
+             const unsigned char *class_end = class_beg;
+             const unsigned char *class_limit = str + size_byte - 2;
+             /* Leave room for the null.        */
+             unsigned char class_name[CHAR_CLASS_MAX_LENGTH + 1];
+             re_wctype_t cc;
+
+             if (class_limit - class_beg > CHAR_CLASS_MAX_LENGTH)
+               class_limit = class_beg + CHAR_CLASS_MAX_LENGTH;
+
+             while (class_end < class_limit
+                    && *class_end >= 'a' && *class_end <= 'z')
+               class_end++;
+
+             if (class_end == class_beg
+                 || *class_end != ':' || class_end[1] != ']')
+               goto not_a_class_name;
+
+             bcopy (class_beg, class_name, class_end - class_beg);
+             class_name[class_end - class_beg] = 0;
+
+             cc = re_wctype (class_name);
+             if (cc == 0)
+               error ("Invalid ISO C character class");
+
+             iso_classes = Fcons (make_number (cc), iso_classes);
+
+             i_byte = class_end + 2 - str;
+             continue;
+           }
+
+       not_a_class_name:
          if (c == '\\')
            {
              if (i_byte == size_byte)
                break;
 
          if (c == '\\')
            {
              if (i_byte == size_byte)
                break;
 
-             c = STRING_CHAR_AND_LENGTH (str+i_byte, size_byte-i_byte, len);
+             c = STRING_CHAR_AND_LENGTH (str + i_byte,
+                                         size_byte - i_byte, len);
              i_byte += len;
            }
              i_byte += len;
            }
-         if (i_byte < size_byte
+         /* Treat `-' as range character only if another character
+            follows.  */
+         if (i_byte + 1 < size_byte
              && str[i_byte] == '-')
            {
              unsigned int c2;
              && str[i_byte] == '-')
            {
              unsigned int c2;
@@ -1446,11 +1506,9 @@ skip_chars (forwardp, syntaxp, string, lim)
              /* Skip over the dash.  */
              i_byte++;
 
              /* Skip over the dash.  */
              i_byte++;
 
-             if (i_byte == size_byte)
-               break;
-
              /* Get the end of the range.  */
              /* Get the end of the range.  */
-             c2 =STRING_CHAR_AND_LENGTH (str+i_byte, size_byte-i_byte, len);
+             c2 = STRING_CHAR_AND_LENGTH (str + i_byte,
+                                          size_byte - i_byte, len);
              i_byte += len;
 
              if (SINGLE_BYTE_CHAR_P (c))
              i_byte += len;
 
              if (SINGLE_BYTE_CHAR_P (c))
@@ -1509,12 +1567,12 @@ skip_chars (forwardp, syntaxp, string, lim)
     if (forwardp)
       {
        endp = (XINT (lim) == GPT) ? GPT_ADDR : CHAR_POS_ADDR (XINT (lim));
     if (forwardp)
       {
        endp = (XINT (lim) == GPT) ? GPT_ADDR : CHAR_POS_ADDR (XINT (lim));
-       stop = (pos < GPT && GPT < XINT (lim)) ? GPT_ADDR : endp; 
+       stop = (pos < GPT && GPT < XINT (lim)) ? GPT_ADDR : endp;
       }
     else
       {
        endp = CHAR_POS_ADDR (XINT (lim));
       }
     else
       {
        endp = CHAR_POS_ADDR (XINT (lim));
-       stop = (pos >= GPT && GPT > XINT (lim)) ? GAP_END_ADDR : endp; 
+       stop = (pos >= GPT && GPT > XINT (lim)) ? GAP_END_ADDR : endp;
       }
 
     immediate_quit = 1;
       }
 
     immediate_quit = 1;
@@ -1622,6 +1680,15 @@ skip_chars (forwardp, syntaxp, string, lim)
                      stop = endp;
                    }
                  c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, nbytes);
                      stop = endp;
                    }
                  c = STRING_CHAR_AND_LENGTH (p, MAX_MULTIBYTE_LENGTH, nbytes);
+
+                 if (! NILP (iso_classes) && in_classes (c, iso_classes))
+                   {
+                     if (negate)
+                       break;
+                     else
+                       goto fwd_ok;
+                   }
+
                  if (SINGLE_BYTE_CHAR_P (c))
                    {
                      if (!fastmap[c])
                  if (SINGLE_BYTE_CHAR_P (c))
                    {
                      if (!fastmap[c])
@@ -1644,6 +1711,7 @@ skip_chars (forwardp, syntaxp, string, lim)
                      if (!(negate ^ (i < n_char_ranges)))
                        break;
                    }
                      if (!(negate ^ (i < n_char_ranges)))
                        break;
                    }
+               fwd_ok:
                  p += nbytes, pos++, pos_byte += nbytes;
                }
            else
                  p += nbytes, pos++, pos_byte += nbytes;
                }
            else
@@ -1656,8 +1724,18 @@ skip_chars (forwardp, syntaxp, string, lim)
                      p = GAP_END_ADDR;
                      stop = endp;
                    }
                      p = GAP_END_ADDR;
                      stop = endp;
                    }
-                 if (fastmap[*p])
+
+                 if (!NILP (iso_classes) && in_classes (*p, iso_classes))
+                   {
+                     if (negate)
+                       break;
+                     else
+                       goto fwd_unibyte_ok;
+                   }
+
+                 if (!fastmap[*p])
                    break;
                    break;
+               fwd_unibyte_ok:
                  p++, pos++;
                }
          }
                  p++, pos++;
                }
          }
@@ -1683,6 +1761,15 @@ skip_chars (forwardp, syntaxp, string, lim)
                    p = prev_p - 1, c = *p, nbytes = 1;
                  else
                    c = STRING_CHAR (p, MAX_MULTIBYTE_LENGTH);
                    p = prev_p - 1, c = *p, nbytes = 1;
                  else
                    c = STRING_CHAR (p, MAX_MULTIBYTE_LENGTH);
+
+                 if (! NILP (iso_classes) && in_classes (c, iso_classes))
+                   {
+                     if (negate)
+                       break;
+                     else
+                       goto back_ok;
+                   }
+
                  if (SINGLE_BYTE_CHAR_P (c))
                    {
                      if (!fastmap[c])
                  if (SINGLE_BYTE_CHAR_P (c))
                    {
                      if (!fastmap[c])
@@ -1697,6 +1784,7 @@ skip_chars (forwardp, syntaxp, string, lim)
                      if (!(negate ^ (i < n_char_ranges)))
                        break;
                    }
                      if (!(negate ^ (i < n_char_ranges)))
                        break;
                    }
+               back_ok:
                  pos--, pos_byte -= nbytes;
                }
            else
                  pos--, pos_byte -= nbytes;
                }
            else
@@ -1709,8 +1797,18 @@ skip_chars (forwardp, syntaxp, string, lim)
                      p = GPT_ADDR;
                      stop = endp;
                    }
                      p = GPT_ADDR;
                      stop = endp;
                    }
-                 if (fastmap[p[-1]])
+
+                 if (! NILP (iso_classes) && in_classes (p[-1], iso_classes))
+                   {
+                     if (negate)
+                       break;
+                     else
+                       goto back_unibyte_ok;
+                   }
+
+                 if (!fastmap[p[-1]])
                    break;
                    break;
+               back_unibyte_ok:
                  p--, pos--;
                }
          }
                  p--, pos--;
                }
          }
@@ -1733,6 +1831,30 @@ skip_chars (forwardp, syntaxp, string, lim)
     return make_number (PT - start_point);
   }
 }
     return make_number (PT - start_point);
   }
 }
+
+/* Return 1 if character C belongs to one of the ISO classes
+   in the list ISO_CLASSES.  Each class is represented by an
+   integer which is its type according to re_wctype.  */
+
+static int
+in_classes (c, iso_classes)
+     int c;
+     Lisp_Object iso_classes;
+{
+  int fits_class = 0;
+
+  while (! NILP (iso_classes))
+    {
+      Lisp_Object elt;
+      elt = XCAR (iso_classes);
+      iso_classes = XCDR (iso_classes);
+
+      if (re_iswctype (c, XFASTINT (elt)))
+       fits_class = 1;
+    }
+
+  return fits_class;
+}
 \f
 /* Jump over a comment, assuming we are at the beginning of one.
    FROM is the current position.
 \f
 /* Jump over a comment, assuming we are at the beginning of one.
    FROM is the current position.
@@ -2116,7 +2238,7 @@ scan_lists (from, count, depth, sexpflag)
          INC_BOTH (from, from_byte);
          UPDATE_SYNTAX_TABLE_FORWARD (from);
          if (from < stop && comstart_first
          INC_BOTH (from, from_byte);
          UPDATE_SYNTAX_TABLE_FORWARD (from);
          if (from < stop && comstart_first
-             && SYNTAX_COMSTART_SECOND (FETCH_CHAR (from_byte))
+             && (c = FETCH_CHAR (from_byte), SYNTAX_COMSTART_SECOND (c))
              && parse_sexp_ignore_comments)
            {
              /* we have encountered a comment start sequence and we
              && parse_sexp_ignore_comments)
            {
              /* we have encountered a comment start sequence and we
@@ -2390,8 +2512,8 @@ scan_lists (from, count, depth, sexpflag)
            case Sstring_fence:
              while (1)
                {
            case Sstring_fence:
              while (1)
                {
-                 DEC_BOTH (from, from_byte);
                  if (from == stop) goto lose;
                  if (from == stop) goto lose;
+                 DEC_BOTH (from, from_byte);
                  UPDATE_SYNTAX_TABLE_BACKWARD (from);
                  if (!char_quoted (from, from_byte)
                      && (c = FETCH_CHAR (from_byte),
                  UPDATE_SYNTAX_TABLE_BACKWARD (from);
                  if (!char_quoted (from, from_byte)
                      && (c = FETCH_CHAR (from_byte),
@@ -2406,19 +2528,13 @@ scan_lists (from, count, depth, sexpflag)
              while (1)
                {
                  if (from == stop) goto lose;
              while (1)
                {
                  if (from == stop) goto lose;
-                 temp_pos = from_byte;
-                 if (! NILP (current_buffer->enable_multibyte_characters))
-                   DEC_POS (temp_pos);
-                 else
-                   temp_pos--;
-                 UPDATE_SYNTAX_TABLE_BACKWARD (from - 1);
-                 if (!char_quoted (from - 1, temp_pos)
-                     && stringterm == (c = FETCH_CHAR (temp_pos))
+                 DEC_BOTH (from, from_byte);
+                 UPDATE_SYNTAX_TABLE_BACKWARD (from);
+                 if (!char_quoted (from, from_byte)
+                     && stringterm == (c = FETCH_CHAR (from_byte))
                      && SYNTAX_WITH_MULTIBYTE_CHECK (c) == Sstring)
                    break;
                      && SYNTAX_WITH_MULTIBYTE_CHECK (c) == Sstring)
                    break;
-                 DEC_BOTH (from, from_byte);
                }
                }
-             DEC_BOTH (from, from_byte);
              if (!depth && sexpflag) goto done2;
              break;
            default:
              if (!depth && sexpflag) goto done2;
              break;
            default:
@@ -2447,7 +2563,7 @@ scan_lists (from, count, depth, sexpflag)
           Fcons (build_string ("Unbalanced parentheses"),
                  Fcons (make_number (last_good),
                         Fcons (make_number (from), Qnil))));
           Fcons (build_string ("Unbalanced parentheses"),
                  Fcons (make_number (last_good),
                         Fcons (make_number (from), Qnil))));
-
+  abort ();
   /* NOTREACHED */
 }
 
   /* NOTREACHED */
 }
 
@@ -2586,8 +2702,8 @@ scan_sexps_forward (stateptr, from, from_byte, end, targetdepth,
 #define INC_FROM                               \
 do { prev_from = from;                         \
      prev_from_byte = from_byte;               \
 #define INC_FROM                               \
 do { prev_from = from;                         \
      prev_from_byte = from_byte;               \
-     prev_from_syntax                          \
-       = SYNTAX_WITH_FLAGS (FETCH_CHAR (prev_from_byte)); \
+     temp = FETCH_CHAR (prev_from_byte);       \
+     prev_from_syntax = SYNTAX_WITH_FLAGS (temp); \
      INC_BOTH (from, from_byte);               \
      if (from < end)                           \
        UPDATE_SYNTAX_TABLE_FORWARD (from);     \
      INC_BOTH (from, from_byte);               \
      if (from < end)                           \
        UPDATE_SYNTAX_TABLE_FORWARD (from);     \
@@ -2662,7 +2778,8 @@ do { prev_from = from;                            \
   curlevel->last = -1;
 
   SETUP_SYNTAX_TABLE (prev_from, 1);
   curlevel->last = -1;
 
   SETUP_SYNTAX_TABLE (prev_from, 1);
-  prev_from_syntax = SYNTAX_WITH_FLAGS (FETCH_CHAR (prev_from_byte));
+  temp = FETCH_CHAR (prev_from_byte);
+  prev_from_syntax = SYNTAX_WITH_FLAGS (temp);
   UPDATE_SYNTAX_TABLE_FORWARD (from);
 
   /* Enter the loop at a place appropriate for initial state.  */
   UPDATE_SYNTAX_TABLE_FORWARD (from);
 
   /* Enter the loop at a place appropriate for initial state.  */
@@ -2684,12 +2801,23 @@ do { prev_from = from;                          \
       INC_FROM;
       code = prev_from_syntax & 0xff;
 
       INC_FROM;
       code = prev_from_syntax & 0xff;
 
-      if (code == Scomment)
+      if (from < end
+         && SYNTAX_FLAGS_COMSTART_FIRST (prev_from_syntax)
+         && (c1 = FETCH_CHAR (from_byte),
+             SYNTAX_COMSTART_SECOND (c1)))
+       /* Duplicate code to avoid a complex if-expression
+          which causes trouble for the SGI compiler.  */
        {
        {
-         state.comstyle = SYNTAX_FLAGS_COMMENT_STYLE (prev_from_syntax);
-         state.incomment = (SYNTAX_FLAGS_COMMENT_NESTED (prev_from_syntax) ?
-                            1 : -1);
+         /* Record the comment style we have entered so that only
+            the comment-end sequence of the same style actually
+            terminates the comment section.  */
+         state.comstyle = SYNTAX_COMMENT_STYLE (c1);
+         comnested = SYNTAX_FLAGS_COMMENT_NESTED (prev_from_syntax);
+         comnested = comnested || SYNTAX_COMMENT_NESTED (c1);
+         state.incomment = comnested ? 1 : -1;
          state.comstr_start = prev_from;
          state.comstr_start = prev_from;
+         INC_FROM;
+         code = Scomment;
        }
       else if (code == Scomment_fence)
        {
        }
       else if (code == Scomment_fence)
        {
@@ -2701,24 +2829,13 @@ do { prev_from = from;                          \
          state.comstr_start = prev_from;
          code = Scomment;
        }
          state.comstr_start = prev_from;
          code = Scomment;
        }
-     else if (from < end)
-       if (SYNTAX_FLAGS_COMSTART_FIRST (prev_from_syntax))
-         if (c1 = FETCH_CHAR (from_byte),
-             SYNTAX_COMSTART_SECOND (c1))
-           /* Duplicate code to avoid a complex if-expression
-              which causes trouble for the SGI compiler.  */
-           {
-             /* Record the comment style we have entered so that only
-                the comment-end sequence of the same style actually
-                terminates the comment section.  */
-             state.comstyle = SYNTAX_COMMENT_STYLE (c1);
-             comnested = SYNTAX_FLAGS_COMMENT_NESTED (prev_from_syntax);
-             comnested = comnested || SYNTAX_COMMENT_NESTED (c1);
-             state.incomment = comnested ? 1 : -1;
-             state.comstr_start = prev_from;
-             INC_FROM;
-             code = Scomment;
-           }
+      else if (code == Scomment)
+       {
+         state.comstyle = SYNTAX_FLAGS_COMMENT_STYLE (prev_from_syntax);
+         state.incomment = (SYNTAX_FLAGS_COMMENT_NESTED (prev_from_syntax) ?
+                            1 : -1);
+         state.comstr_start = prev_from;
+       }
 
       if (SYNTAX_FLAGS_PREFIX (prev_from_syntax))
        continue;
 
       if (SYNTAX_FLAGS_PREFIX (prev_from_syntax))
        continue;
@@ -2741,7 +2858,8 @@ do { prev_from = from;                            \
          while (from < end)
            {
              /* Some compilers can't handle this inside the switch.  */
          while (from < end)
            {
              /* Some compilers can't handle this inside the switch.  */
-             temp = SYNTAX (FETCH_CHAR (from_byte));
+             temp = FETCH_CHAR (from_byte);
+             temp = SYNTAX (temp);
              switch (temp)
                {
                case Scharquote:
              switch (temp)
                {
                case Scharquote:
@@ -3103,3 +3221,6 @@ See the info node `(elisp)Syntax Properties' for a description of the
   defsubr (&Sbackward_prefix_chars);
   defsubr (&Sparse_partial_sexp);
 }
   defsubr (&Sbackward_prefix_chars);
   defsubr (&Sparse_partial_sexp);
 }
+
+/* arch-tag: 3e297b9f-088e-4b64-8f4c-fb0b3443e412
+   (do not change this comment) */