All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rene Scharfe <l.s.r@web.de>
To: git@vger.kernel.org
Subject: [PATCH 12/34] diff: release strbuf after use in show_stats()
Date: Wed, 30 Aug 2017 19:58:11 +0200	[thread overview]
Message-ID: <20170830175825.20905-7-l.s.r@web.de> (raw)
In-Reply-To: <20170830175825.20905-1-l.s.r@web.de>

Signed-off-by: Rene Scharfe <l.s.r@web.de>
---
 diff.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/diff.c b/diff.c
index 33c65f492d..64cdcf2331 100644
--- a/diff.c
+++ b/diff.c
@@ -2334,255 +2334,256 @@ void print_stat_summary(FILE *fp, int files,
 static void show_stats(struct diffstat_t *data, struct diff_options *options)
 {
 	int i, len, add, del, adds = 0, dels = 0;
 	uintmax_t max_change = 0, max_len = 0;
 	int total_files = data->nr, count;
 	int width, name_width, graph_width, number_width = 0, bin_width = 0;
 	const char *reset, *add_c, *del_c;
 	int extra_shown = 0;
 	const char *line_prefix = diff_line_prefix(options);
 	struct strbuf out = STRBUF_INIT;
 
 	if (data->nr == 0)
 		return;
 
 	count = options->stat_count ? options->stat_count : data->nr;
 
 	reset = diff_get_color_opt(options, DIFF_RESET);
 	add_c = diff_get_color_opt(options, DIFF_FILE_NEW);
 	del_c = diff_get_color_opt(options, DIFF_FILE_OLD);
 
 	/*
 	 * Find the longest filename and max number of changes
 	 */
 	for (i = 0; (i < count) && (i < data->nr); i++) {
 		struct diffstat_file *file = data->files[i];
 		uintmax_t change = file->added + file->deleted;
 
 		if (!file->is_interesting && (change == 0)) {
 			count++; /* not shown == room for one more */
 			continue;
 		}
 		fill_print_name(file);
 		len = strlen(file->print_name);
 		if (max_len < len)
 			max_len = len;
 
 		if (file->is_unmerged) {
 			/* "Unmerged" is 8 characters */
 			bin_width = bin_width < 8 ? 8 : bin_width;
 			continue;
 		}
 		if (file->is_binary) {
 			/* "Bin XXX -> YYY bytes" */
 			int w = 14 + decimal_width(file->added)
 				+ decimal_width(file->deleted);
 			bin_width = bin_width < w ? w : bin_width;
 			/* Display change counts aligned with "Bin" */
 			number_width = 3;
 			continue;
 		}
 
 		if (max_change < change)
 			max_change = change;
 	}
 	count = i; /* where we can stop scanning in data->files[] */
 
 	/*
 	 * We have width = stat_width or term_columns() columns total.
 	 * We want a maximum of min(max_len, stat_name_width) for the name part.
 	 * We want a maximum of min(max_change, stat_graph_width) for the +- part.
 	 * We also need 1 for " " and 4 + decimal_width(max_change)
 	 * for " | NNNN " and one the empty column at the end, altogether
 	 * 6 + decimal_width(max_change).
 	 *
 	 * If there's not enough space, we will use the smaller of
 	 * stat_name_width (if set) and 5/8*width for the filename,
 	 * and the rest for constant elements + graph part, but no more
 	 * than stat_graph_width for the graph part.
 	 * (5/8 gives 50 for filename and 30 for the constant parts + graph
 	 * for the standard terminal size).
 	 *
 	 * In other words: stat_width limits the maximum width, and
 	 * stat_name_width fixes the maximum width of the filename,
 	 * and is also used to divide available columns if there
 	 * aren't enough.
 	 *
 	 * Binary files are displayed with "Bin XXX -> YYY bytes"
 	 * instead of the change count and graph. This part is treated
 	 * similarly to the graph part, except that it is not
 	 * "scaled". If total width is too small to accommodate the
 	 * guaranteed minimum width of the filename part and the
 	 * separators and this message, this message will "overflow"
 	 * making the line longer than the maximum width.
 	 */
 
 	if (options->stat_width == -1)
 		width = term_columns() - strlen(line_prefix);
 	else
 		width = options->stat_width ? options->stat_width : 80;
 	number_width = decimal_width(max_change) > number_width ?
 		decimal_width(max_change) : number_width;
 
 	if (options->stat_graph_width == -1)
 		options->stat_graph_width = diff_stat_graph_width;
 
 	/*
 	 * Guarantee 3/8*16==6 for the graph part
 	 * and 5/8*16==10 for the filename part
 	 */
 	if (width < 16 + 6 + number_width)
 		width = 16 + 6 + number_width;
 
 	/*
 	 * First assign sizes that are wanted, ignoring available width.
 	 * strlen("Bin XXX -> YYY bytes") == bin_width, and the part
 	 * starting from "XXX" should fit in graph_width.
 	 */
 	graph_width = max_change + 4 > bin_width ? max_change : bin_width - 4;
 	if (options->stat_graph_width &&
 	    options->stat_graph_width < graph_width)
 		graph_width = options->stat_graph_width;
 
 	name_width = (options->stat_name_width > 0 &&
 		      options->stat_name_width < max_len) ?
 		options->stat_name_width : max_len;
 
 	/*
 	 * Adjust adjustable widths not to exceed maximum width
 	 */
 	if (name_width + number_width + 6 + graph_width > width) {
 		if (graph_width > width * 3/8 - number_width - 6) {
 			graph_width = width * 3/8 - number_width - 6;
 			if (graph_width < 6)
 				graph_width = 6;
 		}
 
 		if (options->stat_graph_width &&
 		    graph_width > options->stat_graph_width)
 			graph_width = options->stat_graph_width;
 		if (name_width > width - number_width - 6 - graph_width)
 			name_width = width - number_width - 6 - graph_width;
 		else
 			graph_width = width - number_width - 6 - name_width;
 	}
 
 	/*
 	 * From here name_width is the width of the name area,
 	 * and graph_width is the width of the graph area.
 	 * max_change is used to scale graph properly.
 	 */
 	for (i = 0; i < count; i++) {
 		const char *prefix = "";
 		struct diffstat_file *file = data->files[i];
 		char *name = file->print_name;
 		uintmax_t added = file->added;
 		uintmax_t deleted = file->deleted;
 		int name_len;
 
 		if (!file->is_interesting && (added + deleted == 0))
 			continue;
 
 		/*
 		 * "scale" the filename
 		 */
 		len = name_width;
 		name_len = strlen(name);
 		if (name_width < name_len) {
 			char *slash;
 			prefix = "...";
 			len -= 3;
 			name += name_len - len;
 			slash = strchr(name, '/');
 			if (slash)
 				name = slash;
 		}
 
 		if (file->is_binary) {
 			strbuf_addf(&out, " %s%-*s |", prefix, len, name);
 			strbuf_addf(&out, " %*s", number_width, "Bin");
 			if (!added && !deleted) {
 				strbuf_addch(&out, '\n');
 				emit_diff_symbol(options, DIFF_SYMBOL_STATS_LINE,
 						 out.buf, out.len, 0);
 				strbuf_reset(&out);
 				continue;
 			}
 			strbuf_addf(&out, " %s%"PRIuMAX"%s",
 				del_c, deleted, reset);
 			strbuf_addstr(&out, " -> ");
 			strbuf_addf(&out, "%s%"PRIuMAX"%s",
 				add_c, added, reset);
 			strbuf_addstr(&out, " bytes\n");
 			emit_diff_symbol(options, DIFF_SYMBOL_STATS_LINE,
 					 out.buf, out.len, 0);
 			strbuf_reset(&out);
 			continue;
 		}
 		else if (file->is_unmerged) {
 			strbuf_addf(&out, " %s%-*s |", prefix, len, name);
 			strbuf_addstr(&out, " Unmerged\n");
 			emit_diff_symbol(options, DIFF_SYMBOL_STATS_LINE,
 					 out.buf, out.len, 0);
 			strbuf_reset(&out);
 			continue;
 		}
 
 		/*
 		 * scale the add/delete
 		 */
 		add = added;
 		del = deleted;
 
 		if (graph_width <= max_change) {
 			int total = scale_linear(add + del, graph_width, max_change);
 			if (total < 2 && add && del)
 				/* width >= 2 due to the sanity check */
 				total = 2;
 			if (add < del) {
 				add = scale_linear(add, graph_width, max_change);
 				del = total - add;
 			} else {
 				del = scale_linear(del, graph_width, max_change);
 				add = total - del;
 			}
 		}
 		strbuf_addf(&out, " %s%-*s |", prefix, len, name);
 		strbuf_addf(&out, " %*"PRIuMAX"%s",
 			number_width, added + deleted,
 			added + deleted ? " " : "");
 		show_graph(&out, '+', add, add_c, reset);
 		show_graph(&out, '-', del, del_c, reset);
 		strbuf_addch(&out, '\n');
 		emit_diff_symbol(options, DIFF_SYMBOL_STATS_LINE,
 				 out.buf, out.len, 0);
 		strbuf_reset(&out);
 	}
 
 	for (i = 0; i < data->nr; i++) {
 		struct diffstat_file *file = data->files[i];
 		uintmax_t added = file->added;
 		uintmax_t deleted = file->deleted;
 
 		if (file->is_unmerged ||
 		    (!file->is_interesting && (added + deleted == 0))) {
 			total_files--;
 			continue;
 		}
 
 		if (!file->is_binary) {
 			adds += added;
 			dels += deleted;
 		}
 		if (i < count)
 			continue;
 		if (!extra_shown)
 			emit_diff_symbol(options,
 					 DIFF_SYMBOL_STATS_SUMMARY_ABBREV,
 					 NULL, 0, 0);
 		extra_shown = 1;
 	}
 
 	print_stat_summary_inserts_deletes(options, total_files, adds, dels);
+	strbuf_release(&out);
 }
 
 static void show_shortstats(struct diffstat_t *data, struct diff_options *options)
-- 
2.14.1


  parent reply	other threads:[~2017-08-30 17:58 UTC|newest]

Thread overview: 75+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-30 17:49 [PATCH 00/34] plug strbuf memory leaks Rene Scharfe
2017-08-30 17:49 ` [PATCH 01/34] am: release strbufs after use in detect_patch_format() Rene Scharfe
2017-08-31 17:31   ` Stefan Beller
2017-08-30 17:49 ` [PATCH 02/34] am: release strbuf on error return in hg_patch_to_mail() Rene Scharfe
2017-08-30 17:49 ` [PATCH 03/34] am: release strbuf after use in safe_to_abort() Rene Scharfe
2017-08-30 17:49 ` [PATCH 04/34] check-ref-format: release strbuf after use in check_ref_format_branch() Rene Scharfe
2017-08-30 17:49 ` [PATCH 05/34] clean: release strbuf after use in remove_dirs() Rene Scharfe
2017-08-30 17:49 ` [PATCH 06/34] clone: release strbuf after use in remove_junk() Rene Scharfe
2017-09-06 19:51   ` Junio C Hamano
2017-09-10  6:27     ` René Scharfe
2017-09-10  7:30       ` Jeff King
2017-09-10 10:37         ` René Scharfe
2017-09-10 17:38           ` Jeff King
2017-09-11 21:40             ` René Scharfe
2017-09-13 12:56               ` Jeff King
2017-08-30 17:49 ` [PATCH 07/34] commit: release strbuf on error return in commit_tree_extended() Rene Scharfe
2017-08-31 17:40   ` Stefan Beller
2017-08-30 17:49 ` [PATCH 08/34] connect: release strbuf on error return in git_connect() Rene Scharfe
2017-08-31 17:44   ` Stefan Beller
2017-08-30 17:49 ` [PATCH 09/34] convert: release strbuf on error return in filter_buffer_or_fd() Rene Scharfe
2017-08-30 17:49 ` [PATCH 10/34] diff: release strbuf after use in diff_summary() Rene Scharfe
2017-08-31 17:46   ` Stefan Beller
2017-08-30 17:49 ` [PATCH 11/34] diff: release strbuf after use in show_rename_copy() Rene Scharfe
2017-08-30 17:49 ` [PATCH 12/34] diff: release strbuf after use in show_stats() Rene Scharfe
2017-08-30 17:49 ` [PATCH 13/34] help: release strbuf on error return in exec_man_konqueror() Rene Scharfe
2017-08-30 17:49 ` [PATCH 14/34] help: release strbuf on error return in exec_man_man() Rene Scharfe
2017-08-30 17:49 ` [PATCH 15/34] help: release strbuf on error return in exec_woman_emacs() Rene Scharfe
2017-08-30 17:49 ` [PATCH 16/34] mailinfo: release strbuf after use in handle_from() Rene Scharfe
2017-08-30 17:49 ` [PATCH 17/34] mailinfo: release strbuf on error return in handle_boundary() Rene Scharfe
2017-08-30 18:23   ` Martin Ågren
2017-08-31 17:21     ` René Scharfe
2017-09-05 17:10       ` Martin Ågren
2017-08-30 17:49 ` [PATCH 18/34] merge: release strbuf after use in save_state() Rene Scharfe
2017-08-30 17:49 ` [PATCH 19/34] merge: release strbuf after use in write_merge_heads() Rene Scharfe
2017-08-30 17:57 ` [PATCH 20/34] notes: release strbuf after use in notes_copy_from_stdin() Rene Scharfe
2017-08-30 17:58 ` [PATCH 02/34] am: release strbuf on error return in hg_patch_to_mail() Rene Scharfe
2017-08-30 17:58   ` [PATCH 03/34] am: release strbuf after use in safe_to_abort() Rene Scharfe
2017-08-30 17:58   ` [PATCH 04/34] check-ref-format: release strbuf after use in check_ref_format_branch() Rene Scharfe
2017-08-30 17:58   ` [PATCH 08/34] connect: release strbuf on error return in git_connect() Rene Scharfe
2017-08-30 17:58   ` [PATCH 09/34] convert: release strbuf on error return in filter_buffer_or_fd() Rene Scharfe
2017-08-30 17:58   ` [PATCH 11/34] diff: release strbuf after use in show_rename_copy() Rene Scharfe
2017-08-30 17:58   ` Rene Scharfe [this message]
2017-08-30 17:58   ` [PATCH 21/34] refs: release strbuf on error return in write_pseudoref() Rene Scharfe
2017-08-30 18:00 ` [PATCH 08/34] connect: release strbuf on error return in git_connect() Rene Scharfe
2017-08-30 18:00   ` [PATCH 21/34] refs: release strbuf on error return in write_pseudoref() Rene Scharfe
2017-08-30 18:00   ` [PATCH 22/34] remote: release strbuf after use in read_remote_branches() Rene Scharfe
2017-08-30 18:00   ` [PATCH 23/34] remote: release strbuf after use in migrate_file() Rene Scharfe
2017-08-30 18:00   ` [PATCH 24/34] remote: release strbuf after use in set_url() Rene Scharfe
2017-08-30 18:00   ` [PATCH 25/34] send-pack: release strbuf on error return in send_pack() Rene Scharfe
2017-08-30 18:00   ` [PATCH 26/34] sha1_file: release strbuf on error return in index_path() Rene Scharfe
2017-08-30 18:00   ` [PATCH 27/34] shortlog: release strbuf after use in insert_one_record() Rene Scharfe
2017-09-06 19:51     ` Junio C Hamano
2017-09-07  4:33       ` Jeff King
2017-09-08  0:33         ` Junio C Hamano
2017-09-08  3:56           ` Jeff King
2017-09-08  4:36             ` Jeff King
2017-09-08  6:39               ` Junio C Hamano
2017-09-08  9:21                 ` [PATCH] shortlog: skip format/parse roundtrip for internal traversal Jeff King
2017-09-10  8:44                   ` René Scharfe
2017-09-10  8:50                     ` Jeff King
2017-08-30 18:05 ` [PATCH 08/34] connect: release strbuf on error return in git_connect() Rene Scharfe
2017-08-30 18:20 ` [PATCH 21/34] refs: release strbuf on error return in write_pseudoref() Rene Scharfe
2017-08-30 18:20 ` [PATCH 25/34] send-pack: release strbuf on error return in send_pack() Rene Scharfe
2017-08-30 18:20 ` [PATCH 28/34] sequencer: release strbuf after use in save_head() Rene Scharfe
2017-08-30 18:20 ` [PATCH 30/34] userdiff: release strbuf after use in userdiff_get_textconv() Rene Scharfe
2017-08-30 18:20 ` [PATCH 29/34] transport-helper: release strbuf after use in process_connect_service() Rene Scharfe
2017-08-30 18:20 ` [PATCH 31/34] utf8: release strbuf on error return in strbuf_utf8_replace() Rene Scharfe
2017-08-30 18:20 ` [PATCH 32/34] vcs-svn: release strbuf after use in end_revision() Rene Scharfe
2017-08-30 18:20 ` [PATCH 33/34] wt-status: release strbuf after use in read_rebase_todolist() Rene Scharfe
2017-08-30 18:20 ` [PATCH 34/34] wt-status: release strbuf after use in wt_longstatus_print_tracking() Rene Scharfe
2017-09-06 19:51   ` Junio C Hamano
2017-09-10  6:27     ` René Scharfe
2017-09-10  7:39       ` Junio C Hamano
2017-08-31 18:05 ` [PATCH 00/34] plug strbuf memory leaks Stefan Beller
2017-09-06 19:51 ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170830175825.20905-7-l.s.r@web.de \
    --to=l.s.r@web.de \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.