Author: breser
Date: Tue Nov 27 19:48:46 2012
New Revision: 1414356
URL: http://svn.apache.org/viewvc?rev=1414356&view=rev
Log:
On the in-repo-authz branch: Add svn_config_parse() for parsing a config file
from a stream.
Note that since the stream code is now separated from the source file code
the filename and line number that errors in config files occur on will be
in separate svn_error_t structures and thusly printed on separate lines by
the command line client. Error output has been adjusted so the line number
error has "line %d:" now.
* subversion/libsvn_subr/config_file.c
(svn_config__parse_file): Factor out the processing of the stream out.
(svn_config__parse_stream): Add.
* subversion/libsvn_subr/config_impl.h
(svn_config__parse_stream): Add.
* subversion/libsvn_subr/config.c
(svn_config_parse): Add.
* subversion/libsvn_subr/config-test.c
(test_stream_interface): Add new test for svn_config_parse().
(test_funcs): Add test_stream_interface() to list of tests.
* subversion/include/svn_config.h
(svn_config_parse): Add.
Modified:
subversion/branches/in-repo-authz/subversion/include/svn_config.h
subversion/branches/in-repo-authz/subversion/libsvn_subr/config.c
subversion/branches/in-repo-authz/subversion/libsvn_subr/config_file.c
subversion/branches/in-repo-authz/subversion/libsvn_subr/config_impl.h
subversion/branches/in-repo-authz/subversion/tests/libsvn_subr/config-test.c
Modified: subversion/branches/in-repo-authz/subversion/include/svn_config.h
URL:
http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/include/svn_config.h?rev=1414356&r1=1414355&r2=1414356&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/include/svn_config.h (original)
+++ subversion/branches/in-repo-authz/subversion/include/svn_config.h Tue Nov
27 19:48:46 2012
@@ -34,6 +34,7 @@
#include <apr_hash.h> /* for apr_hash_t */
#include "svn_types.h"
+#include "svn_io.h"
#ifdef __cplusplus
extern "C" {
@@ -242,6 +243,21 @@ svn_config_read(svn_config_t **cfgp,
svn_boolean_t must_exist,
apr_pool_t *pool);
+/** Read configuration data from @a stream into @a *cfgp, allocated in
+ * @a result_pool.
+ *
+ * If @a section_names_case_sensitive is TRUE, populate section name hashes
+ * case sensitively, except for the default SVN_CONFIG__DEFAULT_SECTION.
+ *
+ * @since New in 1.8.
+ */
+
+svn_error_t *
+svn_config_parse(svn_config_t **cfgp,
+ svn_stream_t *stream,
+ svn_boolean_t section_names_case_sensitive,
+ apr_pool_t *result_pool);
+
/** Like svn_config_read(), but merges the configuration data from @a file
* (a file or registry path) into @a *cfg, which was previously returned
* from svn_config_read(). This function invalidates all value
Modified: subversion/branches/in-repo-authz/subversion/libsvn_subr/config.c
URL:
http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_subr/config.c?rev=1414356&r1=1414355&r2=1414356&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_subr/config.c (original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_subr/config.c Tue Nov
27 19:48:46 2012
@@ -129,7 +129,27 @@ svn_config_read2(svn_config_t **cfgp, co
return SVN_NO_ERROR;
}
+svn_error_t *
+svn_config_parse(svn_config_t **cfgp, svn_stream_t *stream,
+ svn_boolean_t section_names_case_sensitive,
+ apr_pool_t *result_pool)
+{
+ svn_config_t *cfg;
+ svn_error_t *err;
+ apr_pool_t *scratch_pool = svn_pool_create(result_pool);
+
+ err = svn_config_create(&cfg, section_names_case_sensitive, result_pool);
+ if (err == SVN_NO_ERROR)
+ err = svn_config__parse_stream(cfg, stream, result_pool, scratch_pool);
+
+ if (err == SVN_NO_ERROR)
+ *cfgp = cfg;
+
+ svn_pool_destroy(scratch_pool);
+
+ return err;
+}
/* Read various configuration sources into *CFGP, in this order, with
* later reads overriding the results of earlier ones:
Modified: subversion/branches/in-repo-authz/subversion/libsvn_subr/config_file.c
URL:
http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_subr/config_file.c?rev=1414356&r1=1414355&r2=1414356&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_subr/config_file.c
(original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_subr/config_file.c Tue
Nov 27 19:48:46 2012
@@ -50,11 +50,10 @@
/* File parsing context */
typedef struct parse_context_t
{
- /* This config struct and file */
+ /* This config struct */
svn_config_t *cfg;
- const char *file;
- /* The file descriptor */
+ /* The stream struct */
svn_stream_t *stream;
/* The current line in the file */
@@ -296,8 +295,7 @@ parse_option(int *pch, parse_context_t *
{
ch = EOF;
err = svn_error_createf(SVN_ERR_MALFORMED_FILE, NULL,
- "%s:%d: Option must end with ':' or '='",
- svn_dirent_local_style(ctx->file, scratch_pool),
+ "line %d: Option must end with ':' or '='",
ctx->line);
}
else
@@ -340,8 +338,7 @@ parse_section_name(int *pch, parse_conte
{
ch = EOF;
err = svn_error_createf(SVN_ERR_MALFORMED_FILE, NULL,
- "%s:%d: Section header must end with ']'",
- svn_dirent_local_style(ctx->file, scratch_pool),
+ "line %d: Section header must end with ']'",
ctx->line);
}
else
@@ -404,8 +401,6 @@ svn_config__parse_file(svn_config_t *cfg
svn_boolean_t must_exist, apr_pool_t *result_pool)
{
svn_error_t *err = SVN_NO_ERROR;
- parse_context_t *ctx;
- int ch, count;
svn_stream_t *stream;
apr_pool_t *scratch_pool = svn_pool_create(result_pool);
@@ -420,10 +415,32 @@ svn_config__parse_file(svn_config_t *cfg
else
SVN_ERR(err);
+ err = svn_config__parse_stream(cfg, stream, result_pool, scratch_pool);
+
+ if (err != SVN_NO_ERROR)
+ {
+ /* Add the filename to the error stack. */
+ err = svn_error_createf(err->apr_err, err,
+ "Error while parsing config file: %s:",
+ svn_dirent_local_style(file, scratch_pool));
+ }
+
+ /* Close the streams (and other cleanup): */
+ svn_pool_destroy(scratch_pool);
+
+ return err;
+}
+
+svn_error_t *
+svn_config__parse_stream(svn_config_t *cfg, svn_stream_t *stream,
+ apr_pool_t *result_pool, apr_pool_t *scratch_pool)
+{
+ parse_context_t *ctx;
+ int ch, count;
+
ctx = apr_palloc(scratch_pool, sizeof(*ctx));
ctx->cfg = cfg;
- ctx->file = file;
ctx->stream = stream;
ctx->line = 1;
ctx->ungotten_char = EOF;
@@ -444,10 +461,8 @@ svn_config__parse_file(svn_config_t *cfg
SVN_ERR(parse_section_name(&ch, ctx, scratch_pool));
else
return svn_error_createf(SVN_ERR_MALFORMED_FILE, NULL,
- "%s:%d: Section header"
+ "line %d: Section header"
" must start in the first column",
- svn_dirent_local_style(file,
- scratch_pool),
ctx->line);
break;
@@ -459,10 +474,8 @@ svn_config__parse_file(svn_config_t *cfg
}
else
return svn_error_createf(SVN_ERR_MALFORMED_FILE, NULL,
- "%s:%d: Comment"
+ "line %d: Comment"
" must start in the first column",
- svn_dirent_local_style(file,
- scratch_pool),
ctx->line);
break;
@@ -476,15 +489,11 @@ svn_config__parse_file(svn_config_t *cfg
default:
if (svn_stringbuf_isempty(ctx->section))
return svn_error_createf(SVN_ERR_MALFORMED_FILE, NULL,
- "%s:%d: Section header expected",
- svn_dirent_local_style(file,
- scratch_pool),
+ "line %d: Section header expected",
ctx->line);
else if (count != 0)
return svn_error_createf(SVN_ERR_MALFORMED_FILE, NULL,
- "%s:%d: Option expected",
- svn_dirent_local_style(file,
- scratch_pool),
+ "line %d: Option expected",
ctx->line);
else
SVN_ERR(parse_option(&ch, ctx, scratch_pool));
@@ -493,8 +502,6 @@ svn_config__parse_file(svn_config_t *cfg
}
while (ch != EOF);
- /* Close the streams (and other cleanup): */
- svn_pool_destroy(scratch_pool);
return SVN_NO_ERROR;
}
Modified: subversion/branches/in-repo-authz/subversion/libsvn_subr/config_impl.h
URL:
http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/libsvn_subr/config_impl.h?rev=1414356&r1=1414355&r2=1414356&view=diff
==============================================================================
--- subversion/branches/in-repo-authz/subversion/libsvn_subr/config_impl.h
(original)
+++ subversion/branches/in-repo-authz/subversion/libsvn_subr/config_impl.h Tue
Nov 27 19:48:46 2012
@@ -32,6 +32,7 @@
#include <apr_hash.h>
#include "svn_types.h"
#include "svn_string.h"
+#include "svn_io.h"
#include "svn_config.h"
#include "svn_private_config.h"
@@ -75,6 +76,12 @@ svn_error_t *svn_config__parse_file(svn_
svn_boolean_t must_exist,
apr_pool_t *pool);
+/* Read sections and options from a stream. */
+svn_error_t *svn_config__parse_stream(svn_config_t *cfg,
+ svn_stream_t *stream,
+ apr_pool_t *result_pool,
+ apr_pool_t *scratch_pool);
+
/* The name of the magic [DEFAULT] section. */
#define SVN_CONFIG__DEFAULT_SECTION "DEFAULT"
Modified:
subversion/branches/in-repo-authz/subversion/tests/libsvn_subr/config-test.c
URL:
http://svn.apache.org/viewvc/subversion/branches/in-repo-authz/subversion/tests/libsvn_subr/config-test.c?rev=1414356&r1=1414355&r2=1414356&view=diff
==============================================================================
---
subversion/branches/in-repo-authz/subversion/tests/libsvn_subr/config-test.c
(original)
+++
subversion/branches/in-repo-authz/subversion/tests/libsvn_subr/config-test.c
Tue Nov 27 19:48:46 2012
@@ -269,6 +269,31 @@ test_has_section_case_sensitive(apr_pool
return SVN_NO_ERROR;
}
+
+static svn_error_t *
+test_stream_interface(apr_pool_t *pool)
+{
+ svn_config_t *cfg;
+ const char *cfg_file;
+ svn_stream_t *stream;
+
+ if (!srcdir)
+ SVN_ERR(init_params(pool));
+
+ cfg_file = apr_pstrcat(pool, srcdir, "/", "config-test.cfg", (char *)NULL);
+ SVN_ERR(svn_stream_open_readonly(&stream, cfg_file, pool, pool));
+
+ SVN_ERR(svn_config_parse(&cfg, stream, TRUE, pool));
+
+ /* nominal test to make sure cfg is populated with something since
+ * svn_config_parse will happily return an empty cfg if the stream is
+ * empty. */
+ if (! svn_config_has_section(cfg, "section1"))
+ return fail(pool, "Failed to find section1");
+
+ return SVN_NO_ERROR;
+}
+
/*
====================================================================
If you add a new test to this file, update this array.
@@ -288,5 +313,7 @@ struct svn_test_descriptor_t test_funcs[
"test svn_config_has_section (case insensitive)"),
SVN_TEST_PASS2(test_has_section_case_sensitive,
"test svn_config_has_section (case sensitive)"),
+ SVN_TEST_PASS2(test_stream_interface,
+ "test svn_config_parse"),
SVN_TEST_NULL
};