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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
// Demonstrates almost all of libpom++'s API
#include <pom.hpp>
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
class FdReader: public pom::Reader {
public:
explicit FdReader(const char *path) {
m_fd = open(path, O_RDONLY);
if (m_fd == -1) {
throw "file doesn't exist";
}
}
~FdReader() { close(m_fd); }
size_t read(char *buf, size_t size) {
ssize_t ret = ::read(m_fd, buf, size);
if (ret < 0) {
// read error
throw "read error";
} else {
return ret;
}
}
private:
int m_fd;
};
int main(void) {
try {
// ordinary usage: load from a path
pom::Configuration conf("conf.pom");
// get a key
std::optional<std::string> indentation_type = conf.get("indentation-type");
std::cout << "Indentation type: " << indentation_type.value_or("(none)") << "\n";
// load configuration with custom settings and a custom reader
pom::Settings settings = {};
settings.set_error_language("fr"); // erreurs en français
FdReader reader("conf.pom");
conf = pom::Configuration(
"conf.pom", // file name for error messages
reader, // object used to read file
&settings // settings
);
// nicer way of doing what we did above
std::cout << "Indentation type: "
<< conf.get_or_default("indentation-type", "(none)")
<< "\n";
// parse value as signed integer
std::optional<int64_t> tab_size = conf.get_int("tab-size");
std::cout << "tab size: ";
if (tab_size.has_value())
std::cout << tab_size.value();
else
std::cout << "(none set)";
std::cout << "\n";
// parse value as unsigned integer, use default of 2
std::cout << "padding pixels: "
<< conf.get_uint_or_default("padding-pixels", 2)
<< "\n";
// parse value as double
std::cout << "font size: "
<< conf.get_float_or_default("font-size", 12.5)
<< "\n";
// parse value as boolean
std::cout << "show line numbers: "
<< (conf.get_bool_or_default("show-line-numbers", true) ? "yes" : "no")
<< "\n";
// extract section out of configuration
pom::Configuration file_extensions = conf.section("file-extensions");
// parse value as list
std::vector<std::string> Cpp_extensions = file_extensions.get_list_or_default("Cpp", {});
if (!Cpp_extensions.empty()) {
for (const std::string &extension: Cpp_extensions)
std::cout << "C++ extension: " << extension << "\n";
} else {
printf("no extensions defined for C++\n");
}
// iterate over keys in section
pom::Configuration plugins = conf.section("plug-in");
for (std::string &key: plugins.keys()) {
pom::Configuration plugin = plugins.section(key);
auto path = plugin.get_or_default("path", "(none)");
bool enabled = plugin.get_bool_or_default("enabled", true);
// get location where key was defined
pom::Location location = plugins.location(key).value();
std::cout << location.file() << ":" << location.line()
<< ": plug-in " << key
<< " (path = " << path <<
", enabled = " << enabled << ")\n";
}
// load config from string
pom::Configuration overrides("<built-in overrides>", "tab-size = 12");
// merge configurations
conf.merge(overrides);
// iterate over items (key-value pairs) in configuration
for (const auto &item: conf.items()) {
if (item->key().find('b') != std::string_view::npos)
std::cout << item->key() << ": " << item->value() << "\n";
}
// iterate over all the keys which haven't been accessed directly
for (const std::string &key: conf.unread_keys()) {
std::cout << "unrecognized key " << key << "\n";
}
} catch (pom::Error &error) { // error from libpom++
std::cerr << error;
return EXIT_FAILURE;
} catch (const char *error) { // error from FdReader
std::cerr << error << "\n";
return EXIT_FAILURE;
}
return 0;
}
|