1 /* kwsearch.c - searching subroutines using kwset for grep.
2 Copyright 1992, 1998, 2000, 2007, 2009-2014 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
19 /* Written August 1992 by Mike Haertel. */
24 /* Whether -w considers WC to be a word constituent. */
28 return wc
== L
'_' || iswalnum (wc
);
31 /* KWset compiled pattern. For Ecompile and Gcompile, we compile
32 a list of strings, at least one of which is known to occur in
33 any string matching the regexp. */
37 Fcompile (char const *pattern
, size_t size
)
40 mb_len_map_t
*map
= NULL
;
41 char const *pat
= (match_icase
&& MB_CUR_MAX
> 1
42 ? mbtoupper (pattern
, &total
, &map
)
51 char const *sep
= memchr (p
, '\n', total
);
67 buf
= xmalloc (len
+ 2);
69 memcpy (buf
+ 1, p
, len
);
70 buf
[len
+ 1] = eolbyte
;
74 kwsincr (kwset
, p
, len
);
84 /* Apply the MAP (created by mbtoupper) to the uppercase-buffer-relative
85 *OFF and *LEN, converting them to be relative to the original buffer. */
88 mb_case_map_apply (mb_len_map_t
const *map
, size_t *off
, size_t *len
)
95 for (k
= 0; k
< *off
; k
++)
97 for (; k
< *off
+ *len
; k
++)
105 Fexecute (char const *buf
, size_t size
, size_t *match_size
,
106 char const *start_ptr
)
108 char const *beg
, *try, *end
, *mb_start
;
111 struct kwsmatch kwsmatch
;
113 mb_len_map_t
*map
= NULL
;
119 char *case_buf
= mbtoupper (buf
, &size
, &map
);
121 start_ptr
= case_buf
+ (start_ptr
- buf
);
126 for (mb_start
= beg
= start_ptr
? start_ptr
: buf
; beg
<= buf
+ size
; beg
++)
128 size_t offset
= kwsexec (kwset
, beg
- match_lines
,
129 buf
+ size
- beg
+ match_lines
, &kwsmatch
);
130 if (offset
== (size_t) -1)
132 len
= kwsmatch
.size
[0] - match_lines
;
133 if (!match_lines
&& MB_CUR_MAX
> 1 && !using_utf8 ()
134 && mb_goback (&mb_start
, beg
+ offset
, buf
+ size
) != 0)
136 /* The match was a part of multibyte character, advance at least
137 one byte to ensure no infinite loop happens. */
142 if (start_ptr
&& !match_words
)
143 goto success_in_beg_and_len
;
145 goto success_in_beg_and_len
;
149 if (wordchar (mb_prev_wc (buf
, try, buf
+ size
)))
151 if (wordchar (mb_next_wc (try + len
, buf
+ size
)))
155 offset
= kwsexec (kwset
, beg
, --len
, &kwsmatch
);
156 if (offset
== (size_t) -1)
159 len
= kwsmatch
.size
[0];
164 goto success_in_beg_and_len
;
168 } /* for (beg in buf) */
174 if ((end
= memchr (beg
+ len
, eol
, (buf
+ size
) - (beg
+ len
))) != NULL
)
178 while (buf
< beg
&& beg
[-1] != eol
)
181 success_in_beg_and_len
:;
182 size_t off
= beg
- buf
;
183 mb_case_map_apply (map
, &off
, &len
);