commit 7187fe972091ffb934d90ab11967d006868f8d7c from: Stefan Sperling date: Sat Oct 17 00:26:51 2020 UTC add diff_chunk_context_load_change() for use with diff_output_unidiff_chunk() commit - 2f26640c77e9b4d1a303b6c3c7776ff75ad51111 commit + 7187fe972091ffb934d90ab11967d006868f8d7c blob - eb5ea9058a20bee4cbe0ab59e51b057ac8067878 blob + 0fa63c3ef700e304d4e3c5950765ea9afd5d8a58 --- include/diff_output.h +++ include/diff_output.h @@ -61,6 +61,12 @@ int diff_chunk_get_right_end(const struct diff_chunk * void diff_chunk_context_get(struct diff_chunk_context *cc, const struct diff_result *r, int chunk_idx, int context_lines); +void diff_chunk_context_load_change(struct diff_chunk_context *cc, + int *nchunks_used, + struct diff_result *result, + int start_chunk_idx, + int context_lines); + struct diff_output_unidiff_state; struct diff_output_unidiff_state *diff_output_unidiff_state_alloc(void); void diff_output_unidiff_state_reset(struct diff_output_unidiff_state *state); blob - 92805f9927a54bfd10e75d1fa3b36915ff80bd93 blob + a0dba87608e0c39d9e91584b1864e08f921d39d3 --- lib/diff_output_unidiff.c +++ lib/diff_output_unidiff.c @@ -110,6 +110,62 @@ diff_chunk_contexts_merge(struct diff_chunk_context *c diff_ranges_merge(&cc->chunk, &other->chunk); diff_ranges_merge(&cc->left, &other->left); diff_ranges_merge(&cc->right, &other->right); +} + +void +diff_chunk_context_load_change(struct diff_chunk_context *cc, + int *nchunks_used, + struct diff_result *result, + int start_chunk_idx, + int context_lines) +{ + int i; + int seen_minus = 0, seen_plus = 0; + + if (nchunks_used) + *nchunks_used = 0; + + for (i = start_chunk_idx; 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 next; + + if (t != CHUNK_MINUS && t != CHUNK_PLUS) { + if (nchunks_used) + (*nchunks_used)++; + if (seen_minus && seen_plus) + break; + else + continue; + } else if (t == CHUNK_MINUS) + seen_minus = 1; + else if (t == CHUNK_PLUS) + seen_plus = 1; + + if (diff_chunk_context_empty(cc)) { + /* 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, context_lines); + if (nchunks_used) + (*nchunks_used)++; + continue; + } + + /* 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, context_lines); + + if (diff_chunk_contexts_touch(cc, &next)) { + /* This next context touches or overlaps the previous + * one, join. */ + diff_chunk_contexts_merge(cc, &next); + if (nchunks_used) + (*nchunks_used)++; + continue; + } else + break; + } } struct diff_output_unidiff_state {