2 * svn_types.c : Implementation for Subversion's data types.
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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
21 * ====================================================================
24 #include <apr_pools.h>
28 #include "svn_types.h"
29 #include "svn_error.h"
30 #include "svn_string.h"
31 #include "svn_props.h"
32 #include "svn_private_config.h"
34 #include "private/svn_dep_compat.h"
35 #include "private/svn_string_private.h"
38 svn_revnum_parse(svn_revnum_t *rev,
44 svn_revnum_t result = (svn_revnum_t)svn__strtoul(str, &end);
50 return svn_error_createf
51 (SVN_ERR_REVNUM_PARSE_FAILURE, NULL,
52 *str == '-' ? _("Negative revision number found parsing '%s'")
53 : _("Invalid revision number found parsing '%s'"),
56 /* a revision number with more than 9 digits is suspicious.
57 Have a closer look at those. */
60 /* we support 32 bit revision numbers only. check for overflows */
62 return svn_error_createf
63 (SVN_ERR_REVNUM_PARSE_FAILURE, NULL,
64 _("Revision number longer than 10 digits '%s'"), str);
66 /* we support 32 bit revision numbers only. check for overflows */
67 if (*str > '2' || (apr_uint32_t)result > APR_INT32_MAX)
68 return svn_error_createf
69 (SVN_ERR_REVNUM_PARSE_FAILURE, NULL,
70 _("Revision number too large '%s'"), str);
82 svn_uuid_generate(apr_pool_t *pool)
85 char *uuid_str = apr_pcalloc(pool, APR_UUID_FORMATTED_LENGTH + 1);
87 apr_uuid_format(uuid_str, &uuid);
92 svn_depth_to_word(svn_depth_t depth)
96 case svn_depth_exclude:
98 case svn_depth_unknown:
100 case svn_depth_empty:
102 case svn_depth_files:
104 case svn_depth_immediates:
106 case svn_depth_infinity:
109 return "INVALID-DEPTH";
115 svn_depth_from_word(const char *word)
117 if (strcmp(word, "exclude") == 0)
118 return svn_depth_exclude;
119 if (strcmp(word, "unknown") == 0)
120 return svn_depth_unknown;
121 if (strcmp(word, "empty") == 0)
122 return svn_depth_empty;
123 if (strcmp(word, "files") == 0)
124 return svn_depth_files;
125 if (strcmp(word, "immediates") == 0)
126 return svn_depth_immediates;
127 if (strcmp(word, "infinity") == 0)
128 return svn_depth_infinity;
129 /* There's no special value for invalid depth, and no convincing
130 reason to make one yet, so just fall back to unknown depth.
131 If you ever change that convention, check callers to make sure
132 they're not depending on it (e.g., option parsing in main() ).
134 return svn_depth_unknown;
138 svn_node_kind_to_word(svn_node_kind_t kind)
148 case svn_node_symlink:
150 case svn_node_unknown:
158 svn_node_kind_from_word(const char *word)
161 return svn_node_unknown;
163 if (strcmp(word, "none") == 0)
164 return svn_node_none;
165 else if (strcmp(word, "file") == 0)
166 return svn_node_file;
167 else if (strcmp(word, "dir") == 0)
169 else if (strcmp(word, "symlink") == 0)
170 return svn_node_symlink;
172 /* This also handles word == "unknown" */
173 return svn_node_unknown;
177 svn_tristate__to_word(svn_tristate_t tristate)
181 case svn_tristate_false:
183 case svn_tristate_true:
185 case svn_tristate_unknown:
192 svn_tristate__from_word(const char *word)
195 return svn_tristate_unknown;
196 else if (0 == svn_cstring_casecmp(word, "true")
197 || 0 == svn_cstring_casecmp(word, "yes")
198 || 0 == svn_cstring_casecmp(word, "on")
199 || 0 == strcmp(word, "1"))
200 return svn_tristate_true;
201 else if (0 == svn_cstring_casecmp(word, "false")
202 || 0 == svn_cstring_casecmp(word, "no")
203 || 0 == svn_cstring_casecmp(word, "off")
204 || 0 == strcmp(word, "0"))
205 return svn_tristate_false;
207 return svn_tristate_unknown;
211 svn_create_commit_info(apr_pool_t *pool)
213 svn_commit_info_t *commit_info
214 = apr_pcalloc(pool, sizeof(*commit_info));
216 commit_info->revision = SVN_INVALID_REVNUM;
217 /* All other fields were initialized to NULL above. */
223 svn_commit_info_dup(const svn_commit_info_t *src_commit_info,
226 svn_commit_info_t *dst_commit_info
227 = apr_palloc(pool, sizeof(*dst_commit_info));
229 dst_commit_info->date = src_commit_info->date
230 ? apr_pstrdup(pool, src_commit_info->date) : NULL;
231 dst_commit_info->author = src_commit_info->author
232 ? apr_pstrdup(pool, src_commit_info->author) : NULL;
233 dst_commit_info->revision = src_commit_info->revision;
234 dst_commit_info->post_commit_err = src_commit_info->post_commit_err
235 ? apr_pstrdup(pool, src_commit_info->post_commit_err) : NULL;
236 dst_commit_info->repos_root = src_commit_info->repos_root
237 ? apr_pstrdup(pool, src_commit_info->repos_root) : NULL;
239 return dst_commit_info;
242 svn_log_changed_path2_t *
243 svn_log_changed_path2_create(apr_pool_t *pool)
245 svn_log_changed_path2_t *new_changed_path
246 = apr_pcalloc(pool, sizeof(*new_changed_path));
248 new_changed_path->text_modified = svn_tristate_unknown;
249 new_changed_path->props_modified = svn_tristate_unknown;
251 return new_changed_path;
254 svn_log_changed_path2_t *
255 svn_log_changed_path2_dup(const svn_log_changed_path2_t *changed_path,
258 svn_log_changed_path2_t *new_changed_path
259 = apr_palloc(pool, sizeof(*new_changed_path));
261 *new_changed_path = *changed_path;
263 if (new_changed_path->copyfrom_path)
264 new_changed_path->copyfrom_path =
265 apr_pstrdup(pool, new_changed_path->copyfrom_path);
267 return new_changed_path;
271 svn_dirent_create(apr_pool_t *result_pool)
273 svn_dirent_t *new_dirent = apr_pcalloc(result_pool, sizeof(*new_dirent));
275 new_dirent->kind = svn_node_unknown;
276 new_dirent->size = SVN_INVALID_FILESIZE;
277 new_dirent->created_rev = SVN_INVALID_REVNUM;
278 new_dirent->time = 0;
279 new_dirent->last_author = NULL;
285 svn_dirent_dup(const svn_dirent_t *dirent,
288 svn_dirent_t *new_dirent = apr_palloc(pool, sizeof(*new_dirent));
290 *new_dirent = *dirent;
292 new_dirent->last_author = apr_pstrdup(pool, dirent->last_author);
298 svn_log_entry_create(apr_pool_t *pool)
300 svn_log_entry_t *log_entry = apr_pcalloc(pool, sizeof(*log_entry));
306 svn_log_entry_dup(const svn_log_entry_t *log_entry, apr_pool_t *pool)
308 apr_hash_index_t *hi;
309 svn_log_entry_t *new_entry = apr_palloc(pool, sizeof(*new_entry));
311 *new_entry = *log_entry;
313 if (log_entry->revprops)
314 new_entry->revprops = svn_prop_hash_dup(log_entry->revprops, pool);
316 if (log_entry->changed_paths2)
318 new_entry->changed_paths2 = apr_hash_make(pool);
320 for (hi = apr_hash_first(pool, log_entry->changed_paths2);
321 hi; hi = apr_hash_next(hi))
326 apr_hash_this(hi, &key, NULL, &change);
328 svn_hash_sets(new_entry->changed_paths2, apr_pstrdup(pool, key),
329 svn_log_changed_path2_dup(change, pool));
333 /* We can't copy changed_paths by itself without using deprecated code,
334 but we don't have to, as this function was new after the introduction
335 of the changed_paths2 field. */
336 new_entry->changed_paths = new_entry->changed_paths2;
341 svn_location_segment_t *
342 svn_location_segment_dup(const svn_location_segment_t *segment,
345 svn_location_segment_t *new_segment =
346 apr_palloc(pool, sizeof(*new_segment));
348 *new_segment = *segment;
350 new_segment->path = apr_pstrdup(pool, segment->path);