@@ -776,7 +776,6 @@ struct moved_entry {
776776 struct hashmap_entry ent ;
777777 const struct emitted_diff_symbol * es ;
778778 struct moved_entry * next_line ;
779- struct ws_delta * wsd ;
780779};
781780
782781/**
@@ -793,6 +792,17 @@ struct ws_delta {
793792};
794793#define WS_DELTA_INIT { NULL, 0 }
795794
795+ struct moved_block {
796+ struct moved_entry * match ;
797+ struct ws_delta wsd ;
798+ };
799+
800+ static void moved_block_clear (struct moved_block * b )
801+ {
802+ FREE_AND_NULL (b -> wsd .string );
803+ b -> match = NULL ;
804+ }
805+
796806static int compute_ws_delta (const struct emitted_diff_symbol * a ,
797807 const struct emitted_diff_symbol * b ,
798808 struct ws_delta * out )
@@ -810,7 +820,7 @@ static int compute_ws_delta(const struct emitted_diff_symbol *a,
810820static int cmp_in_block_with_wsd (const struct diff_options * o ,
811821 const struct moved_entry * cur ,
812822 const struct moved_entry * match ,
813- struct moved_entry * pmb ,
823+ struct moved_block * pmb ,
814824 int n )
815825{
816826 struct emitted_diff_symbol * l = & o -> emitted_symbols -> buf [n ];
@@ -830,25 +840,24 @@ static int cmp_in_block_with_wsd(const struct diff_options *o,
830840 if (strcmp (a , b ))
831841 return 1 ;
832842
833- if (!pmb -> wsd )
843+ if (!pmb -> wsd . string )
834844 /*
835- * No white space delta was carried forward? This can happen
836- * when we exit early in this function and do not carry
837- * forward ws.
845+ * The white space delta is not active? This can happen
846+ * when we exit early in this function.
838847 */
839848 return 1 ;
840849
841850 /*
842- * The indent changes of the block are known and carried forward in
851+ * The indent changes of the block are known and stored in
843852 * pmb->wsd; however we need to check if the indent changes of the
844853 * current line are still the same as before.
845854 *
846855 * To do so we need to compare 'l' to 'cur', adjusting the
847856 * one of them for the white spaces, depending which was longer.
848857 */
849858
850- wslen = strlen (pmb -> wsd -> string );
851- if (pmb -> wsd -> current_longer ) {
859+ wslen = strlen (pmb -> wsd . string );
860+ if (pmb -> wsd . current_longer ) {
852861 c += wslen ;
853862 cl -= wslen ;
854863 } else {
@@ -898,7 +907,6 @@ static struct moved_entry *prepare_entry(struct diff_options *o,
898907 ret -> ent .hash = xdiff_hash_string (l -> line , l -> len , flags );
899908 ret -> es = l ;
900909 ret -> next_line = NULL ;
901- ret -> wsd = NULL ;
902910
903911 return ret ;
904912}
@@ -938,76 +946,72 @@ static void add_lines_to_move_detection(struct diff_options *o,
938946static void pmb_advance_or_null (struct diff_options * o ,
939947 struct moved_entry * match ,
940948 struct hashmap * hm ,
941- struct moved_entry * * pmb ,
949+ struct moved_block * pmb ,
942950 int pmb_nr )
943951{
944952 int i ;
945953 for (i = 0 ; i < pmb_nr ; i ++ ) {
946- struct moved_entry * prev = pmb [i ];
954+ struct moved_entry * prev = pmb [i ]. match ;
947955 struct moved_entry * cur = (prev && prev -> next_line ) ?
948956 prev -> next_line : NULL ;
949957 if (cur && !hm -> cmpfn (o , cur , match , NULL )) {
950- pmb [i ] = cur ;
958+ pmb [i ]. match = cur ;
951959 } else {
952- pmb [i ] = NULL ;
960+ pmb [i ]. match = NULL ;
953961 }
954962 }
955963}
956964
957965static void pmb_advance_or_null_multi_match (struct diff_options * o ,
958966 struct moved_entry * match ,
959967 struct hashmap * hm ,
960- struct moved_entry * * pmb ,
968+ struct moved_block * pmb ,
961969 int pmb_nr , int n )
962970{
963971 int i ;
964972 char * got_match = xcalloc (1 , pmb_nr );
965973
966974 for (; match ; match = hashmap_get_next (hm , match )) {
967975 for (i = 0 ; i < pmb_nr ; i ++ ) {
968- struct moved_entry * prev = pmb [i ];
976+ struct moved_entry * prev = pmb [i ]. match ;
969977 struct moved_entry * cur = (prev && prev -> next_line ) ?
970978 prev -> next_line : NULL ;
971979 if (!cur )
972980 continue ;
973- if (!cmp_in_block_with_wsd (o , cur , match , pmb [i ], n ))
981+ if (!cmp_in_block_with_wsd (o , cur , match , & pmb [i ], n ))
974982 got_match [i ] |= 1 ;
975983 }
976984 }
977985
978986 for (i = 0 ; i < pmb_nr ; i ++ ) {
979987 if (got_match [i ]) {
980- /* Carry the white space delta forward */
981- pmb [i ]-> next_line -> wsd = pmb [i ]-> wsd ;
982- pmb [i ] = pmb [i ]-> next_line ;
988+ /* Advance to the next line */
989+ pmb [i ].match = pmb [i ].match -> next_line ;
983990 } else {
984- if (pmb [i ]-> wsd ) {
985- free (pmb [i ]-> wsd -> string );
986- FREE_AND_NULL (pmb [i ]-> wsd );
987- }
988- pmb [i ] = NULL ;
991+ moved_block_clear (& pmb [i ]);
989992 }
990993 }
991994}
992995
993- static int shrink_potential_moved_blocks (struct moved_entry * * pmb ,
996+ static int shrink_potential_moved_blocks (struct moved_block * pmb ,
994997 int pmb_nr )
995998{
996999 int lp , rp ;
9971000
9981001 /* Shrink the set of potential block to the remaining running */
9991002 for (lp = 0 , rp = pmb_nr - 1 ; lp <= rp ;) {
1000- while (lp < pmb_nr && pmb [lp ])
1003+ while (lp < pmb_nr && pmb [lp ]. match )
10011004 lp ++ ;
10021005 /* lp points at the first NULL now */
10031006
1004- while (rp > -1 && !pmb [rp ])
1007+ while (rp > -1 && !pmb [rp ]. match )
10051008 rp -- ;
10061009 /* rp points at the last non-NULL */
10071010
10081011 if (lp < pmb_nr && rp > -1 && lp < rp ) {
10091012 pmb [lp ] = pmb [rp ];
1010- pmb [rp ] = NULL ;
1013+ pmb [rp ].match = NULL ;
1014+ pmb [rp ].wsd .string = NULL ;
10111015 rp -- ;
10121016 lp ++ ;
10131017 }
@@ -1054,7 +1058,7 @@ static void mark_color_as_moved(struct diff_options *o,
10541058 struct hashmap * add_lines ,
10551059 struct hashmap * del_lines )
10561060{
1057- struct moved_entry * * pmb = NULL ; /* potentially moved blocks */
1061+ struct moved_block * pmb = NULL ; /* potentially moved blocks */
10581062 int pmb_nr = 0 , pmb_alloc = 0 ;
10591063 int n , flipped_block = 1 , block_length = 0 ;
10601064
@@ -1083,7 +1087,11 @@ static void mark_color_as_moved(struct diff_options *o,
10831087 }
10841088
10851089 if (!match ) {
1090+ int i ;
1091+
10861092 adjust_last_block (o , n , block_length );
1093+ for (i = 0 ; i < pmb_nr ; i ++ )
1094+ moved_block_clear (& pmb [i ]);
10871095 pmb_nr = 0 ;
10881096 block_length = 0 ;
10891097 continue ;
@@ -1111,14 +1119,12 @@ static void mark_color_as_moved(struct diff_options *o,
11111119 ALLOC_GROW (pmb , pmb_nr + 1 , pmb_alloc );
11121120 if (o -> color_moved_ws_handling &
11131121 COLOR_MOVED_WS_ALLOW_INDENTATION_CHANGE ) {
1114- struct ws_delta * wsd = xmalloc (sizeof (* match -> wsd ));
1115- if (compute_ws_delta (l , match -> es , wsd )) {
1116- match -> wsd = wsd ;
1117- pmb [pmb_nr ++ ] = match ;
1118- } else
1119- free (wsd );
1122+ if (compute_ws_delta (l , match -> es ,
1123+ & pmb [pmb_nr ].wsd ))
1124+ pmb [pmb_nr ++ ].match = match ;
11201125 } else {
1121- pmb [pmb_nr ++ ] = match ;
1126+ pmb [pmb_nr ].wsd .string = NULL ;
1127+ pmb [pmb_nr ++ ].match = match ;
11221128 }
11231129 }
11241130
@@ -1135,6 +1141,8 @@ static void mark_color_as_moved(struct diff_options *o,
11351141 }
11361142 adjust_last_block (o , n , block_length );
11371143
1144+ for (n = 0 ; n < pmb_nr ; n ++ )
1145+ moved_block_clear (& pmb [n ]);
11381146 free (pmb );
11391147}
11401148
0 commit comments