]> code.delx.au - gnu-emacs/blobdiff - src/search.c
* window.c (Fwindow_live_p): Use WINDOW_LIVE_P.
[gnu-emacs] / src / search.c
index 31c9398c761c2ef5a8dd2c2a3e07705c0b900420..99da344c1baaf143dc3826dfeb63caca45da707f 100644 (file)
@@ -97,12 +97,6 @@ matcher_overflow ()
   error ("Stack overflow in regexp matcher");
 }
 
-#ifdef __STDC__
-#define CONST const
-#else
-#define CONST
-#endif
-
 /* Compile a regexp and signal a Lisp error if anything goes wrong.
    PATTERN is the pattern to compile.
    CP is the place to put the result.
@@ -186,7 +180,7 @@ compile_pattern_1 (cp, pattern, translate, regp, posix, multibyte)
 void
 shrink_regexp_cache ()
 {
-  struct regexp_cache *cp, **cpp;
+  struct regexp_cache *cp;
 
   for (cp = searchbuf_head; cp != 0; cp = cp->next)
     {
@@ -224,9 +218,10 @@ compile_pattern (pattern, regp, translate, posix, multibyte)
         XSTRING in those cases.  However, compile_pattern_1 is only
         applied to the cache entry we pick here to reuse.  So nil
         should never appear before a non-nil entry.  */
-      if (cp->regexp == Qnil)
+      if (NILP (cp->regexp))
        goto compile_it;
       if (XSTRING (cp->regexp)->size == XSTRING (pattern)->size
+         && STRING_MULTIBYTE (cp->regexp) == STRING_MULTIBYTE (pattern)
          && !NILP (Fstring_equal (cp->regexp, pattern))
          && EQ (cp->buf.translate, (! NILP (translate) ? translate : make_number (0)))
          && cp->posix == posix
@@ -954,7 +949,6 @@ trivial_regexp_p (regexp)
 {
   int len = STRING_BYTES (XSTRING (regexp));
   unsigned char *s = XSTRING (regexp)->data;
-  unsigned char c;
   while (--len >= 0)
     {
       switch (*s++)
@@ -1532,7 +1526,7 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt,
 {
   int direction = ((n > 0) ? 1 : -1);
   register int dirlen;
-  int infinity, limit, k, stride_for_teases;
+  int infinity, limit, stride_for_teases = 0;
   register int *BM_tab;
   int *BM_tab_base;
   register unsigned char *cursor, *p_limit;  
@@ -1541,8 +1535,8 @@ boyer_moore (n, base_pat, len, len_byte, trt, inverse_trt,
   int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
 
   unsigned char simple_translate[0400];
-  int translate_prev_byte;
-  int translate_anteprev_byte;
+  int translate_prev_byte = 0;
+  int translate_anteprev_byte = 0;
 
 #ifdef C_ALLOCA
   int BM_tab_space[0400];
@@ -1965,10 +1959,7 @@ wordify (string)
     {
       int c;
       
-      if (STRING_MULTIBYTE (string))
-       FETCH_STRING_CHAR_ADVANCE (c, string, i, i_byte);
-      else
-       c = XSTRING (string)->data[i++];
+      FETCH_STRING_CHAR_ADVANCE (c, string, i, i_byte);
 
       if (SYNTAX (c) != Sword)
        {
@@ -2003,13 +1994,7 @@ wordify (string)
       int c;
       int i_byte_orig = i_byte;
       
-      if (STRING_MULTIBYTE (string))
-       FETCH_STRING_CHAR_ADVANCE (c, string, i, i_byte);
-      else
-       {
-         c = XSTRING (string)->data[i++];
-         i_byte++;
-       }
+      FETCH_STRING_CHAR_ADVANCE (c, string, i, i_byte);
 
       if (SYNTAX (c) == Sword)
        {
@@ -2044,6 +2029,10 @@ The match found must not extend before that position.\n\
 Optional third argument, if t, means if fail just return nil (no error).\n\
  If not nil and not t, position at limit of search and return nil.\n\
 Optional fourth argument is repeat count--search for successive occurrences.\n\
+\n\
+Search case-sensitivity is determined by the value of the variable\n\
+`case-fold-search', which see.\n\
+\n\
 See also the functions `match-beginning', `match-end' and `replace-match'.")
   (string, bound, noerror, count)
      Lisp_Object string, bound, noerror, count;
@@ -2060,6 +2049,10 @@ The match found must not extend after that position.  nil is equivalent\n\
 Optional third argument, if t, means if fail just return nil (no error).\n\
   If not nil and not t, move to limit of search and return nil.\n\
 Optional fourth argument is repeat count--search for successive occurrences.\n\
+\n\
+Search case-sensitivity is determined by the value of the variable\n\
+`case-fold-search', which see.\n\
+\n\
 See also the functions `match-beginning', `match-end' and `replace-match'.")
   (string, bound, noerror, count)
      Lisp_Object string, bound, noerror, count;
@@ -2108,7 +2101,8 @@ The match found must start at or after that position.\n\
 Optional third argument, if t, means if fail just return nil (no error).\n\
   If not nil and not t, move to limit of search and return nil.\n\
 Optional fourth argument is repeat count--search for successive occurrences.\n\
-See also the functions `match-beginning', `match-end' and `replace-match'.")
+See also the functions `match-beginning', `match-end', `match-string',\n\
+and `replace-match'.")
   (regexp, bound, noerror, count)
      Lisp_Object regexp, bound, noerror, count;
 {
@@ -2124,7 +2118,8 @@ The match found must not extend after that position.\n\
 Optional third argument, if t, means if fail just return nil (no error).\n\
   If not nil and not t, move to limit of search and return nil.\n\
 Optional fourth argument is repeat count--search for successive occurrences.\n\
-See also the functions `match-beginning', `match-end' and `replace-match'.")
+See also the functions `match-beginning', `match-end', `match-string',\n\
+and `replace-match'.")
   (regexp, bound, noerror, count)
      Lisp_Object regexp, bound, noerror, count;
 {
@@ -2143,7 +2138,8 @@ The match found must start at or after that position.\n\
 Optional third argument, if t, means if fail just return nil (no error).\n\
   If not nil and not t, move to limit of search and return nil.\n\
 Optional fourth argument is repeat count--search for successive occurrences.\n\
-See also the functions `match-beginning', `match-end' and `replace-match'.")
+See also the functions `match-beginning', `match-end', `match-string',\n\
+and `replace-match'.")
   (regexp, bound, noerror, count)
      Lisp_Object regexp, bound, noerror, count;
 {
@@ -2160,7 +2156,8 @@ The match found must not extend after that position.\n\
 Optional third argument, if t, means if fail just return nil (no error).\n\
   If not nil and not t, move to limit of search and return nil.\n\
 Optional fourth argument is repeat count--search for successive occurrences.\n\
-See also the functions `match-beginning', `match-end' and `replace-match'.")
+See also the functions `match-beginning', `match-end', `match-string',\n\
+and `replace-match'.")
   (regexp, bound, noerror, count)
      Lisp_Object regexp, bound, noerror, count;
 {
@@ -2347,7 +2344,7 @@ since only regular expressions have distinguished subexpressions.")
          for (pos_byte = 0, pos = 0; pos_byte < length;)
            {
              int substart = -1;
-             int subend;
+             int subend = 0;
              int delbackslash = 0;
 
              FETCH_STRING_CHAR_ADVANCE (c, newtext, pos, pos_byte);
@@ -2355,6 +2352,7 @@ since only regular expressions have distinguished subexpressions.")
              if (c == '\\')
                {
                  FETCH_STRING_CHAR_ADVANCE (c, newtext, pos, pos_byte);
+                     
                  if (c == '&')
                    {
                      substart = search_regs.start[sub];
@@ -2440,21 +2438,43 @@ since only regular expressions have distinguished subexpressions.")
       int length = STRING_BYTES (XSTRING (newtext));
       unsigned char *substed;
       int substed_alloc_size, substed_len;
+      int buf_multibyte = !NILP (current_buffer->enable_multibyte_characters);
+      int str_multibyte = STRING_MULTIBYTE (newtext);
+      Lisp_Object rev_tbl;
+
+      rev_tbl= (!buf_multibyte && CHAR_TABLE_P (Vnonascii_translation_table)
+               ? Fchar_table_extra_slot (Vnonascii_translation_table,
+                                         make_number (0))
+               : Qnil);
 
       substed_alloc_size = length * 2 + 100;
       substed = (unsigned char *) xmalloc (substed_alloc_size + 1);
       substed_len = 0;
 
-      /* Go thru NEWTEXT, producing the actual text to insert in SUBSTED.  */
+      /* Go thru NEWTEXT, producing the actual text to insert in
+        SUBSTED while adjusting multibyteness to that of the current
+        buffer.  */
 
       for (pos_byte = 0, pos = 0; pos_byte < length;)
        {
          unsigned char str[MAX_MULTIBYTE_LENGTH];
-         unsigned char *add_stuff;
-         int add_len;
+         unsigned char *add_stuff = NULL;
+         int add_len = 0;
          int idx = -1;
 
-         FETCH_STRING_CHAR_ADVANCE (c, newtext, pos, pos_byte);
+         if (str_multibyte)
+           {
+             FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, newtext, pos, pos_byte);
+             if (!buf_multibyte)
+               c = multibyte_char_to_unibyte (c, rev_tbl);
+           }
+         else
+           {
+             /* Note that we don't have to increment POS.  */
+             c = XSTRING (newtext)->data[pos_byte++];
+             if (buf_multibyte)
+               c = unibyte_char_to_multibyte (c);
+           }
 
          /* Either set ADD_STUFF and ADD_LEN to the text to put in SUBSTED,
             or set IDX to a match index, which means put that part
@@ -2462,7 +2482,20 @@ since only regular expressions have distinguished subexpressions.")
 
          if (c == '\\')
            {
-             FETCH_STRING_CHAR_ADVANCE (c, newtext, pos, pos_byte);
+             if (str_multibyte)
+               {
+                 FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, newtext,
+                                                     pos, pos_byte);
+                 if (!buf_multibyte && !SINGLE_BYTE_CHAR_P (c))
+                   c = multibyte_char_to_unibyte (c, rev_tbl);
+               }
+             else
+               {
+                 c = XSTRING (newtext)->data[pos_byte++];
+                 if (buf_multibyte)
+                   c = unibyte_char_to_multibyte (c);
+               }
+
              if (c == '&')
                idx = sub;
              else if (c >= '1' && c <= '9' && c <= search_regs.num_regs + '0')
@@ -2473,7 +2506,10 @@ since only regular expressions have distinguished subexpressions.")
              else if (c == '\\')
                add_len = 1, add_stuff = "\\";
              else
-               error ("Invalid use of `\\' in replacement text");
+               {
+                 xfree (substed);
+                 error ("Invalid use of `\\' in replacement text");
+               }
            }
          else
            {
@@ -2504,8 +2540,11 @@ since only regular expressions have distinguished subexpressions.")
            }
 
          /* Now add to the end of SUBSTED.  */
-         bcopy (add_stuff, substed + substed_len, add_len);
-         substed_len += add_len;
+         if (add_stuff)
+           {
+             bcopy (add_stuff, substed + substed_len, add_len);
+             substed_len += add_len;
+           }
        }
 
       /* Now insert what we accumulated.  */
@@ -2601,6 +2640,8 @@ to hold all the values, and if INTEGERS is non-nil, no consing is done.")
   if (NILP (last_thing_searched))
     return Qnil;
 
+  prev = Qnil;
+
   data = (Lisp_Object *) alloca ((2 * search_regs.num_regs)
                                 * sizeof (Lisp_Object));
 
@@ -2704,6 +2745,9 @@ LIST should have been created by calling `match-data' previously.")
                                       length * sizeof (regoff_t));
          }
 
+       for (i = search_regs.num_regs; i < length; i++)
+         search_regs.start[i] = -1;
+
        search_regs.num_regs = length;
       }
   }
@@ -2718,6 +2762,8 @@ LIST should have been created by calling `match-data' previously.")
        }
       else
        {
+         int from;
+
          if (MARKERP (marker))
            {
              if (XMARKER (marker)->buffer == 0)
@@ -2727,7 +2773,7 @@ LIST should have been created by calling `match-data' previously.")
            }
 
          CHECK_NUMBER_COERCE_MARKER (marker, 0);
-         search_regs.start[i] = XINT (marker);
+         from = XINT (marker);
          list = Fcdr (list);
 
          marker = Fcar (list);
@@ -2735,6 +2781,7 @@ LIST should have been created by calling `match-data' previously.")
            XSETFASTINT (marker, 0);
 
          CHECK_NUMBER_COERCE_MARKER (marker, 0);
+         search_regs.start[i] = from;
          search_regs.end[i] = XINT (marker);
        }
       list = Fcdr (list);