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/11/27 12:52:46 UTC

svn commit: r1546002 [4/39] - in /subversion/branches/verify-keep-going: ./ build/ build/ac-macros/ build/generator/ build/generator/swig/ build/generator/templates/ build/win32/ contrib/client-side/emacs/ contrib/server-side/ contrib/server-side/svncu...

Modified: subversion/branches/verify-keep-going/contrib/server-side/svncutter/svncutter
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/contrib/server-side/svncutter/svncutter?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/contrib/server-side/svncutter/svncutter (original)
+++ subversion/branches/verify-keep-going/contrib/server-side/svncutter/svncutter Wed Nov 27 11:52:35 2013
@@ -126,10 +126,12 @@ in the LOGFILE, which should be in the f
 Replacements may be restricted to a specified range.
 """,
     "skeleton": """\
-skeleton: usage: svncutter [-r SELECTION] skeleton
+skeleton: usage: svncutter [-r SELECTION] skeleton PATTERN...
 
-Replace content with unique generated cookies.  Useful
-when you need to examine a particularly complex node structure.
+Replace content with unique generated cookies on all node paths
+matching the specified regular expressions; if no expressions are
+given, match all paths.  Useful when you need to examine a
+particularly complex node structure.
 """,
     "expunge": """\
 expunge: usage: svncutter [-r SELECTION ] expunge PATTERN...
@@ -725,7 +727,7 @@ def setlog(source, logpatch, selection):
         return (propkeys, propdict)
     source.apply_property_hook(selection, loghook)
 
-def skeletonize(source, selection):
+def skeletonize(source, selection, patterns):
     "Skeletonize a portion of the dump file defined by a revision selection."
     def __skeletonize(header, properties, content):
         def get_header(hd, name):
@@ -733,6 +735,18 @@ def skeletonize(source, selection):
             return m and m.group(1)
         def set_length(hd, name, val):
             return re.sub("(?<=%s: )[0-9]+" % name, str(val), hd)
+
+        # first check against the pattern
+        ok = True
+        for pattern in patterns:
+            if header.startswith("Node-path: ") and re.search(pattern, header[11:]):
+                #sys.stderr.write("skeletonize skipping: " + header[11:header.index("\n")] +"\n")
+                ok = False
+                break
+        if not ok:
+            return header + properties + content
+        del ok
+
         if content:
             tell = "Revision is %s, file path is %s.\n\n\n" % \
                       (source.revision, get_header(header, "Node-path"),)
@@ -756,7 +770,8 @@ def expunge(source, selection, patterns)
     "Strip out ops defined by a revision selection and a path regexp."
     def __expunge(header, properties, content):
         for pattern in patterns:
-            if re.search("Node-path: " + pattern, header):
+            if header.startswith("Node-path: ") and re.search(pattern, header[11:]):
+                #sys.stderr.write("expunge skipping: " + header[11:header.index("\n")] +"\n")
                 return ""
         else:
             return header + properties + content
@@ -840,9 +855,9 @@ if __name__ == '__main__':
                 sys.stderr.write("svncutter: setlog requires a log entries file.\n")
             setlog(DumpfileSource(sys.stdin, baton), logpatch, selection)
         elif arguments[0] == "skeleton":
-            skeletonize(DumpfileSource(sys.stdin, baton), selection)
+            skeletonize(DumpfileSource(sys.stdin, baton), selection, arguments[1:])
         elif arguments[0] == "expunge":
-            expunge(DumpfileSource(sys.stdin, baton), selection, arguments)
+            expunge(DumpfileSource(sys.stdin, baton), selection, arguments[1:])
         elif arguments[0] == "renumber":
             renumber(DumpfileSource(sys.stdin, baton))
         elif arguments[0] == "help":

Modified: subversion/branches/verify-keep-going/gen-make.py
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/gen-make.py?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/gen-make.py (original)
+++ subversion/branches/verify-keep-going/gen-make.py Wed Nov 27 11:52:35 2013
@@ -209,11 +209,14 @@ def _usage_exit(err=None):
   print("           Use static openssl")
   print("")
   print("  --vsnet-version=VER")
-  print("           generate for VS.NET version VER (2002, 2003, 2005, 2008, 2010 or 2012)")
+  print("           generate for VS.NET version VER (2002, 2003, 2005, 2008,")
+  print("           2010, 2012 or 2013)")
   print("           [only valid in combination with '-t vcproj']")
   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 +225,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 +266,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 +311,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/verify-keep-going/get-deps.sh
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/get-deps.sh?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/get-deps.sh (original)
+++ subversion/branches/verify-keep-going/get-deps.sh Wed Nov 27 11:52:35 2013
@@ -36,8 +36,8 @@ 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"}
-GTEST_VERSION=${GTEST_VERSION:-"1.6.0"}
-HTTPD_VERSION=${HTTPD_VERSION:-"2.4.3"}
+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}
@@ -46,8 +46,8 @@ 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=gtest-${GTEST_VERSION}
-GTEST_URL=http://googletest.googlecode.com/files/
+GMOCK=gmock-${GMOCK_VERSION}
+GMOCK_URL=https://googlemock.googlecode.com/files/
 
 HTTPD=httpd-${HTTPD_VERSION}
 APR_ICONV=apr-iconv-${APR_ICONV_VERSION}
@@ -67,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
 }
 
@@ -122,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

Modified: subversion/branches/verify-keep-going/notes/ev2-callbacks-template.c
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/notes/ev2-callbacks-template.c?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/notes/ev2-callbacks-template.c (original)
+++ subversion/branches/verify-keep-going/notes/ev2-callbacks-template.c Wed Nov 27 11:52:35 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/verify-keep-going/notes/http-and-webdav/webdav-protocol
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/notes/http-and-webdav/webdav-protocol?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/notes/http-and-webdav/webdav-protocol (original)
+++ subversion/branches/verify-keep-going/notes/http-and-webdav/webdav-protocol Wed Nov 27 11:52:35 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.
 
@@ -354,6 +354,7 @@ Request:
     <S:discover-changed-paths/> (optional)
     <S:strict-node-history/> (optional)
     <S:include-merged-revisions/> (optional)
+    <S:move-behavior>0</S:move-behavior> (optional, see below for values)
     <S:encode-binary-props> (optional)
     <S:revprop>REVPROP</S:revprop>... | <S:all-revprops/> | <S:no-revprops/>
       ('revprop', 'all-revprops', and 'no-revprops' are all optional)
@@ -374,12 +375,21 @@ Response:
       <S:has-children/> (optional)
       <S:added-path( copyfrom-path="PATH" copyfrom-rev="REVNUM">PATH</S:added-path>... (optional)
       <S:replaced-path( copyfrom-path="PATH" copyfrom-rev="REVNUM">PATH</S:replaced-path>... (optional)
+      <S:moved-path( copyfrom-path="PATH" copyfrom-rev="REVNUM">PATH</S:moved-path>... (optional)
+      <S:replaced-by-moved-path( copyfrom-path="PATH" copyfrom-rev="REVNUM">PATH</S:replaced-by-moved-path>... (optional)
       <S:deleted-path>PATH</S:deleted-path>... (optional)
       <S:modified-path>PATH</S:modified-path>... (optional)
     </S:log-item>
     ...multiple log-items for each returned revision...
   </S:log-report>
 
+Move behavior values (see svn_move_behavior_t in svn_types.h):
+
+  0 .. send all moves as adds / replaces (default if not specified)
+  1 .. send moves only when stored as such in the repository
+  2 .. send moves as stored in the repository and also send send
+       suitable adds / replacements as moves
+
 mergeinfo-report
 ----------------
 
@@ -452,4 +462,4 @@ Request:
 
 Response:
 
-  ### TODO ###
\ No newline at end of file
+  ### TODO ###

Modified: subversion/branches/verify-keep-going/notes/knobs
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/notes/knobs?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/notes/knobs (original)
+++ subversion/branches/verify-keep-going/notes/knobs Wed Nov 27 11:52:35 2013
@@ -52,6 +52,7 @@ SVN_FS_FS_DELTIFY_DIRECTORIES
 SVN_FS_FS_DELTIFY_PROPS
 SVN_SQLITE_MIN_VERSION_NUMBER
 SVN_SQLITE_MIN_VERSION
+SVN_SERF_NO_LOGGING
 
 2.3 Debugging Support
 
@@ -68,6 +69,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 +82,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 +398,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 +461,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/verify-keep-going/subversion/bindings/ctypes-python/csvn/txn.py
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/bindings/ctypes-python/csvn/txn.py?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/bindings/ctypes-python/csvn/txn.py (original)
+++ subversion/branches/verify-keep-going/subversion/bindings/ctypes-python/csvn/txn.py Wed Nov 27 11:52:35 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/verify-keep-going/subversion/bindings/cxxhl/include/svncxxhl/_compat.hpp
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/bindings/cxxhl/include/svncxxhl/_compat.hpp?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/bindings/cxxhl/include/svncxxhl/_compat.hpp (original)
+++ subversion/branches/verify-keep-going/subversion/bindings/cxxhl/include/svncxxhl/_compat.hpp Wed Nov 27 11:52:35 2013
@@ -85,6 +85,7 @@ using std::tr1::enable_shared_from_this;
 // ::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 {
@@ -100,4 +101,44 @@ using boost::enable_shared_from_this;
 
 #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/verify-keep-going/subversion/bindings/cxxhl/include/svncxxhl/exception.hpp
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/bindings/cxxhl/include/svncxxhl/exception.hpp?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/bindings/cxxhl/include/svncxxhl/exception.hpp (original)
+++ subversion/branches/verify-keep-going/subversion/bindings/cxxhl/include/svncxxhl/exception.hpp Wed Nov 27 11:52:35 2013
@@ -35,9 +35,6 @@
 
 #include "svncxxhl/_compat.hpp"
 
-// Forward declaration of implementation-specific structure
-struct svn_error_t;
-
 namespace apache {
 namespace subversion {
 namespace cxxhl {
@@ -49,40 +46,95 @@ namespace detail {
 class ErrorDescription;
 } // namespace detail
 
-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);
+
+  InternalError(const InternalError& that) throw();
+  InternalError& operator= (const InternalError& that) throw();
+  virtual ~InternalError() throw();
+
+  /**
+   * Returns the message associated with this exception object.
+   */
+  virtual const char* what() const throw();
 
-  Error(const char* description, int error_code);
-  Error(const char* description, int error_code, shared_ptr nested_error);
+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 the error code associated with the exception.
+   * Returns the error code associated with the top-level error that
+   * caused the exception.
    */
-  virtual int code() const throw() { return m_errno; }
-
-  /**
-   * Returns a shared pointer to the nested exception object, if any.
-   */
-  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.
@@ -91,7 +143,7 @@ public:
 
   /**
    * Returns the complete list of error messages, including those from
-   * nested exceptions.
+   * nested errors.
    */
   virtual MessageList messages() const
     {
@@ -110,29 +162,22 @@ public:
       return compile_messages(true);
     }
 
-public:
-  /** Used internally by the implementation. */
-  static void throw_svn_error(svn_error_t*);
-
 protected:
-  Error(int error_code, detail::ErrorDescription* description) throw();
-
-private:
+  explicit Error(description_ptr description) throw()
+    : InternalError(description)
+    {}
   MessageList 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::ErrorDescription* m_description;
 };
 
+/**
+ * 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::ErrorDescription* description) throw()
-    : Error(error_code, description)
+  explicit Cancelled(description_ptr description) throw()
+    : Error(description)
     {}
 };
 

Modified: subversion/branches/verify-keep-going/subversion/bindings/cxxhl/src/exception.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/bindings/cxxhl/src/exception.cpp?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/bindings/cxxhl/src/exception.cpp (original)
+++ subversion/branches/verify-keep-going/subversion/bindings/cxxhl/src/exception.cpp Wed Nov 27 11:52:35 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"
@@ -46,90 +48,104 @@ namespace detail {
 class ErrorDescription
 {
 public:
-  static ErrorDescription* 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(ErrorDescription));
+      void* memblock = ::operator new(length + sizeof(ErrorDescription));
 
       ErrorDescription* description = new(memblock) ErrorDescription(
-          loc_file, loc_line, trace_link, empty_message);
+          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 ErrorDescription* 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);
     }
 
-  ErrorDescription* reference() throw()
-    {
-      if (this)
-        svn_atomic_inc(&m_refcount);
-      return this;
-    }
-
-  ErrorDescription* dereference() throw()
-    {
-      if (this && 0 == svn_atomic_dec(&m_refcount))
-        {
-          this->~ErrorDescription();
-          ::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:
-  ErrorDescription(const char *loc_file, long loc_line,
+  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)
     {}
 
-  ~ErrorDescription() 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
+//
 
-Error::Error(const char* description, int error_code)
-  : m_errno(error_code),
-    m_description(detail::ErrorDescription::create(description)->reference())
+InternalError::InternalError(const char* description)
+  : m_description(detail::ErrorDescription::create(description, 0))
 {}
 
-Error::Error(const char* description, int error_code,
-             Error::shared_ptr nested_error)
-  : m_errno(error_code),
-    m_nested(nested_error),
-    m_description(detail::ErrorDescription::create(description)->reference())
+InternalError::InternalError(const InternalError& that) throw()
+  : m_description(that.m_description)
 {}
 
+InternalError& InternalError::operator=(const InternalError& that) throw()
+{
+  if (this == &that)
+    return *this;
+
+  // 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->~InternalError();
+  return *new(this) InternalError(that);
+}
+
+InternalError::~InternalError() throw() {}
+
+const char* InternalError::what() const throw()
+{
+  return m_description->what();
+}
+
+InternalError::InternalError(description_ptr description) throw()
+  : m_description(description)
+{}
+
+//
+// Class Error
+//
+
 Error::Error(const Error& that) throw()
-  : m_errno(that.m_errno),
-    m_nested(that.m_nested),
-    m_description(that.m_description->reference())
+  : InternalError(that.m_description)
 {}
 
 Error& Error::operator=(const Error& that) throw()
@@ -144,87 +160,50 @@ Error& Error::operator=(const Error& tha
   return *new(this) Error(that);
 }
 
-Error::~Error() throw()
-{
-  m_description->dereference();
-}
+Error::~Error() throw() {}
 
-const char* Error::what() const throw()
+int Error::code() const throw()
 {
-  return m_description->what();
+  return m_description->code();
 }
 
-Error::Error(int error_code, detail::ErrorDescription* description) throw()
-  : m_errno(error_code),
-    m_description(description)
-{}
-
-void Error::throw_svn_error(svn_error_t* err)
+namespace {
+const char* get_generic_message(apr_status_t error_code,
+                                const APR::Pool& scratch_pool)
 {
-  detail::ErrorDescription* 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.
+  char errorbuf[512];
 
-      shared_ptr nested;
-      shared_ptr* current = &nested;
+  // 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;
 
-      bool cancelled = (err->apr_err == SVN_ERR_CANCELLED);
-      for (svn_error_t* next = err->child; next; next = next->child)
-        {
-          description = detail::ErrorDescription::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;
-          if (next->apr_err == SVN_ERR_CANCELLED)
-            cancelled = true;
-        }
-
-      const int apr_err = err->apr_err;
-      description = detail::ErrorDescription::create(
-          err->message, err->file, err->line,
-          svn_error__is_tracing_link(err));
-      description->reference();
+      // Use fuzzy transliteration instead.
       svn_error_clear(err);
-      if (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::MessageList& ml, bool show_traces,
-                      int error_code, detail::ErrorDescription* descr,
-                      apr_pool_t* pool)
+                      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);
@@ -240,15 +219,13 @@ void handle_one_error(Error::MessageList
       else
         {
 #ifdef SVN_DEBUG
-          if (const char *const symbolic_name =
-              svn_error_symbolic_name(error_code))
-            //if (symbolic_name)
+          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(0, buffer.str()));
+      ml.push_back(Error::Message(error_code, buffer.str(), true));
     }
 
   if (descr->trace())
@@ -256,28 +233,8 @@ void handle_one_error(Error::MessageList
 
   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
 
@@ -285,11 +242,12 @@ Error::MessageList Error::compile_messag
 {
   // Determine the maximum size of the returned list
   MessageList::size_type max_length = 0;
-  for (const Error* err = this; err; err = err->m_nested.get())
+  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
     }
   MessageList ml;
@@ -300,36 +258,74 @@ Error::MessageList Error::compile_messag
   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;
 }
 
+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/verify-keep-going/subversion/bindings/cxxhl/tests/test_exception.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/bindings/cxxhl/tests/test_exception.cpp?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/bindings/cxxhl/tests/test_exception.cpp (original)
+++ subversion/branches/verify-keep-going/subversion/bindings/cxxhl/tests/test_exception.cpp Wed Nov 27 11:52:35 2013
@@ -26,52 +26,16 @@
 #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;
-}
-
-void traceall(const char *message, const SVN::Error& err)
-{
-  typedef SVN::Error::MessageList MessageList;
-  std::cout << message << std::endl;
-  std::cout << "Traced Messages:" << std::endl;
-  MessageList 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);
-}
-
-void tracecheck(svn_error_t* err)
-{
-  std::cout << "C-API handler:" << std::endl;
-  svn_handle_error2(err, stdout, false, "    test_exception");
-  svn_error_clear(err);
-}
-
-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;
-}
+#include <gmock/gmock.h>
 
+namespace {
 svn_error_t* make_error_test_error()
 {
   svn_error_t* err;
@@ -85,67 +49,85 @@ svn_error_t* make_error_test_error()
 }
 } // anonymous namespace
 
-
-bool test_cancel()
+TEST(Exceptions, CatchError)
 {
   try
     {
-      SVN::Error::throw_svn_error(make_cancel_test_error());
-    }
-  catch (const SVN::Cancelled& err)
-    {
-      traceall("Caught: CANCELLED", err);
-      tracecheck(make_cancel_test_error());
-      return true;
+      SVN::detail::checked_call(make_error_test_error());
     }
   catch (const SVN::Error& err)
     {
-      traceall("Caught: ERROR", err);
-      tracecheck(make_cancel_test_error());
-      return false;
-    }
-  catch (...)
-    {
-      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
     }
-  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::throw_svn_error(make_error_test_error());
+      SVN::detail::checked_call(make_cancel_test_error());
     }
   catch (const SVN::Cancelled& err)
     {
-      traceall("Caught: CANCELLED", err);
-      tracecheck(make_error_test_error());
-      return false;
-    }
-  catch (const SVN::Error& err)
-    {
-      traceall("Caught: ERROR", err);
-      tracecheck(make_error_test_error());
-      return true;
-    }
-  catch (...)
-    {
-      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/verify-keep-going/subversion/bindings/javahl/README
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/bindings/javahl/README?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/bindings/javahl/README (original)
+++ subversion/branches/verify-keep-going/subversion/bindings/javahl/README Wed Nov 27 11:52:35 2013
@@ -33,10 +33,9 @@ javahl                build javahl
 install-javahl        install javahl
 check-javahl          run javahl tests
 
-(In order to run check-javahl, you must have already installed JavaHL,
-and you must have specified a path to a JUnit jar file with
---with-junit when running configure; JUnit version 3.8.1 has been
-tested.  JUnit can be downloaded from http://junit.sf.net/ .)
+(In order to run check-javahl, you must have specified a path to a JUnit
+jar file with --with-junit when running configure; JUnit version 3.8.1
+has been tested.  JUnit can be downloaded from http://junit.org/ .)
 
 
 MacOS X:

Modified: subversion/branches/verify-keep-going/subversion/bindings/javahl/native/ClientContext.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/bindings/javahl/native/ClientContext.cpp?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/bindings/javahl/native/ClientContext.cpp (original)
+++ subversion/branches/verify-keep-going/subversion/bindings/javahl/native/ClientContext.cpp Wed Nov 27 11:52:35 2013
@@ -70,12 +70,38 @@ ClientContext::ClientContext(jobject jsv
     m_context->conflict_baton2 = m_jctx;
 
     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()
 {
 }
 
+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()

Modified: subversion/branches/verify-keep-going/subversion/bindings/javahl/native/ClientContext.h
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/bindings/javahl/native/ClientContext.h?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/bindings/javahl/native/ClientContext.h (original)
+++ subversion/branches/verify-keep-going/subversion/bindings/javahl/native/ClientContext.h Wed Nov 27 11:52:35 2013
@@ -64,6 +64,7 @@ class ClientContext : public OperationCo
  public:
   ClientContext(jobject jsvnclient, SVN::Pool &pool);
   virtual ~ClientContext();
+  virtual void setTunnelCallback(jobject jtunnelcb);
 
   svn_client_ctx_t *getContext(CommitMessage *message, SVN::Pool &in_pool);
 };

Modified: subversion/branches/verify-keep-going/subversion/bindings/javahl/native/CommitEditor.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/bindings/javahl/native/CommitEditor.cpp?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/bindings/javahl/native/CommitEditor.cpp (original)
+++ subversion/branches/verify-keep-going/subversion/bindings/javahl/native/CommitEditor.cpp Wed Nov 27 11:52:35 2013
@@ -39,6 +39,10 @@
 #include "private/svn_ra_private.h"
 #include "svn_private_config.h"
 
+#include "EditorCallbacks.hpp"
+#include "jniwrapper/jni_string.hpp"
+#include "jniwrapper/jni_stack.hpp"
+
 CommitEditor*
 CommitEditor::getCppObject(jobject jthis)
 {
@@ -53,14 +57,19 @@ CommitEditor::createInstance(jobject jse
                              jobject jrevprops,
                              jobject jcommit_callback,
                              jobject jlock_tokens,
-                             jboolean jkeep_locks)
+                             jboolean jkeep_locks,
+                             jobject jget_base_cb,
+                             jobject jget_props_cb,
+                             jobject jget_kind_cb)
 {
   RemoteSession* session = RemoteSession::getCppObject(jsession);
   CPPADDR_NULL_PTR(session, 0);
 
   CommitEditor* editor = new CommitEditor(session,
                                           jrevprops, jcommit_callback,
-                                          jlock_tokens, jkeep_locks);
+                                          jlock_tokens, jkeep_locks,
+                                          jget_base_cb, jget_props_cb,
+                                          jget_kind_cb);
   if (JNIUtil::isJavaExceptionThrown())
     {
       delete editor;
@@ -71,11 +80,17 @@ CommitEditor::createInstance(jobject jse
 
 CommitEditor::CommitEditor(RemoteSession* session,
                            jobject jrevprops, jobject jcommit_callback,
-                           jobject jlock_tokens, jboolean jkeep_locks)
+                           jobject jlock_tokens, jboolean jkeep_locks,
+                           jobject jget_base_cb, jobject jget_props_cb,
+                           jobject jget_kind_cb)
+
   : m_valid(false),
     m_callback(jcommit_callback),
     m_session(session),
     m_editor(NULL),
+    m_get_base_cb(Java::Env(), jget_base_cb),
+    m_get_props_cb(Java::Env(), jget_props_cb),
+    m_get_kind_cb(Java::Env(), jget_kind_cb),
     m_callback_session(NULL),
     m_callback_session_url(NULL),
     m_callback_session_uuid(NULL)
@@ -89,7 +104,7 @@ CommitEditor::CommitEditor(RemoteSession
                                &m_callback_session_uuid,
                                pool.getPool()),);
 
-  PropertyTable revprops(jrevprops, true);
+  PropertyTable revprops(jrevprops, true, true);
   if (JNIUtil::isJavaExceptionThrown())
     return;
   LockTokenTable lock_tokens(jlock_tokens);
@@ -100,7 +115,7 @@ CommitEditor::CommitEditor(RemoteSession
   SVN_JNI_ERR(svn_ra__get_commit_ev2(
                   &m_editor,
                   session->m_session,
-                  revprops.hash(subPool, false),
+                  revprops.hash(subPool),
                   m_callback.callback, &m_callback,
                   lock_tokens.hash(subPool, true),
                   bool(jkeep_locks),
@@ -200,57 +215,6 @@ build_checksum(jobject jchecksum, SVN::P
 
   return checksum;
 }
-
-// void
-// build_rotation(const apr_array_header_t **p_relpaths,
-//                const apr_array_header_t **p_revisions,
-//                const Iterator& iter, SVN::Pool& pool)
-// {
-//   *p_relpaths = *p_revisions = NULL;
-//
-//   static jfieldID relpath_fid = 0;
-//   static jfieldID revision_fid = 0;
-//
-//   JNIEnv *env = JNIUtil::getEnv();
-//   if (0 == relpath_fid || 0 == revision_fid)
-//     {
-//       jclass cls = env->FindClass(JAVA_PACKAGE"/ISVNEditor$RotatePair");
-//       if (JNIUtil::isJavaExceptionThrown())
-//         return;
-//
-//       relpath_fid = env->GetFieldID(cls, "relativePath", "Ljava/lang/String;");
-//       if (JNIUtil::isJavaExceptionThrown())
-//         return;
-//       revision_fid = env->GetFieldID(cls, "revision", "J");
-//       if (JNIUtil::isJavaExceptionThrown())
-//         return;
-//     }
-//
-//   apr_pool_t* result_pool = pool.getPool();
-//   apr_array_header_t* relpaths = apr_array_make(
-//       result_pool, 0, sizeof(const char*));
-//   apr_array_header_t* revisions = apr_array_make(
-//       result_pool, 0, sizeof(svn_revnum_t));
-//   while (iter.hasNext())
-//     {
-//       jobject jpair = iter.next();
-//       jobject jrelpath = env->GetObjectField(jpair, relpath_fid);
-//       if (JNIUtil::isJavaExceptionThrown())
-//         return;
-//       jlong jrevision = env->GetLongField(jpair, revision_fid);
-//       if (JNIUtil::isJavaExceptionThrown())
-//         return;
-//       JNIStringHolder relpath((jstring)jrelpath);
-//       if (JNIUtil::isJavaExceptionThrown())
-//         return;
-//
-//       APR_ARRAY_PUSH(relpaths, const char*) = relpath.pstrdup(result_pool);
-//       APR_ARRAY_PUSH(revisions, svn_revnum_t) = svn_revnum_t(jrevision);
-//     }
-//
-//   *p_relpaths = relpaths;
-//   *p_revisions = revisions;
-// }
 } // anonymous namespace
 
 
@@ -264,7 +228,7 @@ void CommitEditor::addDirectory(jstring 
   Iterator children(jchildren);
   if (JNIUtil::isJavaExceptionThrown())
     return;
-  PropertyTable properties(jproperties, true);
+  PropertyTable properties(jproperties, true, true);
   if (JNIUtil::isJavaExceptionThrown())
     return;
 
@@ -276,7 +240,7 @@ void CommitEditor::addDirectory(jstring 
 
   SVN_JNI_ERR(svn_editor_add_directory(m_editor, relpath.c_str(),
                                        build_children(children, subPool),
-                                       properties.hash(subPool, false),
+                                       properties.hash(subPool),
                                        svn_revnum_t(jreplaces_revision)),);
 }
 
@@ -289,7 +253,7 @@ void CommitEditor::addFile(jstring jrelp
   SVN_JNI_ERR(m_session->m_context->checkCancel(m_session->m_context),);
 
   InputStream contents(jcontents);
-  PropertyTable properties(jproperties, true);
+  PropertyTable properties(jproperties, true, true);
   if (JNIUtil::isJavaExceptionThrown())
     return;
 
@@ -304,7 +268,7 @@ void CommitEditor::addFile(jstring jrelp
     return;
   SVN_JNI_ERR(svn_editor_add_file(m_editor, relpath.c_str(),
                                   &checksum, contents.getStream(subPool),
-                                  properties.hash(subPool, false),
+                                  properties.hash(subPool),
                                   svn_revnum_t(jreplaces_revision)),);
 }
 
@@ -341,7 +305,7 @@ void CommitEditor::alterDirectory(jstrin
   Iterator children(jchildren);
   if (JNIUtil::isJavaExceptionThrown())
     return;
-  PropertyTable properties(jproperties, true);
+  PropertyTable properties(jproperties, true, false);
   if (JNIUtil::isJavaExceptionThrown())
     return;
 
@@ -354,7 +318,7 @@ void CommitEditor::alterDirectory(jstrin
   SVN_JNI_ERR(svn_editor_alter_directory(
                   m_editor, relpath.c_str(), svn_revnum_t(jrevision),
                   (jchildren ? build_children(children, subPool) : NULL),
-                  properties.hash(subPool, true)),);
+                  properties.hash(subPool)),);
 }
 
 void CommitEditor::alterFile(jstring jrelpath, jlong jrevision,
@@ -365,7 +329,7 @@ void CommitEditor::alterFile(jstring jre
   SVN_JNI_ERR(m_session->m_context->checkCancel(m_session->m_context),);
 
   InputStream contents(jcontents);
-  PropertyTable properties(jproperties, true);
+  PropertyTable properties(jproperties, true, false);
   if (JNIUtil::isJavaExceptionThrown())
     return;
 
@@ -382,7 +346,7 @@ void CommitEditor::alterFile(jstring jre
                   m_editor, relpath.c_str(), svn_revnum_t(jrevision),
                   (jcontents ? &checksum : NULL),
                   (jcontents ? contents.getStream(subPool) : NULL),
-                  properties.hash(subPool, true)),);
+                  properties.hash(subPool)),);
 }
 
 void CommitEditor::alterSymlink(jstring jrelpath, jlong jrevision,
@@ -452,21 +416,6 @@ void CommitEditor::move(jstring jsrc_rel
                               svn_revnum_t(jreplaces_revision)),);
 }
 
-// void CommitEditor::rotate(jobject jelements)
-// {
-//   if (!m_valid) { throw_editor_inactive(); return; }
-//   SVN_JNI_ERR(m_session->m_context->checkCancel(m_session->m_context),);
-//
-//   SVN::Pool subPool(pool);
-//   const apr_array_header_t* relpaths;
-//   const apr_array_header_t* revisions;
-//   build_rotation(&relpaths, &revisions, jelements, subPool);
-//   if (JNIUtil::isJavaExceptionThrown())
-//     return;
-//
-//   SVN_JNI_ERR(svn_editor_rotate(m_editor, relpaths, revisions),);
-// }
-
 void CommitEditor::complete()
 {
   if (!m_valid) { throw_editor_inactive(); return; }
@@ -516,6 +465,44 @@ svn_error_t* open_callback_session(svn_r
     }
   return SVN_NO_ERROR;
 }
+
+void
+invoke_get_base_cb(svn_stream_t **contents, svn_revnum_t *revision,
+                   Java::Env env, jobject get_base_cb,
+                   const char *repos_relpath, apr_pool_t *result_pool)
+{
+  Java::String relpath(env, repos_relpath);
+  jobject jrv =
+    JavaHL::ProvideBaseCallback(env, get_base_cb)(relpath.get());
+  JavaHL::ProvideBaseCallback::ReturnValue rv(env, jrv);
+  *contents = rv.get_global_stream(result_pool);
+  *revision = svn_revnum_t(rv.get_revision());
+}
+
+void
+invoke_get_props_cb(apr_hash_t **props, svn_revnum_t *revision,
+                   Java::Env env, jobject get_props_cb,
+                   const char *repos_relpath, apr_pool_t *result_pool)
+{
+  Java::String relpath(env, repos_relpath);
+  jobject jrv =
+    JavaHL::ProvidePropsCallback(env, get_props_cb)(relpath.get());
+  JavaHL::ProvidePropsCallback::ReturnValue rv(env, jrv);
+  *props = rv.get_property_hash(result_pool);
+  *revision = svn_revnum_t(rv.get_revision());
+}
+
+void
+invoke_get_kind_cb(svn_node_kind_t *kind,
+                   Java::Env env, jobject get_kind_cb,
+                   const char *repos_relpath, svn_revnum_t revision)
+{
+  Java::String relpath(env, repos_relpath);
+  jobject jnode_kind =
+    JavaHL::GetNodeKindCallback(env, get_kind_cb)(relpath.get(),
+                                                  jlong(revision));
+  *kind = EnumMapper::toNodeKind(jnode_kind);
+}
 } // anonymous namespace
 
 
@@ -527,8 +514,21 @@ CommitEditor::provide_base_cb(svn_stream
                               apr_pool_t *result_pool,
                               apr_pool_t *scratch_pool)
 {
-  *contents = NULL;
-  *revision = NULL;
+  CommitEditor* editor = static_cast<CommitEditor*>(baton);
+  if (editor->m_get_base_cb.get())
+    {
+      const Java::Env env;
+      SVN_JAVAHL_CATCH(env, SVN_ERR_BASE,
+                       invoke_get_base_cb(contents, revision, env,
+                                          editor->m_get_base_cb.get(),
+                                          repos_relpath,
+                                          result_pool));
+    }
+  else
+    {
+      *contents = NULL;
+      *revision = SVN_INVALID_REVNUM;
+    }
   return SVN_NO_ERROR;
 }
 
@@ -541,33 +541,49 @@ CommitEditor::provide_props_cb(apr_hash_
                                apr_pool_t *scratch_pool)
 {
   CommitEditor* editor = static_cast<CommitEditor*>(baton);
-  SVN_ERR(open_callback_session(editor->m_callback_session,
-                                editor->m_callback_session_url,
-                                editor->m_callback_session_uuid,
-                                editor->m_session->m_context,
-                                editor->pool));
-
-  svn_node_kind_t kind = svn_node_unknown;
-  SVN_ERR(svn_ra_check_path(editor->m_callback_session,
-                            repos_relpath, SVN_INVALID_REVNUM, &kind,
-                            scratch_pool));
-
-  // FIXME: Getting properties from the youngest revision is in fact
-  // not such a bright idea, as the path may have been moved or
-  // deleted in the path.
-  if (kind == svn_node_file)
-    return svn_ra_get_file(editor->m_callback_session,
-                           repos_relpath, SVN_INVALID_REVNUM,
-                           NULL, revision, props, scratch_pool);
-  else if (kind == svn_node_dir)
-    return svn_ra_get_dir2(editor->m_callback_session, NULL, revision, props,
-                           repos_relpath, SVN_INVALID_REVNUM, 0, scratch_pool);
+  if (editor->m_get_props_cb.get())
+    {
+      const Java::Env env;
+      SVN_JAVAHL_CATCH(env, SVN_ERR_BASE,
+                       invoke_get_props_cb(props, revision, env,
+                                           editor->m_get_props_cb.get(),
+                                           repos_relpath,
+                                           result_pool));
+    }
   else
-    return svn_error_createf(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
-                             _("Expected node kind '%s' or '%s' but got '%s'"),
-                             svn_node_kind_to_word(svn_node_file),
-                             svn_node_kind_to_word(svn_node_dir),
-                             svn_node_kind_to_word(kind));
+    {
+      SVN_ERR(open_callback_session(editor->m_callback_session,
+                                    editor->m_callback_session_url,
+                                    editor->m_callback_session_uuid,
+                                    editor->m_session->m_context,
+                                    editor->pool));
+
+      svn_node_kind_t kind = svn_node_unknown;
+      SVN_ERR(svn_ra_check_path(editor->m_callback_session,
+                                repos_relpath, SVN_INVALID_REVNUM, &kind,
+                                scratch_pool));
+
+      // FIXME: Getting properties from the youngest revision is in
+      // fact not such a bright idea, as the path may have been moved
+      // or deleted in the repository. On the other hand, if that
+      // happens, the commit would fail due to a conflict anyway.
+      if (kind == svn_node_file)
+        return svn_ra_get_file(editor->m_callback_session,
+                               repos_relpath, SVN_INVALID_REVNUM,
+                               NULL, revision, props, scratch_pool);
+      else if (kind == svn_node_dir)
+        return svn_ra_get_dir2(editor->m_callback_session, NULL, revision,
+                               props, repos_relpath, SVN_INVALID_REVNUM, 0,
+                               scratch_pool);
+      else
+        return svn_error_createf(
+            SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
+            _("Expected node kind '%s' or '%s' but got '%s'"),
+            svn_node_kind_to_word(svn_node_file),
+            svn_node_kind_to_word(svn_node_dir),
+            svn_node_kind_to_word(kind));
+    }
+  return SVN_NO_ERROR;
 }
 
 svn_error_t*
@@ -577,13 +593,26 @@ CommitEditor::get_copysrc_kind_cb(svn_no
                                   apr_pool_t *scratch_pool)
 {
   CommitEditor* editor = static_cast<CommitEditor*>(baton);
-  SVN_ERR(open_callback_session(editor->m_callback_session,
-                                editor->m_callback_session_url,
-                                editor->m_callback_session_uuid,
-                                editor->m_session->m_context,
-                                editor->pool));
-
-  return svn_ra_check_path(editor->m_callback_session,
-                           repos_relpath, src_revision, kind,
-                           scratch_pool);
+  if (editor->m_get_kind_cb.get())
+    {
+      const Java::Env env;
+      SVN_JAVAHL_CATCH(env, SVN_ERR_BASE,
+                       invoke_get_kind_cb(kind, env,
+                                          editor->m_get_kind_cb.get(),
+                                          repos_relpath,
+                                          src_revision));
+    }
+  else
+    {
+      SVN_ERR(open_callback_session(editor->m_callback_session,
+                                    editor->m_callback_session_url,
+                                    editor->m_callback_session_uuid,
+                                    editor->m_session->m_context,
+                                    editor->pool));
+
+      return svn_ra_check_path(editor->m_callback_session,
+                               repos_relpath, src_revision, kind,
+                               scratch_pool);
+    }
+  return SVN_NO_ERROR;
 }

Propchange: subversion/branches/verify-keep-going/subversion/bindings/javahl/native/CommitEditor.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: subversion/branches/verify-keep-going/subversion/bindings/javahl/native/CommitEditor.h
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/bindings/javahl/native/CommitEditor.h?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/bindings/javahl/native/CommitEditor.h (original)
+++ subversion/branches/verify-keep-going/subversion/bindings/javahl/native/CommitEditor.h Wed Nov 27 11:52:35 2013
@@ -36,6 +36,8 @@
 #include "SVNBase.h"
 #include "CommitCallback.h"
 
+#include "jniwrapper/jni_globalref.hpp"
+
 class RemoteSession;
 
 // Forward-declare the currently private EV2 editor struct.
@@ -52,7 +54,10 @@ public:
                               jobject jrevprops,
                               jobject jcommit_callback,
                               jobject jlock_tokens,
-                              jboolean jkeep_locks);
+                              jboolean jkeep_locks,
+                              jobject jget_base_cb,
+                              jobject jget_props_cb,
+                              jobject jget_kind_cb);
   virtual ~CommitEditor();
 
   virtual void dispose(jobject jthis);
@@ -81,14 +86,15 @@ public:
             jstring jdst_relpath, jlong jreplaces_revision);
   void move(jstring jsrc_relpath, jlong jsrc_revision,
             jstring jdst_relpath, jlong jreplaces_revision);
-  // void rotate(jobject jelements);
   void complete();
   void abort();
 
 private:
   CommitEditor(RemoteSession* session,
                jobject jrevprops, jobject jcommit_callback,
-               jobject jlock_tokens, jboolean jkeep_locks);
+               jobject jlock_tokens, jboolean jkeep_locks,
+               jobject jget_base_cb, jobject jget_props_cb,
+               jobject jget_kind_cb);
 
   // This is our private callbacks for the commit editor.
   static svn_error_t* provide_base_cb(svn_stream_t **contents,
@@ -113,6 +119,10 @@ private:
   RemoteSession* m_session;
   svn_editor_t* m_editor;
 
+  Java::GlobalObject m_get_base_cb;
+  Java::GlobalObject m_get_props_cb;
+  Java::GlobalObject m_get_kind_cb;
+
   // Temporary, while EV2 shims are in place
   svn_ra_session_t* m_callback_session;
   const char* m_callback_session_url;

Propchange: subversion/branches/verify-keep-going/subversion/bindings/javahl/native/CommitEditor.h
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: subversion/branches/verify-keep-going/subversion/bindings/javahl/native/CreateJ.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/bindings/javahl/native/CreateJ.cpp?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/bindings/javahl/native/CreateJ.cpp (original)
+++ subversion/branches/verify-keep-going/subversion/bindings/javahl/native/CreateJ.cpp Wed Nov 27 11:52:35 2013
@@ -30,6 +30,7 @@
 #include "JNIStringHolder.h"
 #include "EnumMapper.h"
 #include "RevisionRange.h"
+#include "RevisionRangeList.h"
 #include "CreateJ.h"
 #include "../include/org_apache_subversion_javahl_types_Revision.h"
 #include "../include/org_apache_subversion_javahl_CommitItemStateFlags.h"
@@ -777,12 +778,13 @@ CreateJ::ClientNotifyInformation(const s
                                "L"JAVA_PACKAGE"/types/NodeKind;"
                                "Ljava/lang/String;"
                                "L"JAVA_PACKAGE"/types/Lock;"
-                               "Ljava/lang/String;"
+                               "Ljava/lang/String;Ljava/util/List;"
                                "L"JAVA_PACKAGE"/ClientNotifyInformation$Status;"
                                "L"JAVA_PACKAGE"/ClientNotifyInformation$Status;"
                                "L"JAVA_PACKAGE"/ClientNotifyInformation$LockStatus;"
                                "JLjava/lang/String;"
                                "L"JAVA_PACKAGE"/types/RevisionRange;"
+                               "Ljava/lang/String;"
                                "Ljava/lang/String;Ljava/lang/String;"
                                "Ljava/util/Map;JJJJJJI)V");
       if (JNIUtil::isJavaExceptionThrown() || midCT == 0)
@@ -810,7 +812,9 @@ CreateJ::ClientNotifyInformation(const s
   if (JNIUtil::isJavaExceptionThrown())
     POP_AND_RETURN_NULL;
 
-  jstring jErr = JNIUtil::makeSVNErrorMessage(wcNotify->err);
+  jstring jErr;
+  jobject jErrStack;
+  JNIUtil::makeSVNErrorMessage(wcNotify->err, &jErr, &jErrStack);
   if (JNIUtil::isJavaExceptionThrown())
     POP_AND_RETURN_NULL;
 
@@ -838,6 +842,10 @@ CreateJ::ClientNotifyInformation(const s
         POP_AND_RETURN_NULL;
     }
 
+  jstring jUrl = JNIUtil::makeJString(wcNotify->url);
+  if (JNIUtil::isJavaExceptionThrown())
+    POP_AND_RETURN_NULL;
+
   jstring jpathPrefix = JNIUtil::makeJString(wcNotify->path_prefix);
   if (JNIUtil::isJavaExceptionThrown())
     POP_AND_RETURN_NULL;
@@ -857,7 +865,7 @@ CreateJ::ClientNotifyInformation(const s
   jlong jhunkModifiedLength = wcNotify->hunk_modified_length;
   jlong jhunkMatchedLine = wcNotify->hunk_matched_line;
   jint jhunkFuzz = static_cast<jint>(wcNotify->hunk_fuzz);
-  if (jhunkFuzz != wcNotify->hunk_fuzz)
+  if (jhunkFuzz < 0 || jhunkFuzz != wcNotify->hunk_fuzz)
     {
       env->ThrowNew(env->FindClass("java.lang.ArithmeticException"),
                     "Overflow converting C svn_linenum_t to Java int");
@@ -866,10 +874,10 @@ CreateJ::ClientNotifyInformation(const s
 
   // call the Java method
   jobject jInfo = env->NewObject(clazz, midCT, jPath, jAction,
-                                 jKind, jMimeType, jLock, jErr,
+                                 jKind, jMimeType, jLock, jErr, jErrStack,
                                  jContentState, jPropState, jLockState,
                                  (jlong) wcNotify->revision, jChangelistName,
-                                 jMergeRange, jpathPrefix, jpropName,
+                                 jMergeRange, jUrl, jpathPrefix, jpropName,
                                  jrevProps, joldRevision,
                                  jhunkOriginalStart, jhunkOriginalLength,
                                  jhunkModifiedStart, jhunkModifiedLength,
@@ -1073,82 +1081,129 @@ CreateJ::CommitInfo(const svn_commit_inf
 }
 
 jobject
-CreateJ::RevisionRangeList(svn_rangelist_t *ranges)
+CreateJ::StringSet(const apr_array_header_t *strings)
 {
-  JNIEnv *env = JNIUtil::getEnv();
-
-  // Create a local frame for our references
-  env->PushLocalFrame(LOCAL_FRAME_SIZE);
-  if (JNIUtil::isJavaExceptionThrown())
-    return NULL;
-
-  jclass clazz = env->FindClass("java/util/ArrayList");
-  if (JNIUtil::isJavaExceptionThrown())
-    POP_AND_RETURN_NULL;
+  std::vector<jobject> jstrs;
 
-  static jmethodID init_mid = 0;
-  if (init_mid == 0)
+  for (int i = 0; i < strings->nelts; ++i)
     {
-      init_mid = env->GetMethodID(clazz, "<init>", "()V");
+      const char *str = APR_ARRAY_IDX(strings, i, const char *);
+      jstring jstr = JNIUtil::makeJString(str);
       if (JNIUtil::isJavaExceptionThrown())
-        POP_AND_RETURN_NULL;
-    }
+        return NULL;
 
-  static jmethodID add_mid = 0;
-  if (add_mid == 0)
-    {
-      add_mid = env->GetMethodID(clazz, "add", "(Ljava/lang/Object;)Z");
-      if (JNIUtil::isJavaExceptionThrown())
-        POP_AND_RETURN_NULL;
+      jstrs.push_back(jstr);
     }
 
-  jobject jranges = env->NewObject(clazz, init_mid);
+  return CreateJ::Set(jstrs);
+}
 
-  for (int i = 0; i < ranges->nelts; ++i)
-    {
-      // Convert svn_merge_range_t *'s to Java RevisionRange objects.
-      svn_merge_range_t *range =
-          APR_ARRAY_IDX(ranges, i, svn_merge_range_t *);
+namespace {
+void fill_property_map(jobject map,
+                       apr_hash_t* prop_hash, apr_array_header_t* prop_diffs,
+                       apr_pool_t* scratch_pool, jmethodID put_mid)
+{
+  SVN_ERR_ASSERT_NO_RETURN(!prop_hash != !prop_diffs
+                           || !prop_hash && !prop_diffs);
 
-      jobject jrange = RevisionRange::makeJRevisionRange(range);
-      if (JNIUtil::isJavaExceptionThrown())
-        POP_AND_RETURN_NULL;
+  if (!map || (prop_hash == NULL && prop_diffs == NULL))
+    return;
 
-      env->CallBooleanMethod(jranges, add_mid, jrange);
-      if (JNIUtil::isJavaExceptionThrown())
-        POP_AND_RETURN_NULL;
+  JNIEnv *env = JNIUtil::getEnv();
+
+  // Create a local frame for our references
+  env->PushLocalFrame(LOCAL_FRAME_SIZE);
+  if (JNIUtil::isJavaExceptionThrown())
+    return;
 
-      env->DeleteLocalRef(jrange);
+  // The caller may not know the concrete class of the map, so
+  // determine the "put" method identifier here.
+  if (put_mid == 0)
+    {
+      put_mid = env->GetMethodID(env->GetObjectClass(map), "put",
+                                 "(Ljava/lang/Object;Ljava/lang/Object;)"
+                                 "Ljava/lang/Object;");
+      if (JNIUtil::isJavaExceptionThrown())
+        POP_AND_RETURN_NOTHING();
     }
 
-  return env->PopLocalFrame(jranges);
-}
+  struct body
+  {
+    void operator()(const char* key, const svn_string_t* val)
+      {
+        jstring jpropName = JNIUtil::makeJString(key);
+        if (JNIUtil::isJavaExceptionThrown())
+          return;
+
+        jbyteArray jpropVal = (!val ? NULL
+                               : JNIUtil::makeJByteArray(val));
+        if (JNIUtil::isJavaExceptionThrown())
+          return;
+
+        m_env->CallObjectMethod(m_map, m_put_mid, jpropName, jpropVal);
+        if (JNIUtil::isJavaExceptionThrown())
+          return;
+
+        m_env->DeleteLocalRef(jpropName);
+        m_env->DeleteLocalRef(jpropVal);
+      }
+
+    JNIEnv*& m_env;
+    jmethodID& m_put_mid;
+    jobject& m_map;
+
+    body(JNIEnv*& xenv, jmethodID& xput_mid, jobject& xmap)
+      : m_env(xenv), m_put_mid(xput_mid), m_map(xmap)
+      {}
+  } loop_body(env, put_mid, map);
+
+  if (prop_hash)
+    {
+      if (!scratch_pool)
+        scratch_pool = apr_hash_pool_get(prop_hash);
+
+      apr_hash_index_t *hi;
+      for (hi = apr_hash_first(scratch_pool, prop_hash);
+           hi; hi = apr_hash_next(hi))
+        {
+          const char* key;
+          svn_string_t* val;
 
-jobject
-CreateJ::StringSet(const apr_array_header_t *strings)
-{
-  std::vector<jobject> jstrs;
+          const void* v_key;
+          void* v_val;
 
-  for (int i = 0; i < strings->nelts; ++i)
-    {
-      const char *str = APR_ARRAY_IDX(strings, i, const char *);
-      jstring jstr = JNIUtil::makeJString(str);
-      if (JNIUtil::isJavaExceptionThrown())
-        return NULL;
+          apr_hash_this(hi, &v_key, NULL, &v_val);
+          key = static_cast<const char*>(v_key);
+          val = static_cast<svn_string_t*>(v_val);
 
-      jstrs.push_back(jstr);
+          loop_body(key, val);
+          if (JNIUtil::isJavaExceptionThrown())
+            POP_AND_RETURN_NOTHING();
+        }
+    }
+  else
+    {
+      for (int i = 0; i < prop_diffs->nelts; ++i)
+        {
+          svn_prop_t* prop = APR_ARRAY_IDX(prop_diffs, i, svn_prop_t*);
+          loop_body(prop->name, prop->value);
+          if (JNIUtil::isJavaExceptionThrown())
+            POP_AND_RETURN_NOTHING();
+        }
     }
-
-  return CreateJ::Set(jstrs);
 }
 
-jobject CreateJ::PropertyMap(apr_hash_t *prop_hash, apr_pool_t* scratch_pool)
+jobject property_map(apr_hash_t *prop_hash, apr_array_header_t* prop_diffs,
+                     apr_pool_t* scratch_pool)
 {
-  JNIEnv *env = JNIUtil::getEnv();
+  SVN_ERR_ASSERT_NO_RETURN(!prop_hash != !prop_diffs
+                           || !prop_hash && !prop_diffs);
 
-  if (prop_hash == NULL)
+  if (prop_hash == NULL && prop_diffs == NULL)
     return NULL;
 
+  JNIEnv *env = JNIUtil::getEnv();
+
   // Create a local frame for our references
   env->PushLocalFrame(LOCAL_FRAME_SIZE);
   if (JNIUtil::isJavaExceptionThrown())
@@ -1180,69 +1235,35 @@ jobject CreateJ::PropertyMap(apr_hash_t 
   if (JNIUtil::isJavaExceptionThrown())
     POP_AND_RETURN_NULL;
 
-  FillPropertyMap(map, prop_hash, scratch_pool, put_mid);
+  fill_property_map(map, prop_hash, prop_diffs, scratch_pool, put_mid);
   if (JNIUtil::isJavaExceptionThrown())
     POP_AND_RETURN_NULL;
 
   return env->PopLocalFrame(map);
 }
+} // anonymous namespace
 
-void CreateJ::FillPropertyMap(jobject map, apr_hash_t* prop_hash,
-                              apr_pool_t* scratch_pool, jmethodID put_mid)
+jobject CreateJ::PropertyMap(apr_hash_t *prop_hash, apr_pool_t* scratch_pool)
 {
-  JNIEnv *env = JNIUtil::getEnv();
-
-  if (!map || !prop_hash)
-    return;
-
-  // Create a local frame for our references
-  env->PushLocalFrame(LOCAL_FRAME_SIZE);
-  if (JNIUtil::isJavaExceptionThrown())
-    return;
-
-  // The caller may not know the concrete class of the map, so
-  // determine the "put" method identifier here.
-  if (put_mid == 0)
-    {
-      put_mid = env->GetMethodID(env->GetObjectClass(map), "put",
-                                 "(Ljava/lang/Object;Ljava/lang/Object;)"
-                                 "Ljava/lang/Object;");
-      if (JNIUtil::isJavaExceptionThrown())
-        POP_AND_RETURN_NOTHING();
-    }
-
-  if (!scratch_pool)
-    scratch_pool = apr_hash_pool_get(prop_hash);
-
-  apr_hash_index_t *hi;
-  for (hi = apr_hash_first(scratch_pool, prop_hash);
-       hi; hi = apr_hash_next(hi))
-    {
-      const char *key;
-      svn_string_t *val;
-
-      const void *v_key;
-      void *v_val;
-
-      apr_hash_this(hi, &v_key, NULL, &v_val);
-      key = static_cast<const char*>(v_key);
-      val = static_cast<svn_string_t*>(v_val);
-
-      jstring jpropName = JNIUtil::makeJString(key);
-      if (JNIUtil::isJavaExceptionThrown())
-        POP_AND_RETURN_NOTHING();
+  return property_map(prop_hash, NULL, scratch_pool);
+}
 
-      jbyteArray jpropVal = JNIUtil::makeJByteArray(val);
-      if (JNIUtil::isJavaExceptionThrown())
-        POP_AND_RETURN_NOTHING();
+jobject CreateJ::PropertyMap(apr_array_header_t* prop_diffs,
+                             apr_pool_t* scratch_pool)
+{
+  return property_map(NULL, prop_diffs, scratch_pool);
+}
 
-      env->CallObjectMethod(map, put_mid, jpropName, jpropVal);
-      if (JNIUtil::isJavaExceptionThrown())
-        POP_AND_RETURN_NOTHING();
+void CreateJ::FillPropertyMap(jobject map, apr_hash_t* prop_hash,
+                              apr_pool_t* scratch_pool, jmethodID put_mid)
+{
+  fill_property_map(map, prop_hash, NULL, scratch_pool, put_mid);
+}
 
-      env->DeleteLocalRef(jpropName);
-      env->DeleteLocalRef(jpropVal);
-    }
+void CreateJ::FillPropertyMap(jobject map, apr_array_header_t* prop_diffs,
+                              apr_pool_t* scratch_pool, jmethodID put_mid)
+{
+  fill_property_map(map, NULL, prop_diffs, scratch_pool, put_mid);
 }
 
 jobject CreateJ::InheritedProps(apr_array_header_t *iprops)
@@ -1370,7 +1391,7 @@ jobject CreateJ::Mergeinfo(svn_mergeinfo
       jstring jpath =
         JNIUtil::makeJString(static_cast<const char*>(path));
       jobject jranges =
-        RevisionRangeList(static_cast<svn_rangelist_t*>(val));
+        RevisionRangeList(static_cast<svn_rangelist_t*>(val)).toList();
 
       env->CallVoidMethod(jmergeinfo, addRevisions, jpath, jranges);
 

Modified: subversion/branches/verify-keep-going/subversion/bindings/javahl/native/CreateJ.h
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/bindings/javahl/native/CreateJ.h?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/bindings/javahl/native/CreateJ.h (original)
+++ subversion/branches/verify-keep-going/subversion/bindings/javahl/native/CreateJ.h Wed Nov 27 11:52:35 2013
@@ -82,19 +82,24 @@ class CreateJ
   CommitInfo(const svn_commit_info_t *info);
 
   static jobject
-  RevisionRangeList(svn_rangelist_t *ranges);
-
-  static jobject
   StringSet(const apr_array_header_t *strings);
 
   static jobject
   PropertyMap(apr_hash_t *prop_hash, apr_pool_t* scratch_pool = NULL);
 
+  static jobject
+  PropertyMap(apr_array_header_t* prop_diffs, apr_pool_t* scratch_pool = NULL);
+
   static void
   FillPropertyMap(jobject map, apr_hash_t* prop_hash,
                   apr_pool_t* scratch_pool,
                   jmethodID put_method_id = 0);
 
+  static void
+  FillPropertyMap(jobject map, apr_array_header_t* prop_diffs,
+                  apr_pool_t* scratch_pool,
+                  jmethodID put_method_id = 0);
+
   static jobject
   InheritedProps(apr_array_header_t *inherited_props);
 

Modified: subversion/branches/verify-keep-going/subversion/bindings/javahl/native/EditorProxy.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/bindings/javahl/native/EditorProxy.cpp?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/bindings/javahl/native/EditorProxy.cpp (original)
+++ subversion/branches/verify-keep-going/subversion/bindings/javahl/native/EditorProxy.cpp Wed Nov 27 11:52:35 2013
@@ -55,7 +55,7 @@ EditorProxy::EditorProxy(jobject jeditor
   static const svn_editor_cb_many_t editor_many_cb = {
     cb_add_directory, cb_add_file, cb_add_symlink, cb_add_absent,
     cb_alter_directory, cb_alter_file, cb_alter_symlink,
-    cb_delete, cb_copy, cb_move, cb_rotate,
+    cb_delete, cb_copy, cb_move,
     cb_complete, cb_abort
   };
 
@@ -473,15 +473,6 @@ EditorProxy::cb_move(void *baton,
 }
 
 svn_error_t*
-EditorProxy::cb_rotate(void*,
-                       const apr_array_header_t*,
-                       const apr_array_header_t*,
-                       apr_pool_t*)
-{
-  return svn_error_create(APR_ENOTIMPL, NULL, "EditorProxy::cb_rotate");
-}
-
-svn_error_t*
 EditorProxy::cb_complete(void *baton, apr_pool_t *scratch_pool)
 {
   //DEBUG:fprintf(stderr, "  (n) EditorProxy::cb_complete()\n");

Propchange: subversion/branches/verify-keep-going/subversion/bindings/javahl/native/EditorProxy.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: subversion/branches/verify-keep-going/subversion/bindings/javahl/native/EditorProxy.h
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/bindings/javahl/native/EditorProxy.h?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/bindings/javahl/native/EditorProxy.h (original)
+++ subversion/branches/verify-keep-going/subversion/bindings/javahl/native/EditorProxy.h Wed Nov 27 11:52:35 2013
@@ -129,10 +129,6 @@ private:
                               const char *dst_relpath,
                               svn_revnum_t replaces_rev,
                               apr_pool_t *scratch_pool);
-  static svn_error_t* cb_rotate(void *baton,
-                                const apr_array_header_t *relpaths,
-                                const apr_array_header_t *revisions,
-                                apr_pool_t *scratch_pool);
   static svn_error_t* cb_complete(void *baton,
                                   apr_pool_t *scratch_pool);
   static svn_error_t* cb_abort(void *baton,

Propchange: subversion/branches/verify-keep-going/subversion/bindings/javahl/native/EditorProxy.h
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: subversion/branches/verify-keep-going/subversion/bindings/javahl/native/InfoCallback.h
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/bindings/javahl/native/InfoCallback.h?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/bindings/javahl/native/InfoCallback.h (original)
+++ subversion/branches/verify-keep-going/subversion/bindings/javahl/native/InfoCallback.h Wed Nov 27 11:52:35 2013
@@ -30,8 +30,6 @@
 #include <jni.h>
 #include "svn_client.h"
 
-struct info_entry;
-
 /**
  * This class holds a Java callback object, which will receive every line of
  * the file for which the callback information is requested.

Propchange: subversion/branches/verify-keep-going/subversion/bindings/javahl/native/Iterator.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: subversion/branches/verify-keep-going/subversion/bindings/javahl/native/Iterator.h
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: subversion/branches/verify-keep-going/subversion/bindings/javahl/native/JNIByteArray.cpp
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/bindings/javahl/native/JNIByteArray.cpp?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/bindings/javahl/native/JNIByteArray.cpp (original)
+++ subversion/branches/verify-keep-going/subversion/bindings/javahl/native/JNIByteArray.cpp Wed Nov 27 11:52:35 2013
@@ -32,30 +32,24 @@
  * @param flag that the underlying byte array reference should be deleted at
  *        destruction
  */
-JNIByteArray::JNIByteArray(jbyteArray jba, bool deleteByteArray)
-{
-  m_array = jba;
-  m_deleteByteArray = deleteByteArray;
-  if (jba != NULL)
-    {
-      // Get the bytes.
-      JNIEnv *env = JNIUtil::getEnv();
-      m_data = env->GetByteArrayElements(jba, NULL);
-    }
-  else
-    {
-      m_data = NULL;
-    }
-}
+JNIByteArray::JNIByteArray(jbyteArray jba,
+                           bool deleteByteArray,
+                           bool abortOnRelease)
+  : m_array(jba),
+    m_data(!jba ? NULL
+           : JNIUtil::getEnv()->GetByteArrayElements(jba, NULL)),
+    m_deleteByteArray(deleteByteArray),
+    m_abortOnRelease(abortOnRelease)
+{}
 
 JNIByteArray::~JNIByteArray()
 {
   if (m_array != NULL)
     {
       // Release the bytes
-      JNIUtil::getEnv()->ReleaseByteArrayElements(m_array,
-                                                  m_data,
-                                                  JNI_ABORT);
+      JNIUtil::getEnv()->ReleaseByteArrayElements(
+          m_array, m_data,
+          (m_abortOnRelease ? JNI_ABORT: JNI_COMMIT));
       if (m_deleteByteArray)
         // And if needed the byte array.
         JNIUtil::getEnv()->DeleteLocalRef(m_array);

Modified: subversion/branches/verify-keep-going/subversion/bindings/javahl/native/JNIByteArray.h
URL: http://svn.apache.org/viewvc/subversion/branches/verify-keep-going/subversion/bindings/javahl/native/JNIByteArray.h?rev=1546002&r1=1546001&r2=1546002&view=diff
==============================================================================
--- subversion/branches/verify-keep-going/subversion/bindings/javahl/native/JNIByteArray.h (original)
+++ subversion/branches/verify-keep-going/subversion/bindings/javahl/native/JNIByteArray.h Wed Nov 27 11:52:35 2013
@@ -51,11 +51,18 @@ class JNIByteArray
    * at destruction.
    */
   bool m_deleteByteArray;
+
+  /**
+   * False if changes to the array should be committed to the Java VM.
+   */
+  bool m_abortOnRelease;
  public:
   bool isNull() const;
   const signed char *getBytes() const;
   int getLength();
-  JNIByteArray(jbyteArray jba, bool deleteByteArray = false);
+  JNIByteArray(jbyteArray jba,
+               bool deleteByteArray = false,
+               bool abortOnRelease = true);
   ~JNIByteArray();
 };