aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/utils/info.txt11
-rw-r--r--src/utils/parsing.h16
-rw-r--r--src/utils/read_cfg.cpp115
3 files changed, 131 insertions, 11 deletions
diff --git a/src/utils/info.txt b/src/utils/info.txt
index 33f38386d..0e8edeb00 100644
--- a/src/utils/info.txt
+++ b/src/utils/info.txt
@@ -2,17 +2,6 @@ define UTIL_FUNCTIONS 20131128
load_on always
-<source>
-assert.cpp
-calendar.cpp
-charset.cpp
-cpuid.cpp
-parsing.cpp
-semaphore.cpp
-version.cpp
-zero_mem.cpp
-</source>
-
<header:internal>
bit_ops.h
prefetch.h
diff --git a/src/utils/parsing.h b/src/utils/parsing.h
index 88c5a7bc0..b37e3cb62 100644
--- a/src/utils/parsing.h
+++ b/src/utils/parsing.h
@@ -13,6 +13,10 @@
#include <vector>
#include <set>
+#include <istream>
+#include <functional>
+#include <map>
+
namespace Botan {
/**
@@ -112,6 +116,18 @@ BOTAN_DLL u32bit string_to_ipv4(const std::string& ip_str);
*/
BOTAN_DLL std::string ipv4_to_string(u32bit ip_addr);
+void BOTAN_DLL lex_cfg(std::istream& is,
+ std::function<void (std::string)> cb);
+
+void BOTAN_DLL lex_cfg_w_headers(std::istream& is,
+ std::function<void (std::string)> cb,
+ std::function<void (std::string)> header_cb);
+
+std::map<std::string, std::map<std::string, std::string>>
+BOTAN_DLL
+parse_cfg(std::istream& is);
+
+
}
#endif
diff --git a/src/utils/read_cfg.cpp b/src/utils/read_cfg.cpp
new file mode 100644
index 000000000..ad57a8b3e
--- /dev/null
+++ b/src/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;
+ }
+
+}