Lars HjemliAdd basic diff view36aba0019 years agoHistory
131 lines · 2.7 KB · C
RawDownload
/* ui-diff.c: show diff between two blobs * * Copyright (C) 2006 Lars Hjemli * * Licensed under GNU General Public License v2 *   (see COPYING for full license text) */ #include "cgit.h"#include "xdiff.h" char *diff_buffer;int diff_buffer_size;  /* * print a single line returned from xdiff */static void print_line(char *line, int len){	char *class = "ctx";	char c = line[len-1]; 	if (line[0] == '+')		class = "add";	else if (line[0] == '-')		class = "del";	else if (line[0] == '@')		class = "hunk"; 	htmlf("<div class='%s'>", class);	line[len-1] = '\0';	html_txt(line);	html("</div>");	line[len-1] = c;} /* * Receive diff-buffers from xdiff and concatenate them as * needed across multiple callbacks. * * This is basically a copy of xdiff-interface.c/xdiff_outf(), * ripped from git and modified to use globals instead of * a special callback-struct. */int diff_cb(void *priv_, mmbuffer_t *mb, int nbuf){	int i; 	for (i = 0; i < nbuf; i++) {		if (mb[i].ptr[mb[i].size-1] != '\n') {			/* Incomplete line */			diff_buffer = xrealloc(diff_buffer,					       diff_buffer_size + mb[i].size);			memcpy(diff_buffer + diff_buffer_size,			       mb[i].ptr, mb[i].size);			diff_buffer_size += mb[i].size;			continue;		} 		/* we have a complete line */		if (!diff_buffer) {			print_line(mb[i].ptr, mb[i].size);			continue;		}		diff_buffer = xrealloc(diff_buffer,				       diff_buffer_size + mb[i].size);		memcpy(diff_buffer + diff_buffer_size, mb[i].ptr, mb[i].size);		print_line(diff_buffer, diff_buffer_size + mb[i].size);		free(diff_buffer);		diff_buffer = NULL;		diff_buffer_size = 0;	}	if (diff_buffer) {		print_line(diff_buffer, diff_buffer_size);		free(diff_buffer);		diff_buffer = NULL;		diff_buffer_size = 0;	}	return 0;} static int load_mmfile(mmfile_t *file, const unsigned char *sha1){	char type[20]; 	if (is_null_sha1(sha1)) {		file->ptr = (char *)"";		file->size = 0;	} else {		file->ptr = read_sha1_file(sha1, type, &file->size);	}	return 1;} static void run_diff(const unsigned char *sha1, const unsigned char *sha2){	mmfile_t file1, file2;	xpparam_t diff_params;	xdemitconf_t emit_params;	xdemitcb_t emit_cb; 	if (!load_mmfile(&file1, sha1) || !load_mmfile(&file2, sha2)) {		cgit_print_error("Unable to load files for diff");		return;	} 	diff_params.flags = XDF_NEED_MINIMAL; 	emit_params.ctxlen = 3;	emit_params.flags = XDL_EMIT_FUNCNAMES; 	emit_cb.outf = diff_cb; 	xdl_diff(&file1, &file2, &diff_params, &emit_params, &emit_cb);}   void cgit_print_diff(const char *old_hex, const char *new_hex){	unsigned char sha1[20], sha2[20]; 	get_sha1(old_hex, sha1);	get_sha1(new_hex, sha2); 	html("<h2>diff</h2>\n");	html("<table class='diff'><tr><td>");	run_diff(sha1, sha2);	html("</td></tr></table>");}