commit - 227cd87e537c560f428629cf170b0f19422b1c56
commit + 26595c7df947f97507904fa391034b6a52bfca7d
blob - 5c8fd1fc7ae45e166e7af7a09a3e9b4cfa0f47b9
blob + 0450a007a948e500aa26ebd54a8aa533da5bbd63
--- lib/diff_internal.h
+++ lib/diff_internal.h
return CHUNK_SAME;
}
+struct diff_chunk_context;
+
+bool
+diff_chunk_contexts_touch(const struct diff_chunk_context *cc,
+ const struct diff_chunk_context *other);
+
+void
+diff_chunk_contexts_merge(struct diff_chunk_context *cc,
+ const struct diff_chunk_context *other);
+
struct diff_state {
/* The final result passed to the original diff caller. */
struct diff_result *result;
blob - 65ef9ad4da6435426210a1e93aeda9c7e57539c3
blob + 38053a9163403e9b1871f8d864aec3d3d8460956
--- lib/diff_output_edscript.c
+++ lib/diff_output_edscript.c
output_edscript_chunk(struct diff_output_info *outinfo,
FILE *dest, const struct diff_input_info *info,
const struct diff_result *result,
- struct diff_chunk_context *cc, enum diff_chunk_type chunk_type)
+ struct diff_chunk_context *cc)
{
off_t outoff = 0, *offp;
int left_start, left_len, right_start, right_len;
else
right_start = cc->right.start + 1;
- if (chunk_type == CHUNK_MINUS) {
+ if (left_len == 0) {
+ /* addition */
+ if (right_len == 1) {
+ rc = fprintf(dest, "%da%d\n", left_start, right_start);
+ } else {
+ rc = fprintf(dest, "%da%d,%d\n", left_start,
+ right_start, cc->right.end);
+ }
+ } else if (right_len == 0) {
+ /* deletion */
if (left_len == 1) {
- rc = fprintf(dest, "%dd%d\n", left_start, right_start);
+ rc = fprintf(dest, "%dd%d\n", left_start,
+ right_start);
} else {
rc = fprintf(dest, "%d,%dd%d\n", left_start,
cc->left.end, right_start);
}
- } else if (chunk_type == CHUNK_PLUS) {
- if (right_len == 1) {
- rc = fprintf(dest, "%da%d\n", left_start, right_start);
- } else {
- rc = fprintf(dest, "%da%d,%d\n", left_start,
+ } else {
+ /* change */
+ if (left_len == 1 && right_len == 1) {
+ rc = fprintf(dest, "%dc%d\n", left_start, right_start);
+ } else if (left_len == 1) {
+ rc = fprintf(dest, "%dc%d,%d\n", left_start,
right_start, cc->right.end);
+ } else if (right_len == 1) {
+ rc = fprintf(dest, "%d,%dc%d\n", left_start,
+ cc->left.end, right_start);
+ } else {
+ rc = fprintf(dest, "%d,%dc%d,%d\n", left_start,
+ cc->left.end, right_start, cc->right.end);
}
- } else
- return EINVAL;
-
+ }
if (rc < 0)
return errno;
if (outinfo) {
const struct diff_result *result)
{
struct diff_output_info *outinfo = NULL;
+ struct diff_chunk_context cc = {};
int i, rc;
if (!result)
for (i = 0; i < result->chunks.len; i++) {
struct diff_chunk *chunk = &result->chunks.head[i];
enum diff_chunk_type t = diff_chunk_type(chunk);
- struct diff_chunk_context cc = {};
+ struct diff_chunk_context next;
if (t != CHUNK_MINUS && t != CHUNK_PLUS)
continue;
- diff_chunk_context_get(&cc, result, i, 0);
+ if (diff_range_empty(&cc.chunk)) {
+ /* Note down the start point, any number of subsequent
+ * chunks may be joined up to this chunk by being
+ * directly adjacent. */
+ diff_chunk_context_get(&cc, result, i, 0);
+ continue;
+ }
- if (diff_range_empty(&cc.chunk))
+ /* There already is a previous chunk noted down for being
+ * printed. Does it join up with this one? */
+ diff_chunk_context_get(&next, result, i, 0);
+
+ if (diff_chunk_contexts_touch(&cc, &next)) {
+ /* This next context touches or overlaps the previous
+ * one, join. */
+ diff_chunk_contexts_merge(&cc, &next);
continue;
+ }
- rc = output_edscript_chunk(outinfo, dest, info, result, &cc, t);
+ rc = output_edscript_chunk(outinfo, dest, info, result, &cc);
if (rc != DIFF_RC_OK)
return rc;
+ cc = next;
}
+ if (!diff_range_empty(&cc.chunk))
+ return output_edscript_chunk(outinfo, dest, info, result, &cc);
return DIFF_RC_OK;
}
blob - d4dfc359e4f14a7a3d3593b4b5d252865abd5e57
blob + eaea44c1044a8f6ee273c5559c2945e50f2475c9
--- lib/diff_output_unidiff.c
+++ lib/diff_output_unidiff.c
};
}
-static bool
-chunk_contexts_touch(const struct diff_chunk_context *cc,
- const struct diff_chunk_context *other)
+bool
+diff_chunk_contexts_touch(const struct diff_chunk_context *cc,
+ const struct diff_chunk_context *other)
{
return diff_ranges_touch(&cc->chunk, &other->chunk)
|| diff_ranges_touch(&cc->left, &other->left)
|| diff_ranges_touch(&cc->right, &other->right);
}
-static void
-chunk_contexts_merge(struct diff_chunk_context *cc,
- const struct diff_chunk_context *other)
+void
+diff_chunk_contexts_merge(struct diff_chunk_context *cc,
+ const struct diff_chunk_context *other)
{
diff_ranges_merge(&cc->chunk, &other->chunk);
diff_ranges_merge(&cc->left, &other->left);
next.left.start, next.left.end,
next.right.start, next.right.end);
- if (chunk_contexts_touch(&cc, &next)) {
+ if (diff_chunk_contexts_touch(&cc, &next)) {
/* This next context touches or overlaps the previous
* one, join. */
- chunk_contexts_merge(&cc, &next);
+ diff_chunk_contexts_merge(&cc, &next);
debug("new chunk to be printed touches previous chunk,"
" now: left %d-%d right %d-%d\n",
cc.left.start, cc.left.end,