@@ -137,16 +137,50 @@ static void free_pcre_regexp(struct grep_pat *p)
137
137
}
138
138
#endif /* !USE_LIBPCRE */
139
139
140
+ static int is_fixed (const char * s , size_t len )
141
+ {
142
+ size_t i ;
143
+
144
+ /* regcomp cannot accept patterns with NULs so we
145
+ * consider any pattern containing a NUL fixed.
146
+ */
147
+ if (memchr (s , 0 , len ))
148
+ return 1 ;
149
+
150
+ for (i = 0 ; i < len ; i ++ ) {
151
+ if (is_regex_special (s [i ]))
152
+ return 0 ;
153
+ }
154
+
155
+ return 1 ;
156
+ }
157
+
140
158
static void compile_regexp (struct grep_pat * p , struct grep_opt * opt )
141
159
{
142
160
int err ;
143
161
144
162
p -> word_regexp = opt -> word_regexp ;
145
163
p -> ignore_case = opt -> ignore_case ;
146
- p -> fixed = opt -> fixed ;
147
164
148
- if (p -> fixed )
165
+ if (opt -> fixed || is_fixed (p -> pattern , p -> patternlen ))
166
+ p -> fixed = 1 ;
167
+ else
168
+ p -> fixed = 0 ;
169
+
170
+ if (p -> fixed ) {
171
+ if (opt -> regflags & REG_ICASE || p -> ignore_case ) {
172
+ static char trans [256 ];
173
+ int i ;
174
+ for (i = 0 ; i < 256 ; i ++ )
175
+ trans [i ] = tolower (i );
176
+ p -> kws = kwsalloc (trans );
177
+ } else {
178
+ p -> kws = kwsalloc (NULL );
179
+ }
180
+ kwsincr (p -> kws , p -> pattern , p -> patternlen );
181
+ kwsprep (p -> kws );
149
182
return ;
183
+ }
150
184
151
185
if (opt -> pcre ) {
152
186
compile_pcre_regexp (p , opt );
@@ -395,7 +429,9 @@ void free_grep_patterns(struct grep_opt *opt)
395
429
case GREP_PATTERN : /* atom */
396
430
case GREP_PATTERN_HEAD :
397
431
case GREP_PATTERN_BODY :
398
- if (p -> pcre_regexp )
432
+ if (p -> kws )
433
+ kwsfree (p -> kws );
434
+ else if (p -> pcre_regexp )
399
435
free_pcre_regexp (p );
400
436
else
401
437
regfree (& p -> regexp );
@@ -455,26 +491,14 @@ static void show_name(struct grep_opt *opt, const char *name)
455
491
static int fixmatch (struct grep_pat * p , char * line , char * eol ,
456
492
regmatch_t * match )
457
493
{
458
- char * hit ;
459
-
460
- if (p -> ignore_case ) {
461
- char * s = line ;
462
- do {
463
- hit = strcasestr (s , p -> pattern );
464
- if (hit )
465
- break ;
466
- s += strlen (s ) + 1 ;
467
- } while (s < eol );
468
- } else
469
- hit = memmem (line , eol - line , p -> pattern , p -> patternlen );
470
-
471
- if (!hit ) {
494
+ struct kwsmatch kwsm ;
495
+ size_t offset = kwsexec (p -> kws , line , eol - line , & kwsm );
496
+ if (offset == -1 ) {
472
497
match -> rm_so = match -> rm_eo = -1 ;
473
498
return REG_NOMATCH ;
474
- }
475
- else {
476
- match -> rm_so = hit - line ;
477
- match -> rm_eo = match -> rm_so + p -> patternlen ;
499
+ } else {
500
+ match -> rm_so = offset ;
501
+ match -> rm_eo = match -> rm_so + kwsm .size [0 ];
478
502
return 0 ;
479
503
}
480
504
}
0 commit comments