776
struct hashmap_entry ent;
777
const struct emitted_diff_symbol *es;
778
struct moved_entry *next_line;
779
- struct ws_delta *wsd;
779
};
780
781
/**
792
};
793
#define WS_DELTA_INIT { NULL, 0 }
794
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
+
806
static int compute_ws_delta(const struct emitted_diff_symbol *a,
807
const struct emitted_diff_symbol *b,
808
struct ws_delta *out)
820
static int cmp_in_block_with_wsd(const struct diff_options *o,
821
const struct moved_entry *cur,
822
const struct moved_entry *match,
813
- struct moved_entry *pmb,
823
+ struct moved_block *pmb,
824
int n)
825
{
826
struct emitted_diff_symbol *l = &o->emitted_symbols->buf[n];
840
if (strcmp(a, b))
841
return 1;
842
833
- if (!pmb->wsd)
843
+ if (!pmb->wsd.string)
844
/*
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.
847
*/
848
return 1;
849
850
/*
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
852
* pmb->wsd; however we need to check if the indent changes of the
853
* current line are still the same as before.
854
*
856
* one of them for the white spaces, depending which was longer.
857
*/
858
850
- wslen = strlen(pmb->wsd->string);
851
- if (pmb->wsd->current_longer) {
859
+ wslen = strlen(pmb->wsd.string);
860
+ if (pmb->wsd.current_longer) {
861
c += wslen;
862
cl -= wslen;
863
} else {
907
ret->ent.hash = xdiff_hash_string(l->line, l->len, flags);
908
ret->es = l;
909
ret->next_line = NULL;
901
- ret->wsd = NULL;
910
911
return ret;
912
}
946
static void pmb_advance_or_null(struct diff_options *o,
947
struct moved_entry *match,
948
struct hashmap *hm,
941
- struct moved_entry **pmb,
949
+ struct moved_block *pmb,
950
int pmb_nr)
951
{
952
int i;
953
for (i = 0; i < pmb_nr; i++) {
946
- struct moved_entry *prev = pmb[i];
954
+ struct moved_entry *prev = pmb[i].match;
955
struct moved_entry *cur = (prev && prev->next_line) ?
956
prev->next_line : NULL;
957
if (cur && !hm->cmpfn(o, cur, match, NULL)) {
950
- pmb[i] = cur;
958
+ pmb[i].match = cur;
959
} else {
952
- pmb[i] = NULL;
960
+ pmb[i].match = NULL;
961
}
962
}
963
}
965
static void pmb_advance_or_null_multi_match(struct diff_options *o,
966
struct moved_entry *match,
967
struct hashmap *hm,
960
- struct moved_entry **pmb,
968
+ struct moved_block *pmb,
969
int pmb_nr, int n)
970
{
971
int i;
973
974
for (; match; match = hashmap_get_next(hm, match)) {
975
for (i = 0; i < pmb_nr; i++) {
968
- struct moved_entry *prev = pmb[i];
976
+ struct moved_entry *prev = pmb[i].match;
977
struct moved_entry *cur = (prev && prev->next_line) ?
978
prev->next_line : NULL;
979
if (!cur)
980
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))
982
got_match[i] |= 1;
983
}
984
}
985
986
for (i = 0; i < pmb_nr; i++) {
987
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;
990
} 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]);
992
}
993
}
994
}
995
993
-static int shrink_potential_moved_blocks(struct moved_entry **pmb,
996
+static int shrink_potential_moved_blocks(struct moved_block *pmb,
997
int pmb_nr)
998
{
999
int lp, rp;
1000
1001
/* Shrink the set of potential block to the remaining running */
1002
for (lp = 0, rp = pmb_nr - 1; lp <= rp;) {
1000
- while (lp < pmb_nr && pmb[lp])
1003
+ while (lp < pmb_nr && pmb[lp].match)
1004
lp++;
1005
/* lp points at the first NULL now */
1006
1004
- while (rp > -1 && !pmb[rp])
1007
+ while (rp > -1 && !pmb[rp].match)
1008
rp--;
1009
/* rp points at the last non-NULL */
1010
1011
if (lp < pmb_nr && rp > -1 && lp < rp) {
1012
pmb[lp] = pmb[rp];
1010
- pmb[rp] = NULL;
1013
+ pmb[rp].match = NULL;
1014
+ pmb[rp].wsd.string = NULL;
1015
rp--;
1016
lp++;
1017
}
1058
struct hashmap *add_lines,
1059
struct hashmap *del_lines)
1060
{
1057
- struct moved_entry **pmb = NULL; /* potentially moved blocks */
1061
+ struct moved_block *pmb = NULL; /* potentially moved blocks */
1062
int pmb_nr = 0, pmb_alloc = 0;
1063
int n, flipped_block = 1, block_length = 0;
1064
1087
}
1088
1089
if (!match) {
1090
+ int i;
1091
+
1092
adjust_last_block(o, n, block_length);
1093
+ for(i = 0; i < pmb_nr; i++)
1094
+ moved_block_clear(&pmb[i]);
1095
pmb_nr = 0;
1096
block_length = 0;
1097
continue;
1119
ALLOC_GROW(pmb, pmb_nr + 1, pmb_alloc);
1120
if (o->color_moved_ws_handling &
1121
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;
1125
} else {
1121
- pmb[pmb_nr++] = match;
1126
+ pmb[pmb_nr].wsd.string = NULL;
1127
+ pmb[pmb_nr++].match = match;
1128
}
1129
}
1130
1141
}
1142
adjust_last_block(o, n, block_length);
1143
1144
+ for(n = 0; n < pmb_nr; n++)
1145
+ moved_block_clear(&pmb[n]);
1146
free(pmb);
1147
}
1148