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; +}