From f8edfd22cb45b554a573d2722900196758e9e958 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 10 Dec 2009 09:47:29 +0200 Subject: Scanner-based parsing with support for element erasing Also implement argv_file_scanner which provides support for reading command line arguments from the argv array as well as files specified with command line options. New examples: file. New tests: ctor, erase, file. --- doc/cli.1 | 5 ++ doc/cli.xhtml | 5 ++ doc/guide/index.xhtml | 148 +++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 151 insertions(+), 7 deletions(-) (limited to 'doc') diff --git a/doc/cli.1 b/doc/cli.1 index 7c89ace..0a2021f 100644 --- a/doc/cli.1 +++ b/doc/cli.1 @@ -73,6 +73,11 @@ 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-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 +specified with command line options\. + .IP "\fB--suppress-inline\fP" Generate all functions non-inline\. By default simple functions are made inline\. This option suppresses creation of the inline file\. diff --git a/doc/cli.xhtml b/doc/cli.xhtml index e431f97..3389c77 100644 --- a/doc/cli.xhtml +++ b/doc/cli.xhtml @@ -96,6 +96,11 @@
--generate-modifier
Generate option value modifiers in addition to accessors.
+
--generate-file-scanner
+
Generate the argv_file_scanner implementation. This scanner is + capable of reading command line arguments from the argv array + as well as files specified with command line options.
+
--suppress-inline
Generate all functions non-inline. By default simple functions are made inline. This option suppresses creation of the inline file.
diff --git a/doc/guide/index.xhtml b/doc/guide/index.xhtml index 89f56e7..0b43209 100644 --- a/doc/guide/index.xhtml +++ b/doc/guide/index.xhtml @@ -561,27 +561,35 @@ class options class options { public: - options (int argc, + options (int& argc, char** argv, + bool erase = false, cli::unknown_mode opt_mode = cli::unknown_mode::fail, cli::unknown_mode arg_mode = cli::unknown_mode::stop); options (int start, - int argc, + int& argc, char** argv, + bool erase = false, cli::unknown_mode opt_mode = cli::unknown_mode::fail, cli::unknown_mode arg_mode = cli::unknown_mode::stop); - options (int argc, + options (int& argc, char** argv, int& end, + bool erase = false, cli::unknown_mode opt_mode = cli::unknown_mode::fail, cli::unknown_mode arg_mode = cli::unknown_mode::stop); options (int start, - int argc, + int& argc, char** argv, int& end, + bool erase = false, + cli::unknown_mode opt_mode = cli::unknown_mode::fail, + cli::unknown_mode arg_mode = cli::unknown_mode::stop); + + options (cli::scanner&, cli::unknown_mode opt_mode = cli::unknown_mode::fail, cli::unknown_mode arg_mode = cli::unknown_mode::stop); @@ -621,7 +629,10 @@ public: from position 1, skipping the executable name in argv[0]. The end argument is used to return the position in the arguments array where the parsing of options stopped. This is the - position of the first program argument, if any.

+ position of the first program argument, if any. If the erase + argument is true, then the recognized options and their + values are removed from the argv array and the + argc count is updated accordingly.

The opt_mode and arg_mode arguments specify the parser behavior when it encounters an unknown option @@ -657,8 +668,96 @@ namespace cli exception (described blow) on encountering an unknown option or argument, respectively.

-

The parsing constructor (those with the argc/argv arguments) - can throw the following exceptions: cli::unknown_option, +

Instead of the argc/argv arguments, the last overloaded + constructor accepts the cli::scanner object. It is part + of the generated CLI runtime support code and has the following + abstract interface:

+ +
+namespace cli
+{
+  class scanner
+  {
+  public:
+    virtual bool
+    more () = 0;
+
+    virtual const char*
+    peek () = 0;
+
+    virtual const char*
+    next () = 0;
+
+    virtual void
+    skip () = 0;
+  };
+}
+  
+ +

The CLI runtime also provides two implementations of this interface: + cli::argv_scanner and cli::argv_file_scanner. + The first implementation is a simple scanner for the argv + array (it is used internally by all the other constructors) and has the + following interface:

+ +
+namespace cli
+{
+  class argv_scanner
+  {
+  public:
+    argv_scanner (int& argc, char** argv, bool erase = false);
+    argv_scanner (int start, int& argc, char** argv, bool erase = false);
+
+    int
+    end () const;
+
+    ...
+  };
+}
+  
+ +

The cli::argv_file_scanner implementation provides + support for reading command line arguments from the argv + array as well as files specified with command line options. It is + generated only if explicitly requested with the + --generate-file-scanner CLI compiler option and has + the following interface:

+ +
+namespace cli
+{
+  class argv_file_scanner
+  {
+  public:
+    argv_file_scanner (int& argc,
+                       char** argv,
+                       const std::string& file_option,
+                       bool erase = false);
+
+    argv_file_scanner (int start,
+                       int& argc,
+                       char** argv,
+                       const std::string& file_option,
+                       bool erase = false);
+    ...
+  };
+}
+  
+ +

The file_option argument is used to pass the option name + that should be recognized as specifying the file containing additional + options. Such a file contains a set of options, each appearing on a + separate line optionally followed by space and an argument. Empty lines + and lines starting with # 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 + options file is specified, except that shell escaping and quoting is not + required. Multiple files can be specified by including several file + options on the command line or inside other files.

+ +

The parsing constructor (those with the argc/argv or + cli::scanner arguments) can throw the following exceptions: cli::unknown_option, cli::unknown_argument, cli::missing_value, and cli::invalid_value. The first two exceptions are thrown on encountering unknown options and arguments, respectively, as @@ -667,6 +766,16 @@ namespace cli thrown when an option value is invalid, for example, a non-integer value is specified for an option of type int.

+

Furthermore, all scanners (and thus the parsing constructors that + call them) can throw the cli::eos_reached exception + which indicates that one of the peek(), next(), + or skip() functions were called while more() + returns false. Catching this exception normally indicates an + error in an option parser implementation. The argv_file_scanner + class can also throw the cli::file_io_failure exception + which indicates that a file could not be opened or there was a reading + error.

+

All CLI exceptions are derived from the common cli::exception class which implements the polymorphic std::ostream insertion. For example, if you catch the cli::unknown_option @@ -759,6 +868,31 @@ namespace cli virtual const char* what () const throw (); }; + + class eos_reached: public exception + { + public: + virtual void + print (std::ostream&) const; + + virtual const char* + what () const throw (); + }; + + class file_io_failure: public exception + { + public: + file_io_failure (const std::string& file); + + const std::string& + file () const; + + virtual void + print (std::ostream&) const; + + virtual const char* + what () const throw (); + }; } -- cgit v1.1