@@ -778,7 +778,6 @@ struct moved_entry {
778
778
struct hashmap_entry ent ;
779
779
const struct emitted_diff_symbol * es ;
780
780
struct moved_entry * next_line ;
781
- struct ws_delta * wsd ;
782
781
};
783
782
784
783
/**
@@ -795,6 +794,17 @@ struct ws_delta {
795
794
};
796
795
#define WS_DELTA_INIT { NULL, 0 }
797
796
797
+ struct moved_block {
798
+ struct moved_entry * match ;
799
+ struct ws_delta wsd ;
800
+ };
801
+
802
+ static void moved_block_clear (struct moved_block * b )
803
+ {
804
+ FREE_AND_NULL (b -> wsd .string );
805
+ b -> match = NULL ;
806
+ }
807
+
798
808
static int compute_ws_delta (const struct emitted_diff_symbol * a ,
799
809
const struct emitted_diff_symbol * b ,
800
810
struct ws_delta * out )
@@ -803,16 +813,19 @@ static int compute_ws_delta(const struct emitted_diff_symbol *a,
803
813
const struct emitted_diff_symbol * shorter = a -> len > b -> len ? b : a ;
804
814
int d = longer -> len - shorter -> len ;
805
815
816
+ if (strncmp (longer -> line + d , shorter -> line , shorter -> len ))
817
+ return 0 ;
818
+
806
819
out -> string = xmemdupz (longer -> line , d );
807
820
out -> current_longer = (a == longer );
808
821
809
- return ! strncmp ( longer -> line + d , shorter -> line , shorter -> len ) ;
822
+ return 1 ;
810
823
}
811
824
812
825
static int cmp_in_block_with_wsd (const struct diff_options * o ,
813
826
const struct moved_entry * cur ,
814
827
const struct moved_entry * match ,
815
- struct moved_entry * pmb ,
828
+ struct moved_block * pmb ,
816
829
int n )
817
830
{
818
831
struct emitted_diff_symbol * l = & o -> emitted_symbols -> buf [n ];
@@ -832,33 +845,32 @@ static int cmp_in_block_with_wsd(const struct diff_options *o,
832
845
if (strcmp (a , b ))
833
846
return 1 ;
834
847
835
- if (!pmb -> wsd )
848
+ if (!pmb -> wsd . string )
836
849
/*
837
- * No white space delta was carried forward? This can happen
838
- * when we exit early in this function and do not carry
839
- * forward ws.
850
+ * The white space delta is not active? This can happen
851
+ * when we exit early in this function.
840
852
*/
841
853
return 1 ;
842
854
843
855
/*
844
- * The indent changes of the block are known and carried forward in
856
+ * The indent changes of the block are known and stored in
845
857
* pmb->wsd; however we need to check if the indent changes of the
846
858
* current line are still the same as before.
847
859
*
848
860
* To do so we need to compare 'l' to 'cur', adjusting the
849
861
* one of them for the white spaces, depending which was longer.
850
862
*/
851
863
852
- wslen = strlen (pmb -> wsd -> string );
853
- if (pmb -> wsd -> current_longer ) {
864
+ wslen = strlen (pmb -> wsd . string );
865
+ if (pmb -> wsd . current_longer ) {
854
866
c += wslen ;
855
867
cl -= wslen ;
856
868
} else {
857
869
a += wslen ;
858
870
al -= wslen ;
859
871
}
860
872
861
- if (strcmp (a , c ))
873
+ if (al != cl || memcmp (a , c , al ))
862
874
return 1 ;
863
875
864
876
return 0 ;
@@ -900,7 +912,6 @@ static struct moved_entry *prepare_entry(struct diff_options *o,
900
912
ret -> ent .hash = xdiff_hash_string (l -> line , l -> len , flags );
901
913
ret -> es = l ;
902
914
ret -> next_line = NULL ;
903
- ret -> wsd = NULL ;
904
915
905
916
return ret ;
906
917
}
@@ -940,76 +951,74 @@ static void add_lines_to_move_detection(struct diff_options *o,
940
951
static void pmb_advance_or_null (struct diff_options * o ,
941
952
struct moved_entry * match ,
942
953
struct hashmap * hm ,
943
- struct moved_entry * * pmb ,
954
+ struct moved_block * pmb ,
944
955
int pmb_nr )
945
956
{
946
957
int i ;
947
958
for (i = 0 ; i < pmb_nr ; i ++ ) {
948
- struct moved_entry * prev = pmb [i ];
959
+ struct moved_entry * prev = pmb [i ]. match ;
949
960
struct moved_entry * cur = (prev && prev -> next_line ) ?
950
961
prev -> next_line : NULL ;
951
962
if (cur && !hm -> cmpfn (o , cur , match , NULL )) {
952
- pmb [i ] = cur ;
963
+ pmb [i ]. match = cur ;
953
964
} else {
954
- pmb [i ] = NULL ;
965
+ pmb [i ]. match = NULL ;
955
966
}
956
967
}
957
968
}
958
969
959
970
static void pmb_advance_or_null_multi_match (struct diff_options * o ,
960
971
struct moved_entry * match ,
961
972
struct hashmap * hm ,
962
- struct moved_entry * * pmb ,
973
+ struct moved_block * pmb ,
963
974
int pmb_nr , int n )
964
975
{
965
976
int i ;
966
977
char * got_match = xcalloc (1 , pmb_nr );
967
978
968
979
for (; match ; match = hashmap_get_next (hm , match )) {
969
980
for (i = 0 ; i < pmb_nr ; i ++ ) {
970
- struct moved_entry * prev = pmb [i ];
981
+ struct moved_entry * prev = pmb [i ]. match ;
971
982
struct moved_entry * cur = (prev && prev -> next_line ) ?
972
983
prev -> next_line : NULL ;
973
984
if (!cur )
974
985
continue ;
975
- if (!cmp_in_block_with_wsd (o , cur , match , pmb [i ], n ))
986
+ if (!cmp_in_block_with_wsd (o , cur , match , & pmb [i ], n ))
976
987
got_match [i ] |= 1 ;
977
988
}
978
989
}
979
990
980
991
for (i = 0 ; i < pmb_nr ; i ++ ) {
981
992
if (got_match [i ]) {
982
- /* Carry the white space delta forward */
983
- pmb [i ]-> next_line -> wsd = pmb [i ]-> wsd ;
984
- pmb [i ] = pmb [i ]-> next_line ;
993
+ /* Advance to the next line */
994
+ pmb [i ].match = pmb [i ].match -> next_line ;
985
995
} else {
986
- if (pmb [i ]-> wsd ) {
987
- free (pmb [i ]-> wsd -> string );
988
- FREE_AND_NULL (pmb [i ]-> wsd );
989
- }
990
- pmb [i ] = NULL ;
996
+ moved_block_clear (& pmb [i ]);
991
997
}
992
998
}
999
+
1000
+ free (got_match );
993
1001
}
994
1002
995
- static int shrink_potential_moved_blocks (struct moved_entry * * pmb ,
1003
+ static int shrink_potential_moved_blocks (struct moved_block * pmb ,
996
1004
int pmb_nr )
997
1005
{
998
1006
int lp , rp ;
999
1007
1000
1008
/* Shrink the set of potential block to the remaining running */
1001
1009
for (lp = 0 , rp = pmb_nr - 1 ; lp <= rp ;) {
1002
- while (lp < pmb_nr && pmb [lp ])
1010
+ while (lp < pmb_nr && pmb [lp ]. match )
1003
1011
lp ++ ;
1004
1012
/* lp points at the first NULL now */
1005
1013
1006
- while (rp > -1 && !pmb [rp ])
1014
+ while (rp > -1 && !pmb [rp ]. match )
1007
1015
rp -- ;
1008
1016
/* rp points at the last non-NULL */
1009
1017
1010
1018
if (lp < pmb_nr && rp > -1 && lp < rp ) {
1011
1019
pmb [lp ] = pmb [rp ];
1012
- pmb [rp ] = NULL ;
1020
+ pmb [rp ].match = NULL ;
1021
+ pmb [rp ].wsd .string = NULL ;
1013
1022
rp -- ;
1014
1023
lp ++ ;
1015
1024
}
@@ -1056,7 +1065,7 @@ static void mark_color_as_moved(struct diff_options *o,
1056
1065
struct hashmap * add_lines ,
1057
1066
struct hashmap * del_lines )
1058
1067
{
1059
- struct moved_entry * * pmb = NULL ; /* potentially moved blocks */
1068
+ struct moved_block * pmb = NULL ; /* potentially moved blocks */
1060
1069
int pmb_nr = 0 , pmb_alloc = 0 ;
1061
1070
int n , flipped_block = 1 , block_length = 0 ;
1062
1071
@@ -1085,7 +1094,11 @@ static void mark_color_as_moved(struct diff_options *o,
1085
1094
}
1086
1095
1087
1096
if (!match ) {
1097
+ int i ;
1098
+
1088
1099
adjust_last_block (o , n , block_length );
1100
+ for (i = 0 ; i < pmb_nr ; i ++ )
1101
+ moved_block_clear (& pmb [i ]);
1089
1102
pmb_nr = 0 ;
1090
1103
block_length = 0 ;
1091
1104
continue ;
@@ -1113,14 +1126,12 @@ static void mark_color_as_moved(struct diff_options *o,
1113
1126
ALLOC_GROW (pmb , pmb_nr + 1 , pmb_alloc );
1114
1127
if (o -> color_moved_ws_handling &
1115
1128
COLOR_MOVED_WS_ALLOW_INDENTATION_CHANGE ) {
1116
- struct ws_delta * wsd = xmalloc (sizeof (* match -> wsd ));
1117
- if (compute_ws_delta (l , match -> es , wsd )) {
1118
- match -> wsd = wsd ;
1119
- pmb [pmb_nr ++ ] = match ;
1120
- } else
1121
- free (wsd );
1129
+ if (compute_ws_delta (l , match -> es ,
1130
+ & pmb [pmb_nr ].wsd ))
1131
+ pmb [pmb_nr ++ ].match = match ;
1122
1132
} else {
1123
- pmb [pmb_nr ++ ] = match ;
1133
+ pmb [pmb_nr ].wsd .string = NULL ;
1134
+ pmb [pmb_nr ++ ].match = match ;
1124
1135
}
1125
1136
}
1126
1137
@@ -1137,6 +1148,8 @@ static void mark_color_as_moved(struct diff_options *o,
1137
1148
}
1138
1149
adjust_last_block (o , n , block_length );
1139
1150
1151
+ for (n = 0 ; n < pmb_nr ; n ++ )
1152
+ moved_block_clear (& pmb [n ]);
1140
1153
free (pmb );
1141
1154
}
1142
1155
@@ -5867,8 +5880,8 @@ static void diff_flush_patch_all_file_pairs(struct diff_options *o)
5867
5880
if (o -> color_moved == COLOR_MOVED_ZEBRA_DIM )
5868
5881
dim_moved_lines (o );
5869
5882
5870
- hashmap_free (& add_lines , 0 );
5871
- hashmap_free (& del_lines , 0 );
5883
+ hashmap_free (& add_lines , 1 );
5884
+ hashmap_free (& del_lines , 1 );
5872
5885
}
5873
5886
5874
5887
for (i = 0 ; i < esm .nr ; i ++ )
0 commit comments