monotone

monotone Mtn Source Tree

Root/botan/inifile.cpp

1/*************************************************
2* Configuration Reader Source File *
3* (C) 1999-2006 The Botan Project *
4*************************************************/
5
6#include <botan/config.h>
7#include <botan/charset.h>
8#include <botan/parsing.h>
9#include <botan/exceptn.h>
10#include <fstream>
11#include <map>
12
13namespace Botan {
14
15namespace {
16
17/*************************************************
18* Strip comments and whitespace from line *
19*************************************************/
20std::string strip_whitespace(const std::string& line)
21 {
22 bool is_escaped = false, in_quote = false, in_string = false;
23 std::string new_line;
24
25 for(std::string::const_iterator j = line.begin(); j != line.end(); ++j)
26 {
27 const char c = *j;
28
29 if(c == '"' && !is_escaped && !in_string)
30 { in_quote = !in_quote; continue; }
31 if(c == '\'' && !is_escaped && !in_quote)
32 { in_string = !in_string; continue; }
33 if(c == '#' && !is_escaped && !in_quote && !in_string)
34 return new_line;
35 if(c == '\\' && !is_escaped) { is_escaped = true; continue; }
36
37 if(Charset::is_space(c) && !in_quote && !in_string && !is_escaped)
38 continue;
39
40 new_line += c;
41 is_escaped = false;
42 }
43
44 return new_line;
45 }
46
47/*************************************************
48* Do variable interpolation *
49*************************************************/
50std::string interpolate(const std::string& value,
51 const std::map<std::string, std::string>& variables)
52 {
53 std::string variable, suffix;
54
55 if(value.find('.') == std::string::npos)
56 variable = value;
57 else
58 {
59 variable = value.substr(0, value.find('.'));
60 suffix = value.substr(value.find('.'), std::string::npos);
61 }
62
63 if(variables.find(variable) != variables.end())
64 {
65 const std::string result = variables.find(variable)->second;
66 if(variable == result)
67 return value;
68 return interpolate(result, variables) + suffix;
69 }
70 return value;
71 }
72
73}
74
75/*************************************************
76* Load a configuration file *
77*************************************************/
78void Config::load_inifile(const std::string& fsname)
79 {
80 std::ifstream config(fsname.c_str());
81
82 if(!config)
83 throw Config_Error("Could not open config file " + fsname);
84
85 u32bit line_no = 0;
86 std::string line, section;
87 std::map<std::string, std::string> variables;
88
89 while(std::getline(config, line))
90 {
91 ++line_no;
92
93 line = strip_whitespace(line);
94
95 if(line == "")
96 continue;
97
98 if(line[0] == '[' && line[line.size()-1] == ']')
99 {
100 section = line.substr(1, line.size() - 2);
101 if(section == "")
102 throw Config_Error("Empty section name", line_no);
103 continue;
104 }
105
106 if(section == "")
107 throw Config_Error("Section must be set before assignment", line_no);
108
109 std::vector<std::string> name_and_value;
110 try {
111 name_and_value = split_on(line, '=');
112 }
113 catch(Format_Error)
114 {
115 throw Config_Error("Bad assignment: " + line, line_no);
116 }
117
118 if(name_and_value.size() != 2)
119 throw Config_Error("Bad line: " + line, line_no);
120 const std::string name = name_and_value[0];
121 const std::string value = interpolate(name_and_value[1], variables);
122
123 if(variables.find(name) == variables.end())
124 variables[name] = value;
125
126 if(section == "oids")
127 {
128 set("oid2str", name, value, false);
129 set("str2oid", value, name, false);
130 }
131 else if(section == "aliases")
132 set("alias", name, value);
133 else
134 set("conf", section + '/' + name, value);
135 }
136 }
137
138}

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status