diff options
-rw-r--r-- | cli/options.cli | 19 | ||||
-rw-r--r-- | cli/options.cxx | 35 | ||||
-rw-r--r-- | cli/options.hxx | 21 | ||||
-rw-r--r-- | cli/options.ixx | 14 | ||||
-rw-r--r-- | doc/cli.1 | 21 | ||||
-rw-r--r-- | doc/cli.xhtml | 22 |
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:: @@ -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> |