@@ -59,6 +59,84 @@ struct grep_opt *grep_opt_dup(const struct grep_opt *opt)
5959 return ret ;
6060}
6161
62+ static NORETURN void compile_regexp_failed (const struct grep_pat * p ,
63+ const char * error )
64+ {
65+ char where [1024 ];
66+
67+ if (p -> no )
68+ sprintf (where , "In '%s' at %d, " , p -> origin , p -> no );
69+ else if (p -> origin )
70+ sprintf (where , "%s, " , p -> origin );
71+ else
72+ where [0 ] = 0 ;
73+
74+ die ("%s'%s': %s" , where , p -> pattern , error );
75+ }
76+
77+ #ifdef USE_LIBPCRE
78+ static void compile_pcre_regexp (struct grep_pat * p , const struct grep_opt * opt )
79+ {
80+ const char * error ;
81+ int erroffset ;
82+ int options = 0 ;
83+
84+ if (opt -> ignore_case )
85+ options |= PCRE_CASELESS ;
86+
87+ p -> pcre_regexp = pcre_compile (p -> pattern , options , & error , & erroffset ,
88+ NULL );
89+ if (!p -> pcre_regexp )
90+ compile_regexp_failed (p , error );
91+
92+ p -> pcre_extra_info = pcre_study (p -> pcre_regexp , 0 , & error );
93+ if (!p -> pcre_extra_info && error )
94+ die ("%s" , error );
95+ }
96+
97+ static int pcrematch (struct grep_pat * p , const char * line , const char * eol ,
98+ regmatch_t * match , int eflags )
99+ {
100+ int ovector [30 ], ret , flags = 0 ;
101+
102+ if (eflags & REG_NOTBOL )
103+ flags |= PCRE_NOTBOL ;
104+
105+ ret = pcre_exec (p -> pcre_regexp , p -> pcre_extra_info , line , eol - line ,
106+ 0 , flags , ovector , ARRAY_SIZE (ovector ));
107+ if (ret < 0 && ret != PCRE_ERROR_NOMATCH )
108+ die ("pcre_exec failed with error code %d" , ret );
109+ if (ret > 0 ) {
110+ ret = 0 ;
111+ match -> rm_so = ovector [0 ];
112+ match -> rm_eo = ovector [1 ];
113+ }
114+
115+ return ret ;
116+ }
117+
118+ static void free_pcre_regexp (struct grep_pat * p )
119+ {
120+ pcre_free (p -> pcre_regexp );
121+ pcre_free (p -> pcre_extra_info );
122+ }
123+ #else /* !USE_LIBPCRE */
124+ static void compile_pcre_regexp (struct grep_pat * p , const struct grep_opt * opt )
125+ {
126+ die ("cannot use Perl-compatible regexes when not compiled with USE_LIBPCRE" );
127+ }
128+
129+ static int pcrematch (struct grep_pat * p , const char * line , const char * eol ,
130+ regmatch_t * match , int eflags )
131+ {
132+ return 1 ;
133+ }
134+
135+ static void free_pcre_regexp (struct grep_pat * p )
136+ {
137+ }
138+ #endif /* !USE_LIBPCRE */
139+
62140static void compile_regexp (struct grep_pat * p , struct grep_opt * opt )
63141{
64142 int err ;
@@ -70,20 +148,17 @@ static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
70148 if (p -> fixed )
71149 return ;
72150
151+ if (opt -> pcre ) {
152+ compile_pcre_regexp (p , opt );
153+ return ;
154+ }
155+
73156 err = regcomp (& p -> regexp , p -> pattern , opt -> regflags );
74157 if (err ) {
75158 char errbuf [1024 ];
76- char where [1024 ];
77- if (p -> no )
78- sprintf (where , "In '%s' at %d, " ,
79- p -> origin , p -> no );
80- else if (p -> origin )
81- sprintf (where , "%s, " , p -> origin );
82- else
83- where [0 ] = 0 ;
84159 regerror (err , & p -> regexp , errbuf , 1024 );
85160 regfree (& p -> regexp );
86- die ( "%s'%s': %s" , where , p -> pattern , errbuf );
161+ compile_regexp_failed ( p , errbuf );
87162 }
88163}
89164
@@ -320,7 +395,10 @@ void free_grep_patterns(struct grep_opt *opt)
320395 case GREP_PATTERN : /* atom */
321396 case GREP_PATTERN_HEAD :
322397 case GREP_PATTERN_BODY :
323- regfree (& p -> regexp );
398+ if (p -> pcre_regexp )
399+ free_pcre_regexp (p );
400+ else
401+ regfree (& p -> regexp );
324402 break ;
325403 default :
326404 break ;
@@ -412,6 +490,21 @@ static int regmatch(const regex_t *preg, char *line, char *eol,
412490 return regexec (preg , line , 1 , match , eflags );
413491}
414492
493+ static int patmatch (struct grep_pat * p , char * line , char * eol ,
494+ regmatch_t * match , int eflags )
495+ {
496+ int hit ;
497+
498+ if (p -> fixed )
499+ hit = !fixmatch (p , line , eol , match );
500+ else if (p -> pcre_regexp )
501+ hit = !pcrematch (p , line , eol , match , eflags );
502+ else
503+ hit = !regmatch (& p -> regexp , line , eol , match , eflags );
504+
505+ return hit ;
506+ }
507+
415508static int strip_timestamp (char * bol , char * * eol_p )
416509{
417510 char * eol = * eol_p ;
@@ -461,10 +554,7 @@ static int match_one_pattern(struct grep_pat *p, char *bol, char *eol,
461554 }
462555
463556 again :
464- if (p -> fixed )
465- hit = !fixmatch (p , bol , eol , pmatch );
466- else
467- hit = !regmatch (& p -> regexp , bol , eol , pmatch , eflags );
557+ hit = patmatch (p , bol , eol , pmatch , eflags );
468558
469559 if (hit && p -> word_regexp ) {
470560 if ((pmatch [0 ].rm_so < 0 ) ||
@@ -791,10 +881,7 @@ static int look_ahead(struct grep_opt *opt,
791881 int hit ;
792882 regmatch_t m ;
793883
794- if (p -> fixed )
795- hit = !fixmatch (p , bol , bol + * left_p , & m );
796- else
797- hit = !regmatch (& p -> regexp , bol , bol + * left_p , & m , 0 );
884+ hit = patmatch (p , bol , bol + * left_p , & m , 0 );
798885 if (!hit || m .rm_so < 0 || m .rm_eo < 0 )
799886 continue ;
800887 if (earliest < 0 || m .rm_so < earliest )
@@ -891,7 +978,7 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
891978 int hit ;
892979
893980 /*
894- * look_ahead() skips quicly to the line that possibly
981+ * look_ahead() skips quickly to the line that possibly
895982 * has the next hit; don't call it if we need to do
896983 * something more than just skipping the current line
897984 * in response to an unmatch for the current line. E.g.
0 commit comments