@@ -39,6 +39,8 @@ static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
3939{
4040 int err ;
4141
42+ p -> word_regexp = opt -> word_regexp ;
43+
4244 if (opt -> fixed || is_fixed (p -> pattern ))
4345 p -> fixed = 1 ;
4446 if (opt -> regflags & REG_ICASE )
@@ -251,18 +253,6 @@ static int word_char(char ch)
251253 return isalnum (ch ) || ch == '_' ;
252254}
253255
254- static void show_line (struct grep_opt * opt , const char * bol , const char * eol ,
255- const char * name , unsigned lno , char sign )
256- {
257- if (opt -> null_following_name )
258- sign = '\0' ;
259- if (opt -> pathname )
260- printf ("%s%c" , name , sign );
261- if (opt -> linenum )
262- printf ("%d%c" , lno , sign );
263- printf ("%.*s\n" , (int )(eol - bol ), bol );
264- }
265-
266256static void show_name (struct grep_opt * opt , const char * name )
267257{
268258 printf ("%s%c" , name , opt -> null_following_name ? '\0' : '\n' );
@@ -306,11 +296,12 @@ static struct {
306296 { "committer " , 10 },
307297};
308298
309- static int match_one_pattern (struct grep_opt * opt , struct grep_pat * p , char * bol , char * eol , enum grep_context ctx )
299+ static int match_one_pattern (struct grep_pat * p , char * bol , char * eol ,
300+ enum grep_context ctx ,
301+ regmatch_t * pmatch , int eflags )
310302{
311303 int hit = 0 ;
312304 int saved_ch = 0 ;
313- regmatch_t pmatch [10 ];
314305
315306 if ((p -> token != GREP_PATTERN ) &&
316307 ((p -> token == GREP_PATTERN_HEAD ) != (ctx == GREP_CONTEXT_HEAD )))
@@ -329,16 +320,12 @@ static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol
329320 }
330321
331322 again :
332- if (!p -> fixed ) {
333- regex_t * exp = & p -> regexp ;
334- hit = !regexec (exp , bol , ARRAY_SIZE (pmatch ),
335- pmatch , 0 );
336- }
337- else {
323+ if (p -> fixed )
338324 hit = !fixmatch (p -> pattern , bol , pmatch );
339- }
325+ else
326+ hit = !regexec (& p -> regexp , bol , 1 , pmatch , eflags );
340327
341- if (hit && opt -> word_regexp ) {
328+ if (hit && p -> word_regexp ) {
342329 if ((pmatch [0 ].rm_so < 0 ) ||
343330 (eol - bol ) <= pmatch [0 ].rm_so ||
344331 (pmatch [0 ].rm_eo < 0 ) ||
@@ -378,39 +365,33 @@ static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol
378365 return hit ;
379366}
380367
381- static int match_expr_eval (struct grep_opt * o ,
382- struct grep_expr * x ,
383- char * bol , char * eol ,
384- enum grep_context ctx ,
385- int collect_hits )
368+ static int match_expr_eval (struct grep_expr * x , char * bol , char * eol ,
369+ enum grep_context ctx , int collect_hits )
386370{
387371 int h = 0 ;
372+ regmatch_t match ;
388373
389374 switch (x -> node ) {
390375 case GREP_NODE_ATOM :
391- h = match_one_pattern (o , x -> u .atom , bol , eol , ctx );
376+ h = match_one_pattern (x -> u .atom , bol , eol , ctx , & match , 0 );
392377 break ;
393378 case GREP_NODE_NOT :
394- h = !match_expr_eval (o , x -> u .unary , bol , eol , ctx , 0 );
379+ h = !match_expr_eval (x -> u .unary , bol , eol , ctx , 0 );
395380 break ;
396381 case GREP_NODE_AND :
397- if (!collect_hits )
398- return (match_expr_eval (o , x -> u .binary .left ,
399- bol , eol , ctx , 0 ) &&
400- match_expr_eval (o , x -> u .binary .right ,
401- bol , eol , ctx , 0 ));
402- h = match_expr_eval (o , x -> u .binary .left , bol , eol , ctx , 0 );
403- h &= match_expr_eval (o , x -> u .binary .right , bol , eol , ctx , 0 );
382+ if (!match_expr_eval (x -> u .binary .left , bol , eol , ctx , 0 ))
383+ return 0 ;
384+ h = match_expr_eval (x -> u .binary .right , bol , eol , ctx , 0 );
404385 break ;
405386 case GREP_NODE_OR :
406387 if (!collect_hits )
407- return (match_expr_eval (o , x -> u .binary .left ,
388+ return (match_expr_eval (x -> u .binary .left ,
408389 bol , eol , ctx , 0 ) ||
409- match_expr_eval (o , x -> u .binary .right ,
390+ match_expr_eval (x -> u .binary .right ,
410391 bol , eol , ctx , 0 ));
411- h = match_expr_eval (o , x -> u .binary .left , bol , eol , ctx , 0 );
392+ h = match_expr_eval (x -> u .binary .left , bol , eol , ctx , 0 );
412393 x -> u .binary .left -> hit |= h ;
413- h |= match_expr_eval (o , x -> u .binary .right , bol , eol , ctx , 1 );
394+ h |= match_expr_eval (x -> u .binary .right , bol , eol , ctx , 1 );
414395 break ;
415396 default :
416397 die ("Unexpected node type (internal error) %d" , x -> node );
@@ -424,24 +405,104 @@ static int match_expr(struct grep_opt *opt, char *bol, char *eol,
424405 enum grep_context ctx , int collect_hits )
425406{
426407 struct grep_expr * x = opt -> pattern_expression ;
427- return match_expr_eval (opt , x , bol , eol , ctx , collect_hits );
408+ return match_expr_eval (x , bol , eol , ctx , collect_hits );
428409}
429410
430411static int match_line (struct grep_opt * opt , char * bol , char * eol ,
431412 enum grep_context ctx , int collect_hits )
432413{
433414 struct grep_pat * p ;
415+ regmatch_t match ;
416+
434417 if (opt -> extended )
435418 return match_expr (opt , bol , eol , ctx , collect_hits );
436419
437420 /* we do not call with collect_hits without being extended */
438421 for (p = opt -> pattern_list ; p ; p = p -> next ) {
439- if (match_one_pattern (opt , p , bol , eol , ctx ))
422+ if (match_one_pattern (p , bol , eol , ctx , & match , 0 ))
440423 return 1 ;
441424 }
442425 return 0 ;
443426}
444427
428+ static int match_next_pattern (struct grep_pat * p , char * bol , char * eol ,
429+ enum grep_context ctx ,
430+ regmatch_t * pmatch , int eflags )
431+ {
432+ regmatch_t match ;
433+
434+ if (!match_one_pattern (p , bol , eol , ctx , & match , eflags ))
435+ return 0 ;
436+ if (match .rm_so < 0 || match .rm_eo < 0 )
437+ return 0 ;
438+ if (pmatch -> rm_so >= 0 && pmatch -> rm_eo >= 0 ) {
439+ if (match .rm_so > pmatch -> rm_so )
440+ return 1 ;
441+ if (match .rm_so == pmatch -> rm_so && match .rm_eo < pmatch -> rm_eo )
442+ return 1 ;
443+ }
444+ pmatch -> rm_so = match .rm_so ;
445+ pmatch -> rm_eo = match .rm_eo ;
446+ return 1 ;
447+ }
448+
449+ static int next_match (struct grep_opt * opt , char * bol , char * eol ,
450+ enum grep_context ctx , regmatch_t * pmatch , int eflags )
451+ {
452+ struct grep_pat * p ;
453+ int hit = 0 ;
454+
455+ pmatch -> rm_so = pmatch -> rm_eo = -1 ;
456+ if (bol < eol ) {
457+ for (p = opt -> pattern_list ; p ; p = p -> next ) {
458+ switch (p -> token ) {
459+ case GREP_PATTERN : /* atom */
460+ case GREP_PATTERN_HEAD :
461+ case GREP_PATTERN_BODY :
462+ hit |= match_next_pattern (p , bol , eol , ctx ,
463+ pmatch , eflags );
464+ break ;
465+ default :
466+ break ;
467+ }
468+ }
469+ }
470+ return hit ;
471+ }
472+
473+ static void show_line (struct grep_opt * opt , char * bol , char * eol ,
474+ const char * name , unsigned lno , char sign )
475+ {
476+ int rest = eol - bol ;
477+
478+ if (opt -> null_following_name )
479+ sign = '\0' ;
480+ if (opt -> pathname )
481+ printf ("%s%c" , name , sign );
482+ if (opt -> linenum )
483+ printf ("%d%c" , lno , sign );
484+ if (opt -> color ) {
485+ regmatch_t match ;
486+ enum grep_context ctx = GREP_CONTEXT_BODY ;
487+ int ch = * eol ;
488+ int eflags = 0 ;
489+
490+ * eol = '\0' ;
491+ while (next_match (opt , bol , eol , ctx , & match , eflags )) {
492+ printf ("%.*s%s%.*s%s" ,
493+ (int )match .rm_so , bol ,
494+ opt -> color_match ,
495+ (int )(match .rm_eo - match .rm_so ), bol + match .rm_so ,
496+ GIT_COLOR_RESET );
497+ bol += match .rm_eo ;
498+ rest -= match .rm_eo ;
499+ eflags = REG_NOTBOL ;
500+ }
501+ * eol = ch ;
502+ }
503+ printf ("%.*s\n" , rest , bol );
504+ }
505+
445506static int grep_buffer_1 (struct grep_opt * opt , const char * name ,
446507 char * buf , unsigned long size , int collect_hits )
447508{
0 commit comments