1*59c8e88eSDag-Erling Smørgrav /* Diff output generators and invocation shims. */ 2*59c8e88eSDag-Erling Smørgrav /* 3*59c8e88eSDag-Erling Smørgrav * Copyright (c) 2020 Neels Hofmeyr <neels@hofmeyr.de> 4*59c8e88eSDag-Erling Smørgrav * 5*59c8e88eSDag-Erling Smørgrav * Permission to use, copy, modify, and distribute this software for any 6*59c8e88eSDag-Erling Smørgrav * purpose with or without fee is hereby granted, provided that the above 7*59c8e88eSDag-Erling Smørgrav * copyright notice and this permission notice appear in all copies. 8*59c8e88eSDag-Erling Smørgrav * 9*59c8e88eSDag-Erling Smørgrav * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10*59c8e88eSDag-Erling Smørgrav * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11*59c8e88eSDag-Erling Smørgrav * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12*59c8e88eSDag-Erling Smørgrav * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13*59c8e88eSDag-Erling Smørgrav * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14*59c8e88eSDag-Erling Smørgrav * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15*59c8e88eSDag-Erling Smørgrav * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16*59c8e88eSDag-Erling Smørgrav */ 17*59c8e88eSDag-Erling Smørgrav 18*59c8e88eSDag-Erling Smørgrav struct diff_input_info { 19*59c8e88eSDag-Erling Smørgrav const char *left_path; 20*59c8e88eSDag-Erling Smørgrav const char *right_path; 21*59c8e88eSDag-Erling Smørgrav 22*59c8e88eSDag-Erling Smørgrav /* Set by caller of diff_output_* functions. */ 23*59c8e88eSDag-Erling Smørgrav int flags; 24*59c8e88eSDag-Erling Smørgrav #define DIFF_INPUT_LEFT_NONEXISTENT 0x00000001 25*59c8e88eSDag-Erling Smørgrav #define DIFF_INPUT_RIGHT_NONEXISTENT 0x00000002 26*59c8e88eSDag-Erling Smørgrav }; 27*59c8e88eSDag-Erling Smørgrav 28*59c8e88eSDag-Erling Smørgrav struct diff_output_info { 29*59c8e88eSDag-Erling Smørgrav /* 30*59c8e88eSDag-Erling Smørgrav * Byte offset to each line in the generated output file. 31*59c8e88eSDag-Erling Smørgrav * The total number of lines in the file is line_offsets.len - 1. 32*59c8e88eSDag-Erling Smørgrav * The last offset in this array corresponds to end-of-file. 33*59c8e88eSDag-Erling Smørgrav */ 34*59c8e88eSDag-Erling Smørgrav ARRAYLIST(off_t) line_offsets; 35*59c8e88eSDag-Erling Smørgrav /* 36*59c8e88eSDag-Erling Smørgrav * Type (i.e., context, minus, plus) of each line generated by the diff. 37*59c8e88eSDag-Erling Smørgrav * nb. 0x00 to 0x3b reserved for client-defined line types. 38*59c8e88eSDag-Erling Smørgrav */ 39*59c8e88eSDag-Erling Smørgrav ARRAYLIST(uint8_t) line_types; 40*59c8e88eSDag-Erling Smørgrav #define DIFF_LINE_HUNK 0x3c 41*59c8e88eSDag-Erling Smørgrav #define DIFF_LINE_MINUS 0x3d 42*59c8e88eSDag-Erling Smørgrav #define DIFF_LINE_PLUS 0x3e 43*59c8e88eSDag-Erling Smørgrav #define DIFF_LINE_CONTEXT 0x3f 44*59c8e88eSDag-Erling Smørgrav #define DIFF_LINE_NONE 0x40 /* binary or no EOF newline msg, etc. */ 45*59c8e88eSDag-Erling Smørgrav }; 46*59c8e88eSDag-Erling Smørgrav 47*59c8e88eSDag-Erling Smørgrav void diff_output_info_free(struct diff_output_info *output_info); 48*59c8e88eSDag-Erling Smørgrav 49*59c8e88eSDag-Erling Smørgrav struct diff_chunk_context { 50*59c8e88eSDag-Erling Smørgrav struct diff_range chunk; 51*59c8e88eSDag-Erling Smørgrav struct diff_range left, right; 52*59c8e88eSDag-Erling Smørgrav }; 53*59c8e88eSDag-Erling Smørgrav 54*59c8e88eSDag-Erling Smørgrav int diff_output_plain(struct diff_output_info **output_info, FILE *dest, 55*59c8e88eSDag-Erling Smørgrav const struct diff_input_info *info, 56*59c8e88eSDag-Erling Smørgrav const struct diff_result *result, 57*59c8e88eSDag-Erling Smørgrav int hunk_headers_only); 58*59c8e88eSDag-Erling Smørgrav int diff_output_unidiff(struct diff_output_info **output_info, 59*59c8e88eSDag-Erling Smørgrav FILE *dest, const struct diff_input_info *info, 60*59c8e88eSDag-Erling Smørgrav const struct diff_result *result, 61*59c8e88eSDag-Erling Smørgrav unsigned int context_lines); 62*59c8e88eSDag-Erling Smørgrav int diff_output_edscript(struct diff_output_info **output_info, 63*59c8e88eSDag-Erling Smørgrav FILE *dest, const struct diff_input_info *info, 64*59c8e88eSDag-Erling Smørgrav const struct diff_result *result); 65*59c8e88eSDag-Erling Smørgrav int diff_chunk_get_left_start(const struct diff_chunk *c, 66*59c8e88eSDag-Erling Smørgrav const struct diff_result *r, 67*59c8e88eSDag-Erling Smørgrav int context_lines); 68*59c8e88eSDag-Erling Smørgrav int diff_chunk_get_left_end(const struct diff_chunk *c, 69*59c8e88eSDag-Erling Smørgrav const struct diff_result *r, 70*59c8e88eSDag-Erling Smørgrav int context_lines); 71*59c8e88eSDag-Erling Smørgrav int diff_chunk_get_right_start(const struct diff_chunk *c, 72*59c8e88eSDag-Erling Smørgrav const struct diff_result *r, 73*59c8e88eSDag-Erling Smørgrav int context_lines); 74*59c8e88eSDag-Erling Smørgrav int diff_chunk_get_right_end(const struct diff_chunk *c, 75*59c8e88eSDag-Erling Smørgrav const struct diff_result *r, 76*59c8e88eSDag-Erling Smørgrav int context_lines); 77*59c8e88eSDag-Erling Smørgrav off_t diff_chunk_get_left_start_pos(const struct diff_chunk *c); 78*59c8e88eSDag-Erling Smørgrav off_t diff_chunk_get_right_start_pos(const struct diff_chunk *c); 79*59c8e88eSDag-Erling Smørgrav struct diff_chunk *diff_chunk_get(const struct diff_result *r, int chunk_idx); 80*59c8e88eSDag-Erling Smørgrav int diff_chunk_get_left_count(struct diff_chunk *c); 81*59c8e88eSDag-Erling Smørgrav int diff_chunk_get_right_count(struct diff_chunk *c); 82*59c8e88eSDag-Erling Smørgrav void diff_chunk_context_get(struct diff_chunk_context *cc, 83*59c8e88eSDag-Erling Smørgrav const struct diff_result *r, 84*59c8e88eSDag-Erling Smørgrav int chunk_idx, int context_lines); 85*59c8e88eSDag-Erling Smørgrav void diff_chunk_context_load_change(struct diff_chunk_context *cc, 86*59c8e88eSDag-Erling Smørgrav int *nchunks_used, 87*59c8e88eSDag-Erling Smørgrav struct diff_result *result, 88*59c8e88eSDag-Erling Smørgrav int start_chunk_idx, 89*59c8e88eSDag-Erling Smørgrav int context_lines); 90*59c8e88eSDag-Erling Smørgrav 91*59c8e88eSDag-Erling Smørgrav struct diff_output_unidiff_state; 92*59c8e88eSDag-Erling Smørgrav struct diff_output_unidiff_state *diff_output_unidiff_state_alloc(void); 93*59c8e88eSDag-Erling Smørgrav void diff_output_unidiff_state_reset(struct diff_output_unidiff_state *state); 94*59c8e88eSDag-Erling Smørgrav void diff_output_unidiff_state_free(struct diff_output_unidiff_state *state); 95*59c8e88eSDag-Erling Smørgrav int diff_output_unidiff_chunk(struct diff_output_info **output_info, FILE *dest, 96*59c8e88eSDag-Erling Smørgrav struct diff_output_unidiff_state *state, 97*59c8e88eSDag-Erling Smørgrav const struct diff_input_info *info, 98*59c8e88eSDag-Erling Smørgrav const struct diff_result *result, 99*59c8e88eSDag-Erling Smørgrav const struct diff_chunk_context *cc); 100*59c8e88eSDag-Erling Smørgrav int diff_output_chunk_left_version(struct diff_output_info **output_info, 101*59c8e88eSDag-Erling Smørgrav FILE *dest, 102*59c8e88eSDag-Erling Smørgrav const struct diff_input_info *info, 103*59c8e88eSDag-Erling Smørgrav const struct diff_result *result, 104*59c8e88eSDag-Erling Smørgrav const struct diff_chunk_context *cc); 105*59c8e88eSDag-Erling Smørgrav int diff_output_chunk_right_version(struct diff_output_info **output_info, 106*59c8e88eSDag-Erling Smørgrav FILE *dest, 107*59c8e88eSDag-Erling Smørgrav const struct diff_input_info *info, 108*59c8e88eSDag-Erling Smørgrav const struct diff_result *result, 109*59c8e88eSDag-Erling Smørgrav const struct diff_chunk_context *cc); 110*59c8e88eSDag-Erling Smørgrav 111*59c8e88eSDag-Erling Smørgrav const char *diff_output_get_label_left(const struct diff_input_info *info); 112*59c8e88eSDag-Erling Smørgrav const char *diff_output_get_label_right(const struct diff_input_info *info); 113