]> code.delx.au - gnu-emacs/blobdiff - src/search.c
(SETUP_SYNTAX_TABLE_FOR_OBJECT): Call bytepos_to_charpos.
[gnu-emacs] / src / search.c
index 7c8e58aa01cf2fe570c54fa840c4d66a9d956987..df73f4a53699cfd62ac07b5177ddd0c7ac028a1e 100644 (file)
@@ -28,6 +28,7 @@ Boston, MA 02111-1307, USA.  */
 #include "region-cache.h"
 #include "commands.h"
 #include "blockinput.h"
+#include "intervals.h"
 
 #include <sys/types.h>
 #include "regex.h"
@@ -121,7 +122,7 @@ compile_pattern_1 (cp, pattern, translate, regp, posix, multibyte)
      int posix;
      int multibyte;
 {
-  CONST char *val;
+  char *val;
   reg_syntax_t old;
 
   cp->regexp = Qnil;
@@ -131,8 +132,8 @@ compile_pattern_1 (cp, pattern, translate, regp, posix, multibyte)
   BLOCK_INPUT;
   old = re_set_syntax (RE_SYNTAX_EMACS
                       | (posix ? 0 : RE_NO_POSIX_BACKTRACKING));
-  val = (CONST char *) re_compile_pattern ((char *) XSTRING (pattern)->data,
-                                          XSTRING (pattern)->size, &cp->buf);
+  val = (char *) re_compile_pattern ((char *) XSTRING (pattern)->data,
+                                    XSTRING (pattern)->size, &cp->buf);
   re_set_syntax (old);
   UNBLOCK_INPUT;
   if (val)
@@ -225,7 +226,7 @@ looking_at_1 (string, posix)
   CHECK_STRING (string, 0);
   bufp = compile_pattern (string, &search_regs,
                          (!NILP (current_buffer->case_fold_search)
-                          ? DOWNCASE_TABLE : 0),
+                          ? XCHAR_TABLE (DOWNCASE_TABLE)->contents : 0),
                          posix);
 
   immediate_quit = 1;
@@ -249,6 +250,8 @@ looking_at_1 (string, posix)
       s1 = ZV - BEGV;
       s2 = 0;
     }
+
+  re_match_object = Qnil;
   
   i = re_match_2 (bufp, (char *) p1, s1, (char *) p2, s2,
                  PT - BEGV, &search_regs,
@@ -322,9 +325,11 @@ string_match_1 (regexp, string, start, posix)
 
   bufp = compile_pattern (regexp, &search_regs,
                          (!NILP (current_buffer->case_fold_search)
-                          ? DOWNCASE_TABLE : 0),
+                          ? XCHAR_TABLE (DOWNCASE_TABLE)->contents : 0),
                          posix);
   immediate_quit = 1;
+  re_match_object = string;
+  
   val = re_search (bufp, (char *) XSTRING (string)->data,
                   XSTRING (string)->size, s, XSTRING (string)->size - s,
                   &search_regs);
@@ -374,6 +379,8 @@ fast_string_match (regexp, string)
 
   bufp = compile_pattern (regexp, 0, 0, 0);
   immediate_quit = 1;
+  re_match_object = string;
+  
   val = re_search (bufp, (char *) XSTRING (string)->data,
                   XSTRING (string)->size, 0, XSTRING (string)->size,
                   0);
@@ -388,7 +395,7 @@ fast_string_match (regexp, string)
 extern Lisp_Object Vascii_downcase_table;
 
 int
-fast_string_match_ignore_case (regexp, string)
+fast_c_string_match_ignore_case (regexp, string)
      Lisp_Object regexp;
      char *string;
 {
@@ -396,6 +403,7 @@ fast_string_match_ignore_case (regexp, string)
   struct re_pattern_buffer *bufp;
   int len = strlen (string);
 
+  re_match_object = Qt;
   bufp = compile_pattern (regexp, 0,
                          XCHAR_TABLE (Vascii_downcase_table)->contents, 0);
   immediate_quit = 1;
@@ -671,299 +679,6 @@ find_before_next_newline (from, to, cnt)
   return pos;
 }
 \f
-Lisp_Object skip_chars ();
-
-DEFUN ("skip-chars-forward", Fskip_chars_forward, Sskip_chars_forward, 1, 2, 0,
-  "Move point forward, stopping before a char not in STRING, or at pos LIM.\n\
-STRING is like the inside of a `[...]' in a regular expression\n\
-except that `]' is never special and `\\' quotes `^', `-' or `\\'.\n\
-Thus, with arg \"a-zA-Z\", this skips letters stopping before first nonletter.\n\
-With arg \"^a-zA-Z\", skips nonletters stopping before first letter.\n\
-Returns the distance traveled, either zero or positive.")
-  (string, lim)
-     Lisp_Object string, lim;
-{
-  return skip_chars (1, 0, string, lim);
-}
-
-DEFUN ("skip-chars-backward", Fskip_chars_backward, Sskip_chars_backward, 1, 2, 0,
-  "Move point backward, stopping after a char not in STRING, or at pos LIM.\n\
-See `skip-chars-forward' for details.\n\
-Returns the distance traveled, either zero or negative.")
-  (string, lim)
-     Lisp_Object string, lim;
-{
-  return skip_chars (0, 0, string, lim);
-}
-
-DEFUN ("skip-syntax-forward", Fskip_syntax_forward, Sskip_syntax_forward, 1, 2, 0,
-  "Move point forward across chars in specified syntax classes.\n\
-SYNTAX is a string of syntax code characters.\n\
-Stop before a char whose syntax is not in SYNTAX, or at position LIM.\n\
-If SYNTAX starts with ^, skip characters whose syntax is NOT in SYNTAX.\n\
-This function returns the distance traveled, either zero or positive.")
-  (syntax, lim)
-     Lisp_Object syntax, lim;
-{
-  return skip_chars (1, 1, syntax, lim);
-}
-
-DEFUN ("skip-syntax-backward", Fskip_syntax_backward, Sskip_syntax_backward, 1, 2, 0,
-  "Move point backward across chars in specified syntax classes.\n\
-SYNTAX is a string of syntax code characters.\n\
-Stop on reaching a char whose syntax is not in SYNTAX, or at position LIM.\n\
-If SYNTAX starts with ^, skip characters whose syntax is NOT in SYNTAX.\n\
-This function returns the distance traveled, either zero or negative.")
-  (syntax, lim)
-     Lisp_Object syntax, lim;
-{
-  return skip_chars (0, 1, syntax, lim);
-}
-
-Lisp_Object
-skip_chars (forwardp, syntaxp, string, lim)
-     int forwardp, syntaxp;
-     Lisp_Object string, lim;
-{
-  register unsigned char *p, *pend;
-  register unsigned int c;
-  register int ch;
-  unsigned char fastmap[0400];
-  /* If SYNTAXP is 0, STRING may contain multi-byte form of characters
-     of which codes don't fit in FASTMAP.  In that case, we set the
-     first byte of multibyte form (i.e. base leading-code) in FASTMAP
-     and set the actual ranges of characters in CHAR_RANGES.  In the
-     form "X-Y" of STRING, both X and Y must belong to the same
-     character set because a range striding across character sets is
-     meaningless.  */
-  int *char_ranges
-    = (int *) alloca (XSTRING (string)->size * (sizeof (int)) * 2);
-  int n_char_ranges = 0;
-  int negate = 0;
-  register int i;
-  int multibyte = !NILP (current_buffer->enable_multibyte_characters);
-
-  CHECK_STRING (string, 0);
-
-  if (NILP (lim))
-    XSETINT (lim, forwardp ? ZV : BEGV);
-  else
-    CHECK_NUMBER_COERCE_MARKER (lim, 1);
-
-  /* In any case, don't allow scan outside bounds of buffer.  */
-  /* jla turned this off, for no known reason.
-     bfox turned the ZV part on, and rms turned the
-     BEGV part back on.  */
-  if (XINT (lim) > ZV)
-    XSETFASTINT (lim, ZV);
-  if (XINT (lim) < BEGV)
-    XSETFASTINT (lim, BEGV);
-
-  p = XSTRING (string)->data;
-  pend = p + XSTRING (string)->size;
-  bzero (fastmap, sizeof fastmap);
-
-  if (p != pend && *p == '^')
-    {
-      negate = 1; p++;
-    }
-
-  /* Find the characters specified and set their elements of fastmap.
-     If syntaxp, each character counts as itself.
-     Otherwise, handle backslashes and ranges specially.  */
-
-  while (p != pend)
-    {
-      c = *p;
-      if (multibyte)
-       {
-         ch = STRING_CHAR (p, pend - p);
-         p += BYTES_BY_CHAR_HEAD (*p);
-       }
-      else
-       {
-         ch = c;
-         p++;
-       }
-      if (syntaxp)
-       fastmap[syntax_spec_code[c]] = 1;
-      else
-       {
-         if (c == '\\')
-           {
-             if (p == pend) break;
-             c = *p++;
-           }
-         if (p != pend && *p == '-')
-           {
-             unsigned int ch2;
-
-             p++;
-             if (p == pend) break;
-             if (SINGLE_BYTE_CHAR_P (ch))
-               while (c <= *p)
-                 {
-                   fastmap[c] = 1;
-                   c++;
-                 }
-             else
-               {
-                 fastmap[c] = 1; /* C is the base leading-code.  */
-                 ch2 = STRING_CHAR (p, pend - p);
-                 if (ch <= ch2)
-                   char_ranges[n_char_ranges++] = ch,
-                   char_ranges[n_char_ranges++] = ch2;
-               }
-             p += multibyte ? BYTES_BY_CHAR_HEAD (*p) : 1;
-           }
-         else
-           {
-             fastmap[c] = 1;
-             if (!SINGLE_BYTE_CHAR_P (ch))
-               char_ranges[n_char_ranges++] = ch,
-               char_ranges[n_char_ranges++] = ch;
-           }
-       }
-    }
-
-  /* If ^ was the first character, complement the fastmap.  In
-     addition, as all multibyte characters have possibility of
-     matching, set all entries for base leading codes, which is
-     harmless even if SYNTAXP is 1.  */
-
-  if (negate)
-    for (i = 0; i < sizeof fastmap; i++)
-      {
-       if (!multibyte || !BASE_LEADING_CODE_P (i))
-         fastmap[i] ^= 1;
-       else
-         fastmap[i] = 1;
-      }
-
-  {
-    int start_point = PT;
-    int pos = PT;
-
-    immediate_quit = 1;
-    if (syntaxp)
-      {
-       if (forwardp)
-         {
-           if (multibyte)
-             while (pos < XINT (lim)
-                    && fastmap[(int) SYNTAX (FETCH_CHAR (pos))])
-               INC_POS (pos);
-           else
-             while (pos < XINT (lim)
-                    && fastmap[(int) SYNTAX (FETCH_BYTE (pos))])
-               pos++;
-         }
-       else
-         {
-           if (multibyte)
-             while (pos > XINT (lim))
-               {
-                 int savepos = pos;
-                 DEC_POS (pos);
-                 if (!fastmap[(int) SYNTAX (FETCH_CHAR (pos))])
-                   {
-                     pos = savepos;
-                     break;
-                   }
-               }
-           else
-             while (pos > XINT (lim)
-                    && fastmap[(int) SYNTAX (FETCH_BYTE (pos - 1))])
-               pos--;
-         }
-      }
-    else
-      {
-       if (forwardp)
-         {
-           if (multibyte)
-             while (pos < XINT (lim) && fastmap[(c = FETCH_BYTE (pos))])
-               {
-                 if (!BASE_LEADING_CODE_P (c))
-                   pos++;
-                 else if (n_char_ranges)
-                   {
-                     /* We much check CHAR_RANGES for a multibyte
-                        character.  */
-                     ch = FETCH_MULTIBYTE_CHAR (pos);
-                     for (i = 0; i < n_char_ranges; i += 2)
-                       if ((ch >= char_ranges[i] && ch <= char_ranges[i + 1]))
-                         break;
-                     if (!(negate ^ (i < n_char_ranges)))
-                       break;
-
-                     INC_POS (pos);
-                   }
-                 else
-                   {
-                     if (!negate) break;
-                     INC_POS (pos);
-                   }
-               }
-           else
-             while (pos < XINT (lim) && fastmap[FETCH_BYTE (pos)])
-               pos++;
-         }
-       else
-         {
-           if (multibyte)
-             while (pos > XINT (lim))
-               {
-                 int savepos = pos;
-                 DEC_POS (pos);
-                 if (fastmap[(c = FETCH_BYTE (pos))])
-                   {
-                     if (!BASE_LEADING_CODE_P (c))
-                       ;
-                     else if (n_char_ranges)
-                       {
-                         /* We much check CHAR_RANGES for a multibyte
-                            character.  */
-                         ch = FETCH_MULTIBYTE_CHAR (pos);
-                         for (i = 0; i < n_char_ranges; i += 2)
-                           if (ch >= char_ranges[i] && ch <= char_ranges[i + 1])
-                             break;
-                         if (!(negate ^ (i < n_char_ranges)))
-                           {
-                             pos = savepos;
-                             break;
-                           }
-                       }
-                     else
-                       if (!negate)
-                         {
-                           pos = savepos;
-                           break;
-                         }
-                   }
-                 else
-                   {
-                     pos = savepos;
-                     break;
-                   }
-               }
-           else
-             while (pos > XINT (lim) && fastmap[FETCH_BYTE (pos - 1)])
-               pos--;
-         }
-      }
-    if (multibyte
-       /* INC_POS or DEC_POS might have moved POS over LIM.  */
-       && (forwardp ? (pos > XINT (lim)) : (pos < XINT (lim))))
-      pos = XINT (lim);
-
-    SET_PT (pos);
-    immediate_quit = 0;
-
-    return make_number (PT - start_point);
-  }
-}
-\f
 /* Subroutines of Lisp buffer search functions. */
 
 static Lisp_Object
@@ -1145,6 +860,8 @@ search_buffer (string, pos, lim, n, RE, trt, inverse_trt, posix)
          s1 = ZV - BEGV;
          s2 = 0;
        }
+      re_match_object = Qnil;
+  
       while (n < 0)
        {
          int val;
@@ -1229,7 +946,7 @@ search_buffer (string, pos, lim, n, RE, trt, inverse_trt, posix)
                len--;
                base_pat++;
              }
-           *pat++ = (trt ? trt[*base_pat++] : *base_pat++);
+           *pat++ = (trt ? XINT (trt[*base_pat++]) : *base_pat++);
          }
        len = pat - patbuf;
        pat = base_pat = patbuf;
@@ -1284,13 +1001,13 @@ search_buffer (string, pos, lim, n, RE, trt, inverse_trt, posix)
          if (i == dirlen) i = infinity;
          if (trt != 0)
            {
-             k = (j = trt[j]);
+             k = (j = XINT (trt[j]));
              if (i == infinity)
                stride_for_teases = BM_tab[j];
              BM_tab[j] = dirlen - i;
              /* A translation table is accompanied by its inverse -- see */
              /* comment following downcase_table for details */ 
-             while ((j = (unsigned char) inverse_trt[j]) != k)
+             while ((j = (unsigned char) XINT (inverse_trt[j])) != k)
                BM_tab[j] = dirlen - i;
            }
          else
@@ -1373,7 +1090,7 @@ search_buffer (string, pos, lim, n, RE, trt, inverse_trt, posix)
                  if (trt != 0)
                    {
                      while ((i -= direction) + direction != 0)
-                       if (pat[i] != trt[*(cursor -= direction)])
+                       if (pat[i] != XINT (trt[*(cursor -= direction)]))
                          break;
                    }
                  else
@@ -1434,7 +1151,7 @@ search_buffer (string, pos, lim, n, RE, trt, inverse_trt, posix)
                    {
                      pos -= direction;
                      if (pat[i] != (trt != 0
-                                    ? trt[FETCH_BYTE (pos)]
+                                    ? XINT (trt[FETCH_BYTE (pos)])
                                     : FETCH_BYTE (pos)))
                        break;
                    }
@@ -1538,7 +1255,7 @@ wordify (string)
 }
 \f
 DEFUN ("search-backward", Fsearch_backward, Ssearch_backward, 1, 4,
-  "sSearch backward: ",
+  "MSearch backward: ",
   "Search backward from point for STRING.\n\
 Set point to the beginning of the occurrence found, and return point.\n\
 An optional second argument bounds the search; it is a buffer position.\n\
@@ -1553,7 +1270,7 @@ See also the functions `match-beginning', `match-end' and `replace-match'.")
   return search_command (string, bound, noerror, count, -1, 0, 0);
 }
 
-DEFUN ("search-forward", Fsearch_forward, Ssearch_forward, 1, 4, "sSearch: ",
+DEFUN ("search-forward", Fsearch_forward, Ssearch_forward, 1, 4, "MSearch: ",
   "Search forward from point for STRING.\n\
 Set point to the end of the occurrence found, and return point.\n\
 An optional second argument bounds the search; it is a buffer position.\n\
@@ -1707,6 +1424,7 @@ since only regular expressions have distinguished subexpressions.")
   register int c, prevc;
   int inslen;
   int sub;
+  int opoint, newpoint;
 
   CHECK_STRING (newtext, 0);
 
@@ -1900,11 +1618,18 @@ since only regular expressions have distinguished subexpressions.")
       return concat3 (before, newtext, after);
     }
 
+  /* Record point, the move (quietly) to the start of the match.  */
+  if (PT > search_regs.start[sub])
+    opoint = PT - ZV;
+  else
+    opoint = PT;
+
+  temp_set_point (search_regs.start[sub], current_buffer);
+
   /* We insert the replacement text before the old text, and then
      delete the original text.  This means that markers at the
      beginning or end of the original will float to the corresponding
      position in the replacement.  */
-  SET_PT (search_regs.start[sub]);
   if (!NILP (literal))
     Finsert_and_inherit (1, &newtext);
   else
@@ -1951,6 +1676,18 @@ since only regular expressions have distinguished subexpressions.")
     Fupcase_region (make_number (PT - inslen), make_number (PT));
   else if (case_action == cap_initial)
     Fupcase_initials_region (make_number (PT - inslen), make_number (PT));
+
+  newpoint = PT;
+
+  /* Put point back where it was in the text.  */
+  if (opoint <= 0)
+    temp_set_point (opoint + ZV, current_buffer);
+  else
+    temp_set_point (opoint, current_buffer);
+
+  /* Now move point "officially" to the start of the inserted replacement.  */
+  move_if_not_intangible (newpoint);
+  
   return Qnil;
 }
 \f
@@ -2273,10 +2010,6 @@ syms_of_search ()
   defsubr (&Sposix_looking_at);
   defsubr (&Sstring_match);
   defsubr (&Sposix_string_match);
-  defsubr (&Sskip_chars_forward);
-  defsubr (&Sskip_chars_backward);
-  defsubr (&Sskip_syntax_forward);
-  defsubr (&Sskip_syntax_backward);
   defsubr (&Ssearch_forward);
   defsubr (&Ssearch_backward);
   defsubr (&Sword_search_forward);