Subject: [PATCH 06/12] Add helpers to redirect stdout to "git column"

From: Nguyễn Thái Ngọc Duy <[email-masked]>
Date: Sun, 7 Mar 2010 19:09:39 +0700

While the columnizer can be used directly, it requires output code
change. The helpers instead redirect all output to "git column" and
let "git column" do all the layout work. This keeps code change
minimum. All we need is:

start_columnizer();
/* do some complex computation and output to stdout */
stop_columnizer();

Signed-off-by: Nguyễn Thái Ngọc Duy <[email-masked]>
---
 column.h |    2 +
 pager.c  |   63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 0 deletions(-)

diff --git a/column.h b/column.h
index 28122e0..6eb19e3 100644
--- a/column.h
+++ b/column.h
@@ -21,3 +21,5 @@ struct columnizer {
 };
 
 extern int feed_columnizer(struct columnizer *cp, char *cell);
+extern int start_columnizer(const char **argv);
+extern int stop_columnizer();
diff --git a/pager.c b/pager.c
index ad447cf..9df727d 100644
--- a/pager.c
+++ b/pager.c
@@ -13,6 +13,8 @@
 
 static int spawned_pager;
 static int max_columns;
+static int fd_out = -1;
+static struct child_process column_process;
 
 #ifndef WIN32
 static void pager_preexec(void)
@@ -148,3 +150,64 @@ int term_columns()
 #endif
 	return 80;
 }
+
+int start_columnizer(const char **argv)
+{
+	int new_argc, argc = 0;
+	const char **column_argv;
+	char columns_param[32];
+
+	if (fd_out != -1)
+		return -1;
+
+	if (argv) {
+		while (argv[argc])
+			argc++;
+	}
+	new_argc = argc + 1; /* argv[0] = "column" */
+	if (spawned_pager && max_columns) {
+		sprintf(columns_param, "--width=%d", max_columns);
+		new_argc++;
+	}
+
+	column_argv = xmalloc(sizeof(*column_argv)*(new_argc+1));
+	column_argv[0] = "column";
+	if (spawned_pager && max_columns)
+		column_argv[1] = columns_param;
+	if (argv)
+		memcpy(column_argv + (new_argc-argc), argv, argc*sizeof(*argv));
+	column_argv[new_argc] = NULL;
+
+	fflush(stdout);
+	memset(&column_process, 0, sizeof(column_process));
+	column_process.in = -1;
+	column_process.out = dup(1);
+	column_process.git_cmd = 1;
+	column_process.argv = column_argv;
+
+	if (start_command(&column_process)) {
+		free(column_argv);
+		return -2;
+	}
+	free(column_argv);
+
+	fd_out = dup(1);
+	close(1);
+	dup2(column_process.in, 1);
+	close(column_process.in);
+	return 0;
+}
+
+int stop_columnizer()
+{
+	if (fd_out == -1)
+		return -1;
+
+	fflush(stdout);
+	close(1);
+	finish_command(&column_process);
+	dup2(fd_out, 1);
+	close(fd_out);
+	fd_out = -1;
+	return 0;
+}
-- 
1.7.0.1.370.gd3c5