XEmacs 21.4.9 "Informed Management".
[chise/xemacs-chise.git.1] / src / search.c
index 169e1d7..8a496cb 100644 (file)
@@ -108,6 +108,7 @@ Lisp_Object Vforward_word_regexp, Vbackward_word_regexp;
 Lisp_Object Vskip_chars_range_table;
 
 static void set_search_regs (struct buffer *buf, Bufpos beg, Charcount len);
+/* #### according to comment in 21.5, unnecessary */
 static void save_search_regs (void);
 static Bufpos simple_search (struct buffer *buf, Bufbyte *base_pat,
                             Bytecount len, Bytind pos, Bytind lim,
@@ -312,8 +313,8 @@ looking_at_1 (Lisp_Object string, struct buffer *buf, int posix)
   s1 = p2 - p1;
   s2 = BI_BUF_ZV (buf) - p2;
 
+  regex_match_object = Qnil;
   regex_emacs_buffer = buf;
-  regex_emacs_buffer_p = 1;
   i = re_match_2 (bufp, (char *) BI_BUF_BYTE_ADDRESS (buf, p1),
                  s1, (char *) BI_BUF_BYTE_ADDRESS (buf, p2), s2,
                  BI_BUF_PT (buf) - BI_BUF_BEGV (buf), &search_regs,
@@ -403,8 +404,8 @@ string_match_1 (Lisp_Object regexp, Lisp_Object string, Lisp_Object start,
   QUIT;
   {
     Bytecount bis = charcount_to_bytecount (XSTRING_DATA (string), s);
+    regex_match_object = string;
     regex_emacs_buffer = buf;
-    regex_emacs_buffer_p = 0;
     val = re_search (bufp, (char *) XSTRING_DATA (string),
                     XSTRING_LENGTH (string), bis,
                     XSTRING_LENGTH (string) - bis,
@@ -495,8 +496,8 @@ fast_string_match (Lisp_Object regexp,  const Bufbyte *nonreloc,
     }
 
   /* #### evil current-buffer dependency */
+  regex_match_object = reloc;
   regex_emacs_buffer = current_buffer;
-  regex_emacs_buffer_p = 0;
   val = re_search (bufp, (char *) newnonreloc + offset, length, 0,
                   length, 0);
 
@@ -772,6 +773,7 @@ find_before_next_newline (struct buffer *buf, Bufpos from, Bufpos to, int count)
   return pos;
 }
 \f
+/* This function synched with FSF 21.1 */
 static Lisp_Object
 skip_chars (struct buffer *buf, int forwardp, int syntaxp,
            Lisp_Object string, Lisp_Object lim)
@@ -784,7 +786,9 @@ skip_chars (struct buffer *buf, int forwardp, int syntaxp,
   unsigned char fastmap[0400];
   int negate = 0;
   REGISTER int i;
+#ifndef emacs
   Lisp_Char_Table *syntax_table = XCHAR_TABLE (buf->mirror_syntax_table);
+#endif
   Bufpos limit;
 
   if (NILP (lim))
@@ -840,6 +844,7 @@ skip_chars (struct buffer *buf, int forwardp, int syntaxp,
            {
              Emchar cend;
 
+             /* Skip over the dash.  */
              p++;
              if (p == pend) break;
              cend = charptr_emchar (p);
@@ -864,6 +869,7 @@ skip_chars (struct buffer *buf, int forwardp, int syntaxp,
        }
     }
 
+  /* #### Not in FSF 21.1 */
   if (syntaxp && fastmap['-'] != 0)
     fastmap[' '] = 1;
 
@@ -877,66 +883,96 @@ skip_chars (struct buffer *buf, int forwardp, int syntaxp,
 
   {
     Bufpos start_point = BUF_PT (buf);
+    Bufpos pos = start_point;
+    Bytind pos_byte = BI_BUF_PT (buf);
 
     if (syntaxp)
       {
+       SETUP_SYNTAX_CACHE_FOR_BUFFER (buf, pos, forwardp ? 1 : -1);
        /* All syntax designators are normal chars so nothing strange
           to worry about */
        if (forwardp)
          {
-           while (BUF_PT (buf) < limit
-                  && fastmap[(unsigned char)
-                              syntax_code_spec
-                             [(int) SYNTAX (syntax_table,
-                                            BUF_FETCH_CHAR
-                                            (buf, BUF_PT (buf)))]])
-             BUF_SET_PT (buf, BUF_PT (buf) + 1);
+           if (pos < limit)
+             while (fastmap[(unsigned char)
+                            syntax_code_spec
+                            [(int) SYNTAX_FROM_CACHE
+                             (syntax_table,
+                              BI_BUF_FETCH_CHAR (buf, pos_byte))]])
+               {
+                 pos++;
+                 INC_BYTIND (buf, pos_byte);
+                 if (pos >= limit)
+                   break;
+                 UPDATE_SYNTAX_CACHE_FORWARD (pos);
+               }
          }
        else
          {
-           while (BUF_PT (buf) > limit
-                  && fastmap[(unsigned char)
-                              syntax_code_spec
-                             [(int) SYNTAX (syntax_table,
-                                            BUF_FETCH_CHAR
-                                            (buf, BUF_PT (buf) - 1))]])
-             BUF_SET_PT (buf, BUF_PT (buf) - 1);
+           while (pos > limit)
+             {
+               Bufpos savepos = pos_byte;
+               pos--;
+               DEC_BYTIND (buf, pos_byte);
+               UPDATE_SYNTAX_CACHE_BACKWARD (pos);
+               if (!fastmap[(unsigned char)
+                            syntax_code_spec
+                            [(int) SYNTAX_FROM_CACHE
+                             (syntax_table,
+                              BI_BUF_FETCH_CHAR (buf, pos_byte))]])
+                 {
+                   pos++;
+                   pos_byte = savepos;
+                   break;
+                 }
+             }
          }
       }
     else
       {
        if (forwardp)
          {
-           while (BUF_PT (buf) < limit)
+           while (pos < limit)
              {
-               Emchar ch = BUF_FETCH_CHAR (buf, BUF_PT (buf));
+               Emchar ch = BI_BUF_FETCH_CHAR (buf, pos_byte);
                if ((ch < 0400) ? fastmap[ch] :
                    (NILP (Fget_range_table (make_int (ch),
                                             Vskip_chars_range_table,
                                             Qnil))
                     == negate))
-                 BUF_SET_PT (buf, BUF_PT (buf) + 1);
+                 {
+                   pos++;
+                   INC_BYTIND (buf, pos_byte);
+                 }
                else
                  break;
              }
          }
        else
          {
-           while (BUF_PT (buf) > limit)
+           while (pos > limit)
              {
-               Emchar ch = BUF_FETCH_CHAR (buf, BUF_PT (buf) - 1);
+               Bufpos prev_pos_byte = pos_byte;
+               Emchar ch;
+
+               DEC_BYTIND (buf, prev_pos_byte);
+               ch = BI_BUF_FETCH_CHAR (buf, prev_pos_byte);
                if ((ch < 0400) ? fastmap[ch] :
-                   (NILP (Fget_range_table (make_int (ch),
-                                            Vskip_chars_range_table,
-                                            Qnil))
-                    == negate))
-                 BUF_SET_PT (buf, BUF_PT (buf) - 1);
-                else
-                  break;
+                     (NILP (Fget_range_table (make_int (ch),
+                                              Vskip_chars_range_table,
+                                              Qnil))
+                      == negate))
+                 {
+                   pos--;
+                   pos_byte = prev_pos_byte;
+                 }
+               else
+                 break;
              }
          }
       }
     QUIT;
+    BOTH_BUF_SET_PT (buf, pos, pos_byte);
     return make_int (BUF_PT (buf) - start_point);
   }
 }
@@ -1160,13 +1196,13 @@ search_buffer (struct buffer *buf, Lisp_Object string, Bufpos bufpos,
       p2 = BI_BUF_CEILING_OF (buf, p1);
       s1 = p2 - p1;
       s2 = BI_BUF_ZV (buf) - p2;
+      regex_match_object = Qnil;
 
       while (n < 0)
        {
          Bytecount val;
          QUIT;
           regex_emacs_buffer = buf;
-         regex_emacs_buffer_p = 1;
          val = re_search_2 (bufp,
                             (char *) BI_BUF_BYTE_ADDRESS (buf, p1), s1,
                             (char *) BI_BUF_BYTE_ADDRESS (buf, p2), s2,
@@ -1205,7 +1241,6 @@ search_buffer (struct buffer *buf, Lisp_Object string, Bufpos bufpos,
          Bytecount val;
          QUIT;
           regex_emacs_buffer = buf;
-         regex_emacs_buffer_p = 1;
           val = re_search_2 (bufp,
                             (char *) BI_BUF_BYTE_ADDRESS (buf, p1), s1,
                             (char *) BI_BUF_BYTE_ADDRESS (buf, p2), s2,
@@ -1555,7 +1590,7 @@ boyer_moore (struct buffer *buf, Bufbyte *base_pat, Bytecount len,
      in the pattern.  Others don't matter anyway!  */
   xzero (simple_translate);
   for (i = 0; i < 0400; i++)
-    simple_translate[i] = i;
+    simple_translate[i] = (Bufbyte) i;
   i = 0;
   while (i != infinity)
     {
@@ -1640,7 +1675,7 @@ boyer_moore (struct buffer *buf, Bufbyte *base_pat, Bytecount len,
 
          while ((j = TRANSLATE (inverse_trt, j)) != k)
            {
-             simple_translate[j] = k;
+             simple_translate[j] = (Bufbyte) k;
              BM_tab[j] = dirlen - i;
            }
 #endif
@@ -2237,6 +2272,11 @@ the buffer to be used for syntax-table and case-table lookup and
 defaults to the current buffer.  When fourth argument is not a string,
 the buffer that the match occurred in has automatically been remembered
 and you do not need to specify it.
+
+When fourth argument is nil, STRBUFFER specifies a subexpression of
+the match.  It says to replace just that subexpression instead of the
+whole match.  This is useful only after a regular expression search or
+match since only regular expressions have distinguished subexpressions.
 */
        (replacement, fixedcase, literal, string, strbuffer))
 {
@@ -2256,6 +2296,7 @@ and you do not need to specify it.
   Lisp_Object buffer;
   int_dynarr *ul_action_dynarr = 0;
   int_dynarr *ul_pos_dynarr = 0;
+  int sub = 0;
   int speccount;
 
   CHECK_STRING (replacement);
@@ -2276,6 +2317,13 @@ and you do not need to specify it.
     }
   else
     {
+      if (!NILP (strbuffer))
+       {
+         CHECK_INT (strbuffer);
+         sub = XINT (strbuffer);
+         if (sub < 0 || sub >= (int) search_regs.num_regs)
+           args_out_of_range (strbuffer, make_int (search_regs.num_regs));
+       }
       if (!BUFFERP (last_thing_searched))
        error ("last thing matched was not a buffer");
       buffer = last_thing_searched;
@@ -2292,11 +2340,11 @@ and you do not need to specify it.
 
   if (NILP (string))
     {
-      if (search_regs.start[0] < BUF_BEGV (buf)
-         || search_regs.start[0] > search_regs.end[0]
-         || search_regs.end[0] > BUF_ZV (buf))
-       args_out_of_range (make_int (search_regs.start[0]),
-                          make_int (search_regs.end[0]));
+      if (search_regs.start[sub] < BUF_BEGV (buf)
+         || search_regs.start[sub] > search_regs.end[sub]
+         || search_regs.end[sub] > BUF_ZV (buf))
+       args_out_of_range (make_int (search_regs.start[sub]),
+                          make_int (search_regs.end[sub]));
     }
   else
     {
@@ -2311,7 +2359,7 @@ and you do not need to specify it.
     {
       /* Decide how to casify by examining the matched text. */
 
-      last = search_regs.end[0];
+      last = search_regs.end[sub];
       prevc = '\n';
       case_action = all_caps;
 
@@ -2322,7 +2370,7 @@ and you do not need to specify it.
       some_nonuppercase_initial = 0;
       some_uppercase = 0;
 
-      for (pos = search_regs.start[0]; pos < last; pos++)
+      for (pos = search_regs.start[sub]; pos < last; pos++)
        {
          if (NILP (string))
            c = BUF_FETCH_CHAR (buf, pos);
@@ -2538,8 +2586,8 @@ and you do not need to specify it.
       return concat3 (before, replacement, after);
     }
 
-  mc_count = begin_multiple_change (buf, search_regs.start[0],
-                                   search_regs.end[0]);
+  mc_count = begin_multiple_change (buf, search_regs.start[sub],
+                                   search_regs.end[sub]);
 
   /* begin_multiple_change() records an unwind-protect, so we need to
      record this value now. */
@@ -2549,7 +2597,7 @@ and you do not need to specify it.
      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.  */
-  BUF_SET_PT (buf, search_regs.start[0]);
+  BUF_SET_PT (buf, search_regs.start[sub]);
   if (!NILP (literal))
     Finsert (1, &replacement);
   else
@@ -2560,11 +2608,21 @@ and you do not need to specify it.
       GCPRO1 (replacement);
       for (strpos = 0; strpos < stlen; strpos++)
        {
-         Charcount offset = BUF_PT (buf) - search_regs.start[0];
+         /* on the first iteration assert(offset==0),
+            exactly complementing BUF_SET_PT() above.
+            During the loop, it keeps track of the amount inserted.
+          */
+         Charcount offset = BUF_PT (buf) - search_regs.start[sub];
 
          c = string_char (XSTRING (replacement), strpos);
          if (c == '\\' && strpos < stlen - 1)
            {
+             /* XXX FIXME: replacing just a substring non-literally
+                using backslash refs to the match looks dangerous.  But
+                <15366.18513.698042.156573@ns.caldera.de> from Torsten Duwe
+                <duwe@caldera.de> claims Finsert_buffer_substring already
+                handles this correctly.
+             */
              c = string_char (XSTRING (replacement), ++strpos);
              if (c == '&')
                Finsert_buffer_substring
@@ -2607,9 +2665,9 @@ and you do not need to specify it.
       UNGCPRO;
     }
 
-  inslen = BUF_PT (buf) - (search_regs.start[0]);
-  buffer_delete_range (buf, search_regs.start[0] + inslen, search_regs.end[0] +
-                      inslen, 0);
+  inslen = BUF_PT (buf) - (search_regs.start[sub]);
+  buffer_delete_range (buf, search_regs.start[sub] + inslen,
+                      search_regs.end[sub] +  inslen, 0);
 
   if (case_action == all_caps)
     Fupcase_region (make_int (BUF_PT (buf) - inslen),
@@ -2794,8 +2852,11 @@ LIST should have been created by calling `match-data' previously.
   int num_regs;
   int length;
 
+#if 0
+  /* #### according to 21.5 comment, unnecessary */
   if (running_asynch_code)
     save_search_regs ();
+#endif
 
   CONCHECK_LIST (list);
 
@@ -2858,6 +2919,7 @@ LIST should have been created by calling `match-data' previously.
   return Qnil;
 }
 
+/* #### according to 21.5 comment, unnecessary */
 /* If non-zero the match data have been saved in saved_search_regs
    during the execution of a sentinel or filter. */
 static int search_regs_saved;
@@ -2881,6 +2943,8 @@ save_search_regs (void)
     }
 }
 
+/* #### according to 21.5 comment, unnecessary
+   prototype in lisp.h, all calls in process.c */
 /* Called upon exit from filters and sentinels. */
 void
 restore_match_data (void)