diff options
Diffstat (limited to 'diff.c')
| -rw-r--r-- | diff.c | 62 | 
1 files changed, 34 insertions, 28 deletions
| @@ -14,6 +14,7 @@  #include "userdiff.h"  #include "sigchain.h"  #include "submodule.h" +#include "ll-merge.h"  #ifdef NO_FAST_WORKING_DIRECTORY  #define FAST_WORKING_DIRECTORY 0 @@ -948,7 +949,7 @@ struct diffstat_t {  		unsigned is_unmerged:1;  		unsigned is_binary:1;  		unsigned is_renamed:1; -		unsigned int added, deleted; +		uintmax_t added, deleted;  	} **files;  }; @@ -1040,7 +1041,7 @@ static void fill_print_name(struct diffstat_file *file)  static void show_stats(struct diffstat_t *data, struct diff_options *options)  {  	int i, len, add, del, adds = 0, dels = 0; -	int max_change = 0, max_len = 0; +	uintmax_t max_change = 0, max_len = 0;  	int total_files = data->nr;  	int width, name_width;  	const char *reset, *set, *add_c, *del_c; @@ -1069,7 +1070,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)  	for (i = 0; i < data->nr; i++) {  		struct diffstat_file *file = data->files[i]; -		int change = file->added + file->deleted; +		uintmax_t change = file->added + file->deleted;  		fill_print_name(file);  		len = strlen(file->print_name);  		if (max_len < len) @@ -1097,8 +1098,8 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)  	for (i = 0; i < data->nr; i++) {  		const char *prefix = "";  		char *name = data->files[i]->print_name; -		int added = data->files[i]->added; -		int deleted = data->files[i]->deleted; +		uintmax_t added = data->files[i]->added; +		uintmax_t deleted = data->files[i]->deleted;  		int name_len;  		/* @@ -1119,9 +1120,11 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)  		if (data->files[i]->is_binary) {  			show_name(options->file, prefix, name, len);  			fprintf(options->file, "  Bin "); -			fprintf(options->file, "%s%d%s", del_c, deleted, reset); +			fprintf(options->file, "%s%"PRIuMAX"%s", +				del_c, deleted, reset);  			fprintf(options->file, " -> "); -			fprintf(options->file, "%s%d%s", add_c, added, reset); +			fprintf(options->file, "%s%"PRIuMAX"%s", +				add_c, added, reset);  			fprintf(options->file, " bytes");  			fprintf(options->file, "\n");  			continue; @@ -1150,7 +1153,7 @@ static void show_stats(struct diffstat_t *data, struct diff_options *options)  			del = scale_linear(del, width, max_change);  		}  		show_name(options->file, prefix, name, len); -		fprintf(options->file, "%5d%s", added + deleted, +		fprintf(options->file, "%5"PRIuMAX"%s", added + deleted,  				added + deleted ? " " : "");  		show_graph(options->file, '+', add, add_c, reset);  		show_graph(options->file, '-', del, del_c, reset); @@ -1200,7 +1203,8 @@ static void show_numstat(struct diffstat_t *data, struct diff_options *options)  			fprintf(options->file, "-\t-\t");  		else  			fprintf(options->file, -				"%d\t%d\t", file->added, file->deleted); +				"%"PRIuMAX"\t%"PRIuMAX"\t", +				file->added, file->deleted);  		if (options->line_termination) {  			fill_print_name(file);  			if (!file->is_renamed) @@ -1370,37 +1374,32 @@ static void free_diffstat_info(struct diffstat_t *diffstat)  struct checkdiff_t {  	const char *filename;  	int lineno; +	int conflict_marker_size;  	struct diff_options *o;  	unsigned ws_rule;  	unsigned status;  }; -static int is_conflict_marker(const char *line, unsigned long len) +static int is_conflict_marker(const char *line, int marker_size, unsigned long len)  {  	char firstchar;  	int cnt; -	if (len < 8) +	if (len < marker_size + 1)  		return 0;  	firstchar = line[0];  	switch (firstchar) { -	case '=': case '>': case '<': +	case '=': case '>': case '<': case '|':  		break;  	default:  		return 0;  	} -	for (cnt = 1; cnt < 7; cnt++) +	for (cnt = 1; cnt < marker_size; cnt++)  		if (line[cnt] != firstchar)  			return 0; -	/* line[0] thru line[6] are same as firstchar */ -	if (firstchar == '=') { -		/* divider between ours and theirs? */ -		if (len != 8 || line[7] != '\n') -			return 0; -	} else if (len < 8 || !isspace(line[7])) { -		/* not divider before ours nor after theirs */ +	/* line[1] thru line[marker_size-1] are same as firstchar */ +	if (len < marker_size + 1 || !isspace(line[marker_size]))  		return 0; -	}  	return 1;  } @@ -1408,6 +1407,7 @@ static void checkdiff_consume(void *priv, char *line, unsigned long len)  {  	struct checkdiff_t *data = priv;  	int color_diff = DIFF_OPT_TST(data->o, COLOR_DIFF); +	int marker_size = data->conflict_marker_size;  	const char *ws = diff_get_color(color_diff, DIFF_WHITESPACE);  	const char *reset = diff_get_color(color_diff, DIFF_RESET);  	const char *set = diff_get_color(color_diff, DIFF_FILE_NEW); @@ -1416,7 +1416,7 @@ static void checkdiff_consume(void *priv, char *line, unsigned long len)  	if (line[0] == '+') {  		unsigned bad;  		data->lineno++; -		if (is_conflict_marker(line + 1, len - 1)) { +		if (is_conflict_marker(line + 1, marker_size, len - 1)) {  			data->status |= 1;  			fprintf(data->o->file,  				"%s:%d: leftover conflict marker\n", @@ -1860,6 +1860,7 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,  	data.lineno = 0;  	data.o = o;  	data.ws_rule = whitespace_rule(attr_path); +	data.conflict_marker_size = ll_merge_marker_size(attr_path);  	if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)  		die("unable to read files to diff"); @@ -3865,6 +3866,7 @@ static char *run_textconv(const char *pgm, struct diff_filespec *spec,  	const char **arg = argv;  	struct child_process child;  	struct strbuf buf = STRBUF_INIT; +	int err = 0;  	temp = prepare_temp_file(spec->path, spec);  	*arg++ = pgm; @@ -3875,16 +3877,20 @@ static char *run_textconv(const char *pgm, struct diff_filespec *spec,  	child.use_shell = 1;  	child.argv = argv;  	child.out = -1; -	if (start_command(&child) != 0 || -	    strbuf_read(&buf, child.out, 0) < 0 || -	    finish_command(&child) != 0) { -		close(child.out); -		strbuf_release(&buf); +	if (start_command(&child)) {  		remove_tempfile(); -		error("error running textconv command '%s'", pgm);  		return NULL;  	} + +	if (strbuf_read(&buf, child.out, 0) < 0) +		err = error("error reading from textconv command '%s'", pgm);  	close(child.out); + +	if (finish_command(&child) || err) { +		strbuf_release(&buf); +		remove_tempfile(); +		return NULL; +	}  	remove_tempfile();  	return strbuf_detach(&buf, outsize); | 
