column: support piping stdout to external git-column process

For too complicated output handling, it'd be easier to just spawn git-column and redirect stdout to it. This patch provides helpers to do that. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Apr 13, 2012 at 17:54 UTC b27004eb32139977f8fa5c01eb235535661f9201
2 files changed +72
column.c
+69
@@ -2,6 +2,7 @@
2 #include "column.h"
3 #include "string-list.h"
4 #include "parse-options.h"
5 +#include "run-command.h"
6 #include "utf8.h"
7
8 #define XY2LINEAR(d, x, y) (COL_LAYOUT((d)->colopts) == COL_COLUMN ? \
@@ -363,3 +364,71 @@ int parseopt_column_callback(const struct option *opt,
364
365 return 0;
366 }
367 +
368 +static int fd_out = -1;
369 +static struct child_process column_process;
370 +
371 +int run_column_filter(int colopts, const struct column_options *opts)
372 +{
373 + const char *av[10];
374 + int ret, ac = 0;
375 + struct strbuf sb_colopt = STRBUF_INIT;
376 + struct strbuf sb_width = STRBUF_INIT;
377 + struct strbuf sb_padding = STRBUF_INIT;
378 +
379 + if (fd_out != -1)
380 + return -1;
381 +
382 + av[ac++] = "column";
383 + strbuf_addf(&sb_colopt, "--raw-mode=%d", colopts);
384 + av[ac++] = sb_colopt.buf;
385 + if (opts && opts->width) {
386 + strbuf_addf(&sb_width, "--width=%d", opts->width);
387 + av[ac++] = sb_width.buf;
388 + }
389 + if (opts && opts->indent) {
390 + av[ac++] = "--indent";
391 + av[ac++] = opts->indent;
392 + }
393 + if (opts && opts->padding) {
394 + strbuf_addf(&sb_padding, "--padding=%d", opts->padding);
395 + av[ac++] = sb_padding.buf;
396 + }
397 + av[ac] = NULL;
398 +
399 + fflush(stdout);
400 + memset(&column_process, 0, sizeof(column_process));
401 + column_process.in = -1;
402 + column_process.out = dup(1);
403 + column_process.git_cmd = 1;
404 + column_process.argv = av;
405 +
406 + ret = start_command(&column_process);
407 +
408 + strbuf_release(&sb_colopt);
409 + strbuf_release(&sb_width);
410 + strbuf_release(&sb_padding);
411 +
412 + if (ret)
413 + return -2;
414 +
415 + fd_out = dup(1);
416 + close(1);
417 + dup2(column_process.in, 1);
418 + close(column_process.in);
419 + return 0;
420 +}
421 +
422 +int stop_column_filter(void)
423 +{
424 + if (fd_out == -1)
425 + return -1;
426 +
427 + fflush(stdout);
428 + close(1);
429 + finish_command(&column_process);
430 + dup2(fd_out, 1);
431 + close(fd_out);
432 + fd_out = -1;
433 + return 0;
434 +}
column.h
+3
@@ -39,4 +39,7 @@ static inline int column_active(unsigned int colopts)
39 extern void print_columns(const struct string_list *list, unsigned int colopts,
40 const struct column_options *opts);
41
42 +extern int run_column_filter(int colopts, const struct column_options *);
43 +extern int stop_column_filter(void);
44 +
45 #endif