diff options
Diffstat (limited to 'subversion/libsvn_repos/compat.c')
-rw-r--r-- | subversion/libsvn_repos/compat.c | 179 |
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; +} |