Author: rinrab
Date: Sun Apr 5 09:44:54 2026
New Revision: 1932855
Log:
Export a function for parsing a single opt_revision into the public API. We'll
probably use it in svnbrowse. Neither of other tools need it because they
primarly operate over a revision range for which there is a separate function
in the API.
* subversion/include/svn_error_codes.h
(SVN_ERR_OPT_REVISION_PARSE_ERROR): Define new error code.
* subversion/include/svn_opt.h
(svn_opt_parse_one_revision): Define function.
* subversion/libsvn_subr/opt_revision.c
(svn_opt_parse_one_revision): New function; forward most of the logic into
parse_one_rev() + error handling and dup string.
* subversion/tests/libsvn_subr/opt-test.c
(test_parse_one_rev): New stupid test to cover up the fact that this function
has zero usages (yet).
(test_funcs): Run new test.
Modified:
subversion/trunk/subversion/include/svn_error_codes.h
subversion/trunk/subversion/include/svn_opt.h
subversion/trunk/subversion/libsvn_subr/opt_revision.c
subversion/trunk/subversion/tests/libsvn_subr/opt-test.c
Modified: subversion/trunk/subversion/include/svn_error_codes.h
==============================================================================
--- subversion/trunk/subversion/include/svn_error_codes.h Sun Apr 5
08:30:18 2026 (r1932854)
+++ subversion/trunk/subversion/include/svn_error_codes.h Sun Apr 5
09:44:54 2026 (r1932855)
@@ -1435,6 +1435,11 @@ SVN_ERROR_START
SVN_ERR_MISC_CATEGORY_START + 31,
"Attempted to write to readonly SQLite db")
+ /** @since New in 1.16. */
+ SVN_ERRDEF(SVN_ERR_OPT_REVISION_PARSE_ERROR,
+ SVN_ERR_MISC_CATEGORY_START + 32,
+ "Error parsing revision argument")
+
/** @since New in 1.6.
* @deprecated the internal sqlite support code does not manage schemas
* any longer. */
Modified: subversion/trunk/subversion/include/svn_opt.h
==============================================================================
--- subversion/trunk/subversion/include/svn_opt.h Sun Apr 5 08:30:18
2026 (r1932854)
+++ subversion/trunk/subversion/include/svn_opt.h Sun Apr 5 09:44:54
2026 (r1932855)
@@ -501,6 +501,18 @@ svn_error_t *
svn_opt_parse_revnum(svn_revnum_t *rev, const char *str);
/**
+ * Parse one revision specification from @a arg into @a revision. Use @a
+ * scratch_pool for temporary allocation.
+ *
+ * @since New in 1.16
+ * @see svn_opt_parse_revision
+ */
+svn_error_t *
+svn_opt_parse_one_revision(svn_opt_revision_t *revision,
+ const char *arg,
+ apr_pool_t *scratch_pool);
+
+/**
* Set @a *start_revision and/or @a *end_revision according to @a arg,
* where @a arg is "N" or "N:M", like so:
*
Modified: subversion/trunk/subversion/libsvn_subr/opt_revision.c
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/opt_revision.c Sun Apr 5
08:30:18 2026 (r1932854)
+++ subversion/trunk/subversion/libsvn_subr/opt_revision.c Sun Apr 5
09:44:54 2026 (r1932855)
@@ -159,6 +159,21 @@ static char *parse_one_rev(svn_opt_revis
return NULL;
}
+svn_error_t *
+svn_opt_parse_one_revision(svn_opt_revision_t *revision,
+ const char *arg,
+ apr_pool_t *scratch_pool)
+{
+ /* copy because parse_one_rev() will mess up the string */
+ char *str = apr_pstrdup(scratch_pool, arg);
+ char *end = parse_one_rev(revision, str, scratch_pool);
+
+ if (! end || *end != '\0')
+ return svn_error_createf(SVN_ERR_OPT_REVISION_PARSE_ERROR, NULL,
+ "Error parsing revision argument '%s'", arg);
+
+ return SVN_NO_ERROR;
+}
int
svn_opt_parse_revision(svn_opt_revision_t *start_revision,
Modified: subversion/trunk/subversion/tests/libsvn_subr/opt-test.c
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_subr/opt-test.c Sun Apr 5
08:30:18 2026 (r1932854)
+++ subversion/trunk/subversion/tests/libsvn_subr/opt-test.c Sun Apr 5
09:44:54 2026 (r1932855)
@@ -263,6 +263,31 @@ test_svn_opt_parse_change_to_range(apr_p
return SVN_NO_ERROR;
}
+static svn_error_t *
+test_parse_one_rev(apr_pool_t *pool)
+{
+ {
+ svn_opt_revision_t rev = { 0 };
+ SVN_ERR(svn_opt_parse_one_revision(&rev, "r123", pool));
+ SVN_TEST_INT_ASSERT(rev.kind, svn_opt_revision_number);
+ SVN_TEST_INT_ASSERT(rev.value.number, 123);
+ }
+
+ {
+ svn_opt_revision_t rev = { 0 };
+ SVN_TEST_ASSERT_ERROR(svn_opt_parse_one_revision(&rev, "bad", pool),
+ SVN_ERR_OPT_REVISION_PARSE_ERROR);
+ }
+
+ {
+ svn_opt_revision_t rev = { 0 };
+ SVN_TEST_ASSERT_ERROR(svn_opt_parse_one_revision(&rev, "r123bad", pool),
+ SVN_ERR_OPT_REVISION_PARSE_ERROR);
+ }
+
+ return SVN_NO_ERROR;
+}
+
/* The test table. */
@@ -277,6 +302,8 @@ static struct svn_test_descriptor_t test
"test svn_opt_args_to_target_array2"),
SVN_TEST_PASS2(test_svn_opt_parse_change_to_range,
"test svn_opt_parse_change_to_range"),
+ SVN_TEST_PASS2(test_parse_one_rev,
+ "test svn_opt_parse_one_revision"),
SVN_TEST_NULL
};