1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
14 #include <anna/core/functions.hpp>
15 #include <anna/core/util/Configuration.hpp>
16 #include <anna/core/RuntimeException.hpp>
17 #include <anna/core/tracing/Logger.hpp>
18 #include <anna/core/tracing/TraceMethod.hpp>
23 const char* Configuration::defaultSection = "@global@";
25 void Configuration::load(const char* configFile)
26 throw(RuntimeException) {
27 LOGMETHOD(TraceMethod tm("Configuration", "load", ANNA_FILE_LOCATION));
31 string currentSection(defaultSection);
35 if((file = fopen(configFile, "r")) == NULL)
36 throw RuntimeException(configFile, errno, ANNA_FILE_LOCATION);
38 LOGDEBUG(Logger::write(Logger::Debug, "Configuration file", configFile, ANNA_FILE_LOCATION));
41 while(fgets(buffer, sizeof(buffer) - 1, file) != NULL) {
42 if((aux = strchr(buffer, '#')) != NULL)
45 if(anna_strlen(aux = strip(buffer)) <= 0)
48 if(processSection(nline, aux, currentSection) == true)
51 processVariable(nline, aux, currentSection);
54 } catch(RuntimeException& ex) {
62 bool Configuration::exists(const char* sectionName, const char* variableName) const
64 const VariableEx* var = find(string(sectionName), variableName);
65 return (var == NULL) ? false : !var->isNull();
68 void Configuration::setDefaultValue(const char* sectionName, const char* variableName, const char* defaultValue)
69 throw(RuntimeException) {
70 string section(sectionName);
71 VariableEx* var = find(section, variableName);
74 var = createVariable(section, variableName);
76 var->setDefaultValue(defaultValue);
78 string msg(sectionName);
82 msg += " | Default value: ";
84 Logger::write(Logger::Information, msg, ANNA_FILE_LOCATION);
88 const char* Configuration::getValue(const char* sectionName, const char* variableName, const bool strict) const
89 throw(RuntimeException) {
90 const VariableEx* variable = find(string(sectionName), variableName);
91 const char* result(NULL);
93 if(variable == NULL) {
94 string msg("Variable ");
98 msg += " is not defined";
99 throw RuntimeException(msg, ANNA_FILE_LOCATION);
102 if(variable->isNull() == false)
103 result = variable->getStringValue();
105 result = (strict == false) ? variable->getDefaultValue() : NULL;
110 int Configuration::getIntegerValue(const char* sectionName, const char* variableName, const bool strict) const
111 throw(RuntimeException) {
112 return atoi(getValue(sectionName, variableName, strict));
115 char* Configuration::strip(char* buffer) {
117 result = buffer + (anna_strlen(buffer) - 1);
119 while(result >= buffer && isspace(*result))
124 for(result = buffer; *result && isspace(*result); result ++);
129 bool Configuration::processSection(const int nline, char* buffer, string& currentSection) {
135 if((end = strchr(buffer, ']')) != NULL) {
136 *end = 0; // JASC, antes NULL
138 if(anna_strlen(section = strip(++ buffer)) > 0)
139 currentSection = section;
141 string msg("Invalid section name at line: ");
142 msg += functions::asString(nline);
143 throw RuntimeException(msg, ANNA_FILE_LOCATION);
153 void Configuration::processVariable(const int nline, char* buffer, const string& currentSection)
154 throw(RuntimeException) {
158 VariableEx* variable;
160 if((aux = anna_strchr(buffer , '=')) == NULL)
165 if(anna_strlen(variableName = strip(buffer)) <= 0) {
166 string msg("Invalid section name at line: ");
167 msg += functions::asString(nline);
168 throw RuntimeException(msg, ANNA_FILE_LOCATION);
171 if(anna_strlen(value = strip(aux + 1)) <= 0)
174 if((variable = find(currentSection, variableName)) != NULL) {
175 if(variable->isNull() == false) {
176 string msg("Duplicated variable | Section: ");
177 msg += currentSection;
178 msg += " | Variable: ";
181 msg += functions::asString(nline);
182 throw RuntimeException(msg, ANNA_FILE_LOCATION);
185 variable = createVariable(currentSection, variableName);
187 variable->setValue(value);
189 if(Logger::isActive(Logger::Information)) {
190 string msg(currentSection);
195 Logger::write(Logger::Information, variable->asString(), ANNA_FILE_LOCATION);
199 Configuration::VariableEx* Configuration::createVariable(const string& section, const char* variableName)
201 map <string, VariableEx::Vector*>::iterator isection(a_sections.find(section));
203 VariableEx::Vector* variables;
204 result = new VariableEx(variableName);
206 if(isection == a_sections.end()) {
207 variables = new VariableEx::Vector;
208 a_sections [section] = variables;
210 variables = isection->second;
212 variables->push_back(result);
216 Configuration::VariableEx* Configuration::find(const string& section, const char* variableName)
218 VariableEx* result(NULL);
219 map <string, VariableEx::Vector*>::iterator isection(a_sections.find(section));
221 if(isection == a_sections.end())
224 VariableEx::Vector* varVector(isection->second);
226 for(VariableEx::Vector::iterator vv = varVector->begin(), maxvv = varVector->end(); vv != maxvv; vv ++) {
227 if(!strcmp((*vv)->getName(), variableName)) {
236 void Configuration::removeAll()
238 map <string, VariableEx::Vector*>::iterator ii(a_sections.begin());
239 map <string, VariableEx::Vector*>::iterator end(a_sections.end());
240 VariableEx::Vector::iterator vv, maxvv;
241 VariableEx* variable;
243 for(; ii != end; ii ++) {
244 for(vv = ii->second->begin(), maxvv = ii->second->end(); vv != maxvv; vv ++) {