svn_mergeinfo_private.h revision 286506
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__combine_adjacent_ranges(). 56 */ 57svn_error_t * 58svn_rangelist__parse(svn_rangelist_t **rangelist, 59 const char *str, 60 apr_pool_t *result_pool); 61 62/* In-place combines adjacent ranges in a rangelist. 63 SCRATCH_POOL is just used for providing error messages. */ 64svn_error_t * 65svn_rangelist__combine_adjacent_ranges(svn_rangelist_t *rangelist, 66 apr_pool_t *scratch_pool); 67 68/** Canonicalize the @a rangelist: sort the ranges, and combine adjacent or 69 * overlapping ranges into single ranges where possible. 70 * 71 * If overlapping ranges have different inheritability, return an error. 72 * 73 * Modify @a rangelist in place. Use @a scratch_pool for temporary 74 * allocations. 75 */ 76svn_error_t * 77svn_rangelist__canonicalize(svn_rangelist_t *rangelist, 78 apr_pool_t *scratch_pool); 79 80/** Canonicalize the revision range lists in the @a mergeinfo. 81 * 82 * Modify @a mergeinfo in place. Use @a scratch_pool for temporary 83 * allocations. 84 */ 85svn_error_t * 86svn_mergeinfo__canonicalize_ranges(svn_mergeinfo_t mergeinfo, 87 apr_pool_t *scratch_pool); 88 89/* Set inheritability of all rangelists in MERGEINFO to INHERITABLE. 90 If MERGEINFO is NULL do nothing. If a rangelist in MERGEINFO is 91 NULL leave it alone. */ 92void 93svn_mergeinfo__set_inheritance(svn_mergeinfo_t mergeinfo, 94 svn_boolean_t inheritable, 95 apr_pool_t *scratch_pool); 96 97/* Return whether INFO1 and INFO2 are equal in *IS_EQUAL. 98 99 CONSIDER_INHERITANCE determines how the rangelists in the two 100 hashes are compared for equality. If CONSIDER_INHERITANCE is FALSE, 101 then the start and end revisions of the svn_merge_range_t's being 102 compared are the only factors considered when determining equality. 103 104 e.g. '/trunk: 1,3-4*,5' == '/trunk: 1,3-5' 105 106 If CONSIDER_INHERITANCE is TRUE, then the inheritability of the 107 svn_merge_range_t's is also considered and must be the same for two 108 otherwise identical ranges to be judged equal. 109 110 e.g. '/trunk: 1,3-4*,5' != '/trunk: 1,3-5' 111 '/trunk: 1,3-4*,5' == '/trunk: 1,3-4*,5' 112 '/trunk: 1,3-4,5' == '/trunk: 1,3-4,5' 113 114 Use POOL for temporary allocations. */ 115svn_error_t * 116svn_mergeinfo__equals(svn_boolean_t *is_equal, 117 svn_mergeinfo_t info1, 118 svn_mergeinfo_t info2, 119 svn_boolean_t consider_inheritance, 120 apr_pool_t *pool); 121 122/* Examine MERGEINFO, removing all paths from the hash which map to 123 empty rangelists. POOL is used only to allocate the apr_hash_index_t 124 iterator. Returns TRUE if any paths were removed and FALSE if none were 125 removed or MERGEINFO is NULL. */ 126svn_boolean_t 127svn_mergeinfo__remove_empty_rangelists(svn_mergeinfo_t mergeinfo, 128 apr_pool_t *pool); 129 130/* Make a shallow (ie, mergeinfos are not duped, or altered at all; 131 keys share storage) copy of IN_CATALOG in *OUT_CATALOG, removing 132 PREFIX_PATH from the beginning of each key in the catalog. 133 PREFIX_PATH and the keys of IN_CATALOG are absolute 'fspaths', 134 starting with '/'. It is illegal for any key to not start with 135 PREFIX_PATH. The keys of *OUT_CATALOG are relpaths. The new hash 136 and temporary values are allocated in POOL. (This is useful for 137 making the return value from svn_ra_get_mergeinfo relative to the 138 session root, say.) */ 139svn_error_t * 140svn_mergeinfo__remove_prefix_from_catalog(svn_mergeinfo_catalog_t *out_catalog, 141 svn_mergeinfo_catalog_t in_catalog, 142 const char *prefix_path, 143 apr_pool_t *pool); 144 145/* Make a shallow (ie, mergeinfos are not duped, or altered at all; 146 though keys are reallocated) copy of IN_CATALOG in *OUT_CATALOG, 147 adding PREFIX_PATH to the beginning of each key in the catalog. 148 149 The new hash keys are allocated in RESULT_POOL. SCRATCH_POOL 150 is used for any temporary allocations.*/ 151svn_error_t * 152svn_mergeinfo__add_prefix_to_catalog(svn_mergeinfo_catalog_t *out_catalog, 153 svn_mergeinfo_catalog_t in_catalog, 154 const char *prefix_path, 155 apr_pool_t *result_pool, 156 apr_pool_t *scratch_pool); 157 158/* Set *OUT_MERGEINFO to a shallow copy of MERGEINFO with the relpath 159 SUFFIX_RELPATH added to the end of each key path. 160 161 Allocate *OUT_MERGEINFO and the new keys in RESULT_POOL. Use 162 SCRATCH_POOL for any temporary allocations. */ 163svn_error_t * 164svn_mergeinfo__add_suffix_to_mergeinfo(svn_mergeinfo_t *out_mergeinfo, 165 svn_mergeinfo_t mergeinfo, 166 const char *suffix_relpath, 167 apr_pool_t *result_pool, 168 apr_pool_t *scratch_pool); 169 170/* Create a string representation of CATALOG in *OUTPUT, allocated in POOL. 171 The hash keys of CATALOG and the merge source paths of each key's mergeinfo 172 are represented in sorted order as per svn_sort_compare_items_as_paths. 173 If CATALOG is empty or NULL then *OUTPUT->DATA is set to "\n". If SVN_DEBUG 174 is true, then a NULL or empty CATALOG causes *OUTPUT to be set to an 175 appropriate newline terminated string. If KEY_PREFIX is not NULL then 176 prepend KEY_PREFIX to each key (path) in *OUTPUT. if VAL_PREFIX is not 177 NULL then prepend VAL_PREFIX to each merge source:rangelist line in 178 *OUTPUT. 179 180 Any relative merge source paths in the mergeinfo in CATALOG are converted 181 to absolute paths in *OUTPUT. */ 182svn_error_t * 183svn_mergeinfo__catalog_to_formatted_string(svn_string_t **output, 184 svn_mergeinfo_catalog_t catalog, 185 const char *key_prefix, 186 const char *val_prefix, 187 apr_pool_t *pool); 188 189/* Set *YOUNGEST_REV and *OLDEST_REV to the youngest and oldest revisions 190 found in the rangelists within MERGEINFO. Note that *OLDEST_REV is 191 exclusive and *YOUNGEST_REV is inclusive. If MERGEINFO is NULL or empty 192 set *YOUNGEST_REV and *OLDEST_REV to SVN_INVALID_REVNUM. */ 193svn_error_t * 194svn_mergeinfo__get_range_endpoints(svn_revnum_t *youngest_rev, 195 svn_revnum_t *oldest_rev, 196 svn_mergeinfo_t mergeinfo, 197 apr_pool_t *pool); 198 199/* Set *FILTERED_MERGEINFO to a deep copy of MERGEINFO, allocated in 200 RESULT_POOL, less any revision ranges that fall outside of the range 201 OLDEST_REV:YOUNGEST_REV (exclusive:inclusive) if INCLUDE_RANGE is true, 202 or less any ranges within OLDEST_REV:YOUNGEST_REV if INCLUDE_RANGE 203 is false. If all the rangelists mapped to a given path are filtered 204 then filter that path as well. If all paths are filtered or MERGEINFO is 205 empty or NULL then *FILTERED_MERGEINFO is set to an empty hash. 206 207 Use SCRATCH_POOL for any temporary allocations. */ 208svn_error_t * 209svn_mergeinfo__filter_mergeinfo_by_ranges(svn_mergeinfo_t *filtered_mergeinfo, 210 svn_mergeinfo_t mergeinfo, 211 svn_revnum_t youngest_rev, 212 svn_revnum_t oldest_rev, 213 svn_boolean_t include_range, 214 apr_pool_t *result_pool, 215 apr_pool_t *scratch_pool); 216 217/* Filter each mergeinfo in CATALOG as per 218 svn_mergeinfo__filter_mergeinfo_by_ranges() and put a deep copy of the 219 result in *FILTERED_CATALOG, allocated in RESULT_POOL. If any mergeinfo 220 is filtered to an empty hash then filter that path/mergeinfo as well. 221 If all mergeinfo is filtered or CATALOG is NULL then set *FILTERED_CATALOG 222 to an empty hash. 223 224 Use SCRATCH_POOL for any temporary allocations. */ 225svn_error_t* 226svn_mergeinfo__filter_catalog_by_ranges( 227 svn_mergeinfo_catalog_t *filtered_catalog, 228 svn_mergeinfo_catalog_t catalog, 229 svn_revnum_t youngest_rev, 230 svn_revnum_t oldest_rev, 231 svn_boolean_t include_range, 232 apr_pool_t *result_pool, 233 apr_pool_t *scratch_pool); 234 235/* If MERGEINFO is non-inheritable return TRUE, return FALSE otherwise. 236 MERGEINFO may be NULL or empty. */ 237svn_boolean_t 238svn_mergeinfo__is_noninheritable(svn_mergeinfo_t mergeinfo, 239 apr_pool_t *scratch_pool); 240 241/* Return a rangelist with one svn_merge_range_t * element defined by START, 242 END, and INHERITABLE. The rangelist and its contents are allocated in 243 RESULT_POOL. */ 244svn_rangelist_t * 245svn_rangelist__initialize(svn_revnum_t start, 246 svn_revnum_t end, 247 svn_boolean_t inheritable, 248 apr_pool_t *result_pool); 249 250/* Adjust in-place MERGEINFO's rangelists by OFFSET. If OFFSET is negative 251 and would adjust any part of MERGEINFO's source revisions to 0 or less, 252 then those revisions are dropped. If all the source revisions for a merge 253 source path are dropped, then the path itself is dropped. If all merge 254 source paths are dropped, then *ADJUSTED_MERGEINFO is set to an empty 255 hash. *ADJUSTED_MERGEINFO is allocated in RESULT_POOL. SCRATCH_POOL is 256 used for any temporary allocations. */ 257svn_error_t * 258svn_mergeinfo__adjust_mergeinfo_rangelists(svn_mergeinfo_t *adjusted_mergeinfo, 259 svn_mergeinfo_t mergeinfo, 260 svn_revnum_t offset, 261 apr_pool_t *result_pool, 262 apr_pool_t *scratch_pool); 263 264/* Translates an array SEGMENTS (of svn_location_segment_t *), like the one 265 returned from svn_client__repos_location_segments, into a mergeinfo 266 *MERGEINFO_P, allocated in POOL. 267 268 Note: A svn_location_segment_t segment may legitimately describe only revision 0, 269 but there is no way to describe that using svn_mergeinfo_t. Any such 270 segment in SEGMENTS are ignored. */ 271svn_error_t * 272svn_mergeinfo__mergeinfo_from_segments(svn_mergeinfo_t *mergeinfo_p, 273 const apr_array_header_t *segments, 274 apr_pool_t *pool); 275 276/* Merge every rangelist in MERGEINFO into the given MERGED_RANGELIST, 277 * ignoring the source paths of MERGEINFO. MERGED_RANGELIST may 278 * initially be empty. New elements added to RANGELIST are allocated in 279 * RESULT_POOL. See svn_rangelist_merge2() for details of inheritability 280 * etc. */ 281svn_error_t * 282svn_rangelist__merge_many(svn_rangelist_t *merged_rangelist, 283 svn_mergeinfo_t mergeinfo, 284 apr_pool_t *result_pool, 285 apr_pool_t *scratch_pool); 286 287#ifdef __cplusplus 288} 289#endif /* __cplusplus */ 290 291#endif /* SVN_MERGEINFO_PRIVATE_H */ 292