1251881Speter/**
2251881Speter * @copyright
3251881Speter * ====================================================================
4251881Speter *    Licensed to the Apache Software Foundation (ASF) under one
5251881Speter *    or more contributor license agreements.  See the NOTICE file
6251881Speter *    distributed with this work for additional information
7251881Speter *    regarding copyright ownership.  The ASF licenses this file
8251881Speter *    to you under the Apache License, Version 2.0 (the
9251881Speter *    "License"); you may not use this file except in compliance
10251881Speter *    with the License.  You may obtain a copy of the License at
11251881Speter *
12251881Speter *      http://www.apache.org/licenses/LICENSE-2.0
13251881Speter *
14251881Speter *    Unless required by applicable law or agreed to in writing,
15251881Speter *    software distributed under the License is distributed on an
16251881Speter *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17251881Speter *    KIND, either express or implied.  See the License for the
18251881Speter *    specific language governing permissions and limitations
19251881Speter *    under the License.
20251881Speter * ====================================================================
21251881Speter * @endcopyright
22251881Speter *
23251881Speter * @file svn_mergeinfo_private.h
24251881Speter * @brief Subversion-internal mergeinfo APIs.
25251881Speter */
26251881Speter
27251881Speter#ifndef SVN_MERGEINFO_PRIVATE_H
28251881Speter#define SVN_MERGEINFO_PRIVATE_H
29251881Speter
30251881Speter#include <apr_pools.h>
31251881Speter
32251881Speter#include "svn_types.h"
33251881Speter#include "svn_error.h"
34251881Speter#include "svn_mergeinfo.h"
35251881Speter
36251881Speter#ifdef __cplusplus
37251881Speterextern "C" {
38251881Speter#endif /* __cplusplus */
39251881Speter
40251881Speter
41251881Speter/* Set inheritability of all ranges in RANGELIST to INHERITABLE.
42251881Speter   If RANGELIST is NULL do nothing. */
43251881Spetervoid
44251881Spetersvn_rangelist__set_inheritance(svn_rangelist_t *rangelist,
45251881Speter                               svn_boolean_t inheritable);
46251881Speter
47251881Speter/* Parse a rangelist from the string STR. Set *RANGELIST to the result,
48251881Speter * allocated in RESULT_POOL. Return an error if the rangelist is not
49251881Speter * well-formed (for example, if it contains invalid characters or if
50251881Speter * R1 >= R2 in a "R1-R2" range element).
51251881Speter *
52251881Speter * Unlike svn_mergeinfo_parse(), this does not sort the ranges into order
53251881Speter * or combine adjacent and overlapping ranges.
54251881Speter *
55251881Speter * The compaction can be done with svn_rangelist__combine_adjacent_ranges().
56251881Speter */
57251881Spetersvn_error_t *
58251881Spetersvn_rangelist__parse(svn_rangelist_t **rangelist,
59251881Speter                     const char *str,
60251881Speter                     apr_pool_t *result_pool);
61251881Speter
62251881Speter/* In-place combines adjacent ranges in a rangelist.
63251881Speter   SCRATCH_POOL is just used for providing error messages. */
64251881Spetersvn_error_t *
65251881Spetersvn_rangelist__combine_adjacent_ranges(svn_rangelist_t *rangelist,
66251881Speter                                       apr_pool_t *scratch_pool);
67251881Speter
68251881Speter/* Set inheritability of all rangelists in MERGEINFO to INHERITABLE.
69251881Speter   If MERGEINFO is NULL do nothing.  If a rangelist in MERGEINFO is
70251881Speter   NULL leave it alone. */
71251881Spetervoid
72251881Spetersvn_mergeinfo__set_inheritance(svn_mergeinfo_t mergeinfo,
73251881Speter                               svn_boolean_t inheritable,
74251881Speter                               apr_pool_t *scratch_pool);
75251881Speter
76251881Speter/* Return whether INFO1 and INFO2 are equal in *IS_EQUAL.
77251881Speter
78251881Speter   CONSIDER_INHERITANCE determines how the rangelists in the two
79251881Speter   hashes are compared for equality.  If CONSIDER_INHERITANCE is FALSE,
80251881Speter   then the start and end revisions of the svn_merge_range_t's being
81251881Speter   compared are the only factors considered when determining equality.
82251881Speter
83251881Speter     e.g. '/trunk: 1,3-4*,5' == '/trunk: 1,3-5'
84251881Speter
85251881Speter   If CONSIDER_INHERITANCE is TRUE, then the inheritability of the
86251881Speter   svn_merge_range_t's is also considered and must be the same for two
87251881Speter   otherwise identical ranges to be judged equal.
88251881Speter
89251881Speter     e.g. '/trunk: 1,3-4*,5' != '/trunk: 1,3-5'
90251881Speter          '/trunk: 1,3-4*,5' == '/trunk: 1,3-4*,5'
91251881Speter          '/trunk: 1,3-4,5'  == '/trunk: 1,3-4,5'
92251881Speter
93251881Speter   Use POOL for temporary allocations. */
94251881Spetersvn_error_t *
95251881Spetersvn_mergeinfo__equals(svn_boolean_t *is_equal,
96251881Speter                      svn_mergeinfo_t info1,
97251881Speter                      svn_mergeinfo_t info2,
98251881Speter                      svn_boolean_t consider_inheritance,
99251881Speter                      apr_pool_t *pool);
100251881Speter
101251881Speter/* Examine MERGEINFO, removing all paths from the hash which map to
102251881Speter   empty rangelists.  POOL is used only to allocate the apr_hash_index_t
103251881Speter   iterator.  Returns TRUE if any paths were removed and FALSE if none were
104251881Speter   removed or MERGEINFO is NULL. */
105251881Spetersvn_boolean_t
106251881Spetersvn_mergeinfo__remove_empty_rangelists(svn_mergeinfo_t mergeinfo,
107251881Speter                                       apr_pool_t *pool);
108251881Speter
109251881Speter/* Make a shallow (ie, mergeinfos are not duped, or altered at all;
110251881Speter   keys share storage) copy of IN_CATALOG in *OUT_CATALOG, removing
111251881Speter   PREFIX_PATH from the beginning of each key in the catalog.
112251881Speter   PREFIX_PATH and the keys of IN_CATALOG are absolute 'fspaths',
113251881Speter   starting with '/'.  It is illegal for any key to not start with
114251881Speter   PREFIX_PATH.  The keys of *OUT_CATALOG are relpaths.  The new hash
115251881Speter   and temporary values are allocated in POOL.  (This is useful for
116251881Speter   making the return value from svn_ra_get_mergeinfo relative to the
117251881Speter   session root, say.) */
118251881Spetersvn_error_t *
119251881Spetersvn_mergeinfo__remove_prefix_from_catalog(svn_mergeinfo_catalog_t *out_catalog,
120251881Speter                                          svn_mergeinfo_catalog_t in_catalog,
121251881Speter                                          const char *prefix_path,
122251881Speter                                          apr_pool_t *pool);
123251881Speter
124251881Speter/* Make a shallow (ie, mergeinfos are not duped, or altered at all;
125251881Speter   though keys are reallocated) copy of IN_CATALOG in *OUT_CATALOG,
126251881Speter   adding PREFIX_PATH to the beginning of each key in the catalog.
127251881Speter
128251881Speter   The new hash keys are allocated in RESULT_POOL.  SCRATCH_POOL
129251881Speter   is used for any temporary allocations.*/
130251881Spetersvn_error_t *
131251881Spetersvn_mergeinfo__add_prefix_to_catalog(svn_mergeinfo_catalog_t *out_catalog,
132251881Speter                                     svn_mergeinfo_catalog_t in_catalog,
133251881Speter                                     const char *prefix_path,
134251881Speter                                     apr_pool_t *result_pool,
135251881Speter                                     apr_pool_t *scratch_pool);
136251881Speter
137251881Speter/* Set *OUT_MERGEINFO to a shallow copy of MERGEINFO with the relpath
138251881Speter   SUFFIX_RELPATH added to the end of each key path.
139251881Speter
140251881Speter   Allocate *OUT_MERGEINFO and the new keys in RESULT_POOL.  Use
141251881Speter   SCRATCH_POOL for any temporary allocations. */
142251881Spetersvn_error_t *
143251881Spetersvn_mergeinfo__add_suffix_to_mergeinfo(svn_mergeinfo_t *out_mergeinfo,
144251881Speter                                       svn_mergeinfo_t mergeinfo,
145251881Speter                                       const char *suffix_relpath,
146251881Speter                                       apr_pool_t *result_pool,
147251881Speter                                       apr_pool_t *scratch_pool);
148251881Speter
149251881Speter/* Create a string representation of CATALOG in *OUTPUT, allocated in POOL.
150251881Speter   The hash keys of CATALOG and the merge source paths of each key's mergeinfo
151251881Speter   are represented in sorted order as per svn_sort_compare_items_as_paths.
152251881Speter   If CATALOG is empty or NULL then *OUTPUT->DATA is set to "\n".  If SVN_DEBUG
153251881Speter   is true, then a NULL or empty CATALOG causes *OUTPUT to be set to an
154251881Speter   appropriate newline terminated string.  If KEY_PREFIX is not NULL then
155251881Speter   prepend KEY_PREFIX to each key (path) in *OUTPUT.  if VAL_PREFIX is not
156251881Speter   NULL then prepend VAL_PREFIX to each merge source:rangelist line in
157251881Speter   *OUTPUT.
158251881Speter
159251881Speter   Any relative merge source paths in the mergeinfo in CATALOG are converted
160251881Speter   to absolute paths in *OUTPUT. */
161251881Spetersvn_error_t *
162251881Spetersvn_mergeinfo__catalog_to_formatted_string(svn_string_t **output,
163251881Speter                                           svn_mergeinfo_catalog_t catalog,
164251881Speter                                           const char *key_prefix,
165251881Speter                                           const char *val_prefix,
166251881Speter                                           apr_pool_t *pool);
167251881Speter
168251881Speter/* Set *YOUNGEST_REV and *OLDEST_REV to the youngest and oldest revisions
169251881Speter   found in the rangelists within MERGEINFO.  Note that *OLDEST_REV is
170251881Speter   exclusive and *YOUNGEST_REV is inclusive.  If MERGEINFO is NULL or empty
171251881Speter   set *YOUNGEST_REV and *OLDEST_REV to SVN_INVALID_REVNUM. */
172251881Spetersvn_error_t *
173251881Spetersvn_mergeinfo__get_range_endpoints(svn_revnum_t *youngest_rev,
174251881Speter                                   svn_revnum_t *oldest_rev,
175251881Speter                                   svn_mergeinfo_t mergeinfo,
176251881Speter                                   apr_pool_t *pool);
177251881Speter
178251881Speter/* Set *FILTERED_MERGEINFO to a deep copy of MERGEINFO, allocated in
179251881Speter   RESULT_POOL, less any revision ranges that fall outside of the range
180251881Speter   OLDEST_REV:YOUNGEST_REV (exclusive:inclusive) if INCLUDE_RANGE is true,
181251881Speter   or less any ranges within OLDEST_REV:YOUNGEST_REV if INCLUDE_RANGE
182251881Speter   is false.  If all the rangelists mapped to a given path are filtered
183251881Speter   then filter that path as well.  If all paths are filtered or MERGEINFO is
184251881Speter   empty or NULL then *FILTERED_MERGEINFO is set to an empty hash.
185251881Speter
186251881Speter   Use SCRATCH_POOL for any temporary allocations. */
187251881Spetersvn_error_t *
188251881Spetersvn_mergeinfo__filter_mergeinfo_by_ranges(svn_mergeinfo_t *filtered_mergeinfo,
189251881Speter                                          svn_mergeinfo_t mergeinfo,
190251881Speter                                          svn_revnum_t youngest_rev,
191251881Speter                                          svn_revnum_t oldest_rev,
192251881Speter                                          svn_boolean_t include_range,
193251881Speter                                          apr_pool_t *result_pool,
194251881Speter                                          apr_pool_t *scratch_pool);
195251881Speter
196251881Speter/* Filter each mergeinfo in CATALOG as per
197251881Speter   svn_mergeinfo__filter_mergeinfo_by_ranges() and put a deep copy of the
198251881Speter   result in *FILTERED_CATALOG, allocated in RESULT_POOL.  If any mergeinfo
199251881Speter   is filtered to an empty hash then filter that path/mergeinfo as well.
200251881Speter   If all mergeinfo is filtered or CATALOG is NULL then set *FILTERED_CATALOG
201251881Speter   to an empty hash.
202251881Speter
203251881Speter   Use SCRATCH_POOL for any temporary allocations. */
204251881Spetersvn_error_t*
205251881Spetersvn_mergeinfo__filter_catalog_by_ranges(
206251881Speter  svn_mergeinfo_catalog_t *filtered_catalog,
207251881Speter  svn_mergeinfo_catalog_t catalog,
208251881Speter  svn_revnum_t youngest_rev,
209251881Speter  svn_revnum_t oldest_rev,
210251881Speter  svn_boolean_t include_range,
211251881Speter  apr_pool_t *result_pool,
212251881Speter  apr_pool_t *scratch_pool);
213251881Speter
214251881Speter/* If MERGEINFO is non-inheritable return TRUE, return FALSE otherwise.
215251881Speter   MERGEINFO may be NULL or empty. */
216251881Spetersvn_boolean_t
217251881Spetersvn_mergeinfo__is_noninheritable(svn_mergeinfo_t mergeinfo,
218251881Speter                                 apr_pool_t *scratch_pool);
219251881Speter
220251881Speter/* Return a rangelist with one svn_merge_range_t * element defined by START,
221251881Speter   END, and INHERITABLE.  The rangelist and its contents are allocated in
222251881Speter   RESULT_POOL. */
223251881Spetersvn_rangelist_t *
224251881Spetersvn_rangelist__initialize(svn_revnum_t start,
225251881Speter                          svn_revnum_t end,
226251881Speter                          svn_boolean_t inheritable,
227251881Speter                          apr_pool_t *result_pool);
228251881Speter
229251881Speter/* Adjust in-place MERGEINFO's rangelists by OFFSET.  If OFFSET is negative
230251881Speter   and would adjust any part of MERGEINFO's source revisions to 0 or less,
231251881Speter   then those revisions are dropped.  If all the source revisions for a merge
232251881Speter   source path are dropped, then the path itself is dropped.  If all merge
233251881Speter   source paths are dropped, then *ADJUSTED_MERGEINFO is set to an empty
234251881Speter   hash.  *ADJUSTED_MERGEINFO is allocated in RESULT_POOL.  SCRATCH_POOL is
235251881Speter   used for any temporary allocations. */
236251881Spetersvn_error_t *
237251881Spetersvn_mergeinfo__adjust_mergeinfo_rangelists(svn_mergeinfo_t *adjusted_mergeinfo,
238251881Speter                                           svn_mergeinfo_t mergeinfo,
239251881Speter                                           svn_revnum_t offset,
240251881Speter                                           apr_pool_t *result_pool,
241251881Speter                                           apr_pool_t *scratch_pool);
242251881Speter
243251881Speter/* Translates an array SEGMENTS (of svn_location_segment_t *), like the one
244251881Speter   returned from svn_client__repos_location_segments, into a mergeinfo
245251881Speter   *MERGEINFO_P, allocated in POOL.
246251881Speter
247251881Speter   Note: A svn_location_segment_t segment may legitimately describe only revision 0,
248251881Speter   but there is no way to describe that using svn_mergeinfo_t.  Any such
249251881Speter   segment in SEGMENTS are ignored. */
250251881Spetersvn_error_t *
251251881Spetersvn_mergeinfo__mergeinfo_from_segments(svn_mergeinfo_t *mergeinfo_p,
252251881Speter                                       const apr_array_header_t *segments,
253251881Speter                                       apr_pool_t *pool);
254251881Speter
255251881Speter/* Merge every rangelist in MERGEINFO into the given MERGED_RANGELIST,
256251881Speter * ignoring the source paths of MERGEINFO. MERGED_RANGELIST may
257251881Speter * initially be empty. New elements added to RANGELIST are allocated in
258251881Speter * RESULT_POOL. See svn_rangelist_merge2() for details of inheritability
259251881Speter * etc. */
260251881Spetersvn_error_t *
261251881Spetersvn_rangelist__merge_many(svn_rangelist_t *merged_rangelist,
262251881Speter                          svn_mergeinfo_t mergeinfo,
263251881Speter                          apr_pool_t *result_pool,
264251881Speter                          apr_pool_t *scratch_pool);
265251881Speter
266251881Speter#ifdef __cplusplus
267251881Speter}
268251881Speter#endif /* __cplusplus */
269251881Speter
270251881Speter#endif /* SVN_MERGEINFO_PRIVATE_H */
271