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 2015/08/31 02:00:09 UTC

svn commit: r1700180 - in /subversion/trunk/subversion: include/svn_repos.h libsvn_repos/load.c tests/cmdline/svnadmin_tests.py

Author: stefan2
Date: Mon Aug 31 00:00:09 2015
New Revision: 1700180

URL: http://svn.apache.org/r1700180
Log:
Enable svn_repos_parse_dumpstream3() to work with incomplete parser callback
function tables.  Replace the functions given by the caller as NULL with a
no-op dummy.

* subversion/include/svn_repos.h
  (svn_repos_parse_dumpstream3): Add comment that caller requirements are
                                 now relaxed.

* subversion/libsvn_repos/load.c
  (dummy_handler_magic_header_record,
   dummy_handler_uuid_record,
   dummy_handler_new_revision_record,
   dummy_handler_new_node_record,
   dummy_handler_set_revision_property,
   dummy_handler_set_node_property,
   dummy_handler_delete_node_property,
   dummy_handler_remove_node_props,
   dummy_handler_set_fulltext,
   dummy_handler_apply_textdelta,
   dummy_handler_close_node,
   dummy_handler_close_revision): Complete set of no-op dummy callbacks.
  (SET_VTABLE_ENTRY): A local macro to make the next function more readable
                      and easier to maintain.
  (complete_vtable): New function to patch up incomplate function tables.
  (svn_repos_parse_dumpstream3): Patch up the function table before using it.

* subversion/tests/cmdline/svnadmin_tests.py
  (load_revprops): No longer expected to fail.

Modified:
    subversion/trunk/subversion/include/svn_repos.h
    subversion/trunk/subversion/libsvn_repos/load.c
    subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py

Modified: subversion/trunk/subversion/include/svn_repos.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_repos.h?rev=1700180&r1=1700179&r2=1700180&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_repos.h (original)
+++ subversion/trunk/subversion/include/svn_repos.h Mon Aug 31 00:00:09 2015
@@ -3443,6 +3443,9 @@ typedef struct svn_repos_parse_fns3_t
  *     could stop reading entirely after the youngest required rev.
  *
  * @since New in 1.8.
+
+ * @since Starting in 1.10, @a parse_fns may contain #NULL pointers for
+ * those callbacks that the caller is not interested in.
  */
 svn_error_t *
 svn_repos_parse_dumpstream3(svn_stream_t *stream,

Modified: subversion/trunk/subversion/libsvn_repos/load.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/load.c?rev=1700180&r1=1700179&r2=1700180&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_repos/load.c (original)
+++ subversion/trunk/subversion/libsvn_repos/load.c Mon Aug 31 00:00:09 2015
@@ -385,7 +385,135 @@ parse_format_version(int *version,
   return SVN_NO_ERROR;
 }
 
+/*----------------------------------------------------------------------*/
+
+/** Dummy callback implementations for functions not provided by the user **/
+
+static svn_error_t *
+dummy_handler_magic_header_record(int version,
+                                  void *parse_baton,
+                                  apr_pool_t *pool)
+{
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+dummy_handler_uuid_record(const char *uuid,
+                          void *parse_baton,
+                          apr_pool_t *pool)
+{
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+dummy_handler_new_revision_record(void **revision_baton,
+                                  apr_hash_t *headers,
+                                  void *parse_baton,
+                                  apr_pool_t *pool)
+{
+  *revision_baton = NULL;
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+dummy_handler_new_node_record(void **node_baton,
+                              apr_hash_t *headers,
+                              void *revision_baton,
+                              apr_pool_t *pool)
+{
+  *node_baton = NULL;
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+dummy_handler_set_revision_property(void *revision_baton,
+                                    const char *name,
+                                    const svn_string_t *value)
+{
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+dummy_handler_set_node_property(void *node_baton,
+                                const char *name,
+                                const svn_string_t *value)
+{
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+dummy_handler_delete_node_property(void *node_baton,
+                                   const char *name)
+{
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+dummy_handler_remove_node_props(void *node_baton)
+{
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+dummy_handler_set_fulltext(svn_stream_t **stream,
+                               void *node_baton)
+{
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+dummy_handler_apply_textdelta(svn_txdelta_window_handler_t *handler,
+                              void **handler_baton,
+                              void *node_baton)
+{
+  /* Only called by parse_text_block() and that tests for NULL handlers. */
+  *handler = NULL;
+  *handler_baton = NULL;
+  return SVN_NO_ERROR;
+}
 
+static svn_error_t *
+dummy_handler_close_node(void *node_baton)
+{
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+dummy_handler_close_revision(void *revision_baton)
+{
+  return SVN_NO_ERROR;
+}
+
+/* Helper macro to copy the function pointer SOURCE->NAME to DEST->NAME.
+ * If the source pointer is NULL, pick the corresponding dummy handler
+ * instead. */
+#define SET_VTABLE_ENTRY(dest, source, name) \
+  dest->name = provided->name ? provided->name : dummy_handler_##name
+
+/* Return a copy of PROVIDED with all NULL callbacks replaced by a dummy
+ * handler.  Allocate the result in RESULT_POOL. */
+static const svn_repos_parse_fns3_t *
+complete_vtable(const svn_repos_parse_fns3_t *provided,
+                apr_pool_t *result_pool)
+{
+  svn_repos_parse_fns3_t *completed = apr_pcalloc(result_pool,
+                                                  sizeof(*completed));
+
+  SET_VTABLE_ENTRY(completed, provided, magic_header_record);
+  SET_VTABLE_ENTRY(completed, provided, uuid_record);
+  SET_VTABLE_ENTRY(completed, provided, new_revision_record);
+  SET_VTABLE_ENTRY(completed, provided, new_node_record);
+  SET_VTABLE_ENTRY(completed, provided, set_revision_property);
+  SET_VTABLE_ENTRY(completed, provided, set_node_property);
+  SET_VTABLE_ENTRY(completed, provided, delete_node_property);
+  SET_VTABLE_ENTRY(completed, provided, remove_node_props);
+  SET_VTABLE_ENTRY(completed, provided, set_fulltext);
+  SET_VTABLE_ENTRY(completed, provided, apply_textdelta);
+  SET_VTABLE_ENTRY(completed, provided, close_node);
+  SET_VTABLE_ENTRY(completed, provided, close_revision);
+
+  return completed;
+}
 
 /*----------------------------------------------------------------------*/
 
@@ -410,6 +538,10 @@ svn_repos_parse_dumpstream3(svn_stream_t
   apr_pool_t *nodepool = svn_pool_create(pool);
   int version;
 
+  /* Make sure we can blindly invoke callbacks. */
+  parse_fns = complete_vtable(parse_fns, pool);
+
+  /* Start parsing process. */
   SVN_ERR(svn_stream_readline(stream, &linebuf, "\n", &eof, linepool));
   if (eof)
     return stream_ran_dry();

Modified: subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py?rev=1700180&r1=1700179&r2=1700180&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/svnadmin_tests.py Mon Aug 31 00:00:09 2015
@@ -3131,7 +3131,6 @@ def fsfs_pack_non_sharded(sbox):
       ['svnadmin: Warning - this repository is not sharded. Packing has no effect.\n'],
       [], "pack", sbox.repo_dir)
 
-@XFail()
 def load_revprops(sbox):
   "svnadmin load-revprops"