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