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 2013/10/15 10:52:18 UTC

svn commit: r1532250 [4/37] - in /subversion/branches/cache-server: ./ build/ build/ac-macros/ build/generator/ build/generator/swig/ build/generator/templates/ contrib/client-side/emacs/ contrib/hook-scripts/ contrib/server-side/fsfsfixer/ contrib/ser...

Modified: subversion/branches/cache-server/contrib/hook-scripts/check-mime-type.pl
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/contrib/hook-scripts/check-mime-type.pl?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/contrib/hook-scripts/check-mime-type.pl (original)
+++ subversion/branches/cache-server/contrib/hook-scripts/check-mime-type.pl Tue Oct 15 08:52:06 2013
@@ -120,7 +120,7 @@ foreach my $path ( @files_added )
 		# Parse the complete list of property values of the file $path to extract
 		# the mime-type and eol-style
 		foreach my $prop (&read_from_process($svnlook, 'proplist', $repos, '-t',
-		                  $txn, '--verbose', $path))
+		                  $txn, '--verbose', '--', $path))
 			{
 				if ($prop =~ /^\s*svn:mime-type : (\S+)/)
 					{
@@ -187,7 +187,7 @@ sub safe_read_from_pipe
       croak "$0: safe_read_from_pipe passed no arguments.\n";
     }
   print "Running @_\n";
-  my $pid = open(SAFE_READ, '-|');
+  my $pid = open(SAFE_READ, '-|', @_);
   unless (defined $pid)
     {
       die "$0: cannot fork: $!\n";

Modified: subversion/branches/cache-server/contrib/hook-scripts/svn-keyword-check.pl
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/contrib/hook-scripts/svn-keyword-check.pl?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/contrib/hook-scripts/svn-keyword-check.pl (original)
+++ subversion/branches/cache-server/contrib/hook-scripts/svn-keyword-check.pl Tue Oct 15 08:52:06 2013
@@ -141,7 +141,7 @@ sub check {
                 return 1;
             } else {
                 my @keywords = get_svnkeywords($file);
-                my $fh = _pipe("$svnlook cat $flag $value $repos $file");
+                my $fh = _pipe($svnlook, qw/cat/, $flag, $value, $repos, '--', $file);
                 while (my $line = <$fh>) {
                     foreach my $keyword (@keywords) {
                         if ($line =~ m/$keyword/) {
@@ -168,7 +168,7 @@ sub file_is_binary {
         return 0;
     }
     if (has_svn_property($file, "svn:mime-type")) {
-        my ($mimetype) = read_from_process("$svnlook propget $flag $value $repos svn:mime-type $file");
+        my ($mimetype) = read_from_process($svnlook, qw/propget/, $flag, $value, $repos, 'svn:mime-type', '--', $file);
         chomp($mimetype);
         $mimetype =~ s/^\s*(.*)/$1/;
         if ($mimetype =~ m/^text\//) {
@@ -186,7 +186,7 @@ sub file_is_binary {
 # Return a list of svn:keywords on a file
 sub get_svnkeywords {
     my $file = shift;
-    my @lines = read_from_process("$svnlook propget $flag $value $repos svn:keywords $file");
+    my @lines = read_from_process($svnlook, qw/propget/, $flag, $value, $repos, 'svn:keywords', '--', $file);
     my @returnlines;
     foreach my $line (@lines) {
         $line =~ s/\s+/ /;
@@ -199,7 +199,7 @@ sub get_svnkeywords {
 sub has_svn_property {
     my $file = shift;
     my $keyword = shift;
-    my @proplist = read_from_process("$svnlook proplist $flag $value $repos $file");
+    my @proplist = read_from_process($svnlook, qw/proplist/, $flag, $value, $repos, '--', $file);
     foreach my $prop (@proplist) {
         chomp($prop);
         if ($prop =~ m/\b$keyword\b/) {
@@ -241,7 +241,7 @@ sub safe_read_from_pipe {
 # Return the filehandle as a glob so we can loop over it elsewhere.
 sub _pipe {
     local *SAFE_READ;
-    my $pid = open(SAFE_READ, '-|');
+    my $pid = open(SAFE_READ, '-|', @_);
     unless (defined $pid) {
         die "$0: cannot fork: $!\n";
     }

Modified: subversion/branches/cache-server/contrib/server-side/fsfsfixer/fix-repo
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/contrib/server-side/fsfsfixer/fix-repo?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/contrib/server-side/fsfsfixer/fix-repo (original)
+++ subversion/branches/cache-server/contrib/server-side/fsfsfixer/fix-repo Tue Oct 15 08:52:06 2013
@@ -1,6 +1,6 @@
 #!/bin/sh
-USAGE="Fix some kinds of corruption in a Subversion repository
-by running './fixer/fix-rev.py' on each revision.
+USAGE="Fix some kinds of corruption in a Subversion FSFS repository.
+This script runs './fixer/fix-rev.py' on each revision.
 Usage: $0 REPO-DIR START-REV
 
 Backup your repository before running these scripts."

Modified: subversion/branches/cache-server/contrib/server-side/fsfsfixer/fixer/find_good_id.py
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/contrib/server-side/fsfsfixer/fixer/find_good_id.py?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/contrib/server-side/fsfsfixer/fixer/find_good_id.py (original)
+++ subversion/branches/cache-server/contrib/server-side/fsfsfixer/fixer/find_good_id.py Tue Oct 15 08:52:06 2013
@@ -1,12 +1,5 @@
 #!/usr/bin/env python
 
-# PER-REPOSITORY CONFIGURATION
-#
-# The number of revs per shard of the repository being accessed, or None if
-# it is not sharded.
-# TODO: Read this from the db/format file.
-REVS_PER_SHARD=None
-
 usage = """
 Print the correct FSFS node-rev id, given one that is correct except for
 its byte-offset part.
@@ -21,6 +14,7 @@ Example:
 """
 
 import os, sys
+from fixer_config import *
 
 class FixError(Exception):
   """An exception for any kind of inablility to repair the repository."""

Modified: subversion/branches/cache-server/contrib/server-side/fsfsfixer/fixer/fix-rev.py
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/contrib/server-side/fsfsfixer/fixer/fix-rev.py?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/contrib/server-side/fsfsfixer/fixer/fix-rev.py (original)
+++ subversion/branches/cache-server/contrib/server-side/fsfsfixer/fixer/fix-rev.py Tue Oct 15 08:52:06 2013
@@ -210,7 +210,7 @@ def fix_one_error(repo_dir, rev):
     if handle_one_error(repo_dir, rev, svnlook_err):
       return True
 
-  raise FixError("unfixable error:\n  " + "\n  ".join(svnadmin_err))
+  raise FixError("unrecognized error message, and so unable to fix:\n  " + "\n  ".join(svnadmin_err))
 
 def check_formats(repo_dir):
   """Check that REPO_DIR isn't newer than we know how to handle."""

Modified: subversion/branches/cache-server/contrib/server-side/fsfsfixer/fixer/fixer_config.py
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/contrib/server-side/fsfsfixer/fixer/fixer_config.py?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/contrib/server-side/fsfsfixer/fixer/fixer_config.py (original)
+++ subversion/branches/cache-server/contrib/server-side/fsfsfixer/fixer/fixer_config.py Tue Oct 15 08:52:06 2013
@@ -8,3 +8,17 @@ SVNLOOK = 'svnlook'
 
 # Verbosity: True for verbose, or False for quiet
 VERBOSE = True
+
+# PER-REPOSITORY CONFIGURATION
+
+# The number of revs per shard of the repository being accessed, or 'None'
+# for a linear (that is, non-sharded) layout.  This is 1000 for almost all
+# repositories in practice.
+#
+# The correct value can be found in the 'db/format' file in the repository.
+# The second line of that file will say something like 'layout sharded 1000'
+# or 'layout linear'.
+#
+# TODO: Read this value automatically from the db/format file.
+REVS_PER_SHARD=1000
+

Modified: subversion/branches/cache-server/gen-make.py
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/gen-make.py?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/gen-make.py (original)
+++ subversion/branches/cache-server/gen-make.py Tue Oct 15 08:52:06 2013
@@ -214,6 +214,8 @@ def _usage_exit(err=None):
   print("")
   print("  --with-apr_memcache=DIR")
   print("           the apr_memcache sources are in DIR")
+  print("  --disable-gmock")
+  print("           do not use Googlemock")
   sys.exit(1)
 
 
@@ -222,9 +224,10 @@ class Options:
     self.list = []
     self.dict = {}
 
-  def add(self, opt, val):
+  def add(self, opt, val, overwrite=True):
     if opt in self.dict:
-      self.list[self.dict[opt]] = (opt, val)
+      if overwrite:
+        self.list[self.dict[opt]] = (opt, val)
     else:
       self.dict[opt] = len(self.list)
       self.list.append((opt, val))
@@ -262,7 +265,7 @@ if __name__ == '__main__':
                             'disable-shared',
                             'installed-libs=',
                             'vsnet-version=',
-
+                            'disable-gmock',
                             # Keep distributions that help by adding a path
                             # working. On unix this would be filtered by
                             # configure, but on Windows gen-make.py is used
@@ -307,9 +310,12 @@ if __name__ == '__main__':
       gentype = val
     else:
       if opt == '--with-httpd':
-        rest.add('--with-apr', os.path.join(val, 'srclib', 'apr'))
-        rest.add('--with-apr-util', os.path.join(val, 'srclib', 'apr-util'))
-        rest.add('--with-apr-iconv', os.path.join(val, 'srclib', 'apr-iconv'))
+        rest.add('--with-apr', os.path.join(val, 'srclib', 'apr'),
+                 overwrite=False)
+        rest.add('--with-apr-util', os.path.join(val, 'srclib', 'apr-util'),
+                 overwrite=False)
+        rest.add('--with-apr-iconv', os.path.join(val, 'srclib', 'apr-iconv'),
+                 overwrite=False)
 
   # Remember all options so that --reload and other scripts can use them
   opt_conf = open('gen-make.opts', 'w')

Modified: subversion/branches/cache-server/get-deps.sh
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/get-deps.sh?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/get-deps.sh (original)
+++ subversion/branches/cache-server/get-deps.sh Tue Oct 15 08:52:06 2013
@@ -23,19 +23,34 @@
 # get-deps.sh -- download the dependencies useful for building Subversion
 #
 
-APR=apr-1.4.6
-APR_UTIL=apr-util-1.5.1
-SERF=serf-1.2.0
-ZLIB=zlib-1.2.7
-SQLITE_VERSION=3.7.15.1
+# If changing this file please take care to try to make your changes as
+# portable as possible.  That means at a minimum only use POSIX supported
+# features and functions.  However, it may be desirable to use an even
+# more narrow set of features than POSIX, e.g. Solaris /bin/sh only has
+# a subset of the POSIX shell features.  If in doubt, limit yourself to
+# features already used in the file.  Reviewing the history of changes
+# may be useful as well.
+
+APR_VERSION=${APR_VERSION:-"1.4.6"}
+APU_VERSION=${APU_VERSION:-"1.5.1"}
+SERF_VERSION=${SERF_VERSION:-"1.2.1"}
+ZLIB_VERSION=${ZLIB_VERSION:-"1.2.8"}
+SQLITE_VERSION=${SQLITE_VERSION:-"3.7.15.1"}
+GMOCK_VERSION=${GMOCK_VERSION:-"1.6.0"}
+HTTPD_VERSION=${HTTPD_VERSION:-"2.4.6"}
+APR_ICONV_VERSION=${APR_ICONV_VERSION:-"1.2.1"}
+
+APR=apr-${APR_VERSION}
+APR_UTIL=apr-util-${APU_VERSION}
+SERF=serf-${SERF_VERSION}
+ZLIB=zlib-${ZLIB_VERSION}
 SQLITE_VERSION_LIST=`echo $SQLITE_VERSION | sed -e 's/\./ /g'`
 SQLITE=sqlite-amalgamation-`printf %d%02d%02d%02d $SQLITE_VERSION_LIST`
-GTEST_VERSION=1.6.0
-GTEST=gtest-${GTEST_VERSION}
-GTEST_URL=http://googletest.googlecode.com/files/
+GMOCK=gmock-${GMOCK_VERSION}
+GMOCK_URL=https://googlemock.googlecode.com/files/
 
-HTTPD=httpd-2.4.3
-APR_ICONV=apr-iconv-1.2.1
+HTTPD=httpd-${HTTPD_VERSION}
+APR_ICONV=apr-iconv-${APR_ICONV_VERSION}
 
 BASEDIR=`pwd`
 TEMPDIR=$BASEDIR/temp
@@ -52,7 +67,7 @@ APACHE_MIRROR=http://archive.apache.org/
 # helpers
 usage() {
     echo "Usage: $0"
-    echo "Usage: $0 [ apr | serf | zlib | sqlite | gtest ] ..."
+    echo "Usage: $0 [ apr | serf | zlib | sqlite | gmock ] ..."
     exit $1
 }
 
@@ -86,10 +101,10 @@ get_zlib() {
     test -d $BASEDIR/zlib && return
 
     cd $TEMPDIR
-    $HTTP_FETCH http://www.zlib.net/$ZLIB.tar.bz2
+    $HTTP_FETCH http://www.zlib.net/$ZLIB.tar.gz
     cd $BASEDIR
 
-    bzip2 -dc $TEMPDIR/$ZLIB.tar.bz2 | tar -xf -
+    gzip -dc $TEMPDIR/$ZLIB.tar.gz | tar -xf -
 
     mv $ZLIB zlib
 }
@@ -107,23 +122,24 @@ get_sqlite() {
 
 }
 
-get_gtest() {
-    test -d $BASEDIR/gtest && return
+get_gmock() {
+    test -d $BASEDIR/gmock-fused && return
 
     cd $TEMPDIR
-    $HTTP_FETCH ${GTEST_URL}/${GTEST}.zip
+    $HTTP_FETCH ${GMOCK_URL}/${GMOCK}.zip
     cd $BASEDIR
 
-    unzip -q $TEMPDIR/$GTEST.zip
+    unzip -q $TEMPDIR/$GMOCK.zip
 
-    mv $GTEST gtest
+    mv $GMOCK/fused-src gmock-fused
+    rm -fr $GMOCK
 }
 
 # main()
 get_deps() {
     mkdir -p $TEMPDIR
 
-    for i in zlib serf sqlite-amalgamation apr apr-util gtest; do
+    for i in zlib serf sqlite-amalgamation apr apr-util gmock-fused; do
       if [ -d $i ]; then
         echo "Local directory '$i' already exists; the downloaded copy won't be used" >&2
       fi

Propchange: subversion/branches/cache-server/get-deps.sh
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: subversion/branches/cache-server/notes/dump-load-format.txt
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/notes/dump-load-format.txt?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/notes/dump-load-format.txt (original)
+++ subversion/branches/cache-server/notes/dump-load-format.txt Tue Oct 15 08:52:06 2013
@@ -215,7 +215,7 @@ is the payload of program source code, d
 that a version control system actually manages.
 
 A Node record describes a change in properties, the addition or deletion
-of a flow, or a change in content.  It nust do at least one of these things,
+of a flow, or a change in content.  It must do at least one of these things,
 otherwise it would be a no-op and omitted.
 
 When no copyfrom is present, and the action isn't an add or copy, then
@@ -341,7 +341,7 @@ to the same directory. 
 
 The properties section of a Revision record consists of some subset
 of the three reserved per-commit properties: svn:author, svn:date,
-and svn.log. These properties do not persist to later revisions.
+and svn:log. These properties do not persist to later revisions.
 
 The key thing to know about Node properties is that they are 
 persistent, once set, until modified by a future property 
@@ -485,8 +485,10 @@ that (1) properties with the same value 
 the flow are not printed, and (2) deleted properties will be written
 out as
 
+-------------------------------------------------------------------
 D <name length>
 <name>
+-------------------------------------------------------------------
 
 just as a regular property is printed, but with the "K " changed to a
 "D " and with no value part.

Modified: subversion/branches/cache-server/notes/ev2-callbacks-template.c
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/notes/ev2-callbacks-template.c?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/notes/ev2-callbacks-template.c (original)
+++ subversion/branches/cache-server/notes/ev2-callbacks-template.c Tue Oct 15 08:52:06 2013
@@ -155,19 +155,6 @@ move_cb(void *baton,
 }
 
 
-/* This implements svn_editor_cb_rotate_t */
-static svn_error_t *
-rotate_cb(void *baton,
-          const apr_array_header_t *relpaths,
-          const apr_array_header_t *revisions,
-          apr_pool_t *scratch_pool)
-{
-  struct edit_baton *eb = baton;
-
-  UNUSED(eb); SVN__NOT_IMPLEMENTED();
-}
-
-
 /* This implements svn_editor_cb_complete_t */
 static svn_error_t *
 complete_cb(void *baton,
@@ -208,7 +195,6 @@ make_editor(svn_editor_t **editor,
     delete_cb,
     copy_cb,
     move_cb,
-    rotate_cb,
     complete_cb,
     abort_cb
   };

Modified: subversion/branches/cache-server/notes/http-and-webdav/webdav-protocol
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/notes/http-and-webdav/webdav-protocol?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/notes/http-and-webdav/webdav-protocol (original)
+++ subversion/branches/cache-server/notes/http-and-webdav/webdav-protocol Tue Oct 15 08:52:06 2013
@@ -228,7 +228,7 @@ Purpose: Present what we have in our WC 
 Target URL: Base VCC URL
             Example: REPORT /repos/test/!svn/vcc/default
 
-Note: ra_serf will not set the send-all attribute to the update-report.  It
+Note: ra_serf may not set the send-all attribute to the update-report.  It
       will instead take the returned D:checked-in href and do a pipelined
       PROPFIND / GET on that resource.
 

Modified: subversion/branches/cache-server/notes/knobs
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/notes/knobs?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/notes/knobs (original)
+++ subversion/branches/cache-server/notes/knobs Tue Oct 15 08:52:06 2013
@@ -68,6 +68,7 @@ SERF_VERBOSE
 SSL_VERBOSE
 SVN_DEPRECATED
 SVN_FS__TRAIL_DEBUG
+SVN_FS_FS__LOG_ACCESS
 SVN_UTF_NO_UNINITIALISED_ACCESS
 
 2.4 Test-only
@@ -80,6 +81,7 @@ TEST16K_ADD
 
 SVNSYNC_UNSUPPORTED_STRIP_MERGEINFO
 SVNSYNC_UNSUPPORTED_MIGRATE_SVNMERGE
+SVN_CMDLINE_DISABLE_CRASH_HANDLER
 SVN_I_LOVE_CORRUPTED_WORKING_COPIES_SO_DISABLE_RELOCATE_VALIDATION
 SVN_I_LOVE_CORRUPTED_WORKING_COPIES_SO_DISABLE_SLEEP_FOR_TIMESTAMPS
 SVN_I_LOVE_PANGALACTIC_GARGLE_BLASTERS
@@ -395,7 +397,17 @@ SVN_I_LIKE_LATENCY_SO_IGNORE_HTTPV2
   Default:   not defined
   Suggested: defined, not defined
 
-5.14 SVN_UTF_NO_UNINITIALISED_ACCESS
+5.14 SVN_FS_FS__LOG_ACCESS
+  
+  Scope:     libsvn_fs_fs/cached_data.c
+  Purpose:   logs type and location info for any fsfs data access above the
+             cache layer to console (i.e. what data gets requested from FSFS
+             rather than disk)
+  Range:     definedness
+  Default:   not defined
+  Suggested: defined, not defined
+
+5.15 SVN_UTF_NO_UNINITIALISED_ACCESS
 
   Scope:     libsvn_subr
   Purpose:   Disables some code that triggers warnings in memory tools
@@ -448,34 +460,41 @@ SVN_I_LIKE_LATENCY_SO_IGNORE_HTTPV2
   Scope:     
   Purpose:   
 
-7.3 SVN_I_LOVE_CORRUPTED_WORKING_COPIES_SO_DISABLE_RELOCATE_VALIDATION
+7.3. SVN_CMDLINE_DISABLE_CRASH_HANDLER
+
+  Scope:     All command line executables. Windows specific.
+  Purpose:   Setting any value disables internal Subversion crash handler
+             for creating minidump and stack trace information on failure on
+             Windows.
+
+7.4 SVN_I_LOVE_CORRUPTED_WORKING_COPIES_SO_DISABLE_RELOCATE_VALIDATION
 
   Scope:     
   Purpose:   
 
-7.4 SVN_I_LOVE_CORRUPTED_WORKING_COPIES_SO_DISABLE_SLEEP_FOR_TIMESTAMPS
+7.5 SVN_I_LOVE_CORRUPTED_WORKING_COPIES_SO_DISABLE_SLEEP_FOR_TIMESTAMPS
 
   Scope:     
   Purpose:   
 
-7.5 SVN_I_LOVE_PANGALACTIC_GARGLE_BLASTERS
+7.6 SVN_I_LOVE_PANGALACTIC_GARGLE_BLASTERS
 
   Scope:     
   Purpose:   
 
-7.6 SVN_I_LIKE_LATENCY_SO_IGNORE_HTTPV2
+7.7 SVN_I_LIKE_LATENCY_SO_IGNORE_HTTPV2
 
   Scope:     libsvn_ra_neon and libsvn_ra_serf, if SVN_DEBUG
   Purpose:   A "yes" value causes the RA modules to ignore the server's
              advertisement of HTTPv2 protocol support (if any), effectively
              causing them to only speak our original HTTP protocol.
 
-7.7 SVN_SVNMUCC_IS_SVNSYITF
+7.8 SVN_SVNMUCC_IS_SVNSYITF
 
   Scope:     'make install-tools'
   Purpose:   Symlinks $prefix/bin/svnsyitf to $prefix/bin/svnmucc
 
-7.8 SVN_X_DOES_NOT_MARK_THE_SPOT
+7.9 SVN_X_DOES_NOT_MARK_THE_SPOT
 
   Scope:     svn_cache__t subsystem (used by FSFS, svnserve, etc)
   Purpose:   Disable the subsystem.  Requires -D SVN_DEBUG.

Modified: subversion/branches/cache-server/notes/tree-conflicts/use-cases.txt
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/notes/tree-conflicts/use-cases.txt?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/notes/tree-conflicts/use-cases.txt (original)
+++ subversion/branches/cache-server/notes/tree-conflicts/use-cases.txt Tue Oct 15 08:52:06 2013
@@ -4,10 +4,16 @@
 
 
 Issue reference:  http://subversion.tigris.org/issues/show_bug.cgi?id=2282
+                  http://subversion.tigris.org/issues/show_bug.cgi?id=3630
 
-(These use cases are based on a scenario paper "SVN move/rename
+These use cases are based on a scenario paper "SVN move/rename
 problems & suggested improvements" submitted by a corporate Subversion
-user, which may be found attached to issue #2282.)
+user, which may be found attached to issue #2282.
+
+These notes were originally written during development of Subversion 1.6.
+The original version focussed on detection of tree conflicts. The notes
+have since been updated with behaviour changes up to Subversion 1.8.
+Any 'desired behaviour' mentioned here is yet to be implemented.
 
 --------------------------------------------------------------------------
 
@@ -19,7 +25,7 @@ Description
 
    During an update, a file modification is merged onto a file move.
 
-Current Behavior
+Behavior of Subversion <= 1.5
 
    Developer A modifies Foo.c and commits it to the repository.
 
@@ -30,7 +36,7 @@ Current Behavior
    update'. The update will apply A's modifications to Foo.c in the
    repository to Foo.c in B's working copy.
 
-Problems With Current Behavior
+Problems With Behavior of Subversion <= 1.5
 
    First problem:
    
@@ -46,7 +52,7 @@ Problems With Current Behavior
    B's working copy because it has "local" modifications (which were in
    fact made by A). This will likely escape B's attention.
 
-Diagram of current behavior
+Diagram of behavior of Subversion <= 1.5
 
 
               (edit)
@@ -61,18 +67,23 @@ Diagram of current behavior
     wcB          -- +Bar.c ---------- +Bar.c ----  Bar.c --->
              (move) -Foo.c            -Foo.c'     ?Foo.c' (unversioned)
 
+Behaviour of Subversion >= 1.6
 
-Desired behavior
+   Foo.c will be deleted from B's working copy.
 
-   When user B updates, A's modifications to Foo.c should be merged into
-   Bar.c. Signal a text conflict if necessary.
-   
-   Foo.c should be deleted from B's working copy.
+   A tree conflict is signalled to inform B of the new changes to Bar.c,
+   so that B can review the modified Bar.c before committing it.
+
+Behavior of Subversion >= 1.8
    
-   A tree conflict should be signalled to inform B of the new changes
-   to Bar.c, so that B can review the modified Bar.c before committing it.
+   As above, a tree conflict is flagged on Foo.c.
 
-Diagram of desired behaviour
+   When user B resolves the tree conflict on Foo.c, A's modifications
+   to Foo.c will be merged into Bar.c.
+   
+   Text/Prop conflicts are signalled necessary.
+   
+Diagram of Behaviour of Subversion >= 1.8
 
 
               (edit)
@@ -101,7 +112,7 @@ Description
    This is essentially the same as Use Case 1, with the difference that
    this time, B does the edit and A does the move.
 
-Current Behavior
+Behavior of Subversion <= 1.5
 
    Developer B modifies Foo.c in his working copy.
    
@@ -114,7 +125,7 @@ Current Behavior
    B's working copy. Since B made local modifications to Foo.c,
    it will not be deleted from disk but left behind unversioned.
 
-Problems with Current Behavior
+Problems with behavior of Subversion <= 1.5
 
    Developer B may not notice that Foo.c fell out of version control.
    B's source tree in the working copy likely builds fine because Foo.c
@@ -122,7 +133,7 @@ Problems with Current Behavior
    possibly breaking the tree.  Everybody will get angry with B if this
    happens.
 
-Diagram of Current Behaviour
+Diagram of Behaviour of Subversion <= 1.5
 
 
               (move)
@@ -137,6 +148,11 @@ Diagram of Current Behaviour
     wcB          -- Foo.c' ------------  Bar.c  ------->
              (edit)                     ?Foo.c' (unversioned)
 
+Behavior of Subversion >= 1.6
+
+   When B updates, Bar.c is added to B's working copy, and a tree conflict
+   is flagged on Foo.c. B is expected to figure out that A renamed Foo.c
+   to Bar.c, and must resolve the conflict in some way before committing.
 
 Desired Behavior
 
@@ -174,7 +190,7 @@ Description
 
    During an update, a file move is merged onto a conflicting file move.
 
-Current Behavior
+Behavior of Subversion <= 1.5
 
    Developer A moves Foo.c to Bar.c and commits the move to the repository.
    
@@ -184,7 +200,7 @@ Current Behavior
    'svn update'. The update will add Bar.c to B's working copy and
    delete Foo.c from B's working copy (the latter is a no-op).
 
-Problems with Current Behavior
+Problems with behavior of Subversion <= 1.5
 
    After B's next commit, the content of the original Foo.c
    will exist twice in the source tree under two different paths,
@@ -192,7 +208,7 @@ Problems with Current Behavior
    
    This may not have been intended.
 
-Diagram of Current Behavior
+Diagram of behavior of Subversion <= 1.5
 
 
              (move)
@@ -208,12 +224,12 @@ Diagram of Current Behavior
              (move) -Foo.c             Bar.c
 
 
-Desired Behavior
+Behavior of Subversion >= 1.6
 
-   A tree conflict should be signaled to inform B of the conflicting rename
+   A tree conflict is signaled to inform B of the conflicting rename
    operation. B can now decide on deleting either file or committing both.
 
-Diagram of Desired Behavior
+Diagram of behavior of Subversion >= 1.6
 
 
              (move)
@@ -230,6 +246,13 @@ Diagram of Desired Behavior
                                                     |
                                                  resolved
 
+Problems with Behaviour of Subversion >= 1.6
+
+   The incoming move is labeled as 'incoming delete' in the tree
+   conflict description, rather than 'incoming move'. No assistance
+   is provided while resolving the tree conflict. Inexperienced users
+   are often unsure why the conflict occurred and don't know how to
+   proceed.
 
 ==========
 USE CASE 4
@@ -239,7 +262,7 @@ Description
 
    A file modification is merged onto the source of a file move.
 
-Current Behavior
+Behavior of Subversion <= 1.5
 
    Developer A modifies Foo.c and commits it to the repository.
 
@@ -249,7 +272,7 @@ Current Behavior
    will apply A's modification to Foo.c to the Foo.c in B's working
    copy.
 
-Problems With Current Behavior
+Problems With behavior of Subversion <= 1.5
 
    First problem:
    
@@ -262,7 +285,7 @@ Problems With Current Behavior
    except for a "skipped" warning in the output of the merge command,
    which might not be noticed.
 
-Diagram of current behavior
+Diagram of behavior of Subversion <= 1.5
 
 
             (edit)
@@ -279,15 +302,12 @@ Diagram of current behavior
     wcB                      -- Bar.c -- Bar.c ------ -->
 
 
-Desired behavior
+Behavior of Subversion >= 1.6
 
-   When user B merges, A's modifications to Foo.c should be merged into
-   Bar.c. Signal a text conflict if necessary.
-   
-   A tree conflict should be signalled to inform B of the new changes
-   to Bar.c, so that B can review the modified Bar.c before committing it.
+   A tree conflict is signalled to inform B of the new changes to Bar.c,
+   so that B can review the modified Bar.c before committing it.
 
-Diagram of desired behaviour
+Diagram of Behaviour of Subversion >= 1.6
 
 
             (edit)
@@ -306,6 +326,17 @@ Diagram of desired behaviour
                                                          |
                                                       resolved
 
+Problems with Behaviour of Subversion >= 1.6
+
+   No assistance is provided while resolving the tree conflict.
+   Inexperienced users are often unsure why the conflict occurred
+   and don't know how to proceed.
+
+Desired Behaviour
+
+   When user B merges, A's modifications to Foo.c should be merged into
+   Bar.c. Signal a text conflict if necessary.
+   
 
 ==========
 USE CASE 5
@@ -318,7 +349,7 @@ Description
    This is essentially the same as Use Case 4, with the difference that
    this time, B does the edit and A does the move.
 
-Current Behavior
+Behavior of Subversion <= 1.5
 
    Developer A moves Foo.c to Bar.c and commits it to the repository.
 
@@ -328,15 +359,13 @@ Current Behavior
    will add Bar.c (with the same content as the original Foo.c) and
    will delete B's Foo.c.
 
-Problems With Current Behavior
+Problems with behavior of Subversion <= 1.5
 
-   First problem:
-   
    B's has modified Foo.c in the past.  This modification will be lost
    unless B reviews the history of Foo.c and Bar.c at both URLs and
    corrects the problem (e.g., via 'svn copy').
 
-Diagram of current behavior
+Diagram of behavior of Subversion <= 1.5
 
 
             (move)
@@ -354,17 +383,31 @@ Diagram of current behavior
                                           -Foo.c'
 
 
+Behavior Subversion >= 1.6
+
+   A tree conflict is signaled on Foo.c to inform B that Foo.c has been
+   renamed to Bar.c
+
+Problems with Behaviour of Subversion >= 1.6
+
+   The incoming move is labeled as 'incoming delete' in the tree
+   conflict description, rather than 'incoming move'. No assistance
+   is provided while resolving the tree conflict. Inexperienced users
+   are often unsure why the conflict occurred and don't know how to
+   proceed.
+
+Behavior of Subversion <= 1.8
+
+    Same as 1.6, but also for directories instead of just files.
+
 Desired behavior
 
    In B's working copy, the update should add Bar.c and merge the local
    modifications to Foo.c into Bar.c. Signal a text conflict if necessary.
    
    Foo.c should be deleted from B's working copy.
-   
-   A tree conflict should be signaled to inform B that Foo.c has been
-   renamed to Bar.c
 
-Diagram of desired behaviour
+Diagram of Desired Behaviour
 
 
             (move)
@@ -383,7 +426,6 @@ Diagram of desired behaviour
                                                          |
                                                       resolved
 
-
 ==========
 USE CASE 6
 ==========
@@ -392,7 +434,7 @@ Description
 
    A file move is merged onto a conflicting file move.
 
-Current Behavior
+Behavior of Subversion <= 1.5
 
    Developer A moves Foo.c to Bar.c and commits it to the repository.
 
@@ -401,13 +443,13 @@ Current Behavior
    Developer B merges A's new revision into his working copy.  The merge
    will add Bar.c with history in B's working copy.
 
-Problems With Current Behavior
+Problems with behavior of Subversion <= 1.5
 
    After B's next commit, the content of the original Foo.c will exist
    twice in the source tree under two different paths (Bar.c and
    Bix.c).  This may not have been intended.
 
-Diagram of current behavior
+Diagram of Behavior of Subversion <= 1.5
 
 
             (move)
@@ -425,12 +467,24 @@ Diagram of current behavior
                                         +Bar.c
 
 
+Behavior of Subversion <= 1.6
+
+    A tree conflict is flagged on Foo.c in B's working copy.
+
+Problems with Behaviour of Subversion >= 1.6
+
+   The incoming move is labeled as 'incoming delete' in the tree
+   conflict description, rather than 'incoming move'. No assistance
+   is provided while resolving the tree conflict. Inexperienced users
+   are often unsure why the conflict occurred and don't know how to
+   proceed.
+
 Desired behavior
 
    A tree conflict should be signaled to inform B of the conflicting
    rename operation.  B can delete either file or commit both.
 
-Diagram of desired behaviour
+Diagram of Desired Behaviour
 
 
             (move)

Modified: subversion/branches/cache-server/subversion/bindings/ctypes-python/csvn/txn.py
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/bindings/ctypes-python/csvn/txn.py?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/bindings/ctypes-python/csvn/txn.py (original)
+++ subversion/branches/cache-server/subversion/bindings/ctypes-python/csvn/txn.py Tue Oct 15 08:52:06 2013
@@ -90,7 +90,7 @@ class Txn(object):
 
         if kind == svn_node_none:
             if base_rev:
-                message = "'%s' not found in rev %d" % (path, base_rev)
+                message = "'%s' not found in r%d" % (path, base_rev)
             else:
                 message = "'%s' not found" % (path)
             raise SubversionException(SVN_ERR_BAD_URL, message)

Modified: subversion/branches/cache-server/subversion/bindings/ctypes-python/setup.py
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/bindings/ctypes-python/setup.py?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/bindings/ctypes-python/setup.py (original)
+++ subversion/branches/cache-server/subversion/bindings/ctypes-python/setup.py Tue Oct 15 08:52:06 2013
@@ -58,7 +58,7 @@ class clean(_clean):
         if not self.dry_run:
           os.remove(f)
       else:
-        log.warn("'%s' does not exist -- can't clean it", os.path.normpath(f))
+        log.debug("'%s' does not exist -- can't clean it", os.path.normpath(f))
 
     # Run standard clean command
     _clean.run(self)

Modified: subversion/branches/cache-server/subversion/bindings/ctypes-python/test/svntypes.py
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/bindings/ctypes-python/test/svntypes.py?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/bindings/ctypes-python/test/svntypes.py (original)
+++ subversion/branches/cache-server/subversion/bindings/ctypes-python/test/svntypes.py Tue Oct 15 08:52:06 2013
@@ -35,7 +35,8 @@ class SvnDateTestCase(unittest.TestCase)
     def test_as_human_string(self):
         d1 = SvnDate('1999-12-31T23:59:59.000000Z')
         s1 = d1.as_human_string()
-        self.assertEqual(s1[:27], '1999-12-31 23:59:59 +0000 (')
+        self.assertRegexpMatches(s1[:27],
+            r'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [+-]\d{4} \(')
 
 
 class HashTestCase(unittest.TestCase):

Modified: subversion/branches/cache-server/subversion/bindings/cxxhl/include/svncxxhl.hpp
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/bindings/cxxhl/include/svncxxhl.hpp?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/bindings/cxxhl/include/svncxxhl.hpp (original)
+++ subversion/branches/cache-server/subversion/bindings/cxxhl/include/svncxxhl.hpp Tue Oct 15 08:52:06 2013
@@ -32,6 +32,6 @@
 #include "svncxxhl/exception.hpp"
 #include "svncxxhl/tristate.hpp"
 
-namespace svn = ::subversion::cxxhl::version_1_9_dev;
+namespace SVN = ::apache::subversion::cxxhl;
 
 #endif  // SVN_CXXHL_HPP

Modified: subversion/branches/cache-server/subversion/bindings/cxxhl/include/svncxxhl/_compat.hpp
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/bindings/cxxhl/include/svncxxhl/_compat.hpp?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/bindings/cxxhl/include/svncxxhl/_compat.hpp (original)
+++ subversion/branches/cache-server/subversion/bindings/cxxhl/include/svncxxhl/_compat.hpp Tue Oct 15 08:52:06 2013
@@ -28,64 +28,117 @@
 #ifndef SVN_CXXHL_COMPAT_HPP
 #define SVN_CXXHL_COMPAT_HPP
 
-// Configuration test: std::shared_ptr<>
+// Configuration test: std::shared_ptr<> and friends
 // Currently detects: clang++, g++, msvc-2010+
-#ifndef SVN_CXXHL_HAVE_STD_SHARED_PTR
+#ifndef SVN_CXXHL_HAVE_STD_SMART_PTRS
 #  if   (defined(__clang__) && __cplusplus >= 201103L) \
      || (defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__)) \
      || (defined(_MSC_VER) && _MSC_VER >= 1600)
-#    define SVN_CXXHL_HAVE_STD_SHARED_PTR
+#    define SVN_CXXHL_HAVE_STD_SMART_PTRS
 #  endif  // config test: std::shared_ptr<>
-#endif  // SVN_CXXHL_HAVE_STD_SHARED_PTR
+#endif  // SVN_CXXHL_HAVE_STD_SMART_PTRS
 
-// Configuration test: std::tr1::shared_ptr<>
+// Configuration test: std::tr1::shared_ptr<> and friends
 // Currently detects: clang++, g++
-#ifndef SVN_CXXHL_HAVE_STD_SHARED_PTR
-#  ifndef SVN_CXXHL_HAVE_STD_TR1_SHARED_PTR
+#ifndef SVN_CXXHL_HAVE_STD_SMART_PTRS
+#  ifndef SVN_CXXHL_HAVE_STD_TR1_SMART_PTRS
 #    if   defined(__GNUC__) \
        && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 1)
-#      define SVN_CXXHL_HAVE_STD_TR1_SHARED_PTR
+#      define SVN_CXXHL_HAVE_STD_TR1_SMART_PTRS
 #    endif  // config test: std::tr1::shared_ptr<>
-#  endif  // SVN_CXXHL_HAVE_STD_TR1_SHARED_PTR
-#endif  // SVN_CXXHL_HAVE_STD_SHARED_PTR
+#  endif  // SVN_CXXHL_HAVE_STD_TR1_SMART_PTRS
+#endif  // SVN_CXXHL_HAVE_STD_SMART_PTRS
 
 
-#if defined(SVN_CXXHL_HAVE_STD_SHARED_PTR)
+#if defined(SVN_CXXHL_HAVE_STD_SMART_PTRS)
 
 #include <memory>
+namespace apache {
 namespace subversion {
 namespace cxxhl {
 namespace compat {
+using std::weak_ptr;
 using std::shared_ptr;
+using std::enable_shared_from_this;
 } // namespace compat
 } // namespace cxxhl
 } // namespace subversion
+} // namespace apache
 
-#elif defined(SVN_CXXHL_HAVE_STD_TR1_SHARED_PTR)
+#elif defined(SVN_CXXHL_HAVE_STD_TR1_SMART_PTRS)
 
 #include <tr1/memory>
+namespace apache {
 namespace subversion {
 namespace cxxhl {
 namespace compat {
+using std::tr1::weak_ptr;
 using std::tr1::shared_ptr;
+using std::tr1::enable_shared_from_this;
 } // namespace compat
 } // namespace cxxhl
 } // namespace subversion
+} // namespace apache
 
 #else
-// We need shared_ptr<> from somewhere. If we cannot find it in ::std
-// given known compiler characteristics, then try boost as a last
-// resort.
+// We need smart pointers from somewhere. If we cannot find them in
+// ::std given known compiler characteristics, then try Boost as a
+// last resort.
 
+#define SVN_CXXHL_USING_BOOST
 #include <boost/shared_ptr.hpp>
+namespace apache {
 namespace subversion {
 namespace cxxhl {
 namespace compat {
+using boost::weak_ptr;
 using boost::shared_ptr;
+using boost::enable_shared_from_this;
 } // namespace compat
 } // namespace cxxhl
 } // namespace subversion
+} // namespace apache
 
-#endif  // SVN_CXXHL_HAVE_STD_SHARED_PTR
+#endif  // SVN_CXXHL_HAVE_STD_SMART_PTRS
+
+// Configuration test: noncopyable mixin.
+#ifdef SVN_CXXHL_USING_BOOST
+
+#include <boost/noncopyable.hpp>
+namespace apache {
+namespace subversion {
+namespace cxxhl {
+namespace compat {
+using boost::noncopyable;
+} // namespace compat
+} // namespace cxxhl
+} // namespace subversion
+} // namespace apache
+
+#else  // !SVN_CXXHL_USING_BOOST
+
+namespace apache {
+namespace subversion {
+namespace cxxhl {
+namespace compat {
+namespace noncopyable_
+{
+class noncopyable
+{
+protected:
+  noncopyable() {}
+  ~noncopyable() {}
+private:
+  noncopyable(const noncopyable&);
+  noncopyable& operator=(const noncopyable&);
+};
+} // namespace noncopyable_
+typedef noncopyable_::noncopyable noncopyable;
+} // namespace compat
+} // namespace cxxhl
+} // namespace subversion
+} // namespace apache
+
+#endif // SVN_CXXHL_USING_BOOST
 
 #endif  // SVN_CXXHL_COMPAT_HPP

Modified: subversion/branches/cache-server/subversion/bindings/cxxhl/include/svncxxhl/exception.hpp
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/bindings/cxxhl/include/svncxxhl/exception.hpp?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/bindings/cxxhl/include/svncxxhl/exception.hpp (original)
+++ subversion/branches/cache-server/subversion/bindings/cxxhl/include/svncxxhl/exception.hpp Tue Oct 15 08:52:06 2013
@@ -35,9 +35,7 @@
 
 #include "svncxxhl/_compat.hpp"
 
-// Forward declaration of implementation-specific structure
-struct svn_error_t;
-
+namespace apache {
 namespace subversion {
 namespace cxxhl {
 
@@ -45,56 +43,109 @@ namespace compat {} // Announce the comp
 
 namespace detail {
 // Forward declaration of implementation-specific structure
-class error_description;
+class ErrorDescription;
 } // namespace detail
 
-namespace version_1_9_dev {
-
-class error : public std::exception
+/**
+ * Exceptions generated by the C++HL implementation.
+ */
+class InternalError : public std::exception
 {
 public:
-  typedef compat::shared_ptr<error> shared_ptr;
+  explicit InternalError(const char* description);
 
-  error(const char* description, int error_code);
-  error(const char* description, int error_code, shared_ptr nested_error);
-
-  error(const error& that) throw();
-  error& operator=(const error& that) throw();
-  virtual ~error() throw();
+  InternalError(const InternalError& that) throw();
+  InternalError& operator= (const InternalError& that) throw();
+  virtual ~InternalError() throw();
 
   /**
-   * Returns the error code associated with the exception.
+   * Returns the message associated with this exception object.
    */
-  virtual int code() const throw() { return m_errno; }
+  virtual const char* what() const throw();
+
+protected:
+  typedef compat::shared_ptr<detail::ErrorDescription> description_ptr;
+  explicit InternalError(description_ptr description) throw();
+  description_ptr m_description;
+};
+
+/**
+ * Encapsulate a stack of Subversion error codes and messages.
+ */
+class Error : public InternalError
+{
+public:
+  Error(const Error& that) throw();
+  Error& operator=(const Error& that) throw();
+  virtual ~Error() throw();
 
   /**
-   * Returns a shared pointer to the nested exception object, if any.
+   * Returns the error code associated with the top-level error that
+   * caused the exception.
    */
-  virtual shared_ptr nested() const throw() { return m_nested; }
-
-  /// Returns the message associated with this exception object.
-  virtual const char* what() const throw();
+  virtual int code() const throw();
 
   /**
    * Error message description.
-   *
-   * The first element of this pair is the error code, the second the
-   * associated error message. If the error code is 0, the message
-   * describes the location in the source code where the error was
-   * generated from.
    */
-  typedef std::pair<int, std::string> message;
+  class Message
+  {
+  public:
+    /**
+     * Create a message object given an error code and error message.
+     */
+    Message(int errno, const std::string& message)
+      : m_errno(errno),
+        m_message(message),
+        m_trace(false)
+      {}
+
+    /**
+     * Create a message object given an error code and error message,
+     * and set the flag that tells if this is a debugging traceback entry.
+     */
+    Message(int errno, const std::string& message, bool trace)
+      : m_errno(errno),
+        m_message(message),
+        m_trace(trace)
+      {}
+
+    /**
+     * Return the error code.
+     */
+    int code() const throw() { return m_errno; }
+
+    /**
+     * Return the error message.
+     */
+    const std::string& message() const throw() { return m_message; }
+
+    /**
+     * Return the generic error message associated with the error code.
+     */
+    const char* generic_message() const;
+
+    /**
+     * Check if this message is in fact a debugging traceback entry.
+     */
+    bool trace() const throw() { return m_trace; }
+
+  private:
+    int m_errno;
+    std::string m_message;
+    bool m_trace;
+  };
 
   /**
    * The list of messages associated with an error.
    */
-  typedef std::vector<message> message_list;
+  typedef std::vector<Message> MessageList;
 
   /**
    * Returns the complete list of error messages, including those from
-   * nested exceptions.
+   * nested errors.
    */
-  virtual message_list messages() const
+  virtual MessageList messages() const
     {
       return compile_messages(false);
     }
@@ -106,39 +157,32 @@ public:
    * Traceback is only available if the Subversion libraries were
    * compiled with tracing enabled.
    */
-  virtual message_list traced_messages() const
+  virtual MessageList traced_messages() const
     {
       return compile_messages(true);
     }
 
-public:
-  /** Used internally by the implementation. */
-  static void throw_svn_error(svn_error_t*);
-
 protected:
-  error(int error_code, detail::error_description* description) throw();
-
-private:
-  std::vector<message> compile_messages(bool show_traces) const;
-
-  int m_errno;                /**< The (SVN or APR) error code. */
-  shared_ptr m_nested;        /**< Optional pointer to nessted error. */
-  /** Error description and trace location information. */
-  detail::error_description* m_description;
+  explicit Error(description_ptr description) throw()
+    : InternalError(description)
+    {}
+  MessageList compile_messages(bool show_traces) const;
 };
 
-class cancelled : public error
+/**
+ * Thrown instead of Error when the error chain contains a
+ * @c SVN_ERR_CANCELLED error code.
+ */
+class Cancelled : public Error
 {
-  friend void error::throw_svn_error(svn_error_t*);
-
 protected:
-  cancelled(int error_code, detail::error_description* description) throw()
-    : error(error_code, description)
+  explicit Cancelled(description_ptr description) throw()
+    : Error(description)
     {}
 };
 
-} // namespace version_1_9_dev
 } // namespace cxxhl
 } // namespace subversion
+} // namespace apache
 
 #endif  // SVN_CXXHL_EXCEPTION_HPP

Modified: subversion/branches/cache-server/subversion/bindings/cxxhl/include/svncxxhl/tristate.hpp
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/bindings/cxxhl/include/svncxxhl/tristate.hpp?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/bindings/cxxhl/include/svncxxhl/tristate.hpp (original)
+++ subversion/branches/cache-server/subversion/bindings/cxxhl/include/svncxxhl/tristate.hpp Tue Oct 15 08:52:06 2013
@@ -28,37 +28,37 @@
 #ifndef SVN_CXXHL_TRISTATE_HPP
 #define SVN_CXXHL_TRISTATE_HPP
 
+namespace apache {
 namespace subversion {
 namespace cxxhl {
-namespace version_1_9_dev {
 
-class tristate
+class Tristate
 {
 public:
-  static const tristate TRUE;
-  static const tristate FALSE;
-  static const tristate UNKNOWN;
+  static const Tristate TRUE;
+  static const Tristate FALSE;
+  static const Tristate UNKNOWN;
 
-  tristate(const tristate& that) throw()
+  Tristate(const Tristate& that) throw()
     : m_value(that.m_value)
     {}
 
-  bool operator==(const tristate& that) const throw()
+  bool operator==(const Tristate& that) const throw()
     { return m_value == that.m_value; }
 
-  bool operator!=(const tristate& that) const throw()
+  bool operator!=(const Tristate& that) const throw()
     { return !(*this == that); }
 
   bool known() const throw()
     { return *this != UNKNOWN; }
 
 private:
-  explicit tristate(short int value) throw();
+  explicit Tristate(short int value) throw();
   short int m_value;
 };
 
-} // namespace version_1_9_dev
 } // namespace cxxhl
 } // namespace subversion
+} // namespace apache
 
 #endif  // SVN_CXXHL_TRISTATE_HPP

Modified: subversion/branches/cache-server/subversion/bindings/cxxhl/src/exception.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/bindings/cxxhl/src/exception.cpp?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/bindings/cxxhl/src/exception.cpp (original)
+++ subversion/branches/cache-server/subversion/bindings/cxxhl/src/exception.cpp Tue Oct 15 08:52:06 2013
@@ -28,6 +28,8 @@
 #include <sstream>
 
 #include "svncxxhl/exception.hpp"
+#include "private.hpp"
+#include "aprwrap.hpp"
 
 #include "svn_error.h"
 #include "svn_utf.h"
@@ -37,103 +39,85 @@
 #undef TRUE
 #undef FALSE
 
+namespace apache {
 namespace subversion {
 namespace cxxhl {
 
 namespace detail {
 
-class error_description
+class ErrorDescription
 {
 public:
-  static error_description* create(const char* message,
-                                   const char *loc_file, long loc_line,
-                                   bool trace_link)
+  typedef compat::shared_ptr<ErrorDescription> shared_ptr;
+
+  static shared_ptr create(const char* message, int error_code,
+                           const char *loc_file, long loc_line,
+                           bool trace_link)
     {
-      bool empty_message = (message == NULL);
+      const bool empty_message = (message == NULL);
       const std::size_t length = (empty_message ? 0 : std::strlen(message));
-      void *memblock = ::operator new(length + sizeof(error_description));
+      void* memblock = ::operator new(length + sizeof(ErrorDescription));
 
-      error_description* description = new(memblock) error_description(
-          loc_file, loc_line, trace_link, empty_message);
+      ErrorDescription* description = new(memblock) ErrorDescription(
+          error_code, loc_file, loc_line, trace_link, empty_message);
       if (length)
         std::memcpy(description->m_message, message, length);
       description->m_message[length] = 0;
-      return description;
+      return shared_ptr(description);
     }
 
-  static error_description* create(const char* message)
+  static shared_ptr create(const char* message, int error_code)
     {
-      return create(message, NULL, 0, false);
+      return create(message, error_code, NULL, 0, false);
     }
 
-  error_description* reference() throw()
-    {
-      if (this)
-        svn_atomic_inc(&m_refcount);
-      return this;
-    }
-
-  error_description* dereference() throw()
-    {
-      if (this && 0 == svn_atomic_dec(&m_refcount))
-        {
-          this->~error_description();
-          ::operator delete(this, std::nothrow);
-          return NULL;
-        }
-      return this;
-    }
+  ~ErrorDescription() throw() {}
 
   const char* what() const throw() { return (m_empty ? NULL : m_message); }
+  int code() const throw() { return m_errno; }
   const char* file() const throw() { return m_loc_file; }
   long line() const throw() { return m_loc_line; }
   bool trace() const throw() { return m_trace; }
+  shared_ptr& nested() throw() { return m_nested; }
+  const shared_ptr& nested() const throw() { return m_nested; }
 
 private:
-  error_description(const char *loc_file, long loc_line,
-                    bool trace_link, bool empty_message) throw()
+  ErrorDescription(int error_code,
+                   const char *loc_file, long loc_line,
+                   bool trace_link, bool empty_message) throw()
     : m_loc_file(loc_file),
       m_loc_line(loc_line),
       m_trace(trace_link),
       m_empty(empty_message),
-      m_refcount(0)
+      m_errno(error_code)
     {}
 
-  ~error_description() throw() {}
-
   const char* m_loc_file;
   long m_loc_line;
   bool m_trace;
   bool m_empty;
 
-  volatile svn_atomic_t m_refcount;
-  char m_message[1];
+  shared_ptr m_nested;
+
+  int m_errno;                  ///< The (SVN or APR) error code.
+  char m_message[1];            ///< The error message
 };
 
 } // namespace detail
 
+//
+// Class InternalError
+//
 
-namespace version_1_9_dev {
-
-error::error(const char* description, int error_code)
-  : m_errno(error_code),
-    m_description(detail::error_description::create(description)->reference())
-{}
-
-error::error(const char* description, int error_code,
-             error::shared_ptr nested_error)
-  : m_errno(error_code),
-    m_nested(nested_error),
-    m_description(detail::error_description::create(description)->reference())
+InternalError::InternalError(const char* description)
+  : m_description(detail::ErrorDescription::create(description, 0))
 {}
 
-error::error(const error& that) throw()
-  : m_errno(that.m_errno),
-    m_nested(that.m_nested),
-    m_description(that.m_description->reference())
+InternalError::InternalError(const InternalError& that) throw()
+  : m_description(that.m_description)
 {}
 
-error& error::operator=(const error& that) throw()
+InternalError& InternalError::operator=(const InternalError& that) throw()
 {
   if (this == &that)
     return *this;
@@ -141,89 +125,85 @@ error& error::operator=(const error& tha
   // This in-place destroy+copy implementation of the assignment
   // operator is safe because both the destructor and the copy
   // constructor do not throw exceptions.
-  this->~error();
-  return *new(this) error(that);
+  this->~InternalError();
+  return *new(this) InternalError(that);
 }
 
-error::~error() throw()
-{
-  m_description->dereference();
-}
+InternalError::~InternalError() throw() {}
 
-const char* error::what() const throw()
+const char* InternalError::what() const throw()
 {
   return m_description->what();
 }
 
-error::error(int error_code, detail::error_description* description) throw()
-  : m_errno(error_code),
-    m_description(description)
+InternalError::InternalError(description_ptr description) throw()
+  : m_description(description)
+{}
+
+//
+// Class Error
+//
+
+Error::Error(const Error& that) throw()
+  : InternalError(that.m_description)
 {}
 
-void error::throw_svn_error(svn_error_t* err)
+Error& Error::operator=(const Error& that) throw()
 {
-  const bool throw_cancelled = (err->apr_err == SVN_ERR_CANCELLED);
-  detail::error_description* description = NULL;
-  try
-    {
-      // Be very careful when creating the error descriptions, so that
-      // the exception unwinder can free them if an allocation fails.
-      // The private constructor does not increment the refcount
-      // precisely for this reason.
+  if (this == &that)
+    return *this;
 
-      shared_ptr nested;
-      shared_ptr* current = &nested;
+  // This in-place destroy+copy implementation of the assignment
+  // operator is safe because both the destructor and the copy
+  // constructor do not throw exceptions.
+  this->~Error();
+  return *new(this) Error(that);
+}
 
-      for (svn_error_t* next = err->child; next; next = next->child)
-        {
-          description = detail::error_description::create(
-              next->message, next->file, next->line,
-              svn_error__is_tracing_link(next));
-          description->reference();
-          current->reset(new error(next->apr_err, description));
-          description = NULL;
-          current = &(*current)->m_nested;
-        }
+Error::~Error() throw() {}
+
+int Error::code() const throw()
+{
+  return m_description->code();
+}
+
+namespace {
+const char* get_generic_message(apr_status_t error_code,
+                                const APR::Pool& scratch_pool)
+{
+  char errorbuf[512];
+
+  // Is this a Subversion-specific error code?
+  if (error_code > APR_OS_START_USEERR && error_code <= APR_OS_START_CANONERR)
+    return svn_strerror(error_code, errorbuf, sizeof(errorbuf));
+  // Otherwise, this must be an APR error code.
+  else
+    {
+      const char* generic;
+      svn_error_t* err = svn_utf_cstring_to_utf8(
+          &generic,
+          apr_strerror(error_code, errorbuf, sizeof(errorbuf)),
+          scratch_pool.get());
+      if (!err)
+        return generic;
 
-      const int apr_err = err->apr_err;
-      description = detail::error_description::create(
-          err->message, err->file, err->line,
-          svn_error__is_tracing_link(err));
-      description->reference();
+      // Use fuzzy transliteration instead.
       svn_error_clear(err);
-      if (throw_cancelled)
-        {
-          cancelled converted = cancelled(apr_err, description);
-          description = NULL;
-          converted.m_nested = nested;
-          throw converted;
-        }
-      else
-        {
-          error converted = error(apr_err, description);
-          description = NULL;
-          converted.m_nested = nested;
-          throw converted;
-        }
-    }
-  catch (...)
-    {
-      description->dereference();
-      throw;
+      return svn_utf_cstring_from_utf8_fuzzy(errorbuf, scratch_pool.get());
     }
 }
 
-
-namespace {
-void handle_one_error(error::message_list& ml, bool show_traces,
-                      int error_code, detail::error_description* descr,
-                      apr_pool_t* pool)
+void handle_one_error(Error::MessageList& ml, bool show_traces,
+                      const detail::ErrorDescription* descr,
+                      const APR::Pool& pool)
 {
+  const int error_code = descr->code();
+
   if (show_traces && descr->file())
     {
       const char* file_utf8 = NULL;
       svn_error_t* err =
-        svn_utf_cstring_to_utf8(&file_utf8, descr->file(), pool);
+        svn_utf_cstring_to_utf8(&file_utf8, descr->file(), pool.get());
       if (err)
         {
           svn_error_clear(err);
@@ -234,8 +214,18 @@ void handle_one_error(error::message_lis
         buffer << file_utf8 << ':' << descr->line();
       else
         buffer << "svn:<undefined>";
-      buffer << ": (apr_err=" << error_code << ')';
-      ml.push_back(error::message(0, buffer.str()));
+      if (descr->trace())
+        buffer << ',';
+      else
+        {
+#ifdef SVN_DEBUG
+          if (const char* symbolic_name = svn_error_symbolic_name(error_code))
+            buffer << ": (apr_err=" << symbolic_name << ')';
+          else
+#endif
+            buffer << ": (apr_err=" << error_code << ')';
+        }
+      ml.push_back(Error::Message(error_code, buffer.str(), true));
     }
 
   if (descr->trace())
@@ -243,43 +233,24 @@ void handle_one_error(error::message_lis
 
   const char *description = descr->what();
   if (!description)
-    {
-      char errorbuf[512];
-
-      // Is this a Subversion-specific error code?
-      if (error_code > APR_OS_START_USEERR
-          && error_code <= APR_OS_START_CANONERR)
-        description = svn_strerror(error_code, errorbuf, sizeof(errorbuf));
-      // Otherwise, this must be an APR error code.
-      else
-        {
-          svn_error_t* err = svn_utf_cstring_to_utf8(
-              &description,
-              apr_strerror(error_code, errorbuf, sizeof(errorbuf)),
-              pool);
-          if (err)
-            {
-              svn_error_clear(err);
-              description = _("Can't recode error string from APR");
-            }
-        }
-    }
-  ml.push_back(error::message(error_code, std::string(description)));
+    description = get_generic_message(error_code, pool);
+  ml.push_back(Error::Message(error_code, std::string(description), false));
 }
 } // anonymous namespace
 
-error::message_list error::compile_messages(bool show_traces) const
+Error::MessageList Error::compile_messages(bool show_traces) const
 {
   // Determine the maximum size of the returned list
-  message_list::size_type max_length = 0;
-  for (const error* err = this; err; err = err->m_nested.get())
+  MessageList::size_type max_length = 0;
+  for (const detail::ErrorDescription* description = m_description.get();
+       description; description = description->nested().get())
     {
-      if (show_traces && m_description->file())
+      if (show_traces && description->file())
         ++max_length;                   // We will display an error location
-      if (!m_description->trace())
+      if (!description->trace())
         ++max_length;                   // Traces do not emit a message line
     }
-  message_list ml;
+  MessageList ml;
   ml.reserve(max_length);
 
   // This vector holds a list of all error codes that we've printed
@@ -287,36 +258,74 @@ error::message_list error::compile_messa
   std::vector<int> empties;
   empties.reserve(max_length);
 
-  apr_pool_t* pool = NULL;
-  apr_pool_create(&pool, NULL);
-  try
+  APR::IterationPool iterbase;
+  for (const detail::ErrorDescription* description = m_description.get();
+       description; description = description->nested().get())
     {
-      for (const error* err = this; err; err = err->m_nested.get())
+      APR::Pool::Iteration iterpool(iterbase);
+
+      if (!description->what())
         {
-          if (!err->m_description->what())
-            {
-              // Non-specific messages are printed only once.
-              std::vector<int>::iterator it = std::find(
-                  empties.begin(), empties.end(), err->m_errno);
-              if (it != empties.end())
-                continue;
-              empties.push_back(err->m_errno);
-            }
-          handle_one_error(ml, show_traces,
-                           err->m_errno, err->m_description,
-                           pool);
+          // Non-specific messages are printed only once.
+          std::vector<int>::iterator it = std::find(
+              empties.begin(), empties.end(), description->code());
+          if (it != empties.end())
+            continue;
+          empties.push_back(description->code());
         }
+      handle_one_error(ml, show_traces, description, iterpool.pool());
     }
-  catch (...)
-    {
-      apr_pool_destroy(pool);
-      throw;
-    }
-
-  apr_pool_destroy(pool);
   return ml;
 }
 
-} // namespace version_1_9_dev
+const char* Error::Message::generic_message() const
+{
+  APR::Pool pool;
+  return get_generic_message(m_errno, pool);
+}
+
+namespace detail {
+void checked_call(svn_error_t* err)
+{
+  if (!err)
+    return;
+
+  struct ErrorBuilder : public Error
+  {
+    explicit ErrorBuilder (ErrorDescription::shared_ptr description)
+      : Error(description)
+      {}
+  };
+
+  struct CancelledBuilder : public Cancelled
+  {
+    explicit CancelledBuilder (ErrorDescription::shared_ptr description)
+      : Cancelled(description)
+      {}
+  };
+
+  ErrorDescription::shared_ptr description;
+  ErrorDescription::shared_ptr* current = &description;
+
+  bool cancelled = false;
+  for (svn_error_t* next = err; next; next = next->child)
+    {
+      *current = ErrorDescription::create(next->message, next->apr_err,
+                                          next->file, next->line,
+                                          svn_error__is_tracing_link(next));
+      current = &(*current)->nested();
+      if (next->apr_err == SVN_ERR_CANCELLED)
+        cancelled = true;
+    }
+  svn_error_clear(err);
+
+  if (cancelled)
+    throw CancelledBuilder(description);
+  else
+    throw ErrorBuilder(description);
+}
+} // namespace detail
+
 } // namespace cxxhl
 } // namespace subversion
+} // namespace apache

Modified: subversion/branches/cache-server/subversion/bindings/cxxhl/src/tristate.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/bindings/cxxhl/src/tristate.cpp?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/bindings/cxxhl/src/tristate.cpp (original)
+++ subversion/branches/cache-server/subversion/bindings/cxxhl/src/tristate.cpp Tue Oct 15 08:52:06 2013
@@ -27,18 +27,18 @@
 #undef TRUE
 #undef FALSE
 
+namespace apache {
 namespace subversion {
 namespace cxxhl {
-namespace version_1_9_dev {
 
-tristate::tristate(short value) throw()
+Tristate::Tristate(short value) throw()
     : m_value(value)
 {}
 
-const tristate tristate::TRUE = tristate(svn_tristate_true);
-const tristate tristate::FALSE = tristate(svn_tristate_false);
-const tristate tristate::UNKNOWN = tristate(svn_tristate_unknown);
+const Tristate Tristate::TRUE = Tristate(svn_tristate_true);
+const Tristate Tristate::FALSE = Tristate(svn_tristate_false);
+const Tristate Tristate::UNKNOWN = Tristate(svn_tristate_unknown);
 
-} // namespace version_1_9_dev
 } // namespace cxxhl
 } // namespace subversion
+} // namespace apache

Modified: subversion/branches/cache-server/subversion/bindings/cxxhl/tests/test_exception.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/bindings/cxxhl/tests/test_exception.cpp?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/bindings/cxxhl/tests/test_exception.cpp (original)
+++ subversion/branches/cache-server/subversion/bindings/cxxhl/tests/test_exception.cpp Tue Oct 15 08:52:06 2013
@@ -20,110 +20,114 @@
  */
 
 #include <algorithm>
+#include <cstdio>
 #include <iomanip>
 #include <ios>
 #include <iostream>
 
 #include "svncxxhl.hpp"
+#include "../src/private.hpp"
 
 #include <apr.h>
 #include "svn_error.h"
+#undef TRUE
+#undef FALSE
 
-namespace {
-void trace(const svn::error::message& msg)
-{
-  std::cout << "    ";
-  if (msg.first)
-    std::cout << "test_exception: E"
-              << std::setw(6) << std::setfill('0') << std::right
-              << msg.first << ':' << ' ';
-  std::cout << msg.second << std::endl;
-}
+#include <gmock/gmock.h>
 
-void traceall(const char *message, const svn::error& err)
+namespace {
+svn_error_t* make_error_test_error()
 {
-  typedef svn::error::message_list message_list;
-  std::cout << message << std::endl;
-  std::cout << "Traced Messages:" << std::endl;
-  message_list ml = err.traced_messages();
-  std::for_each(ml.begin(), ml.end(), trace);
-  std::cout << "Just Messages:" << std::endl;
-  ml = err.messages();
-  std::for_each(ml.begin(), ml.end(), trace);
+  svn_error_t* err;
+  err = svn_error_create(SVN_ERR_TEST_FAILED, NULL, "original message");
+  err = svn_error_create(SVN_ERR_BASE, err, "wrapper message");
+  err = svn_error_trace(err);
+  err = svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, err, NULL);
+  err = svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, err, NULL);
+  err = svn_error_trace(err);
+  return err;
 }
 } // anonymous namespace
 
-
-bool test_cancel()
+TEST(Exceptions, CatchError)
 {
   try
     {
-      svn_error_t* err;
-      err = svn_error_create(SVN_ERR_TEST_FAILED, NULL, "original message");
-      err = svn_error_create(SVN_ERR_BASE, err, "wrapper message");
-      err = svn_error_create(SVN_ERR_CANCELLED, err, NULL);
-      err = svn_error_create(SVN_ERR_CANCELLED, err, NULL);
-      err = svn_error_trace(err);
-      svn::error::throw_svn_error(err);
-    }
-  catch (const svn::cancelled& err)
-    {
-      traceall("Caught: CANCEL", err);
-      return true;
+      SVN::detail::checked_call(make_error_test_error());
     }
-  catch (const svn::error& err)
+  catch (const SVN::Error& err)
     {
-      traceall("Caught: ERROR", err);
-      return false;
+      SVN::Error::MessageList ml = err.messages();
+      EXPECT_EQ(3, ml.size());
+      EXPECT_EQ(SVN_ERR_UNSUPPORTED_FEATURE, ml[0].code());
+      EXPECT_EQ(SVN_ERR_BASE, ml[1].code());
+      EXPECT_EQ(SVN_ERR_TEST_FAILED, ml[2].code());
+
+      SVN::Error::MessageList tml = err.traced_messages();
+#ifdef SVN_DEBUG
+      EXPECT_EQ(8, tml.size());
+      EXPECT_EQ(SVN_ERR_UNSUPPORTED_FEATURE, tml[0].code());
+      EXPECT_EQ(SVN_ERR_UNSUPPORTED_FEATURE, tml[1].code());
+      EXPECT_EQ(SVN_ERR_UNSUPPORTED_FEATURE, tml[2].code());
+      EXPECT_EQ(SVN_ERR_BASE, tml[3].code());
+      EXPECT_EQ(SVN_ERR_BASE, tml[4].code());
+      EXPECT_EQ(SVN_ERR_BASE, tml[5].code());
+      EXPECT_EQ(SVN_ERR_TEST_FAILED, tml[6].code());
+      EXPECT_EQ(SVN_ERR_TEST_FAILED, tml[7].code());
+#else  // !SVN_DEBUG
+      EXPECT_EQ(3, tml.size());
+      EXPECT_EQ(SVN_ERR_UNSUPPORTED_FEATURE, tml[0].code());
+      EXPECT_EQ(SVN_ERR_BASE, tml[1].code());
+      EXPECT_EQ(SVN_ERR_TEST_FAILED, tml[2].code());
+#endif // SVN_DEBUG
     }
-  catch (...)
-    {
-      return false;
-    }
-  return false;
 }
 
-int test_error()
+
+namespace {
+svn_error_t* make_cancel_test_error()
+{
+  svn_error_t* err;
+  err = svn_error_create(SVN_ERR_CANCELLED, NULL, NULL);
+  err = svn_error_create(SVN_ERR_CANCELLED, err, NULL);
+  err = svn_error_trace(err);
+  err = svn_error_create(SVN_ERR_TEST_FAILED, err, "original message");
+  err = svn_error_create(SVN_ERR_BASE, err, "wrapper message");
+  err = svn_error_trace(err);
+  return err;
+}
+} // anonymous namespace
+
+TEST(Exceptions, CatchCancelled)
 {
   try
     {
-      svn_error_t* err;
-      err = svn_error_create(SVN_ERR_TEST_FAILED, NULL, "original message");
-      err = svn_error_create(SVN_ERR_BASE, err, "wrapper message");
-      err = svn_error_create(SVN_ERR_CANCELLED, err, NULL);
-      err = svn_error_create(SVN_ERR_CANCELLED, err, NULL);
-      err = svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, err, NULL);
-      err = svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, err, NULL);
-      err = svn_error_trace(err);
-      svn::error::throw_svn_error(err);
-    }
-  catch (const svn::cancelled& err)
-    {
-      traceall("Caught: CANCEL", err);
-      return false;
-    }
-  catch (const svn::error& err)
-    {
-      traceall("Caught: ERROR", err);
-      return true;
+      SVN::detail::checked_call(make_cancel_test_error());
     }
-  catch (...)
+  catch (const SVN::Cancelled& err)
     {
-      return false;
+      SVN::Error::MessageList ml = err.messages();
+      EXPECT_EQ(3, ml.size());
+      EXPECT_EQ(SVN_ERR_BASE, ml[0].code());
+      EXPECT_EQ(SVN_ERR_TEST_FAILED, ml[1].code());
+      EXPECT_EQ(SVN_ERR_CANCELLED, ml[2].code());
+
+      SVN::Error::MessageList tml = err.traced_messages();
+#ifdef SVN_DEBUG
+      EXPECT_EQ(8, tml.size());
+      EXPECT_EQ(SVN_ERR_BASE, tml[0].code());
+      EXPECT_EQ(SVN_ERR_BASE, tml[1].code());
+      EXPECT_EQ(SVN_ERR_BASE, tml[2].code());
+      EXPECT_EQ(SVN_ERR_TEST_FAILED, tml[3].code());
+      EXPECT_EQ(SVN_ERR_TEST_FAILED, tml[4].code());
+      EXPECT_EQ(SVN_ERR_CANCELLED, tml[5].code());
+      EXPECT_EQ(SVN_ERR_CANCELLED, tml[6].code());
+      EXPECT_EQ(SVN_ERR_CANCELLED, tml[7].code());
+#else  // !SVN_DEBUG
+      EXPECT_EQ(3, tml.size());
+      EXPECT_EQ(SVN_ERR_BASE, tml[0].code());
+      EXPECT_EQ(SVN_ERR_TEST_FAILED, tml[1].code());
+      EXPECT_EQ(SVN_ERR_CANCELLED, tml[2].code());
+#endif // SVN_DEBUG
     }
-  return false;
-}
-
-int main()
-{
-  apr_initialize();
-
-  const char *stat  = (test_cancel() ? "OK" : "ERROR");
-  std::cerr << "test_cancel .... " << stat << std::endl;
-
-  stat = (test_error() ? "OK" : "ERROR");
-  std::cerr << "test_error ..... " << stat << std::endl;
-
-  apr_terminate();
-  return 0;
 }

Modified: subversion/branches/cache-server/subversion/bindings/javahl/native/BlameCallback.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/bindings/javahl/native/BlameCallback.cpp?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/bindings/javahl/native/BlameCallback.cpp (original)
+++ subversion/branches/cache-server/subversion/bindings/javahl/native/BlameCallback.cpp Tue Oct 15 08:52:06 2013
@@ -104,14 +104,14 @@ BlameCallback::singleLine(svn_revnum_t s
     }
 
   // convert the parameters to their Java relatives
-  jobject jrevProps = CreateJ::PropertyMap(revProps);
+  jobject jrevProps = CreateJ::PropertyMap(revProps, pool);
   if (JNIUtil::isJavaExceptionThrown())
     POP_AND_RETURN(SVN_NO_ERROR);
 
   jobject jmergedRevProps = NULL;
   if (mergedRevProps != NULL)
     {
-      jmergedRevProps = CreateJ::PropertyMap(mergedRevProps);
+      jmergedRevProps = CreateJ::PropertyMap(mergedRevProps, pool);
       if (JNIUtil::isJavaExceptionThrown())
         POP_AND_RETURN(SVN_NO_ERROR);
     }

Modified: subversion/branches/cache-server/subversion/bindings/javahl/native/ClientContext.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/bindings/javahl/native/ClientContext.cpp?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/bindings/javahl/native/ClientContext.cpp (original)
+++ subversion/branches/cache-server/subversion/bindings/javahl/native/ClientContext.cpp Tue Oct 15 08:52:06 2013
@@ -39,37 +39,10 @@
 
 
 ClientContext::ClientContext(jobject jsvnclient, SVN::Pool &pool)
-    : m_prompter(NULL),
-      m_cancelOperation(false)
+    : OperationContext(pool)
 {
-    JNIEnv *env = JNIUtil::getEnv();
-
-    /* Grab a global reference to the Java object embedded in the parent Java
-       object. */
     static jfieldID ctxFieldID = 0;
-    if (ctxFieldID == 0)
-    {
-        jclass clazz = env->GetObjectClass(jsvnclient);
-        if (JNIUtil::isJavaExceptionThrown())
-            return;
-
-        ctxFieldID = env->GetFieldID(clazz, "clientContext",
-                                "L"JAVA_PACKAGE"/SVNClient$ClientContext;");
-        if (JNIUtil::isJavaExceptionThrown() || ctxFieldID == 0)
-            return;
-
-        env->DeleteLocalRef(clazz);
-    }
-
-    jobject jctx = env->GetObjectField(jsvnclient, ctxFieldID);
-    if (JNIUtil::isJavaExceptionThrown())
-        return;
-
-    m_jctx = env->NewGlobalRef(jctx);
-    if (JNIUtil::isJavaExceptionThrown())
-        return;
-
-    env->DeleteLocalRef(jctx);
+    attachJavaObject(jsvnclient, "L"JAVA_PACKAGE"/SVNClient$ClientContext;", "clientContext", &ctxFieldID);
 
     SVN_JNI_ERR(svn_client_create_context2(&m_context, NULL,
                                            pool.getPool()),
@@ -96,18 +69,39 @@ ClientContext::ClientContext(jobject jsv
     m_context->conflict_func2 = resolve;
     m_context->conflict_baton2 = m_jctx;
 
-    m_context->client_name = "javahl";
-    m_pool = &pool;
+    m_context->client_name = getClientName();
+
+    if (m_jtunnelcb)
+      {
+        m_context->check_tunnel_func = checkTunnel;
+        m_context->open_tunnel_func = openTunnel;
+        m_context->close_tunnel_func = closeTunnel;
+        m_context->tunnel_baton = m_jtunnelcb;
+      }
 }
 
 ClientContext::~ClientContext()
 {
-    delete m_prompter;
-
-    JNIEnv *env = JNIUtil::getEnv();
-    env->DeleteGlobalRef(m_jctx);
 }
 
+void ClientContext::setTunnelCallback(jobject jtunnelcb)
+{
+  OperationContext::setTunnelCallback(jtunnelcb);
+  if (m_jtunnelcb)
+    {
+      m_context->check_tunnel_func = checkTunnel;
+      m_context->open_tunnel_func = openTunnel;
+      m_context->close_tunnel_func = closeTunnel;
+      m_context->tunnel_baton = m_jtunnelcb;
+    }
+  else
+    {
+      m_context->check_tunnel_func = NULL;
+      m_context->open_tunnel_func = NULL;
+      m_context->close_tunnel_func = NULL;
+      m_context->tunnel_baton = NULL;
+    }
+}
 
 /* Helper function to make sure that we don't keep dangling pointers in ctx.
    Note that this function might be called multiple times if getContext()
@@ -140,7 +134,6 @@ svn_client_ctx_t *
 ClientContext::getContext(CommitMessage *message, SVN::Pool &in_pool)
 {
     apr_pool_t *pool = in_pool.getPool();
-    svn_auth_baton_t *ab;
     svn_client_ctx_t *ctx = m_context;
 
     /* Make a temporary copy of ctx to restore at pool cleanup to avoid
@@ -157,122 +150,17 @@ ClientContext::getContext(CommitMessage 
     apr_pool_cleanup_register(in_pool.getPool(), bt, clear_ctx_ptrs,
                               clear_ctx_ptrs);
 
-
     if (!ctx->config)
       {
-        const char *configDir = m_configDir.c_str();
-        if (m_configDir.empty())
-            configDir = NULL;
-        SVN_JNI_ERR(svn_config_get_config(&(ctx->config), configDir,
-                                          m_pool->getPool()),
-                    NULL);
+        apr_hash_t * configData = getConfigData();
 
+        ctx->config = configData;
         bt->backup->config = ctx->config;
       }
-    svn_config_t *config =
-        reinterpret_cast<svn_config_t *>(apr_hash_get(ctx->config,
-                                                      SVN_CONFIG_CATEGORY_CONFIG,
-                                                      APR_HASH_KEY_STRING));
-
-
-    /* The whole list of registered providers */
-    apr_array_header_t *providers;
-
-    /* Populate the registered providers with the platform-specific providers */
-    SVN_JNI_ERR(svn_auth_get_platform_specific_client_providers(&providers,
-                                                                config,
-                                                                pool),
-                NULL);
-
-    /* Use the prompter (if available) to prompt for password and cert
-     * caching. */
-    svn_auth_plaintext_prompt_func_t plaintext_prompt_func = NULL;
-    void *plaintext_prompt_baton = NULL;
-    svn_auth_plaintext_passphrase_prompt_func_t plaintext_passphrase_prompt_func;
-    void *plaintext_passphrase_prompt_baton = NULL;
-
-    if (m_prompter != NULL)
-    {
-        plaintext_prompt_func = Prompter::plaintext_prompt;
-        plaintext_prompt_baton = m_prompter;
-        plaintext_passphrase_prompt_func = Prompter::plaintext_passphrase_prompt;
-        plaintext_passphrase_prompt_baton = m_prompter;
-    }
-
-    /* The main disk-caching auth providers, for both
-     * 'username/password' creds and 'username' creds.  */
-    svn_auth_provider_object_t *provider;
-
-    svn_auth_get_simple_provider2(&provider, plaintext_prompt_func,
-                                  plaintext_prompt_baton, pool);
-    APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
-
-    svn_auth_get_username_provider(&provider, pool);
-    APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
-
-    /* The server-cert, client-cert, and client-cert-password providers. */
-    SVN_JNI_ERR(svn_auth_get_platform_specific_provider(&provider,
-                                                        "windows",
-                                                        "ssl_server_trust",
-                                                        pool),
-                NULL);
-
-    if (provider)
-        APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
-
-    svn_auth_get_ssl_server_trust_file_provider(&provider, pool);
-    APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
-    svn_auth_get_ssl_client_cert_file_provider(&provider, pool);
-    APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
-    svn_auth_get_ssl_client_cert_pw_file_provider2(&provider,
-                        plaintext_passphrase_prompt_func,
-                        plaintext_passphrase_prompt_baton, pool);
-    APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
-
-    if (m_prompter != NULL)
-    {
-        /* Two basic prompt providers: username/password, and just username.*/
-        provider = m_prompter->getProviderSimple(in_pool);
-
-        APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
-
-        provider = m_prompter->getProviderUsername(in_pool);
-        APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
-
-        /* Three ssl prompt providers, for server-certs, client-certs,
-         * and client-cert-passphrases.  */
-        provider = m_prompter->getProviderServerSSLTrust(in_pool);
-        APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
-
-        provider = m_prompter->getProviderClientSSL(in_pool);
-        APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
-
-        provider = m_prompter->getProviderClientSSLPassword(in_pool);
-        APR_ARRAY_PUSH(providers, svn_auth_provider_object_t *) = provider;
-    }
-
-    /* Build an authentication baton to give to libsvn_client. */
-    svn_auth_open(&ab, providers, pool);
-
-    /* Place any default --username or --password credentials into the
-     * auth_baton's run-time parameter hash.  ### Same with --no-auth-cache? */
-    if (!m_userName.empty())
-        svn_auth_set_parameter(ab, SVN_AUTH_PARAM_DEFAULT_USERNAME,
-                               apr_pstrdup(in_pool.getPool(),
-                                           m_userName.c_str()));
-    if (!m_passWord.empty())
-        svn_auth_set_parameter(ab, SVN_AUTH_PARAM_DEFAULT_PASSWORD,
-                               apr_pstrdup(in_pool.getPool(),
-                                           m_passWord.c_str()));
-    /* Store where to retrieve authentication data? */
-    if (!m_configDir.empty())
-        svn_auth_set_parameter(ab, SVN_AUTH_PARAM_CONFIG_DIR,
-                               apr_pstrdup(in_pool.getPool(),
-                                           m_configDir.c_str()));
 
-    ctx->auth_baton = ab;
+    ctx->auth_baton = getAuthBaton(in_pool);
     ctx->log_msg_baton3 = message;
-    m_cancelOperation = false;
+    resetCancelRequest();
 
     SVN_JNI_ERR(svn_wc_context_create(&ctx->wc_ctx, NULL,
                                       in_pool.getPool(), in_pool.getPool()),
@@ -282,60 +170,6 @@ ClientContext::getContext(CommitMessage 
 }
 
 void
-ClientContext::username(const char *pi_username)
-{
-    m_userName = (pi_username == NULL ? "" : pi_username);
-}
-
-void
-ClientContext::password(const char *pi_password)
-{
-    m_passWord = (pi_password == NULL ? "" : pi_password);
-}
-
-void
-ClientContext::setPrompt(Prompter *prompter)
-{
-    delete m_prompter;
-    m_prompter = prompter;
-}
-
-void
-ClientContext::setConfigDirectory(const char *configDir)
-{
-    // A change to the config directory may necessitate creation of
-    // the config templates.
-    SVN::Pool requestPool;
-    SVN_JNI_ERR(svn_config_ensure(configDir, requestPool.getPool()), );
-
-    m_configDir = (configDir == NULL ? "" : configDir);
-    m_context->config = NULL;
-}
-
-const char *
-ClientContext::getConfigDirectory() const
-{
-    return m_configDir.c_str();
-}
-
-void
-ClientContext::cancelOperation()
-{
-    m_cancelOperation = true;
-}
-
-svn_error_t *
-ClientContext::checkCancel(void *cancelBaton)
-{
-    ClientContext *that = static_cast<ClientContext *>(cancelBaton);
-    if (that->m_cancelOperation)
-        return svn_error_create(SVN_ERR_CANCELLED, NULL,
-                                _("Operation cancelled"));
-    else
-        return SVN_NO_ERROR;
-}
-
-void
 ClientContext::notify(void *baton,
                       const svn_wc_notify_t *notify,
                       apr_pool_t *pool)
@@ -369,54 +203,6 @@ ClientContext::notify(void *baton,
   env->DeleteLocalRef(jInfo);
 }
 
-void
-ClientContext::progress(apr_off_t progressVal, apr_off_t total,
-                        void *baton, apr_pool_t *pool)
-{
-  jobject jctx = (jobject) baton;
-  JNIEnv *env = JNIUtil::getEnv();
-
-  // Create a local frame for our references
-  env->PushLocalFrame(LOCAL_FRAME_SIZE);
-  if (JNIUtil::isJavaExceptionThrown())
-    return;
-
-  static jmethodID mid = 0;
-  if (mid == 0)
-    {
-      jclass clazz = env->GetObjectClass(jctx);
-      if (JNIUtil::isJavaExceptionThrown())
-        POP_AND_RETURN_NOTHING();
-
-      mid = env->GetMethodID(clazz, "onProgress",
-                             "(L"JAVA_PACKAGE"/ProgressEvent;)V");
-      if (JNIUtil::isJavaExceptionThrown() || mid == 0)
-        POP_AND_RETURN_NOTHING();
-    }
-
-  static jmethodID midCT = 0;
-  jclass clazz = env->FindClass(JAVA_PACKAGE"/ProgressEvent");
-  if (JNIUtil::isJavaExceptionThrown())
-    POP_AND_RETURN_NOTHING();
-
-  if (midCT == 0)
-    {
-      midCT = env->GetMethodID(clazz, "<init>", "(JJ)V");
-      if (JNIUtil::isJavaExceptionThrown() || midCT == 0)
-        POP_AND_RETURN_NOTHING();
-    }
-
-  // Call the Java method.
-  jobject jevent = env->NewObject(clazz, midCT,
-                                  (jlong) progressVal, (jlong) total);
-  if (JNIUtil::isJavaExceptionThrown())
-    POP_AND_RETURN_NOTHING();
-
-  env->CallVoidMethod(jctx, mid, jevent);
-
-  POP_AND_RETURN_NOTHING();
-}
-
 svn_error_t *
 ClientContext::resolve(svn_wc_conflict_result_t **result,
                        const svn_wc_conflict_description2_t *desc,

Modified: subversion/branches/cache-server/subversion/bindings/javahl/native/ClientContext.h
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/bindings/javahl/native/ClientContext.h?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/bindings/javahl/native/ClientContext.h (original)
+++ subversion/branches/cache-server/subversion/bindings/javahl/native/ClientContext.h Tue Oct 15 08:52:06 2013
@@ -29,6 +29,8 @@
 
 #include <string>
 
+#include "OperationContext.h"
+
 #include "svn_types.h"
 #include "svn_client.h"
 
@@ -36,7 +38,6 @@
 #include "Pool.h"
 #include "JNIStringHolder.h"
 
-class Prompter;
 class CommitMessage;
 
 /**
@@ -44,25 +45,14 @@ class CommitMessage;
  * and implements the functions read & close of svn_stream_t.
  *
  */
-class ClientContext
+class ClientContext : public OperationContext
 {
  private:
   svn_client_ctx_t *m_context;
-  const SVN::Pool *m_pool;
-  jobject m_jctx;
-
-  std::string m_userName;
-  std::string m_passWord;
-  std::string m_configDir;
-
-  Prompter *m_prompter;
-  bool m_cancelOperation;
 
  protected:
   static void notify(void *baton, const svn_wc_notify_t *notify,
                      apr_pool_t *pool);
-  static void progress(apr_off_t progressVal, apr_off_t total,
-                       void *baton, apr_pool_t *pool);
   static svn_error_t *resolve(svn_wc_conflict_result_t **result,
                               const svn_wc_conflict_description2_t *desc,
                               void *baton,
@@ -73,24 +63,10 @@ class ClientContext
 
  public:
   ClientContext(jobject jsvnclient, SVN::Pool &pool);
-  ~ClientContext();
-
-  static svn_error_t *checkCancel(void *cancelBaton);
+  virtual ~ClientContext();
+  virtual void setTunnelCallback(jobject jtunnelcb);
 
   svn_client_ctx_t *getContext(CommitMessage *message, SVN::Pool &in_pool);
-
-  void username(const char *pi_username);
-  void password(const char *pi_password);
-  void setPrompt(Prompter *prompter);
-  void cancelOperation();
-  const char *getConfigDirectory() const;
-
-  /**
-   * Set the configuration directory, taking the usual steps to
-   * ensure that Subversion's config file templates exist in the
-   * specified location.
-   */
-  void setConfigDirectory(const char *configDir);
 };
 
 #endif // CLIENTCONTEXT_H

Modified: subversion/branches/cache-server/subversion/bindings/javahl/native/CommitCallback.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/bindings/javahl/native/CommitCallback.cpp?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/bindings/javahl/native/CommitCallback.cpp (original)
+++ subversion/branches/cache-server/subversion/bindings/javahl/native/CommitCallback.cpp Tue Oct 15 08:52:06 2013
@@ -37,9 +37,8 @@
  * @param jcallback the Java callback object.
  */
 CommitCallback::CommitCallback(jobject jcallback)
-{
-  m_callback = jcallback;
-}
+  : m_callback(jcallback)
+{}
 
 /**
  * Destroy a CommitCallback object
@@ -102,3 +101,14 @@ CommitCallback::commitInfo(const svn_com
   env->PopLocalFrame(NULL);
   return SVN_NO_ERROR;
 }
+
+
+PersistentCommitCallback::PersistentCommitCallback(jobject jcallback)
+  : CommitCallback(JNIUtil::getEnv()->NewGlobalRef(jcallback))
+{}
+
+PersistentCommitCallback::~PersistentCommitCallback()
+{
+  if (m_callback)
+    JNIUtil::getEnv()->DeleteGlobalRef(m_callback);
+}

Modified: subversion/branches/cache-server/subversion/bindings/javahl/native/CommitCallback.h
URL: http://svn.apache.org/viewvc/subversion/branches/cache-server/subversion/bindings/javahl/native/CommitCallback.h?rev=1532250&r1=1532249&r2=1532250&view=diff
==============================================================================
--- subversion/branches/cache-server/subversion/bindings/javahl/native/CommitCallback.h (original)
+++ subversion/branches/cache-server/subversion/bindings/javahl/native/CommitCallback.h Tue Oct 15 08:52:06 2013
@@ -47,11 +47,26 @@ class CommitCallback
   svn_error_t *commitInfo(const svn_commit_info_t *commit_info,
                           apr_pool_t *pool);
 
- private:
   /**
    * This a local reference to the Java object.
    */
   jobject m_callback;
 };
 
+/**
+ * Like CommitCallback, but maintains a reference to the Java object
+ * across JNI calls.
+ */
+class PersistentCommitCallback : protected CommitCallback
+{
+ public:
+  PersistentCommitCallback(jobject jcallback);
+  ~PersistentCommitCallback();
+  static svn_error_t *callback(const svn_commit_info_t *commit_info,
+                               void *baton, apr_pool_t *pool)
+    {
+      return CommitCallback::callback(commit_info, baton, pool);
+    }
+};
+
 #endif  // COMMITCALLBACK_H