(U+6215): Apply new conventions for glyph granularity.
[chise/xemacs-chise.git.1] / src / search.c
index 6ae5f9d..7ca50a6 100644 (file)
@@ -1,6 +1,7 @@
 /* String search routines for XEmacs.
    Copyright (C) 1985, 1986, 1987, 1992-1995 Free Software Foundation, Inc.
    Copyright (C) 1995 Sun Microsystems, Inc.
+   Copyright (C) 1999,2000,2001 MORIOKA Tomohiko
 
 This file is part of XEmacs.
 
@@ -108,6 +109,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);
+static void clear_unused_search_regs (struct re_registers *regp, int no_sub);
 static void save_search_regs (void);
 static Bufpos simple_search (struct buffer *buf, Bufbyte *base_pat,
                             Bytecount len, Bytind pos, Bytind lim,
@@ -772,6 +774,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)
@@ -785,8 +788,12 @@ skip_chars (struct buffer *buf, int forwardp, int syntaxp,
   int negate = 0;
   REGISTER int i;
 #ifndef emacs
+#ifdef UTF2000
+  Lisp_Char_Table *syntax_table = XCHAR_TABLE (buf->syntax_table);
+#else
   Lisp_Char_Table *syntax_table = XCHAR_TABLE (buf->mirror_syntax_table);
 #endif
+#endif
   Bufpos limit;
 
   if (NILP (lim))
@@ -842,6 +849,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);
@@ -866,6 +874,7 @@ skip_chars (struct buffer *buf, int forwardp, int syntaxp,
        }
     }
 
+  /* #### Not in FSF 21.1 */
   if (syntaxp && fastmap['-'] != 0)
     fastmap[' '] = 1;
 
@@ -879,36 +888,48 @@ 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, BUF_PT (buf), forwardp ? 1 : -1);
+       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_FROM_CACHE (syntax_table,
-                                                       BUF_FETCH_CHAR
-                                                       (buf, BUF_PT (buf)))]])
-             {
-               BUF_SET_PT (buf, BUF_PT (buf) + 1);
-               UPDATE_SYNTAX_CACHE_FORWARD (BUF_PT (buf));
-             }
+           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_FROM_CACHE (syntax_table,
-                                                       BUF_FETCH_CHAR
-                                                       (buf, BUF_PT (buf) - 1))]])
+           while (pos > limit)
              {
-               BUF_SET_PT (buf, BUF_PT (buf) - 1);
-               UPDATE_SYNTAX_CACHE_BACKWARD (BUF_PT (buf) - 1);
+               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;
+                 }
              }
          }
       }
@@ -916,36 +937,47 @@ skip_chars (struct buffer *buf, int forwardp, int syntaxp,
       {
        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);
   }
 }
@@ -1057,7 +1089,7 @@ search_command (Lisp_Object string, Lisp_Object limit, Lisp_Object noerror,
       if (!EQ (noerror, Qt))
        {
          if (lim < BUF_BEGV (buf) || lim > BUF_ZV (buf))
-           abort ();
+           ABORT ();
          BUF_SET_PT (buf, lim);
          return Qnil;
 #if 0 /* This would be clean, but maybe programs depend on
@@ -1070,7 +1102,7 @@ search_command (Lisp_Object string, Lisp_Object limit, Lisp_Object noerror,
     }
 
   if (np < BUF_BEGV (buf) || np > BUF_ZV (buf))
-    abort ();
+    ABORT ();
 
   BUF_SET_PT (buf, np);
 
@@ -1087,6 +1119,7 @@ trivial_regexp_p (Lisp_Object regexp)
     {
       switch (*s++)
        {
+       /* ']' doesn't appear here because it's only special after ] */
        case '.': case '*': case '+': case '?': case '[': case '^': case '$':
          return 0;
        case '\\':
@@ -1096,7 +1129,7 @@ trivial_regexp_p (Lisp_Object regexp)
            {
            case '|': case '(': case ')': case '`': case '\'': case 'b':
            case 'B': case '<': case '>': case 'w': case 'W': case 's':
-           case 'S': case '=':
+           case 'S': case '=': case '{': case '}':
 #ifdef MULE
            /* 97/2/25 jhod Added for category matches */
            case 'c': case 'C':
@@ -1146,10 +1179,11 @@ search_buffer (struct buffer *buf, Lisp_Object string, Bufpos bufpos,
   if (len == 0)
     {
       set_search_regs (buf, bufpos, 0);
+      clear_unused_search_regs (&search_regs, 0);
       return bufpos;
     }
 
-  /* Searching 0 times means don't move.  */
+  /* Searching 0 times means noop---don't move, don't touch registers.  */
   if (n == 0)
     return bufpos;
 
@@ -1196,6 +1230,8 @@ search_buffer (struct buffer *buf, Lisp_Object string, Bufpos bufpos,
                    search_regs.start[i] += j;
                    search_regs.end[i] += j;
                  }
+             /* re_match (called from re_search et al) does this for us */
+             /* clear_unused_search_regs (search_regs, bufp->no_sub);   */
              XSETBUFFER (last_thing_searched, buf);
              /* Set pos to the new position. */
              pos = search_regs.start[0];
@@ -1233,6 +1269,8 @@ search_buffer (struct buffer *buf, Lisp_Object string, Bufpos bufpos,
                    search_regs.start[i] += j;
                    search_regs.end[i] += j;
                  }
+             /* re_match (called from re_search et al) does this for us */
+             /* clear_unused_search_regs (search_regs, bufp->no_sub);   */
              XSETBUFFER (last_thing_searched, buf);
              /* Set pos to the new position. */
              pos = search_regs.end[0];
@@ -1285,7 +1323,11 @@ search_buffer (struct buffer *buf, Lisp_Object string, Bufpos bufpos,
            {
              /* Keep track of which character set row
                 contains the characters that need translation.  */
+#ifdef UTF2000
+             int charset_base_code = c >> 6;
+#else
              int charset_base_code = c & ~CHAR_FIELD3_MASK;
+#endif
              if (charset_base == -1)
                charset_base = charset_base_code;
              else if (charset_base != charset_base_code)
@@ -1433,6 +1475,7 @@ simple_search (struct buffer *buf, Bufbyte *base_pat, Bytecount len_byte,
          end = bytind_to_bufpos (buf, idx + buf_len);
        }
       set_search_regs (buf, beg, end - beg);
+      clear_unused_search_regs (&search_regs, 0);
 
       return retval;
     }
@@ -1584,7 +1627,11 @@ boyer_moore (struct buffer *buf, Bufbyte *base_pat, Bytecount len,
              while (!BUFBYTE_FIRST_BYTE_P (*charstart))
                charstart--;
              untranslated = charptr_emchar (charstart);
+#ifdef UTF2000
+             if (charset_base == (untranslated >> 6))
+#else
              if (charset_base == (untranslated & ~CHAR_FIELD3_MASK))
+#endif
                {
                  ch = TRANSLATE (trt, untranslated);
                  if (!BUFBYTE_FIRST_BYTE_P (*ptr))
@@ -1794,6 +1841,7 @@ boyer_moore (struct buffer *buf, Bufbyte *base_pat, Bytecount len,
                    Bufpos bufend = bytind_to_bufpos (buf, bytstart + len);
 
                    set_search_regs (buf, bufstart, bufend - bufstart);
+                   clear_unused_search_regs (&search_regs, 0);
                  }
 
                  if ((n -= direction) != 0)
@@ -1883,6 +1931,7 @@ boyer_moore (struct buffer *buf, Bufbyte *base_pat, Bytecount len,
                    Bufpos bufend = bytind_to_bufpos (buf, bytstart + len);
 
                    set_search_regs (buf, bufstart, bufend - bufstart);
+                   clear_unused_search_regs (&search_regs, 0);
                  }
 
                  if ((n -= direction) != 0)
@@ -1902,8 +1951,8 @@ boyer_moore (struct buffer *buf, Bufbyte *base_pat, Bytecount len,
   return bytind_to_bufpos (buf, pos);
 }
 
-/* Record beginning BEG and end BEG + LEN
-   for a match just found in the current buffer.  */
+/* Record the whole-match data (beginning BEG and end BEG + LEN) and the
+   buffer for a match just found.  */
 
 static void
 set_search_regs (struct buffer *buf, Bufpos beg, Charcount len)
@@ -1923,6 +1972,24 @@ set_search_regs (struct buffer *buf, Bufpos beg, Charcount len)
   XSETBUFFER (last_thing_searched, buf);
 }
 
+/* Clear unused search registers so match data will be null.
+   REGP is a pointer to the register structure to clear, usually the global
+   search_regs.
+   NO_SUB is the number of subexpressions to allow for.  (Does not count
+   the whole match, ie, for a string search NO_SUB == 0.)
+   It is an error if NO_SUB > REGP.num_regs - 1. */
+
+static void
+clear_unused_search_regs (struct re_registers *regp, int no_sub)
+{
+  /* This function has been Mule-ized. */
+  int i;
+
+  assert (no_sub >= 0 && no_sub < regp->num_regs);
+  for (i = no_sub + 1; i < regp->num_regs; i++)
+    regp->start[i] = regp->end[i] = -1;
+}
+
 \f
 /* Given a string of words separated by word delimiters,
    compute a regexp that matches those exact words
@@ -1934,7 +2001,11 @@ wordify (Lisp_Object buffer, Lisp_Object string)
   Charcount i, len;
   EMACS_INT punct_count = 0, word_count = 0;
   struct buffer *buf = decode_buffer (buffer, 0);
+#ifdef UTF2000
+  Lisp_Char_Table *syntax_table = XCHAR_TABLE (buf->syntax_table);
+#else
   Lisp_Char_Table *syntax_table = XCHAR_TABLE (buf->mirror_syntax_table);
+#endif
 
   CHECK_STRING (string);
   len = XSTRING_CHAR_LENGTH (string);
@@ -2303,7 +2374,11 @@ match since only regular expressions have distinguished subexpressions.
       buf = XBUFFER (buffer);
     }
 
+#ifdef UTF2000
+  syntax_table = XCHAR_TABLE (buf->syntax_table);
+#else
   syntax_table = XCHAR_TABLE (buf->mirror_syntax_table);
+#endif
 
   case_action = nochange;      /* We tried an initialization */
                                /* but some C compilers blew it */
@@ -2702,9 +2777,9 @@ match_limit (Lisp_Object num, int beginningp)
 
   CHECK_INT (num);
   n = XINT (num);
-  if (n < 0 || n >= search_regs.num_regs)
+  if (n < 0 || search_regs.num_regs <= 0)
     args_out_of_range (num, make_int (search_regs.num_regs));
-  if (search_regs.num_regs == 0 ||
+  if (n >= search_regs.num_regs ||
       search_regs.start[n] < 0)
     return Qnil;
   return make_int (beginningp ? search_regs.start[n] : search_regs.end[n]);
@@ -2783,7 +2858,7 @@ to hold all the values, and if INTEGERS is non-nil, no consing is done.
            }
          else
            /* last_thing_searched must always be Qt, a buffer, or Qnil.  */
-           abort ();
+           ABORT ();
 
          len = i;
        }