You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2014/02/06 00:44:47 UTC
svn commit: r1564998 - in
/subversion/branches/automatic-pager/subversion/svn: blame-cmd.c cl.h
diff-cmd.c help-cmd.c util.c
Author: breser
Date: Wed Feb 5 23:44:46 2014
New Revision: 1564998
URL: http://svn.apache.org/r1564998
Log:
Initial and very rough support for automatic pager for the blame, diff and help
commands.
* subversion/svn/util.c
(): pull in necessary headers.
(svn_cl__start_pager, svn_cl__close_pager): New
* subversion/svn/cl.h
(svn_cl__start_pager, svn_cl__close_pager): New
* subversion/svn/blame-cmd.c
(svn_cl__blame): Add support for automatic pager.
* subversion/svn/diff-cmd.c
(svn_cl__diff): Add support for automatic pager.
* subversion/svn/help-cmd.c
(svn_cl__help): Add support for automatic pager.
Patch by: stsp
(from https://mail-archives.apache.org/mod_mbox/subversion-dev/201402.mbox/%3C20140203200233.GA29698%40jim.stsp.name%3E with changelog by me)
Modified:
subversion/branches/automatic-pager/subversion/svn/blame-cmd.c
subversion/branches/automatic-pager/subversion/svn/cl.h
subversion/branches/automatic-pager/subversion/svn/diff-cmd.c
subversion/branches/automatic-pager/subversion/svn/help-cmd.c
subversion/branches/automatic-pager/subversion/svn/util.c
Modified: subversion/branches/automatic-pager/subversion/svn/blame-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/automatic-pager/subversion/svn/blame-cmd.c?rev=1564998&r1=1564997&r2=1564998&view=diff
==============================================================================
--- subversion/branches/automatic-pager/subversion/svn/blame-cmd.c (original)
+++ subversion/branches/automatic-pager/subversion/svn/blame-cmd.c Wed Feb 5 23:44:46 2014
@@ -246,6 +246,7 @@ svn_cl__blame(apr_getopt_t *os,
svn_boolean_t end_revision_unspecified = FALSE;
svn_diff_file_options_t *diff_options = svn_diff_file_options_create(pool);
svn_boolean_t seen_nonexistent_target = FALSE;
+ apr_proc_t *pager_proc = NULL;
SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
opt_state->targets,
@@ -316,6 +317,9 @@ svn_cl__blame(apr_getopt_t *os,
"mode"));
}
+ if (!opt_state->non_interactive && !opt_state->xml)
+ SVN_ERR(svn_cl__start_pager(&pager_proc, pool, pool));
+
for (i = 0; i < targets->nelts; i++)
{
svn_error_t *err;
@@ -409,6 +413,9 @@ svn_cl__blame(apr_getopt_t *os,
if (opt_state->xml && ! opt_state->incremental)
SVN_ERR(svn_cl__xml_print_footer("blame", pool));
+ if (pager_proc)
+ SVN_ERR(svn_cl__close_pager(pager_proc, pool));
+
if (seen_nonexistent_target)
return svn_error_create(
SVN_ERR_ILLEGAL_TARGET, NULL,
Modified: subversion/branches/automatic-pager/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/automatic-pager/subversion/svn/cl.h?rev=1564998&r1=1564997&r2=1564998&view=diff
==============================================================================
--- subversion/branches/automatic-pager/subversion/svn/cl.h (original)
+++ subversion/branches/automatic-pager/subversion/svn/cl.h Wed Feb 5 23:44:46 2014
@@ -848,6 +848,22 @@ svn_cl__deprecated_merge_reintegrate(con
svn_client_ctx_t *ctx,
apr_pool_t *pool);
+
+/* Launch an external pager program and redirect stdout to the pager.
+ *
+ * If the pager was started, return a pointer to the process handle
+ * for the pager in *PAGER_PROC. Else, set *PAGER_PROC to NULL. */
+svn_error_t *
+svn_cl__start_pager(apr_proc_t **pager_proc,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
+/* Close the pager with process handle PAGER_PROC.
+ * Must be called after all output has been written. */
+svn_error_t *
+svn_cl__close_pager(apr_proc_t *pager_proc,
+ apr_pool_t *scratch_pool);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
Modified: subversion/branches/automatic-pager/subversion/svn/diff-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/automatic-pager/subversion/svn/diff-cmd.c?rev=1564998&r1=1564997&r2=1564998&view=diff
==============================================================================
--- subversion/branches/automatic-pager/subversion/svn/diff-cmd.c (original)
+++ subversion/branches/automatic-pager/subversion/svn/diff-cmd.c Wed Feb 5 23:44:46 2014
@@ -188,6 +188,7 @@ svn_cl__diff(apr_getopt_t *os,
struct summarize_baton_t summarize_baton;
const svn_client_diff_summarize_func_t summarize_func =
(opt_state->xml ? summarize_xml : summarize_regular);
+ apr_proc_t *pager_proc = NULL;
if (opt_state->extensions)
options = svn_cstring_split(opt_state->extensions, " \t\n\r", TRUE, pool);
@@ -355,6 +356,9 @@ svn_cl__diff(apr_getopt_t *os,
svn_opt_push_implicit_dot_target(targets, pool);
+ if (!opt_state->non_interactive && !opt_state->diff.summarize)
+ SVN_ERR(svn_cl__start_pager(&pager_proc, pool, pool));
+
iterpool = svn_pool_create(pool);
for (i = 0; i < targets->nelts; ++i)
@@ -488,5 +492,8 @@ svn_cl__diff(apr_getopt_t *os,
svn_pool_destroy(iterpool);
+ if (pager_proc)
+ SVN_ERR(svn_cl__close_pager(pager_proc, pool));
+
return SVN_NO_ERROR;
}
Modified: subversion/branches/automatic-pager/subversion/svn/help-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/automatic-pager/subversion/svn/help-cmd.c?rev=1564998&r1=1564997&r2=1564998&view=diff
==============================================================================
--- subversion/branches/automatic-pager/subversion/svn/help-cmd.c (original)
+++ subversion/branches/automatic-pager/subversion/svn/help-cmd.c Wed Feb 5 23:44:46 2014
@@ -45,6 +45,7 @@ svn_cl__help(apr_getopt_t *os,
{
svn_cl__opt_state_t *opt_state = NULL;
svn_stringbuf_t *version_footer = NULL;
+ apr_proc_t *pager_proc = NULL;
char help_header[] =
N_("usage: svn <subcommand> [options] [args]\n"
@@ -132,16 +133,24 @@ svn_cl__help(apr_getopt_t *os,
version_footer = svn_stringbuf_create(ra_desc_start, pool);
SVN_ERR(svn_ra_print_modules(version_footer, pool));
- return svn_opt_print_help4(os,
- "svn", /* ### erm, derive somehow? */
- opt_state ? opt_state->version : FALSE,
- opt_state ? opt_state->quiet : FALSE,
- opt_state ? opt_state->verbose : FALSE,
- version_footer->data,
- help_header, /* already gettext()'d */
- svn_cl__cmd_table,
- svn_cl__options,
- svn_cl__global_options,
- _(help_footer),
- pool);
+ if (!opt_state->non_interactive)
+ SVN_ERR(svn_cl__start_pager(&pager_proc, pool, pool));
+
+ SVN_ERR(svn_opt_print_help4(os,
+ "svn", /* ### erm, derive somehow? */
+ opt_state ? opt_state->version : FALSE,
+ opt_state ? opt_state->quiet : FALSE,
+ opt_state ? opt_state->verbose : FALSE,
+ version_footer->data,
+ help_header, /* already gettext()'d */
+ svn_cl__cmd_table,
+ svn_cl__options,
+ svn_cl__global_options,
+ _(help_footer),
+ pool));
+
+ if (pager_proc)
+ SVN_ERR(svn_cl__close_pager(pager_proc, pool));
+
+ return SVN_NO_ERROR;
}
Modified: subversion/branches/automatic-pager/subversion/svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/automatic-pager/subversion/svn/util.c?rev=1564998&r1=1564997&r2=1564998&view=diff
==============================================================================
--- subversion/branches/automatic-pager/subversion/svn/util.c (original)
+++ subversion/branches/automatic-pager/subversion/svn/util.c Wed Feb 5 23:44:46 2014
@@ -33,6 +33,15 @@
#include <ctype.h>
#include <assert.h>
+#ifndef WIN32
+#include <unistd.h>
+#else
+#include <crtdbg.h>
+#include <io.h>
+#include <conio.h>
+#endif
+
+#include <apr.h> /* for STDOUT_FILENO */
#include <apr_env.h>
#include <apr_errno.h>
#include <apr_file_info.h>
@@ -1062,3 +1071,86 @@ svn_cl__propset_print_binary_mime_type_w
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_cl__start_pager(apr_proc_t **pager_proc,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool)
+{
+ apr_array_header_t *pager_cmd;
+ const char *pager;
+ const char **args;
+ apr_file_t *stdout_file;
+ apr_status_t apr_err;
+ int i;
+
+ *pager_proc = NULL;
+
+ pager = getenv("SVN_PAGER");
+ if (pager == NULL)
+ pager = getenv("PAGER");
+ /* TODO get pager-cmd from config */
+ if (pager == NULL)
+ return SVN_NO_ERROR;
+
+#ifdef WIN32
+ if (_isatty(STDOUT_FILENO) == 0)
+ return SVN_NO_ERROR;
+#else
+ if (isatty(STDOUT_FILENO) == 0)
+ return SVN_NO_ERROR;
+#endif
+
+ pager_cmd = svn_cstring_split(pager, " \t", TRUE, scratch_pool);
+ if (pager_cmd->nelts <= 0)
+ return SVN_NO_ERROR;
+ args = apr_pcalloc(scratch_pool,
+ (sizeof(const char *) * pager_cmd->nelts + 1));
+ for (i = 0; i < pager_cmd->nelts; i++)
+ args[i] = APR_ARRAY_IDX(pager_cmd, i, const char *);
+ args[i] = NULL;
+
+ apr_err = apr_file_open_stdout(&stdout_file, scratch_pool);
+ if (apr_err)
+ return svn_error_wrap_apr(apr_err, "Can't open stdout");
+
+ *pager_proc = apr_pcalloc(result_pool, sizeof(**pager_proc));
+ SVN_ERR(svn_io_start_cmd3(*pager_proc, NULL, args[0], args, NULL, TRUE,
+ TRUE, NULL,
+ FALSE, NULL,
+ FALSE, NULL,
+ result_pool));
+
+ apr_err = apr_file_dup2(stdout_file, (*pager_proc)->in, result_pool);
+ if (apr_err)
+ return svn_error_wrap_apr(apr_err, "Can't redirect stdout");
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_cl__close_pager(apr_proc_t *pager_proc,
+ apr_pool_t *scratch_pool)
+{
+ apr_file_t *stdout_file;
+ apr_status_t apr_err;
+ svn_error_t *err;
+
+ apr_err = apr_file_open_stdout(&stdout_file, scratch_pool);
+ if (apr_err)
+ return svn_error_wrap_apr(apr_err, "Can't open stdout");
+ SVN_ERR(svn_io_file_close(stdout_file, scratch_pool));
+ SVN_ERR(svn_io_file_close(pager_proc->in, scratch_pool));
+ err = svn_io_wait_for_cmd(pager_proc,
+ apr_psprintf(scratch_pool, "%ld",
+ (long)pager_proc->pid),
+ NULL, NULL, scratch_pool);
+ if (err && err->apr_err == SVN_ERR_EXTERNAL_PROGRAM)
+ {
+ svn_handle_warning2(stderr, err, "svn: ");
+ svn_error_clear(err);
+ }
+ else
+ SVN_ERR(err);
+
+ return SVN_NO_ERROR;
+}