1 /* fs-util.c : internal utility functions used by both FSFS and BDB back
4 * ====================================================================
5 * Copyright (c) 2007 CollabNet. All rights reserved.
7 * This software is licensed as described in the file COPYING, which
8 * you should have received as part of this distribution. The terms
9 * are also available at http://subversion.tigris.org/license-1.html.
10 * If newer versions of this license are posted there, you may use a
11 * newer version instead, at your option.
13 * This software consists of voluntary contributions made by many
14 * individuals. For exact contribution history, see the revision
15 * history and logs, available at http://subversion.tigris.org/.
16 * ====================================================================
21 #include <apr_pools.h>
22 #include <apr_strings.h>
26 #include "svn_private_config.h"
28 #include "private/svn_fs_util.h"
29 #include "../libsvn_fs/fs-loader.h"
32 svn_fs__canonicalize_abspath(const char *path
, apr_pool_t
*pool
)
36 int path_i
= 0, newpath_i
= 0;
37 svn_boolean_t eating_slashes
= FALSE
;
39 /* No PATH? No problem. */
43 /* Empty PATH? That's just "/". */
45 return apr_pstrdup(pool
, "/");
47 /* Now, the fun begins. Alloc enough room to hold PATH with an
49 path_len
= strlen(path
);
50 newpath
= apr_pcalloc(pool
, path_len
+ 2);
52 /* No leading slash? Fix that. */
55 newpath
[newpath_i
++] = '/';
58 for (path_i
= 0; path_i
< path_len
; path_i
++)
60 if (path
[path_i
] == '/')
62 /* The current character is a '/'. If we are eating up
63 extra '/' characters, skip this character. Else, note
64 that we are now eating slashes. */
67 eating_slashes
= TRUE
;
71 /* The current character is NOT a '/'. If we were eating
72 slashes, we need not do that any more. */
74 eating_slashes
= FALSE
;
77 /* Copy the current character into our new buffer. */
78 newpath
[newpath_i
++] = path
[path_i
];
81 /* Did we leave a '/' attached to the end of NEWPATH (other than in
82 the root directory case)? */
83 if ((newpath
[newpath_i
- 1] == '/') && (newpath_i
> 1))
84 newpath
[newpath_i
- 1] = '\0';
90 svn_fs__check_fs(svn_fs_t
*fs
,
91 svn_boolean_t expect_open
)
93 if ((expect_open
&& fs
->fsap_data
)
94 || ((! expect_open
) && (! fs
->fsap_data
)))
97 return svn_error_create(SVN_ERR_FS_NOT_OPEN
, 0,
98 _("Filesystem object has not been opened yet"));
100 return svn_error_create(SVN_ERR_FS_ALREADY_OPEN
, 0,
101 _("Filesystem object already open"));
105 svn_fs__next_entry_name(const char **next_p
,
111 /* Find the end of the current component. */
112 end
= strchr(path
, '/');
116 /* The path contains only one component, with no trailing
119 return apr_pstrdup(pool
, path
);
123 /* There's a slash after the first component. Skip over an arbitrary
124 number of slashes to find the next one. */
125 const char *next
= end
;
129 return apr_pstrndup(pool
, path
, end
- path
);