diff options
Diffstat (limited to 'doc/guide')
-rw-r--r-- | doc/guide/.gitignore | 2 | ||||
-rw-r--r-- | doc/guide/guide.html2ps | 63 | ||||
-rw-r--r-- | doc/guide/index.xhtml | 1336 | ||||
-rw-r--r-- | doc/guide/makefile | 39 |
4 files changed, 0 insertions, 1440 deletions
diff --git a/doc/guide/.gitignore b/doc/guide/.gitignore deleted file mode 100644 index 239cc7f..0000000 --- a/doc/guide/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.ps -*.pdf diff --git a/doc/guide/guide.html2ps b/doc/guide/guide.html2ps deleted file mode 100644 index a691002..0000000 --- a/doc/guide/guide.html2ps +++ /dev/null @@ -1,63 +0,0 @@ -@html2ps { - option { - toc: hb; - colour: 1; - hyphenate: 1; - titlepage: 1; - } - - datefmt: "%B %Y"; - - titlepage { - content: " -<div align=center> - <h1><big>CLI Language</big></h1> - <h1><big>Getting Started Guide</big></h1> - <h1> </h1> - <h1> </h1> - <h1> </h1> - <h1> </h1> - <h1> </h1> - <h1> </h1> -</div> - <p>Copyright © 2009-2020 Code Synthesis Tools CC.</p> - - <p>Permission is granted to copy, distribute, and/or modify this document - under the terms of the - <a href='http://www.codesynthesis.com/licenses/mit.txt'>MIT License</a>. - </p> - - <p>This document is available in the following formats: - <a href='http://www.codesynthesis.com/projects/cli/doc/guide/index.xhtml'>XHTML</a>, - <a href='http://www.codesynthesis.com/projects/cli/doc/guide/cli-guide.pdf'>PDF</a>, and - <a href='http://www.codesynthesis.com/projects/cli/doc/guide/cli-guide.ps'>PostScript</a>.</p>"; - } - - toc { - indent: 2em; - } - - header { - odd-right: $H; - even-left: $H; - } - - footer { - odd-left: $D; - odd-center: $T; - odd-right: $N; - - even-left: $N; - even-center: $T; - even-right: $D; - } -} - -body { - font-size: 12pt; - text-align: justify; -} - -pre { - font-size: 10pt; -} diff --git a/doc/guide/index.xhtml b/doc/guide/index.xhtml deleted file mode 100644 index 675db03..0000000 --- a/doc/guide/index.xhtml +++ /dev/null @@ -1,1336 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> - -<head> - <title>CLI Language Getting Started Guide</title> - - <meta name="copyright" content="© 2009-2020 Code Synthesis Tools CC"/> - <meta name="keywords" content="cli,command,line,interface,language,c++"/> - <meta name="description" content="CLI Language Getting Started Guide"/> - - <link rel="stylesheet" type="text/css" href="../default.css" /> - -<style type="text/css"> - pre { - padding : 0 0 0 0em; - margin : 0em 0em 0em 0; - - font-size : 102% - } - - body { - min-width: 48em; - } - - h1 { - font-weight: bold; - font-size: 200%; - line-height: 1.2em; - } - - h2 { - font-weight : bold; - font-size : 150%; - - padding-top : 0.8em; - } - - h3 { - font-size : 140%; - padding-top : 0.8em; - } - - /* Adjust indentation for three levels. */ - #container { - max-width: 48em; - } - - #content { - padding: 0 0.1em 0 4em; - /*background-color: red;*/ - } - - #content h1 { - margin-left: -2.06em; - } - - #content h2 { - margin-left: -1.33em; - } - - /* Title page */ - - #titlepage { - padding: 2em 0 1em 0; - border-bottom: 1px solid black; - } - - #titlepage .title { - font-weight: bold; - font-size: 200%; - text-align: center; - } - - #titlepage #first-title { - padding: 1em 0 0.4em 0; - } - - #titlepage #second-title { - padding: 0.4em 0 2em 0; - } - - /* Lists */ - ul.list li, ol.list li { - padding-top : 0.3em; - padding-bottom : 0.3em; - } - - dl dt { - padding : 0.8em 0 0 0; - } - - /* TOC */ - table.toc { - border-style : none; - border-collapse : separate; - border-spacing : 0; - - margin : 0.2em 0 0.2em 0; - padding : 0 0 0 0; - } - - table.toc tr { - padding : 0 0 0 0; - margin : 0 0 0 0; - } - - table.toc * td, table.toc * th { - border-style : none; - margin : 0 0 0 0; - vertical-align : top; - } - - table.toc * th { - font-weight : normal; - padding : 0em 0.1em 0em 0; - text-align : left; - white-space : nowrap; - } - - table.toc * table.toc th { - padding-left : 1em; - } - - table.toc * td { - padding : 0em 0 0em 0.7em; - text-align : left; - } - - /* Sample options documentation. */ - .options dt { - padding-top : 0.4em; - } - - .options dd { - padding-top : 0.1em; - padding-bottom : 0.4em; - padding-left : 1.4em; - } -</style> - - -</head> - -<body> -<div id="container"> - <div id="content"> - - <div class="noprint"> - - <div id="titlepage"> - <div class="title" id="first-title">CLI Language</div> - <div class="title" id="second-title">Getting Started Guide</div> - - <p>Copyright © 2009-2020 Code Synthesis Tools CC.</p> - - <p>Permission is granted to copy, distribute, and/or modify this document - under the terms of the - <a href="http://www.codesynthesis.com/licenses/mit.txt">MIT License</a>. - </p> - - <p>This document is available in the following formats: - <a href="http://www.codesynthesis.com/projects/cli/doc/guide/index.xhtml">XHTML</a>, - <a href="http://www.codesynthesis.com/projects/cli/doc/guide/cli-guide.pdf">PDF</a>, and - <a href="http://www.codesynthesis.com/projects/cli/doc/guide/cli-guide.ps">PostScript</a>.</p> - - </div> - -<h1>Table of Contents</h1> - - <table class="toc"> - <tr> - <th>1</th><td><a href="#1">Introduction</a></td> - </tr> - - <tr> - <th>2</th><td><a href="#2">Hello World Example</a> - <table class="toc"> - <tr><th>2.1</th><td><a href="#2.1">Defining Command Line Interface</a></td></tr> - <tr><th>2.2</th><td><a href="#2.2">Translating CLI Definitions to C++</a></td></tr> - <tr><th>2.3</th><td><a href="#2.3">Implementing Application Logic</a></td></tr> - <tr><th>2.4</th><td><a href="#2.4">Compiling and Running</a></td></tr> - <tr><th>2.5</th><td><a href="#2.5">Adding Documentation</a></td></tr> - </table> - </td> - </tr> - - <tr> - <th>3</th><td><a href="#3">CLI Language</a> - <table class="toc"> - <tr><th>3.1</th><td><a href="#3.1">Options Class Definition</a></td></tr> - <tr><th>3.2</th><td><a href="#3.2">Option Definition</a></td></tr> - <tr><th>3.3</th><td><a href="#3.3">Option Documentation</a></td></tr> - <tr><th>3.4</th><td><a href="#3.4">Include Directive</a></td></tr> - <tr><th>3.5</th><td><a href="#3.5">Namespace Definition</a></td></tr> - </table> - </td> - </tr> - </table> - </div> - - <!-- Introduction --> - - <h1><a name="1">1 Introduction</a></h1> - - <p>Command Line Interface (CLI) definition language is a domain-specific - language (DSL) for defining command line interfaces of C++ programs. - CLI definitions are automatically translated to C++ classes using the - CLI compiler. These classes implement parsing of the command - line arguments and provide a convenient and type-safe interface - for accessing the extracted data.</p> - - <p>Beyond this guide, you may also find the following sources of - information useful:</p> - - <ul class="list"> - <li><a href="http://www.codesynthesis.com/projects/cli/doc/cli.xhtml">CLI - Compiler Command Line Manual</a></li> - - <li>The <code>INSTALL</code> file in the CLI distribution provides build - instructions for various platforms.</li> - - <li>The <code>examples/</code> directory in the CLI distribution contains - a collection of examples and a README file with an overview of each - example.</li> - - <li>The <a href="http://www.codesynthesis.com/mailman/listinfo/cli-users">cli-users</a> - mailing list is the place to ask technical questions about the CLI language - and compiler. Furthermore, the - <a href="http://www.codesynthesis.com/pipermail/cli-users/">cli-users mailing - list archives</a> may already have answers to some of your questions.</li> - </ul> - - - <!-- Hello World Example --> - - - <h1><a name="2">2 Hello World Example</a></h1> - - <p>In this chapter we will examine how to define a very simple command - line interface in CLI, translate this interface to C++, and use the - result in an application. The code presented in this chapter is based - on the <code>hello</code> example which can be found in the - <code>examples/hello/</code> directory of the CLI distribution.</p> - - <h2><a name="2.1">2.1 Defining Command Line Interface</a></h2> - - <p>Our <code>hello</code> application is going to print a greeting - line for each name supplied on the command line. It will also - support two command line options, <code>--greeting</code> - and <code>--exclamations</code>, that can be used to - customize the greeting line. The <code>--greeting</code> - option allows us to specify the greeting phrase instead of the - default <code>"Hello"</code>. The <code>--exclamations</code> - option is used to specify how many exclamation marks should - be printed at the end of each greeting. We will also support - the <code>--help</code> option which triggers printing of the - usage information.</p> - - <p>We can now write a description of the above command line interface - in the CLI language and save it into <code>hello.cli</code>:</p> - - <pre class="cli"> -include <string>; - -class options -{ - bool --help; - std::string --greeting = "Hello"; - unsigned int --exclamations = 1; -}; - </pre> - - <p>While some details in the above code fragment might not be completely - clear (the CLI language is covered in greater detail in the next - chapter), it should be easy to connect declarations in - <code>hello.cli</code> to the command line interface described in - the preceding paragraphs. The next step is to translate this - interface specification to C++.</p> - - <h2><a name="2.2">2.2 Translating CLI Definitions to C++</a></h2> - - <p>Now we are ready to translate <code>hello.cli</code> to C++. - To do this we invoke the CLI compiler from a terminal (UNIX) or - a command prompt (Windows): - </p> - - <pre class="term"> -$ cli hello.cli - </pre> - - <p>This invocation of the CLI compiler produces three C++ files: - <code>hello.hxx</code> <code>hello.ixx</code>, and - <code>hello.cxx</code>. You can change the file name extensions - for these files with the compiler command line options. See the - <a href="http://www.codesynthesis.com/projects/cli/doc/cli.xhtml">CLI - Compiler Command Line Manual</a> for more information.</p> - - <p>The following code fragment is taken from <code>hello.hxx</code>; it - should give you an idea about what gets generated:</p> - - <pre class="cxx"> -#include <string> - -class options -{ -public: - options (int argc, char** argv); - options (int argc, char** argv, int& end); - - // Option accessors. - // -public: - bool - help () const; - - const std::string& - greeting () const; - - unsigned int - exclamations () const; - -private: - .. -}; - </pre> - - <p>The <code>options</code> C++ class corresponds to the <code>options</code> - CLI class. For each option in this CLI class an accessor function is - generated inside the C++ class. The <code>options</code> C++ class also - defines a number of overloaded constructs that we can use to parse the - <code>argc/argv</code> array. Let's now see how we can use this generated - class to implement option parsing in our <code>hello</code> application.</p> - - <h2><a name="2.3">2.3 Implementing Application Logic</a></h2> - - <p>At this point we have everything we need to implement our - application:</p> - - <pre class="cxx"> -#include <iostream> -#include "hello.hxx" - -using namespace std; - -void -usage (ostream& os) -{ - os << "usage: driver [options] <names>" << endl - << "options:" << endl; - options::print_usage (os); -} - -int -main (int argc, char* argv[]) -{ - try - { - int end; // End of options. - options o (argc, argv, end); - - if (o.help ()) - { - usage (cout); - return 0; - } - - if (end == argc) - { - cerr << "no names provided" << endl; - usage (cerr); - return 1; - } - - // Print the greetings. - // - for (int i = end; i < argc; i++) - { - cout << o.greeting () << ", " << argv[i]; - - for (unsigned int j = 0; j < o.exclamations (); j++) - cout << '!'; - - cout << endl; - } - } - catch (const cli::exception& e) - { - cerr << e << endl; - usage (cerr); - return 1; - } -} -</pre> - - <p>At the beginning of our application we create the <code>options</code> - object which parses the command line. The <code>end</code> variable - contains the index of the first non-option argument. We then access - the option values as needed during the application execution. We also - catch and print <code>cli::exception</code> in case something goes - wrong, for example, an unknown option is specified or an option value - is invalid. - </p> - - <h2><a name="2.4">2.4 Compiling and Running</a></h2> - - <p>After saving our application from the previous section in - <code>driver.cxx</code>, we are ready to build and run our program. - On UNIX this can be done with the following commands:</p> - - <pre class="term"> -$ c++ -o driver driver.cxx hello.cxx - -$ ./driver world -Hello, world! - -$ ./driver --greeting Hi --exclamations 3 John Jane -Hi, John!!! -Hi, Jane!!! - </pre> - - <p>We can also test the error handling:</p> - - <pre class="term"> -$ ./driver -n 3 Jane -unknown option '-n' -usage: driver [options] <names> -options: ---help ---greeting <arg> ---exclamations <arg> - -$ ./driver --exclamations abc Jane -invalid value 'abc' for option '--exclamations' -usage: driver [options] <names> -options: ---help ---greeting <arg> ---exclamations <arg> - </pre> - - <h2><a name="2.5">2.5 Adding Documentation</a></h2> - - <p>As we have seen in the previous sections, the <code>options</code> - C++ class provides the <code>print_usage()</code> function which we - can use to display the application usage information. Right now this - information is very basic and does not include any description of - the purpose of each option:</p> - - <pre class="term"> -$ ./driver --help -usage: driver [options] <names> -options: ---help ---greeting <arg> ---exclamations <arg> - </pre> - - <p>To make the usage information more descriptive we can document each - option in the command line interface definition. This information can - also be used to automatically generate program documentation in various - formats, such as HTML and man page. For example:</p> - - <pre class="cli"> -include <string>; - -class options -{ - bool --help {"Print usage information and exit."}; - - std::string --greeting = "Hello" - { - "<text>", - "Use <text> as a greeting phrase instead of the default \"Hello\"." - }; - - unsigned int --exclamations = 1 - { - "<num>", - "Print <num> exclamation marks instead of 1 by default." - }; -}; - </pre> - - <p>If we now save this updated command line interface to - <code>hello.cli</code> and recompile our application, the usage - information printed by the program will look like this:</p> - - <pre class="term"> -usage: driver [options] <names> -options: ---help Print usage information and exit. ---greeting <text> Use <text> as a greeting phrase instead of the - default "Hello". ---exclamations <num> Print <num> exclamation marks instead of 1 by - default. - </pre> - - <p>We can also generate the program documentation in the HTML - (<code>--generate-html</code> CLI option) and man page - (<code>--generate-man</code> CLI option) formats. For example:</p> - - <pre class="term"> -$ cli --generate-html hello.cli - </pre> - - <p>The resulting <code>hello.html</code> file contains the following - documentation:</p> - -<dl class="options"> - <dt><code><b>--help</b></code></dt> - <dd>Print usage information and exit.</dd> - - <dt><code><b>--greeting</b></code> <i>text</i></dt> - <dd>Use <i>text</i> as a greeting phrase instead of the default "Hello".</dd> - - <dt><code><b>--exclamations</b></code> <i>num</i></dt> - <dd>Print <i>num</i> exclamation marks instead of 1 by default.</dd> - -</dl> - - <p>This HTML fragment can be combined with custom prologue and epilogue - to create a complete program documentation - (<code>--html-prologue/--html-epilogue</code> options for the HTML - output, <code>--man-prologue/--man-epilogue</code> options for the - man page output). For an example of such complete documentation see - the <a href="http://www.codesynthesis.com/projects/cli/doc/cli.xhtml">CLI - Compiler Command Line Manual</a> and the <code>cli(1)</code> man - page. For more information on the option documentation syntax, - see <a href="#3.3">Section 3.3, Option Documentation</a>.</p> - - <!-- CLI Language --> - - - <h1><a name="3">3 CLI Language</a></h1> - - <p>This chapter describes the CLI language and its mapping to C++. - A CLI file consists of zero or more <a href="#3.4">Include - Directives</a> followed by one or more <a href="#3.5">Namespace Definitions</a> - or <a href="#3.1">Option Class Definitions</a>. C and C++-style comments - can be used anywhere in the CLI file except in character and - string literals.</p> - - <h2><a name="3.1">3.1 Option Class Definition</a></h2> - -<p>The central part of the CLI language is <em>option class</em>. An - option class contains one or more <em>option</em> definitions, for - example:</p> - - <pre class="cli"> -class options -{ - bool --help; - int --compression; -}; - </pre> - - <p>If we translate the above CLI fragment to C++, we will get a C++ - class with the following interface:</p> - - <pre class="cli"> -class options -{ -public: - 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, - 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, - 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, - 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); - - options (const options&); - - options& - operator= (const options&); - -public: - static void - print_usage (std::ostream&); - -public: - bool - help () const; - - int - compression () const; -}; - </pre> - - - <p>An option class is mapped to a C++ class with the same name. The - C++ class defines a set of public overloaded constructors, a public - copy constructor and an assignment operator, as well as a set of public - accessor functions and, if the <code>--generate-modifier</code> CLI - compiler option is specified, modifier functions corresponding to option - definitions. It also defines a public static <code>print_usage()</code> - function that can be used to print the usage information for the options - defined by the class.</p> - - <p>The <code>argc/argv</code> arguments in the overloaded constructors - are used to pass the command line arguments array, normally as passed - to <code>main()</code>. The <code>start</code> argument is used to - specify the position in the arguments array from which the parsing - should start. The constructors that don't have this argument, start - from position 1, skipping the executable name in <code>argv[0]</code>. - The <code>end</code> 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. If the <code>erase</code> - argument is <code>true</code>, then the recognized options and their - values are removed from the <code>argv</code> array and the - <code>argc</code> count is updated accordingly.</p> - - <p>The <code>opt_mode</code> and <code>arg_mode</code> arguments - specify the parser behavior when it encounters an unknown option - and argument, respectively. The <code>unknown_mode</code> type - is part of the generated CLI runtime support code. It has the - following interface:</p> - - <pre class="cxx"> -namespace cli -{ - class unknown_mode - { - public: - enum value - { - skip, - stop, - fail - }; - - unknown_mode (value v); - operator value () const; - }; -} - </pre> - - <p>If the mode is <code>skip</code>, the parser skips an unknown - option or argument and continue parsing. If the mode is - <code>stop</code>, the parser stops the parsing process. The - position of the unknown entity is stored in the <code>end</code> - argument. If the mode is <code>fail</code>, the parser throws the - <code>cli::unknown_option</code> or <code>cli::unknown_argument</code> - exception (described blow) on encountering an unknown option or argument, - respectively.</p> - - <p>Instead of the <code>argc/argv</code> arguments, the last overloaded - constructor accepts the <code>cli::scanner</code> object. It is part - of the generated CLI runtime support code and has the following - abstract interface:</p> - - <pre class="cxx"> -namespace cli -{ - class scanner - { - public: - virtual bool - more () = 0; - - virtual const char* - peek () = 0; - - virtual const char* - next () = 0; - - virtual void - skip () = 0; - }; -} - </pre> - - <p>The CLI runtime also provides two implementations of this interface: - <code>cli::argv_scanner</code> and <code>cli::argv_file_scanner</code>. - The first implementation is a simple scanner for the <code>argv</code> - array (it is used internally by all the other constructors) and has the - following interface:</p> - - <pre class="cxx"> -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; - - ... - }; -} - </pre> - - <p>The <code>cli::argv_file_scanner</code> implementation provides - support for reading command line arguments from the <code>argv</code> - array as well as files specified with command line options. It is - generated only if explicitly requested with the - <code>--generate-file-scanner</code> CLI compiler option and has - the following interface:</p> - - <pre class="cxx"> -namespace cli -{ - class argv_file_scanner - { - public: - argv_file_scanner (int& argc, - char** argv, - const std::string& option, - bool erase = false); - - argv_file_scanner (int start, - int& argc, - char** argv, - const std::string& option, - bool erase = false); - - struct option_info - { - // If search_func is not NULL, it is called, with the arg - // value as the second argument, to locate the options file. - // If it returns an empty string, then the file is ignored. - // - const char* option; - std::string (*search_func) (const char*, void* arg); - void* arg; - }; - - argv_file_scanner (int& argc, - char** argv, - const option_info* options, - std::size_t options_count, - bool erase = false); - - argv_file_scanner (int start, - int& argc, - char** argv, - const option_info* options, - std::size_t options_count, - bool erase = false); - ... - }; -} - </pre> - - <p>The <code>option</code> argument in the first two constructors and - the <code>options</code> and <code>options_count</code> arguments - in the last two are used to pass the option name(s) 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 option value. Empty lines - and lines starting with <code>#</code> are ignored. Option values can - be enclosed in double (<code>"</code>) or single (<code>'</code>) - quotes to preserve leading and trailing whitespaces as well as to - specify empty values. If the value itself contains trailing or leading - quotes, enclose it with an extra pair of quotes, for example - <code>'"x"'</code>. Non-leading and non-trailing quotes are interpreted - as being part of the option value.</p> - - <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 options file is specified, except that the 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.</p> - - <p>The parsing constructor (those with the <code>argc/argv</code> or - <code>cli::scanner</code> arguments) can throw the following exceptions: <code>cli::unknown_option</code>, - <code>cli::unknown_argument</code>, <code>cli::missing_value</code>, and - <code>cli::invalid_value</code>. The first two exceptions are thrown - on encountering unknown options and arguments, respectively, as - described above. The <code>missing_value</code> exception is thrown when - an option value is missing. The <code>invalid_value</code> exception is - thrown when an option value is invalid, for example, a non-integer value - is specified for an option of type <code>int</code>.</p> - - <p>Furthermore, all scanners (and thus the parsing constructors that - call them) can throw the <code>cli::eos_reached</code> exception - which indicates that one of the <code>peek()</code>, <code>next()</code>, - or <code>skip()</code> functions were called while <code>more()</code> - returns <code>false</code>. Catching this exception normally indicates an - error in an option parser implementation. The <code>argv_file_scanner</code> - class can also throw the <code>cli::file_io_failure</code> exception - which indicates that a file could not be opened or there was a reading - error as well as the <code>cli::unmatched_quote</code> exception - which indicates that an unmatched leading or trailing quote was - found in an option value.</p> - - <p>All CLI exceptions are derived from the common <code>cli::exception</code> - class which implements the polymorphic <code>std::ostream</code> insertion. - For example, if you catch the <code>cli::unknown_option</code> - exception as <code>cli::exception</code> and print it to - <code>std::cerr</code>, you will get the error message corresponding - to the <code>unknown_option</code> exception.</p> - - <p>The exceptions described above are part of the generated CLI runtime - support code and have the following interfaces:</p> - - <pre class="cxx"> -#include <exception> - -namespace cli -{ - class exception: public std::exception - { - public: - virtual void - print (std::ostream&) const = 0; - }; - - inline std::ostream& - operator<< (std::ostream& os, const exception& e) - { - e.print (os); - return os; - } - - class unknown_option: public exception - { - public: - unknown_option (const std::string& option); - - const std::string& - option () const; - - virtual void - print (std::ostream&) const; - - virtual const char* - what () const throw (); - }; - - class unknown_argument: public exception - { - public: - unknown_argument (const std::string& argument); - - const std::string& - argument () const; - - virtual void - print (std::ostream&) const; - - virtual const char* - what () const throw (); - }; - - class missing_value: public exception - { - public: - missing_value (const std::string& option); - - const std::string& - option () const; - - virtual void - print (std::ostream&) const; - - virtual const char* - what () const throw (); - }; - - class invalid_value: public exception - { - public: - invalid_value (const std::string& option, - const std::string& value); - - const std::string& - option () const; - - const std::string& - value () const; - - virtual void - print (std::ostream&) const; - - 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 (); - }; - - class unmatched_quote: public exception - { - public: - unmatched_quote (const std::string& argument); - - const std::string& - argument () const; - - virtual void - print (std::ostream&) const; - - virtual const char* - what () const throw (); - }; -} - </pre> - - - <h2><a name="3.2">3.2 Option Definition</a></h2> - -<p>An option definition consists of four components: <em>type</em>, - <em>name</em>, <em>default value</em>, and <em>documentation</em>. - An option type can be any C++ type as long as its string representation - can be parsed using the <code>std::istream</code> interface. If the option - type is user-defined then you will need to include its declaration using - the <a href="#3.4">Include Directive</a>.</p> - -<p>An option of a type other than <code>bool</code> is expected to - have a value. An option of type <code>bool</code> is treated as - a flag and does not have a value. That is, a mere presence of such - an option on the command line sets this option's value to - <code>true</code>.</p> - -<p>The name component specifies the option name as it will be entered - in the command line. A name can contain any number of aliases separated - by <code>|</code>. The C++ accessor and modifier function names are - derived from the first name by removing any leading special characters, - such as <code>-</code>, <code>/</code>, etc., and replacing special - characters in other places with underscores. For example, the following - option definition:</p> - - <pre class="cli"> -class options -{ - int --compression-level | --comp | -c; -}; - </pre> - - <p>Will result in the following accessor function:</p> - - <pre class="cli"> -class options -{ - int - compression_level () const; -}; - </pre> - - <p>While any option alias can be used on the command line to specify - this option's value.</p> - - <p>If the option name conflicts with one of the CLI language keywords, - it can be specified as a string literal:</p> - - <pre class="cli"> -class options -{ - bool "int"; -}; - </pre> - - <p>The following component of the option definition is the optional default - value. If the default value is not specified, then the option is - initialized with the default constructor. In particular, this means - that a <code>bool</code> option will be initialized to <code>false</code>, - an <code>int</code> option will be initialized to <code>0</code>, etc.</p> - - <p>Similar to C++ variable initialization, the default option value - can be specified using two syntactic forms: an assignment initialization - and constructor initialization. The two forms are equivalent except - that the constructor initialization can be used with multiple arguments, - for example:</p> - - <pre class="cli"> -include <string>; - -class options -{ - int -i1 = 5; - int -i2 (5); - - std::string -s1 = "John"; - std::string -s2 ("Mr John Doe", 8, 3); -}; - </pre> - - <p>The assignment initialization supports character, string, boolean, and - simple integer literals (including negative integers) as well - as identifiers. For more complex expressions use the constructor - initialization or wrap the expressions in parenthesis, for example:</p> - - <pre class="cli"> -include "constants.hxx"; // Defines default_value. - -class options -{ - int -a = default_value; - int -b (25 * 4); - int -c = (25 / default_value + 3); -}; - </pre> - - <p>By default, when an option is specified two or more times on the command - line, the last value overrides all the previous ones. However, a number - of standard C++ containers are handled differently to allow collecting - multiple option values or building key-value maps. These - containers are <code>std::vector</code>, <code>std::set</code>, and - <code>std::map</code>.</p> - - <p>When <code>std::vector</code> or <code>std::set</code> is specified - as an option type, all the values for this option are inserted into the - container in the order they are encountered. As a result, - <code>std::vector</code> will contain all the values, including - duplicates while <code>std::set</code> will contain all the unique - values. For example:</p> - - <pre class="cli"> -include <set>; -include <vector>; - -class options -{ - std::vector<int> --vector | -v; - std::set<int> --set | -s; -}; - </pre> - - <p>If we have a command line like this: - <code>-v 1 -v 2 -v 1 -s 1 -s 2 -s 1</code>, then the vector returned - by the <code>vector()</code> accessor function will contain three - elements: <code>1</code>, <code>2</code>, and <code>1</code> while - the set returned by the <code>set()</code> accessor will contain - two elements: <code>1</code> and <code>2</code>.</p> - - <p>When <code>std::map</code> is specified as an option type, the option - value is expected to have two parts: the key and the value, separated - by <code>=</code>. All the option values are then parsed into key/value - pairs and inserted into the map. For example:</p> - - <pre class="cli"> -include <map>; -include <string>; - -class options -{ - std::map<std::string, std::string> --map | -m; -}; - </pre> - - <p>The possible option values for this interface are: <code>-m a=A</code>, - <code>-m =B</code> (key is an empty string), <code>-m c=</code> (value - is an empty string), or <code>-m d</code> (same as <code>-m d=</code>).</p> - - <p>The last component in the option definition is optional documentation. - It is discussed in the next section.</p> - - <h2><a name="3.3">3.3 Option Documentation</a></h2> - - <p>Option documentation mimics C++ string array initialization: - it is enclosed in <code>{}</code> and consists of one or more - documentation strings separated by a comma, for example:</p> - - <pre class="cli"> -class options -{ - int --compression = 5 - { - "<level>", - "Set compression to <level> instead of 5 by default. - - With the higher compression levels the program may produce a - smaller output but may also take longer and use more memory." - }; -}; - </pre> - - <p>The option documentation consists of a maximum of three documentation - strings. The first string is the value documentation string. - It describes the option value and is only applicable to options - with types other than <code>bool</code> (options of type - <code>bool</code> are flags and don't have an explicit value). - The second string (or the first string for options of type - <code>bool</code>) is the short documentation string. It - provides a brief description of the option. The last entry - in the option documentation is the long documentation string. - It provides a detailed description of the option. The short - documentation string is optional. If only two strings are - present in the option documentation (one string for options - of type <code>bool</code>), then the second (first) string is - assumed to be the long documentation string.</p> - - <p>Option documentation is used to print the usage information - as well as to generate program documentation in the HTML and - man page formats. For usage information the short documentation - string is used if provided. If only the long string is available, - then, by default, only the first sentence from the long string - is used. You can override this behavior and include the complete - long string in the usage information by specifying the - <code>--long-usage</code> CLI compiler option. When generating - the program documentation, the long documentation strings are - always used.</p> - - <p>The value documentation string can contain text enclosed in - <code><></code> which is automatically recognized by the CLI - compiler and typeset according to the selected output in all three - documentation strings. For example, in usage the <code>level</code> - value for the <code>--compression</code> option presented above - will be displayed as <code><level></code> while in the HTML and - man page output it will be typeset in italic as - <code><i>level</i></code>. Here is another example using the - <code>std::map</code> type:</p> - - <pre class="cli"> -include <map>; -include <string>; - -class options -{ - std::map<std::string, std::string> --map - { - "<key>=<value>", - "Add the <key>, <value> pair to the map." - }; -}; - </pre> - - <p>The resulting HTML output for this option would look like this:</p> - -<dl class="options"> - <dt><code><b>--map</b></code> <i>key</i>=<i>value</i></dt> - <dd>Add the <i>key</i>, <i>value</i> pair to the map.</dd> -</dl> - - <p>As you might have noticed from the examples presented so far, the - documentation strings can span multiple lines which is not possible - in C++. Also, all three documentation strings support the following - basic formatting mechanisms. The start of a new paragraph is indicated - by a blank line. A fragment of text can be typeset in monospace font - (normally used for code fragments) by enclosing it in the - <code>\c{}</code> block. Similarly, text can be typeset in bold or - italic fonts using the <code>\b{}</code> and <code>\i{}</code> blocks, - respectively. You can also combine several font properties in a single - block, for example, <code>\cb{bold code}</code>. If you need to include - literal <code>}</code> in a formatting block, you can use the - <code>\}</code> escape sequence, for example, - <code>\c{int a[] = {1, 2\}}</code>. The following example shows how we - can use these mechanisms:</p> - - <pre class="cli"> -class options -{ - int --compression = 5 - { - "<level>", - "Set compression to <level> instead of 5 by default. - - With the higher compression levels the program \i{may} - produce a smaller output but may also \b{take longer} - and \b{use more memory}." - }; -}; - </pre> - - <p>The resulting HTML output for this option would look like this:</p> - -<dl class="options"> - <dt><code><b>--compression</b></code> <i>level</i></dt> - <dd>Set compression to <i>level</i> instead of 5 by default. - - <p>With the higher compression levels the program <i>may</i> produce a - smaller output but may also <b>take longer</b> and <b>use more memory</b>.</p></dd> -</dl> - - <h2><a name="3.4">3.4 Include Directive</a></h2> - - <p>If you are using user-defined types in your option definitions, - you will need to include their declarations with the include - directive. Include directives can use <code>< ></code> or - <code>" "</code>-enclosed paths. The CLI compiler does not - actually open or read these files. Instead, the include directives - are translated to C++ preprocessor <code>#include</code> directives - in the generated C++ header file. For example, the following CLI - definition:</p> - - <pre class="cli"> -include <string>; -include "types.hxx"; // Defines the name_type class. - -class options -{ - std::string --string; - name_type --name; -}; - </pre> - - <p>Will result in the following C++ header file:</p> - - <pre class="cli"> -#include <string> -#include "types.hxx" - -class options -{ - ... - - const std::string& - string () const; - - const name_type& - name () const; - - ... -}; - </pre> - - <p>Without the <code>#include</code> directives the <code>std::string</code> - and <code>name_type</code> types in the <code>options</code> class would - be undeclared and result in compilation errors.</p> - - <h2><a name="3.5">3.5 Namespace Definition</a></h2> - - <p>Option classes can be placed into namespaces which are translated - directly to C++ namespaces. For example:</p> - - <pre class="cli"> -namespace compiler -{ - namespace lexer - { - class options - { - int --warning-level = 0; - }; - } - - namespace parser - { - class options - { - int --warning-level = 0; - }; - } - - namespace generator - { - class options - { - int --target-width = 32; - }; - } -} - </pre> - - <p>The above CLI namespace structure would result in the equivalent C++ - namespaces structure:</p> - - <pre class="cxx"> -namespace compiler -{ - namespace lexer - { - class options - { - int - warning_level () const; - }; - } - - namespace parser - { - class options - { - int - warning_level () const; - }; - } - - namespace generator - { - class options - { - int - target_width () const; - }; - } -} - </pre> - - - </div> -</div> - - -</body> -</html> diff --git a/doc/guide/makefile b/doc/guide/makefile deleted file mode 100644 index 40ed0f9..0000000 --- a/doc/guide/makefile +++ /dev/null @@ -1,39 +0,0 @@ -# file : doc/guide/makefile -# author : Boris Kolpackov <boris@codesynthesis.com> -# license : MIT; see accompanying LICENSE file - -include $(dir $(lastword $(MAKEFILE_LIST)))../../build/bootstrap.make - -default := $(out_base)/ -install := $(out_base)/.install -cleandoc := $(out_base)/.cleandoc - -# Build. -# -$(default): $(out_base)/cli-guide.ps $(out_base)/cli-guide.pdf - - -$(out_base)/cli-guide.ps: $(src_base)/index.xhtml \ - $(src_base)/guide.html2ps \ - | $(out_base)/. - $(call message,html2ps $<,html2ps -f $(src_base)/guide.html2ps -o $@ $<) - -$(out_base)/cli-guide.pdf: $(out_base)/cli-guide.ps | $(out_base)/. - $(call message,ps2pdf $<,ps2pdf14 $< $@) - -# Install. -# -$(install): $(out_base)/cli-guide.ps $(out_base)/cli-guide.pdf - $(call install-data,$(src_base)/index.xhtml,$(install_doc_dir)/cli/guide/index.xhtml) - $(call install-data,$(src_base)/cli-guide.ps,$(install_doc_dir)/cli/guide/cli-guide.ps) - $(call install-data,$(src_base)/cli-guide.pdf,$(install_doc_dir)/cli/guide/cli-guide.pdf) - -# Clean. -# -$(cleandoc): - $(call message,rm $$1,rm -f $$1,$(out_base)/cli-guide.ps) - $(call message,rm $$1,rm -f $$1,$(out_base)/cli-guide.pdf) - -# How to. -# -$(call include,$(bld_root)/install.make) |