That patch exacerbated a problem that was already there to a lesser extent: it
was wrongly using native-encoded paths (from os->argv[]) before they had been
converted to UTF-8. This version fixes that.
- Julian
In "svn diff", avoid using a deprecated function and fix an encoding bug.
* subversion/clients/cmdline/diff-cmd.c
(parse_path): New helper function.
(svn_cl__diff): Simplify the code for argument parsing, using a helper,
and avoid using the recently deprecated svn_opt_args_to_target_array.
Fix encoding bug: was passing a native-encoded path to svn_path_is_url.
Index: subversion/clients/cmdline/diff-cmd.c
===================================================================
--- subversion/clients/cmdline/diff-cmd.c (revision 11829)
+++ subversion/clients/cmdline/diff-cmd.c (working copy)
@@ -38,6 +38,24 @@
/*** Code. ***/
+/* Parse PATH of the form "path[@rev]" into TRUEPATH and *REV,
+ overwriting *REV only if "@rev" was present. */
+static svn_error_t *
+parse_path (svn_opt_revision_t *rev,
+ const char **truepath,
+ const char *path,
+ apr_pool_t *pool)
+{
+ svn_opt_revision_t new_rev;
+ const char *new_path;
+
+ SVN_ERR (svn_opt_parse_path (&new_rev, &new_path, path, pool));
+ *truepath = svn_path_canonicalize (new_path, pool);
+ if (new_rev.kind != svn_opt_revision_unspecified)
+ *rev = new_rev;
+ return SVN_NO_ERROR;
+}
+
/* An svn_opt_subcommand_t to handle the 'diff' command.
This implements the `svn_opt_subcommand_t' interface. */
svn_error_t *
@@ -68,22 +86,22 @@
if ((status = apr_file_open_stderr (&errfile, pool)))
return svn_error_wrap_apr (status, _("Can't open stderr"));
+ SVN_ERR (svn_opt_args_to_target_array2 (&targets, os,
+ opt_state->targets, pool));
+
if (! opt_state->old_target && ! opt_state->new_target
- && (os->argc - os->ind == 2)
- && svn_path_is_url (os->argv[os->ind])
- && svn_path_is_url (os->argv[os->ind + 1])
+ && (targets->nelts == 2)
+ && svn_path_is_url (APR_ARRAY_IDX (targets, 0, const char *))
+ && svn_path_is_url (APR_ARRAY_IDX (targets, 1, const char *))
&& opt_state->start_revision.kind == svn_opt_revision_unspecified
&& opt_state->end_revision.kind == svn_opt_revision_unspecified)
{
/* The 'svn diff OLD_URL[@OLDREV] NEW_URL[@NEWREV]' case matches. */
- SVN_ERR (svn_opt_args_to_target_array (&targets, os,
- opt_state->targets,
- &(opt_state->start_revision),
- &(opt_state->end_revision),
- TRUE, /* extract @revs */ pool));
- old_target = APR_ARRAY_IDX (targets, 0, const char *);
- new_target = APR_ARRAY_IDX (targets, 1, const char *);
+ SVN_ERR (parse_path (&opt_state->start_revision, &old_target,
+ APR_ARRAY_IDX (targets, 0, const char *), pool));
+ SVN_ERR (parse_path (&opt_state->end_revision, &new_target,
+ APR_ARRAY_IDX (targets, 1, const char *), pool));
targets->nelts = 0;
if (opt_state->start_revision.kind == svn_opt_revision_unspecified)
@@ -93,28 +111,17 @@
}
else if (opt_state->old_target)
{
- apr_array_header_t *tmp, *tmp2;
-
/* The 'svn diff --old=OLD[@OLDREV] [--new=NEW[@NEWREV]]
[PATH...]' case matches. */
- SVN_ERR (svn_opt_args_to_target_array2 (&targets, os,
- opt_state->targets, pool));
-
- tmp = apr_array_make (pool, 2, sizeof (const char *));
- APR_ARRAY_PUSH (tmp, const char *) = (opt_state->old_target);
- APR_ARRAY_PUSH (tmp, const char *) = (opt_state->new_target
- ? opt_state->new_target
- : APR_ARRAY_IDX (tmp, 0,
- const char *));
-
- SVN_ERR (svn_opt_args_to_target_array (&tmp2, os, tmp,
- &(opt_state->start_revision),
- &(opt_state->end_revision),
- TRUE, /* extract @revs */ pool));
+ SVN_ERR (parse_path (&opt_state->start_revision, &old_target,
+ opt_state->old_target, pool));
- old_target = APR_ARRAY_IDX (tmp2, 0, const char *);
- new_target = APR_ARRAY_IDX (tmp2, 1, const char *);
+ SVN_ERR (parse_path (&opt_state->end_revision, &new_target,
+ opt_state->new_target
+ ? opt_state->new_target
+ : opt_state->old_target,
+ pool));
if (opt_state->start_revision.kind == svn_opt_revision_unspecified)
opt_state->start_revision.kind = svn_path_is_url (old_target)
@@ -126,29 +133,17 @@
}
else
{
- apr_array_header_t *tmp, *tmp2;
svn_boolean_t working_copy_present = FALSE, url_present = FALSE;
/* The 'svn diff [-r M[:N]] [TARGET[@REV]...]' case matches. */
/* Here each target is a pegged object. Find out the starting
and ending paths for each target. */
- SVN_ERR (svn_opt_args_to_target_array2 (&targets, os,
- opt_state->targets, pool));
svn_opt_push_implicit_dot_target (targets, pool);
- tmp = apr_array_make (pool, 2, sizeof (const char *));
- APR_ARRAY_PUSH (tmp, const char *) = ".";
- APR_ARRAY_PUSH (tmp, const char *) = ".";
-
- SVN_ERR (svn_opt_args_to_target_array (&tmp2, os, tmp,
- &(opt_state->start_revision),
- &(opt_state->end_revision),
- TRUE, /* extract @revs */ pool));
-
- old_target = APR_ARRAY_IDX (tmp2, 0, const char *);
- new_target = APR_ARRAY_IDX (tmp2, 1, const char *);
+ old_target = "";
+ new_target = "";
/* Check to see if at least one of our paths is a working copy
path. */
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Fri Nov 12 00:58:11 2004