]> code.delx.au - gnu-emacs/blobdiff - src/search.c
(try_window): Revert previous change.
[gnu-emacs] / src / search.c
index b92812597d5de581ba0b0d428321d13d69b0586a..abc28619199ea780ab4135f72d5642bbfa529911 100644 (file)
@@ -1,6 +1,6 @@
 /* String search routines for GNU Emacs.
-   Copyright (C) 1985, 1986, 1987, 1993, 1994, 1997, 1998, 1999, 2002, 2003,
-                 2004, 2005, 2006 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),
@@ -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)
@@ -1475,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)
@@ -1720,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;
@@ -1739,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;
@@ -2126,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.
@@ -2873,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.  */
@@ -3092,8 +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];