// Demonstrates almost all of libpom++'s API #include #include #include #include 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 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 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 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("", "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; }