diff options
author | lloyd <[email protected]> | 2006-05-18 18:33:19 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2006-05-18 18:33:19 +0000 |
commit | a2c99d3270eb73ef2db5704fc54356c6b75096f8 (patch) | |
tree | ad3d6c4fcc8dd0f403f8105598943616246fe172 /src/inifile.cpp |
Initial checkin1.5.6
Diffstat (limited to 'src/inifile.cpp')
-rw-r--r-- | src/inifile.cpp | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/src/inifile.cpp b/src/inifile.cpp new file mode 100644 index 000000000..44830ef22 --- /dev/null +++ b/src/inifile.cpp @@ -0,0 +1,150 @@ +/************************************************* +* Configuration Reader Source File * +* (C) 1999-2006 The Botan Project * +*************************************************/ + +#include <botan/conf.h> +#include <botan/libstate.h> +#include <botan/charset.h> +#include <botan/parsing.h> +#include <fstream> +#include <map> + +namespace Botan { + +namespace { + +/************************************************* +* Strip comments and whitespace from line * +*************************************************/ +std::string strip_whitespace(const std::string& line) + { + bool is_escaped = false, in_quote = false, in_string = false; + std::string new_line; + + for(std::string::const_iterator j = line.begin(); j != line.end(); ++j) + { + const char c = *j; + + if(c == '"' && !is_escaped && !in_string) + { in_quote = !in_quote; continue; } + if(c == '\'' && !is_escaped && !in_quote) + { in_string = !in_string; continue; } + if(c == '#' && !is_escaped && !in_quote && !in_string) + return new_line; + if(c == '\\' && !is_escaped) { is_escaped = true; continue; } + + if(is_space(c) && !in_quote && !in_string && !is_escaped) + continue; + + new_line += c; + is_escaped = false; + } + + return new_line; + } + +/************************************************* +* Do variable interpolation * +*************************************************/ +std::string interpolate(const std::string& value, + const std::map<std::string, std::string>& variables) + { + std::string variable, suffix; + + if(value.find('.') == std::string::npos) + variable = value; + else + { + variable = value.substr(0, value.find('.')); + suffix = value.substr(value.find('.'), std::string::npos); + } + + if(variables.find(variable) != variables.end()) + { + const std::string result = variables.find(variable)->second; + if(variable == result) + return value; + return interpolate(result, variables) + suffix; + } + return value; + } + +} + +namespace Config { + +/************************************************* +* Load a configuration file * +*************************************************/ +void load(const std::string& fsname) + { + load(fsname, global_state()); + } + +/************************************************* +* Load a configuration file * +*************************************************/ +void load(const std::string& fsname, Library_State& state) + { + std::ifstream config(fsname.c_str()); + + if(!config) + throw Config_Error("Could not open config file " + fsname); + + u32bit line_no = 0; + std::string line, section; + std::map<std::string, std::string> variables; + + while(std::getline(config, line)) + { + ++line_no; + + line = strip_whitespace(line); + + if(line == "") + continue; + + if(line[0] == '[' && line[line.size()-1] == ']') + { + section = line.substr(1, line.size() - 2); + if(section == "") + throw Config_Error("Empty section name", line_no); + continue; + } + + if(section == "") + throw Config_Error("Section must be set before assignment", line_no); + + std::vector<std::string> name_and_value; + try { + name_and_value = split_on(line, '='); + } + catch(Format_Error) + { + throw Config_Error("Bad assignment: " + line, line_no); + } + + if(name_and_value.size() != 2) + throw Config_Error("Bad line: " + line, line_no); + const std::string name = name_and_value[0]; + const std::string value = interpolate(name_and_value[1], variables); + + if(variables.find(name) == variables.end()) + variables[name] = value; + + if(section == "oids") + { + state.set_option("oid2str", name, value, false); + state.set_option("str2oid", value, name, false); + } + else if(section == "aliases") + state.set_option("alias", name, value); + else + state.set_option("conf", section + '/' + name, value); + } + } + +} + +} |