subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hwri...@apache.org
Subject svn commit: r1229895 - /subversion/trunk/subversion/libsvn_delta/compat.c
Date Wed, 11 Jan 2012 05:29:42 GMT
Author: hwright
Date: Wed Jan 11 05:29:42 2012
New Revision: 1229895

URL: http://svn.apache.org/viewvc?rev=1229895&view=rev
Log:
Ev2 shims: Rewrite the tree driver to be much more intelligible, and fix
a couple of bugs while we're at it.

Current number of Ev2 test failures: 167

* subversion/libsvn_delta/compat.c
  (operation): Add path member.
  (get_operation): Populate path member.
  (drive_tree): Rewrite to operate on a single node, rather than all its
    children.
  (drive_root): New.
  (complete_cb, abort_cb): Update callers.
  (editor_from_delta): Populate path member for the root operation.

Modified:
    subversion/trunk/subversion/libsvn_delta/compat.c

Modified: subversion/trunk/subversion/libsvn_delta/compat.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_delta/compat.c?rev=1229895&r1=1229894&r2=1229895&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_delta/compat.c (original)
+++ subversion/trunk/subversion/libsvn_delta/compat.c Wed Jan 11 05:29:42 2012
@@ -815,6 +815,8 @@ struct operation {
                             occuring; directories are OP_OPEN with non-empty
                             props */
   } operation;
+
+  const char *path;
   svn_kind_t kind;  /* to copy, mkdir, put or set revprops */
   svn_revnum_t base_revision;       /* When committing, the base revision */
   svn_revnum_t copyfrom_revision;      /* to copy, valid for add and replace */
@@ -863,6 +865,7 @@ get_operation(const char *path,
     {
       child = apr_pcalloc(result_pool, sizeof(*child));
       child->children = apr_hash_make(result_pool);
+      child->path = apr_pstrdup(result_pool, path);
       child->operation = OP_OPEN;
       child->copyfrom_revision = SVN_INVALID_REVNUM;
       child->kind = svn_kind_dir;
@@ -1324,119 +1327,146 @@ change_props(const svn_delta_editor_t *e
 }
 
 static svn_error_t *
-drive_tree(const struct operation *operation,
+drive_tree(struct operation *op,
+           const struct operation *parent_op,
            const svn_delta_editor_t *editor,
-           svn_boolean_t *make_abs_paths,
+           svn_boolean_t make_abs_paths,
            apr_pool_t *scratch_pool)
 {
-  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-  apr_hash_index_t *hi;
+  const char *path = op->path;
 
-  for (hi = apr_hash_first(scratch_pool, operation->children);
-       hi; hi = apr_hash_next(hi))
+  if (path[0] != '/' && make_abs_paths)
+    path = apr_pstrcat(scratch_pool, "/", path, NULL);
+
+  /* Deletes and replacements are simple -- just delete the thing. */
+  if (op->operation == OP_DELETE || op->operation == OP_REPLACE)
     {
-      struct operation *child;
-      const char *path;
-      void *file_baton = NULL;
+      SVN_ERR(editor->delete_entry(path, SVN_INVALID_REVNUM,
+                                   parent_op->baton, scratch_pool));
+    }
 
-      svn_pool_clear(iterpool);
-      child = svn__apr_hash_index_val(hi);
-      path = svn__apr_hash_index_key(hi);
+  if (op->kind == svn_kind_dir)
+    {
+      /* Open or create our baton. */
+      if (op->operation == OP_OPEN || op->operation == OP_PROPSET)
+        SVN_ERR(editor->open_directory(path, parent_op->baton,
+                                       parent_op->base_revision,
+                                       scratch_pool, &op->baton));
 
-      if (path[0] != '/' && *make_abs_paths)
-        path = apr_pstrcat(iterpool, "/", path, NULL);
+      else if (op->operation == OP_ADD || op->operation == OP_REPLACE)
+        SVN_ERR(editor->add_directory(path, parent_op->baton,
+                                      op->copyfrom_url, op->copyfrom_revision,
+                                      scratch_pool, &op->baton));
 
-      /* Deletes and replacements are simple -- just delete the thing. */
-      if (child->operation == OP_DELETE || child->operation == OP_REPLACE)
-        {
-          SVN_ERR(editor->delete_entry(path, SVN_INVALID_REVNUM,
-                                       operation->baton, iterpool));
-        }
+      else if (op->operation == OP_ADD_ABSENT)
+        SVN_ERR(editor->absent_directory(path, parent_op->baton,
+                                         scratch_pool));
 
-      if (child->operation == OP_OPEN || child->operation == OP_PROPSET)
+      if (op->baton)
         {
-          if (child->kind == svn_kind_dir)
-            SVN_ERR(editor->open_directory(path, operation->baton,
-                                           operation->base_revision,
-                                           iterpool, &child->baton));
-          else
-            SVN_ERR(editor->open_file(path, operation->baton,
-                                      operation->base_revision,
-                                      iterpool, &file_baton));
-        }
+          apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+          apr_hash_index_t *hi;
 
-      if (child->operation == OP_ADD || child->operation == OP_REPLACE)
-        {
-          if (child->kind == svn_kind_dir)
-            SVN_ERR(editor->add_directory(path, operation->baton,
-                                          child->copyfrom_url,
-                                          child->copyfrom_revision,
-                                          iterpool, &child->baton));
-          else
-            SVN_ERR(editor->add_file(path, operation->baton,
-                                     child->copyfrom_url,
-                                     child->copyfrom_revision, iterpool,
-                                     &file_baton));
-        }
+          /* Do any prop mods we may have. */
+          SVN_ERR(change_props(editor, op->baton, op, scratch_pool));
 
-      if (child->operation == OP_ADD_ABSENT)
-        {
-          if (child->kind == svn_kind_dir)
-            SVN_ERR(editor->absent_directory(path, operation->baton,
-                                             iterpool));
-          else
-            SVN_ERR(editor->absent_file(path, operation->baton, iterpool));
-        }
+          for (hi = apr_hash_first(scratch_pool, op->children);
+               hi; hi = apr_hash_next(hi))
+            {
+              struct operation *child = svn__apr_hash_index_val(hi);
 
-      if (child->src_file && file_baton)
-        {
-          /* We need to change textual contents. */
-          svn_txdelta_window_handler_t handler;
-          void *handler_baton;
-          svn_stream_t *contents;
-
-          SVN_ERR(editor->apply_textdelta(file_baton, NULL, iterpool,
-                                          &handler, &handler_baton));
-          SVN_ERR(svn_stream_open_readonly(&contents, child->src_file,
-                                           iterpool, iterpool));
-          SVN_ERR(svn_txdelta_send_stream(contents, handler, handler_baton,
-                                          NULL, iterpool));
-          SVN_ERR(svn_stream_close(contents));
+              svn_pool_clear(iterpool);
+              SVN_ERR(drive_tree(child, op, editor, make_abs_paths, iterpool));
+            }
+          svn_pool_destroy(iterpool);
+
+          /* We're done, close the directory. */
+          SVN_ERR(editor->close_directory(op->baton, scratch_pool));
         }
+    }
+  else
+    {
+      /* This currently treats anything that isn't a directory as a file.
+         I don't know that that's a valid assumption... */
+
+      void *file_baton = NULL;
+      
+      /* Open or create our baton. */
+      if (op->operation == OP_OPEN || op->operation == OP_PROPSET)
+        SVN_ERR(editor->open_file(path, parent_op->baton,
+                                  parent_op->base_revision,
+                                  scratch_pool, &file_baton));
+
+      else if (op->operation == OP_ADD || op->operation == OP_REPLACE)
+        SVN_ERR(editor->add_file(path, parent_op->baton, op->copyfrom_url,
+                                 op->copyfrom_revision, scratch_pool,
+                                 &file_baton));
+
+      else if (op->operation == OP_ADD_ABSENT)
+        SVN_ERR(editor->absent_file(path, parent_op->baton, scratch_pool));
 
-      /* Only worry about properties and closing the file baton if we've
-         previously opened it. */
       if (file_baton)
         {
-          if (child->kind == svn_kind_file)
-            SVN_ERR(change_props(editor, file_baton, child, iterpool));
-          SVN_ERR(editor->close_file(file_baton, NULL, iterpool));
-        }
+          /* Do we need to change text contents? */
+          if (op->src_file)
+            {
+              svn_txdelta_window_handler_t handler;
+              void *handler_baton;
+              svn_stream_t *contents;
 
-      /* We *always* open the child directory, so drive the child, change any
-         props, and then close the directory. */
-      if (child->kind == svn_kind_dir
-                   && (child->operation == OP_OPEN
-                    || child->operation == OP_PROPSET
-                    || child->operation == OP_ADD
-                    || child->operation == OP_REPLACE))
-        {
-          SVN_ERR(drive_tree(child, editor, make_abs_paths, iterpool));
-          SVN_ERR(editor->close_directory(child->baton, iterpool));
+              SVN_ERR(editor->apply_textdelta(file_baton, NULL, scratch_pool,
+                                              &handler, &handler_baton));
+              SVN_ERR(svn_stream_open_readonly(&contents, op->src_file,
+                                               scratch_pool, scratch_pool));
+              SVN_ERR(svn_txdelta_send_stream(contents, handler, handler_baton,
+                                              NULL, scratch_pool));
+              SVN_ERR(svn_stream_close(contents));
+            }
+
+          /* Do any prop mods we may have. */
+          SVN_ERR(change_props(editor, file_baton, op, scratch_pool));
+
+          /* Close the file. */
+          SVN_ERR(editor->close_file(file_baton, NULL, scratch_pool));
         }
+
     }
-  svn_pool_destroy(iterpool);
 
-  /* Finally, for this node, if it's a directory, change any props before
-     returning (our caller will close the directory. */
-  if (operation->kind == svn_kind_dir
-                   && (operation->operation == OP_OPEN
-                    || operation->operation == OP_PROPSET
-                    || operation->operation == OP_ADD
-                    || operation->operation == OP_REPLACE))
+  return SVN_NO_ERROR;
+}
+
+/* This is a special case of drive_tree(), meant to handle the root, which
+   doesn't have a parent and should already be open. */
+static svn_error_t *
+drive_root(struct operation *root,
+           const svn_delta_editor_t *editor,
+           svn_boolean_t make_abs_paths,
+           apr_pool_t *scratch_pool)
+{
+  apr_hash_index_t *hi;
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+
+  /* Early out: if we haven't opened the root yet (which would usually only
+     be the case in an abort), there isn't much we can do here. */
+  if (!root->baton)
+    return SVN_NO_ERROR;
+
+  /* Do any prop mods we may have. */
+  SVN_ERR(change_props(editor, root->baton, root, scratch_pool));
+
+  /* Now iterate over our children. */
+  for (hi = apr_hash_first(scratch_pool, root->children);
+       hi; hi = apr_hash_next(hi))
     {
-      SVN_ERR(change_props(editor, operation->baton, operation, scratch_pool));
+      struct operation *child = svn__apr_hash_index_val(hi);
+
+      svn_pool_clear(iterpool);
+      SVN_ERR(drive_tree(child, root, editor, make_abs_paths, iterpool));
     }
+  
+  /* We need to close the root directory, but leave it to our caller to call
+     close_ or abort_edit(). */
+  SVN_ERR(editor->close_directory(root->baton, scratch_pool));
 
   return SVN_NO_ERROR;
 }
@@ -1452,10 +1482,9 @@ complete_cb(void *baton,
   SVN_ERR(ensure_root_opened(eb));
 
   /* Drive the tree we've created. */
-  err = drive_tree(&eb->root, eb->deditor, eb->make_abs_paths, scratch_pool);
+  err = drive_root(&eb->root, eb->deditor, *eb->make_abs_paths, scratch_pool);
   if (!err)
      {
-       err = eb->deditor->close_directory(eb->root.baton, scratch_pool);
        err = svn_error_compose_create(err, eb->deditor->close_edit(
                                                             eb->dedit_baton,
                                                             scratch_pool));
@@ -1480,7 +1509,7 @@ abort_cb(void *baton,
      point. */
 
   /* Drive the tree we've created. */
-  err = drive_tree(&eb->root, eb->deditor, eb->make_abs_paths, scratch_pool);
+  err = drive_root(&eb->root, eb->deditor, *eb->make_abs_paths, scratch_pool);
 
   err2 = eb->deditor->abort_edit(eb->dedit_baton, scratch_pool);
 
@@ -1564,6 +1593,7 @@ editor_from_delta(svn_editor_t **editor_
   eb->fetch_props_func = fetch_props_func;
   eb->fetch_props_baton = fetch_props_baton;
 
+  eb->root.path = NULL;
   eb->root.children = apr_hash_make(result_pool);
   eb->root.kind = svn_kind_dir;
   eb->root.operation = OP_OPEN;



Mime
View raw message