VirtualBox

source: kBuild/vendor/grep/2.12/src/kwsearch.c@ 2595

Last change on this file since 2595 was 2595, checked in by bird, 12 years ago

gnu grep version 2.12 (grep-2.12.tar.xz, md5sum=8d2f0346d08b13c18afb81f0e8aa1e2f)

  • Property svn:eol-style set to native
File size: 4.7 KB
Line 
1/* kwsearch.c - searching subroutines using kwset for grep.
2 Copyright 1992, 1998, 2000, 2007, 2009-2012 Free Software Foundation, Inc.
3
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)
7 any later version.
8
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.
13
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
17 02110-1301, USA. */
18
19/* Written August 1992 by Mike Haertel. */
20
21#include <config.h>
22#include "search.h"
23
24/* For -w, we also consider _ to be word constituent. */
25#define WCHAR(C) (isalnum (C) || (C) == '_')
26
27/* KWset compiled pattern. For Ecompile and Gcompile, we compile
28 a list of strings, at least one of which is known to occur in
29 any string matching the regexp. */
30static kwset_t kwset;
31
32void
33Fcompile (char const *pattern, size_t size)
34{
35 char const *err;
36 size_t psize = size;
37 char const *pat = (match_icase && MB_CUR_MAX > 1
38 ? mbtolower (pattern, &psize)
39 : pattern);
40
41 kwsinit (&kwset);
42
43 char const *beg = pat;
44 do
45 {
46 char const *lim;
47 char const *end;
48 for (lim = beg;; ++lim)
49 {
50 end = lim;
51 if (lim >= pat + psize)
52 break;
53 if (*lim == '\n')
54 {
55 lim++;
56 break;
57 }
58#if HAVE_DOS_FILE_CONTENTS
59 if (*lim == '\r' && lim + 1 < pat + psize && lim[1] == '\n')
60 {
61 lim += 2;
62 break;
63 }
64#endif
65 }
66
67 if ((err = kwsincr (kwset, beg, end - beg)) != NULL)
68 error (EXIT_TROUBLE, 0, "%s", err);
69 beg = lim;
70 }
71 while (beg < pat + psize);
72
73 if ((err = kwsprep (kwset)) != NULL)
74 error (EXIT_TROUBLE, 0, "%s", err);
75}
76
77size_t
78Fexecute (char const *buf, size_t size, size_t *match_size,
79 char const *start_ptr)
80{
81 char const *beg, *try, *end, *mb_start;
82 size_t len;
83 char eol = eolbyte;
84 struct kwsmatch kwsmatch;
85 size_t ret_val;
86 if (MB_CUR_MAX > 1)
87 {
88 if (match_icase)
89 {
90 char *case_buf = mbtolower (buf, &size);
91 if (start_ptr)
92 start_ptr = case_buf + (start_ptr - buf);
93 buf = case_buf;
94 }
95 }
96
97 for (mb_start = beg = start_ptr ? start_ptr : buf; beg <= buf + size; beg++)
98 {
99 size_t offset = kwsexec (kwset, beg, buf + size - beg, &kwsmatch);
100 if (offset == (size_t) -1)
101 goto failure;
102 len = kwsmatch.size[0];
103 if (MB_CUR_MAX > 1
104 && is_mb_middle (&mb_start, beg + offset, buf + size, len))
105 {
106 /* The match was a part of multibyte character, advance at least
107 one byte to ensure no infinite loop happens. */
108 mbstate_t s;
109 memset (&s, 0, sizeof s);
110 size_t mb_len = mbrlen (mb_start, (buf + size) - (beg + offset), &s);
111 if (mb_len == (size_t) -2)
112 goto failure;
113 beg = mb_start;
114 if (mb_len != (size_t) -1)
115 beg += mb_len - 1;
116 continue;
117 }
118 beg += offset;
119 if (start_ptr && !match_words)
120 goto success_in_beg_and_len;
121 if (match_lines)
122 {
123 if (beg > buf && beg[-1] != eol)
124 continue;
125 if (beg + len < buf + size && beg[len] != eol)
126 continue;
127 goto success;
128 }
129 else if (match_words)
130 for (try = beg; ; )
131 {
132 if (try > buf && WCHAR((unsigned char) try[-1]))
133 break;
134 if (try + len < buf + size && WCHAR((unsigned char) try[len]))
135 {
136 if (!len)
137 break;
138 offset = kwsexec (kwset, beg, --len, &kwsmatch);
139 if (offset == (size_t) -1)
140 break;
141 try = beg + offset;
142 len = kwsmatch.size[0];
143 }
144 else if (!start_ptr)
145 goto success;
146 else
147 goto success_in_beg_and_len;
148 } /* for (try) */
149 else
150 goto success;
151 } /* for (beg in buf) */
152
153 failure:
154 ret_val = -1;
155 goto out;
156
157 success:
158 if ((end = memchr (beg + len, eol, (buf + size) - (beg + len))) != NULL)
159 end++;
160 else
161 end = buf + size;
162 while (buf < beg && beg[-1] != eol)
163 --beg;
164 len = end - beg;
165 success_in_beg_and_len:
166 *match_size = len;
167 ret_val = beg - buf;
168 out:
169 return ret_val;
170}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette