summaryrefslogtreecommitdiffstats
path: root/examples/example05_update_notification_settings.cpp
Commit message (Collapse)AuthorAge
* Allow examples to build outside mastodonpp.tastytea2020-01-18
|
* Add examples 05 and 06.tastytea2020-01-11
a> 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
/* 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>");
}