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"
35 svn_revnum_parse(svn_revnum_t *rev,
41 svn_revnum_t result = strtol(str, &end, 10);
47 return svn_error_createf(SVN_ERR_REVNUM_PARSE_FAILURE, NULL,
48 _("Invalid revision number found parsing '%s'"),
53 /* The end pointer from strtol() is valid, but a negative revision
54 number is invalid, so move the end pointer back to the
55 beginning of the string. */
59 return svn_error_createf(SVN_ERR_REVNUM_PARSE_FAILURE, NULL,
60 _("Negative revision number found parsing '%s'"),
70 svn_uuid_generate(apr_pool_t *pool)
73 char *uuid_str = apr_pcalloc(pool, APR_UUID_FORMATTED_LENGTH + 1);
75 apr_uuid_format(uuid_str, &uuid);
80 svn_depth_to_word(svn_depth_t depth)
84 case svn_depth_exclude:
86 case svn_depth_unknown:
92 case svn_depth_immediates:
94 case svn_depth_infinity:
97 return "INVALID-DEPTH";
103 svn_depth_from_word(const char *word)
105 if (strcmp(word, "exclude") == 0)
106 return svn_depth_exclude;
107 if (strcmp(word, "unknown") == 0)
108 return svn_depth_unknown;
109 if (strcmp(word, "empty") == 0)
110 return svn_depth_empty;
111 if (strcmp(word, "files") == 0)
112 return svn_depth_files;
113 if (strcmp(word, "immediates") == 0)
114 return svn_depth_immediates;
115 if (strcmp(word, "infinity") == 0)
116 return svn_depth_infinity;
117 /* There's no special value for invalid depth, and no convincing
118 reason to make one yet, so just fall back to unknown depth.
119 If you ever change that convention, check callers to make sure
120 they're not depending on it (e.g., option parsing in main() ).
122 return svn_depth_unknown;
126 svn_node_kind_to_word(svn_node_kind_t kind)
136 case svn_node_symlink:
138 case svn_node_unknown:
146 svn_node_kind_from_word(const char *word)
149 return svn_node_unknown;
151 if (strcmp(word, "none") == 0)
152 return svn_node_none;
153 else if (strcmp(word, "file") == 0)
154 return svn_node_file;
155 else if (strcmp(word, "dir") == 0)
157 else if (strcmp(word, "symlink") == 0)
158 return svn_node_symlink;
160 /* This also handles word == "unknown" */
161 return svn_node_unknown;
165 svn_tristate__to_word(svn_tristate_t tristate)
169 case svn_tristate_false:
171 case svn_tristate_true:
173 case svn_tristate_unknown:
180 svn_tristate__from_word(const char *word)
183 return svn_tristate_unknown;
184 else if (0 == svn_cstring_casecmp(word, "true")
185 || 0 == svn_cstring_casecmp(word, "yes")
186 || 0 == svn_cstring_casecmp(word, "on")
187 || 0 == strcmp(word, "1"))
188 return svn_tristate_true;
189 else if (0 == svn_cstring_casecmp(word, "false")
190 || 0 == svn_cstring_casecmp(word, "no")
191 || 0 == svn_cstring_casecmp(word, "off")
192 || 0 == strcmp(word, "0"))
193 return svn_tristate_false;
195 return svn_tristate_unknown;
199 svn_create_commit_info(apr_pool_t *pool)
201 svn_commit_info_t *commit_info
202 = apr_pcalloc(pool, sizeof(*commit_info));
204 commit_info->revision = SVN_INVALID_REVNUM;
205 /* All other fields were initialized to NULL above. */
211 svn_commit_info_dup(const svn_commit_info_t *src_commit_info,
214 svn_commit_info_t *dst_commit_info
215 = apr_palloc(pool, sizeof(*dst_commit_info));
217 dst_commit_info->date = src_commit_info->date
218 ? apr_pstrdup(pool, src_commit_info->date) : NULL;
219 dst_commit_info->author = src_commit_info->author
220 ? apr_pstrdup(pool, src_commit_info->author) : NULL;
221 dst_commit_info->revision = src_commit_info->revision;
222 dst_commit_info->post_commit_err = src_commit_info->post_commit_err
223 ? apr_pstrdup(pool, src_commit_info->post_commit_err) : NULL;
224 dst_commit_info->repos_root = src_commit_info->repos_root
225 ? apr_pstrdup(pool, src_commit_info->repos_root) : NULL;
227 return dst_commit_info;
230 svn_log_changed_path2_t *
231 svn_log_changed_path2_create(apr_pool_t *pool)
233 svn_log_changed_path2_t *new_changed_path
234 = apr_pcalloc(pool, sizeof(*new_changed_path));
236 new_changed_path->text_modified = svn_tristate_unknown;
237 new_changed_path->props_modified = svn_tristate_unknown;
239 return new_changed_path;
242 svn_log_changed_path2_t *
243 svn_log_changed_path2_dup(const svn_log_changed_path2_t *changed_path,
246 svn_log_changed_path2_t *new_changed_path
247 = apr_palloc(pool, sizeof(*new_changed_path));
249 *new_changed_path = *changed_path;
251 if (new_changed_path->copyfrom_path)
252 new_changed_path->copyfrom_path =
253 apr_pstrdup(pool, new_changed_path->copyfrom_path);
255 return new_changed_path;
259 svn_dirent_create(apr_pool_t *result_pool)
261 svn_dirent_t *new_dirent = apr_pcalloc(result_pool, sizeof(*new_dirent));
263 new_dirent->kind = svn_node_unknown;
264 new_dirent->size = SVN_INVALID_FILESIZE;
265 new_dirent->created_rev = SVN_INVALID_REVNUM;
266 new_dirent->time = 0;
267 new_dirent->last_author = NULL;
273 svn_dirent_dup(const svn_dirent_t *dirent,
276 svn_dirent_t *new_dirent = apr_palloc(pool, sizeof(*new_dirent));
278 *new_dirent = *dirent;
280 new_dirent->last_author = apr_pstrdup(pool, dirent->last_author);
286 svn_log_entry_create(apr_pool_t *pool)
288 svn_log_entry_t *log_entry = apr_pcalloc(pool, sizeof(*log_entry));
294 svn_log_entry_dup(const svn_log_entry_t *log_entry, apr_pool_t *pool)
296 apr_hash_index_t *hi;
297 svn_log_entry_t *new_entry = apr_palloc(pool, sizeof(*new_entry));
299 *new_entry = *log_entry;
301 if (log_entry->revprops)
302 new_entry->revprops = svn_prop_hash_dup(log_entry->revprops, pool);
304 if (log_entry->changed_paths2)
306 new_entry->changed_paths2 = apr_hash_make(pool);
308 for (hi = apr_hash_first(pool, log_entry->changed_paths2);
309 hi; hi = apr_hash_next(hi))
314 apr_hash_this(hi, &key, NULL, &change);
316 svn_hash_sets(new_entry->changed_paths2, apr_pstrdup(pool, key),
317 svn_log_changed_path2_dup(change, pool));
321 /* We can't copy changed_paths by itself without using deprecated code,
322 but we don't have to, as this function was new after the introduction
323 of the changed_paths2 field. */
324 new_entry->changed_paths = new_entry->changed_paths2;
329 svn_location_segment_t *
330 svn_location_segment_dup(const svn_location_segment_t *segment,
333 svn_location_segment_t *new_segment =
334 apr_palloc(pool, sizeof(*new_segment));
336 *new_segment = *segment;
338 new_segment->path = apr_pstrdup(pool, segment->path);