summaryrefslogtreecommitdiff
path: root/tools/diff
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-08-05 16:22:51 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-08-05 16:22:51 +0000
commitcf46733632c7279a9fd0fe6ce26f9185a4ae82a9 (patch)
treeda27775a2161723ef342e91af41a8b51fedef405 /tools/diff
parentbb0ef45f7c46b0ae221b26265ef98a768c33f820 (diff)
downloadsubversion-tarball-cf46733632c7279a9fd0fe6ce26f9185a4ae82a9.tar.gz
Diffstat (limited to 'tools/diff')
-rw-r--r--tools/diff/diff.c15
-rw-r--r--tools/diff/diff3.c153
-rw-r--r--tools/diff/diff4.c3
3 files changed, 156 insertions, 15 deletions
diff --git a/tools/diff/diff.c b/tools/diff/diff.c
index c4b5e9d..c69a6d9 100644
--- a/tools/diff/diff.c
+++ b/tools/diff/diff.c
@@ -43,9 +43,11 @@ do_diff(svn_stream_t *ostream,
SVN_ERR(svn_diff_file_diff_2(&diff, original, modified, options, pool));
*has_changes = svn_diff_contains_diffs(diff);
- return svn_diff_file_output_unified3(ostream, diff, original, modified,
+ return svn_diff_file_output_unified4(ostream, diff, original, modified,
NULL, NULL, SVN_APR_LOCALE_CHARSET,
- NULL, show_c_function, pool);
+ NULL, show_c_function,
+ options->context_size,
+ NULL, NULL, pool);
}
static void
@@ -112,7 +114,16 @@ int main(int argc, const char *argv[])
diff_options->ignore_space = svn_diff_file_ignore_space_all;
continue;
}
+
APR_ARRAY_PUSH(options_array, const char *) = argv[i];
+
+ /* Special case: '-U' takes an argument, so capture the
+ * next argument in the array. */
+ if (argv[i][1] == 'U' && !argv[i][2])
+ {
+ i++;
+ APR_ARRAY_PUSH(options_array, const char *) = argv[i];
+ }
}
else
{
diff --git a/tools/diff/diff3.c b/tools/diff/diff3.c
index 63d7dec..5502254 100644
--- a/tools/diff/diff3.c
+++ b/tools/diff/diff3.c
@@ -28,11 +28,19 @@
#include "svn_pools.h"
#include "svn_diff.h"
#include "svn_io.h"
+#include "svn_opt.h"
+#include "private/svn_token.h"
static svn_error_t *
do_diff3(svn_stream_t *ostream,
- const char *original, const char *modified, const char *latest,
+ const char *original,
+ const char *modified,
+ const char *latest,
+ const char *conflict_original,
+ const char *conflict_modified,
+ const char *conflict_latest,
+ svn_diff_conflict_display_style_t conflict_style,
svn_boolean_t *has_changes,
apr_pool_t *pool)
{
@@ -43,38 +51,129 @@ do_diff3(svn_stream_t *ostream,
*has_changes = svn_diff_contains_diffs(diff);
- SVN_ERR(svn_diff_file_output_merge2(ostream, diff,
+ SVN_ERR(svn_diff_file_output_merge3(ostream, diff,
original, modified, latest,
- NULL, NULL, NULL, NULL,
- svn_diff_conflict_display_modified_latest,
+ conflict_original,
+ conflict_modified,
+ conflict_latest,
+ "=======",
+ conflict_style,
+ NULL, NULL, /* cancel */
pool));
return NULL;
}
-int main(int argc, char *argv[])
+int main(int argc, const char *argv[])
{
apr_pool_t *pool;
svn_stream_t *ostream;
int rc;
- svn_error_t *svn_err;
+ svn_error_t *svn_err = SVN_NO_ERROR;
+ apr_getopt_t *opts;
+ svn_boolean_t help = FALSE;
+
+ enum {
+ conflict_style_opt = SVN_OPT_FIRST_LONGOPT_ID
+ };
+ static const apr_getopt_option_t options[] = {
+ {"conflict-style", conflict_style_opt, 1, ""},
+ {"label", 'L', 1, ""},
+ {"show-overlap", 'E', 0, ""},
+ {"merge", 'm', 0, ""},
+ {"help", 'h', 0, ""},
+ {NULL, '?', 0, ""},
+ {NULL, 0, 0, NULL}
+ };
+ svn_diff_conflict_display_style_t conflict_style
+ = svn_diff_conflict_display_modified_latest;
+ const svn_token_map_t style_map[] = {
+ { "modified-latest",
+ svn_diff_conflict_display_modified_latest },
+ { "resolved-modified-latest",
+ svn_diff_conflict_display_resolved_modified_latest },
+ { "modified-original-latest",
+ svn_diff_conflict_display_modified_original_latest },
+ { "modified",
+ svn_diff_conflict_display_modified },
+ { "latest",
+ svn_diff_conflict_display_latest },
+ { "only-conflicts",
+ svn_diff_conflict_display_only_conflicts },
+ {NULL, 0}
+ };
+ const char *conflict_original = NULL;
+ const char *conflict_modified = NULL;
+ const char *conflict_latest = NULL;
apr_initialize();
pool = svn_pool_create(NULL);
- svn_err = svn_stream_for_stdout(&ostream, pool);
+ apr_getopt_init(&opts, pool, argc, argv);
+ opts->interleave = 1;
+ while (!svn_err)
+ {
+ int opt;
+ const char *arg;
+ apr_status_t status = apr_getopt_long(opts, options, &opt, &arg);
+
+ if (APR_STATUS_IS_EOF(status))
+ break;
+ if (status != APR_SUCCESS)
+ {
+ svn_err = svn_error_wrap_apr(status, "getopt failure");
+ break;
+ }
+ switch (opt)
+ {
+ case conflict_style_opt:
+ {
+ int val;
+ svn_err = svn_token__from_word_err(&val, style_map, arg);
+ conflict_style = val;
+ break;
+ }
+ case 'L':
+ if (!conflict_modified)
+ conflict_modified = apr_pstrcat(pool, "<<<<<<< ", arg, SVN_VA_NULL);
+ else if (!conflict_original)
+ conflict_original = apr_pstrcat(pool, "||||||| ", arg, SVN_VA_NULL);
+ else if (!conflict_latest)
+ conflict_latest = apr_pstrcat(pool, ">>>>>>> ", arg, SVN_VA_NULL);
+ else
+ svn_err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ "too many labels");
+ break;
+ case 'E':
+ case 'm':
+ /* These are allowed and ignored so that all the options
+ passed when invoking --diff3-cmd are accepted as that
+ makes it easier to use this as an external diff3
+ program. */
+ break;
+ case 'h':
+ case '?':
+ help = TRUE;
+ break;
+ }
+ }
+
+ if (!svn_err)
+ svn_err = svn_stream_for_stdout(&ostream, pool);
if (svn_err)
{
svn_handle_error2(svn_err, stdout, FALSE, "diff3: ");
+ svn_error_clear(svn_err);
rc = 2;
}
- else if (argc == 4)
+ else if (argc - opts->ind == 3 && !help)
{
svn_boolean_t has_changes;
- svn_err = do_diff3(ostream, argv[2], argv[1], argv[3],
- &has_changes, pool);
+ svn_err = do_diff3(ostream, argv[argc-2], argv[argc-3], argv[argc-1],
+ conflict_original, conflict_modified, conflict_latest,
+ conflict_style, &has_changes, pool);
if (svn_err == NULL)
{
rc = has_changes ? 1 : 0;
@@ -88,8 +187,38 @@ int main(int argc, char *argv[])
else
{
svn_error_clear(svn_stream_printf(ostream, pool,
- "Usage: %s <mine> <older> <yours>\n",
- argv[0]));
+ "Usage: %s [options] <mine> <older> <yours>\n"
+ "Options:\n"
+ " --conflict-style STYLE\n"
+ " where STYLE can be:\n"
+ " %s\n"
+ " %s\n"
+ " %s\n"
+ " %s\n"
+ " %s\n"
+ " %s\n"
+ "\n"
+ " --label [-L] LABEL\n"
+ " can be repeated up to three times\n"
+ "\n"
+ " --merge [-m]\n"
+ " ignored (present for compatibility)\n"
+ "\n"
+ " --show-overlap [-E]\n"
+ " ignored (present for compatibility)\n",
+ argv[0],
+ svn_token__to_word(style_map,
+ svn_diff_conflict_display_modified_latest),
+ svn_token__to_word(style_map,
+ svn_diff_conflict_display_resolved_modified_latest),
+ svn_token__to_word(style_map,
+ svn_diff_conflict_display_modified_original_latest),
+ svn_token__to_word(style_map,
+ svn_diff_conflict_display_modified),
+ svn_token__to_word(style_map,
+ svn_diff_conflict_display_latest),
+ svn_token__to_word(style_map,
+ svn_diff_conflict_display_only_conflicts)));
rc = 2;
}
diff --git a/tools/diff/diff4.c b/tools/diff/diff4.c
index 084184c..58216a8 100644
--- a/tools/diff/diff4.c
+++ b/tools/diff/diff4.c
@@ -42,10 +42,11 @@ do_diff4(svn_stream_t *ostream,
SVN_ERR(svn_diff_file_diff4_2(&diff, original, modified, latest, ancestor,
svn_diff_file_options_create(pool), pool));
- SVN_ERR(svn_diff_file_output_merge2(ostream, diff,
+ SVN_ERR(svn_diff_file_output_merge3(ostream, diff,
original, modified, latest,
NULL, NULL, NULL, NULL,
svn_diff_conflict_display_modified_latest,
+ NULL, NULL, /* cancel */
pool));
return NULL;