summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/options.cli19
-rw-r--r--cli/options.cxx35
-rw-r--r--cli/options.hxx21
-rw-r--r--cli/options.ixx14
-rw-r--r--doc/cli.121
-rw-r--r--doc/cli.xhtml22
6 files changed, 113 insertions, 19 deletions
diff --git a/cli/options.cli b/cli/options.cli
index dff5443..58f9565 100644
--- a/cli/options.cli
+++ b/cli/options.cli
@@ -213,11 +213,18 @@ class options
"<file>",
"Read additional options from <file> with each option appearing on a
separate line optionally followed by space and an option value. Empty
- lines and lines starting with \cb{#} are ignored. The semantics of
- providing options in a file is equivalent to providing the same set
- of options in the same order on the command line at the point where the
- \cb{--options-file} option is specified except that shell escaping and
- quoting is not required. Repeat this option to specify more than one
- options files."
+ lines and lines starting with \cb{#} are ignored. Option values can
+ be enclosed in double quotes (\cb{\"\"}) to preserve leading and
+ trailing whitespaces as well as to specify empty values. If the value
+ itself contains trailing or leading double quote, enclose it with an
+ extra pair of double quotes, for example \cb{\"\"x\"\"}. Non-leading
+ and non-trailing quotes are interpreted as being part of the option
+ value.
+
+ The semantics of providing options in a file is equivalent to providing
+ the same set of options in the same order on the command line at the
+ point where the \cb{--options-file} option is specified except that
+ the shell escaping and quoting is not required. Repeat this option
+ to specify more than one options files."
};
};
diff --git a/cli/options.cxx b/cli/options.cxx
index a079f9e..3f3c1b9 100644
--- a/cli/options.cxx
+++ b/cli/options.cxx
@@ -125,6 +125,25 @@ namespace cli
return "unable to open file or read failure";
}
+ // unmatched_quote
+ //
+ unmatched_quote::
+ ~unmatched_quote () throw ()
+ {
+ }
+
+ void unmatched_quote::
+ print (std::ostream& os) const
+ {
+ os << "unmatched quote in argument '" << argument () << "'";
+ }
+
+ const char* unmatched_quote::
+ what () const throw ()
+ {
+ return "unmatched quote";
+ }
+
// scanner
//
scanner::
@@ -329,6 +348,18 @@ namespace cli
string s2 (line, p);
+ // If the string is wrapped in quotes, remove them.
+ //
+ n = s2.size ();
+
+ if (s2[0] == '"' || s2[n - 1] == '"')
+ {
+ if (n == 1 || s2[0] != s2[n - 1])
+ throw unmatched_quote (s2);
+
+ s2 = string (s2, 1, n - 2);
+ }
+
if (!skip_ && s1 == option_)
load (s2.c_str ());
else
@@ -468,11 +499,11 @@ namespace cli
}
};
- template <typename X, typename T, T X::*P>
+ template <typename X, typename T, T X::*M>
void
thunk (X& x, scanner& s)
{
- parser<T>::parse (x.*P, s);
+ parser<T>::parse (x.*M, s);
}
}
diff --git a/cli/options.hxx b/cli/options.hxx
index e17a7d3..2c60c83 100644
--- a/cli/options.hxx
+++ b/cli/options.hxx
@@ -166,6 +166,27 @@ namespace cli
std::string file_;
};
+ class unmatched_quote: public exception
+ {
+ public:
+ virtual
+ ~unmatched_quote () throw ();
+
+ unmatched_quote (const std::string& argument);
+
+ const std::string&
+ argument () const;
+
+ virtual void
+ print (std::ostream&) const;
+
+ virtual const char*
+ what () const throw ();
+
+ private:
+ std::string argument_;
+ };
+
class scanner
{
public:
diff --git a/cli/options.ixx b/cli/options.ixx
index df0e39e..4a5b17e 100644
--- a/cli/options.ixx
+++ b/cli/options.ixx
@@ -98,6 +98,20 @@ namespace cli
return file_;
}
+ // unmatched_quote
+ //
+ inline unmatched_quote::
+ unmatched_quote (const std::string& argument)
+ : argument_ (argument)
+ {
+ }
+
+ inline const std::string& unmatched_quote::
+ argument () const
+ {
+ return argument_;
+ }
+
// argv_scanner
//
inline argv_scanner::
diff --git a/doc/cli.1 b/doc/cli.1
index b42652e..739b845 100644
--- a/doc/cli.1
+++ b/doc/cli.1
@@ -73,6 +73,10 @@ Write the generated files to \fIdir\fP instead of the current directory\.
.IP "\fB--generate-modifier\fP"
Generate option value modifiers in addition to accessors\.
+.IP "\fB--generate-specifier\fP"
+Generate functions for determining whether the option was specified on the
+command line\.
+
.IP "\fB--generate-file-scanner\fP"
Generate the argv_file_scanner implementation\. This scanner is capable of
reading command line arguments from the argv array as well as files
@@ -181,11 +185,18 @@ is used instead\. All C++ keywords are already in this list\.
.IP "\fB--options-file\fP \fIfile\fP"
Read additional options from \fIfile\fP with each option appearing on a
separate line optionally followed by space and an option value\. Empty lines
-and lines starting with \fB#\fP are ignored\. The semantics of providing
-options in a file is equivalent to providing the same set of options in the
-same order on the command line at the point where the \fB--options-file\fP
-option is specified except that shell escaping and quoting is not required\.
-Repeat this option to specify more than one options files\.
+and lines starting with \fB#\fP are ignored\. Option values can be enclosed
+in double quotes (\fB""\fP) to preserve leading and trailing whitespaces as
+well as to specify empty values\. If the value itself contains trailing or
+leading double quote, enclose it with an extra pair of double quotes, for
+example \fB""x""\fP\. Non-leading and non-trailing quotes are interpreted as
+being part of the option value\.
+
+The semantics of providing options in a file is equivalent to providing the
+same set of options in the same order on the command line at the point where
+the \fB--options-file\fP option is specified except that the shell escaping
+and quoting is not required\. Repeat this option to specify more than one
+options files\.
.\"
.\" DIAGNOSTICS
diff --git a/doc/cli.xhtml b/doc/cli.xhtml
index d39e8ac..5a136af 100644
--- a/doc/cli.xhtml
+++ b/doc/cli.xhtml
@@ -96,6 +96,10 @@
<dt><code><b>--generate-modifier</b></code></dt>
<dd>Generate option value modifiers in addition to accessors.</dd>
+ <dt><code><b>--generate-specifier</b></code></dt>
+ <dd>Generate functions for determining whether the option was specified on the
+ command line.</dd>
+
<dt><code><b>--generate-file-scanner</b></code></dt>
<dd>Generate the <code>argv_file_scanner</code> implementation. This scanner is
capable of reading command line arguments from the <code>argv</code> array
@@ -207,12 +211,18 @@
<dt><code><b>--options-file</b></code> <i>file</i></dt>
<dd>Read additional options from <i>file</i> with each option appearing on a
separate line optionally followed by space and an option value. Empty lines
- and lines starting with <code><b>#</b></code> are ignored. The semantics of
- providing options in a file is equivalent to providing the same set of
- options in the same order on the command line at the point where the
- <code><b>--options-file</b></code> option is specified except that shell
- escaping and quoting is not required. Repeat this option to specify more
- than one options files.</dd>
+ and lines starting with <code><b>#</b></code> are ignored. Option values can
+ be enclosed in double quotes (<code><b>""</b></code>) to preserve leading
+ and trailing whitespaces as well as to specify empty values. If the value
+ itself contains trailing or leading double quote, enclose it with an extra
+ pair of double quotes, for example <code><b>""x""</b></code>. Non-leading
+ and non-trailing quotes are interpreted as being part of the option value.
+
+ <p>The semantics of providing options in a file is equivalent to providing
+ the same set of options in the same order on the command line at the point
+ where the <code><b>--options-file</b></code> option is specified except that
+ the shell escaping and quoting is not required. Repeat this option to
+ specify more than one options files.</p></dd>
</dl>
<h1>DIAGNOSTICS</h1>