summaryrefslogtreecommitdiff
path: root/cpp/examples/all_functions.cpp
blob: 326ae39c1312960308b3efc708d6946e1643b1bc (plain)
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
129
130
131
132
133
134
135
136
137
138
139
// 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) {
		size_t total_read = 0;
		while (true) {
			// must call read in a loop to fill buf up as much as possible!
			// (read isn't guaranteed to read len bytes even if it could)
			ssize_t ret = ::read(m_fd, buf, size);
			if (ret < 0) {
				// read error
				throw "read error";
			} else if (ret == 0) {
				// end-of-file
				break;
			} else {
				total_read += ret;
				buf += ret;
				size -= ret;
			}
		}
		return total_read;
	}
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;
}