diff --git a/doc/overview.xml b/doc/overview.xml
index 52fe9b9865..e67ad8eb02 100644
--- a/doc/overview.xml
+++ b/doc/overview.xml
@@ -498,7 +498,9 @@ notify(vm);
introduces a new section in the configuration file.
The # character introduces a
- comment that spans until the end of the line.
+ comment that spans until the end of the line. A flag may be
+ passed to limit comments to only # characters
+ which start the line.
diff --git a/include/boost/program_options/detail/config_file.hpp b/include/boost/program_options/detail/config_file.hpp
index be6bba1447..5285d914b9 100644
--- a/include/boost/program_options/detail/config_file.hpp
+++ b/include/boost/program_options/detail/config_file.hpp
@@ -74,7 +74,8 @@ namespace boost { namespace program_options { namespace detail {
common_config_file_iterator() { found_eof(); }
common_config_file_iterator(
const std::set& allowed_options,
- bool allow_unregistered = false);
+ bool allow_unregistered = false,
+ bool limited_comments = false);
virtual ~common_config_file_iterator() {}
@@ -113,6 +114,7 @@ namespace boost { namespace program_options { namespace detail {
std::set allowed_prefixes;
std::string m_prefix;
bool m_allow_unregistered;
+ bool m_limited_comments;
};
template
@@ -127,7 +129,8 @@ namespace boost { namespace program_options { namespace detail {
*/
basic_config_file_iterator(std::basic_istream& is,
const std::set& allowed_options,
- bool allow_unregistered = false);
+ bool allow_unregistered = false,
+ bool limited_comments = false);
private: // base overrides
@@ -151,8 +154,11 @@ namespace boost { namespace program_options { namespace detail {
basic_config_file_iterator::
basic_config_file_iterator(std::basic_istream& is,
const std::set& allowed_options,
- bool allow_unregistered)
- : common_config_file_iterator(allowed_options, allow_unregistered)
+ bool allow_unregistered,
+ bool limited_comments)
+ : common_config_file_iterator(allowed_options,
+ allow_unregistered,
+ limited_comments)
{
this->is.reset(&is, null_deleter());
get();
diff --git a/include/boost/program_options/parsers.hpp b/include/boost/program_options/parsers.hpp
index 0576469278..a60d7d87ad 100644
--- a/include/boost/program_options/parsers.hpp
+++ b/include/boost/program_options/parsers.hpp
@@ -182,8 +182,10 @@ namespace boost { namespace program_options {
BOOST_PROGRAM_OPTIONS_DECL
#endif
basic_parsed_options
- parse_config_file(std::basic_istream&, const options_description&,
- bool allow_unregistered = false);
+ parse_config_file(std::basic_istream&,
+ const options_description&,
+ bool allow_unregistered = false,
+ bool limited_comments = false);
/** Parse a config file.
@@ -199,8 +201,10 @@ namespace boost { namespace program_options {
BOOST_PROGRAM_OPTIONS_DECL
#endif
basic_parsed_options
- parse_config_file(const char* filename, const options_description&,
- bool allow_unregistered = false);
+ parse_config_file(const char* filename,
+ const options_description&,
+ bool allow_unregistered = false,
+ bool limited_comments = false);
/** Controls if the 'collect_unregistered' function should
include positional options, or not. */
diff --git a/src/config_file.cpp b/src/config_file.cpp
index f2a57b4b82..86e6d11cd1 100644
--- a/src/config_file.cpp
+++ b/src/config_file.cpp
@@ -22,9 +22,11 @@ namespace boost { namespace program_options { namespace detail {
common_config_file_iterator::common_config_file_iterator(
const std::set& allowed_options,
- bool allow_unregistered)
+ bool allow_unregistered,
+ bool limited_comments)
: allowed_options(allowed_options),
- m_allow_unregistered(allow_unregistered)
+ m_allow_unregistered(allow_unregistered),
+ m_limited_comments(limited_comments)
{
for(std::set::const_iterator i = allowed_options.begin();
i != allowed_options.end();
@@ -88,9 +90,13 @@ namespace boost { namespace program_options { namespace detail {
while(this->getline(s)) {
// strip '#' comments and whitespace
- if ((n = s.find('#')) != string::npos)
- s = s.substr(0, n);
s = trim_ws(s);
+ if ((n = s.find('#')) != string::npos) {
+ if (!m_limited_comments || n == 0) {
+ s = s.substr(0, n);
+ s = trim_ws(s);
+ }
+ }
if (!s.empty()) {
// Handle section name
diff --git a/src/parsers.cpp b/src/parsers.cpp
index 364fc81a4c..3ae600c24b 100644
--- a/src/parsers.cpp
+++ b/src/parsers.cpp
@@ -101,7 +101,8 @@ namespace boost { namespace program_options {
basic_parsed_options
parse_config_file(std::basic_istream& is,
const options_description& desc,
- bool allow_unregistered)
+ bool allow_unregistered,
+ bool limited_comments)
{
set allowed_options;
@@ -120,7 +121,7 @@ namespace boost { namespace program_options {
// Parser return char strings
parsed_options result(&desc);
copy(detail::basic_config_file_iterator(
- is, allowed_options, allow_unregistered),
+ is, allowed_options, allow_unregistered, limited_comments),
detail::basic_config_file_iterator(),
back_inserter(result.options));
// Convert char strings into desired type.
@@ -131,21 +132,24 @@ namespace boost { namespace program_options {
BOOST_PROGRAM_OPTIONS_DECL basic_parsed_options
parse_config_file(std::basic_istream& is,
const options_description& desc,
- bool allow_unregistered);
+ bool allow_unregistered,
+ bool limited_comments);
#ifndef BOOST_NO_STD_WSTRING
template
BOOST_PROGRAM_OPTIONS_DECL basic_parsed_options
parse_config_file(std::basic_istream& is,
const options_description& desc,
- bool allow_unregistered);
+ bool allow_unregistered,
+ bool limited_comments);
#endif
template
basic_parsed_options
parse_config_file(const char* filename,
const options_description& desc,
- bool allow_unregistered)
+ bool allow_unregistered,
+ bool limited_comments)
{
// Parser return char strings
std::basic_ifstream< charT > strm(filename);
@@ -153,21 +157,26 @@ namespace boost { namespace program_options {
{
boost::throw_exception(reading_file(filename));
}
- return parse_config_file(strm, desc, allow_unregistered);
+ return parse_config_file(strm,
+ desc,
+ allow_unregistered,
+ limited_comments);
}
template
BOOST_PROGRAM_OPTIONS_DECL basic_parsed_options
parse_config_file(const char* filename,
const options_description& desc,
- bool allow_unregistered);
+ bool allow_unregistered,
+ bool limited_comments);
#ifndef BOOST_NO_STD_WSTRING
template
BOOST_PROGRAM_OPTIONS_DECL basic_parsed_options
parse_config_file(const char* filename,
const options_description& desc,
- bool allow_unregistered);
+ bool allow_unregistered,
+ bool limited_comments);
#endif
diff --git a/test/config_test.cfg b/test/config_test.cfg
index 1530f7c8ab..9a4cdd540e 100644
--- a/test/config_test.cfg
+++ b/test/config_test.cfg
@@ -1,6 +1,7 @@
-gv1 = 0#asd
+gv1 = 0 #asd
empty_value =
plug3 = 7
+ # line comment
b = true
[m1]
diff --git a/test/parsers_test.cpp b/test/parsers_test.cpp
index 8f01731dcd..70502594e5 100644
--- a/test/parsers_test.cpp
+++ b/test/parsers_test.cpp
@@ -266,9 +266,10 @@ void test_config_file(const char* config_file)
;
const char content1[] =
- " gv1 = 0#asd\n"
+ " gv1 = 0 #asd\n"
"empty_value = \n"
"plug3 = 7\n"
+ " # line comment\n"
"b = true\n"
"[m1]\n"
"v1 = 1\n"
@@ -298,6 +299,19 @@ void test_config_file(const char* config_file)
check_value(a2[4], "m1.v1", "1");
check_value(a2[5], "m1.v2", "2");
check_value(a2[6], "m1.v3", "3");
+
+ // same test, with # signs in values
+ ss.clear();
+ ss.seekg(0, ios::beg);
+ vector