1*59c8e88eSDag-Erling Smørgrav /* Common parts for printing diff output */ 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 #include <ctype.h> 19*59c8e88eSDag-Erling Smørgrav #include <errno.h> 20*59c8e88eSDag-Erling Smørgrav #include <stdbool.h> 21*59c8e88eSDag-Erling Smørgrav #include <stdint.h> 22*59c8e88eSDag-Erling Smørgrav #include <stdio.h> 23*59c8e88eSDag-Erling Smørgrav #include <stdlib.h> 24*59c8e88eSDag-Erling Smørgrav #include <string.h> 25*59c8e88eSDag-Erling Smørgrav #include <unistd.h> 26*59c8e88eSDag-Erling Smørgrav 27*59c8e88eSDag-Erling Smørgrav #include <arraylist.h> 28*59c8e88eSDag-Erling Smørgrav #include <diff_main.h> 29*59c8e88eSDag-Erling Smørgrav #include <diff_output.h> 30*59c8e88eSDag-Erling Smørgrav 31*59c8e88eSDag-Erling Smørgrav #include "diff_internal.h" 32*59c8e88eSDag-Erling Smørgrav 33*59c8e88eSDag-Erling Smørgrav static int 34*59c8e88eSDag-Erling Smørgrav get_atom_byte(int *ch, struct diff_atom *atom, off_t off) 35*59c8e88eSDag-Erling Smørgrav { 36*59c8e88eSDag-Erling Smørgrav off_t cur; 37*59c8e88eSDag-Erling Smørgrav 38*59c8e88eSDag-Erling Smørgrav if (atom->at != NULL) { 39*59c8e88eSDag-Erling Smørgrav *ch = atom->at[off]; 40*59c8e88eSDag-Erling Smørgrav return 0; 41*59c8e88eSDag-Erling Smørgrav } 42*59c8e88eSDag-Erling Smørgrav 43*59c8e88eSDag-Erling Smørgrav cur = ftello(atom->root->f); 44*59c8e88eSDag-Erling Smørgrav if (cur == -1) 45*59c8e88eSDag-Erling Smørgrav return errno; 46*59c8e88eSDag-Erling Smørgrav 47*59c8e88eSDag-Erling Smørgrav if (cur != atom->pos + off && 48*59c8e88eSDag-Erling Smørgrav fseeko(atom->root->f, atom->pos + off, SEEK_SET) == -1) 49*59c8e88eSDag-Erling Smørgrav return errno; 50*59c8e88eSDag-Erling Smørgrav 51*59c8e88eSDag-Erling Smørgrav *ch = fgetc(atom->root->f); 52*59c8e88eSDag-Erling Smørgrav if (*ch == EOF && ferror(atom->root->f)) 53*59c8e88eSDag-Erling Smørgrav return errno; 54*59c8e88eSDag-Erling Smørgrav 55*59c8e88eSDag-Erling Smørgrav return 0; 56*59c8e88eSDag-Erling Smørgrav } 57*59c8e88eSDag-Erling Smørgrav 58*59c8e88eSDag-Erling Smørgrav #define DIFF_OUTPUT_BUF_SIZE 512 59*59c8e88eSDag-Erling Smørgrav 60*59c8e88eSDag-Erling Smørgrav int 61*59c8e88eSDag-Erling Smørgrav diff_output_lines(struct diff_output_info *outinfo, FILE *dest, 62*59c8e88eSDag-Erling Smørgrav const char *prefix, struct diff_atom *start_atom, 63*59c8e88eSDag-Erling Smørgrav unsigned int count) 64*59c8e88eSDag-Erling Smørgrav { 65*59c8e88eSDag-Erling Smørgrav struct diff_atom *atom; 66*59c8e88eSDag-Erling Smørgrav off_t outoff = 0, *offp; 67*59c8e88eSDag-Erling Smørgrav uint8_t *typep; 68*59c8e88eSDag-Erling Smørgrav int rc; 69*59c8e88eSDag-Erling Smørgrav 70*59c8e88eSDag-Erling Smørgrav if (outinfo && outinfo->line_offsets.len > 0) { 71*59c8e88eSDag-Erling Smørgrav unsigned int idx = outinfo->line_offsets.len - 1; 72*59c8e88eSDag-Erling Smørgrav outoff = outinfo->line_offsets.head[idx]; 73*59c8e88eSDag-Erling Smørgrav } 74*59c8e88eSDag-Erling Smørgrav 75*59c8e88eSDag-Erling Smørgrav foreach_diff_atom(atom, start_atom, count) { 76*59c8e88eSDag-Erling Smørgrav off_t outlen = 0; 77*59c8e88eSDag-Erling Smørgrav int i, ch, nbuf = 0; 78*59c8e88eSDag-Erling Smørgrav unsigned int len = atom->len; 79*59c8e88eSDag-Erling Smørgrav unsigned char buf[DIFF_OUTPUT_BUF_SIZE + 1 /* '\n' */]; 80*59c8e88eSDag-Erling Smørgrav size_t n; 81*59c8e88eSDag-Erling Smørgrav 82*59c8e88eSDag-Erling Smørgrav n = strlcpy(buf, prefix, sizeof(buf)); 83*59c8e88eSDag-Erling Smørgrav if (n >= DIFF_OUTPUT_BUF_SIZE) /* leave room for '\n' */ 84*59c8e88eSDag-Erling Smørgrav return ENOBUFS; 85*59c8e88eSDag-Erling Smørgrav nbuf += n; 86*59c8e88eSDag-Erling Smørgrav 87*59c8e88eSDag-Erling Smørgrav if (len) { 88*59c8e88eSDag-Erling Smørgrav rc = get_atom_byte(&ch, atom, len - 1); 89*59c8e88eSDag-Erling Smørgrav if (rc) 90*59c8e88eSDag-Erling Smørgrav return rc; 91*59c8e88eSDag-Erling Smørgrav if (ch == '\n') 92*59c8e88eSDag-Erling Smørgrav len--; 93*59c8e88eSDag-Erling Smørgrav } 94*59c8e88eSDag-Erling Smørgrav 95*59c8e88eSDag-Erling Smørgrav for (i = 0; i < len; i++) { 96*59c8e88eSDag-Erling Smørgrav rc = get_atom_byte(&ch, atom, i); 97*59c8e88eSDag-Erling Smørgrav if (rc) 98*59c8e88eSDag-Erling Smørgrav return rc; 99*59c8e88eSDag-Erling Smørgrav if (nbuf >= DIFF_OUTPUT_BUF_SIZE) { 100*59c8e88eSDag-Erling Smørgrav rc = fwrite(buf, 1, nbuf, dest); 101*59c8e88eSDag-Erling Smørgrav if (rc != nbuf) 102*59c8e88eSDag-Erling Smørgrav return errno; 103*59c8e88eSDag-Erling Smørgrav outlen += rc; 104*59c8e88eSDag-Erling Smørgrav nbuf = 0; 105*59c8e88eSDag-Erling Smørgrav } 106*59c8e88eSDag-Erling Smørgrav buf[nbuf++] = ch; 107*59c8e88eSDag-Erling Smørgrav } 108*59c8e88eSDag-Erling Smørgrav buf[nbuf++] = '\n'; 109*59c8e88eSDag-Erling Smørgrav rc = fwrite(buf, 1, nbuf, dest); 110*59c8e88eSDag-Erling Smørgrav if (rc != nbuf) 111*59c8e88eSDag-Erling Smørgrav return errno; 112*59c8e88eSDag-Erling Smørgrav outlen += rc; 113*59c8e88eSDag-Erling Smørgrav if (outinfo) { 114*59c8e88eSDag-Erling Smørgrav ARRAYLIST_ADD(offp, outinfo->line_offsets); 115*59c8e88eSDag-Erling Smørgrav if (offp == NULL) 116*59c8e88eSDag-Erling Smørgrav return ENOMEM; 117*59c8e88eSDag-Erling Smørgrav outoff += outlen; 118*59c8e88eSDag-Erling Smørgrav *offp = outoff; 119*59c8e88eSDag-Erling Smørgrav ARRAYLIST_ADD(typep, outinfo->line_types); 120*59c8e88eSDag-Erling Smørgrav if (typep == NULL) 121*59c8e88eSDag-Erling Smørgrav return ENOMEM; 122*59c8e88eSDag-Erling Smørgrav *typep = *prefix == ' ' ? DIFF_LINE_CONTEXT : 123*59c8e88eSDag-Erling Smørgrav *prefix == '-' ? DIFF_LINE_MINUS : 124*59c8e88eSDag-Erling Smørgrav *prefix == '+' ? DIFF_LINE_PLUS : DIFF_LINE_NONE; 125*59c8e88eSDag-Erling Smørgrav } 126*59c8e88eSDag-Erling Smørgrav } 127*59c8e88eSDag-Erling Smørgrav 128*59c8e88eSDag-Erling Smørgrav return DIFF_RC_OK; 129*59c8e88eSDag-Erling Smørgrav } 130*59c8e88eSDag-Erling Smørgrav 131*59c8e88eSDag-Erling Smørgrav int 132*59c8e88eSDag-Erling Smørgrav diff_output_chunk_left_version(struct diff_output_info **output_info, 133*59c8e88eSDag-Erling Smørgrav FILE *dest, 134*59c8e88eSDag-Erling Smørgrav const struct diff_input_info *info, 135*59c8e88eSDag-Erling Smørgrav const struct diff_result *result, 136*59c8e88eSDag-Erling Smørgrav const struct diff_chunk_context *cc) 137*59c8e88eSDag-Erling Smørgrav { 138*59c8e88eSDag-Erling Smørgrav int rc, c_idx; 139*59c8e88eSDag-Erling Smørgrav struct diff_output_info *outinfo = NULL; 140*59c8e88eSDag-Erling Smørgrav 141*59c8e88eSDag-Erling Smørgrav if (diff_range_empty(&cc->left)) 142*59c8e88eSDag-Erling Smørgrav return DIFF_RC_OK; 143*59c8e88eSDag-Erling Smørgrav 144*59c8e88eSDag-Erling Smørgrav if (output_info) { 145*59c8e88eSDag-Erling Smørgrav *output_info = diff_output_info_alloc(); 146*59c8e88eSDag-Erling Smørgrav if (*output_info == NULL) 147*59c8e88eSDag-Erling Smørgrav return ENOMEM; 148*59c8e88eSDag-Erling Smørgrav outinfo = *output_info; 149*59c8e88eSDag-Erling Smørgrav } 150*59c8e88eSDag-Erling Smørgrav 151*59c8e88eSDag-Erling Smørgrav /* Write out all chunks on the left side. */ 152*59c8e88eSDag-Erling Smørgrav for (c_idx = cc->chunk.start; c_idx < cc->chunk.end; c_idx++) { 153*59c8e88eSDag-Erling Smørgrav const struct diff_chunk *c = &result->chunks.head[c_idx]; 154*59c8e88eSDag-Erling Smørgrav 155*59c8e88eSDag-Erling Smørgrav if (c->left_count) { 156*59c8e88eSDag-Erling Smørgrav rc = diff_output_lines(outinfo, dest, "", 157*59c8e88eSDag-Erling Smørgrav c->left_start, c->left_count); 158*59c8e88eSDag-Erling Smørgrav if (rc) 159*59c8e88eSDag-Erling Smørgrav return rc; 160*59c8e88eSDag-Erling Smørgrav } 161*59c8e88eSDag-Erling Smørgrav } 162*59c8e88eSDag-Erling Smørgrav 163*59c8e88eSDag-Erling Smørgrav return DIFF_RC_OK; 164*59c8e88eSDag-Erling Smørgrav } 165*59c8e88eSDag-Erling Smørgrav 166*59c8e88eSDag-Erling Smørgrav int 167*59c8e88eSDag-Erling Smørgrav diff_output_chunk_right_version(struct diff_output_info **output_info, 168*59c8e88eSDag-Erling Smørgrav FILE *dest, 169*59c8e88eSDag-Erling Smørgrav const struct diff_input_info *info, 170*59c8e88eSDag-Erling Smørgrav const struct diff_result *result, 171*59c8e88eSDag-Erling Smørgrav const struct diff_chunk_context *cc) 172*59c8e88eSDag-Erling Smørgrav { 173*59c8e88eSDag-Erling Smørgrav int rc, c_idx; 174*59c8e88eSDag-Erling Smørgrav struct diff_output_info *outinfo = NULL; 175*59c8e88eSDag-Erling Smørgrav 176*59c8e88eSDag-Erling Smørgrav if (diff_range_empty(&cc->right)) 177*59c8e88eSDag-Erling Smørgrav return DIFF_RC_OK; 178*59c8e88eSDag-Erling Smørgrav 179*59c8e88eSDag-Erling Smørgrav if (output_info) { 180*59c8e88eSDag-Erling Smørgrav *output_info = diff_output_info_alloc(); 181*59c8e88eSDag-Erling Smørgrav if (*output_info == NULL) 182*59c8e88eSDag-Erling Smørgrav return ENOMEM; 183*59c8e88eSDag-Erling Smørgrav outinfo = *output_info; 184*59c8e88eSDag-Erling Smørgrav } 185*59c8e88eSDag-Erling Smørgrav 186*59c8e88eSDag-Erling Smørgrav /* Write out all chunks on the right side. */ 187*59c8e88eSDag-Erling Smørgrav for (c_idx = cc->chunk.start; c_idx < cc->chunk.end; c_idx++) { 188*59c8e88eSDag-Erling Smørgrav const struct diff_chunk *c = &result->chunks.head[c_idx]; 189*59c8e88eSDag-Erling Smørgrav 190*59c8e88eSDag-Erling Smørgrav if (c->right_count) { 191*59c8e88eSDag-Erling Smørgrav rc = diff_output_lines(outinfo, dest, "", c->right_start, 192*59c8e88eSDag-Erling Smørgrav c->right_count); 193*59c8e88eSDag-Erling Smørgrav if (rc) 194*59c8e88eSDag-Erling Smørgrav return rc; 195*59c8e88eSDag-Erling Smørgrav } 196*59c8e88eSDag-Erling Smørgrav } 197*59c8e88eSDag-Erling Smørgrav 198*59c8e88eSDag-Erling Smørgrav return DIFF_RC_OK; 199*59c8e88eSDag-Erling Smørgrav } 200*59c8e88eSDag-Erling Smørgrav 201*59c8e88eSDag-Erling Smørgrav int 202*59c8e88eSDag-Erling Smørgrav diff_output_trailing_newline_msg(struct diff_output_info *outinfo, FILE *dest, 203*59c8e88eSDag-Erling Smørgrav const struct diff_chunk *c) 204*59c8e88eSDag-Erling Smørgrav { 205*59c8e88eSDag-Erling Smørgrav enum diff_chunk_type chunk_type = diff_chunk_type(c); 206*59c8e88eSDag-Erling Smørgrav struct diff_atom *atom, *start_atom; 207*59c8e88eSDag-Erling Smørgrav unsigned int atom_count; 208*59c8e88eSDag-Erling Smørgrav int rc, ch; 209*59c8e88eSDag-Erling Smørgrav off_t outoff = 0, *offp; 210*59c8e88eSDag-Erling Smørgrav uint8_t *typep; 211*59c8e88eSDag-Erling Smørgrav 212*59c8e88eSDag-Erling Smørgrav 213*59c8e88eSDag-Erling Smørgrav if (chunk_type == CHUNK_MINUS || chunk_type == CHUNK_SAME) { 214*59c8e88eSDag-Erling Smørgrav start_atom = c->left_start; 215*59c8e88eSDag-Erling Smørgrav atom_count = c->left_count; 216*59c8e88eSDag-Erling Smørgrav } else if (chunk_type == CHUNK_PLUS) { 217*59c8e88eSDag-Erling Smørgrav start_atom = c->right_start; 218*59c8e88eSDag-Erling Smørgrav atom_count = c->right_count; 219*59c8e88eSDag-Erling Smørgrav } else 220*59c8e88eSDag-Erling Smørgrav return EINVAL; 221*59c8e88eSDag-Erling Smørgrav 222*59c8e88eSDag-Erling Smørgrav /* Locate the last atom. */ 223*59c8e88eSDag-Erling Smørgrav if (atom_count == 0) 224*59c8e88eSDag-Erling Smørgrav return EINVAL; 225*59c8e88eSDag-Erling Smørgrav atom = &start_atom[atom_count - 1]; 226*59c8e88eSDag-Erling Smørgrav 227*59c8e88eSDag-Erling Smørgrav rc = get_atom_byte(&ch, atom, atom->len - 1); 228*59c8e88eSDag-Erling Smørgrav if (rc != DIFF_RC_OK) 229*59c8e88eSDag-Erling Smørgrav return rc; 230*59c8e88eSDag-Erling Smørgrav 231*59c8e88eSDag-Erling Smørgrav if (ch != '\n') { 232*59c8e88eSDag-Erling Smørgrav if (outinfo && outinfo->line_offsets.len > 0) { 233*59c8e88eSDag-Erling Smørgrav unsigned int idx = outinfo->line_offsets.len - 1; 234*59c8e88eSDag-Erling Smørgrav outoff = outinfo->line_offsets.head[idx]; 235*59c8e88eSDag-Erling Smørgrav } 236*59c8e88eSDag-Erling Smørgrav rc = fprintf(dest, "\\ No newline at end of file\n"); 237*59c8e88eSDag-Erling Smørgrav if (rc < 0) 238*59c8e88eSDag-Erling Smørgrav return errno; 239*59c8e88eSDag-Erling Smørgrav if (outinfo) { 240*59c8e88eSDag-Erling Smørgrav ARRAYLIST_ADD(offp, outinfo->line_offsets); 241*59c8e88eSDag-Erling Smørgrav if (offp == NULL) 242*59c8e88eSDag-Erling Smørgrav return ENOMEM; 243*59c8e88eSDag-Erling Smørgrav outoff += rc; 244*59c8e88eSDag-Erling Smørgrav *offp = outoff; 245*59c8e88eSDag-Erling Smørgrav ARRAYLIST_ADD(typep, outinfo->line_types); 246*59c8e88eSDag-Erling Smørgrav if (typep == NULL) 247*59c8e88eSDag-Erling Smørgrav return ENOMEM; 248*59c8e88eSDag-Erling Smørgrav *typep = DIFF_LINE_NONE; 249*59c8e88eSDag-Erling Smørgrav } 250*59c8e88eSDag-Erling Smørgrav } 251*59c8e88eSDag-Erling Smørgrav 252*59c8e88eSDag-Erling Smørgrav return DIFF_RC_OK; 253*59c8e88eSDag-Erling Smørgrav } 254*59c8e88eSDag-Erling Smørgrav 255*59c8e88eSDag-Erling Smørgrav static bool 256*59c8e88eSDag-Erling Smørgrav is_function_prototype(unsigned char ch) 257*59c8e88eSDag-Erling Smørgrav { 258*59c8e88eSDag-Erling Smørgrav return (isalpha((unsigned char)ch) || ch == '_' || ch == '$'); 259*59c8e88eSDag-Erling Smørgrav } 260*59c8e88eSDag-Erling Smørgrav 261*59c8e88eSDag-Erling Smørgrav #define begins_with(s, pre) (strncmp(s, pre, sizeof(pre)-1) == 0) 262*59c8e88eSDag-Erling Smørgrav 263*59c8e88eSDag-Erling Smørgrav int 264*59c8e88eSDag-Erling Smørgrav diff_output_match_function_prototype(char *prototype, size_t prototype_size, 265*59c8e88eSDag-Erling Smørgrav int *last_prototype_idx, const struct diff_result *result, 266*59c8e88eSDag-Erling Smørgrav const struct diff_chunk_context *cc) 267*59c8e88eSDag-Erling Smørgrav { 268*59c8e88eSDag-Erling Smørgrav struct diff_atom *start_atom, *atom; 269*59c8e88eSDag-Erling Smørgrav const struct diff_data *data; 270*59c8e88eSDag-Erling Smørgrav unsigned char buf[DIFF_FUNCTION_CONTEXT_SIZE]; 271*59c8e88eSDag-Erling Smørgrav const char *state = NULL; 272*59c8e88eSDag-Erling Smørgrav int rc, i, ch; 273*59c8e88eSDag-Erling Smørgrav 274*59c8e88eSDag-Erling Smørgrav if (result->left->atoms.len > 0 && cc->left.start > 0) { 275*59c8e88eSDag-Erling Smørgrav data = result->left; 276*59c8e88eSDag-Erling Smørgrav start_atom = &data->atoms.head[cc->left.start - 1]; 277*59c8e88eSDag-Erling Smørgrav } else 278*59c8e88eSDag-Erling Smørgrav return DIFF_RC_OK; 279*59c8e88eSDag-Erling Smørgrav 280*59c8e88eSDag-Erling Smørgrav diff_data_foreach_atom_backwards_from(start_atom, atom, data) { 281*59c8e88eSDag-Erling Smørgrav int atom_idx = diff_atom_root_idx(data, atom); 282*59c8e88eSDag-Erling Smørgrav if (atom_idx < *last_prototype_idx) 283*59c8e88eSDag-Erling Smørgrav break; 284*59c8e88eSDag-Erling Smørgrav rc = get_atom_byte(&ch, atom, 0); 285*59c8e88eSDag-Erling Smørgrav if (rc) 286*59c8e88eSDag-Erling Smørgrav return rc; 287*59c8e88eSDag-Erling Smørgrav buf[0] = (unsigned char)ch; 288*59c8e88eSDag-Erling Smørgrav if (!is_function_prototype(buf[0])) 289*59c8e88eSDag-Erling Smørgrav continue; 290*59c8e88eSDag-Erling Smørgrav for (i = 1; i < atom->len && i < sizeof(buf) - 1; i++) { 291*59c8e88eSDag-Erling Smørgrav rc = get_atom_byte(&ch, atom, i); 292*59c8e88eSDag-Erling Smørgrav if (rc) 293*59c8e88eSDag-Erling Smørgrav return rc; 294*59c8e88eSDag-Erling Smørgrav if (ch == '\n') 295*59c8e88eSDag-Erling Smørgrav break; 296*59c8e88eSDag-Erling Smørgrav buf[i] = (unsigned char)ch; 297*59c8e88eSDag-Erling Smørgrav } 298*59c8e88eSDag-Erling Smørgrav buf[i] = '\0'; 299*59c8e88eSDag-Erling Smørgrav if (begins_with(buf, "private:")) { 300*59c8e88eSDag-Erling Smørgrav if (!state) 301*59c8e88eSDag-Erling Smørgrav state = " (private)"; 302*59c8e88eSDag-Erling Smørgrav } else if (begins_with(buf, "protected:")) { 303*59c8e88eSDag-Erling Smørgrav if (!state) 304*59c8e88eSDag-Erling Smørgrav state = " (protected)"; 305*59c8e88eSDag-Erling Smørgrav } else if (begins_with(buf, "public:")) { 306*59c8e88eSDag-Erling Smørgrav if (!state) 307*59c8e88eSDag-Erling Smørgrav state = " (public)"; 308*59c8e88eSDag-Erling Smørgrav } else { 309*59c8e88eSDag-Erling Smørgrav if (state) /* don't care about truncation */ 310*59c8e88eSDag-Erling Smørgrav strlcat(buf, state, sizeof(buf)); 311*59c8e88eSDag-Erling Smørgrav strlcpy(prototype, buf, prototype_size); 312*59c8e88eSDag-Erling Smørgrav break; 313*59c8e88eSDag-Erling Smørgrav } 314*59c8e88eSDag-Erling Smørgrav } 315*59c8e88eSDag-Erling Smørgrav 316*59c8e88eSDag-Erling Smørgrav *last_prototype_idx = diff_atom_root_idx(data, start_atom); 317*59c8e88eSDag-Erling Smørgrav return DIFF_RC_OK; 318*59c8e88eSDag-Erling Smørgrav } 319*59c8e88eSDag-Erling Smørgrav 320*59c8e88eSDag-Erling Smørgrav struct diff_output_info * 321*59c8e88eSDag-Erling Smørgrav diff_output_info_alloc(void) 322*59c8e88eSDag-Erling Smørgrav { 323*59c8e88eSDag-Erling Smørgrav struct diff_output_info *output_info; 324*59c8e88eSDag-Erling Smørgrav off_t *offp; 325*59c8e88eSDag-Erling Smørgrav uint8_t *typep; 326*59c8e88eSDag-Erling Smørgrav 327*59c8e88eSDag-Erling Smørgrav output_info = malloc(sizeof(*output_info)); 328*59c8e88eSDag-Erling Smørgrav if (output_info != NULL) { 329*59c8e88eSDag-Erling Smørgrav ARRAYLIST_INIT(output_info->line_offsets, 128); 330*59c8e88eSDag-Erling Smørgrav ARRAYLIST_ADD(offp, output_info->line_offsets); 331*59c8e88eSDag-Erling Smørgrav if (offp == NULL) { 332*59c8e88eSDag-Erling Smørgrav diff_output_info_free(output_info); 333*59c8e88eSDag-Erling Smørgrav return NULL; 334*59c8e88eSDag-Erling Smørgrav } 335*59c8e88eSDag-Erling Smørgrav *offp = 0; 336*59c8e88eSDag-Erling Smørgrav ARRAYLIST_INIT(output_info->line_types, 128); 337*59c8e88eSDag-Erling Smørgrav ARRAYLIST_ADD(typep, output_info->line_types); 338*59c8e88eSDag-Erling Smørgrav if (typep == NULL) { 339*59c8e88eSDag-Erling Smørgrav diff_output_info_free(output_info); 340*59c8e88eSDag-Erling Smørgrav return NULL; 341*59c8e88eSDag-Erling Smørgrav } 342*59c8e88eSDag-Erling Smørgrav *typep = DIFF_LINE_NONE; 343*59c8e88eSDag-Erling Smørgrav } 344*59c8e88eSDag-Erling Smørgrav return output_info; 345*59c8e88eSDag-Erling Smørgrav } 346*59c8e88eSDag-Erling Smørgrav 347*59c8e88eSDag-Erling Smørgrav void 348*59c8e88eSDag-Erling Smørgrav diff_output_info_free(struct diff_output_info *output_info) 349*59c8e88eSDag-Erling Smørgrav { 350*59c8e88eSDag-Erling Smørgrav ARRAYLIST_FREE(output_info->line_offsets); 351*59c8e88eSDag-Erling Smørgrav ARRAYLIST_FREE(output_info->line_types); 352*59c8e88eSDag-Erling Smørgrav free(output_info); 353*59c8e88eSDag-Erling Smørgrav } 354*59c8e88eSDag-Erling Smørgrav 355*59c8e88eSDag-Erling Smørgrav const char * 356*59c8e88eSDag-Erling Smørgrav diff_output_get_label_left(const struct diff_input_info *info) 357*59c8e88eSDag-Erling Smørgrav { 358*59c8e88eSDag-Erling Smørgrav if (info->flags & DIFF_INPUT_LEFT_NONEXISTENT) 359*59c8e88eSDag-Erling Smørgrav return "/dev/null"; 360*59c8e88eSDag-Erling Smørgrav 361*59c8e88eSDag-Erling Smørgrav return info->left_path ? info->left_path : "a"; 362*59c8e88eSDag-Erling Smørgrav } 363*59c8e88eSDag-Erling Smørgrav 364*59c8e88eSDag-Erling Smørgrav const char * 365*59c8e88eSDag-Erling Smørgrav diff_output_get_label_right(const struct diff_input_info *info) 366*59c8e88eSDag-Erling Smørgrav { 367*59c8e88eSDag-Erling Smørgrav if (info->flags & DIFF_INPUT_RIGHT_NONEXISTENT) 368*59c8e88eSDag-Erling Smørgrav return "/dev/null"; 369*59c8e88eSDag-Erling Smørgrav 370*59c8e88eSDag-Erling Smørgrav return info->right_path ? info->right_path : "b"; 371*59c8e88eSDag-Erling Smørgrav } 372