aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/utils/read_cfg.cpp
diff options
context:
space:
mode:
authorlloyd <[email protected]>2015-01-23 22:29:13 +0000
committerlloyd <[email protected]>2015-01-23 22:29:13 +0000
commit72883a57553a1e6845eec71d1b53254ee041c6ec (patch)
treef66ea82daa6b15d6fb05194dcd622fdbcdb6f1ab /src/lib/utils/read_cfg.cpp
parentb8814d2833741156a5ddc2c758da4e907581c823 (diff)
Add support for configuring a TLS::Policy by text file
Diffstat (limited to 'src/lib/utils/read_cfg.cpp')
-rw-r--r--src/lib/utils/read_cfg.cpp129
1 files changed, 37 insertions, 92 deletions
diff --git a/src/lib/utils/read_cfg.cpp b/src/lib/utils/read_cfg.cpp
index 8f186cefd..02708c3d6 100644
--- a/src/lib/utils/read_cfg.cpp
+++ b/src/lib/utils/read_cfg.cpp
@@ -1,121 +1,66 @@
/*
* Simple config/test file reader
-* (C) 2013,2014 Jack Lloyd
+* (C) 2013,2014,2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#include <botan/parsing.h>
-#include <ctype.h>
namespace Botan {
-void lex_cfg(std::istream& is,
- std::function<void (std::string)> cb)
+namespace {
+
+std::string clean_ws(const std::string& s)
{
+ const char* ws = " \t\n";
+ auto start = s.find_first_not_of(ws);
+ auto end = s.find_last_not_of(ws);
+
+ if(start == std::string::npos)
+ return "";
+
+ if(end == std::string::npos)
+ return s.substr(start, end);
+ else
+ return s.substr(start, start + end + 1);
+ }
+
+}
+
+std::map<std::string, std::string> read_cfg(std::istream& is)
+ {
+ std::map<std::string, std::string> kv;
+ size_t line = 0;
+
while(is.good())
{
std::string s;
std::getline(is, s);
- while(is.good() && s.back() == '\\')
- {
- while(s.size() && (s.back() == '\\' || s.back() == '\n'))
- s.resize(s.size()-1);
-
- std::string x;
- std::getline(is, x);
-
- size_t i = 0;
+ ++line;
- while(i < x.size() && (::isspace(x[i])))
- ++i;
-
- s += x.substr(i);
- }
+ if(s == "" || s[0] == '#')
+ continue;
- auto comment = s.find('#');
- if(comment)
- s = s.substr(0, comment);
+ s = clean_ws(s.substr(0, s.find('#')));
- if(s.empty())
+ if(s == "")
continue;
- auto parts = split_on_pred(s, [](char c) { return ::isspace(c); });
-
- 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));
- }
- }
- }
- }
+ auto eq = s.find("=");
-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);
- };
+ if(eq == std::string::npos || eq == 0 || eq == s.size() - 1)
+ throw std::runtime_error("Bad read_cfg input '" + s + "' on line " + std::to_string(line));
- lex_cfg(is, intercept);
- }
+ const std::string key = clean_ws(s.substr(0, eq));
+ const std::string val = clean_ws(s.substr(eq + 1, std::string::npos));
-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;
+ kv[key] = val;
+ }
- 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;
+ return kv;
}
}