Factor out the handle_conflict function, which handles a single
conflict in a path.  This is a preparation for the next step, where
this function will be re-used.  No functional changes intended.

Signed-off-by: Thomas Gummerer <t.gumme...@gmail.com>
---
 rerere.c | 143 +++++++++++++++++++++++++------------------------------
 1 file changed, 65 insertions(+), 78 deletions(-)

diff --git a/rerere.c b/rerere.c
index f3e658e374..f3cfd1c09b 100644
--- a/rerere.c
+++ b/rerere.c
@@ -302,38 +302,6 @@ static void rerere_io_putstr(const char *str, struct 
rerere_io *io)
                ferr_puts(str, io->output, &io->wrerror);
 }
 
-/*
- * Write a conflict marker to io->output (if defined).
- */
-static void rerere_io_putconflict(int ch, int size, struct rerere_io *io)
-{
-       char buf[64];
-
-       while (size) {
-               if (size <= sizeof(buf) - 2) {
-                       memset(buf, ch, size);
-                       buf[size] = '\n';
-                       buf[size + 1] = '\0';
-                       size = 0;
-               } else {
-                       int sz = sizeof(buf) - 1;
-
-                       /*
-                        * Make sure we will not write everything out
-                        * in this round by leaving at least 1 byte
-                        * for the next round, giving the next round
-                        * a chance to add the terminating LF.  Yuck.
-                        */
-                       if (size <= sz)
-                               sz -= (sz - size) + 1;
-                       memset(buf, ch, sz);
-                       buf[sz] = '\0';
-                       size -= sz;
-               }
-               rerere_io_putstr(buf, io);
-       }
-}
-
 static void rerere_io_putmem(const char *mem, size_t sz, struct rerere_io *io)
 {
        if (io->output)
@@ -384,37 +352,25 @@ static int is_cmarker(char *buf, int marker_char, int 
marker_size)
        return isspace(*buf);
 }
 
-/*
- * Read contents a file with conflicts, normalize the conflicts
- * by (1) discarding the common ancestor version in diff3-style,
- * (2) reordering our side and their side so that whichever sorts
- * alphabetically earlier comes before the other one, while
- * computing the "conflict ID", which is just an SHA-1 hash of
- * one side of the conflict, NUL, the other side of the conflict,
- * and NUL concatenated together.
- *
- * Return 1 if conflict hunks are found, 0 if there are no conflict
- * hunks and -1 if an error occured.
- */
-static int handle_path(unsigned char *sha1, struct rerere_io *io, int 
marker_size)
+static void rerere_strbuf_putconflict(struct strbuf *buf, int ch, size_t size)
+{
+       strbuf_addchars(buf, ch, size);
+       strbuf_addch(buf, '\n');
+}
+
+static int handle_conflict(struct strbuf *out, struct rerere_io *io,
+                          int marker_size, git_SHA_CTX *ctx)
 {
-       git_SHA_CTX ctx;
-       int has_conflicts = 0;
        enum {
-               RR_CONTEXT = 0, RR_SIDE_1, RR_SIDE_2, RR_ORIGINAL
-       } hunk = RR_CONTEXT;
+               RR_SIDE_1 = 0, RR_SIDE_2, RR_ORIGINAL
+       } hunk = RR_SIDE_1;
        struct strbuf one = STRBUF_INIT, two = STRBUF_INIT;
        struct strbuf buf = STRBUF_INIT;
-
-       if (sha1)
-               git_SHA1_Init(&ctx);
-
+       int has_conflicts = 1;
        while (!io->getline(&buf, io)) {
-               if (is_cmarker(buf.buf, '<', marker_size)) {
-                       if (hunk != RR_CONTEXT)
-                               goto bad;
-                       hunk = RR_SIDE_1;
-               } else if (is_cmarker(buf.buf, '|', marker_size)) {
+               if (is_cmarker(buf.buf, '<', marker_size))
+                       goto bad;
+               else if (is_cmarker(buf.buf, '|', marker_size)) {
                        if (hunk != RR_SIDE_1)
                                goto bad;
                        hunk = RR_ORIGINAL;
@@ -427,42 +383,73 @@ static int handle_path(unsigned char *sha1, struct 
rerere_io *io, int marker_siz
                                goto bad;
                        if (strbuf_cmp(&one, &two) > 0)
                                strbuf_swap(&one, &two);
-                       has_conflicts = 1;
-                       hunk = RR_CONTEXT;
-                       rerere_io_putconflict('<', marker_size, io);
-                       rerere_io_putmem(one.buf, one.len, io);
-                       rerere_io_putconflict('=', marker_size, io);
-                       rerere_io_putmem(two.buf, two.len, io);
-                       rerere_io_putconflict('>', marker_size, io);
-                       if (sha1) {
-                               git_SHA1_Update(&ctx, one.buf ? one.buf : "",
+                       rerere_strbuf_putconflict(out, '<', marker_size);
+                       strbuf_addbuf(out, &one);
+                       rerere_strbuf_putconflict(out, '=', marker_size);
+                       strbuf_addbuf(out, &two);
+                       rerere_strbuf_putconflict(out, '>', marker_size);
+                       if (ctx) {
+                               git_SHA1_Update(ctx, one.buf ? one.buf : "",
                                            one.len + 1);
-                               git_SHA1_Update(&ctx, two.buf ? two.buf : "",
+                               git_SHA1_Update(ctx, two.buf ? two.buf : "",
                                            two.len + 1);
                        }
-                       strbuf_reset(&one);
-                       strbuf_reset(&two);
+                       goto out;
                } else if (hunk == RR_SIDE_1)
                        strbuf_addbuf(&one, &buf);
                else if (hunk == RR_ORIGINAL)
                        ; /* discard */
                else if (hunk == RR_SIDE_2)
                        strbuf_addbuf(&two, &buf);
-               else
-                       rerere_io_putstr(buf.buf, io);
-               continue;
-       bad:
-               hunk = 99; /* force error exit */
-               break;
        }
+bad:
+       has_conflicts = -1;
+out:
        strbuf_release(&one);
        strbuf_release(&two);
        strbuf_release(&buf);
 
+       return has_conflicts;
+}
+
+/*
+ * Read contents a file with conflicts, normalize the conflicts
+ * by (1) discarding the common ancestor version in diff3-style,
+ * (2) reordering our side and their side so that whichever sorts
+ * alphabetically earlier comes before the other one, while
+ * computing the "conflict ID", which is just an SHA-1 hash of
+ * one side of the conflict, NUL, the other side of the conflict,
+ * and NUL concatenated together.
+ *
+ * Return 1 if conflict hunks are found, 0 if there are no conflict
+ * hunks and -1 if an error occured.
+ */
+static int handle_path(unsigned char *sha1, struct rerere_io *io, int 
marker_size)
+{
+       git_SHA_CTX ctx;
+       struct strbuf buf = STRBUF_INIT;
+       struct strbuf out = STRBUF_INIT;
+       int has_conflicts = 0;
+       if (sha1)
+               git_SHA1_Init(&ctx);
+
+       while (!io->getline(&buf, io)) {
+               if (is_cmarker(buf.buf, '<', marker_size)) {
+                       has_conflicts = handle_conflict(&out, io, marker_size,
+                                                           sha1 ? &ctx : NULL);
+                       if (has_conflicts < 0)
+                               break;
+                       rerere_io_putmem(out.buf, out.len, io);
+                       strbuf_reset(&out);
+               } else
+                       rerere_io_putstr(buf.buf, io);
+       }
+       strbuf_release(&buf);
+       strbuf_release(&out);
+
        if (sha1)
                git_SHA1_Final(sha1, &ctx);
-       if (hunk != RR_CONTEXT)
-               return -1;
+
        return has_conflicts;
 }
 
-- 
2.17.0.588.g4d217cdf8e.dirty

Reply via email to