You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2012/09/25 02:16:37 UTC

svn commit: r1389662 [2/2] - in /subversion/branches/10Gb: ./ tools/client-side/svn-bench/

Added: subversion/branches/10Gb/tools/client-side/svn-bench/notify.c
URL: http://svn.apache.org/viewvc/subversion/branches/10Gb/tools/client-side/svn-bench/notify.c?rev=1389662&view=auto
==============================================================================
--- subversion/branches/10Gb/tools/client-side/svn-bench/notify.c (added)
+++ subversion/branches/10Gb/tools/client-side/svn-bench/notify.c Tue Sep 25 00:16:36 2012
@@ -0,0 +1,1082 @@
+/*
+ * notify.c:  feedback handlers for cmdline client.
+ *
+ * ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one
+ *    or more contributor license agreements.  See the NOTICE file
+ *    distributed with this work for additional information
+ *    regarding copyright ownership.  The ASF licenses this file
+ *    to you under the Apache License, Version 2.0 (the
+ *    "License"); you may not use this file except in compliance
+ *    with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing,
+ *    software distributed under the License is distributed on an
+ *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *    KIND, either express or implied.  See the License for the
+ *    specific language governing permissions and limitations
+ *    under the License.
+ * ====================================================================
+ */
+
+/* ==================================================================== */
+
+
+
+/*** Includes. ***/
+
+#define APR_WANT_STDIO
+#define APR_WANT_STRFUNC
+#include <apr_want.h>
+
+#include "svn_cmdline.h"
+#include "svn_pools.h"
+#include "svn_dirent_uri.h"
+#include "svn_path.h"
+#include "svn_sorts.h"
+#include "cl.h"
+
+#include "svn_private_config.h"
+
+
+/* Baton for notify and friends. */
+struct notify_baton
+{
+  svn_boolean_t received_some_change;
+  svn_boolean_t is_checkout;
+  svn_boolean_t is_export;
+  svn_boolean_t is_wc_to_repos_copy;
+  svn_boolean_t sent_first_txdelta;
+  svn_boolean_t in_external;
+  svn_boolean_t had_print_error; /* Used to not keep printing error messages
+                                    when we've already had one print error. */
+
+  /* Conflict stats for update and merge. */
+  unsigned int text_conflicts;
+  unsigned int prop_conflicts;
+  unsigned int tree_conflicts;
+  unsigned int skipped_paths;
+  apr_hash_t *conflicted_paths;
+
+  /* The cwd, for use in decomposing absolute paths. */
+  const char *path_prefix;
+};
+
+
+svn_error_t *
+svn_cl__print_conflict_stats(void *notify_baton, apr_pool_t *pool)
+{
+  struct notify_baton *nb = notify_baton;
+  unsigned int text_conflicts;
+  unsigned int prop_conflicts;
+  unsigned int tree_conflicts;
+  unsigned int skipped_paths;
+
+  text_conflicts = nb->text_conflicts;
+  prop_conflicts = nb->prop_conflicts;
+  tree_conflicts = nb->tree_conflicts;
+  skipped_paths = nb->skipped_paths;
+
+  if (text_conflicts > 0 || prop_conflicts > 0
+    || tree_conflicts > 0 || skipped_paths > 0)
+      SVN_ERR(svn_cmdline_printf(pool, "%s", _("Summary of conflicts:\n")));
+
+  if (text_conflicts > 0)
+    SVN_ERR(svn_cmdline_printf
+      (pool, _("  Text conflicts: %u\n"), text_conflicts));
+
+  if (prop_conflicts > 0)
+    SVN_ERR(svn_cmdline_printf
+      (pool, _("  Property conflicts: %u\n"), prop_conflicts));
+
+  if (tree_conflicts > 0)
+    SVN_ERR(svn_cmdline_printf
+      (pool, _("  Tree conflicts: %u\n"), tree_conflicts));
+
+  if (skipped_paths > 0)
+    SVN_ERR(svn_cmdline_printf
+      (pool, _("  Skipped paths: %u\n"), skipped_paths));
+
+  return SVN_NO_ERROR;
+}
+
+/* Add a conflicted path to the list of conflicted paths stored
+ * in the notify baton. */
+static void
+add_conflicted_path(struct notify_baton *nb, const char *path)
+{
+  apr_hash_set(nb->conflicted_paths,
+               apr_pstrdup(apr_hash_pool_get(nb->conflicted_paths), path),
+               APR_HASH_KEY_STRING, "");
+}
+
+/* This implements `svn_wc_notify_func2_t'.
+ * NOTE: This function can't fail, so we just ignore any print errors. */
+static void
+notify(void *baton, const svn_wc_notify_t *n, apr_pool_t *pool)
+{
+  struct notify_baton *nb = baton;
+  char statchar_buf[5] = "    ";
+  const char *path_local;
+  svn_error_t *err;
+
+  if (n->url)
+    path_local = n->url;
+  else
+    {
+      if (n->path_prefix)
+        path_local = svn_cl__local_style_skip_ancestor(n->path_prefix, n->path,
+                                                       pool);
+      else /* skip nb->path_prefix, if it's non-null */
+        path_local = svn_cl__local_style_skip_ancestor(nb->path_prefix, n->path,
+                                                       pool);
+    }
+
+  switch (n->action)
+    {
+    case svn_wc_notify_skip:
+      nb->skipped_paths++;
+      if (n->content_state == svn_wc_notify_state_missing)
+        {
+          if ((err = svn_cmdline_printf
+               (pool, _("Skipped missing target: '%s'\n"),
+                path_local)))
+            goto print_error;
+        }
+      else if (n->content_state == svn_wc_notify_state_source_missing)
+        {
+          if ((err = svn_cmdline_printf
+               (pool, _("Skipped target: '%s' -- copy-source is missing\n"),
+                path_local)))
+            goto print_error;
+        }
+      else
+        {
+          if ((err = svn_cmdline_printf
+               (pool, _("Skipped '%s'\n"), path_local)))
+            goto print_error;
+        }
+      break;
+    case svn_wc_notify_update_skip_obstruction:
+      nb->skipped_paths++;
+      if ((err = svn_cmdline_printf(
+            pool, _("Skipped '%s' -- An obstructing working copy was found\n"),
+            path_local)))
+        goto print_error;
+      break;
+    case svn_wc_notify_update_skip_working_only:
+      nb->skipped_paths++;
+      if ((err = svn_cmdline_printf(
+            pool, _("Skipped '%s' -- Has no versioned parent\n"),
+            path_local)))
+        goto print_error;
+      break;
+    case svn_wc_notify_update_skip_access_denied:
+      nb->skipped_paths++;
+      if ((err = svn_cmdline_printf(
+            pool, _("Skipped '%s' -- Access denied\n"),
+            path_local)))
+        goto print_error;
+      break;
+    case svn_wc_notify_skip_conflicted:
+      nb->skipped_paths++;
+      if ((err = svn_cmdline_printf(
+            pool, _("Skipped '%s' -- Node remains in conflict\n"),
+            path_local)))
+        goto print_error;
+      break;
+    case svn_wc_notify_update_delete:
+    case svn_wc_notify_exclude:
+      nb->received_some_change = TRUE;
+      if ((err = svn_cmdline_printf(pool, "D    %s\n", path_local)))
+        goto print_error;
+      break;
+    case svn_wc_notify_update_broken_lock:
+      if ((err = svn_cmdline_printf(pool, "B    %s\n", path_local)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_update_external_removed:
+      nb->received_some_change = TRUE;
+      if (n->err && n->err->message)
+        {
+          if ((err = svn_cmdline_printf(pool, "Removed external '%s': %s\n",
+              path_local, n->err->message)))
+            goto print_error;
+        }
+      else
+        {
+          if ((err = svn_cmdline_printf(pool, "Removed external '%s'\n",
+                                        path_local)))
+            goto print_error;
+        }
+      break;
+
+    case svn_wc_notify_left_local_modifications:
+      if ((err = svn_cmdline_printf(pool, "Left local modifications as '%s'\n",
+                                        path_local)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_update_replace:
+      nb->received_some_change = TRUE;
+      if ((err = svn_cmdline_printf(pool, "R    %s\n", path_local)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_update_add:
+      nb->received_some_change = TRUE;
+      if (n->content_state == svn_wc_notify_state_conflicted)
+        {
+          nb->text_conflicts++;
+          add_conflicted_path(nb, n->path);
+          if ((err = svn_cmdline_printf(pool, "C    %s\n", path_local)))
+            goto print_error;
+        }
+      else
+        {
+          if ((err = svn_cmdline_printf(pool, "A    %s\n", path_local)))
+            goto print_error;
+        }
+      break;
+
+    case svn_wc_notify_exists:
+      nb->received_some_change = TRUE;
+      if (n->content_state == svn_wc_notify_state_conflicted)
+        {
+          nb->text_conflicts++;
+          add_conflicted_path(nb, n->path);
+          statchar_buf[0] = 'C';
+        }
+      else
+        statchar_buf[0] = 'E';
+
+      if (n->prop_state == svn_wc_notify_state_conflicted)
+        {
+          nb->prop_conflicts++;
+          add_conflicted_path(nb, n->path);
+          statchar_buf[1] = 'C';
+        }
+      else if (n->prop_state == svn_wc_notify_state_merged)
+        statchar_buf[1] = 'G';
+
+      if ((err = svn_cmdline_printf(pool, "%s %s\n", statchar_buf, path_local)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_restore:
+      if ((err = svn_cmdline_printf(pool, _("Restored '%s'\n"),
+                                    path_local)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_revert:
+      if ((err = svn_cmdline_printf(pool, _("Reverted '%s'\n"),
+                                    path_local)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_failed_revert:
+      if (( err = svn_cmdline_printf(pool, _("Failed to revert '%s' -- "
+                                             "try updating instead.\n"),
+                                     path_local)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_resolved:
+      if ((err = svn_cmdline_printf(pool,
+                                    _("Resolved conflicted state of '%s'\n"),
+                                    path_local)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_add:
+      /* We *should* only get the MIME_TYPE if PATH is a file.  If we
+         do get it, and the mime-type is not textual, note that this
+         is a binary addition. */
+      if (n->mime_type && (svn_mime_type_is_binary(n->mime_type)))
+        {
+          if ((err = svn_cmdline_printf(pool, "A  (bin)  %s\n",
+                                        path_local)))
+            goto print_error;
+        }
+      else
+        {
+          if ((err = svn_cmdline_printf(pool, "A         %s\n",
+                                        path_local)))
+            goto print_error;
+        }
+      break;
+
+    case svn_wc_notify_delete:
+      nb->received_some_change = TRUE;
+      if ((err = svn_cmdline_printf(pool, "D         %s\n",
+                                    path_local)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_patch:
+      {
+        nb->received_some_change = TRUE;
+        if (n->content_state == svn_wc_notify_state_conflicted)
+          {
+            nb->text_conflicts++;
+            add_conflicted_path(nb, n->path);
+            statchar_buf[0] = 'C';
+          }
+        else if (n->kind == svn_node_file)
+          {
+            if (n->content_state == svn_wc_notify_state_merged)
+              statchar_buf[0] = 'G';
+            else if (n->content_state == svn_wc_notify_state_changed)
+              statchar_buf[0] = 'U';
+          }
+
+        if (n->prop_state == svn_wc_notify_state_conflicted)
+          {
+            nb->prop_conflicts++;
+            add_conflicted_path(nb, n->path);
+            statchar_buf[1] = 'C';
+          }
+        else if (n->prop_state == svn_wc_notify_state_changed)
+              statchar_buf[1] = 'U';
+
+        if (statchar_buf[0] != ' ' || statchar_buf[1] != ' ')
+          {
+            if ((err = svn_cmdline_printf(pool, "%s      %s\n",
+                                          statchar_buf, path_local)))
+              goto print_error;
+          }
+      }
+      break;
+
+    case svn_wc_notify_patch_applied_hunk:
+      nb->received_some_change = TRUE;
+      if (n->hunk_original_start != n->hunk_matched_line)
+        {
+          apr_uint64_t off;
+          const char *s;
+          const char *minus;
+
+          if (n->hunk_matched_line > n->hunk_original_start)
+            {
+              off = n->hunk_matched_line - n->hunk_original_start;
+              minus = "";
+            }
+          else
+            {
+              off = n->hunk_original_start - n->hunk_matched_line;
+              minus = "-";
+            }
+
+          /* ### We're creating the localized strings without
+           * ### APR_INT64_T_FMT since it isn't translator-friendly */
+          if (n->hunk_fuzz)
+            {
+
+              if (n->prop_name)
+                {
+                  s = _(">         applied hunk ## -%lu,%lu +%lu,%lu ## "
+                        "with offset %s");
+
+                  err = svn_cmdline_printf(pool,
+                                           apr_pstrcat(pool, s,
+                                                       "%"APR_UINT64_T_FMT
+                                                       " and fuzz %lu (%s)\n",
+                                                       (char *)NULL),
+                                           n->hunk_original_start,
+                                           n->hunk_original_length,
+                                           n->hunk_modified_start,
+                                           n->hunk_modified_length,
+                                           minus, off, n->hunk_fuzz,
+                                           n->prop_name);
+                }
+              else
+                {
+                  s = _(">         applied hunk @@ -%lu,%lu +%lu,%lu @@ "
+                        "with offset %s");
+
+                  err = svn_cmdline_printf(pool,
+                                           apr_pstrcat(pool, s,
+                                                       "%"APR_UINT64_T_FMT
+                                                       " and fuzz %lu\n",
+                                                       (char *)NULL),
+                                           n->hunk_original_start,
+                                           n->hunk_original_length,
+                                           n->hunk_modified_start,
+                                           n->hunk_modified_length,
+                                           minus, off, n->hunk_fuzz);
+                }
+
+              if (err)
+                goto print_error;
+            }
+          else
+            {
+
+              if (n->prop_name)
+                {
+                  s = _(">         applied hunk ## -%lu,%lu +%lu,%lu ## "
+                        "with offset %s");
+                  err = svn_cmdline_printf(pool,
+                                            apr_pstrcat(pool, s,
+                                                        "%"APR_UINT64_T_FMT" (%s)\n",
+                                                        (char *)NULL),
+                                            n->hunk_original_start,
+                                            n->hunk_original_length,
+                                            n->hunk_modified_start,
+                                            n->hunk_modified_length,
+                                            minus, off, n->prop_name);
+                }
+              else
+                {
+                  s = _(">         applied hunk @@ -%lu,%lu +%lu,%lu @@ "
+                        "with offset %s");
+                  err = svn_cmdline_printf(pool,
+                                           apr_pstrcat(pool, s,
+                                                       "%"APR_UINT64_T_FMT"\n",
+                                                       (char *)NULL),
+                                           n->hunk_original_start,
+                                           n->hunk_original_length,
+                                           n->hunk_modified_start,
+                                           n->hunk_modified_length,
+                                           minus, off);
+                }
+
+              if (err)
+                goto print_error;
+            }
+        }
+      else if (n->hunk_fuzz)
+        {
+          if (n->prop_name)
+            err = svn_cmdline_printf(pool,
+                          _(">         applied hunk ## -%lu,%lu +%lu,%lu ## "
+                                        "with fuzz %lu (%s)\n"),
+                                        n->hunk_original_start,
+                                        n->hunk_original_length,
+                                        n->hunk_modified_start,
+                                        n->hunk_modified_length,
+                                        n->hunk_fuzz,
+                                        n->prop_name);
+          else
+            err = svn_cmdline_printf(pool,
+                          _(">         applied hunk @@ -%lu,%lu +%lu,%lu @@ "
+                                        "with fuzz %lu\n"),
+                                        n->hunk_original_start,
+                                        n->hunk_original_length,
+                                        n->hunk_modified_start,
+                                        n->hunk_modified_length,
+                                        n->hunk_fuzz);
+          if (err)
+            goto print_error;
+
+        }
+      break;
+
+    case svn_wc_notify_patch_rejected_hunk:
+      nb->received_some_change = TRUE;
+
+      if (n->prop_name)
+        err = svn_cmdline_printf(pool,
+                                 _(">         rejected hunk "
+                                   "## -%lu,%lu +%lu,%lu ## (%s)\n"),
+                                 n->hunk_original_start,
+                                 n->hunk_original_length,
+                                 n->hunk_modified_start,
+                                 n->hunk_modified_length,
+                                 n->prop_name);
+      else
+        err = svn_cmdline_printf(pool,
+                                 _(">         rejected hunk "
+                                   "@@ -%lu,%lu +%lu,%lu @@\n"),
+                                 n->hunk_original_start,
+                                 n->hunk_original_length,
+                                 n->hunk_modified_start,
+                                 n->hunk_modified_length);
+      if (err)
+        goto print_error;
+      break;
+
+    case svn_wc_notify_patch_hunk_already_applied:
+      nb->received_some_change = TRUE;
+      if (n->prop_name)
+        err = svn_cmdline_printf(pool,
+                                 _(">         hunk "
+                                   "## -%lu,%lu +%lu,%lu ## "
+                                   "already applied (%s)\n"),
+                                 n->hunk_original_start,
+                                 n->hunk_original_length,
+                                 n->hunk_modified_start,
+                                 n->hunk_modified_length,
+                                 n->prop_name);
+      else
+        err = svn_cmdline_printf(pool,
+                                 _(">         hunk "
+                                   "@@ -%lu,%lu +%lu,%lu @@ "
+                                   "already applied\n"),
+                                 n->hunk_original_start,
+                                 n->hunk_original_length,
+                                 n->hunk_modified_start,
+                                 n->hunk_modified_length);
+      if (err)
+        goto print_error;
+      break;
+
+    case svn_wc_notify_update_update:
+    case svn_wc_notify_merge_record_info:
+      {
+        if (n->content_state == svn_wc_notify_state_conflicted)
+          {
+            nb->text_conflicts++;
+            add_conflicted_path(nb, n->path);
+            statchar_buf[0] = 'C';
+          }
+        else if (n->kind == svn_node_file)
+          {
+            if (n->content_state == svn_wc_notify_state_merged)
+              statchar_buf[0] = 'G';
+            else if (n->content_state == svn_wc_notify_state_changed)
+              statchar_buf[0] = 'U';
+          }
+
+        if (n->prop_state == svn_wc_notify_state_conflicted)
+          {
+            nb->prop_conflicts++;
+            add_conflicted_path(nb, n->path);
+            statchar_buf[1] = 'C';
+          }
+        else if (n->prop_state == svn_wc_notify_state_merged)
+          statchar_buf[1] = 'G';
+        else if (n->prop_state == svn_wc_notify_state_changed)
+          statchar_buf[1] = 'U';
+
+        if (n->lock_state == svn_wc_notify_lock_state_unlocked)
+          statchar_buf[2] = 'B';
+
+        if (statchar_buf[0] != ' ' || statchar_buf[1] != ' ')
+          nb->received_some_change = TRUE;
+
+        if (statchar_buf[0] != ' ' || statchar_buf[1] != ' '
+            || statchar_buf[2] != ' ')
+          {
+            if ((err = svn_cmdline_printf(pool, "%s %s\n",
+                                          statchar_buf, path_local)))
+              goto print_error;
+          }
+      }
+      break;
+
+    case svn_wc_notify_update_external:
+      /* Remember that we're now "inside" an externals definition. */
+      nb->in_external = TRUE;
+
+      /* Currently this is used for checkouts and switches too.  If we
+         want different output, we'll have to add new actions. */
+      if ((err = svn_cmdline_printf(pool,
+                                    _("\nFetching external item into '%s':\n"),
+                                    path_local)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_failed_external:
+      /* If we are currently inside the handling of an externals
+         definition, then we can simply present n->err as a warning
+         and feel confident that after this, we aren't handling that
+         externals definition any longer. */
+      if (nb->in_external)
+        {
+          svn_handle_warning2(stderr, n->err, "svn: ");
+          nb->in_external = FALSE;
+          if ((err = svn_cmdline_printf(pool, "\n")))
+            goto print_error;
+        }
+      /* Otherwise, we'll just print two warnings.  Why?  Because
+         svn_handle_warning2() only shows the single "best message",
+         but we have two pretty important ones: that the external at
+         '/some/path' didn't pan out, and then the more specific
+         reason why (from n->err). */
+      else
+        {
+          svn_error_t *warn_err =
+            svn_error_createf(SVN_ERR_BASE, NULL,
+                              _("Error handling externals definition for '%s':"),
+                              path_local);
+          svn_handle_warning2(stderr, warn_err, "svn: ");
+          svn_error_clear(warn_err);
+          svn_handle_warning2(stderr, n->err, "svn: ");
+        }
+      break;
+
+    case svn_wc_notify_update_started:
+      if (! (nb->in_external ||
+             nb->is_checkout ||
+             nb->is_export))
+        {
+          if ((err = svn_cmdline_printf(pool, _("Updating '%s':\n"),
+                                        path_local)))
+            goto print_error;
+        }
+      break;
+
+    case svn_wc_notify_update_completed:
+      {
+        if (SVN_IS_VALID_REVNUM(n->revision))
+          {
+            if (nb->is_export)
+              {
+                if ((err = svn_cmdline_printf
+                     (pool, nb->in_external
+                      ? _("Exported external at revision %ld.\n")
+                      : _("Exported revision %ld.\n"),
+                      n->revision)))
+                  goto print_error;
+              }
+            else if (nb->is_checkout)
+              {
+                if ((err = svn_cmdline_printf
+                     (pool, nb->in_external
+                      ? _("Checked out external at revision %ld.\n")
+                      : _("Checked out revision %ld.\n"),
+                      n->revision)))
+                  goto print_error;
+              }
+            else
+              {
+                if (nb->received_some_change)
+                  {
+                    nb->received_some_change = FALSE;
+                    if ((err = svn_cmdline_printf
+                         (pool, nb->in_external
+                          ? _("Updated external to revision %ld.\n")
+                          : _("Updated to revision %ld.\n"),
+                          n->revision)))
+                      goto print_error;
+                  }
+                else
+                  {
+                    if ((err = svn_cmdline_printf
+                         (pool, nb->in_external
+                          ? _("External at revision %ld.\n")
+                          : _("At revision %ld.\n"),
+                          n->revision)))
+                      goto print_error;
+                  }
+              }
+          }
+        else  /* no revision */
+          {
+            if (nb->is_export)
+              {
+                if ((err = svn_cmdline_printf
+                     (pool, nb->in_external
+                      ? _("External export complete.\n")
+                      : _("Export complete.\n"))))
+                  goto print_error;
+              }
+            else if (nb->is_checkout)
+              {
+                if ((err = svn_cmdline_printf
+                     (pool, nb->in_external
+                      ? _("External checkout complete.\n")
+                      : _("Checkout complete.\n"))))
+                  goto print_error;
+              }
+            else
+              {
+                if ((err = svn_cmdline_printf
+                     (pool, nb->in_external
+                      ? _("External update complete.\n")
+                      : _("Update complete.\n"))))
+                  goto print_error;
+              }
+          }
+      }
+
+      if (nb->in_external)
+        {
+          nb->in_external = FALSE;
+          if ((err = svn_cmdline_printf(pool, "\n")))
+            goto print_error;
+        }
+      break;
+
+    case svn_wc_notify_status_external:
+      if ((err = svn_cmdline_printf
+           (pool, _("\nPerforming status on external item at '%s':\n"),
+            path_local)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_status_completed:
+      if (SVN_IS_VALID_REVNUM(n->revision))
+        if ((err = svn_cmdline_printf(pool,
+                                      _("Status against revision: %6ld\n"),
+                                      n->revision)))
+          goto print_error;
+      break;
+
+    case svn_wc_notify_commit_modified:
+      /* xgettext: Align the %s's on this and the following 4 messages */
+      if ((err = svn_cmdline_printf(pool,
+                                    nb->is_wc_to_repos_copy
+                                      ? _("Sending copy of       %s\n")
+                                      : _("Sending        %s\n"),
+                                    path_local)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_commit_added:
+    case svn_wc_notify_commit_copied:
+      if (n->mime_type && svn_mime_type_is_binary(n->mime_type))
+        {
+          if ((err = svn_cmdline_printf(pool,
+                                        nb->is_wc_to_repos_copy
+                                          ? _("Adding copy of (bin)  %s\n")
+                                          : _("Adding  (bin)  %s\n"),
+                                        path_local)))
+          goto print_error;
+        }
+      else
+        {
+          if ((err = svn_cmdline_printf(pool,
+                                        nb->is_wc_to_repos_copy
+                                          ? _("Adding copy of        %s\n")
+                                          : _("Adding         %s\n"),
+                                        path_local)))
+            goto print_error;
+        }
+      break;
+
+    case svn_wc_notify_commit_deleted:
+      if ((err = svn_cmdline_printf(pool,
+                                    nb->is_wc_to_repos_copy
+                                      ? _("Deleting copy of      %s\n")
+                                      : _("Deleting       %s\n"),
+                                    path_local)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_commit_replaced:
+    case svn_wc_notify_commit_copied_replaced:
+      if ((err = svn_cmdline_printf(pool,
+                                    nb->is_wc_to_repos_copy
+                                      ? _("Replacing copy of     %s\n")
+                                      : _("Replacing      %s\n"),
+                                    path_local)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_commit_postfix_txdelta:
+      if (! nb->sent_first_txdelta)
+        {
+          nb->sent_first_txdelta = TRUE;
+          if ((err = svn_cmdline_printf(pool,
+                                        _("Transmitting file data "))))
+            goto print_error;
+        }
+
+      if ((err = svn_cmdline_printf(pool, ".")))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_locked:
+      if ((err = svn_cmdline_printf(pool, _("'%s' locked by user '%s'.\n"),
+                                    path_local, n->lock->owner)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_unlocked:
+      if ((err = svn_cmdline_printf(pool, _("'%s' unlocked.\n"),
+                                    path_local)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_failed_lock:
+    case svn_wc_notify_failed_unlock:
+      svn_handle_warning2(stderr, n->err, "svn: ");
+      break;
+
+    case svn_wc_notify_changelist_set:
+      if ((err = svn_cmdline_printf(pool, "A [%s] %s\n",
+                                    n->changelist_name, path_local)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_changelist_clear:
+    case svn_wc_notify_changelist_moved:
+      if ((err = svn_cmdline_printf(pool,
+                                    "D [%s] %s\n",
+                                    n->changelist_name, path_local)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_merge_begin:
+      if (n->merge_range == NULL)
+        err = svn_cmdline_printf(pool,
+                                 _("--- Merging differences between "
+                                   "repository URLs into '%s':\n"),
+                                 path_local);
+      else if (n->merge_range->start == n->merge_range->end - 1
+          || n->merge_range->start == n->merge_range->end)
+        err = svn_cmdline_printf(pool, _("--- Merging r%ld into '%s':\n"),
+                                 n->merge_range->end, path_local);
+      else if (n->merge_range->start - 1 == n->merge_range->end)
+        err = svn_cmdline_printf(pool,
+                                 _("--- Reverse-merging r%ld into '%s':\n"),
+                                 n->merge_range->start, path_local);
+      else if (n->merge_range->start < n->merge_range->end)
+        err = svn_cmdline_printf(pool,
+                                 _("--- Merging r%ld through r%ld into "
+                                   "'%s':\n"),
+                                 n->merge_range->start + 1,
+                                 n->merge_range->end, path_local);
+      else /* n->merge_range->start > n->merge_range->end - 1 */
+        err = svn_cmdline_printf(pool,
+                                 _("--- Reverse-merging r%ld through r%ld "
+                                   "into '%s':\n"),
+                                 n->merge_range->start,
+                                 n->merge_range->end + 1, path_local);
+      if (err)
+        goto print_error;
+      break;
+
+    case svn_wc_notify_merge_record_info_begin:
+      if (!n->merge_range)
+        {
+          err = svn_cmdline_printf(pool,
+                                   _("--- Recording mergeinfo for merge "
+                                     "between repository URLs into '%s':\n"),
+                                   path_local);
+        }
+      else
+        {
+          if (n->merge_range->start == n->merge_range->end - 1
+              || n->merge_range->start == n->merge_range->end)
+            err = svn_cmdline_printf(
+              pool,
+              _("--- Recording mergeinfo for merge of r%ld into '%s':\n"),
+              n->merge_range->end, path_local);
+          else if (n->merge_range->start - 1 == n->merge_range->end)
+            err = svn_cmdline_printf(
+              pool,
+              _("--- Recording mergeinfo for reverse merge of r%ld into '%s':\n"),
+              n->merge_range->start, path_local);
+           else if (n->merge_range->start < n->merge_range->end)
+             err = svn_cmdline_printf(
+               pool,
+               _("--- Recording mergeinfo for merge of r%ld through r%ld into '%s':\n"),
+               n->merge_range->start + 1, n->merge_range->end, path_local);
+           else /* n->merge_range->start > n->merge_range->end - 1 */
+             err = svn_cmdline_printf(
+               pool,
+               _("--- Recording mergeinfo for reverse merge of r%ld through r%ld into '%s':\n"),
+               n->merge_range->start, n->merge_range->end + 1, path_local);
+        }
+
+      if (err)
+        goto print_error;
+      break;
+
+    case svn_wc_notify_merge_elide_info:
+      if ((err = svn_cmdline_printf(pool,
+                                    _("--- Eliding mergeinfo from '%s':\n"),
+                                    path_local)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_foreign_merge_begin:
+      if (n->merge_range == NULL)
+        err = svn_cmdline_printf(pool,
+                                 _("--- Merging differences between "
+                                   "foreign repository URLs into '%s':\n"),
+                                 path_local);
+      else if (n->merge_range->start == n->merge_range->end - 1
+          || n->merge_range->start == n->merge_range->end)
+        err = svn_cmdline_printf(pool,
+                                 _("--- Merging (from foreign repository) "
+                                   "r%ld into '%s':\n"),
+                                 n->merge_range->end, path_local);
+      else if (n->merge_range->start - 1 == n->merge_range->end)
+        err = svn_cmdline_printf(pool,
+                                 _("--- Reverse-merging (from foreign "
+                                   "repository) r%ld into '%s':\n"),
+                                 n->merge_range->start, path_local);
+      else if (n->merge_range->start < n->merge_range->end)
+        err = svn_cmdline_printf(pool,
+                                 _("--- Merging (from foreign repository) "
+                                   "r%ld through r%ld into '%s':\n"),
+                                 n->merge_range->start + 1,
+                                 n->merge_range->end, path_local);
+      else /* n->merge_range->start > n->merge_range->end - 1 */
+        err = svn_cmdline_printf(pool,
+                                 _("--- Reverse-merging (from foreign "
+                                   "repository) r%ld through r%ld into "
+                                   "'%s':\n"),
+                                 n->merge_range->start,
+                                 n->merge_range->end + 1, path_local);
+      if (err)
+        goto print_error;
+      break;
+
+    case svn_wc_notify_tree_conflict:
+      nb->tree_conflicts++;
+      add_conflicted_path(nb, n->path);
+      if ((err = svn_cmdline_printf(pool, "   C %s\n", path_local)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_update_shadowed_add:
+      nb->received_some_change = TRUE;
+      if ((err = svn_cmdline_printf(pool, "   A %s\n", path_local)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_update_shadowed_update:
+      nb->received_some_change = TRUE;
+      if ((err = svn_cmdline_printf(pool, "   U %s\n", path_local)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_update_shadowed_delete:
+      nb->received_some_change = TRUE;
+      if ((err = svn_cmdline_printf(pool, "   D %s\n", path_local)))
+        goto print_error;
+      break;
+
+    case svn_wc_notify_property_modified:
+    case svn_wc_notify_property_added:
+        err = svn_cmdline_printf(pool,
+                                 _("property '%s' set on '%s'\n"),
+                                 n->prop_name, path_local);
+        if (err)
+          goto print_error;
+      break;
+
+    case svn_wc_notify_property_deleted:
+        err = svn_cmdline_printf(pool,
+                                 _("property '%s' deleted from '%s'.\n"),
+                                 n->prop_name, path_local);
+        if (err)
+          goto print_error;
+      break;
+
+    case svn_wc_notify_property_deleted_nonexistent:
+        err = svn_cmdline_printf(pool,
+                                 _("Attempting to delete nonexistent "
+                                   "property '%s' on '%s'\n"), n->prop_name,
+                                   path_local);
+        if (err)
+          goto print_error;
+      break;
+
+    case svn_wc_notify_revprop_set:
+        err = svn_cmdline_printf(pool,
+                          _("property '%s' set on repository revision %ld\n"),
+                          n->prop_name, n->revision);
+        if (err)
+          goto print_error;
+      break;
+
+    case svn_wc_notify_revprop_deleted:
+        err = svn_cmdline_printf(pool,
+                     _("property '%s' deleted from repository revision %ld\n"),
+                     n->prop_name, n->revision);
+        if (err)
+          goto print_error;
+      break;
+
+    case svn_wc_notify_upgraded_path:
+        err = svn_cmdline_printf(pool, _("Upgraded '%s'\n"), path_local);
+        if (err)
+          goto print_error;
+      break;
+
+    case svn_wc_notify_url_redirect:
+      err = svn_cmdline_printf(pool, _("Redirecting to URL '%s':\n"),
+                               n->url);
+      if (err)
+        goto print_error;
+      break;
+
+    case svn_wc_notify_path_nonexistent:
+      err = svn_cmdline_printf(pool, _("'%s' is not under version control"),
+                               path_local);
+      if (err)
+        goto print_error;
+      break;
+
+    case svn_wc_notify_conflict_resolver_starting:
+      /* Once all operations invoke the interactive conflict resolution after
+       * they've completed, we can run svn_cl__print_conflict_stats() here. */
+      break;
+
+    case svn_wc_notify_conflict_resolver_done:
+      break;
+
+    default:
+      break;
+    }
+
+  if ((err = svn_cmdline_fflush(stdout)))
+    goto print_error;
+
+  return;
+
+ print_error:
+  /* If we had no errors before, print this error to stderr. Else, don't print
+     anything.  The user already knows there were some output errors,
+     so there is no point in flooding her with an error per notification. */
+  if (!nb->had_print_error)
+    {
+      nb->had_print_error = TRUE;
+      /* Issue #3014:
+       * Don't print anything on broken pipes. The pipe was likely
+       * closed by the process at the other end. We expect that
+       * process to perform error reporting as necessary.
+       *
+       * ### This assumes that there is only one error in a chain for
+       * ### SVN_ERR_IO_PIPE_WRITE_ERROR. See svn_cmdline_fputs(). */
+      if (err->apr_err != SVN_ERR_IO_PIPE_WRITE_ERROR)
+        svn_handle_error2(err, stderr, FALSE, "svn: ");
+    }
+  svn_error_clear(err);
+}
+
+
+svn_error_t *
+svn_cl__get_notifier(svn_wc_notify_func2_t *notify_func_p,
+                     void **notify_baton_p,
+                     apr_pool_t *pool)
+{
+  struct notify_baton *nb = apr_pcalloc(pool, sizeof(*nb));
+
+  nb->received_some_change = FALSE;
+  nb->sent_first_txdelta = FALSE;
+  nb->is_checkout = FALSE;
+  nb->is_export = FALSE;
+  nb->is_wc_to_repos_copy = FALSE;
+  nb->in_external = FALSE;
+  nb->had_print_error = FALSE;
+  nb->text_conflicts = 0;
+  nb->prop_conflicts = 0;
+  nb->tree_conflicts = 0;
+  nb->skipped_paths = 0;
+  nb->conflicted_paths = apr_hash_make(pool);
+  SVN_ERR(svn_dirent_get_absolute(&nb->path_prefix, "", pool));
+
+  *notify_func_p = notify;
+  *notify_baton_p = nb;
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_cl__notifier_mark_export(void *baton)
+{
+  struct notify_baton *nb = baton;
+
+  nb->is_export = TRUE;
+  return SVN_NO_ERROR;
+}

Added: subversion/branches/10Gb/tools/client-side/svn-bench/null-export-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/10Gb/tools/client-side/svn-bench/null-export-cmd.c?rev=1389662&view=auto
==============================================================================
--- subversion/branches/10Gb/tools/client-side/svn-bench/null-export-cmd.c (added)
+++ subversion/branches/10Gb/tools/client-side/svn-bench/null-export-cmd.c Tue Sep 25 00:16:36 2012
@@ -0,0 +1,358 @@
+/*
+ * export-cmd.c -- Subversion export command
+ *
+ * ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one
+ *    or more contributor license agreements.  See the NOTICE file
+ *    distributed with this work for additional information
+ *    regarding copyright ownership.  The ASF licenses this file
+ *    to you under the Apache License, Version 2.0 (the
+ *    "License"); you may not use this file except in compliance
+ *    with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing,
+ *    software distributed under the License is distributed on an
+ *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *    KIND, either express or implied.  See the License for the
+ *    specific language governing permissions and limitations
+ *    under the License.
+ * ====================================================================
+ */
+
+/* ==================================================================== */
+
+
+
+/*** Includes. ***/
+
+#include "svn_client.h"
+#include "svn_error.h"
+#include "svn_dirent_uri.h"
+#include "svn_path.h"
+#include "svn_cmdline.h"
+#include "cl.h"
+
+#include "svn_private_config.h"
+#include "libsvn_client/client.h"
+
+
+/*** The export editor code. ***/
+
+/* ---------------------------------------------------------------------- */
+
+/*** A dedicated 'export' editor, which does no .svn/ accounting.  ***/
+
+typedef struct edit_baton_t
+{
+  apr_int64_t file_count;
+  apr_int64_t dir_count;
+  apr_int64_t byte_count;
+  apr_int64_t prop_count;
+  apr_int64_t prop_byte_count;
+} edit_baton_t;
+
+static svn_error_t *
+set_target_revision(void *edit_baton,
+                    svn_revnum_t target_revision,
+                    apr_pool_t *pool)
+{
+  return SVN_NO_ERROR;
+}
+
+
+/* Just ensure that the main export directory exists. */
+static svn_error_t *
+open_root(void *edit_baton,
+          svn_revnum_t base_revision,
+          apr_pool_t *pool,
+          void **root_baton)
+{
+  *root_baton = edit_baton;
+  return SVN_NO_ERROR;
+}
+
+
+/* Ensure the directory exists, and send feedback. */
+static svn_error_t *
+add_directory(const char *path,
+              void *parent_baton,
+              const char *copyfrom_path,
+              svn_revnum_t copyfrom_revision,
+              apr_pool_t *pool,
+              void **baton)
+{
+  edit_baton_t *eb = parent_baton;
+  eb->dir_count++;
+
+  *baton = parent_baton;
+  return SVN_NO_ERROR;
+}
+
+
+/* Build a file baton. */
+static svn_error_t *
+add_file(const char *path,
+          void *parent_baton,
+          const char *copyfrom_path,
+          svn_revnum_t copyfrom_revision,
+          apr_pool_t *pool,
+          void **baton)
+{
+  edit_baton_t *eb = parent_baton;
+  eb->file_count++;
+
+  *baton = parent_baton;
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+window_handler(svn_txdelta_window_t *window, void *baton)
+{
+  edit_baton_t *eb = baton;
+  if (window != NULL)
+    eb->byte_count += window->tview_len;
+
+  return SVN_NO_ERROR;
+}
+
+/* Write incoming data into the tmpfile stream */
+
+static svn_error_t *
+apply_textdelta(void *file_baton,
+                const char *base_checksum,
+                apr_pool_t *pool,
+                svn_txdelta_window_handler_t *handler,
+                void **handler_baton)
+{
+  *handler_baton = file_baton;
+  *handler = window_handler;
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+change_file_prop(void *file_baton,
+                 const char *name,
+                 const svn_string_t *value,
+                 apr_pool_t *pool)
+{
+  edit_baton_t *eb = file_baton;
+  eb->prop_count++;
+  eb->prop_byte_count += value->len;
+  
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+change_dir_prop(void *dir_baton,
+                const char *name,
+                const svn_string_t *value,
+                apr_pool_t *pool)
+{
+  edit_baton_t *eb = dir_baton;
+  eb->prop_count++;
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+close_file(void *file_baton,
+           const char *text_checksum,
+           apr_pool_t *pool)
+{
+  return SVN_NO_ERROR;
+}
+
+
+/*** Public Interfaces ***/
+
+svn_error_t *
+bench_null_export(svn_revnum_t *result_rev,
+                  const char *from_path_or_url,
+                  svn_opt_revision_t *peg_revision,
+                  svn_opt_revision_t *revision,
+                  svn_depth_t depth,
+                  void *baton,
+                  svn_client_ctx_t *ctx,
+                  apr_pool_t *pool)
+{
+  svn_revnum_t edit_revision = SVN_INVALID_REVNUM;
+  svn_boolean_t from_is_url = svn_path_is_url(from_path_or_url);
+
+  SVN_ERR_ASSERT(peg_revision != NULL);
+  SVN_ERR_ASSERT(revision != NULL);
+
+  if (peg_revision->kind == svn_opt_revision_unspecified)
+    peg_revision->kind = svn_path_is_url(from_path_or_url)
+                       ? svn_opt_revision_head
+                       : svn_opt_revision_working;
+
+  if (revision->kind == svn_opt_revision_unspecified)
+    revision = peg_revision;
+
+  if (from_is_url || ! SVN_CLIENT__REVKIND_IS_LOCAL_TO_WC(revision->kind))
+    {
+      svn_client__pathrev_t *loc;
+      svn_ra_session_t *ra_session;
+      svn_node_kind_t kind;
+
+      /* Get the RA connection. */
+      SVN_ERR(svn_client__ra_session_from_path2(&ra_session, &loc,
+                                                from_path_or_url, NULL,
+                                                peg_revision,
+                                                revision, ctx, pool));
+
+      SVN_ERR(svn_ra_check_path(ra_session, "", loc->rev, &kind, pool));
+
+      if (kind == svn_node_file)
+        {
+          apr_hash_t *props;
+
+          /* Since you cannot actually root an editor at a file, we
+           * manually drive a few functions of our editor. */
+
+          /* Step outside the editor-likeness for a moment, to actually talk
+           * to the repository. */
+          /* ### note: the stream will not be closed */
+          SVN_ERR(svn_ra_get_file(ra_session, "", loc->rev,
+                                  svn_stream_empty(pool),
+                                  NULL, &props, pool));
+        }
+      else if (kind == svn_node_dir)
+        {
+          void *edit_baton = NULL;
+          const svn_delta_editor_t *export_editor;
+          const svn_ra_reporter3_t *reporter;
+          void *report_baton;
+
+          svn_delta_editor_t *editor = svn_delta_default_editor(pool);
+
+          editor->set_target_revision = set_target_revision;
+          editor->open_root = open_root;
+          editor->add_directory = add_directory;
+          editor->add_file = add_file;
+          editor->apply_textdelta = apply_textdelta;
+          editor->close_file = close_file;
+          editor->change_file_prop = change_file_prop;
+          editor->change_dir_prop = change_dir_prop;
+
+          export_editor = editor;
+          if (ctx->cancel_func)
+            SVN_ERR(svn_delta_get_cancellation_editor(ctx->cancel_func,
+                                                      ctx->cancel_baton,
+                                                      editor,
+                                                      baton,
+                                                      &export_editor,
+                                                      &edit_baton,
+                                                      pool));
+
+          /* Manufacture a basic 'report' to the update reporter. */
+          SVN_ERR(svn_ra_do_update2(ra_session,
+                                    &reporter, &report_baton,
+                                    loc->rev,
+                                    "", /* no sub-target */
+                                    depth,
+                                    FALSE, /* don't want copyfrom-args */
+                                    export_editor, edit_baton, pool));
+
+          SVN_ERR(reporter->set_path(report_baton, "", loc->rev,
+                                     /* Depth is irrelevant, as we're
+                                        passing start_empty=TRUE anyway. */
+                                     svn_depth_infinity,
+                                     TRUE, /* "help, my dir is empty!" */
+                                     NULL, pool));
+
+          SVN_ERR(reporter->finish_report(report_baton, pool));
+        }
+      else if (kind == svn_node_none)
+        {
+          return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
+                                   _("URL '%s' doesn't exist"),
+                                   from_path_or_url);
+        }
+      /* kind == svn_node_unknown not handled */
+    }
+
+
+  if (result_rev)
+    *result_rev = edit_revision;
+
+  return SVN_NO_ERROR;
+}
+
+
+/*** Code. ***/
+
+/* This implements the `svn_opt_subcommand_t' interface. */
+svn_error_t *
+svn_cl__null_export(apr_getopt_t *os,
+                    void *baton,
+                    apr_pool_t *pool)
+{
+  svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
+  svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
+  const char *from, *to;
+  apr_array_header_t *targets;
+  svn_error_t *err;
+  svn_opt_revision_t peg_revision;
+  const char *truefrom;
+  edit_baton_t eb = { 0 };
+
+  SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
+                                                      opt_state->targets,
+                                                      ctx, FALSE, pool));
+
+  /* We want exactly 1 or 2 targets for this subcommand. */
+  if (targets->nelts < 1)
+    return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL);
+  if (targets->nelts > 2)
+    return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0, NULL);
+
+  /* The first target is the `from' path. */
+  from = APR_ARRAY_IDX(targets, 0, const char *);
+
+  /* Get the peg revision if present. */
+  SVN_ERR(svn_opt_parse_path(&peg_revision, &truefrom, from, pool));
+
+  /* If only one target was given, split off the basename to use as
+     the `to' path.  Else, a `to' path was supplied. */
+  if (targets->nelts == 1)
+    {
+      to = svn_path_uri_decode(svn_uri_basename(truefrom, pool), pool);
+    }
+  else
+    {
+      to = APR_ARRAY_IDX(targets, 1, const char *);
+
+      /* If given the cwd, pretend we weren't given anything. */
+      if (strcmp("", to) == 0)
+        to = svn_path_uri_decode(svn_uri_basename(truefrom, pool), pool);
+    }
+
+  if (opt_state->depth == svn_depth_unknown)
+    opt_state->depth = svn_depth_infinity;
+
+  /* Do the export. */
+  err = bench_null_export(NULL, truefrom, &peg_revision,
+                          &(opt_state->start_revision),
+                          opt_state->depth,
+                          &eb,
+                          ctx, pool);
+
+  if (!opt_state->quiet)
+    SVN_ERR(svn_cmdline_printf(pool,
+                               _("%15ld directories\n"
+                                 "%15ld files\n"
+                                 "%15ld bytes in files\n"
+                                 "%15ld properties\n"
+                                 "%15ld bytes in properties\n"),
+                               eb.dir_count,
+                               eb.file_count,
+                               eb.byte_count,
+                               eb.prop_count,
+                               eb.prop_byte_count));
+
+  return svn_error_trace(err);
+}

Added: subversion/branches/10Gb/tools/client-side/svn-bench/null-list-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/10Gb/tools/client-side/svn-bench/null-list-cmd.c?rev=1389662&view=auto
==============================================================================
--- subversion/branches/10Gb/tools/client-side/svn-bench/null-list-cmd.c (added)
+++ subversion/branches/10Gb/tools/client-side/svn-bench/null-list-cmd.c Tue Sep 25 00:16:36 2012
@@ -0,0 +1,161 @@
+/*
+ * list-cmd.c -- list a URL
+ *
+ * ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one
+ *    or more contributor license agreements.  See the NOTICE file
+ *    distributed with this work for additional information
+ *    regarding copyright ownership.  The ASF licenses this file
+ *    to you under the Apache License, Version 2.0 (the
+ *    "License"); you may not use this file except in compliance
+ *    with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing,
+ *    software distributed under the License is distributed on an
+ *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *    KIND, either express or implied.  See the License for the
+ *    specific language governing permissions and limitations
+ *    under the License.
+ * ====================================================================
+ */
+
+#include "svn_cmdline.h"
+#include "svn_client.h"
+#include "svn_error.h"
+#include "svn_pools.h"
+#include "svn_time.h"
+#include "svn_xml.h"
+#include "svn_dirent_uri.h"
+#include "svn_path.h"
+#include "svn_utf.h"
+#include "svn_opt.h"
+
+#include "cl.h"
+
+#include "svn_private_config.h"
+
+
+
+/* Baton used when printing directory entries. */
+struct print_baton {
+  svn_boolean_t verbose;
+  apr_int64_t directories;
+  apr_int64_t files;
+  apr_int64_t locks;
+  svn_client_ctx_t *ctx;
+};
+
+/* This implements the svn_client_list_func_t API, printing a single
+   directory entry in text format. */
+static svn_error_t *
+print_dirent(void *baton,
+             const char *path,
+             const svn_dirent_t *dirent,
+             const svn_lock_t *lock,
+             const char *abs_path,
+             apr_pool_t *pool)
+{
+  struct print_baton *pb = baton;
+
+  if (pb->ctx->cancel_func)
+    SVN_ERR(pb->ctx->cancel_func(pb->ctx->cancel_baton));
+
+  if (dirent->kind == svn_node_dir)
+    pb->directories++;
+  if (dirent->kind == svn_node_file)
+    pb->files++;
+  if (lock)
+    pb->locks++;
+
+  return SVN_NO_ERROR;
+}
+
+
+/* This implements the `svn_opt_subcommand_t' interface. */
+svn_error_t *
+svn_cl__null_list(apr_getopt_t *os,
+                  void *baton,
+                  apr_pool_t *pool)
+{
+  svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
+  svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
+  apr_array_header_t *targets;
+  int i;
+  apr_pool_t *subpool = svn_pool_create(pool);
+  apr_uint32_t dirent_fields;
+  struct print_baton pb = { FALSE };
+  svn_boolean_t seen_nonexistent_target = FALSE;
+  svn_error_t *err;
+
+  SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
+                                                      opt_state->targets,
+                                                      ctx, FALSE, pool));
+
+  /* Add "." if user passed 0 arguments */
+  svn_opt_push_implicit_dot_target(targets, pool);
+
+  if (opt_state->verbose)
+    dirent_fields = SVN_DIRENT_ALL;
+  else
+    dirent_fields = SVN_DIRENT_KIND; /* the only thing we actually need... */
+
+  pb.ctx = ctx;
+  pb.verbose = opt_state->verbose;
+
+  if (opt_state->depth == svn_depth_unknown)
+    opt_state->depth = svn_depth_immediates;
+
+  /* For each target, try to list it. */
+  for (i = 0; i < targets->nelts; i++)
+    {
+      const char *target = APR_ARRAY_IDX(targets, i, const char *);
+      const char *truepath;
+      svn_opt_revision_t peg_revision;
+
+      svn_pool_clear(subpool);
+
+      SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));
+
+      /* Get peg revisions. */
+      SVN_ERR(svn_opt_parse_path(&peg_revision, &truepath, target,
+                                 subpool));
+
+      err = svn_client_list2(truepath, &peg_revision,
+                             &(opt_state->start_revision),
+                             opt_state->depth,
+                             dirent_fields,
+                             opt_state->verbose,
+                             print_dirent,
+                             &pb, ctx, subpool);
+
+      if (err)
+        {
+          /* If one of the targets is a non-existent URL or wc-entry,
+             don't bail out.  Just warn and move on to the next target. */
+          if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND ||
+              err->apr_err == SVN_ERR_FS_NOT_FOUND)
+              svn_handle_warning2(stderr, err, "svn-bench: ");
+          else
+              return svn_error_trace(err);
+
+          svn_error_clear(err);
+          err = NULL;
+          seen_nonexistent_target = TRUE;
+        }
+      else if (!opt_state->quiet)
+        SVN_ERR(svn_cmdline_printf(pool,
+                               _("%15ld directories\n%15ld files\n%15ld locks\n"),
+                               pb.directories, pb.files, pb.locks));
+    }
+
+  svn_pool_destroy(subpool);
+
+  if (seen_nonexistent_target)
+    return svn_error_create(
+      SVN_ERR_ILLEGAL_TARGET, NULL,
+      _("Could not list all targets because some targets don't exist"));
+  else
+    return SVN_NO_ERROR;
+}

Added: subversion/branches/10Gb/tools/client-side/svn-bench/null-log-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/10Gb/tools/client-side/svn-bench/null-log-cmd.c?rev=1389662&view=auto
==============================================================================
--- subversion/branches/10Gb/tools/client-side/svn-bench/null-log-cmd.c (added)
+++ subversion/branches/10Gb/tools/client-side/svn-bench/null-log-cmd.c Tue Sep 25 00:16:36 2012
@@ -0,0 +1,224 @@
+/*
+ * log-cmd.c -- Display log messages
+ *
+ * ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one
+ *    or more contributor license agreements.  See the NOTICE file
+ *    distributed with this work for additional information
+ *    regarding copyright ownership.  The ASF licenses this file
+ *    to you under the Apache License, Version 2.0 (the
+ *    "License"); you may not use this file except in compliance
+ *    with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing,
+ *    software distributed under the License is distributed on an
+ *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *    KIND, either express or implied.  See the License for the
+ *    specific language governing permissions and limitations
+ *    under the License.
+ * ====================================================================
+ */
+
+#define APR_WANT_STRFUNC
+#define APR_WANT_STDIO
+#include <apr_want.h>
+
+#include "svn_cmdline.h"
+#include "svn_compat.h"
+#include "svn_path.h"
+#include "svn_props.h"
+
+#include "cl.h"
+
+#include "svn_private_config.h"
+
+
+/*** Code. ***/
+
+/* Baton for log_entry_receiver() and log_entry_receiver_xml(). */
+struct log_receiver_baton
+{
+  /* Client context. */
+  svn_client_ctx_t *ctx;
+
+  /* Level of merge revision nesting */
+  apr_size_t merge_depth;
+
+  /* collect counters? */
+  svn_boolean_t quiet;
+
+  /* total revision counters */
+  apr_int64_t revisions;
+  apr_int64_t changes;
+  apr_int64_t message_lines;
+
+  /* part that came from merges */
+  apr_int64_t merges;
+  apr_int64_t merged_revs;
+  apr_int64_t merged_changes;
+  apr_int64_t merged_message_lines;
+};
+
+
+/* Implement `svn_log_entry_receiver_t', printing the logs in
+ * a human-readable and machine-parseable format.
+ *
+ * BATON is of type `struct log_receiver_baton'.
+ */
+static svn_error_t *
+log_entry_receiver(void *baton,
+                   svn_log_entry_t *log_entry,
+                   apr_pool_t *pool)
+{
+  struct log_receiver_baton *lb = baton;
+  const char *author;
+  const char *date;
+  const char *message;
+
+  if (lb->ctx->cancel_func)
+    SVN_ERR(lb->ctx->cancel_func(lb->ctx->cancel_baton));
+
+  if (! SVN_IS_VALID_REVNUM(log_entry->revision))
+    {
+      lb->merge_depth--;
+      return SVN_NO_ERROR;
+    }
+
+  /* if we don't want counters, we are done */
+  if (lb->quiet)
+    return SVN_NO_ERROR;
+
+  /* extract the message and do all the other counting */
+  svn_compat_log_revprops_out(&author, &date, &message, log_entry->revprops);
+  if (log_entry->revision == 0 && message == NULL)
+    return SVN_NO_ERROR;
+  
+  lb->revisions++;
+  if (lb->merge_depth)
+    lb->merged_revs++;
+
+  if (message != NULL)
+    {
+      lb->message_lines += svn_cstring_count_newlines(message) + 1;
+      if (lb->merge_depth)
+        lb->merged_message_lines++;
+    }
+
+  if (log_entry->changed_paths2)
+    {
+      lb->changes += apr_hash_count(log_entry->changed_paths2);
+      if (lb->merge_depth)
+        lb->merged_changes++;
+    }
+
+  if (log_entry->has_children)
+    {
+      lb->merge_depth++;
+      lb->merges++;
+    }
+
+  return SVN_NO_ERROR;
+}
+
+/* This implements the `svn_opt_subcommand_t' interface. */
+svn_error_t *
+svn_cl__null_log(apr_getopt_t *os,
+                 void *baton,
+                 apr_pool_t *pool)
+{
+  svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state;
+  svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx;
+  apr_array_header_t *targets;
+  struct log_receiver_baton lb = { ctx };
+  const char *target;
+  int i;
+  apr_array_header_t *revprops;
+  svn_opt_revision_t target_peg_revision;
+  const char *target_path_or_url;
+
+  SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
+                                                      opt_state->targets,
+                                                      ctx, FALSE, pool));
+
+  /* Add "." if user passed 0 arguments */
+  svn_opt_push_implicit_dot_target(targets, pool);
+
+  /* Determine if they really want a two-revision range. */
+  if (opt_state->used_change_arg)
+    {
+      if (opt_state->used_revision_arg && opt_state->revision_ranges->nelts > 1)
+        {
+          return svn_error_create
+            (SVN_ERR_CLIENT_BAD_REVISION, NULL,
+             _("-c and -r are mutually exclusive"));
+        }
+      for (i = 0; i < opt_state->revision_ranges->nelts; i++)
+        {
+          svn_opt_revision_range_t *range;
+          range = APR_ARRAY_IDX(opt_state->revision_ranges, i,
+                                svn_opt_revision_range_t *);
+          if (range->start.value.number < range->end.value.number)
+            range->start.value.number++;
+          else
+            range->end.value.number++;
+        }
+    }
+
+  /* Parse the first target into path-or-url and peg revision. */
+  target = APR_ARRAY_IDX(targets, 0, const char *);
+  SVN_ERR(svn_opt_parse_path(&target_peg_revision, &target_path_or_url,
+                             target, pool));
+  if (target_peg_revision.kind == svn_opt_revision_unspecified)
+    target_peg_revision.kind = (svn_path_is_url(target)
+                                     ? svn_opt_revision_head
+                                     : svn_opt_revision_working);
+  APR_ARRAY_IDX(targets, 0, const char *) = target_path_or_url;
+
+  if (svn_path_is_url(target))
+    {
+      for (i = 1; i < targets->nelts; i++)
+        {
+          target = APR_ARRAY_IDX(targets, i, const char *);
+
+          if (svn_path_is_url(target) || target[0] == '/')
+            return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                     _("Only relative paths can be specified"
+                                       " after a URL for 'svn-bench log', "
+                                       "but '%s' is not a relative path"),
+                                     target);
+        }
+    }
+
+  lb.quiet = opt_state->quiet;
+
+  revprops = apr_array_make(pool, 3, sizeof(char *));
+  APR_ARRAY_PUSH(revprops, const char *) = SVN_PROP_REVISION_AUTHOR;
+  APR_ARRAY_PUSH(revprops, const char *) = SVN_PROP_REVISION_DATE;
+  if (!opt_state->quiet)
+    APR_ARRAY_PUSH(revprops, const char *) = SVN_PROP_REVISION_LOG;
+  SVN_ERR(svn_client_log5(targets,
+                          &target_peg_revision,
+                          opt_state->revision_ranges,
+                          opt_state->limit,
+                          opt_state->verbose,
+                          opt_state->stop_on_copy,
+                          opt_state->use_merge_history,
+                          revprops,
+                          log_entry_receiver,
+                          &lb,
+                          ctx,
+                          pool));
+
+  if (!opt_state->quiet)
+    SVN_ERR(svn_cmdline_printf(pool,
+                               _("%15ld revisions, %15ld merged in %ld merges\n"
+                                 "%15ld msg lines, %15ld in merged revision\n"
+                                 "%15ld changes,   %15ld in merged revision\n"),
+                               lb.revisions, lb.merged_revs, lb.merges,
+                               lb.message_lines, lb.merged_message_lines,
+                               lb.changes, lb.merged_changes));
+
+  return SVN_NO_ERROR;
+}

Added: subversion/branches/10Gb/tools/client-side/svn-bench/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/10Gb/tools/client-side/svn-bench/util.c?rev=1389662&view=auto
==============================================================================
--- subversion/branches/10Gb/tools/client-side/svn-bench/util.c (added)
+++ subversion/branches/10Gb/tools/client-side/svn-bench/util.c Tue Sep 25 00:16:36 2012
@@ -0,0 +1,92 @@
+/*
+ * util.c: Subversion command line client utility functions. Any
+ * functions that need to be shared across subcommands should be put
+ * in here.
+ *
+ * ====================================================================
+ *    Licensed to the Apache Software Foundation (ASF) under one
+ *    or more contributor license agreements.  See the NOTICE file
+ *    distributed with this work for additional information
+ *    regarding copyright ownership.  The ASF licenses this file
+ *    to you under the Apache License, Version 2.0 (the
+ *    "License"); you may not use this file except in compliance
+ *    with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing,
+ *    software distributed under the License is distributed on an
+ *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *    KIND, either express or implied.  See the License for the
+ *    specific language governing permissions and limitations
+ *    under the License.
+ * ====================================================================
+ */
+
+/* ==================================================================== */
+
+
+
+/*** Includes. ***/
+
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include "svn_private_config.h"
+#include "svn_error.h"
+#include "svn_path.h"
+
+#include "cl.h"
+
+
+
+svn_error_t *
+svn_cl__args_to_target_array_print_reserved(apr_array_header_t **targets,
+                                            apr_getopt_t *os,
+                                            const apr_array_header_t *known_targets,
+                                            svn_client_ctx_t *ctx,
+                                            svn_boolean_t keep_last_origpath_on_truepath_collision,
+                                            apr_pool_t *pool)
+{
+  svn_error_t *err = svn_client_args_to_target_array2(targets,
+                                                      os,
+                                                      known_targets,
+                                                      ctx,
+                                                      keep_last_origpath_on_truepath_collision,
+                                                      pool);
+  if (err)
+    {
+      if (err->apr_err ==  SVN_ERR_RESERVED_FILENAME_SPECIFIED)
+        {
+          svn_handle_error2(err, stderr, FALSE, "svn: Skipping argument: ");
+          svn_error_clear(err);
+        }
+      else
+        return svn_error_trace(err);
+    }
+  return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_cl__check_target_is_local_path(const char *target)
+{
+  if (svn_path_is_url(target))
+    return svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                             _("'%s' is not a local path"), target);
+  return SVN_NO_ERROR;
+}
+
+const char *
+svn_cl__local_style_skip_ancestor(const char *parent_path,
+                                  const char *path,
+                                  apr_pool_t *pool)
+{
+  const char *relpath = NULL;
+
+  if (parent_path)
+    relpath = svn_dirent_skip_ancestor(parent_path, path);
+
+  return svn_dirent_local_style(relpath ? relpath : path, pool);
+}
+