/* * ConfigManager.cpp * * Copyright (C) 2008 Matthias Schiffer * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along * with this program. If not, see . */ #include "Application.h" #include "ConfigManager.h" #include "ConfigEntry.h" #include "Configurable.h" #include "Tokenizer.h" #include #include #include namespace Mad { namespace Core { bool ConfigManager::Compare::operator() (const Configurable *c1, const Configurable *c2) { if(c1->getPriority() != c2->getPriority()) return c1->getPriority() > c2->getPriority(); else return c1 < c2; } bool ConfigManager::loadFile(const std::string &filename) { if(configured) return false; std::ifstream file(filename.c_str()); ConfigEntry *currentEntry = this; ConfigEntry *lastEntry = this; String line, input; UChar delim; std::vector splitLine; if(!file.good()) return false; while(!(file.eof() && line.isEmpty() && input.isEmpty())) { while(input.isEmpty() && !file.eof()) { input = String::getline(file); } if(input.isEmpty()) break; boost::int32_t pos = input.findFirstOf("#{}"); if(pos < 0) { line += input; delim = '\n'; input.remove(); } else { line += input.substr(0, pos); delim = input[pos]; input.remove(0, pos+1); } if(!Tokenizer::tokenize(line, splitLine)) { line += delim; continue; } if(!splitLine.empty()) { boost::shared_ptr entry(new ConfigEntry(currentEntry, std::vector(splitLine.begin()+1, splitLine.end()))); currentEntry->addChild(splitLine.front(), entry); lastEntry = entry.get(); } switch(delim) { case '#': input.remove(); break; case '{': currentEntry = lastEntry; break; case '}': lastEntry = currentEntry = currentEntry->getParent(); } line.remove(); } // TODO Depth check return true; } void ConfigManager::configure() { if(configured) return; while(!unconfiguredConfigurables.empty()) { std::set::iterator it = unconfiguredConfigurables.begin(); Configurable *c = *it; unconfiguredConfigurables.erase(it); c->configure(); } configured = true; } } }