(main): Use Vbuffer_alist instead of Fbuffer_list.
[bpt/emacs.git] / src / search.c
index a4e17a7..9015580 100644 (file)
@@ -20,6 +20,9 @@ Boston, MA 02111-1307, USA.  */
 
 
 #include <config.h>
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#endif
 #include "lisp.h"
 #include "syntax.h"
 #include "category.h"
@@ -33,6 +36,9 @@ Boston, MA 02111-1307, USA.  */
 #include <sys/types.h>
 #include "regex.h"
 
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#define max(a, b) ((a) > (b) ? (a) : (b))
+
 #define REGEXP_CACHE_SIZE 20
 
 /* If the regexp is non-nil, then the buffer contains the compiled form
@@ -135,7 +141,7 @@ compile_pattern_1 (cp, pattern, translate, regp, posix, multibyte)
   if (multibyte == STRING_MULTIBYTE (pattern))
     {
       raw_pattern = (char *) XSTRING (pattern)->data;
-      raw_pattern_size = XSTRING (pattern)->size_byte;
+      raw_pattern_size = STRING_BYTES (XSTRING (pattern));
     }
   else if (multibyte)
     {
@@ -156,11 +162,11 @@ compile_pattern_1 (cp, pattern, translate, regp, posix, multibyte)
       raw_pattern_size = XSTRING (pattern)->size;
       raw_pattern = (char *) alloca (raw_pattern_size + 1);
       copy_text (XSTRING (pattern)->data, raw_pattern,
-                XSTRING (pattern)->size_byte, 1, 0);
+                STRING_BYTES (XSTRING (pattern)), 1, 0);
     }
 
   cp->regexp = Qnil;
-  cp->buf.translate = (! NILP (translate) ? translate : 0);
+  cp->buf.translate = (! NILP (translate) ? translate : make_number (0));
   cp->posix = posix;
   cp->buf.multibyte = multibyte;
   BLOCK_INPUT;
@@ -200,7 +206,7 @@ compile_pattern (pattern, regp, translate, posix, multibyte)
       cp = *cpp;
       if (XSTRING (cp->regexp)->size == XSTRING (pattern)->size
          && !NILP (Fstring_equal (cp->regexp, pattern))
-         && cp->buf.translate == (! NILP (translate) ? translate : 0)
+         && EQ (cp->buf.translate, (! NILP (translate) ? translate : make_number (0)))
          && cp->posix == posix
          && cp->buf.multibyte == multibyte)
        break;
@@ -368,8 +374,8 @@ string_match_1 (regexp, string, start, posix)
   re_match_object = string;
   
   val = re_search (bufp, (char *) XSTRING (string)->data,
-                  XSTRING (string)->size_byte, pos_byte,
-                  XSTRING (string)->size_byte - pos_byte,
+                  STRING_BYTES (XSTRING (string)), pos_byte,
+                  STRING_BYTES (XSTRING (string)) - pos_byte,
                   &search_regs);
   immediate_quit = 0;
   last_thing_searched = Qt;
@@ -431,8 +437,8 @@ fast_string_match (regexp, string)
   re_match_object = string;
   
   val = re_search (bufp, (char *) XSTRING (string)->data,
-                  XSTRING (string)->size_byte, 0, XSTRING (string)->size_byte,
-                  0);
+                  STRING_BYTES (XSTRING (string)), 0,
+                  STRING_BYTES (XSTRING (string)), 0);
   immediate_quit = 0;
   return val;
 }
@@ -464,23 +470,6 @@ fast_c_string_match_ignore_case (regexp, string)
   return val;
 }
 \f
-/* max and min.  */
-
-static int
-max (a, b)
-     int a, b;
-{
-  return ((a > b) ? a : b);
-}
-
-static int
-min (a, b)
-     int a, b;
-{
-  return ((a < b) ? a : b);
-}
-
-\f
 /* The newline cache: remembering which sections of text have no newlines.  */
 
 /* If the user has requested newline caching, make sure it's on.
@@ -529,6 +518,7 @@ newline_cache_on_off (buf)
    If ALLOW_QUIT is non-zero, set immediate_quit.  That's good to do
    except when inside redisplay.  */
 
+int
 scan_buffer (target, start, end, count, shortage, allow_quit)
      register int target;
      int start, end;
@@ -568,6 +558,7 @@ scan_buffer (target, start, end, count, shortage, allow_quit)
            examine.  */
        int ceiling_byte = CHAR_TO_BYTE (end) - 1;
        int start_byte = CHAR_TO_BYTE (start);
+       int tem;
 
         /* If we're looking for a newline, consult the newline cache
            to see where we can avoid some scanning.  */
@@ -593,7 +584,8 @@ scan_buffer (target, start, end, count, shortage, allow_quit)
            bytes. BUFFER_CEILING_OF returns the last character
            position that is contiguous, so the ceiling is the
            position after that.  */
-        ceiling_byte = min (BUFFER_CEILING_OF (start_byte), ceiling_byte);
+       tem = BUFFER_CEILING_OF (start_byte);
+       ceiling_byte = min (tem, ceiling_byte);
 
         {
           /* The termination address of the dumb loop.  */ 
@@ -639,6 +631,7 @@ scan_buffer (target, start, end, count, shortage, allow_quit)
         /* The last character to check before the next obstacle.  */
        int ceiling_byte = CHAR_TO_BYTE (end);
        int start_byte = CHAR_TO_BYTE (start);
+       int tem;
 
         /* Consult the newline cache, if appropriate.  */
         if (target == '\n' && newline_cache)
@@ -660,7 +653,8 @@ scan_buffer (target, start, end, count, shortage, allow_quit)
           }
 
         /* Stop scanning before the gap.  */
-        ceiling_byte = max (BUFFER_FLOOR_OF (start_byte - 1), ceiling_byte);
+       tem = BUFFER_FLOOR_OF (start_byte - 1);
+       ceiling_byte = max (tem, ceiling_byte);
 
         {
           /* The termination address of the dumb loop.  */
@@ -786,7 +780,6 @@ scan_newline (start, start_byte, limit, limit_byte, count, allow_quit)
     }
   else
     {
-      int start_byte = CHAR_TO_BYTE (start);
       while (start_byte > limit_byte)
        {
          ceiling = BUFFER_FLOOR_OF (start_byte - 1);
@@ -931,7 +924,7 @@ static int
 trivial_regexp_p (regexp)
      Lisp_Object regexp;
 {
-  int len = XSTRING (regexp)->size_byte;
+  int len = STRING_BYTES (XSTRING (regexp));
   unsigned char *s = XSTRING (regexp)->data;
   unsigned char c;
   while (--len >= 0)
@@ -1005,7 +998,7 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n,
      int posix;
 {
   int len = XSTRING (string)->size;
-  int len_byte = XSTRING (string)->size_byte;
+  int len_byte = STRING_BYTES (XSTRING (string));
   register int i;
 
   if (running_asynch_code)
@@ -1070,6 +1063,7 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n,
            }
          if (val >= 0)
            {
+             pos_byte = search_regs.start[0] + BEGV_BYTE;
              for (i = 0; i < search_regs.num_regs; i++)
                if (search_regs.start[i] >= 0)
                  {
@@ -1102,6 +1096,7 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n,
            }
          if (val >= 0)
            {
+             pos_byte = search_regs.end[0] + BEGV_BYTE;
              for (i = 0; i < search_regs.num_regs; i++)
                if (search_regs.start[i] >= 0)
                  {
@@ -1142,7 +1137,7 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n,
        {
          raw_pattern = (char *) XSTRING (string)->data;
          raw_pattern_size = XSTRING (string)->size;
-         raw_pattern_size_byte = XSTRING (string)->size_byte;
+         raw_pattern_size_byte = STRING_BYTES (XSTRING (string));
        }
       else if (multibyte)
        {
@@ -1166,7 +1161,7 @@ search_buffer (string, pos, pos_byte, lim, lim_byte, n,
          raw_pattern_size_byte = XSTRING (string)->size;
          raw_pattern = (char *) alloca (raw_pattern_size + 1);
          copy_text (XSTRING (string)->data, raw_pattern,
-                    XSTRING (string)->size_byte, 1, 0);
+                    STRING_BYTES (XSTRING (string)), 1, 0);
        }
 
       /* Copy and optionally translate the pattern.  */
@@ -1303,6 +1298,7 @@ simple_search (n, pat, len, len_byte, trt, pos, pos_byte, lim, lim_byte)
      int lim, lim_byte;
 {
   int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
+  int forward = n > 0;
 
   if (lim > pos && multibyte)
     while (n > 0)
@@ -1321,22 +1317,23 @@ simple_search (n, pat, len, len_byte, trt, pos, pos_byte, lim, lim_byte)
            while (this_len > 0)
              {
                int charlen, buf_charlen;
-               int pat_ch = STRING_CHAR_AND_LENGTH (p, this_len_byte, charlen);
-               int buf_ch;
-
-               this_len_byte -= charlen;
-               this_len--;
-               p += charlen;
+               int pat_ch, buf_ch;
 
+               pat_ch = STRING_CHAR_AND_LENGTH (p, this_len_byte, charlen);
                buf_ch = STRING_CHAR_AND_LENGTH (BYTE_POS_ADDR (this_pos_byte),
                                                 ZV_BYTE - this_pos_byte,
                                                 buf_charlen);
-               this_pos_byte += buf_charlen;
-               this_pos++;
                TRANSLATE (buf_ch, trt, buf_ch);
 
                if (buf_ch != pat_ch)
                  break;
+
+               this_len_byte -= charlen;
+               this_len--;
+               p += charlen;
+
+               this_pos_byte += buf_charlen;
+               this_pos++;
              }
 
            if (this_len == 0)
@@ -1368,12 +1365,13 @@ simple_search (n, pat, len, len_byte, trt, pos, pos_byte, lim, lim_byte)
              {
                int pat_ch = *p++;
                int buf_ch = FETCH_BYTE (this_pos);
-               this_len--;
-               this_pos++;
                TRANSLATE (buf_ch, trt, buf_ch);
 
                if (buf_ch != pat_ch)
                  break;
+
+               this_len--;
+               this_pos++;
              }
 
            if (this_len == 0)
@@ -1406,22 +1404,22 @@ simple_search (n, pat, len, len_byte, trt, pos, pos_byte, lim, lim_byte)
            while (this_len > 0)
              {
                int charlen, buf_charlen;
-               int pat_ch = STRING_CHAR_AND_LENGTH (p, this_len_byte, charlen);
-               int buf_ch;
-
-               this_len_byte -= charlen;
-               this_len--;
-               p += charlen;
+               int pat_ch, buf_ch;
 
+               pat_ch = STRING_CHAR_AND_LENGTH (p, this_len_byte, charlen);
                buf_ch = STRING_CHAR_AND_LENGTH (BYTE_POS_ADDR (this_pos_byte),
                                                 ZV_BYTE - this_pos_byte,
                                                 buf_charlen);
-               this_pos_byte += buf_charlen;
-               this_pos++;
                TRANSLATE (buf_ch, trt, buf_ch);
 
                if (buf_ch != pat_ch)
                  break;
+
+               this_len_byte -= charlen;
+               this_len--;
+               p += charlen;
+               this_pos_byte += buf_charlen;
+               this_pos++;
              }
 
            if (this_len == 0)
@@ -1453,12 +1451,12 @@ simple_search (n, pat, len, len_byte, trt, pos, pos_byte, lim, lim_byte)
              {
                int pat_ch = *p++;
                int buf_ch = FETCH_BYTE (this_pos);
-               this_len--;
-               this_pos++;
                TRANSLATE (buf_ch, trt, buf_ch);
 
                if (buf_ch != pat_ch)
                  break;
+               this_len--;
+               this_pos++;
              }
 
            if (this_len == 0)
@@ -1476,7 +1474,10 @@ simple_search (n, pat, len, len_byte, trt, pos, pos_byte, lim, lim_byte)
  stop:
   if (n == 0)
     {
-      set_search_regs (multibyte ? pos_byte : pos, len_byte);
+      if (forward)
+       set_search_regs ((multibyte ? pos_byte : pos) - len_byte, len_byte);
+      else
+       set_search_regs (multibyte ? pos_byte : pos, len_byte);
 
       return pos;
     }
@@ -1604,9 +1605,9 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt,
              while (! CHAR_HEAD_P (*charstart))
                charstart--;
              untranslated = STRING_CHAR (charstart, ptr - charstart + 1);
-             TRANSLATE (ch, trt, untranslated);
-             if (charset_base == (ch & ~0xff))
+             if (charset_base == (untranslated & ~0xff))
                {
+                 TRANSLATE (ch, trt, untranslated);
                  if (! CHAR_HEAD_P (*ptr))
                    {
                      translate_prev_byte = ptr[-1];
@@ -1615,7 +1616,10 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt,
                    }
                }
              else
-               this_translated = 0;
+               {
+                 this_translated = 0;
+                 ch = *ptr;
+               }
            }
          else if (!multibyte)
            TRANSLATE (ch, trt, *ptr);
@@ -1625,23 +1629,38 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt,
              this_translated = 0;
            }
 
-         k = j = (unsigned char) ch;
+         if (ch > 0400)
+           j = ((unsigned char) ch) | 0200;
+         else
+           j = (unsigned char) ch;
+
          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 */ 
          if (this_translated)
-           while (1)
-             {
-               TRANSLATE (ch, inverse_trt, ch);
-               /* For all the characters that map into K,
-                  set up simple_translate to map them into K.  */
-               simple_translate[(unsigned char) ch] = k;
-               if ((unsigned char) ch == k)
-                 break;
-               BM_tab[(unsigned char) ch] = dirlen - i;
-             }
+           {
+             int starting_ch = ch;
+             int starting_j = j;
+             while (1)
+               {
+                 TRANSLATE (ch, inverse_trt, ch);
+                 if (ch > 0400)
+                   j = ((unsigned char) ch) | 0200;
+                 else
+                   j = (unsigned char) ch;
+
+                 /* For all the characters that map into CH,
+                    set up simple_translate to map the last byte
+                    into STARTING_J.  */
+                 simple_translate[j] = starting_j;
+                 if (ch == starting_ch)
+                   break;
+                 BM_tab[j] = dirlen - i;
+               }
+           }
        }
       else
        {
@@ -1676,14 +1695,22 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt,
       QUIT;
       pat = base_pat;
       limit = pos_byte - dirlen + direction;
-      limit = ((direction > 0)
-              ? BUFFER_CEILING_OF (limit)
-              : BUFFER_FLOOR_OF (limit));
-      /* LIMIT is now the last (not beyond-last!) value POS_BYTE
-        can take on without hitting edge of buffer or the gap.  */
-      limit = ((direction > 0)
-              ? min (lim_byte - 1, min (limit, pos_byte + 20000))
-              : max (lim_byte, max (limit, pos_byte - 20000)));
+      if (direction > 0)
+       {
+         limit = BUFFER_CEILING_OF (limit);
+         /* LIMIT is now the last (not beyond-last!) value POS_BYTE
+            can take on without hitting edge of buffer or the gap.  */
+         limit = min (limit, pos_byte + 20000);
+         limit = min (limit, lim_byte - 1);
+       }
+      else
+       {
+         limit = BUFFER_FLOOR_OF (limit);
+         /* LIMIT is now the last (not beyond-last!) value POS_BYTE
+            can take on without hitting edge of buffer or the gap.  */
+         limit = max (limit, pos_byte - 20000);
+         limit = max (limit, lim_byte);
+       }
       tail_end = BUFFER_CEILING_OF (pos_byte) + 1;
       tail_end_ptr = BYTE_POS_ADDR (tail_end);
 
@@ -1926,13 +1953,13 @@ wordify (string)
 
   adjust = - punct_count + 5 * (word_count - 1) + 4;
   val = make_uninit_multibyte_string (len + adjust,
-                                     XSTRING (string)->size_byte + adjust);
+                                     STRING_BYTES (XSTRING (string)) + adjust);
 
   o = XSTRING (val)->data;
   *o++ = '\\';
   *o++ = 'b';
 
-  for (i = 0; i < XSTRING (val)->size_byte; i++)
+  for (i = 0; i < STRING_BYTES (XSTRING (val)); i++)
     if (SYNTAX (p[i]) == Sword)
       *o++ = p[i];
     else if (i > 0 && SYNTAX (p[i-1]) == Sword && --word_count)
@@ -2258,7 +2285,7 @@ since only regular expressions have distinguished subexpressions.")
 
          accum = Qnil;
 
-         for (pos_byte = 0, pos = 0; pos_byte < XSTRING (newtext)->size_byte;)
+         for (pos_byte = 0, pos = 0; pos_byte < STRING_BYTES (XSTRING (newtext));)
            {
              int substart = -1;
              int subend;
@@ -2532,7 +2559,7 @@ to hold all the values, and if INTEGERS is non-nil, no consing is done.")
 }
 
 
-DEFUN ("store-match-data", Fstore_match_data, Sstore_match_data, 1, 1, 0,
+DEFUN ("set-match-data", Fset_match_data, Sset_match_data, 1, 1, 0,
   "Set internal data on last search match from elements of LIST.\n\
 LIST should have been created by calling `match-data' previously.")
   (list)
@@ -2668,12 +2695,12 @@ DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0,
 
   CHECK_STRING (string, 0);
 
-  temp = (unsigned char *) alloca (XSTRING (string)->size_byte * 2);
+  temp = (unsigned char *) alloca (STRING_BYTES (XSTRING (string)) * 2);
 
   /* Now copy the data into the new string, inserting escapes. */
 
   in = XSTRING (string)->data;
-  end = in + XSTRING (string)->size_byte;
+  end = in + STRING_BYTES (XSTRING (string));
   out = temp; 
 
   for (; in != end; in++)
@@ -2686,11 +2713,13 @@ DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0,
       *out++ = *in;
     }
 
-  return make_multibyte_string (temp,
+  return make_specified_string (temp,
                                XSTRING (string)->size + backslashes_added,
-                               out - temp);
+                               out - temp,
+                               STRING_MULTIBYTE (string));
 }
 \f  
+void
 syms_of_search ()
 {
   register int i;
@@ -2740,6 +2769,6 @@ syms_of_search ()
   defsubr (&Smatch_beginning);
   defsubr (&Smatch_end);
   defsubr (&Smatch_data);
-  defsubr (&Sstore_match_data);
+  defsubr (&Sset_match_data);
   defsubr (&Sregexp_quote);
 }