svn_mergeinfo_private.h revision 362181
1/**
2 * @copyright
3 * ====================================================================
4 *    Licensed to the Apache Software Foundation (ASF) under one
5 *    or more contributor license agreements.  See the NOTICE file
6 *    distributed with this work for additional information
7 *    regarding copyright ownership.  The ASF licenses this file
8 *    to you under the Apache License, Version 2.0 (the
9 *    "License"); you may not use this file except in compliance
10 *    with the License.  You may obtain a copy of the License at
11 *
12 *      http://www.apache.org/licenses/LICENSE-2.0
13 *
14 *    Unless required by applicable law or agreed to in writing,
15 *    software distributed under the License is distributed on an
16 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 *    KIND, either express or implied.  See the License for the
18 *    specific language governing permissions and limitations
19 *    under the License.
20 * ====================================================================
21 * @endcopyright
22 *
23 * @file svn_mergeinfo_private.h
24 * @brief Subversion-internal mergeinfo APIs.
25 */
26
27#ifndef SVN_MERGEINFO_PRIVATE_H
28#define SVN_MERGEINFO_PRIVATE_H
29
30#include <apr_pools.h>
31
32#include "svn_types.h"
33#include "svn_error.h"
34#include "svn_mergeinfo.h"
35
36#ifdef __cplusplus
37extern "C" {
38#endif /* __cplusplus */
39
40
41/* Set inheritability of all ranges in RANGELIST to INHERITABLE.
42   If RANGELIST is NULL do nothing. */
43void
44svn_rangelist__set_inheritance(svn_rangelist_t *rangelist,
45                               svn_boolean_t inheritable);
46
47/* Parse a rangelist from the string STR. Set *RANGELIST to the result,
48 * allocated in RESULT_POOL. Return an error if the rangelist is not
49 * well-formed (for example, if it contains invalid characters or if
50 * R1 >= R2 in a "R1-R2" range element).
51 *
52 * Unlike svn_mergeinfo_parse(), this does not sort the ranges into order
53 * or combine adjacent and overlapping ranges.
54 *
55 * The compaction can be done with svn_rangelist__canonicalize().
56 */
57svn_error_t *
58svn_rangelist__parse(svn_rangelist_t **rangelist,
59                     const char *str,
60                     apr_pool_t *result_pool);
61
62/* Return TRUE, if all ranges in RANGELIST are in ascending order and do
63* not overlap and are not adjacent.
64*
65* If this returns FALSE, you probaly want to call
66* svn_rangelist__canonicalize().
67*/
68svn_boolean_t
69svn_rangelist__is_canonical(const svn_rangelist_t *rangelist);
70
71/** Canonicalize the @a rangelist: sort the ranges, and combine adjacent or
72 * overlapping ranges into single ranges where possible.
73 *
74 * If overlapping ranges have different inheritability, return an error.
75 *
76 * Modify @a rangelist in place. Use @a scratch_pool for temporary
77 * allocations.
78 */
79svn_error_t *
80svn_rangelist__canonicalize(svn_rangelist_t *rangelist,
81                            apr_pool_t *scratch_pool);
82
83/** Canonicalize the revision range lists in the @a mergeinfo.
84 *
85 * Modify @a mergeinfo in place. Use @a scratch_pool for temporary
86 * allocations.
87 */
88svn_error_t *
89svn_mergeinfo__canonicalize_ranges(svn_mergeinfo_t mergeinfo,
90                                   apr_pool_t *scratch_pool);
91
92/* Set inheritability of all rangelists in MERGEINFO to INHERITABLE.
93   If MERGEINFO is NULL do nothing.  If a rangelist in MERGEINFO is
94   NULL leave it alone. */
95void
96svn_mergeinfo__set_inheritance(svn_mergeinfo_t mergeinfo,
97                               svn_boolean_t inheritable,
98                               apr_pool_t *scratch_pool);
99
100/* Return whether INFO1 and INFO2 are equal in *IS_EQUAL.
101
102   CONSIDER_INHERITANCE determines how the rangelists in the two
103   hashes are compared for equality.  If CONSIDER_INHERITANCE is FALSE,
104   then the start and end revisions of the svn_merge_range_t's being
105   compared are the only factors considered when determining equality.
106
107     e.g. '/trunk: 1,3-4*,5' == '/trunk: 1,3-5'
108
109   If CONSIDER_INHERITANCE is TRUE, then the inheritability of the
110   svn_merge_range_t's is also considered and must be the same for two
111   otherwise identical ranges to be judged equal.
112
113     e.g. '/trunk: 1,3-4*,5' != '/trunk: 1,3-5'
114          '/trunk: 1,3-4*,5' == '/trunk: 1,3-4*,5'
115          '/trunk: 1,3-4,5'  == '/trunk: 1,3-4,5'
116
117   Use POOL for temporary allocations. */
118svn_error_t *
119svn_mergeinfo__equals(svn_boolean_t *is_equal,
120                      svn_mergeinfo_t info1,
121                      svn_mergeinfo_t info2,
122                      svn_boolean_t consider_inheritance,
123                      apr_pool_t *pool);
124
125/* Remove all paths from MERGEINFO which map to empty rangelists.
126
127   Return TRUE if any paths were removed and FALSE if none were
128   removed or MERGEINFO is NULL. */
129svn_boolean_t
130svn_mergeinfo__remove_empty_rangelists(svn_mergeinfo_t mergeinfo,
131                                       apr_pool_t *scratch_pool);
132
133/* Make a shallow (ie, mergeinfos are not duped, or altered at all;
134   keys share storage) copy of IN_CATALOG in *OUT_CATALOG, removing
135   PREFIX_PATH from the beginning of each key in the catalog.
136   PREFIX_PATH and the keys of IN_CATALOG are absolute 'fspaths',
137   starting with '/'.  It is illegal for any key to not start with
138   PREFIX_PATH.  The keys of *OUT_CATALOG are relpaths.  The new hash
139   and temporary values are allocated in POOL.  (This is useful for
140   making the return value from svn_ra_get_mergeinfo relative to the
141   session root, say.) */
142svn_error_t *
143svn_mergeinfo__remove_prefix_from_catalog(svn_mergeinfo_catalog_t *out_catalog,
144                                          svn_mergeinfo_catalog_t in_catalog,
145                                          const char *prefix_path,
146                                          apr_pool_t *pool);
147
148/* Make a shallow (ie, mergeinfos are not duped, or altered at all;
149   though keys are reallocated) copy of IN_CATALOG in *OUT_CATALOG,
150   adding PREFIX_PATH to the beginning of each key in the catalog.
151
152   The new hash keys are allocated in RESULT_POOL.  SCRATCH_POOL
153   is used for any temporary allocations.*/
154svn_error_t *
155svn_mergeinfo__add_prefix_to_catalog(svn_mergeinfo_catalog_t *out_catalog,
156                                     svn_mergeinfo_catalog_t in_catalog,
157                                     const char *prefix_path,
158                                     apr_pool_t *result_pool,
159                                     apr_pool_t *scratch_pool);
160
161/* Set *OUT_MERGEINFO to a shallow copy of MERGEINFO with the relpath
162   SUFFIX_RELPATH added to the end of each key path.
163
164   Allocate *OUT_MERGEINFO and the new keys in RESULT_POOL.  Use
165   SCRATCH_POOL for any temporary allocations. */
166svn_error_t *
167svn_mergeinfo__add_suffix_to_mergeinfo(svn_mergeinfo_t *out_mergeinfo,
168                                       svn_mergeinfo_t mergeinfo,
169                                       const char *suffix_relpath,
170                                       apr_pool_t *result_pool,
171                                       apr_pool_t *scratch_pool);
172
173/* Create a string representation of CATALOG in *OUTPUT, allocated in POOL.
174   The hash keys of CATALOG and the merge source paths of each key's mergeinfo
175   are represented in sorted order as per svn_sort_compare_items_as_paths.
176   If CATALOG is empty or NULL then *OUTPUT->DATA is set to "\n".  If SVN_DEBUG
177   is true, then a NULL or empty CATALOG causes *OUTPUT to be set to an
178   appropriate newline terminated string.  If KEY_PREFIX is not NULL then
179   prepend KEY_PREFIX to each key (path) in *OUTPUT.  if VAL_PREFIX is not
180   NULL then prepend VAL_PREFIX to each merge source:rangelist line in
181   *OUTPUT.
182
183   Any relative merge source paths in the mergeinfo in CATALOG are converted
184   to absolute paths in *OUTPUT. */
185svn_error_t *
186svn_mergeinfo__catalog_to_formatted_string(svn_string_t **output,
187                                           svn_mergeinfo_catalog_t catalog,
188                                           const char *key_prefix,
189                                           const char *val_prefix,
190                                           apr_pool_t *pool);
191
192/* Set *YOUNGEST_REV and *OLDEST_REV to the youngest and oldest revisions
193   found in the rangelists within MERGEINFO.  Note that *OLDEST_REV is
194   exclusive and *YOUNGEST_REV is inclusive.  If MERGEINFO is NULL or empty
195   set *YOUNGEST_REV and *OLDEST_REV to SVN_INVALID_REVNUM. */
196svn_error_t *
197svn_mergeinfo__get_range_endpoints(svn_revnum_t *youngest_rev,
198                                   svn_revnum_t *oldest_rev,
199                                   svn_mergeinfo_t mergeinfo,
200                                   apr_pool_t *pool);
201
202/* Set *FILTERED_MERGEINFO to a deep copy of MERGEINFO, allocated in
203   RESULT_POOL, less any revision ranges that fall outside of the range
204   OLDEST_REV:YOUNGEST_REV (exclusive:inclusive) if INCLUDE_RANGE is true,
205   or less any ranges within OLDEST_REV:YOUNGEST_REV if INCLUDE_RANGE
206   is false.  If all the rangelists mapped to a given path are filtered
207   then filter that path as well.  If all paths are filtered or MERGEINFO is
208   empty or NULL then *FILTERED_MERGEINFO is set to an empty hash.
209
210   Use SCRATCH_POOL for any temporary allocations. */
211svn_error_t *
212svn_mergeinfo__filter_mergeinfo_by_ranges(svn_mergeinfo_t *filtered_mergeinfo,
213                                          svn_mergeinfo_t mergeinfo,
214                                          svn_revnum_t youngest_rev,
215                                          svn_revnum_t oldest_rev,
216                                          svn_boolean_t include_range,
217                                          apr_pool_t *result_pool,
218                                          apr_pool_t *scratch_pool);
219
220/* Filter each mergeinfo in CATALOG as per
221   svn_mergeinfo__filter_mergeinfo_by_ranges() and put a deep copy of the
222   result in *FILTERED_CATALOG, allocated in RESULT_POOL.  If any mergeinfo
223   is filtered to an empty hash then filter that path/mergeinfo as well.
224   If all mergeinfo is filtered or CATALOG is NULL then set *FILTERED_CATALOG
225   to an empty hash.
226
227   Use SCRATCH_POOL for any temporary allocations. */
228svn_error_t*
229svn_mergeinfo__filter_catalog_by_ranges(
230  svn_mergeinfo_catalog_t *filtered_catalog,
231  svn_mergeinfo_catalog_t catalog,
232  svn_revnum_t youngest_rev,
233  svn_revnum_t oldest_rev,
234  svn_boolean_t include_range,
235  apr_pool_t *result_pool,
236  apr_pool_t *scratch_pool);
237
238/* If MERGEINFO is non-inheritable return TRUE, return FALSE otherwise.
239   MERGEINFO may be NULL or empty. */
240svn_boolean_t
241svn_mergeinfo__is_noninheritable(svn_mergeinfo_t mergeinfo,
242                                 apr_pool_t *scratch_pool);
243
244/* Return a rangelist with one svn_merge_range_t * element defined by START,
245   END, and INHERITABLE.  The rangelist and its contents are allocated in
246   RESULT_POOL. */
247svn_rangelist_t *
248svn_rangelist__initialize(svn_revnum_t start,
249                          svn_revnum_t end,
250                          svn_boolean_t inheritable,
251                          apr_pool_t *result_pool);
252
253/* Adjust in-place MERGEINFO's rangelists by OFFSET.  If OFFSET is negative
254   and would adjust any part of MERGEINFO's source revisions to 0 or less,
255   then those revisions are dropped.  If all the source revisions for a merge
256   source path are dropped, then the path itself is dropped.  If all merge
257   source paths are dropped, then *ADJUSTED_MERGEINFO is set to an empty
258   hash.  *ADJUSTED_MERGEINFO is allocated in RESULT_POOL.  SCRATCH_POOL is
259   used for any temporary allocations. */
260svn_error_t *
261svn_mergeinfo__adjust_mergeinfo_rangelists(svn_mergeinfo_t *adjusted_mergeinfo,
262                                           svn_mergeinfo_t mergeinfo,
263                                           svn_revnum_t offset,
264                                           apr_pool_t *result_pool,
265                                           apr_pool_t *scratch_pool);
266
267/* Translates an array SEGMENTS (of svn_location_segment_t *), like the one
268   returned from svn_client__repos_location_segments, into a mergeinfo
269   *MERGEINFO_P, allocated in POOL.
270
271   Note: A svn_location_segment_t segment may legitimately describe only revision 0,
272   but there is no way to describe that using svn_mergeinfo_t.  Any such
273   segment in SEGMENTS are ignored. */
274svn_error_t *
275svn_mergeinfo__mergeinfo_from_segments(svn_mergeinfo_t *mergeinfo_p,
276                                       const apr_array_header_t *segments,
277                                       apr_pool_t *pool);
278
279/* Merge every rangelist in MERGEINFO into the given MERGED_RANGELIST,
280 * ignoring the source paths of MERGEINFO. MERGED_RANGELIST may
281 * initially be empty. New elements added to RANGELIST are allocated in
282 * RESULT_POOL. See svn_rangelist_merge2() for details of inheritability
283 * etc. */
284svn_error_t *
285svn_rangelist__merge_many(svn_rangelist_t *merged_rangelist,
286                          svn_mergeinfo_t mergeinfo,
287                          apr_pool_t *result_pool,
288                          apr_pool_t *scratch_pool);
289
290#ifdef __cplusplus
291}
292#endif /* __cplusplus */
293
294#endif /* SVN_MERGEINFO_PRIVATE_H */
295