]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/subversion/subversion/libsvn_subr/types.c
MFC r275385 (by bapt):
[FreeBSD/stable/10.git] / contrib / subversion / subversion / libsvn_subr / types.c
1 /*
2  * svn_types.c :  Implementation for Subversion's data types.
3  *
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
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
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
20  *    under the License.
21  * ====================================================================
22  */
23
24 #include <apr_pools.h>
25 #include <apr_uuid.h>
26
27 #include "svn_hash.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"
33
34 #include "private/svn_dep_compat.h"
35 #include "private/svn_string_private.h"
36
37 svn_error_t *
38 svn_revnum_parse(svn_revnum_t *rev,
39                  const char *str,
40                  const char **endptr)
41 {
42   const char *end;
43
44   svn_revnum_t result = (svn_revnum_t)svn__strtoul(str, &end);
45
46   if (endptr)
47     *endptr = str;
48
49   if (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'"),
54                str);
55
56   /* a revision number with more than 9 digits is suspicious.
57      Have a closer look at those. */
58   if (str + 10 <= end)
59     {
60       /* we support 32 bit revision numbers only. check for overflows */
61       if (str + 10 < end)
62         return svn_error_createf
63                   (SVN_ERR_REVNUM_PARSE_FAILURE, NULL,
64                   _("Revision number longer than 10 digits '%s'"), str);
65
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);
71     }
72
73   if (endptr)
74     *endptr = end;
75
76   *rev = result;
77
78   return SVN_NO_ERROR;
79 }
80
81 const char *
82 svn_uuid_generate(apr_pool_t *pool)
83 {
84   apr_uuid_t uuid;
85   char *uuid_str = apr_pcalloc(pool, APR_UUID_FORMATTED_LENGTH + 1);
86   apr_uuid_get(&uuid);
87   apr_uuid_format(uuid_str, &uuid);
88   return uuid_str;
89 }
90
91 const char *
92 svn_depth_to_word(svn_depth_t depth)
93 {
94   switch (depth)
95     {
96     case svn_depth_exclude:
97       return "exclude";
98     case svn_depth_unknown:
99       return "unknown";
100     case svn_depth_empty:
101       return "empty";
102     case svn_depth_files:
103       return "files";
104     case svn_depth_immediates:
105       return "immediates";
106     case svn_depth_infinity:
107       return "infinity";
108     default:
109       return "INVALID-DEPTH";
110     }
111 }
112
113
114 svn_depth_t
115 svn_depth_from_word(const char *word)
116 {
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() ).
133   */
134   return svn_depth_unknown;
135 }
136
137 const char *
138 svn_node_kind_to_word(svn_node_kind_t kind)
139 {
140   switch (kind)
141     {
142     case svn_node_none:
143       return "none";
144     case svn_node_file:
145       return "file";
146     case svn_node_dir:
147       return "dir";
148     case svn_node_symlink:
149       return "symlink";
150     case svn_node_unknown:
151     default:
152       return "unknown";
153     }
154 }
155
156
157 svn_node_kind_t
158 svn_node_kind_from_word(const char *word)
159 {
160   if (word == NULL)
161     return svn_node_unknown;
162
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)
168     return svn_node_dir;
169   else if (strcmp(word, "symlink") == 0)
170     return svn_node_symlink;
171   else
172     /* This also handles word == "unknown" */
173     return svn_node_unknown;
174 }
175
176 const char *
177 svn_tristate__to_word(svn_tristate_t tristate)
178 {
179   switch (tristate)
180     {
181       case svn_tristate_false:
182         return "false";
183       case svn_tristate_true:
184         return "true";
185       case svn_tristate_unknown:
186       default:
187         return NULL;
188     }
189 }
190
191 svn_tristate_t
192 svn_tristate__from_word(const char *word)
193 {
194   if (word == NULL)
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;
206
207   return svn_tristate_unknown;
208 }
209
210 svn_commit_info_t *
211 svn_create_commit_info(apr_pool_t *pool)
212 {
213   svn_commit_info_t *commit_info
214     = apr_pcalloc(pool, sizeof(*commit_info));
215
216   commit_info->revision = SVN_INVALID_REVNUM;
217   /* All other fields were initialized to NULL above. */
218
219   return commit_info;
220 }
221
222 svn_commit_info_t *
223 svn_commit_info_dup(const svn_commit_info_t *src_commit_info,
224                     apr_pool_t *pool)
225 {
226   svn_commit_info_t *dst_commit_info
227     = apr_palloc(pool, sizeof(*dst_commit_info));
228
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;
238
239   return dst_commit_info;
240 }
241
242 svn_log_changed_path2_t *
243 svn_log_changed_path2_create(apr_pool_t *pool)
244 {
245   svn_log_changed_path2_t *new_changed_path
246     = apr_pcalloc(pool, sizeof(*new_changed_path));
247
248   new_changed_path->text_modified = svn_tristate_unknown;
249   new_changed_path->props_modified = svn_tristate_unknown;
250
251   return new_changed_path;
252 }
253
254 svn_log_changed_path2_t *
255 svn_log_changed_path2_dup(const svn_log_changed_path2_t *changed_path,
256                           apr_pool_t *pool)
257 {
258   svn_log_changed_path2_t *new_changed_path
259     = apr_palloc(pool, sizeof(*new_changed_path));
260
261   *new_changed_path = *changed_path;
262
263   if (new_changed_path->copyfrom_path)
264     new_changed_path->copyfrom_path =
265       apr_pstrdup(pool, new_changed_path->copyfrom_path);
266
267   return new_changed_path;
268 }
269
270 svn_dirent_t *
271 svn_dirent_create(apr_pool_t *result_pool)
272 {
273   svn_dirent_t *new_dirent = apr_pcalloc(result_pool, sizeof(*new_dirent));
274
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;
280
281   return new_dirent;
282 }
283
284 svn_dirent_t *
285 svn_dirent_dup(const svn_dirent_t *dirent,
286                apr_pool_t *pool)
287 {
288   svn_dirent_t *new_dirent = apr_palloc(pool, sizeof(*new_dirent));
289
290   *new_dirent = *dirent;
291
292   new_dirent->last_author = apr_pstrdup(pool, dirent->last_author);
293
294   return new_dirent;
295 }
296
297 svn_log_entry_t *
298 svn_log_entry_create(apr_pool_t *pool)
299 {
300   svn_log_entry_t *log_entry = apr_pcalloc(pool, sizeof(*log_entry));
301
302   return log_entry;
303 }
304
305 svn_log_entry_t *
306 svn_log_entry_dup(const svn_log_entry_t *log_entry, apr_pool_t *pool)
307 {
308   apr_hash_index_t *hi;
309   svn_log_entry_t *new_entry = apr_palloc(pool, sizeof(*new_entry));
310
311   *new_entry = *log_entry;
312
313   if (log_entry->revprops)
314     new_entry->revprops = svn_prop_hash_dup(log_entry->revprops, pool);
315
316   if (log_entry->changed_paths2)
317     {
318       new_entry->changed_paths2 = apr_hash_make(pool);
319
320       for (hi = apr_hash_first(pool, log_entry->changed_paths2);
321            hi; hi = apr_hash_next(hi))
322         {
323           const void *key;
324           void *change;
325
326           apr_hash_this(hi, &key, NULL, &change);
327
328           svn_hash_sets(new_entry->changed_paths2, apr_pstrdup(pool, key),
329                         svn_log_changed_path2_dup(change, pool));
330         }
331     }
332
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;
337
338   return new_entry;
339 }
340
341 svn_location_segment_t *
342 svn_location_segment_dup(const svn_location_segment_t *segment,
343                          apr_pool_t *pool)
344 {
345   svn_location_segment_t *new_segment =
346     apr_palloc(pool, sizeof(*new_segment));
347
348   *new_segment = *segment;
349   if (segment->path)
350     new_segment->path = apr_pstrdup(pool, segment->path);
351   return new_segment;
352 }