XEmacs 21.4.6 "Common Lisp".
[chise/xemacs-chise.git.1] / src / search.c
index bb12714..6ae5f9d 100644 (file)
@@ -1563,7 +1563,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)
     {
@@ -1648,7 +1648,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
@@ -2245,6 +2245,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))
 {
@@ -2264,6 +2269,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);
@@ -2284,6 +2290,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;
@@ -2300,11 +2313,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
     {
@@ -2319,7 +2332,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;
 
@@ -2330,7 +2343,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);
@@ -2546,8 +2559,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. */
@@ -2557,7 +2570,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
@@ -2568,11 +2581,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
@@ -2615,9 +2638,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),