From 840f2fae3995a3e263801ad07d1285d35ddd9485 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 2 Jun 2010 19:00:38 +0200 Subject: Update description of the --options-file option --- cli/options.cli | 19 +++++++++++++------ cli/options.cxx | 35 +++++++++++++++++++++++++++++++++-- cli/options.hxx | 21 +++++++++++++++++++++ cli/options.ixx | 14 ++++++++++++++ 4 files changed, 81 insertions(+), 8 deletions(-) (limited to 'cli') 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 "", "Read additional options from 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 + template void thunk (X& x, scanner& s) { - parser::parse (x.*P, s); + parser::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:: -- cgit v1.1