]> code.delx.au - gnu-emacs/blobdiff - src/search.c
Merge from emacs--devo--0
[gnu-emacs] / src / search.c
index 3b212e007e8db4a05a9d1e503799912da1ea5895..15cc51cb5113a35ed46d3d20d8a4dc32b1a5aec7 100644 (file)
@@ -1,6 +1,6 @@
 /* String search routines for GNU Emacs.
-   Copyright (C) 1985, 86,87,93,94,97,98, 1999, 2004
-             Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1987, 1993, 1994, 1997, 1998, 1999, 2002, 2003,
+                 2004, 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -90,6 +90,7 @@ static void save_search_regs ();
 static int simple_search ();
 static int boyer_moore ();
 static int search_buffer ();
+static void matcher_overflow () NO_RETURN;
 
 static void
 matcher_overflow ()
@@ -395,7 +396,7 @@ string_match_1 (regexp, string, start, posix)
 
 DEFUN ("string-match", Fstring_match, Sstring_match, 2, 3, 0,
        doc: /* Return index of start of first match for REGEXP in STRING, or nil.
-Case is ignored if `case-fold-search' is non-nil in the current buffer.
+Matching ignores case if `case-fold-search' is non-nil.
 If third arg START is non-nil, start search at that index in STRING.
 For index of first char beyond the match, do (match-end 0).
 `match-end' and `match-beginning' also give indices of substrings
@@ -1140,10 +1141,10 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n,
       int raw_pattern_size_byte;
       unsigned char *patbuf;
       int multibyte = !NILP (current_buffer->enable_multibyte_characters);
-      unsigned char *base_pat = SDATA (string);
-      /* Set to nozero if we find a non-ASCII char that need
-        translation.  */
-      int char_base = 0;
+      unsigned char *base_pat;
+      /* Set to positive if we find a non-ASCII char that need
+        translation.  Otherwise set to zero later.  */
+      int char_base = -1;
       int boyer_moore_ok = 1;
 
       /* MULTIBYTE says whether the text to be searched is multibyte.
@@ -1209,6 +1210,7 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n,
              if (RE && *base_pat == '\\')
                {
                  len--;
+                 raw_pattern_size--;
                  len_byte--;
                  base_pat++;
                }
@@ -1234,37 +1236,46 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n,
                    {
                      /* Check if all equivalents belong to the same
                         group of characters.  Note that the check of C
-                        itself is done by the last iteration.  Note
-                        also that we don't have to check ASCII
-                        characters because boyer-moore search can
-                        always handle their translation.  */
-                     while (1)
+                        itself is done by the last iteration.  */
+                     int this_char_base = -1;
+
+                     while (boyer_moore_ok)
                        {
-                         if (ASCII_BYTE_P (inverse))
+                         if (ASCII_BYTE_P (inverse))
                            {
-                             if (CHAR_BYTE8_P (inverse))
+                             if (this_char_base > 0)
+                               boyer_moore_ok = 0;
+                             else
                                {
-                                 /* Boyer-moore search can't handle a
-                                    translation of an eight-bit
-                                    character.  */
-                                 boyer_moore_ok = 0;
-                                 break;
-                               }
-                             else if (char_base == 0)
-                               char_base = inverse & ~0x3F;
-                             else if ((inverse & ~0x3F)
-                                      != char_base)
-                               {
-                                 boyer_moore_ok = 0;
-                                 break;
+                                 this_char_base = 0;
+                                 if (char_base < 0)
+                                   char_base = this_char_base;
                                }
                            }
+                         else if (CHAR_BYTE8_P (inverse))
+                           /* Boyer-moore search can't handle a
+                              translation of an eight-bit
+                              character.  */
+                           boyer_moore_ok = 0;
+                         else if (this_char_base < 0)
+                           {
+                             this_char_base = inverse & ~0x3F;
+                             if (char_base < 0)
+                               char_base = this_char_base;
+                             else if (char_base > 0
+                                      && this_char_base != char_base)
+                               boyer_moore_ok = 0;
+                           }
+                         else if ((inverse & ~0x3F) != this_char_base)
+                           boyer_moore_ok = 0;
                          if (c == inverse)
                            break;
                          TRANSLATE (inverse, inverse_trt, inverse);
                        }
                    }
                }
+             if (char_base < 0)
+               char_base = 0;
 
              /* Store this character into the translated pattern.  */
              bcopy (str, pat, charlen);
@@ -1333,6 +1344,9 @@ simple_search (n, pat, len, len_byte, trt, pos, pos_byte, lim, lim_byte)
 {
   int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
   int forward = n > 0;
+  /* Number of buffer bytes matched.  Note that this may be different
+     from len_byte in a multibyte buffer.  */
+  int match_byte;
 
   if (lim > pos && multibyte)
     while (n > 0)
@@ -1372,8 +1386,9 @@ simple_search (n, pat, len, len_byte, trt, pos, pos_byte, lim, lim_byte)
 
            if (this_len == 0)
              {
+               match_byte = this_pos_byte - pos_byte;
                pos += len;
-               pos_byte += len_byte;
+               pos_byte += match_byte;
                break;
              }
 
@@ -1410,6 +1425,7 @@ simple_search (n, pat, len, len_byte, trt, pos, pos_byte, lim, lim_byte)
 
            if (this_len == 0)
              {
+               match_byte = len;
                pos += len;
                break;
              }
@@ -1435,6 +1451,7 @@ simple_search (n, pat, len, len_byte, trt, pos, pos_byte, lim, lim_byte)
            if (pos - len < lim)
              goto stop;
            this_pos_byte = CHAR_TO_BYTE (this_pos);
+           match_byte = pos_byte - this_pos_byte;
 
            while (this_len > 0)
              {
@@ -1460,7 +1477,7 @@ simple_search (n, pat, len, len_byte, trt, pos, pos_byte, lim, lim_byte)
            if (this_len == 0)
              {
                pos -= len;
-               pos_byte -= len_byte;
+               pos_byte -= match_byte;
                break;
              }
 
@@ -1496,6 +1513,7 @@ simple_search (n, pat, len, len_byte, trt, pos, pos_byte, lim, lim_byte)
 
            if (this_len == 0)
              {
+               match_byte = len;
                pos -= len;
                break;
              }
@@ -1510,9 +1528,9 @@ simple_search (n, pat, len, len_byte, trt, pos, pos_byte, lim, lim_byte)
   if (n == 0)
     {
       if (forward)
-       set_search_regs ((multibyte ? pos_byte : pos) - len_byte, len_byte);
+       set_search_regs ((multibyte ? pos_byte : pos) - match_byte, match_byte);
       else
-       set_search_regs (multibyte ? pos_byte : pos, len_byte);
+       set_search_regs (multibyte ? pos_byte : pos, match_byte);
 
       return pos;
     }
@@ -1561,7 +1579,7 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt,
 
   unsigned char simple_translate[0400];
   /* These are set to the preceding bytes of a byte to be translated
-     if charset_base is nonzero.  As the maximum byte length of a
+     if char_base is nonzero.  As the maximum byte length of a
      multibyte character is 5, we have to check at most four previous
      bytes.  */
   int translate_prev_byte1 = 0;
@@ -1662,22 +1680,31 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt,
        i = infinity;
       if (! NILP (trt))
        {
-         /* If the byte currently looking at is a head of a character
-            to check case-equivalents, set CH to that character.  An
-            ASCII character and a non-ASCII character matching with
-            CHAR_BASE are to be checked.  */
+         /* If the byte currently looking at is the last of a
+            character to check case-equivalents, set CH to that
+            character.  An ASCII character and a non-ASCII character
+            matching with CHAR_BASE are to be checked.  */
          int ch = -1;
 
          if (ASCII_BYTE_P (*ptr) || ! multibyte)
            ch = *ptr;
-         else if (char_base && CHAR_HEAD_P (*ptr))
+         else if (char_base
+                  && ((pat_end - ptr) == 1 || CHAR_HEAD_P (ptr[1])))
            {
-             ch = STRING_CHAR (ptr, pat_end - ptr);
+             unsigned char *charstart = ptr - 1;
+
+             while (! (CHAR_HEAD_P (*charstart)))
+               charstart--;
+             ch = STRING_CHAR (charstart, ptr - charstart + 1);
              if (char_base != (ch & ~0x3F))
                ch = -1;
            }
 
-         j = *ptr;
+         if (ch >= 0400)
+           j = (ch & 0x3F) | 0200;
+         else
+           j = *ptr;
+
          if (i == infinity)
            stride_for_teases = BM_tab[j];
 
@@ -1687,17 +1714,13 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt,
          if (ch >= 0)
            {
              int starting_ch = ch;
-             int starting_j;
+             int starting_j = j;
 
-             if (ch > 0400)
-               starting_j = (ch & ~0x3F) | 0200;
-             else
-               starting_j = ch;
              while (1)
                {
                  TRANSLATE (ch, inverse_trt, ch);
-                 if (ch > 0400)
-                   j = (ch & ~0x3F) | 0200;
+                 if (ch >= 0400)
+                   j = (ch & 0x3F) | 0200;
                  else
                    j = ch;
 
@@ -2333,7 +2356,7 @@ since only regular expressions have distinguished subexpressions.  */)
              else
                some_multiletter_word = 1;
            }
-         else if (!NOCASEP (c))
+         else if (UPPERCASEP (c))
            {
              some_uppercase = 1;
              if (SYNTAX (prevc) != Sword)
@@ -3020,7 +3043,7 @@ DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0,
 
   for (; in != end; in++)
     {
-      if (*in == '[' || *in == ']'
+      if (*in == '['
          || *in == '*' || *in == '.' || *in == '\\'
          || *in == '?' || *in == '+'
          || *in == '^' || *in == '$')