monotone

monotone Mtn Source Tree

Root/botan/inifile.cpp

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

Archive Download this file

Branches

Tags

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