summaryrefslogtreecommitdiff
path: root/subversion/libsvn_repos/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/libsvn_repos/compat.c')
-rw-r--r--subversion/libsvn_repos/compat.c179
1 files changed, 179 insertions, 0 deletions
diff --git a/subversion/libsvn_repos/compat.c b/subversion/libsvn_repos/compat.c
new file mode 100644
index 0000000000000..405b1c415b8df
--- /dev/null
+++ b/subversion/libsvn_repos/compat.c
@@ -0,0 +1,179 @@
+/*
+ * compat.c: compatibility shims to adapt between different API versions.
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ */
+
+#include "svn_repos.h"
+#include "svn_compat.h"
+#include "svn_hash.h"
+#include "svn_props.h"
+#include "svn_pools.h"
+
+#include "svn_private_config.h"
+
+#include "repos.h"
+
+#include "private/svn_repos_private.h"
+#include "private/svn_subr_private.h"
+
+
+
+/*** log4 -> log5 ***/
+
+/* Baton type to be used with both log4 compatibility callbacks.
+ * For each revision, we collect the CHANGES and then pass them
+ * on to INNER. */
+typedef struct log_entry_receiver_baton_t
+{
+ /* Pool to use to allocate CHANGES and its entries.
+ * Gets cleared after each revision. */
+ apr_pool_t *changes_pool;
+
+ /* Path changes reported so far for the current revision.
+ * Will be NULL before the first item gets added and will be reset
+ * to NULL after the INNER callback has returned. */
+ apr_hash_t *changes;
+
+ /* User-provided callback to send the log entry to. */
+ svn_log_entry_receiver_t inner;
+ void *inner_baton;
+} log_entry_receiver_baton_t;
+
+/* Return the action character (see svn_log_changed_path2_t) for KIND.
+ * Returns 0 for invalid KINDs. */
+static char
+path_change_kind_to_char(svn_fs_path_change_kind_t kind)
+{
+ const char symbol[] = "MADR";
+
+ if (kind < svn_fs_path_change_modify || kind > svn_fs_path_change_replace)
+ return 0;
+
+ return symbol[kind];
+}
+
+/* Implement svn_repos_path_change_receiver_t.
+ * Convert CHANGE and add it to the CHANGES list in *BATON. */
+static svn_error_t *
+log4_path_change_receiver(void *baton,
+ svn_repos_path_change_t *change,
+ apr_pool_t *scratch_pool)
+{
+ log_entry_receiver_baton_t *b = baton;
+ svn_log_changed_path2_t *change_copy;
+ const char *path = apr_pstrmemdup(b->changes_pool, change->path.data,
+ change->path.len);
+
+ /* Create a deep copy of the temporary CHANGE struct. */
+ change_copy = svn_log_changed_path2_create(b->changes_pool);
+ change_copy->action = path_change_kind_to_char(change->change_kind);
+
+ if (change->copyfrom_path)
+ change_copy->copyfrom_path = apr_pstrdup(b->changes_pool,
+ change->copyfrom_path);
+
+ change_copy->copyfrom_rev = change->copyfrom_rev;
+ change_copy->node_kind = change->node_kind;
+ change_copy->text_modified = change->text_mod ? svn_tristate_true
+ : svn_tristate_false;
+ change_copy->props_modified = change->prop_mod ? svn_tristate_true
+ : svn_tristate_false;
+
+ /* Auto-create the CHANGES container (happens for each first change
+ * in any revison. */
+ if (b->changes == NULL)
+ b->changes = svn_hash__make(b->changes_pool);
+
+ /* Add change to per-revision collection. */
+ apr_hash_set(b->changes, path, change->path.len, change_copy);
+
+ return SVN_NO_ERROR;
+}
+
+/* Implement svn_log_entry_receiver_t.
+ * Combine the data gathered in BATON for this revision and send it
+ * to the user-provided log4-compatible callback. */
+static svn_error_t *
+log4_entry_receiver(void *baton,
+ svn_repos_log_entry_t *log_entry,
+ apr_pool_t *scratch_pool)
+{
+ log_entry_receiver_baton_t *b = baton;
+ svn_log_entry_t *entry = svn_log_entry_create(scratch_pool);
+
+ /* Complete the ENTRY. */
+ entry->changed_paths = b->changes;
+ entry->revision = log_entry->revision;
+ entry->revprops = log_entry->revprops;
+ entry->has_children = log_entry->has_children;
+ entry->changed_paths2 = b->changes;
+ entry->non_inheritable = log_entry->non_inheritable;
+ entry->subtractive_merge = log_entry->subtractive_merge;
+
+ /* Invoke the log4-compatible callback. */
+ SVN_ERR(b->inner(b->inner_baton, entry, scratch_pool));
+
+ /* Release per-revision data. */
+ svn_pool_clear(b->changes_pool);
+ b->changes = NULL;
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_repos__get_logs_compat(svn_repos_t *repos,
+ const apr_array_header_t *paths,
+ svn_revnum_t start,
+ svn_revnum_t end,
+ int limit,
+ svn_boolean_t discover_changed_paths,
+ svn_boolean_t strict_node_history,
+ svn_boolean_t include_merged_revisions,
+ const apr_array_header_t *revprops,
+ svn_repos_authz_func_t authz_read_func,
+ void *authz_read_baton,
+ svn_log_entry_receiver_t receiver,
+ void *receiver_baton,
+ apr_pool_t *pool)
+{
+ apr_pool_t *changes_pool = svn_pool_create(pool);
+
+ log_entry_receiver_baton_t baton;
+ baton.changes_pool = changes_pool;
+ baton.changes = NULL;
+ baton.inner = receiver;
+ baton.inner_baton = receiver_baton;
+
+ SVN_ERR(svn_repos_get_logs5(repos, paths, start, end, limit,
+ strict_node_history,
+ include_merged_revisions,
+ revprops,
+ authz_read_func, authz_read_baton,
+ discover_changed_paths
+ ? log4_path_change_receiver
+ : NULL,
+ &baton,
+ log4_entry_receiver, &baton,
+ pool));
+
+ svn_pool_destroy(changes_pool);
+ return SVN_NO_ERROR;
+}