diff options
Diffstat (limited to 'src/lib/utils/read_cfg.cpp')
-rw-r--r-- | src/lib/utils/read_cfg.cpp | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/src/lib/utils/read_cfg.cpp b/src/lib/utils/read_cfg.cpp new file mode 100644 index 000000000..ad57a8b3e --- /dev/null +++ b/src/lib/utils/read_cfg.cpp @@ -0,0 +1,115 @@ +/* +* Simple config/test file reader +* (C) 2013 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/parsing.h> +#include <boost/algorithm/string.hpp> + +namespace Botan { + +void lex_cfg(std::istream& is, + std::function<void (std::string)> cb) + { + while(is.good()) + { + std::string s; + + std::getline(is, s); + + while(is.good() && s.back() == '\\') + { + boost::trim_if(s, boost::is_any_of("\\\n")); + std::string x; + std::getline(is, x); + boost::trim_left(x); + s += x; + } + + auto comment = s.find('#'); + if(comment) + s = s.substr(0, comment); + + if(s.empty()) + continue; + + std::vector<std::string> parts; + boost::split(parts, s, boost::is_any_of(" \t\n"), boost::token_compress_on); + + for(auto p : parts) + { + if(p.empty()) + continue; + + auto eq = p.find("="); + + if(eq == std::string::npos || p.size() < 2) + { + cb(p); + } + else if(eq == 0) + { + cb("="); + cb(p.substr(1, std::string::npos)); + } + else if(eq == p.size() - 1) + { + cb(p.substr(0, p.size() - 1)); + cb("="); + } + else if(eq != std::string::npos) + { + cb(p.substr(0, eq)); + cb("="); + cb(p.substr(eq + 1, std::string::npos)); + } + } + } + } + +void lex_cfg_w_headers(std::istream& is, + std::function<void (std::string)> cb, + std::function<void (std::string)> hdr_cb) + { + auto intercept = [cb,hdr_cb](const std::string& s) + { + if(s[0] == '[' && s[s.length()-1] == ']') + hdr_cb(s.substr(1, s.length()-2)); + else + cb(s); + }; + + lex_cfg(is, intercept); + } + +std::map<std::string, std::map<std::string, std::string>> + parse_cfg(std::istream& is) + { + std::string header = "default"; + std::map<std::string, std::map<std::string, std::string>> vals; + std::string key; + + auto header_cb = [&header](const std::string i) { header = i; }; + auto cb = [&header,&key,&vals](const std::string s) + { + if(s == "=") + { + BOTAN_ASSERT(!key.empty(), "Valid assignment in config"); + } + else if(key.empty()) + key = s; + else + { + vals[header][key] = s; + key = ""; + } + }; + + lex_cfg_w_headers(is, cb, header_cb); + + return vals; + } + +} |