1
1
#include "cache.h"
2
2
#include "grep.h"
3
+ #include "userdiff.h"
3
4
#include "xdiff-interface.h"
4
5
5
6
void append_header_grep_pattern (struct grep_opt * opt , enum grep_header_field field , const char * pat )
@@ -490,6 +491,17 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
490
491
{
491
492
int rest = eol - bol ;
492
493
494
+ if (opt -> pre_context || opt -> post_context ) {
495
+ if (opt -> last_shown == 0 ) {
496
+ if (opt -> show_hunk_mark )
497
+ fputs ("--\n" , stdout );
498
+ else
499
+ opt -> show_hunk_mark = 1 ;
500
+ } else if (lno > opt -> last_shown + 1 )
501
+ fputs ("--\n" , stdout );
502
+ }
503
+ opt -> last_shown = lno ;
504
+
493
505
if (opt -> null_following_name )
494
506
sign = '\0' ;
495
507
if (opt -> pathname )
@@ -520,22 +532,95 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
520
532
printf ("%.*s\n" , rest , bol );
521
533
}
522
534
535
+ static int match_funcname (struct grep_opt * opt , char * bol , char * eol )
536
+ {
537
+ xdemitconf_t * xecfg = opt -> priv ;
538
+ if (xecfg && xecfg -> find_func ) {
539
+ char buf [1 ];
540
+ return xecfg -> find_func (bol , eol - bol , buf , 1 ,
541
+ xecfg -> find_func_priv ) >= 0 ;
542
+ }
543
+
544
+ if (bol == eol )
545
+ return 0 ;
546
+ if (isalpha (* bol ) || * bol == '_' || * bol == '$' )
547
+ return 1 ;
548
+ return 0 ;
549
+ }
550
+
551
+ static void show_funcname_line (struct grep_opt * opt , const char * name ,
552
+ char * buf , char * bol , unsigned lno )
553
+ {
554
+ while (bol > buf ) {
555
+ char * eol = -- bol ;
556
+
557
+ while (bol > buf && bol [-1 ] != '\n' )
558
+ bol -- ;
559
+ lno -- ;
560
+
561
+ if (lno <= opt -> last_shown )
562
+ break ;
563
+
564
+ if (match_funcname (opt , bol , eol )) {
565
+ show_line (opt , bol , eol , name , lno , '=' );
566
+ break ;
567
+ }
568
+ }
569
+ }
570
+
571
+ static void show_pre_context (struct grep_opt * opt , const char * name , char * buf ,
572
+ char * bol , unsigned lno )
573
+ {
574
+ unsigned cur = lno , from = 1 , funcname_lno = 0 ;
575
+ int funcname_needed = opt -> funcname ;
576
+
577
+ if (opt -> pre_context < lno )
578
+ from = lno - opt -> pre_context ;
579
+ if (from <= opt -> last_shown )
580
+ from = opt -> last_shown + 1 ;
581
+
582
+ /* Rewind. */
583
+ while (bol > buf && cur > from ) {
584
+ char * eol = -- bol ;
585
+
586
+ while (bol > buf && bol [-1 ] != '\n' )
587
+ bol -- ;
588
+ cur -- ;
589
+ if (funcname_needed && match_funcname (opt , bol , eol )) {
590
+ funcname_lno = cur ;
591
+ funcname_needed = 0 ;
592
+ }
593
+ }
594
+
595
+ /* We need to look even further back to find a function signature. */
596
+ if (opt -> funcname && funcname_needed )
597
+ show_funcname_line (opt , name , buf , bol , cur );
598
+
599
+ /* Back forward. */
600
+ while (cur < lno ) {
601
+ char * eol = bol , sign = (cur == funcname_lno ) ? '=' : '-' ;
602
+
603
+ while (* eol != '\n' )
604
+ eol ++ ;
605
+ show_line (opt , bol , eol , name , cur , sign );
606
+ bol = eol + 1 ;
607
+ cur ++ ;
608
+ }
609
+ }
610
+
523
611
static int grep_buffer_1 (struct grep_opt * opt , const char * name ,
524
612
char * buf , unsigned long size , int collect_hits )
525
613
{
526
614
char * bol = buf ;
527
615
unsigned long left = size ;
528
616
unsigned lno = 1 ;
529
- struct pre_context_line {
530
- char * bol ;
531
- char * eol ;
532
- } * prev = NULL , * pcl ;
533
617
unsigned last_hit = 0 ;
534
- unsigned last_shown = 0 ;
535
618
int binary_match_only = 0 ;
536
- const char * hunk_mark = "" ;
537
619
unsigned count = 0 ;
538
620
enum grep_context ctx = GREP_CONTEXT_HEAD ;
621
+ xdemitconf_t xecfg ;
622
+
623
+ opt -> last_shown = 0 ;
539
624
540
625
if (buffer_is_binary (buf , size )) {
541
626
switch (opt -> binary ) {
@@ -550,10 +635,16 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
550
635
}
551
636
}
552
637
553
- if (opt -> pre_context )
554
- prev = xcalloc (opt -> pre_context , sizeof (* prev ));
555
- if (opt -> pre_context || opt -> post_context )
556
- hunk_mark = "--\n" ;
638
+ memset (& xecfg , 0 , sizeof (xecfg ));
639
+ if (opt -> funcname && !opt -> unmatch_name_only && !opt -> status_only &&
640
+ !opt -> name_only && !binary_match_only && !collect_hits ) {
641
+ struct userdiff_driver * drv = userdiff_find_by_path (name );
642
+ if (drv && drv -> funcname .pattern ) {
643
+ const struct userdiff_funcname * pe = & drv -> funcname ;
644
+ xdiff_set_find_func (& xecfg , pe -> pattern , pe -> cflags );
645
+ opt -> priv = & xecfg ;
646
+ }
647
+ }
557
648
558
649
while (left ) {
559
650
char * eol , ch ;
@@ -601,45 +692,20 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
601
692
* the context which is nonsense, but the user
602
693
* deserves to get that ;-).
603
694
*/
604
- if (opt -> pre_context ) {
605
- unsigned from ;
606
- if (opt -> pre_context < lno )
607
- from = lno - opt -> pre_context ;
608
- else
609
- from = 1 ;
610
- if (from <= last_shown )
611
- from = last_shown + 1 ;
612
- if (last_shown && from != last_shown + 1 )
613
- fputs (hunk_mark , stdout );
614
- while (from < lno ) {
615
- pcl = & prev [lno - from - 1 ];
616
- show_line (opt , pcl -> bol , pcl -> eol ,
617
- name , from , '-' );
618
- from ++ ;
619
- }
620
- last_shown = lno - 1 ;
621
- }
622
- if (last_shown && lno != last_shown + 1 )
623
- fputs (hunk_mark , stdout );
695
+ if (opt -> pre_context )
696
+ show_pre_context (opt , name , buf , bol , lno );
697
+ else if (opt -> funcname )
698
+ show_funcname_line (opt , name , buf , bol , lno );
624
699
if (!opt -> count )
625
700
show_line (opt , bol , eol , name , lno , ':' );
626
- last_shown = last_hit = lno ;
701
+ last_hit = lno ;
627
702
}
628
703
else if (last_hit &&
629
704
lno <= last_hit + opt -> post_context ) {
630
705
/* If the last hit is within the post context,
631
706
* we need to show this line.
632
707
*/
633
- if (last_shown && lno != last_shown + 1 )
634
- fputs (hunk_mark , stdout );
635
708
show_line (opt , bol , eol , name , lno , '-' );
636
- last_shown = lno ;
637
- }
638
- if (opt -> pre_context ) {
639
- memmove (prev + 1 , prev ,
640
- (opt -> pre_context - 1 ) * sizeof (* prev ));
641
- prev -> bol = bol ;
642
- prev -> eol = eol ;
643
709
}
644
710
645
711
next_line :
@@ -650,7 +716,6 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
650
716
lno ++ ;
651
717
}
652
718
653
- free (prev );
654
719
if (collect_hits )
655
720
return 0 ;
656
721
@@ -662,6 +727,9 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
662
727
return 1 ;
663
728
}
664
729
730
+ xdiff_clear_find_func (& xecfg );
731
+ opt -> priv = NULL ;
732
+
665
733
/* NEEDSWORK:
666
734
* The real "grep -c foo *.c" gives many "bar.c:0" lines,
667
735
* which feels mostly useless but sometimes useful. Maybe
0 commit comments