Author: rinrab
Date: Sat May 31 19:11:16 2025
New Revision: 1926013
URL: http://svn.apache.org/viewvc?rev=1926013&view=rev
Log:
On the 'utf8-cmdline-prototype' branch: Checkpoint svn_opt__target_t stuff.
This seems pretty good to implement our target utils, because we could
parse everything once. I'll try to rewrite those utils and cmdline I guess...
* subversion/include/private/svn_opt_private.h
(svn_opt__target_type_e,
svn_opt__target_t,
svn_opt__target_parse,
svn_opt__target_to_string,
svn_opt__target_resolve,
svn_opt__target_array_parse,
svn_opt__target_array_to_string): Declare.
* subversion/libsvn_subr/opt.c
(svn_opt__target_parse,
svn_opt__target_to_string,
svn_opt__target_resolve,
svn_opt__target_array_parse,
svn_opt__target_array_to_string): Implement.
Modified:
subversion/branches/utf8-cmdline-prototype/subversion/include/private/svn_opt_private.h
subversion/branches/utf8-cmdline-prototype/subversion/libsvn_subr/opt.c
Modified:
subversion/branches/utf8-cmdline-prototype/subversion/include/private/svn_opt_private.h
URL:
http://svn.apache.org/viewvc/subversion/branches/utf8-cmdline-prototype/subversion/include/private/svn_opt_private.h?rev=1926013&r1=1926012&r2=1926013&view=diff
==============================================================================
---
subversion/branches/utf8-cmdline-prototype/subversion/include/private/svn_opt_private.h
(original)
+++
subversion/branches/utf8-cmdline-prototype/subversion/include/private/svn_opt_private.h
Sat May 31 19:11:16 2025
@@ -165,6 +165,105 @@ svn_opt__revision_range_from_revnums(svn
svn_revnum_t end_revnum,
apr_pool_t *result_pool);
+/**
+ *
+ */
+typedef enum svn_opt__target_type_e
+{
+ svn_opt__target_type_local_abspath,
+ svn_opt__target_type_absolute_url,
+ svn_opt__target_type_relative_url
+
+} svn_opt__target_type_e;
+
+/**
+ * Stores info about a parsed target.
+ *
+ * FIXME: peg_revision wouldn yet be an empty string instead of NULL if
+ * one wasn't found.
+ *
+ * TODO: potentially also parse peg_revision to svn_opt_revision_t so we
+ * won't need to do it later in the cmdline.
+ *
+ * TODO: add an option to reject all peg revisions which might be useful,
+ * for example, in svnadmin, which doesn't support it by design.
+ *
+ * TODO: pass this directly into the cmdline so we won't need to parse
+ * targets twice and could operate with pretty parsed ones.
+ */
+typedef struct svn_opt__target_t
+{
+ /* Type of the target */
+ svn_opt__target_type_e type;
+
+ /* Path component of the target */
+ const char *true_target;
+
+ /* Peg revision of the target or @c NULL if it wasn't found */
+ const char *peg_revision;
+
+} svn_opt__target_t;
+
+/**
+ * Parses a target described in @a str into @a target_p, allocated in @a pool.
+ *
+ * If the target represents a relative URL and @a rel_url_found_p is not
+ * @c NULL, sets it to @c TRUE.
+ */
+svn_error_t *
+svn_opt__target_parse(svn_opt__target_t **target_p,
+ svn_boolean_t *rel_url_found_p,
+ const char *str,
+ apr_pool_t *pool);
+
+/**
+ * Converts @a target back into its canonical string representation,
+ * including svn_opt__target_t::peg_revision, and sets @a path_p with
+ * the result.
+ */
+svn_error_t *
+svn_opt__target_to_string(const char **path_p,
+ svn_opt__target_t *target,
+ apr_pool_t *pool);
+
+/**
+ * Resolves @a target of type @c svn_opt__target_type_relative_url, by
+ * adding @a root path before and changing type to @c
+ * svn_opt__target_type_absolute_url.
+ */
+svn_error_t *
+svn_opt__target_resolve(svn_opt__target_t *target,
+ const char *root,
+ apr_pool_t *pool);
+
+/**
+ * Parses targets described in @a paths (an array of const char *)
+ * into @a targets_p (an array of svn_opt__target_t *).
+ *
+ * If any of the targets represents a relative URL and @a rel_url_found_p
+ * is not @c NULL, sets it to @c TRUE.
+ *
+ * @see svn_opt__target_parse()
+ */
+svn_error_t *
+svn_opt__target_array_parse(apr_array_header_t **targets_p,
+ svn_boolean_t *rel_url_found_p,
+ apr_array_header_t *paths,
+ apr_pool_t *pool);
+
+/**
+ * Converts all targets in @a targets (an array of svn_opt__target_t *)
+ * back into its canonical string representation, including
+ * svn_opt__target_t::peg_revision, and sets @a path_p (an array of
+ * const char *) with the result.
+ *
+ * @see svn_opt__target_to_string()
+ */
+svn_error_t *
+svn_opt__target_array_to_string(apr_array_header_t **paths_p,
+ apr_array_header_t *targets,
+ apr_pool_t *pool);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
Modified:
subversion/branches/utf8-cmdline-prototype/subversion/libsvn_subr/opt.c
URL:
http://svn.apache.org/viewvc/subversion/branches/utf8-cmdline-prototype/subversion/libsvn_subr/opt.c?rev=1926013&r1=1926012&r2=1926013&view=diff
==============================================================================
--- subversion/branches/utf8-cmdline-prototype/subversion/libsvn_subr/opt.c
(original)
+++ subversion/branches/utf8-cmdline-prototype/subversion/libsvn_subr/opt.c Sat
May 31 19:11:16 2025
@@ -549,3 +549,120 @@ svn_opt__arg_canonicalize_path(const cha
return SVN_NO_ERROR;
}
+
+svn_error_t *
+svn_opt__target_parse(svn_opt__target_t **target_p,
+ svn_boolean_t *rel_url_found_p,
+ const char *path,
+ apr_pool_t *pool)
+{
+ svn_opt__target_t *new_target = apr_pcalloc(pool,
+ sizeof(*new_target));
+
+ SVN_ERR(svn_opt__split_arg_at_peg_revision(&new_target->true_target,
+ &new_target->peg_revision,
+ path, pool));
+
+ if (svn_path_is_repos_relative_url(path))
+ {
+ new_target->type = svn_opt__target_type_relative_url;
+
+ if (rel_url_found_p != NULL)
+ *rel_url_found_p = TRUE;
+ }
+ if (svn_path_is_url(path))
+ new_target->type = svn_opt__target_type_absolute_url;
+ else
+ new_target->type = svn_opt__target_type_local_abspath;
+
+ *target_p = new_target;
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_opt__target_to_string(const char **path_p,
+ svn_opt__target_t *target,
+ apr_pool_t *pool)
+{
+ const char *canonical_target;
+
+ if (target->type == svn_opt__target_type_absolute_url
+ || target->type == svn_opt__target_type_relative_url)
+ {
+ SVN_ERR(svn_opt__arg_canonicalize_url(&canonical_target,
+ target->true_target, pool));
+ }
+ else
+ {
+ canonical_target = target->true_target;
+ }
+
+ *path_p = apr_pstrcat(pool, canonical_target,
+ target->peg_revision, SVN_VA_NULL);
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_opt__target_resolve(svn_opt__target_t *target,
+ const char *root,
+ apr_pool_t *pool)
+{
+ const char *abs_target;
+
+ assert(target->type == svn_opt__target_type_relative_url);
+
+ SVN_ERR(svn_path_resolve_repos_relative_url(&abs_target, target->true_target,
+ root, pool));
+
+ target->true_target = abs_target;
+ target->type = svn_opt__target_type_absolute_url;
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_opt__target_array_parse(apr_array_header_t **targets_p,
+ svn_boolean_t *rel_url_found_p,
+ apr_array_header_t *paths,
+ apr_pool_t *pool)
+{
+ int i;
+
+ if (*targets_p != NULL)
+ *targets_p = apr_array_make(pool, DEFAULT_ARRAY_SIZE,
+ sizeof(svn_opt__target_t *));
+
+ for (i = 0; i < paths->nelts; i++)
+ {
+ const char *path = APR_ARRAY_IDX(paths, i, const char *);
+ svn_opt__target_t *target;
+
+ SVN_ERR(svn_opt__target_parse(&target, rel_url_found_p, path, pool));
+ APR_ARRAY_PUSH(*targets_p, svn_opt__target_t *) = target;
+ }
+
+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_opt__target_array_to_string(apr_array_header_t **paths_p,
+ apr_array_header_t *targets,
+ apr_pool_t *pool)
+{
+ int i;
+
+ if (*paths_p != NULL)
+ *paths_p = apr_array_make(pool, DEFAULT_ARRAY_SIZE, sizeof(const char *));
+
+ for (i = 0; i < targets->nelts; i++)
+ {
+ const char *path;
+ svn_opt__target_t *target = APR_ARRAY_IDX(targets, i,
+ svn_opt__target_t *);
+
+ SVN_ERR(svn_opt__target_to_string(&path, target, pool));
+ APR_ARRAY_PUSH(*paths_p, const char *) = path;
+ }
+
+ return SVN_NO_ERROR;
+}