]> git.ipfire.org Git - thirdparty/git.git/blobdiff - xdiff/xpatience.c
Merge branch 'rs/archive-dedup-printf' into maint-2.38
[thirdparty/git.git] / xdiff / xpatience.c
index c5d48e80aefb33eddb4dbe4e359f2c598a5483d7..a2d8955537f566458b6e912ff5fb8496fa7fe85a 100644 (file)
@@ -69,7 +69,6 @@ struct hashmap {
        } *entries, *first, *last;
        /* were common records found? */
        unsigned long has_matches;
-       mmfile_t *file1, *file2;
        xdfenv_t *env;
        xpparam_t const *xpp;
 };
@@ -139,23 +138,17 @@ static void insert_record(xpparam_t const *xpp, int line, struct hashmap *map,
  *
  * It is assumed that env has been prepared using xdl_prepare().
  */
-static int fill_hashmap(mmfile_t *file1, mmfile_t *file2,
-               xpparam_t const *xpp, xdfenv_t *env,
+static int fill_hashmap(xpparam_t const *xpp, xdfenv_t *env,
                struct hashmap *result,
                int line1, int count1, int line2, int count2)
 {
-       result->file1 = file1;
-       result->file2 = file2;
        result->xpp = xpp;
        result->env = env;
 
        /* We know exactly how large we want the hash map */
        result->alloc = count1 * 2;
-       result->entries = (struct entry *)
-               xdl_malloc(result->alloc * sizeof(struct entry));
-       if (!result->entries)
+       if (!XDL_CALLOC_ARRAY(result->entries, result->alloc))
                return -1;
-       memset(result->entries, 0, result->alloc * sizeof(struct entry));
 
        /* First, fill with entries from the first file */
        while (count1--)
@@ -198,9 +191,9 @@ static int binary_search(struct entry **sequence, int longest,
  * item per sequence length: the sequence with the smallest last
  * element (in terms of line2).
  */
-static struct entry *find_longest_common_sequence(struct hashmap *map)
+static int find_longest_common_sequence(struct hashmap *map, struct entry **res)
 {
-       struct entry **sequence = xdl_malloc(map->nr * sizeof(struct entry *));
+       struct entry **sequence;
        int longest = 0, i;
        struct entry *entry;
 
@@ -211,6 +204,9 @@ static struct entry *find_longest_common_sequence(struct hashmap *map)
         */
        int anchor_i = -1;
 
+       if (!XDL_ALLOC_ARRAY(sequence, map->nr))
+               return -1;
+
        for (entry = map->first; entry; entry = entry->next) {
                if (!entry->line2 || entry->line2 == NON_UNIQUE)
                        continue;
@@ -230,8 +226,9 @@ static struct entry *find_longest_common_sequence(struct hashmap *map)
 
        /* No common unique lines were found */
        if (!longest) {
+               *res = NULL;
                xdl_free(sequence);
-               return NULL;
+               return 0;
        }
 
        /* Iterate starting at the last element, adjusting the "next" members */
@@ -241,8 +238,9 @@ static struct entry *find_longest_common_sequence(struct hashmap *map)
                entry->previous->next = entry;
                entry = entry->previous;
        }
+       *res = entry;
        xdl_free(sequence);
-       return entry;
+       return 0;
 }
 
 static int match(struct hashmap *map, int line1, int line2)
@@ -252,8 +250,7 @@ static int match(struct hashmap *map, int line1, int line2)
        return record1->ha == record2->ha;
 }
 
-static int patience_diff(mmfile_t *file1, mmfile_t *file2,
-               xpparam_t const *xpp, xdfenv_t *env,
+static int patience_diff(xpparam_t const *xpp, xdfenv_t *env,
                int line1, int count1, int line2, int count2);
 
 static int walk_common_sequence(struct hashmap *map, struct entry *first,
@@ -284,8 +281,7 @@ static int walk_common_sequence(struct hashmap *map, struct entry *first,
 
                /* Recurse */
                if (next1 > line1 || next2 > line2) {
-                       if (patience_diff(map->file1, map->file2,
-                                       map->xpp, map->env,
+                       if (patience_diff(map->xpp, map->env,
                                        line1, next1 - line1,
                                        line2, next2 - line2))
                                return -1;
@@ -324,8 +320,7 @@ static int fall_back_to_classic_diff(struct hashmap *map,
  *
  * This function assumes that env was prepared with xdl_prepare_env().
  */
-static int patience_diff(mmfile_t *file1, mmfile_t *file2,
-               xpparam_t const *xpp, xdfenv_t *env,
+static int patience_diff(xpparam_t const *xpp, xdfenv_t *env,
                int line1, int count1, int line2, int count2)
 {
        struct hashmap map;
@@ -344,7 +339,7 @@ static int patience_diff(mmfile_t *file1, mmfile_t *file2,
        }
 
        memset(&map, 0, sizeof(map));
-       if (fill_hashmap(file1, file2, xpp, env, &map,
+       if (fill_hashmap(xpp, env, &map,
                        line1, count1, line2, count2))
                return -1;
 
@@ -358,25 +353,21 @@ static int patience_diff(mmfile_t *file1, mmfile_t *file2,
                return 0;
        }
 
-       first = find_longest_common_sequence(&map);
+       result = find_longest_common_sequence(&map, &first);
+       if (result)
+               goto out;
        if (first)
                result = walk_common_sequence(&map, first,
                        line1, count1, line2, count2);
        else
                result = fall_back_to_classic_diff(&map,
                        line1, count1, line2, count2);
-
+ out:
        xdl_free(map.entries);
        return result;
 }
 
-int xdl_do_patience_diff(mmfile_t *file1, mmfile_t *file2,
-               xpparam_t const *xpp, xdfenv_t *env)
+int xdl_do_patience_diff(xpparam_t const *xpp, xdfenv_t *env)
 {
-       if (xdl_prepare_env(file1, file2, xpp, env) < 0)
-               return -1;
-
-       /* environment is cleaned up in xdl_diff() */
-       return patience_diff(file1, file2, xpp, env,
-                       1, env->xdf1.nrec, 1, env->xdf2.nrec);
+       return patience_diff(xpp, env, 1, env->xdf1.nrec, 1, env->xdf2.nrec);
 }