File: example.cpp

package info (click to toggle)
libmcfp 1.4.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 304 kB
  • sloc: cpp: 1,573; sh: 20; makefile: 8
file content (107 lines) | stat: -rw-r--r-- 3,289 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// Example of using libmcfp

#include <iostream>
#include <filesystem>

#include <mcfp/mcfp.hpp>

int main(int argc, char * const argv[])
{
    // config is a singleton
	auto &config = mcfp::config::instance();

	// Initialise the config object. This can be done more than once,
	// e.g. when you have different sets of options depending on the
	// first operand.

	config.init(
		// The first parameter is the 'usage' line, used when printing out the options
		"usage: example [options] file",

		// Flag options (not taking a parameter)
		mcfp::make_option("help,h", "Print this help text"),
		mcfp::make_option("verbose,v", "Verbose level, can be specified more than once to increase level"),

		// A couple of options with parameter
		mcfp::make_option<std::string>("config", "Config file to use"),
		mcfp::make_option<std::string>("text", "The text string to echo"),

		// And options with a default parameter
		mcfp::make_option<int>("a", 1, "first parameter for multiplication"),
		mcfp::make_option<float>("b", 2.0f, "second parameter for multiplication"),

		// You can also allow multiple values
		mcfp::make_option<std::vector<std::string>>("c", "Option c, can be specified more than once"),

		// This option is not shown when printing out the options
		mcfp::make_hidden_option("d", "Debug mode")
	);

	// There are two flavors of calls, ones that take an error_code
	// and return the error in that code in case something is wrong.
	// The alternative is calling without an error_code, in which
	// case an exception is thrown when appropriate

	// Parse the command line arguments here

	std::error_code ec;
	config.parse(argc, argv, ec);
	if (ec)
	{
        std::cerr << "Error parsing argument " << std::quoted(config.get_last_option()) << ": " << ec.message() << std::endl;
		exit(1);
	}

	// First check, to see if we need to stop early on

	if (config.has("help") or config.operands().size() != 1)
	{
		// This will print out the 'usage' message with all the visible options
		std::cerr << config << std::endl;
		exit(config.has("help") ? 0 : 1);
	}

	// Configuration files, read it if it exists. If the users
	// specifies an alternative config file, it is an error if that
	// file cannot be found.

	config.parse_config_file("config", "example.conf", { "." }, ec);
	if (ec)
	{
        std::cerr << "Error parsing config file, option " << std::quoted(config.get_last_option()) << ": " << ec.message() << std::endl;
		exit(1);
	}

	// If options are specified more than once, you can get the count 

	int VERBOSE = config.count("verbose");

	// Operands are arguments that are not options, e.g. files to act upon

	std::cout << "The first operand is " << config.operands().front() << std::endl;

	// Getting the value of a string option

	auto text = config.get<std::string>("text", ec);
	if (ec)
	{
		std::cerr << "Error getting option text: " << ec.message() << std::endl;
		exit(1);
	}

	std::cout << "Text option is " << text << std::endl;

	// Likewise for numeric options

	int a = config.get<int>("a");
	float b = config.get<float>("b");

	std::cout << "a (" << a << ") * b (" << b << ") = " << a * b << std::endl;

	// And multiple strings

	for (std::string s : config.get<std::vector<std::string>>("c"))
		std::cout << "c: " << s << std::endl;

	return 0;
}