subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From g..@apache.org
Subject svn commit: r1549081 [12/18] - in /subversion/branches/invoke-diff-cmd-feature: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ contrib/server-side/ contrib/server-side/svncutter/ subversion/bindings/javahl/native/ subversion/bin...
Date Sun, 08 Dec 2013 17:56:53 GMT
Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svn/mergeinfo-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svn/mergeinfo-cmd.c?rev=1549081&r1=1549080&r2=1549081&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svn/mergeinfo-cmd.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svn/mergeinfo-cmd.c Sun Dec  8 17:56:46 2013
@@ -37,6 +37,7 @@
 #include "svn_error_codes.h"
 #include "svn_types.h"
 #include "cl.h"
+#include "cl-log.h"
 
 #include "svn_private_config.h"
 
@@ -57,59 +58,23 @@ print_log_rev(void *baton,
   return SVN_NO_ERROR;
 }
 
-/* The separator between log messages. */
-#define SEP_STRING \
-  "------------------------------------------------------------------------\n"
-
-/* Implements the svn_log_entry_receiver_t interface. */
+/* Implements a svn_log_entry_receiver_t interface that filters out changed
+ * paths data before calling the svn_cl__log_entry_receiver().  Right now we
+ * always have to pass TRUE for discover_changed_paths for
+ * svn_client_mergeinfo_log2() due to the side effect of that option.  The
+ * svn_cl__log_entry_receiver() discovers if it should print the changed paths
+ * implicitly by the path info existing.  As a result this filter is needed
+ * to allow expected output without changed paths.
+ */
 static svn_error_t *
 print_log_details(void *baton,
                   svn_log_entry_t *log_entry,
                   apr_pool_t *pool)
 {
-  const char *author;
-  const char *date;
-  const char *message;
-
-  svn_compat_log_revprops_out(&author, &date, &message, log_entry->revprops);
-
-  if (author == NULL)
-    author = _("(no author)");
-
-  if (date && date[0])
-    /* Convert date to a format for humans. */
-    SVN_ERR(svn_cl__time_cstring_to_human_cstring(&date, date, pool));
-  else
-    date = _("(no date)");
-
-  if (log_entry->non_inheritable)
-    SVN_ERR(svn_cmdline_printf(pool,
-                               SEP_STRING "r%ld* | %s | %s",
-                               log_entry->revision, author, date));
-  else
-    SVN_ERR(svn_cmdline_printf(pool,
-                               SEP_STRING "r%ld | %s | %s",
-                               log_entry->revision, author, date));
-
-  if (message != NULL)
-    {
-      /* Number of lines in the msg. */
-      int lines = svn_cstring_count_newlines(message) + 1;
-
-      SVN_ERR(svn_cmdline_printf(pool,
-                                 Q_(" | %d line", " | %d lines", lines),
-                                 lines));
-    }
-
-  SVN_ERR(svn_cmdline_printf(pool, "\n"));
-
-  if (message != NULL)
-    {
-      /* A blank line always precedes the log message. */
-      SVN_ERR(svn_cmdline_printf(pool, "\n%s\n", message));
-    }
+  log_entry->changed_paths = NULL;
+  log_entry->changed_paths2 = NULL;
 
-  return SVN_NO_ERROR;
+  return svn_cl__log_entry_receiver(baton, log_entry, pool);
 }
 
 /* Draw a diagram (by printing text to the console) summarizing the state
@@ -275,7 +240,8 @@ mergeinfo_summary(
 
   target_is_wc = (! svn_path_is_url(target_path_or_url))
                  && (target_revision->kind == svn_opt_revision_unspecified
-                     || target_revision->kind == svn_opt_revision_working);
+                     || target_revision->kind == svn_opt_revision_working 
+                     || target_revision->kind == svn_opt_revision_base);
   SVN_ERR(svn_client_get_merging_summary(
             &is_reintegration,
             &yca_url, &yca_rev,
@@ -305,26 +271,50 @@ mergeinfo_log(svn_boolean_t finding_merg
               const svn_opt_revision_t *src_end_revision,
               svn_depth_t depth,
               svn_boolean_t include_log_details,
+              svn_boolean_t quiet,
+              svn_boolean_t verbose,
+              svn_boolean_t incremental,
               svn_client_ctx_t *ctx,
               apr_pool_t *pool)
 {
   apr_array_header_t *revprops;
-  svn_log_entry_receiver_t log_reciever;
+  svn_log_entry_receiver_t log_receiver;
+  void *log_receiver_baton;
 
   if (include_log_details)
     {
+      svn_cl__log_receiver_baton *baton;
+
       revprops = apr_array_make(pool, 3, sizeof(const char *));
       APR_ARRAY_PUSH(revprops, const char *) = SVN_PROP_REVISION_AUTHOR;
       APR_ARRAY_PUSH(revprops, const char *) = SVN_PROP_REVISION_DATE;
-      APR_ARRAY_PUSH(revprops, const char *) = SVN_PROP_REVISION_LOG;
+      if (!quiet)
+        APR_ARRAY_PUSH(revprops, const char *) = SVN_PROP_REVISION_LOG;
+
+      if (verbose)
+        log_receiver = svn_cl__log_entry_receiver;
+      else
+        log_receiver = print_log_details;
 
-      log_reciever = print_log_details;
+      baton = apr_palloc(pool, sizeof(svn_cl__log_receiver_baton));
+      baton->ctx = ctx;
+      baton->target_path_or_url = target;
+      baton->target_peg_revision = *tgt_peg_revision;
+      baton->omit_log_message = quiet;
+      baton->show_diff = FALSE;
+      baton->depth = depth;
+      baton->diff_extensions = NULL;
+      baton->merge_stack = NULL; 
+      baton->search_patterns = NULL;
+      baton->pool = pool;
+      log_receiver_baton = baton; 
     }
   else
     {
       /* We need only revisions number, not revision properties. */
       revprops = apr_array_make(pool, 0, sizeof(const char *));
-      log_reciever = print_log_rev;
+      log_receiver = print_log_rev;
+      log_receiver_baton = NULL;
     }
 
   SVN_ERR(svn_client_mergeinfo_log2(finding_merged, target,
@@ -332,10 +322,13 @@ mergeinfo_log(svn_boolean_t finding_merg
                                     source, src_peg_revision,
                                     src_start_revision,
                                     src_end_revision,
-                                    log_reciever, NULL,
+                                    log_receiver, log_receiver_baton,
                                     TRUE, depth, revprops, ctx,
                                     pool));
 
+  if (include_log_details && !incremental)
+    SVN_ERR(svn_cmdline_printf(pool, SVN_CL__LOG_SEP_STRING));
+
   return SVN_NO_ERROR;
 }
 
@@ -404,6 +397,24 @@ svn_cl__mergeinfo(apr_getopt_t *os,
   else
     src_end_revision = &(opt_state->end_revision);
 
+  if (!opt_state->mergeinfo_log)
+    {
+      if (opt_state->quiet)
+        return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                _("--quiet (-q) option valid only with --log "
+                                  "option"));
+
+      if (opt_state->verbose)
+        return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                _("--verbose (-v) option valid only with "
+                                  "--log option"));
+
+      if (opt_state->incremental)
+        return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                _("--incremental option valid only with "
+                                  "--log option"));
+    }
+
   /* Do the real work, depending on the requested data flavor. */
   if (opt_state->show_revs == svn_cl__show_revs_merged)
     {
@@ -412,7 +423,8 @@ svn_cl__mergeinfo(apr_getopt_t *os,
                             src_start_revision,
                             src_end_revision,
                             depth, opt_state->mergeinfo_log,
-                            ctx, pool));
+                            opt_state->quiet, opt_state->verbose,
+                            opt_state->incremental, ctx, pool));
     }
   else if (opt_state->show_revs == svn_cl__show_revs_eligible)
     {
@@ -421,7 +433,8 @@ svn_cl__mergeinfo(apr_getopt_t *os,
                             src_start_revision,
                             src_end_revision,
                             depth, opt_state->mergeinfo_log,
-                            ctx, pool));
+                            opt_state->quiet, opt_state->verbose,
+                            opt_state->incremental, ctx, pool));
     }
   else
     {

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svn/propget-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svn/propget-cmd.c?rev=1549081&r1=1549080&r2=1549081&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svn/propget-cmd.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svn/propget-cmd.c Sun Dec  8 17:56:46 2013
@@ -99,7 +99,7 @@ print_properties_xml(const char *pname,
             name_local = svn_dirent_local_style(iprop->path_or_url, iterpool);
 
           svn_xml_make_open_tag(&sb, iterpool, svn_xml_normal, "target",
-                            "path", name_local, NULL);
+                            "path", name_local, SVN_VA_NULL);
 
           svn_cmdline__print_xml_prop(&sb, pname, propval, TRUE, iterpool);
           svn_xml_make_close_tag(&sb, iterpool, "target");
@@ -122,7 +122,7 @@ print_properties_xml(const char *pname,
       svn_pool_clear(iterpool);
 
       svn_xml_make_open_tag(&sb, iterpool, svn_xml_normal, "target",
-                        "path", filename, NULL);
+                        "path", filename, SVN_VA_NULL);
       svn_cmdline__print_xml_prop(&sb, pname, propval, FALSE, iterpool);
       svn_xml_make_close_tag(&sb, iterpool, "target");
 
@@ -375,7 +375,7 @@ svn_cl__propget(apr_getopt_t *os,
 
               svn_xml_make_open_tag(&sb, pool, svn_xml_normal,
                                     "revprops",
-                                    "rev", revstr, NULL);
+                                    "rev", revstr, SVN_VA_NULL);
 
               svn_cmdline__print_xml_prop(&sb, pname_utf8, propval, FALSE,
                                           pool);

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svn/proplist-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svn/proplist-cmd.c?rev=1549081&r1=1549080&r2=1549081&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svn/proplist-cmd.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svn/proplist-cmd.c Sun Dec  8 17:56:46 2013
@@ -83,7 +83,7 @@ proplist_receiver_xml(void *baton,
             name_local = svn_dirent_local_style(iprop->path_or_url, iterpool);
 
           svn_xml_make_open_tag(&sb, iterpool, svn_xml_normal, "target",
-                            "path", name_local, NULL);
+                            "path", name_local, SVN_VA_NULL);
           SVN_ERR(svn_cmdline__print_xml_prop_hash(&sb, iprop->prop_hash,
                                                    (! opt_state->verbose),
                                                    TRUE, iterpool));
@@ -105,7 +105,7 @@ proplist_receiver_xml(void *baton,
     {
       /* "<target ...>" */
         svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "target",
-                              "path", name_local, NULL);
+                              "path", name_local, SVN_VA_NULL);
 
         SVN_ERR(svn_cmdline__print_xml_prop_hash(&sb, prop_hash,
                                                  (! opt_state->verbose),
@@ -230,7 +230,7 @@ svn_cl__proplist(apr_getopt_t *os,
 
           svn_xml_make_open_tag(&sb, scratch_pool, svn_xml_normal,
                                 "revprops",
-                                "rev", revstr, NULL);
+                                "rev", revstr, SVN_VA_NULL);
           SVN_ERR(svn_cmdline__print_xml_prop_hash(&sb, proplist,
                                                    (! opt_state->verbose),
                                                    FALSE, scratch_pool));
@@ -299,7 +299,7 @@ svn_cl__proplist(apr_getopt_t *os,
                    errors, opt_state->quiet,
                    SVN_ERR_UNVERSIONED_RESOURCE,
                    SVN_ERR_ENTRY_NOT_FOUND,
-                   SVN_NO_ERROR));
+                   0));
         }
       svn_pool_destroy(iterpool);
 

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svn/status-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svn/status-cmd.c?rev=1549081&r1=1549080&r2=1549081&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svn/status-cmd.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svn/status-cmd.c Sun Dec  8 17:56:46 2013
@@ -115,7 +115,7 @@ print_start_target_xml(const char *targe
   svn_stringbuf_t *sb = svn_stringbuf_create_empty(pool);
 
   svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "target",
-                        "path", target, NULL);
+                        "path", target, SVN_VA_NULL);
 
   return svn_cl__error_checked_fputs(sb->data, stdout);
 }
@@ -135,7 +135,7 @@ print_finish_target_xml(svn_revnum_t rep
       const char *repos_rev_str;
       repos_rev_str = apr_psprintf(pool, "%ld", repos_rev);
       svn_xml_make_open_tag(&sb, pool, svn_xml_self_closing, "against",
-                            "revision", repos_rev_str, NULL);
+                            "revision", repos_rev_str, SVN_VA_NULL);
     }
 
   svn_xml_make_close_tag(&sb, pool, "target");
@@ -358,7 +358,8 @@ svn_cl__status(apr_getopt_t *os,
                           NULL, opt_state->quiet,
                           /* not versioned: */
                           SVN_ERR_WC_NOT_WORKING_COPY,
-                          SVN_ERR_WC_PATH_NOT_FOUND));
+                          SVN_ERR_WC_PATH_NOT_FOUND,
+                          0));
 
       if (opt_state->xml)
         SVN_ERR(print_finish_target_xml(repos_rev, iterpool));
@@ -389,7 +390,7 @@ svn_cl__status(apr_getopt_t *os,
               svn_stringbuf_setempty(buf);
               svn_xml_make_open_tag(&buf, scratch_pool, svn_xml_normal,
                                     "changelist", "name", changelist_name,
-                                    NULL);
+                                    SVN_VA_NULL);
               SVN_ERR(svn_cl__error_checked_fputs(buf->data, stdout));
             }
           else

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svn/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svn/status.c?rev=1549081&r1=1549080&r2=1549081&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svn/status.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svn/status.c Sun Dec  8 17:56:46 2013
@@ -492,7 +492,8 @@ svn_cl__print_status_xml(const char *tar
   path = make_relpath(target_abspath, target_path, path, pool, pool);
 
   svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "entry",
-                        "path", svn_dirent_local_style(path, pool), NULL);
+                        "path", svn_dirent_local_style(path, pool),
+                        SVN_VA_NULL);
 
   att_hash = apr_hash_make(pool);
   svn_hash_sets(att_hash, "item",
@@ -562,7 +563,7 @@ svn_cl__print_status_xml(const char *tar
                             generate_status_desc(combined_repos_status(status)),
                             "props",
                             generate_status_desc(status->repos_prop_status),
-                            NULL);
+                            SVN_VA_NULL);
       if (status->repos_lock)
         svn_cl__print_xml_lock(&sb, status->repos_lock, pool);
 

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svn/svn.c?rev=1549081&r1=1549080&r2=1549081&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svn/svn.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svn/svn.c Sun Dec  8 17:56:46 2013
@@ -489,7 +489,7 @@ const svn_opt_subcommand_desc2_t svn_cl_
      "\n"
      "  If specified, REV determines in which revision the target is first\n"
      "  looked up.\n"),
-    {'r'} },
+    {'r', opt_ignore_keywords} },
 
   { "changelist", svn_cl__changelist, {"cl"}, N_
     ("Associate (or dissociate) changelist CLNAME with the named files.\n"
@@ -1172,7 +1172,8 @@ const svn_opt_subcommand_desc2_t svn_cl_
      "  and the default for TARGET is HEAD for a URL or BASE for a WC path.\n"
      "\n"
      "  The depth can be 'empty' or 'infinity'; the default is 'empty'.\n"),
-    {'r', 'R', opt_depth, opt_show_revs, opt_mergeinfo_log} },
+    {'r', 'R', 'q', 'v', opt_depth, opt_show_revs, opt_mergeinfo_log,
+      opt_incremental } },
 
   { "mkdir", svn_cl__mkdir, {0}, N_
     ("Create a new directory under version control.\n"
@@ -1771,23 +1772,13 @@ add_search_pattern_to_latest_group(svn_c
 
 /*** Main. ***/
 
-/* Report and clear the error ERR, and return EXIT_FAILURE. Suppress the
- * error message if it is SVN_ERR_IO_PIPE_WRITE_ERROR. */
-#define EXIT_ERROR(err)                                                 \
-  svn_cmdline_handle_exit_error(err, NULL, "svn: ")
-
-/* A redefinition of the public SVN_INT_ERR macro, that suppresses the
- * error message if it is SVN_ERR_IO_PIPE_WRITE_ERROR. */
-#undef SVN_INT_ERR
-#define SVN_INT_ERR(expr)                                        \
-  do {                                                           \
-    svn_error_t *svn_err__temp = (expr);                         \
-    if (svn_err__temp)                                           \
-      return EXIT_ERROR(svn_err__temp);                          \
-  } while (0)
-
-static int
-sub_main(int argc, const char *argv[], apr_pool_t *pool)
+/*
+ * On success, leave *EXIT_CODE untouched and return SVN_NO_ERROR. On error,
+ * either return an error to be displayed, or set *EXIT_CODE to non-zero and
+ * return SVN_NO_ERROR.
+ */
+static svn_error_t *
+sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
 {
   svn_error_t *err;
   int opt_id;
@@ -1814,18 +1805,18 @@ sub_main(int argc, const char *argv[], a
   received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
 
   /* Check library versions */
-  SVN_INT_ERR(check_lib_versions());
+  SVN_ERR(check_lib_versions());
 
 #if defined(WIN32) || defined(__CYGWIN__)
   /* Set the working copy administrative directory name. */
   if (getenv("SVN_ASP_DOT_NET_HACK"))
     {
-      SVN_INT_ERR(svn_wc_set_adm_dir("_svn", pool));
+      SVN_ERR(svn_wc_set_adm_dir("_svn", pool));
     }
 #endif
 
   /* Initialize the RA library. */
-  SVN_INT_ERR(svn_ra_initialize(pool));
+  SVN_ERR(svn_ra_initialize(pool));
 
   /* Init our changelists hash. */
   changelists = apr_hash_make(pool);
@@ -1843,12 +1834,13 @@ sub_main(int argc, const char *argv[], a
   /* No args?  Show usage. */
   if (argc <= 1)
     {
-      SVN_INT_ERR(svn_cl__help(NULL, NULL, pool));
-      return EXIT_FAILURE;
+      SVN_ERR(svn_cl__help(NULL, NULL, pool));
+      *exit_code = EXIT_FAILURE;
+      return SVN_NO_ERROR;
     }
 
   /* Else, parse options. */
-  SVN_INT_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
+  SVN_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
 
   os->interleave = 1;
   while (1)
@@ -1863,8 +1855,9 @@ sub_main(int argc, const char *argv[], a
         break;
       else if (apr_err)
         {
-          SVN_INT_ERR(svn_cl__help(NULL, NULL, pool));
-          return EXIT_FAILURE;
+          SVN_ERR(svn_cl__help(NULL, NULL, pool));
+          *exit_code = EXIT_FAILURE;
+          return SVN_NO_ERROR;
         }
 
       /* Stash the option code in an array before parsing it. */
@@ -1873,19 +1866,17 @@ sub_main(int argc, const char *argv[], a
       switch (opt_id) {
       case 'l':
         {
-          SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+          SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
           err = svn_cstring_atoi(&opt_state.limit, utf8_opt_arg);
           if (err)
             {
-              err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, err,
-                                     _("Non-numeric limit argument given"));
-              return EXIT_ERROR(err);
+              return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, err,
+                                      _("Non-numeric limit argument given"));
             }
           if (opt_state.limit <= 0)
             {
-              err = svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
-                                    _("Argument to --limit must be positive"));
-              return EXIT_ERROR(err);
+              return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
+                                      _("Argument to --limit must be positive"));
             }
         }
         break;
@@ -1898,16 +1889,14 @@ sub_main(int argc, const char *argv[], a
         {
           apr_array_header_t *change_revs;
 
-          SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+          SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
           change_revs = svn_cstring_split(utf8_opt_arg, ", \n\r\t\v", TRUE,
                                           pool);
 
           if (opt_state.old_target)
             {
-              err = svn_error_create
-                (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                 _("Can't specify -c with --old"));
-              return EXIT_ERROR(err);
+              return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                      _("Can't specify -c with --old"));
             }
 
           for (i = 0; i < change_revs->nelts; i++)
@@ -1935,12 +1924,11 @@ sub_main(int argc, const char *argv[], a
                 {
                   if (changeno < 0 || is_negative)
                     {
-                      err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR,
-                                              NULL,
-                                              _("Negative number in range (%s)"
-                                                " not supported with -c"),
-                                              change_str);
-                      return EXIT_ERROR(err);
+                      return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR,
+                                               NULL,
+                                               _("Negative number in range (%s)"
+                                                 " not supported with -c"),
+                                               change_str);
                     }
                   s = end + 1;
                   while (*s == 'r')
@@ -1949,17 +1937,15 @@ sub_main(int argc, const char *argv[], a
                 }
               if (end == change_str || *end != '\0')
                 {
-                  err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                                          _("Non-numeric change argument (%s) "
-                                            "given to -c"), change_str);
-                  return EXIT_ERROR(err);
+                  return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                           _("Non-numeric change argument (%s) "
+                                             "given to -c"), change_str);
                 }
 
               if (changeno == 0)
                 {
-                  err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                                         _("There is no change 0"));
-                  return EXIT_ERROR(err);
+                  return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                          _("There is no change 0"));
                 }
 
               if (is_negative)
@@ -1995,15 +1981,13 @@ sub_main(int argc, const char *argv[], a
         break;
       case 'r':
         opt_state.used_revision_arg = TRUE;
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
         if (svn_opt_parse_revision_to_range(opt_state.revision_ranges,
                                             utf8_opt_arg, pool) != 0)
           {
-            err = svn_error_createf
-                (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+            return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                  _("Syntax error in revision argument '%s'"),
                  utf8_opt_arg);
-            return EXIT_ERROR(err);
           }
         break;
       case 'v':
@@ -2026,9 +2010,9 @@ sub_main(int argc, const char *argv[], a
         /* We read the raw file content here.  We will convert it to UTF-8
          * later (if it's a log/lock message or an svn:* prop value),
          * according to the value of the '--encoding' option. */
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
-        SVN_INT_ERR(svn_stringbuf_from_file2(&(opt_state.filedata),
-                                             utf8_opt_arg, pool));
+        SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        SVN_ERR(svn_stringbuf_from_file2(&(opt_state.filedata),
+                                         utf8_opt_arg, pool));
         reading_file_from_stdin = (strcmp(utf8_opt_arg, "-") == 0);
         dash_F_arg = utf8_opt_arg;
         break;
@@ -2036,9 +2020,9 @@ sub_main(int argc, const char *argv[], a
         {
           svn_stringbuf_t *buffer, *buffer_utf8;
 
-          SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
-          SVN_INT_ERR(svn_stringbuf_from_file2(&buffer, utf8_opt_arg, pool));
-          SVN_INT_ERR(svn_utf_stringbuf_to_utf8(&buffer_utf8, buffer, pool));
+          SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+          SVN_ERR(svn_stringbuf_from_file2(&buffer, utf8_opt_arg, pool));
+          SVN_ERR(svn_utf_stringbuf_to_utf8(&buffer_utf8, buffer, pool));
           opt_state.targets = svn_cstring_split(buffer_utf8->data, "\n\r",
                                                 TRUE, pool);
         }
@@ -2064,51 +2048,47 @@ sub_main(int argc, const char *argv[], a
       case opt_depth:
         err = svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool);
         if (err)
-          return EXIT_ERROR
-            (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, err,
-                               _("Error converting depth "
-                                 "from locale to UTF-8")));
+          return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, err,
+                                   _("Error converting depth "
+                                     "from locale to UTF-8"));
         opt_state.depth = svn_depth_from_word(utf8_opt_arg);
         if (opt_state.depth == svn_depth_unknown
             || opt_state.depth == svn_depth_exclude)
           {
-            return EXIT_ERROR
-              (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                                 _("'%s' is not a valid depth; try "
-                                   "'empty', 'files', 'immediates', "
-                                   "or 'infinity'"),
-                                 utf8_opt_arg));
+            return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                     _("'%s' is not a valid depth; try "
+                                       "'empty', 'files', 'immediates', "
+                                       "or 'infinity'"),
+                                     utf8_opt_arg);
           }
         break;
       case opt_set_depth:
         err = svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool);
         if (err)
-          return EXIT_ERROR
-            (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, err,
-                               _("Error converting depth "
-                                 "from locale to UTF-8")));
+          return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, err,
+                                   _("Error converting depth "
+                                     "from locale to UTF-8"));
         opt_state.set_depth = svn_depth_from_word(utf8_opt_arg);
         /* svn_depth_exclude is okay for --set-depth. */
         if (opt_state.set_depth == svn_depth_unknown)
           {
-            return EXIT_ERROR
-              (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                                 _("'%s' is not a valid depth; try "
-                                   "'exclude', 'empty', 'files', "
-                                   "'immediates', or 'infinity'"),
-                                 utf8_opt_arg));
+            return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                     _("'%s' is not a valid depth; try "
+                                       "'exclude', 'empty', 'files', "
+                                       "'immediates', or 'infinity'"),
+                                     utf8_opt_arg);
           }
         break;
       case opt_version:
         opt_state.version = TRUE;
         break;
       case opt_auth_username:
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.auth_username,
-                                            opt_arg, pool));
+        SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.auth_username,
+                                        opt_arg, pool));
         break;
       case opt_auth_password:
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.auth_password,
-                                            opt_arg, pool));
+        SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.auth_password,
+                                        opt_arg, pool));
         break;
       case opt_encoding:
         opt_state.encoding = apr_pstrdup(pool, opt_arg);
@@ -2162,8 +2142,8 @@ sub_main(int argc, const char *argv[], a
         opt_state.relocate = TRUE;
         break;
       case 'x':
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.extensions,
-                                            opt_arg, pool));
+        SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.extensions,
+                                        opt_arg, pool));
         break;
       case opt_diff_cmd:
         opt_state.diff.diff_cmd = apr_pstrdup(pool, opt_arg);
@@ -2183,20 +2163,18 @@ sub_main(int argc, const char *argv[], a
       case opt_old_cmd:
         if (opt_state.used_change_arg)
           {
-            err = svn_error_create
-              (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-               _("Can't specify -c with --old"));
-            return EXIT_ERROR(err);
+            return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                    _("Can't specify -c with --old"));
           }
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
         opt_state.old_target = apr_pstrdup(pool, utf8_opt_arg);
         break;
       case opt_new_cmd:
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
         opt_state.new_target = apr_pstrdup(pool, utf8_opt_arg);
         break;
       case opt_config_dir:
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
         opt_state.config_dir = svn_dirent_internal_style(utf8_opt_arg, pool);
         break;
       case opt_config_options:
@@ -2205,9 +2183,9 @@ sub_main(int argc, const char *argv[], a
                    apr_array_make(pool, 1,
                                   sizeof(svn_cmdline__config_argument_t*));
 
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
-        SVN_INT_ERR(svn_cmdline__parse_config_option(opt_state.config_options,
-                                                     utf8_opt_arg, pool));
+        SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        SVN_ERR(svn_cmdline__parse_config_option(opt_state.config_options,
+                                                 utf8_opt_arg, pool));
         break;
       case opt_autoprops:
         opt_state.autoprops = TRUE;
@@ -2216,17 +2194,15 @@ sub_main(int argc, const char *argv[], a
         opt_state.no_autoprops = TRUE;
         break;
       case opt_native_eol:
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
         if ( !strcmp("LF", utf8_opt_arg) || !strcmp("CR", utf8_opt_arg) ||
              !strcmp("CRLF", utf8_opt_arg))
           opt_state.native_eol = utf8_opt_arg;
         else
           {
-            err = svn_error_createf
-                (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+            return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                  _("Syntax error in native-eol argument '%s'"),
                  utf8_opt_arg);
-            return EXIT_ERROR(err);
           }
         break;
       case opt_no_unlock:
@@ -2239,12 +2215,11 @@ sub_main(int argc, const char *argv[], a
         opt_state.remove = TRUE;
         break;
       case opt_changelist:
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
         if (utf8_opt_arg[0] == '\0')
           {
-            err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                                   _("Changelist names must not be empty"));
-            return EXIT_ERROR(err);
+            return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                    _("Changelist names must not be empty"));
           }
         svn_hash_sets(changelists, utf8_opt_arg, (void *)1);
         break;
@@ -2263,8 +2238,8 @@ sub_main(int argc, const char *argv[], a
         opt_state.no_revprops = TRUE;
         break;
       case opt_with_revprop:
-        SVN_INT_ERR(svn_opt_parse_revprop(&opt_state.revprop_table,
-                                          opt_arg, pool));
+        SVN_ERR(svn_opt_parse_revprop(&opt_state.revprop_table,
+                                      opt_arg, pool));
         break;
       case opt_parents:
         opt_state.parents = TRUE;
@@ -2276,22 +2251,20 @@ sub_main(int argc, const char *argv[], a
         opt_state.auto_moves = TRUE;
         break;
       case opt_accept:
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
         opt_state.accept_which = svn_cl__accept_from_word(utf8_opt_arg);
         if (opt_state.accept_which == svn_cl__accept_invalid)
-          return EXIT_ERROR
-            (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                               _("'%s' is not a valid --accept value"),
-                               utf8_opt_arg));
+          return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                   _("'%s' is not a valid --accept value"),
+                                   utf8_opt_arg);
         break;
       case opt_show_revs:
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
         opt_state.show_revs = svn_cl__show_revs_from_word(utf8_opt_arg);
         if (opt_state.show_revs == svn_cl__show_revs_invalid)
-          return EXIT_ERROR
-            (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                               _("'%s' is not a valid --show-revs value"),
-                               utf8_opt_arg));
+          return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                   _("'%s' is not a valid --show-revs value"),
+                                   utf8_opt_arg);
         break;
       case opt_mergeinfo_log:
         opt_state.mergeinfo_log = TRUE;
@@ -2301,20 +2274,18 @@ sub_main(int argc, const char *argv[], a
         break;
       case opt_strip:
         {
-          SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+          SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
           err = svn_cstring_atoi(&opt_state.strip, utf8_opt_arg);
           if (err)
             {
-              err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, err,
-                                      _("Invalid strip count '%s'"),
-                                      utf8_opt_arg);
-              return EXIT_ERROR(err);
+              return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, err,
+                                       _("Invalid strip count '%s'"),
+                                       utf8_opt_arg);
             }
           if (opt_state.strip < 0)
             {
-              err = svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
-                                     _("Argument to --strip must be positive"));
-              return EXIT_ERROR(err);
+              return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
+                                      _("Argument to --strip must be positive"));
             }
         }
         break;
@@ -2352,11 +2323,11 @@ sub_main(int argc, const char *argv[], a
         opt_state.diff.properties_only = TRUE;
         break;
       case opt_search:
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
         add_search_pattern_group(&opt_state, utf8_opt_arg, pool);
         break;
       case opt_search_and:
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
         add_search_pattern_to_latest_group(&opt_state, utf8_opt_arg, pool);
       case opt_remove_unversioned:
         opt_state.remove_unversioned = TRUE;
@@ -2378,10 +2349,9 @@ sub_main(int argc, const char *argv[], a
    * exclusive. */
   if (opt_state.non_interactive && force_interactive)
     {
-      err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                             _("--non-interactive and --force-interactive "
-                               "are mutually exclusive"));
-      return EXIT_ERROR(err);
+      return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                              _("--non-interactive and --force-interactive "
+                                "are mutually exclusive"));
     }
   else
     opt_state.non_interactive = !svn_cmdline__be_interactive(
@@ -2389,7 +2359,7 @@ sub_main(int argc, const char *argv[], a
                                   force_interactive);
 
   /* Turn our hash of changelists into an array of unique ones. */
-  SVN_INT_ERR(svn_hash_keys(&(opt_state.changelists), changelists, pool));
+  SVN_ERR(svn_hash_keys(&(opt_state.changelists), changelists, pool));
 
   /* ### This really belongs in libsvn_client.  The trouble is,
      there's no one place there to run it from, no
@@ -2401,7 +2371,7 @@ sub_main(int argc, const char *argv[], a
      hand, the alternative is effectively to demand that they call
      svn_config_ensure() instead, so maybe we should have a generic
      init function anyway.  Thoughts?  */
-  SVN_INT_ERR(svn_config_ensure(opt_state.config_dir, pool));
+  SVN_ERR(svn_config_ensure(opt_state.config_dir, pool));
 
   /* If the user asked for help, then the rest of the arguments are
      the names of subcommands to get help on (if any), or else they're
@@ -2435,7 +2405,8 @@ sub_main(int argc, const char *argv[], a
                 (svn_cmdline_fprintf(stderr, pool,
                                      _("Subcommand argument required\n")));
               svn_error_clear(svn_cl__help(NULL, NULL, pool));
-              return EXIT_FAILURE;
+              *exit_code = EXIT_FAILURE;
+              return SVN_NO_ERROR;
             }
         }
       else
@@ -2446,8 +2417,8 @@ sub_main(int argc, const char *argv[], a
           if (subcommand == NULL)
             {
               const char *first_arg_utf8;
-              SVN_INT_ERR(svn_utf_cstring_to_utf8(&first_arg_utf8,
-                                                  first_arg, pool));
+              SVN_ERR(svn_utf_cstring_to_utf8(&first_arg_utf8,
+                                              first_arg, pool));
               svn_error_clear
                 (svn_cmdline_fprintf(stderr, pool,
                                      _("Unknown subcommand: '%s'\n"),
@@ -2464,7 +2435,8 @@ sub_main(int argc, const char *argv[], a
                                            "command.\n")));
                 }
 
-              return EXIT_FAILURE;
+              *exit_code = EXIT_FAILURE;
+              return SVN_NO_ERROR;
             }
         }
     }
@@ -2497,7 +2469,8 @@ sub_main(int argc, const char *argv[], a
                (stderr, pool, _("Subcommand '%s' doesn't accept option '%s'\n"
                                 "Type 'svn help %s' for usage.\n"),
                 subcommand->name, optstr, subcommand->name));
-          return EXIT_FAILURE;
+          *exit_code = EXIT_FAILURE;
+          return SVN_NO_ERROR;
         }
     }
 
@@ -2507,11 +2480,10 @@ sub_main(int argc, const char *argv[], a
     {
       if (opt_state.revision_ranges->nelts > 1)
         {
-          err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                                 _("Multiple revision arguments "
-                                   "encountered; can't specify -c twice, "
-                                   "or both -c and -r"));
-          return EXIT_ERROR(err);
+          return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                  _("Multiple revision arguments "
+                                    "encountered; can't specify -c twice, "
+                                    "or both -c and -r"));
         }
     }
 
@@ -2519,30 +2491,27 @@ sub_main(int argc, const char *argv[], a
   if ((opt_state.depth != svn_depth_unknown)
       && (opt_state.set_depth != svn_depth_unknown))
     {
-      err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                             _("--depth and --set-depth are mutually "
-                               "exclusive"));
-      return EXIT_ERROR(err);
+      return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                              _("--depth and --set-depth are mutually "
+                                "exclusive"));
     }
 
   /* Disallow simultaneous use of both --with-all-revprops and
      --with-no-revprops.  */
   if (opt_state.all_revprops && opt_state.no_revprops)
     {
-      err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                             _("--with-all-revprops and --with-no-revprops "
-                               "are mutually exclusive"));
-      return EXIT_ERROR(err);
+      return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                              _("--with-all-revprops and --with-no-revprops "
+                                "are mutually exclusive"));
     }
 
   /* Disallow simultaneous use of both --with-revprop and
      --with-no-revprops.  */
   if (opt_state.revprop_table && opt_state.no_revprops)
     {
-      err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                             _("--with-revprop and --with-no-revprops "
-                               "are mutually exclusive"));
-      return EXIT_ERROR(err);
+      return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                              _("--with-revprop and --with-no-revprops "
+                                "are mutually exclusive"));
     }
 
 #ifdef SVN_CL__OPTION_WITH_REVPROP_CAN_SET_PROPERTIES_IN_SVN_NAMESPACE
@@ -2556,9 +2525,9 @@ sub_main(int argc, const char *argv[], a
       for (hi = apr_hash_first(pool, opt_state.revprop_table);
            hi; hi = apr_hash_next(hi))
         {
-          SVN_INT_ERR(svn_cl__check_svn_prop_name(svn__apr_hash_index_key(hi),
-                                                  TRUE, svn_cl__prop_use_use,
-                                                  pool));
+          SVN_ERR(svn_cl__check_svn_prop_name(svn__apr_hash_index_key(hi),
+                                              TRUE, svn_cl__prop_use_use,
+                                              pool));
         }
     }
 #endif /* SVN_CL__OPTION_WITH_REVPROP_CAN_SET_PROPERTIES_IN_SVN_NAMESPACE */
@@ -2570,29 +2539,26 @@ sub_main(int argc, const char *argv[], a
   if (opt_state.filedata && opt_state.message
       && subcommand->cmd_func != svn_cl__propset)
     {
-      err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                             _("--message (-m) and --file (-F) "
-                               "are mutually exclusive"));
-      return EXIT_ERROR(err);
+      return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                              _("--message (-m) and --file (-F) "
+                                "are mutually exclusive"));
     }
 
   /* --trust-server-cert can only be used with --non-interactive */
   if (opt_state.trust_server_cert && !opt_state.non_interactive)
     {
-      err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                             _("--trust-server-cert requires "
-                               "--non-interactive"));
-      return EXIT_ERROR(err);
+      return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                              _("--trust-server-cert requires "
+                                "--non-interactive"));
     }
 
   /* Disallow simultaneous use of --diff-cmd, --invoke-diff-cmd and
      --internal-diff.  */
   if (opt_state.diff.diff_cmd && opt_state.diff.internal_diff)
     {
-      err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                             _("--diff-cmd and --internal-diff "
-                               "are mutually exclusive"));
-      return EXIT_ERROR(err);
+      return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                              _("--diff-cmd and --internal-diff "
+                                "are mutually exclusive"));
     }
 
   if (opt_state.diff.invoke_diff_cmd && opt_state.diff.internal_diff)
@@ -2639,7 +2605,7 @@ sub_main(int argc, const char *argv[], a
           cfg_hash = NULL;
         }
       else
-        return EXIT_ERROR(err);
+        return err;
     }
 
   /* Relocation is infinite-depth only. */
@@ -2647,18 +2613,16 @@ sub_main(int argc, const char *argv[], a
     {
       if (opt_state.depth != svn_depth_unknown)
         {
-          err = svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
-                                 _("--relocate and --depth are mutually "
-                                   "exclusive"));
-          return EXIT_ERROR(err);
+          return svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
+                                  _("--relocate and --depth are mutually "
+                                    "exclusive"));
         }
       if (! descend)
         {
-          err = svn_error_create(
+          return svn_error_create(
                     SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
                     _("--relocate and --non-recursive (-N) are mutually "
                       "exclusive"));
-          return EXIT_ERROR(err);
         }
     }
 
@@ -2672,8 +2636,7 @@ sub_main(int argc, const char *argv[], a
     {
       if (opt_state.end_revision.kind != svn_opt_revision_unspecified)
         {
-          err = svn_error_create(SVN_ERR_CLIENT_REVISION_RANGE, NULL, NULL);
-          return EXIT_ERROR(err);
+          return svn_error_create(SVN_ERR_CLIENT_REVISION_RANGE, NULL, NULL);
         }
     }
 
@@ -2740,7 +2703,7 @@ sub_main(int argc, const char *argv[], a
 
   /* Create a client context object. */
   command_baton.opt_state = &opt_state;
-  SVN_INT_ERR(svn_client_create_context2(&ctx, cfg_hash, pool));
+  SVN_ERR(svn_client_create_context2(&ctx, cfg_hash, pool));
   command_baton.ctx = ctx;
 
   /* If we're running a command that could result in a commit, verify
@@ -2776,19 +2739,18 @@ sub_main(int argc, const char *argv[], a
                 {
                   if (subcommand->cmd_func != svn_cl__lock)
                     {
-                      err = svn_error_create(
+                      return svn_error_create(
                          SVN_ERR_CL_LOG_MESSAGE_IS_VERSIONED_FILE, NULL,
                          _("Log message file is a versioned file; "
                            "use '--force-log' to override"));
                     }
                   else
                     {
-                      err = svn_error_create(
+                      return svn_error_create(
                          SVN_ERR_CL_LOG_MESSAGE_IS_VERSIONED_FILE, NULL,
                          _("Lock comment file is a versioned file; "
                            "use '--force-log' to override"));
                     }
-                  return EXIT_ERROR(err);
                 }
             }
           svn_error_clear(err);
@@ -2804,19 +2766,18 @@ sub_main(int argc, const char *argv[], a
             {
               if (subcommand->cmd_func != svn_cl__lock)
                 {
-                  err = svn_error_create
+                  return svn_error_create
                     (SVN_ERR_CL_LOG_MESSAGE_IS_PATHNAME, NULL,
                      _("The log message is a pathname "
                        "(was -F intended?); use '--force-log' to override"));
                 }
               else
                 {
-                  err = svn_error_create
+                  return svn_error_create
                     (SVN_ERR_CL_LOG_MESSAGE_IS_PATHNAME, NULL,
                      _("The lock comment is a pathname "
                        "(was -F intended?); use '--force-log' to override"));
                 }
-              return EXIT_ERROR(err);
             }
         }
     }
@@ -2839,10 +2800,9 @@ sub_main(int argc, const char *argv[], a
   /* Check for mutually exclusive args --auto-props and --no-auto-props */
   if (opt_state.autoprops && opt_state.no_autoprops)
     {
-      err = svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
-                             _("--auto-props and --no-auto-props are "
-                               "mutually exclusive"));
-      return EXIT_ERROR(err);
+      return svn_error_create(SVN_ERR_CL_MUTUALLY_EXCLUSIVE_ARGS, NULL,
+                              _("--auto-props and --no-auto-props are "
+                                "mutually exclusive"));
     }
 
   /* Update auto-props-enable option, and populate the MIME types map,
@@ -2856,8 +2816,8 @@ sub_main(int argc, const char *argv[], a
                      SVN_CONFIG_OPTION_MIMETYPES_FILE, FALSE);
       if (mimetypes_file && *mimetypes_file)
         {
-          SVN_INT_ERR(svn_io_parse_mimetypes_file(&(ctx->mimetypes_map),
-                                                  mimetypes_file, pool));
+          SVN_ERR(svn_io_parse_mimetypes_file(&(ctx->mimetypes_map),
+                                              mimetypes_file, pool));
         }
 
       if (opt_state.autoprops)
@@ -2895,8 +2855,8 @@ sub_main(int argc, const char *argv[], a
     use_notifier = FALSE;
   if (use_notifier)
     {
-      SVN_INT_ERR(svn_cl__get_notifier(&ctx->notify_func2, &ctx->notify_baton2,
-                                       conflict_stats, pool));
+      SVN_ERR(svn_cl__get_notifier(&ctx->notify_func2, &ctx->notify_baton2,
+                                   conflict_stats, pool));
     }
 
   /* Set up our cancellation support. */
@@ -2926,35 +2886,36 @@ sub_main(int argc, const char *argv[], a
 #endif
 
   /* Set up Authentication stuff. */
-  SVN_INT_ERR(svn_cmdline_create_auth_baton(&ab,
-                                            opt_state.non_interactive,
-                                            opt_state.auth_username,
-                                            opt_state.auth_password,
-                                            opt_state.config_dir,
-                                            opt_state.no_auth_cache,
-                                            opt_state.trust_server_cert,
-                                            cfg_config,
-                                            ctx->cancel_func,
-                                            ctx->cancel_baton,
-                                            pool));
+  SVN_ERR(svn_cmdline_create_auth_baton(&ab,
+                                        opt_state.non_interactive,
+                                        opt_state.auth_username,
+                                        opt_state.auth_password,
+                                        opt_state.config_dir,
+                                        opt_state.no_auth_cache,
+                                        opt_state.trust_server_cert,
+                                        cfg_config,
+                                        ctx->cancel_func,
+                                        ctx->cancel_baton,
+                                        pool));
 
   ctx->auth_baton = ab;
 
   if (opt_state.non_interactive)
     {
       if (opt_state.accept_which == svn_cl__accept_edit)
-        return EXIT_ERROR(
-                 svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+        {
+          return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                    _("--accept=%s incompatible with"
                                      " --non-interactive"),
-                                   SVN_CL__ACCEPT_EDIT));
-
+                                   SVN_CL__ACCEPT_EDIT);
+        }
       if (opt_state.accept_which == svn_cl__accept_launch)
-        return EXIT_ERROR(
-                 svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+        {
+          return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                    _("--accept=%s incompatible with"
                                      " --non-interactive"),
-                                   SVN_CL__ACCEPT_LAUNCH));
+                                   SVN_CL__ACCEPT_LAUNCH);
+        }
 
       /* The default action when we're non-interactive is to postpone
        * conflict resolution. */
@@ -2965,10 +2926,10 @@ sub_main(int argc, const char *argv[], a
   /* Check whether interactive conflict resolution is disabled by
    * the configuration file. If no --accept option was specified
    * we postpone all conflicts in this case. */
-  SVN_INT_ERR(svn_config_get_bool(cfg_config, &interactive_conflicts,
-                                  SVN_CONFIG_SECTION_MISCELLANY,
-                                  SVN_CONFIG_OPTION_INTERACTIVE_CONFLICTS,
-                                  TRUE));
+  SVN_ERR(svn_config_get_bool(cfg_config, &interactive_conflicts,
+                              SVN_CONFIG_SECTION_MISCELLANY,
+                              SVN_CONFIG_OPTION_INTERACTIVE_CONFLICTS,
+                              TRUE));
   if (!interactive_conflicts)
     {
       /* Make 'svn resolve' non-interactive. */
@@ -2989,7 +2950,7 @@ sub_main(int argc, const char *argv[], a
     ctx->conflict_baton = NULL;
 
     ctx->conflict_func2 = svn_cl__conflict_func_interactive;
-    SVN_INT_ERR(svn_cl__get_conflict_func_interactive_baton(
+    SVN_ERR(svn_cl__get_conflict_func_interactive_baton(
                 &b,
                 opt_state.accept_which,
                 ctx->config, opt_state.editor_cmd, conflict_stats,
@@ -3062,27 +3023,18 @@ sub_main(int argc, const char *argv[], a
                          "Subversion"));
         }
 
-      /* Ensure that stdout is flushed, so the user will see any write errors.
-         This makes sure that output is not silently lost. */
-      SVN_INT_ERR(svn_cmdline_fflush(stdout));
-
-      return EXIT_ERROR(err);
+      return err;
     }
-  else
-    {
-      /* Ensure that stdout is flushed, so the user will see any write errors.
-         This makes sure that output is not silently lost. */
-      SVN_INT_ERR(svn_cmdline_fflush(stdout));
 
-      return EXIT_SUCCESS;
-    }
+  return SVN_NO_ERROR;
 }
 
 int
 main(int argc, const char *argv[])
 {
   apr_pool_t *pool;
-  int exit_code;
+  int exit_code = EXIT_SUCCESS;
+  svn_error_t *err;
 
   /* Initialize the app. */
   if (svn_cmdline_init("svn", stderr) != EXIT_SUCCESS)
@@ -3093,7 +3045,17 @@ main(int argc, const char *argv[])
    */
   pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
 
-  exit_code = sub_main(argc, argv, pool);
+  err = sub_main(&exit_code, argc, argv, pool);
+
+  /* Flush stdout and report if it fails. It would be flushed on exit anyway
+     but this makes sure that output is not silently lost if it fails. */
+  err = svn_error_compose_create(err, svn_cmdline_fflush(stdout));
+
+  if (err)
+    {
+      exit_code = EXIT_FAILURE;
+      svn_cmdline_handle_exit_error(err, NULL, "svn: ");
+    }
 
   svn_pool_destroy(pool);
   return exit_code;

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svn/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svn/util.c?rev=1549081&r1=1549080&r2=1549081&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svn/util.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svn/util.c Sun Dec  8 17:56:46 2013
@@ -626,7 +626,7 @@ svn_cl__xml_tagged_cdata(svn_stringbuf_t
   if (string)
     {
       svn_xml_make_open_tag(sb, pool, svn_xml_protect_pcdata,
-                            tagname, NULL);
+                            tagname, SVN_VA_NULL);
       svn_xml_escape_cdata_cstring(sb, string, pool);
       svn_xml_make_close_tag(sb, pool, tagname);
     }
@@ -643,7 +643,7 @@ svn_cl__print_xml_commit(svn_stringbuf_t
   /* "<commit ...>" */
   svn_xml_make_open_tag(sb, pool, svn_xml_normal, "commit",
                         "revision",
-                        apr_psprintf(pool, "%ld", revision), NULL);
+                        apr_psprintf(pool, "%ld", revision), SVN_VA_NULL);
 
   /* "<author>xx</author>" */
   if (author)
@@ -664,7 +664,7 @@ svn_cl__print_xml_lock(svn_stringbuf_t *
                        apr_pool_t *pool)
 {
   /* "<lock>" */
-  svn_xml_make_open_tag(sb, pool, svn_xml_normal, "lock", NULL);
+  svn_xml_make_open_tag(sb, pool, svn_xml_normal, "lock", SVN_VA_NULL);
 
   /* "<token>xx</token>" */
   svn_cl__xml_tagged_cdata(sb, pool, "token", lock->token);
@@ -699,7 +699,7 @@ svn_cl__xml_print_header(const char *tag
   svn_xml_make_header2(&sb, "UTF-8", pool);
 
   /* "<TAGNAME>" */
-  svn_xml_make_open_tag(&sb, pool, svn_xml_normal, tagname, NULL);
+  svn_xml_make_open_tag(&sb, pool, svn_xml_normal, tagname, SVN_VA_NULL);
 
   return svn_cl__error_checked_fputs(sb->data, stdout);
 }

Modified: subversion/branches/invoke-diff-cmd-feature/subversion/svnadmin/svnadmin.c
URL: http://svn.apache.org/viewvc/subversion/branches/invoke-diff-cmd-feature/subversion/svnadmin/svnadmin.c?rev=1549081&r1=1549080&r2=1549081&view=diff
==============================================================================
--- subversion/branches/invoke-diff-cmd-feature/subversion/svnadmin/svnadmin.c (original)
+++ subversion/branches/invoke-diff-cmd-feature/subversion/svnadmin/svnadmin.c Sun Dec  8 17:56:46 2013
@@ -197,7 +197,8 @@ enum svnadmin__cmdline_options_t
     svnadmin__pre_1_4_compatible,
     svnadmin__pre_1_5_compatible,
     svnadmin__pre_1_6_compatible,
-    svnadmin__compatible_version
+    svnadmin__compatible_version,
+    svnadmin__check_normalization
   };
 
 /* Option codes and descriptions.
@@ -302,6 +303,14 @@ static const apr_getopt_option_t options
 
     {"file", 'F', 1, N_("read repository paths from file ARG")},
 
+    {"check-normalization", svnadmin__check_normalization, 0,
+     N_("report paths in the filesystem and mergeinfo\n"
+        "                             that are not normalized to Unicode Normalization\n"
+        "                             Form C, and any names within the same directory\n"
+        "                             or svn:mergeinfo property value that differ only\n"
+        "                             in character representation, but are otherwise\n"
+        "                             identical")},
+
     {NULL}
   };
 
@@ -494,7 +503,8 @@ static const svn_opt_subcommand_desc2_t 
   {"verify", subcommand_verify, {0}, N_
    ("usage: svnadmin verify REPOS_PATH\n\n"
     "Verify the data stored in the repository.\n"),
-  {'t', 'r', 'q', svnadmin__keep_going, 'M'} },
+   {'t', 'r', 'q', svnadmin__keep_going, 'M',
+    svnadmin__check_normalization} },
 
   { NULL, NULL, {0}, NULL, {0} }
 };
@@ -523,6 +533,7 @@ struct svnadmin_opt_state
   svn_boolean_t bypass_hooks;                       /* --bypass-hooks */
   svn_boolean_t wait;                               /* --wait */
   svn_boolean_t keep_going;                         /* --keep-going */
+  svn_boolean_t check_normalization;                /* --check-normalization */
   svn_boolean_t bypass_prop_validation;             /* --bypass-prop-validation */
   enum svn_repos_load_uuid uuid_action;             /* --ignore-uuid,
                                                        --force-uuid */
@@ -709,7 +720,8 @@ subcommand_create(apr_getopt_t *os, void
                                  opt_state->compatible_version->patch,
                                  opt_state->compatible_version->tag
                                  ? "-" : "",
-                                 opt_state->compatible_version->tag));
+                                 opt_state->compatible_version->tag
+                                 ? opt_state->compatible_version->tag : ""));
     }
 
   if (opt_state->compatible_version)
@@ -794,6 +806,34 @@ subcommand_deltify(apr_getopt_t *os, voi
   return SVN_NO_ERROR;
 }
 
+/* Structure for errors encountered during 'svnadmin verify --keep-going'. */
+struct verification_error
+{
+  svn_revnum_t rev;
+  svn_error_t *err;
+};
+
+/* Pool cleanup function to clear an svn_error_t *. */
+static apr_status_t
+err_cleanup(void *data)
+{
+  svn_error_t *err = data;
+
+  svn_error_clear(err);
+
+  return APR_SUCCESS;
+}
+
+struct repos_notify_handler_baton {
+  /* Stream to write progress and other non-error output to. */
+  svn_stream_t *feedback_stream;
+
+  /* List of errors encountered during 'svnadmin verify --keep-going'. */
+  apr_array_header_t *error_summary;
+
+  /* Pool for data collected during notifications. */
+  apr_pool_t *result_pool;
+};
 
 /* Implementation of svn_repos_notify_func_t to wrap the output to a
    response stream for svn_repos_dump_fs2() and svn_repos_verify_fs() */
@@ -802,7 +842,8 @@ repos_notify_handler(void *baton,
                      const svn_repos_notify_t *notify,
                      apr_pool_t *scratch_pool)
 {
-  svn_stream_t *feedback_stream = baton;
+  struct repos_notify_handler_baton *b = baton;
+  svn_stream_t *feedback_stream = b->feedback_stream;
 
   switch (notify->action)
   {
@@ -818,8 +859,22 @@ repos_notify_handler(void *baton,
                                     _("* Error verifying revision %ld.\n"),
                                     notify->revision));
       if (notify->err)
-        svn_handle_error2(notify->err, stderr, FALSE /* non-fatal */,
-                          "svnadmin: ");
+        {
+          svn_handle_error2(notify->err, stderr, FALSE /* non-fatal */,
+                            "svnadmin: ");
+          if (b->error_summary && notify->revision != SVN_INVALID_REVNUM)
+            {
+              struct verification_error *verr;
+              
+              verr = apr_palloc(b->result_pool, sizeof(*verr));
+              verr->rev = notify->revision;
+              verr->err = svn_error_dup(notify->err);
+              apr_pool_cleanup_register(b->result_pool, verr->err, err_cleanup,
+                                        apr_pool_cleanup_null);
+              APR_ARRAY_PUSH(b->error_summary,
+                             struct verification_error *) = verr;
+            }
+        }
       return;
 
     case svn_repos_notify_dump_rev_end:
@@ -1054,7 +1109,7 @@ subcommand_dump(apr_getopt_t *os, void *
   svn_stream_t *stdout_stream;
   svn_revnum_t lower = SVN_INVALID_REVNUM, upper = SVN_INVALID_REVNUM;
   svn_revnum_t youngest;
-  svn_stream_t *progress_stream = NULL;
+  struct repos_notify_handler_baton notify_baton = { 0 };
 
   /* Expect no more arguments. */
   SVN_ERR(parse_args(NULL, os, 0, 0, pool));
@@ -1088,12 +1143,12 @@ subcommand_dump(apr_getopt_t *os, void *
 
   /* Progress feedback goes to STDERR, unless they asked to suppress it. */
   if (! opt_state->quiet)
-    progress_stream = recode_stream_create(stderr, pool);
+    notify_baton.feedback_stream = recode_stream_create(stderr, pool);
 
   SVN_ERR(svn_repos_dump_fs3(repos, stdout_stream, lower, upper,
                              opt_state->incremental, opt_state->use_deltas,
                              !opt_state->quiet ? repos_notify_handler : NULL,
-                             progress_stream, check_cancel, NULL, pool));
+                             &notify_baton, check_cancel, NULL, pool));
 
   return SVN_NO_ERROR;
 }
@@ -1240,7 +1295,8 @@ subcommand_load(apr_getopt_t *os, void *
   struct svnadmin_opt_state *opt_state = baton;
   svn_repos_t *repos;
   svn_revnum_t lower = SVN_INVALID_REVNUM, upper = SVN_INVALID_REVNUM;
-  svn_stream_t *stdin_stream, *stdout_stream = NULL;
+  svn_stream_t *stdin_stream;
+  struct repos_notify_handler_baton notify_baton = { 0 };
 
   /* Expect no more arguments. */
   SVN_ERR(parse_args(NULL, os, 0, 0, pool));
@@ -1274,7 +1330,7 @@ subcommand_load(apr_getopt_t *os, void *
 
   /* Progress feedback goes to STDOUT, unless they asked to suppress it. */
   if (! opt_state->quiet)
-    stdout_stream = recode_stream_create(stdout, pool);
+    notify_baton.feedback_stream = recode_stream_create(stdout, pool);
 
   err = svn_repos_load_fs4(repos, stdin_stream, lower, upper,
                            opt_state->uuid_action, opt_state->parent_dir,
@@ -1282,7 +1338,7 @@ subcommand_load(apr_getopt_t *os, void *
                            opt_state->use_post_commit_hook,
                            !opt_state->bypass_prop_validation,
                            opt_state->quiet ? NULL : repos_notify_handler,
-                           stdout_stream, check_cancel, NULL, pool);
+                           &notify_baton, check_cancel, NULL, pool);
   if (err && err->apr_err == SVN_ERR_BAD_PROPERTY_VALUE)
     return svn_error_quick_wrap(err,
                                 _("Invalid property value found in "
@@ -1329,12 +1385,12 @@ subcommand_recover(apr_getopt_t *os, voi
   svn_repos_t *repos;
   svn_error_t *err;
   struct svnadmin_opt_state *opt_state = baton;
-  svn_stream_t *stdout_stream;
+  struct repos_notify_handler_baton notify_baton = { 0 };
 
   /* Expect no more arguments. */
   SVN_ERR(parse_args(NULL, os, 0, 0, pool));
 
-  SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool));
+  SVN_ERR(svn_stream_for_stdout(&notify_baton.feedback_stream, pool));
 
   /* Restore default signal handlers until after we have acquired the
    * exclusive lock so that the user interrupt before we actually
@@ -1342,7 +1398,7 @@ subcommand_recover(apr_getopt_t *os, voi
   setup_cancellation_signals(SIG_DFL);
 
   err = svn_repos_recover4(opt_state->repository_path, TRUE,
-                           repos_notify_handler, stdout_stream,
+                           repos_notify_handler, &notify_baton,
                            check_cancel, NULL, pool);
   if (err)
     {
@@ -1360,7 +1416,7 @@ subcommand_recover(apr_getopt_t *os, voi
                                    " another process has it open?\n")));
       SVN_ERR(svn_cmdline_fflush(stdout));
       SVN_ERR(svn_repos_recover4(opt_state->repository_path, FALSE,
-                                 repos_notify_handler, stdout_stream,
+                                 repos_notify_handler, &notify_baton,
                                  check_cancel, NULL, pool));
     }
 
@@ -1615,7 +1671,7 @@ subcommand_pack(apr_getopt_t *os, void *
 {
   struct svnadmin_opt_state *opt_state = baton;
   svn_repos_t *repos;
-  svn_stream_t *progress_stream = NULL;
+  struct repos_notify_handler_baton notify_baton = { 0 };
 
   /* Expect no more arguments. */
   SVN_ERR(parse_args(NULL, os, 0, 0, pool));
@@ -1624,11 +1680,11 @@ subcommand_pack(apr_getopt_t *os, void *
 
   /* Progress feedback goes to STDOUT, unless they asked to suppress it. */
   if (! opt_state->quiet)
-    progress_stream = recode_stream_create(stdout, pool);
+    notify_baton.feedback_stream = recode_stream_create(stdout, pool);
 
   return svn_error_trace(
     svn_repos_fs_pack2(repos, !opt_state->quiet ? repos_notify_handler : NULL,
-                       progress_stream, check_cancel, NULL, pool));
+                       &notify_baton, check_cancel, NULL, pool));
 }
 
 
@@ -1640,7 +1696,8 @@ subcommand_verify(apr_getopt_t *os, void
   svn_repos_t *repos;
   svn_fs_t *fs;
   svn_revnum_t youngest, lower, upper;
-  svn_stream_t *progress_stream = NULL;
+  struct repos_notify_handler_baton notify_baton = { 0 };
+  svn_error_t *verify_err;
 
   /* Expect no more arguments. */
   SVN_ERR(parse_args(NULL, os, 0, 0, pool));
@@ -1685,14 +1742,79 @@ subcommand_verify(apr_getopt_t *os, void
     }
 
   if (! opt_state->quiet)
-    progress_stream = recode_stream_create(stdout, pool);
+    notify_baton.feedback_stream = recode_stream_create(stdout, pool);
+
+  if (opt_state->keep_going)
+    notify_baton.error_summary =
+      apr_array_make(pool, 0, sizeof(struct verification_error *));
+
+  notify_baton.result_pool = pool;
+
+  verify_err = svn_repos_verify_fs3(repos, lower, upper,
+                                    opt_state->keep_going,
+                                    opt_state->check_normalization,
+                                    !opt_state->quiet
+                                    ? repos_notify_handler : NULL,
+                                    &notify_baton, check_cancel,
+                                    NULL, pool);
+
+  /* Show the --keep-going error summary. */
+  if (opt_state->keep_going && notify_baton.error_summary->nelts > 0)
+    {
+      int rev_maxlength;
+      svn_revnum_t end_revnum;
+      apr_pool_t *iterpool;
+      int i;
+
+      svn_error_clear(
+        svn_stream_puts(notify_baton.feedback_stream,
+                          _("\n-----Summary of corrupt revisions-----\n")));
+
+      /* The standard column width for the revision number is 6 characters.
+         If the revision number can potentially be larger (i.e. if end_revnum
+         is larger than 1000000), we increase the column width as needed. */
+      rev_maxlength = 6;
+      end_revnum = APR_ARRAY_IDX(notify_baton.error_summary,
+                                 notify_baton.error_summary->nelts - 1,
+                                 struct verification_error *)->rev;
+      while (end_revnum >= 1000000)
+        {
+          rev_maxlength++;
+          end_revnum = end_revnum / 10;
+        }
+
+      iterpool = svn_pool_create(pool);
+      for (i = 0; i < notify_baton.error_summary->nelts; i++)
+        {
+          struct verification_error *verr;
+          svn_error_t *err;
+          const char *rev_str;
+          
+          svn_pool_clear(iterpool);
+
+          verr = APR_ARRAY_IDX(notify_baton.error_summary, i,
+                               struct verification_error *);
+          rev_str = apr_psprintf(iterpool, "r%ld", verr->rev);
+          rev_str = apr_psprintf(iterpool, "%*s", rev_maxlength, rev_str);
+          for (err = svn_error_purge_tracing(verr->err);
+               err != SVN_NO_ERROR; err = err->child)
+            {
+              char buf[512];
+              const char *message;
+              
+              message = svn_err_best_message(err, buf, sizeof(buf));
+              svn_error_clear(svn_stream_printf(notify_baton.feedback_stream,
+                                                iterpool,
+                                                "%s: E%06d: %s\n",
+                                                rev_str, err->apr_err,
+                                                message));
+            }
+        }
+
+       svn_pool_destroy(iterpool);
+    }
 
-  return svn_error_trace(svn_repos_verify_fs3(repos, lower, upper,
-                                              opt_state->keep_going,
-                                              !opt_state->quiet
-                                              ? repos_notify_handler : NULL,
-                                              progress_stream, check_cancel,
-                                              NULL, pool));
+  return svn_error_trace(verify_err);
 }
 
 /* This implements `svn_opt_subcommand_t'. */
@@ -2079,18 +2201,18 @@ subcommand_upgrade(apr_getopt_t *os, voi
 {
   svn_error_t *err;
   struct svnadmin_opt_state *opt_state = baton;
-  svn_stream_t *stdout_stream;
+  struct repos_notify_handler_baton notify_baton = { 0 };
 
   /* Expect no more arguments. */
   SVN_ERR(parse_args(NULL, os, 0, 0, pool));
 
-  SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool));
+  SVN_ERR(svn_stream_for_stdout(&notify_baton.feedback_stream, pool));
 
   /* Restore default signal handlers. */
   setup_cancellation_signals(SIG_DFL);
 
   err = svn_repos_upgrade2(opt_state->repository_path, TRUE,
-                           repos_notify_handler, stdout_stream, pool);
+                           repos_notify_handler, &notify_baton, pool);
   if (err)
     {
       if (APR_STATUS_IS_EAGAIN(err->apr_err))
@@ -2108,7 +2230,7 @@ subcommand_upgrade(apr_getopt_t *os, voi
                                        " another process has it open?\n")));
           SVN_ERR(svn_cmdline_fflush(stdout));
           SVN_ERR(svn_repos_upgrade2(opt_state->repository_path, FALSE,
-                                     repos_notify_handler, stdout_stream,
+                                     repos_notify_handler, &notify_baton,
                                      pool));
         }
       else if (err->apr_err == SVN_ERR_FS_UNSUPPORTED_UPGRADE)
@@ -2135,23 +2257,13 @@ subcommand_upgrade(apr_getopt_t *os, voi
 
 /** Main. **/
 
-/* Report and clear the error ERR, and return EXIT_FAILURE. */
-#define EXIT_ERROR(err)                                                 \
-  svn_cmdline_handle_exit_error(err, NULL, "svnadmin: ")
-
-/* A redefinition of the public SVN_INT_ERR macro, that suppresses the
- * error message if it is SVN_ERR_IO_PIPE_WRITE_ERROR, amd with the
- * program name 'svnadmin' instead of 'svn'. */
-#undef SVN_INT_ERR
-#define SVN_INT_ERR(expr)                                        \
-  do {                                                           \
-    svn_error_t *svn_err__temp = (expr);                         \
-    if (svn_err__temp)                                           \
-      return EXIT_ERROR(svn_err__temp);                          \
-  } while (0)
-
-static int
-sub_main(int argc, const char *argv[], apr_pool_t *pool)
+/*
+ * On success, leave *EXIT_CODE untouched and return SVN_NO_ERROR. On error,
+ * either return an error to be displayed, or set *EXIT_CODE to non-zero and
+ * return SVN_NO_ERROR.
+ */
+static svn_error_t *
+sub_main(int *exit_code, int argc, const char *argv[], apr_pool_t *pool)
 {
   svn_error_t *err;
   apr_status_t apr_err;
@@ -2167,15 +2279,16 @@ sub_main(int argc, const char *argv[], a
   received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
 
   /* Check library versions */
-  SVN_INT_ERR(check_lib_versions());
+  SVN_ERR(check_lib_versions());
 
   /* Initialize the FS library. */
-  SVN_INT_ERR(svn_fs_initialize(pool));
+  SVN_ERR(svn_fs_initialize(pool));
 
   if (argc <= 1)
     {
-      SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
-      return EXIT_FAILURE;
+      SVN_ERR(subcommand_help(NULL, NULL, pool));
+      *exit_code = EXIT_FAILURE;
+      return SVN_NO_ERROR;
     }
 
   /* Initialize opt_state. */
@@ -2184,7 +2297,7 @@ sub_main(int argc, const char *argv[], a
   opt_state.memory_cache_size = svn_cache_config_get()->cache_size;
 
   /* Parse options. */
-  SVN_INT_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
+  SVN_ERR(svn_cmdline__getopt_init(&os, argc, argv, pool));
 
   os->interleave = 1;
 
@@ -2199,8 +2312,9 @@ sub_main(int argc, const char *argv[], a
         break;
       else if (apr_err)
         {
-          SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
-          return EXIT_FAILURE;
+          SVN_ERR(subcommand_help(NULL, NULL, pool));
+          *exit_code = EXIT_FAILURE;
+          return SVN_NO_ERROR;
         }
 
       /* Stash the option code in an array before parsing it. */
@@ -2211,23 +2325,19 @@ sub_main(int argc, const char *argv[], a
         {
           if (opt_state.start_revision.kind != svn_opt_revision_unspecified)
             {
-              err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                 _("Multiple revision arguments encountered; "
-                   "try '-r N:M' instead of '-r N -r M'"));
-              return EXIT_ERROR(err);
+              return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                        _("Multiple revision arguments encountered; "
+                          "try '-r N:M' instead of '-r N -r M'"));
             }
           if (svn_opt_parse_revision(&(opt_state.start_revision),
                                      &(opt_state.end_revision),
                                      opt_arg, pool) != 0)
             {
-              err = svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg,
-                                            pool);
+              SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
 
-              if (! err)
-                err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+              return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                         _("Syntax error in revision argument '%s'"),
                         utf8_opt_arg);
-              return EXIT_ERROR(err);
             }
         }
         break;
@@ -2247,8 +2357,8 @@ sub_main(int argc, const char *argv[], a
             = 0x100000 * apr_strtoi64(opt_arg, NULL, 0);
         break;
       case 'F':
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
-        SVN_INT_ERR(svn_stringbuf_from_file2(&(opt_state.filedata),
+        SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        SVN_ERR(svn_stringbuf_from_file2(&(opt_state.filedata),
                                              utf8_opt_arg, pool));
         dash_F_arg = TRUE;
       case svnadmin__version:
@@ -2289,16 +2399,15 @@ sub_main(int argc, const char *argv[], a
 
           /* Parse the version string which carries our target
              compatibility. */
-          SVN_INT_ERR(svn_version__parse_version_string(&compatible_version,
+          SVN_ERR(svn_version__parse_version_string(&compatible_version,
                                                         opt_arg, pool));
 
           /* We can't create repository with a version older than 1.0.0.  */
           if (! svn_version__at_least(compatible_version, 1, 0, 0))
             {
-              err = svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-                                      _("Cannot create pre-1.0-compatible "
-                                        "repositories"));
-              return EXIT_ERROR(err);
+              return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                                       _("Cannot create pre-1.0-compatible "
+                                         "repositories"));
             }
 
           /* We can't create repository with a version newer than what
@@ -2308,12 +2417,11 @@ sub_main(int argc, const char *argv[], a
                                       compatible_version->minor,
                                       compatible_version->patch))
             {
-              err = svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-                                      _("Cannot guarantee compatibility "
-                                        "beyond the current running version "
-                                        "(%s)"),
-                                      SVN_VER_NUM );
-              return EXIT_ERROR(err);
+              return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                                       _("Cannot guarantee compatibility "
+                                         "beyond the current running version "
+                                         "(%s)"),
+                                       SVN_VER_NUM);
             }
 
           opt_state.compatible_version = compatible_version;
@@ -2322,11 +2430,14 @@ sub_main(int argc, const char *argv[], a
       case svnadmin__keep_going:
         opt_state.keep_going = TRUE;
         break;
+      case svnadmin__check_normalization:
+        opt_state.check_normalization = TRUE;
+        break;
       case svnadmin__fs_type:
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.fs_type, opt_arg, pool));
+        SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.fs_type, opt_arg, pool));
         break;
       case svnadmin__parent_dir:
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.parent_dir, opt_arg,
+        SVN_ERR(svn_utf_cstring_to_utf8(&opt_state.parent_dir, opt_arg,
                                             pool));
         opt_state.parent_dir
           = svn_dirent_internal_style(opt_state.parent_dir, pool);
@@ -2359,7 +2470,7 @@ sub_main(int argc, const char *argv[], a
         opt_state.clean_logs = TRUE;
         break;
       case svnadmin__config_dir:
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        SVN_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
         opt_state.config_dir =
             apr_pstrdup(pool, svn_dirent_canonicalize(utf8_opt_arg, pool));
         break;
@@ -2368,8 +2479,9 @@ sub_main(int argc, const char *argv[], a
         break;
       default:
         {
-          SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
-          return EXIT_FAILURE;
+          SVN_ERR(subcommand_help(NULL, NULL, pool));
+          *exit_code = EXIT_FAILURE;
+          return SVN_NO_ERROR;
         }
       }  /* close `switch' */
     }  /* close `while' */
@@ -2402,8 +2514,9 @@ sub_main(int argc, const char *argv[], a
             {
               svn_error_clear(svn_cmdline_fprintf(stderr, pool,
                                         _("subcommand argument required\n")));
-              SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
-              return EXIT_FAILURE;
+              SVN_ERR(subcommand_help(NULL, NULL, pool));
+              *exit_code = EXIT_FAILURE;
+              return SVN_NO_ERROR;
             }
         }
       else
@@ -2413,14 +2526,15 @@ sub_main(int argc, const char *argv[], a
           if (subcommand == NULL)
             {
               const char *first_arg_utf8;
-              SVN_INT_ERR(svn_utf_cstring_to_utf8(&first_arg_utf8,
+              SVN_ERR(svn_utf_cstring_to_utf8(&first_arg_utf8,
                                                   first_arg, pool));
               svn_error_clear(
                 svn_cmdline_fprintf(stderr, pool,
                                     _("Unknown subcommand: '%s'\n"),
                                     first_arg_utf8));
-              SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
-              return EXIT_FAILURE;
+              SVN_ERR(subcommand_help(NULL, NULL, pool));
+              *exit_code = EXIT_FAILURE;
+              return SVN_NO_ERROR;
             }
         }
     }
@@ -2435,23 +2549,17 @@ sub_main(int argc, const char *argv[], a
 
       if (os->ind >= os->argc)
         {
-          err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                                 _("Repository argument required"));
-          return EXIT_ERROR(err);
+          return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                  _("Repository argument required"));
         }
 
-      if ((err = svn_utf_cstring_to_utf8(&repos_path,
-                                         os->argv[os->ind++], pool)))
-        {
-          return EXIT_ERROR(err);
-        }
+      SVN_ERR(svn_utf_cstring_to_utf8(&repos_path, os->argv[os->ind++], pool));
 
       if (svn_path_is_url(repos_path))
         {
-          err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
-                                  _("'%s' is a URL when it should be a "
-                                    "local path"), repos_path);
-          return EXIT_ERROR(err);
+          return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                   _("'%s' is a URL when it should be a "
+                                     "local path"), repos_path);
         }
 
       opt_state.repository_path = svn_dirent_internal_style(repos_path, pool);
@@ -2477,13 +2585,14 @@ sub_main(int argc, const char *argv[], a
                                           pool);
           svn_opt_format_option(&optstr, badopt, FALSE, pool);
           if (subcommand->name[0] == '-')
-            SVN_INT_ERR(subcommand_help(NULL, NULL, pool));
+            SVN_ERR(subcommand_help(NULL, NULL, pool));
           else
             svn_error_clear(svn_cmdline_fprintf(stderr, pool
                             , _("Subcommand '%s' doesn't accept option '%s'\n"
                                 "Type 'svnadmin help %s' for usage.\n"),
                 subcommand->name, optstr, subcommand->name));
-          return EXIT_FAILURE;
+          *exit_code = EXIT_FAILURE;
+          return SVN_NO_ERROR;
         }
     }
 
@@ -2525,26 +2634,18 @@ sub_main(int argc, const char *argv[], a
           err = svn_error_quick_wrap(err,
                                      _("Try 'svnadmin help' for more info"));
         }
-      return EXIT_ERROR(err);
-    }
-  else
-    {
-      /* Ensure that everything is written to stdout, so the user will
-         see any print errors. */
-      err = svn_cmdline_fflush(stdout);
-      if (err)
-        {
-          return EXIT_ERROR(err);
-        }
-      return EXIT_SUCCESS;
+      return err;
     }
+
+  return SVN_NO_ERROR;
 }
 
 int
 main(int argc, const char *argv[])
 {
   apr_pool_t *pool;
-  int exit_code;
+  int exit_code = EXIT_SUCCESS;
+  svn_error_t *err;
 
   /* Initialize the app. */
   if (svn_cmdline_init("svnadmin", stderr) != EXIT_SUCCESS)
@@ -2555,7 +2656,17 @@ main(int argc, const char *argv[])
    */
   pool = apr_allocator_owner_get(svn_pool_create_allocator(FALSE));
 
-  exit_code = sub_main(argc, argv, pool);
+  err = sub_main(&exit_code, argc, argv, pool);
+
+  /* Flush stdout and report if it fails. It would be flushed on exit anyway
+     but this makes sure that output is not silently lost if it fails. */
+  err = svn_error_compose_create(err, svn_cmdline_fflush(stdout));
+
+  if (err)
+    {
+      exit_code = EXIT_FAILURE;
+      svn_cmdline_handle_exit_error(err, NULL, "svnadmin: ");
+    }
 
   svn_pool_destroy(pool);
   return exit_code;



Mime
View raw message