1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
|
--- grep-2.5.1/src/search.c
+++ grep-2.5.1/src/search.c
@@ -360,13 +360,7 @@
/* Find a possible match using the KWset matcher. */
size_t offset = kwsexec (kwset, beg, buflim - beg, &kwsm);
if (offset == (size_t) -1)
- {
-#ifdef MBS_SUPPORT
- if (MB_CUR_MAX > 1)
- free(mb_properties);
-#endif
- return (size_t)-1;
- }
+ goto failure;
beg += offset;
/* Narrow down to the line containing the candidate, and
run it through DFA. */
@@ -379,7 +373,7 @@
while (beg > buf && beg[-1] != eol)
--beg;
if (kwsm.index < kwset_exact_matches)
- goto success;
+ goto success_in_beg_and_end;
if (dfaexec (&dfa, beg, end - beg, &backref) == (size_t) -1)
continue;
}
@@ -398,7 +392,7 @@
}
/* Successful, no backreferences encountered! */
if (!backref)
- goto success;
+ goto success_in_beg_and_end;
}
else
end = beg + size;
@@ -413,14 +407,11 @@
end - beg - 1, &(patterns[i].regs))))
{
len = patterns[i].regs.end[0] - start;
- if (exact)
- {
- *match_size = len;
- return start;
- }
+ if (exact && !match_words)
+ goto success_in_start_and_len;
if ((!match_lines && !match_words)
|| (match_lines && len == end - beg - 1))
- goto success;
+ goto success_in_beg_and_end;
/* If -w, check if the match aligns with word boundaries.
We do this iteratively because:
(a) the line may contain more than one occurence of the
@@ -434,7 +425,7 @@
if ((start == 0 || !WCHAR ((unsigned char) beg[start - 1]))
&& (len == end - beg - 1
|| !WCHAR ((unsigned char) beg[start + len])))
- goto success;
+ goto success_in_start_and_len;
if (len > 0)
{
/* Try a shorter length anchored at the same place. */
@@ -461,19 +452,26 @@
}
} /* for Regex patterns. */
} /* for (beg = end ..) */
+
+ failure:
#ifdef MBS_SUPPORT
if (MB_CUR_MAX > 1 && mb_properties)
free (mb_properties);
#endif /* MBS_SUPPORT */
return (size_t) -1;
- success:
+ success_in_beg_and_end:
+ len = end - beg;
+ start = beg - buf;
+ /* FALLTHROUGH */
+
+ success_in_start_and_len:
#ifdef MBS_SUPPORT
if (MB_CUR_MAX > 1 && mb_properties)
free (mb_properties);
#endif /* MBS_SUPPORT */
- *match_size = end - beg;
- return beg - buf;
+ *match_size = len;
+ return start;
}
static void
@@ -516,28 +514,15 @@
{
size_t offset = kwsexec (kwset, beg, buf + size - beg, &kwsmatch);
if (offset == (size_t) -1)
- {
-#ifdef MBS_SUPPORT
- if (MB_CUR_MAX > 1)
- free(mb_properties);
-#endif /* MBS_SUPPORT */
- return offset;
- }
+ goto failure;
#ifdef MBS_SUPPORT
if (MB_CUR_MAX > 1 && mb_properties[offset+beg-buf] == 0)
continue; /* It is a part of multibyte character. */
#endif /* MBS_SUPPORT */
beg += offset;
len = kwsmatch.size[0];
- if (exact)
- {
- *match_size = len;
-#ifdef MBS_SUPPORT
- if (MB_CUR_MAX > 1)
- free (mb_properties);
-#endif /* MBS_SUPPORT */
- return beg - buf;
- }
+ if (exact && !match_words)
+ goto success_in_beg_and_len;
if (match_lines)
{
if (beg > buf && beg[-1] != eol)
@@ -547,31 +532,37 @@
goto success;
}
else if (match_words)
- for (try = beg; len; )
- {
- if (try > buf && WCHAR((unsigned char) try[-1]))
- break;
- if (try + len < buf + size && WCHAR((unsigned char) try[len]))
- {
- offset = kwsexec (kwset, beg, --len, &kwsmatch);
- if (offset == (size_t) -1)
- {
-#ifdef MBS_SUPPORT
- if (MB_CUR_MAX > 1)
- free (mb_properties);
-#endif /* MBS_SUPPORT */
- return offset;
- }
- try = beg + offset;
- len = kwsmatch.size[0];
- }
- else
- goto success;
- }
+ {
+ while (offset >= 0)
+ {
+ if ((offset == 0 || !WCHAR ((unsigned char) beg[-1]))
+ && (len == end - beg - 1 || !WCHAR ((unsigned char) beg[len])))
+ {
+ if (!exact)
+ /* Returns the whole line now we know there's a word match. */
+ goto success;
+ else
+ /* Returns just this word match. */
+ goto success_in_beg_and_len;
+ }
+ if (len > 0)
+ {
+ /* Try a shorter length anchored at the same place. */
+ --len;
+ offset = kwsexec (kwset, beg, len, &kwsmatch);
+ if (offset == -1) {
+ break; /* Try a different anchor. */
+ }
+ beg += offset;
+ len = kwsmatch.size[0];
+ }
+ }
+ }
else
goto success;
}
+ failure:
#ifdef MBS_SUPPORT
if (MB_CUR_MAX > 1)
free (mb_properties);
@@ -583,7 +574,11 @@
end++;
while (buf < beg && beg[-1] != eol)
--beg;
- *match_size = end - beg;
+ len = end - beg;
+ /* FALLTHROUGH */
+
+ success_in_beg_and_len:
+ *match_size = len;
#ifdef MBS_SUPPORT
if (MB_CUR_MAX > 1)
free (mb_properties);
|