summaryrefslogtreecommitdiff
path: root/cli-examples
diff options
context:
space:
mode:
Diffstat (limited to 'cli-examples')
-rw-r--r--cli-examples/.gitignore21
l---------cli-examples/LICENSE1
-rw-r--r--cli-examples/README15
-rw-r--r--cli-examples/build/.gitignore3
-rw-r--r--cli-examples/build/bootstrap.build9
-rw-r--r--cli-examples/build/root.build27
-rw-r--r--cli-examples/buildfile4
-rw-r--r--cli-examples/features/.gitignore1
-rw-r--r--cli-examples/features/README20
-rw-r--r--cli-examples/features/buildfile8
-rw-r--r--cli-examples/features/driver.cxx61
-rw-r--r--cli-examples/features/options.cli39
-rw-r--r--cli-examples/file/.gitignore1
-rw-r--r--cli-examples/file/README38
-rw-r--r--cli-examples/file/buildfile11
-rw-r--r--cli-examples/file/driver.cxx35
-rw-r--r--cli-examples/file/options.cli7
-rw-r--r--cli-examples/file/test.ops7
-rw-r--r--cli-examples/hello/.gitignore1
-rw-r--r--cli-examples/hello/README26
-rw-r--r--cli-examples/hello/buildfile9
-rw-r--r--cli-examples/hello/driver.cxx58
-rw-r--r--cli-examples/hello/hello.cli18
-rw-r--r--cli-examples/manifest15
24 files changed, 435 insertions, 0 deletions
diff --git a/cli-examples/.gitignore b/cli-examples/.gitignore
new file mode 100644
index 0000000..e1d6ab8
--- /dev/null
+++ b/cli-examples/.gitignore
@@ -0,0 +1,21 @@
+# Compiler/linker output.
+#
+*.d
+*.t
+*.i
+*.ii
+*.o
+*.obj
+*.so
+*.dll
+*.a
+*.lib
+*.exp
+*.pdb
+*.ilk
+*.exe
+*.exe.dlls/
+*.exe.manifest
+*.pc
+
+driver
diff --git a/cli-examples/LICENSE b/cli-examples/LICENSE
new file mode 120000
index 0000000..ea5b606
--- /dev/null
+++ b/cli-examples/LICENSE
@@ -0,0 +1 @@
+../LICENSE \ No newline at end of file
diff --git a/cli-examples/README b/cli-examples/README
new file mode 100644
index 0000000..11589d2
--- /dev/null
+++ b/cli-examples/README
@@ -0,0 +1,15 @@
+This package contains a number of examples that show how to use the CLI
+language and compiler to implement command line interface parsing in C++.
+The following list gives an overview of each example. See the README files
+in example directories for more information on each example.
+
+hello
+ A simple "Hello, world!" example that shows how to implement a very basic
+ command line interface using CLI.
+
+features
+ Shows how to use various features of the CLI language.
+
+file
+ Shows how to allow the users of your application to supply options in
+ files in addition to the command line.
diff --git a/cli-examples/build/.gitignore b/cli-examples/build/.gitignore
new file mode 100644
index 0000000..4a730a3
--- /dev/null
+++ b/cli-examples/build/.gitignore
@@ -0,0 +1,3 @@
+config.build
+root/
+bootstrap/
diff --git a/cli-examples/build/bootstrap.build b/cli-examples/build/bootstrap.build
new file mode 100644
index 0000000..c50c6ac
--- /dev/null
+++ b/cli-examples/build/bootstrap.build
@@ -0,0 +1,9 @@
+# file : build/bootstrap.build
+# license : MIT; see accompanying LICENSE file
+
+project = cli-examples
+
+using version
+using config
+using dist
+using test
diff --git a/cli-examples/build/root.build b/cli-examples/build/root.build
new file mode 100644
index 0000000..53bde39
--- /dev/null
+++ b/cli-examples/build/root.build
@@ -0,0 +1,27 @@
+# file : build/root.build
+# license : MIT; see accompanying LICENSE file
+
+cxx.std = latest
+
+using cxx
+
+hxx{*}: extension = hxx
+ixx{*}: extension = ixx
+txx{*}: extension = txx
+cxx{*}: extension = cxx
+
+if ($cxx.target.system == 'win32-msvc')
+ cxx.poptions += -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS
+
+if ($cxx.class == 'msvc')
+ cxx.coptions += /wd4251 /wd4275 /wd4800
+
+using cli
+
+# Every exe{} in this subproject is by default a test.
+#
+exe{*}: test = true
+
+# Specify the test target for cross-testing.
+#
+test.target = $cxx.target
diff --git a/cli-examples/buildfile b/cli-examples/buildfile
new file mode 100644
index 0000000..53d51dd
--- /dev/null
+++ b/cli-examples/buildfile
@@ -0,0 +1,4 @@
+# file : buildfile
+# license : MIT; see accompanying LICENSE file
+
+./: {*/ -build/} doc{LICENSE README} manifest
diff --git a/cli-examples/features/.gitignore b/cli-examples/features/.gitignore
new file mode 100644
index 0000000..c6e608b
--- /dev/null
+++ b/cli-examples/features/.gitignore
@@ -0,0 +1 @@
+options.?xx
diff --git a/cli-examples/features/README b/cli-examples/features/README
new file mode 100644
index 0000000..9416320
--- /dev/null
+++ b/cli-examples/features/README
@@ -0,0 +1,20 @@
+This example shows how to use various features of the CLI language.
+
+The example consists of the following files:
+
+options.cli
+ Command line interface description in the CLI language.
+
+options.hxx
+options.ixx
+options.cxx
+ Command line interface implementation in C++. These files are generated
+ by the CLI compiler from hello.cli using the following command line:
+
+ cli options.cli
+
+driver.cxx
+ Driver for the example. It first instantiates the option class which parses
+ the command line. The driver then examines and prints the option values.
+
+To run the example you can try various command lines suggested in options.cli.
diff --git a/cli-examples/features/buildfile b/cli-examples/features/buildfile
new file mode 100644
index 0000000..5051eae
--- /dev/null
+++ b/cli-examples/features/buildfile
@@ -0,0 +1,8 @@
+# file : features/buildfile
+# license : MIT; see accompanying LICENSE file
+
+exe{driver}: {hxx cxx}{* -options} cli.cxx{options} doc{README}
+
+cxx.poptions =+ "-I$out_base"
+
+cli.cxx{options}: cli{options}
diff --git a/cli-examples/features/driver.cxx b/cli-examples/features/driver.cxx
new file mode 100644
index 0000000..c14b5c7
--- /dev/null
+++ b/cli-examples/features/driver.cxx
@@ -0,0 +1,61 @@
+// file : features/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// license : MIT; see accompanying LICENSE file
+
+#include <iostream>
+#include <iterator>
+#include <algorithm>
+
+#include "options.hxx"
+
+using namespace std;
+
+int
+main (int argc, char* argv[])
+{
+ try
+ {
+ features::options o (argc, argv);
+
+ // --out-dir | -o
+ //
+ if (!o.out_dir ().empty ())
+ cerr << "output dir: " << o.out_dir () << endl;
+
+ // --first-name & --last-name
+ //
+ cerr << "first name: " << o.first_name () << endl
+ << "last name : " << o.last_name () << endl;
+
+ // --vector | -v & --set | -s
+ //
+ if (!o.vector ().empty ())
+ {
+ copy (o.vector ().begin (), o.vector ().end (),
+ ostream_iterator<int> (cerr, " "));
+ cerr << endl;
+ }
+
+ if (!o.set ().empty ())
+ {
+ copy (o.set ().begin (), o.set ().end (),
+ ostream_iterator<int> (cerr, " "));
+ cerr << endl;
+ }
+
+ // --map | -m
+ //
+ typedef map<std::string, std::string> str_map;
+ const str_map& m = o.map ();
+ str_map::const_iterator i (m.find ("a"));
+
+ if (i != m.end ())
+ cerr << "value for the 'a' key: " << i->second << endl;
+
+ }
+ catch (const cli::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/cli-examples/features/options.cli b/cli-examples/features/options.cli
new file mode 100644
index 0000000..ea055b3
--- /dev/null
+++ b/cli-examples/features/options.cli
@@ -0,0 +1,39 @@
+include <set>;
+include <map>;
+include <vector>;
+include <string>;
+
+// We can place the options classes into namespaces which mapped to C++
+// namespaces.
+//
+namespace features
+{
+ class options
+ {
+ // We can have several aliases for the same option. The first one is used
+ // to derive the accessor name.
+ //
+ std::string --out-dir | -o;
+
+ // We can use both assignment and constructor notations to provide the
+ // default option value.
+ //
+ std::string --first-name = "John";
+ std::string --last-name ("Mr John Doe", 8, 3);
+
+ // We can use containers to to collect option value. If we have a command
+ // line like this: -v 1 -v 2 -v 1 -s 1 -s 2 -s 1 then the vector returned
+ // by the vector() accessor will contain three elements: 1, 2, and 1 while
+ // the set returned by the set() accessor will contain two elements: 1 and
+ // 2.
+ //
+ std::vector<int> --vector | -v;
+ std::set<int> --set | -s;
+
+ // We can also use maps. In this case the option value is expected to have
+ // two parts: the key and the value, separated by '='. For example: -m a=A
+ // -m =B -m c= -m d (same as -m d=).
+ //
+ std::map<std::string, std::string> --map | -m;
+ };
+}
diff --git a/cli-examples/file/.gitignore b/cli-examples/file/.gitignore
new file mode 100644
index 0000000..c6e608b
--- /dev/null
+++ b/cli-examples/file/.gitignore
@@ -0,0 +1 @@
+options.?xx
diff --git a/cli-examples/file/README b/cli-examples/file/README
new file mode 100644
index 0000000..289fc64
--- /dev/null
+++ b/cli-examples/file/README
@@ -0,0 +1,38 @@
+This example shows how to allow the users of your application to supply
+options in files in addition to the command line.
+
+The example consists of the following files:
+
+options.cli
+ Command line interface description in the CLI language.
+
+options.hxx
+options.ixx
+options.cxx
+ Command line interface implementation in C++. These files are generated
+ by the CLI compiler from options.cli using the following command line:
+
+ cli --generate-file-scanner hello.cli
+
+ We use the --generate-file-scanner CLI compiler option to include the
+ argv_file_scanner scanner implementation which provides support for
+ reading options from files in addition to the command line.
+
+driver.cxx
+ Driver for the example. It first creates the argv_file_scanner object
+ and indicates that the values for the --options-file option should be
+ recognized as files containing additional options. It then passes this
+ scanner object to the option class which parses the command line. The
+ driver then prints the option values.
+
+test.ops
+ Sample options file.
+
+To run this example you can try the following command line:
+
+$ ./driver --verbose 2 --val 1 --options-file test.ops --val 4
+
+The output will be:
+
+verbosity: 5
+values: 1 2 3 4
diff --git a/cli-examples/file/buildfile b/cli-examples/file/buildfile
new file mode 100644
index 0000000..89675d8
--- /dev/null
+++ b/cli-examples/file/buildfile
@@ -0,0 +1,11 @@
+# file : file/buildfile
+# license : MIT; see accompanying LICENSE file
+
+exe{driver}: {hxx cxx}{* -options} cli.cxx{options} doc{README}
+exe{driver}: test.arguments = --options-file
+exe{driver}: file{test.ops}: test.input = true # Added after test.arguments.
+
+cxx.poptions =+ "-I$out_base"
+
+cli.cxx{options}: cli{options}
+cli.options = --generate-file-scanner
diff --git a/cli-examples/file/driver.cxx b/cli-examples/file/driver.cxx
new file mode 100644
index 0000000..b53574c
--- /dev/null
+++ b/cli-examples/file/driver.cxx
@@ -0,0 +1,35 @@
+// file : file/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// license : MIT; see accompanying LICENSE file
+
+#include <iostream>
+#include <iterator>
+#include <algorithm>
+
+#include "options.hxx"
+
+using namespace std;
+
+int
+main (int argc, char* argv[])
+{
+ try
+ {
+ cli::argv_file_scanner s (argc, argv, "--options-file");
+ options o (s);
+
+ cout << "verbosity: " << o.verbose () << endl
+ << "values: ";
+
+ copy (o.val ().begin (),
+ o.val ().end (),
+ ostream_iterator<int> (cout, " "));
+
+ cerr << endl;
+ }
+ catch (const cli::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/cli-examples/file/options.cli b/cli-examples/file/options.cli
new file mode 100644
index 0000000..3e6db5a
--- /dev/null
+++ b/cli-examples/file/options.cli
@@ -0,0 +1,7 @@
+include <vector>;
+
+class options
+{
+ int --verbose;
+ std::vector<int> --val;
+};
diff --git a/cli-examples/file/test.ops b/cli-examples/file/test.ops
new file mode 100644
index 0000000..65fcf07
--- /dev/null
+++ b/cli-examples/file/test.ops
@@ -0,0 +1,7 @@
+# Sample options file. Empty lines and lines starting with '#' are
+# ignored.
+#
+--verbose 5
+
+--val 2
+--val=3
diff --git a/cli-examples/hello/.gitignore b/cli-examples/hello/.gitignore
new file mode 100644
index 0000000..d73130a
--- /dev/null
+++ b/cli-examples/hello/.gitignore
@@ -0,0 +1 @@
+hello.?xx
diff --git a/cli-examples/hello/README b/cli-examples/hello/README
new file mode 100644
index 0000000..dd14b01
--- /dev/null
+++ b/cli-examples/hello/README
@@ -0,0 +1,26 @@
+This is a "Hello, world!" example that shows how to implement a very basic
+command line interface using CLI.
+
+The example consists of the following files:
+
+hello.cli
+ Command line interface description in the CLI language.
+
+hello.hxx
+hello.ixx
+hello.cxx
+ Command line interface implementation in C++. These files are generated
+ by the CLI compiler from hello.cli using the following command line:
+
+ cli hello.cli
+
+driver.cxx
+ Driver for the example. It first instantiates the option class which parses
+ the command line. The driver then examines the options and prints the
+ greeting string for each name passed as an argument.
+
+To run the example you can try the following command lines:
+
+$ ./driver --help
+$ ./driver John Jane
+$ ./driver --greeting Hi --exclamations 3 John Jane
diff --git a/cli-examples/hello/buildfile b/cli-examples/hello/buildfile
new file mode 100644
index 0000000..8197d9e
--- /dev/null
+++ b/cli-examples/hello/buildfile
@@ -0,0 +1,9 @@
+# file : hello/buildfile
+# license : MIT; see accompanying LICENSE file
+
+exe{driver}: {hxx cxx}{* -hello} cli.cxx{hello} doc{README}
+exe{driver}: test.arguments = --greeting Hi John Jane
+
+cxx.poptions =+ "-I$out_base"
+
+cli.cxx{hello}: cli{hello}
diff --git a/cli-examples/hello/driver.cxx b/cli-examples/hello/driver.cxx
new file mode 100644
index 0000000..bc37564
--- /dev/null
+++ b/cli-examples/hello/driver.cxx
@@ -0,0 +1,58 @@
+// file : hello/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// license : MIT; see accompanying LICENSE file
+
+#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;
+ }
+}
diff --git a/cli-examples/hello/hello.cli b/cli-examples/hello/hello.cli
new file mode 100644
index 0000000..b75e1b8
--- /dev/null
+++ b/cli-examples/hello/hello.cli
@@ -0,0 +1,18 @@
+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."
+ };
+};
diff --git a/cli-examples/manifest b/cli-examples/manifest
new file mode 100644
index 0000000..9ef14f3
--- /dev/null
+++ b/cli-examples/manifest
@@ -0,0 +1,15 @@
+: 1
+name: cli-examples
+version: 1.2.0-b.6.z
+project: cli
+summary: Examples of using the CLI language and compiler for C++
+license: MIT
+description-file: README
+url: https://www.codesynthesis.com/projects/cli/
+doc-url: https://www.codesynthesis.com/projects/cli/doc/guide/
+src-url: https://git.codesynthesis.com/cgit/cli/cli/tree/cli-examples
+email: cli-users@codesynthesis.com ; Mailing list
+build-email: builds@codesynthesis.com
+requires: c++14
+depends: * build2 >= 0.13.0-
+depends: * bpkg >= 0.13.0-