]> code.delx.au - gnu-emacs/blobdiff - src/search.c
(try_window): Revert previous change.
[gnu-emacs] / src / search.c
index 6beaa2d4186a203ddb3f2e0dd400c9d25fb540ef..abc28619199ea780ab4135f72d5642bbfa529911 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, 2001, 2002,
+                 2003, 2004, 2005, 2006, 2007  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -42,6 +42,10 @@ struct regexp_cache
 {
   struct regexp_cache *next;
   Lisp_Object regexp, whitespace_regexp;
+  /* Syntax table for which the regexp applies.  We need this because
+     of character classes.  If this is t, then the compiled pattern is valid
+     for any syntax-table.  */
+  Lisp_Object syntax_table;
   struct re_pattern_buffer buf;
   char fastmap[0400];
   /* Nonzero means regexp was compiled to do full POSIX backtracking.  */
@@ -83,6 +87,9 @@ static Lisp_Object last_thing_searched;
 
 Lisp_Object Qinvalid_regexp;
 
+/* Error condition used for failing searches */
+Lisp_Object Qsearch_failed;
+
 Lisp_Object Vsearch_spaces_regexp;
 
 static void set_search_regs ();
@@ -90,6 +97,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 ()
@@ -163,7 +171,11 @@ compile_pattern_1 (cp, pattern, translate, regp, posix, multibyte)
   cp->posix = posix;
   cp->buf.multibyte = multibyte;
   cp->whitespace_regexp = Vsearch_spaces_regexp;
-  BLOCK_INPUT;
+  /* rms: I think BLOCK_INPUT is not needed here any more,
+     because regex.c defines malloc to call xmalloc.
+     Using BLOCK_INPUT here means the debugger won't run if an error occurs.
+     So let's turn it off.  */
+  /*  BLOCK_INPUT;  */
   old = re_set_syntax (RE_SYNTAX_EMACS
                       | (posix ? 0 : RE_NO_POSIX_BACKTRACKING));
 
@@ -173,12 +185,16 @@ compile_pattern_1 (cp, pattern, translate, regp, posix, multibyte)
   val = (char *) re_compile_pattern ((char *)raw_pattern,
                                     raw_pattern_size, &cp->buf);
 
+  /* If the compiled pattern hard codes some of the contents of the
+     syntax-table, it can only be reused with *this* syntax table.  */
+  cp->syntax_table = cp->buf.used_syntax ? current_buffer->syntax_table : Qt;
+
   re_set_whitespace_regexp (NULL);
 
   re_set_syntax (old);
-  UNBLOCK_INPUT;
+  /* UNBLOCK_INPUT;  */
   if (val)
-    Fsignal (Qinvalid_regexp, Fcons (build_string (val), Qnil));
+    xsignal1 (Qinvalid_regexp, build_string (val));
 
   cp->regexp = Fcopy_sequence (pattern);
 }
@@ -200,6 +216,24 @@ shrink_regexp_cache ()
     }
 }
 
+/* Clear the regexp cache w.r.t. a particular syntax table,
+   because it was changed.
+   There is no danger of memory leak here because re_compile_pattern
+   automagically manages the memory in each re_pattern_buffer struct,
+   based on its `allocated' and `buffer' values.  */
+void
+clear_regexp_cache ()
+{
+  int i;
+
+  for (i = 0; i < REGEXP_CACHE_SIZE; ++i)
+    /* It's tempting to compare with the syntax-table we've actually changd,
+       but it's not sufficient because char-table inheritance mewans that
+       modifying one syntax-table can change others at the same time.  */
+    if (!EQ (searchbufs[i].syntax_table, Qt))
+      searchbufs[i].regexp = Qnil;
+}
+
 /* Compile a regexp if necessary, but first check to see if there's one in
    the cache.
    PATTERN is the pattern to compile.
@@ -236,6 +270,8 @@ compile_pattern (pattern, regp, translate, posix, multibyte)
          && EQ (cp->buf.translate, (! NILP (translate) ? translate : make_number (0)))
          && cp->posix == posix
          && cp->buf.multibyte == multibyte
+         && (EQ (cp->syntax_table, Qt)
+             || EQ (cp->syntax_table, current_buffer->syntax_table))
          && !NILP (Fequal (cp->whitespace_regexp, Vsearch_spaces_regexp)))
        break;
 
@@ -265,16 +301,6 @@ compile_pattern (pattern, regp, translate, posix, multibyte)
   return &cp->buf;
 }
 
-/* Error condition used for failing searches */
-Lisp_Object Qsearch_failed;
-
-Lisp_Object
-signal_failure (arg)
-     Lisp_Object arg;
-{
-  Fsignal (Qsearch_failed, Fcons (arg, Qnil));
-  return Qnil;
-}
 \f
 static Lisp_Object
 looking_at_1 (string, posix)
@@ -290,6 +316,10 @@ looking_at_1 (string, posix)
   if (running_asynch_code)
     save_search_regs ();
 
+  /* This is so set_image_of_range_1 in regex.c can find the EQV table.  */
+  XCHAR_TABLE (current_buffer->case_canon_table)->extras[2]
+    = current_buffer->case_eqv_table;
+
   CHECK_STRING (string);
   bufp = compile_pattern (string, &search_regs,
                          (!NILP (current_buffer->case_fold_search)
@@ -397,6 +427,10 @@ string_match_1 (regexp, string, start, posix)
       pos_byte = string_char_to_byte (string, pos);
     }
 
+  /* This is so set_image_of_range_1 in regex.c can find the EQV table.  */
+  XCHAR_TABLE (current_buffer->case_canon_table)->extras[2]
+    = current_buffer->case_eqv_table;
+
   bufp = compile_pattern (regexp, &search_regs,
                          (!NILP (current_buffer->case_fold_search)
                           ? current_buffer->case_canon_table : Qnil),
@@ -429,7 +463,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
@@ -936,6 +970,10 @@ search_command (string, bound, noerror, count, direction, RE, posix)
        lim_byte = CHAR_TO_BYTE (lim);
     }
 
+  /* This is so set_image_of_range_1 in regex.c can find the EQV table.  */
+  XCHAR_TABLE (current_buffer->case_canon_table)->extras[2]
+    = current_buffer->case_eqv_table;
+
   np = search_buffer (string, PT, PT_BYTE, lim, lim_byte, n, RE,
                      (!NILP (current_buffer->case_fold_search)
                       ? current_buffer->case_canon_table
@@ -947,7 +985,8 @@ search_command (string, bound, noerror, count, direction, RE, posix)
   if (np <= 0)
     {
       if (NILP (noerror))
-       return signal_failure (string);
+       xsignal1 (Qsearch_failed, string);
+
       if (!EQ (noerror, Qt))
        {
          if (lim < BEGV || lim > ZV)
@@ -1174,10 +1213,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 charset_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 charset_base = -1;
       int boyer_moore_ok = 1;
 
       /* MULTIBYTE says whether the text to be searched is multibyte.
@@ -1275,24 +1314,30 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n,
                         always handle their translation.  */
                      while (1)
                        {
-                         if (ASCII_BYTE_P (inverse))
+                         if (ASCII_BYTE_P (inverse))
                            {
-                             if (SINGLE_BYTE_CHAR_P (inverse))
-                               {
-                                 /* Boyer-moore search can't handle a
-                                    translation of an eight-bit
-                                    character.  */
-                                 boyer_moore_ok = 0;
-                                 break;
-                               }
-                             else if (charset_base == 0)
-                               charset_base = inverse & ~CHAR_FIELD3_MASK;
-                             else if ((inverse & ~CHAR_FIELD3_MASK)
-                                      != charset_base)
+                             if (charset_base > 0)
                                {
                                  boyer_moore_ok = 0;
                                  break;
                                }
+                             charset_base = 0;
+                           }
+                         else if (SINGLE_BYTE_CHAR_P (inverse))
+                           {
+                             /* Boyer-moore search can't handle a
+                                translation of an eight-bit
+                                character.  */
+                             boyer_moore_ok = 0;
+                             break;
+                           }
+                         else if (charset_base < 0)
+                           charset_base = inverse & ~CHAR_FIELD3_MASK;
+                         else if ((inverse & ~CHAR_FIELD3_MASK)
+                                  != charset_base)
+                           {
+                             boyer_moore_ok = 0;
+                             break;
                            }
                          if (c == inverse)
                            break;
@@ -1300,6 +1345,8 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n,
                        }
                    }
                }
+             if (charset_base < 0)
+               charset_base = 0;
 
              /* Store this character into the translated pattern.  */
              bcopy (str, pat, charlen);
@@ -1467,7 +1514,7 @@ simple_search (n, pat, len, len_byte, trt, pos, pos_byte, lim, lim_byte)
            int this_len_byte = len_byte;
            unsigned char *p = pat;
 
-           if (pos - len < lim)
+           if (this_pos < lim || this_pos_byte < lim_byte)
              goto stop;
 
            while (this_len > 0)
@@ -1701,7 +1748,7 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt,
          if (ASCII_BYTE_P (*ptr) || ! multibyte)
            ch = *ptr;
          else if (charset_base
-                  && (pat_end - ptr) == 1 || CHAR_HEAD_P (ptr[1]))
+                  && ((pat_end - ptr) == 1 || CHAR_HEAD_P (ptr[1])))
            {
              unsigned char *charstart = ptr - 1;
 
@@ -1712,7 +1759,7 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt,
                ch = -1;
            }
 
-         if (ch > 0400)
+         if (ch >= 0400)
            j = ((unsigned char) ch) | 0200;
          else
            j = *ptr;
@@ -1731,7 +1778,7 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt,
              while (1)
                {
                  TRANSLATE (ch, inverse_trt, ch);
-                 if (ch > 0400)
+                 if (ch >= 0400)
                    j = ((unsigned char) ch) | 0200;
                  else
                    j = (unsigned char) ch;
@@ -2118,8 +2165,8 @@ DEFUN ("search-forward", Fsearch_forward, Ssearch_forward, 1, 4, "MSearch: ",
        doc: /* Search forward from point for STRING.
 Set point to the end of the occurrence found, and return point.
 An optional second argument bounds the search; it is a buffer position.
-The match found must not extend after that position.  nil is equivalent
-  to (point-max).
+The match found must not extend after that position.  A value of nil is
+  equivalent to (point-max).
 Optional third argument, if t, means if fail just return nil (no error).
   If not nil and not t, move to limit of search and return nil.
 Optional fourth argument is repeat count--search for successive occurrences.
@@ -2368,7 +2415,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)
@@ -2865,8 +2912,7 @@ If optional arg RESEAT is non-nil, make markers on LIST point nowhere.  */)
   if (running_asynch_code)
     save_search_regs ();
 
-  if (!CONSP (list) && !NILP (list))
-    list = wrong_type_argument (Qconsp, list);
+  CHECK_LIST (list);
 
   /* Unless we find a marker with a buffer or an explicit buffer
      in LIST, assume that this match data came from a string.  */
@@ -3058,7 +3104,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 == '$')
@@ -3084,7 +3130,10 @@ syms_of_search ()
       searchbufs[i].buf.fastmap = searchbufs[i].fastmap;
       searchbufs[i].regexp = Qnil;
       searchbufs[i].whitespace_regexp = Qnil;
+      searchbufs[i].syntax_table = Qnil;
       staticpro (&searchbufs[i].regexp);
+      staticpro (&searchbufs[i].whitespace_regexp);
+      staticpro (&searchbufs[i].syntax_table);
       searchbufs[i].next = (i == REGEXP_CACHE_SIZE-1 ? 0 : &searchbufs[i+1]);
     }
   searchbuf_head = &searchbufs[0];