Alien-SVN
view release on metacpan or search on metacpan
src/subversion/subversion/libsvn_wc/externals.c view on Meta::CPAN
apr_pool_t *scratch_pool)
{
const char *url = item->url;
apr_uri_t parent_dir_uri;
apr_status_t status;
*resolved_url = item->url;
/* If the URL is already absolute, there is nothing to do. */
if (svn_path_is_url(url))
{
/* "http://server/path" */
*resolved_url = svn_uri_canonicalize(url, result_pool);
return SVN_NO_ERROR;
}
if (url[0] == '/')
{
/* "/path", "//path", and "///path" */
int num_leading_slashes = 1;
if (url[1] == '/')
{
num_leading_slashes++;
if (url[2] == '/')
num_leading_slashes++;
}
/* "//schema-relative" and in some cases "///schema-relative".
This last format is supported on file:// schema relative. */
url = apr_pstrcat(scratch_pool,
apr_pstrndup(scratch_pool, url, num_leading_slashes),
svn_relpath_canonicalize(url + num_leading_slashes,
scratch_pool),
(char*)NULL);
}
else
{
/* "^/path" and "../path" */
url = svn_relpath_canonicalize(url, scratch_pool);
}
/* Parse the parent directory URL into its parts. */
status = apr_uri_parse(scratch_pool, parent_dir_url, &parent_dir_uri);
if (status)
return svn_error_createf(SVN_ERR_BAD_URL, 0,
_("Illegal parent directory URL '%s'"),
parent_dir_url);
/* If the parent directory URL is at the server root, then the URL
may have no / after the hostname so apr_uri_parse() will leave
the URL's path as NULL. */
if (! parent_dir_uri.path)
parent_dir_uri.path = apr_pstrmemdup(scratch_pool, "/", 1);
parent_dir_uri.query = NULL;
parent_dir_uri.fragment = NULL;
/* Handle URLs relative to the current directory or to the
repository root. The backpaths may only remove path elements,
not the hostname. This allows an external to refer to another
repository in the same server relative to the location of this
repository, say using SVNParentPath. */
if ((0 == strncmp("../", url, 3)) ||
(0 == strncmp("^/", url, 2)))
{
apr_array_header_t *base_components;
apr_array_header_t *relative_components;
int i;
/* Decompose either the parent directory's URL path or the
repository root's URL path into components. */
if (0 == strncmp("../", url, 3))
{
base_components = svn_path_decompose(parent_dir_uri.path,
scratch_pool);
relative_components = svn_path_decompose(url, scratch_pool);
}
else
{
apr_uri_t repos_root_uri;
status = apr_uri_parse(scratch_pool, repos_root_url,
&repos_root_uri);
if (status)
return svn_error_createf(SVN_ERR_BAD_URL, 0,
_("Illegal repository root URL '%s'"),
repos_root_url);
/* If the repository root URL is at the server root, then
the URL may have no / after the hostname so
apr_uri_parse() will leave the URL's path as NULL. */
if (! repos_root_uri.path)
repos_root_uri.path = apr_pstrmemdup(scratch_pool, "/", 1);
base_components = svn_path_decompose(repos_root_uri.path,
scratch_pool);
relative_components = svn_path_decompose(url + 2, scratch_pool);
}
for (i = 0; i < relative_components->nelts; ++i)
{
const char *component = APR_ARRAY_IDX(relative_components,
i,
const char *);
if (0 == strcmp("..", component))
{
/* Constructing the final absolute URL together with
apr_uri_unparse() requires that the path be absolute,
so only pop a component if the component being popped
is not the component for the root directory. */
if (base_components->nelts > 1)
apr_array_pop(base_components);
}
else
APR_ARRAY_PUSH(base_components, const char *) = component;
}
parent_dir_uri.path = (char *)svn_path_compose(base_components,
scratch_pool);
*resolved_url = svn_uri_canonicalize(apr_uri_unparse(scratch_pool,
&parent_dir_uri, 0),
result_pool);
( run in 0.447 second using v1.01-cache-2.11-cpan-483215c6ad5 )