]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/subversion/subversion/libsvn_repos/compat.c
Merge llvm trunk r338150 (just before the 7.0.0 branch point), and
[FreeBSD/FreeBSD.git] / contrib / subversion / subversion / libsvn_repos / compat.c
1 /*
2  * compat.c:  compatibility shims to adapt between different API versions.
3  *
4  * ====================================================================
5  *    Licensed to the Apache Software Foundation (ASF) under one
6  *    or more contributor license agreements.  See the NOTICE file
7  *    distributed with this work for additional information
8  *    regarding copyright ownership.  The ASF licenses this file
9  *    to you under the Apache License, Version 2.0 (the
10  *    "License"); you may not use this file except in compliance
11  *    with the License.  You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  *    Unless required by applicable law or agreed to in writing,
16  *    software distributed under the License is distributed on an
17  *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18  *    KIND, either express or implied.  See the License for the
19  *    specific language governing permissions and limitations
20  *    under the License.
21  * ====================================================================
22  */
23
24 #include "svn_repos.h"
25 #include "svn_compat.h"
26 #include "svn_hash.h"
27 #include "svn_props.h"
28 #include "svn_pools.h"
29
30 #include "svn_private_config.h"
31
32 #include "repos.h"
33
34 #include "private/svn_repos_private.h"
35 #include "private/svn_subr_private.h"
36
37 \f
38
39 /*** log4 -> log5 ***/
40
41 /* Baton type to be used with both log4 compatibility callbacks.
42  * For each revision, we collect the CHANGES and then pass them
43  * on to INNER. */
44 typedef struct log_entry_receiver_baton_t
45 {
46   /* Pool to use to allocate CHANGES and its entries.
47    * Gets cleared after each revision. */
48   apr_pool_t *changes_pool;
49
50   /* Path changes reported so far for the current revision.
51    * Will be NULL before the first item gets added and will be reset
52    * to NULL after the INNER callback has returned. */
53   apr_hash_t *changes;
54
55   /* User-provided callback to send the log entry to. */
56   svn_log_entry_receiver_t inner;
57   void *inner_baton;
58 } log_entry_receiver_baton_t;
59
60 /* Return the action character (see svn_log_changed_path2_t) for KIND.
61  * Returns 0 for invalid KINDs. */
62 static char
63 path_change_kind_to_char(svn_fs_path_change_kind_t kind)
64 {
65   const char symbol[] = "MADR";
66
67   if (kind < svn_fs_path_change_modify || kind > svn_fs_path_change_replace)
68     return 0;
69
70   return symbol[kind];
71 }
72
73 /* Implement svn_repos_path_change_receiver_t.
74  * Convert CHANGE and add it to the CHANGES list in *BATON. */
75 static svn_error_t *
76 log4_path_change_receiver(void *baton,
77                           svn_repos_path_change_t *change,
78                           apr_pool_t *scratch_pool)
79 {
80   log_entry_receiver_baton_t *b = baton;
81   svn_log_changed_path2_t *change_copy;
82   const char *path = apr_pstrmemdup(b->changes_pool, change->path.data,
83                                     change->path.len);
84
85   /* Create a deep copy of the temporary CHANGE struct. */
86   change_copy = svn_log_changed_path2_create(b->changes_pool);
87   change_copy->action = path_change_kind_to_char(change->change_kind);
88
89   if (change->copyfrom_path)
90     change_copy->copyfrom_path = apr_pstrdup(b->changes_pool,
91                                              change->copyfrom_path);
92
93   change_copy->copyfrom_rev = change->copyfrom_rev;
94   change_copy->node_kind = change->node_kind;
95   change_copy->text_modified = change->text_mod ? svn_tristate_true
96                                                 : svn_tristate_false;
97   change_copy->props_modified = change->prop_mod ? svn_tristate_true
98                                                  : svn_tristate_false;
99
100   /* Auto-create the CHANGES container (happens for each first change
101    * in any revison. */
102   if (b->changes == NULL)
103     b->changes = svn_hash__make(b->changes_pool);
104
105   /* Add change to per-revision collection. */
106   apr_hash_set(b->changes, path, change->path.len, change_copy);
107
108   return SVN_NO_ERROR;
109 }
110
111 /* Implement svn_log_entry_receiver_t.
112  * Combine the data gathered in BATON for this revision and send it
113  * to the user-provided log4-compatible callback. */
114 static svn_error_t *
115 log4_entry_receiver(void *baton,
116                     svn_repos_log_entry_t *log_entry,
117                     apr_pool_t *scratch_pool)
118 {
119   log_entry_receiver_baton_t *b = baton;
120   svn_log_entry_t *entry = svn_log_entry_create(scratch_pool);
121
122   /* Complete the ENTRY. */
123   entry->changed_paths = b->changes;
124   entry->revision = log_entry->revision;
125   entry->revprops = log_entry->revprops;
126   entry->has_children = log_entry->has_children;
127   entry->changed_paths2 = b->changes;
128   entry->non_inheritable = log_entry->non_inheritable;
129   entry->subtractive_merge = log_entry->subtractive_merge;
130
131   /* Invoke the log4-compatible callback. */
132   SVN_ERR(b->inner(b->inner_baton, entry, scratch_pool));
133
134   /* Release per-revision data. */
135   svn_pool_clear(b->changes_pool);
136   b->changes = NULL;
137
138   return SVN_NO_ERROR;
139 }
140
141 svn_error_t *
142 svn_repos__get_logs_compat(svn_repos_t *repos,
143                            const apr_array_header_t *paths,
144                            svn_revnum_t start,
145                            svn_revnum_t end,
146                            int limit,
147                            svn_boolean_t discover_changed_paths,
148                            svn_boolean_t strict_node_history,
149                            svn_boolean_t include_merged_revisions,
150                            const apr_array_header_t *revprops,
151                            svn_repos_authz_func_t authz_read_func,
152                            void *authz_read_baton,
153                            svn_log_entry_receiver_t receiver,
154                            void *receiver_baton,
155                            apr_pool_t *pool)
156 {
157   apr_pool_t *changes_pool = svn_pool_create(pool);
158
159   log_entry_receiver_baton_t baton;
160   baton.changes_pool = changes_pool;
161   baton.changes = NULL;
162   baton.inner = receiver;
163   baton.inner_baton = receiver_baton;
164
165   SVN_ERR(svn_repos_get_logs5(repos, paths, start, end, limit,
166                               strict_node_history,
167                               include_merged_revisions,
168                               revprops,
169                               authz_read_func, authz_read_baton,
170                               discover_changed_paths
171                                 ? log4_path_change_receiver
172                                 : NULL,
173                               &baton,
174                               log4_entry_receiver, &baton,
175                               pool));
176
177   svn_pool_destroy(changes_pool);
178   return SVN_NO_ERROR;
179 }