From 90b225394dac8a5d9a0e6eb8c046e0973299c9c9 Mon Sep 17 00:00:00 2001 From: dwk Date: Sun, 7 Nov 2010 01:04:00 -0600 Subject: [PATCH] Implemented adhoc parser for config files because I was the most awake. --- .aesalon.conf | 13 ++ configformat | 23 +++ include/monitor/Coordinator.h | 8 +- include/monitor/config/ArgumentParser.h | 13 +- include/monitor/config/ConcreteVault.h | 39 ++++ include/monitor/config/Parser.h | 48 +++++ include/monitor/config/Vault.h | 33 ++++ include/monitor/module/Module.h | 4 +- include/monitor/program/Launcher.h | 6 +- monitor/src/Coordinator.cpp | 39 +--- monitor/src/SConscript | 2 +- monitor/src/config/ArgumentParser.cpp | 90 ++++----- .../src/config/ConcreteVault.cpp | 26 +-- monitor/src/config/Parser.cpp | 202 +++++++++++++++++++++ .../src/{module/Module.cpp => config/Vault.cpp} | 18 +- monitor/src/module/Module.cpp | 2 +- monitor/src/program/Launcher.cpp | 2 +- this.conf | 4 + 18 files changed, 433 insertions(+), 139 deletions(-) create mode 100644 .aesalon.conf create mode 100644 configformat create mode 100644 include/monitor/config/ConcreteVault.h create mode 100644 include/monitor/config/Parser.h create mode 100644 include/monitor/config/Vault.h rewrite monitor/src/config/ArgumentParser.cpp (60%) copy include/monitor/config/ArgumentParser.h => monitor/src/config/ConcreteVault.cpp (52%) create mode 100644 monitor/src/config/Parser.cpp copy monitor/src/{module/Module.cpp => config/Vault.cpp} (51%) create mode 100644 this.conf diff --git a/.aesalon.conf b/.aesalon.conf new file mode 100644 index 0000000..138bfa3 --- /dev/null +++ b/.aesalon.conf @@ -0,0 +1,13 @@ +include "this.conf"; + +PATH += "modules/build"; + +module M { + var = 4; + varg += g; + newvar = a, b; +} + +use M; + +global = f, g; diff --git a/configformat b/configformat new file mode 100644 index 0000000..4f0c822 --- /dev/null +++ b/configformat @@ -0,0 +1,23 @@ +include "file.config" + +module M { + var = 4; + var += 4; + var = g, h; + var += g; +} + +use cpuTime; + +tokens: + = + += + { + } + " + ; + , + include + module + use + diff --git a/include/monitor/Coordinator.h b/include/monitor/Coordinator.h index 1c110cf..e7a498d 100644 --- a/include/monitor/Coordinator.h +++ b/include/monitor/Coordinator.h @@ -12,7 +12,7 @@ #ifndef AesalonMonitor_Coordinator_H #define AesalonMonitor_Coordinator_H -#include "config/Store.h" +#include "config/Vault.h" #include "module/List.h" namespace Monitor { @@ -21,8 +21,7 @@ class Coordinator { private: static Coordinator *m_instance; char **m_argv; - Config::Store *m_store; - int m_argumentEndpoint; + Config::Vault *m_vault; Module::List *m_moduleList; public: static Coordinator *instance() { return m_instance; } @@ -30,8 +29,7 @@ public: ~Coordinator(); char **argv() const { return m_argv; } - Config::Store *store() const { return m_store; } - int argumentEndpoint() const { return m_argumentEndpoint; } + Config::Vault *vault() const { return m_vault; } Module::List *moduleList() const { return m_moduleList; } void run(); diff --git a/include/monitor/config/ArgumentParser.h b/include/monitor/config/ArgumentParser.h index 6c1ff65..0ede974 100644 --- a/include/monitor/config/ArgumentParser.h +++ b/include/monitor/config/ArgumentParser.h @@ -12,20 +12,17 @@ #ifndef AesalonMonitor_Config_ArgumentParser_H #define AesalonMonitor_Config_ArgumentParser_H -#include "Store.h" +#include "Vault.h" namespace Monitor { namespace Config { class ArgumentParser { -private: - Store *m_store; - char **m_argv; public: - ArgumentParser(Store *store, char **argv); - ~ArgumentParser(); - - int parse(); + /** + @return The argc corresponding to the first argv element that was not processed. + */ + int parse(Vault *vault, char **argv, int argc); }; } // namespace Config diff --git a/include/monitor/config/ConcreteVault.h b/include/monitor/config/ConcreteVault.h new file mode 100644 index 0000000..bf67adf --- /dev/null +++ b/include/monitor/config/ConcreteVault.h @@ -0,0 +1,39 @@ +/** + Aesalon, a tool to visualize a program's behaviour at run-time. + Copyright (C) 2010, Aesalon Development Team. + + Aesalon is distributed under the terms of the GNU GPLv3. For more + licensing information, see the file LICENSE included with the distribution. + + @file include/monitor/config/ConcreteVault.h + +*/ + +#ifndef AesalonMonitor_Config_ConcreteVault_H +#define AesalonMonitor_Config_ConcreteVault_H + +#include + +#include "Vault.h" + +namespace Monitor { +namespace Config { + +class ConcreteVault : public Vault { +private: + typedef std::map DataMap; + DataMap m_data; +public: + virtual ~ConcreteVault() {} + + virtual void set(const std::string &key, const std::string &value); + + /** Re-implemented. + */ + virtual std::string get(const std::string &key); +}; + +} // namespace Config +} // namespace Monitor + +#endif diff --git a/include/monitor/config/Parser.h b/include/monitor/config/Parser.h new file mode 100644 index 0000000..26fb3ce --- /dev/null +++ b/include/monitor/config/Parser.h @@ -0,0 +1,48 @@ +/** + Aesalon, a tool to visualize a program's behaviour at run-time. + Copyright (C) 2010, Aesalon Development Team. + + Aesalon is distributed under the terms of the GNU GPLv3. For more + licensing information, see the file LICENSE included with the distribution. + + @file include/monitor/config/Parser.h + +*/ + +#ifndef AesalonMonitor_Config_Parser_H +#define AesalonMonitor_Config_Parser_H + +#include + +#include "Vault.h" + +namespace Monitor { +namespace Config { + +class Parser { +private: + std::ifstream *m_stream; + + enum TokenType { + WORD, + QUOTED_WORD, + SYMBOL, + END_OF_FILE + }; +public: + void parse(Vault *vault, const std::string &configFile); +private: + void openFile(const std::string &configFile); + std::string nextToken(TokenType &type); + std::string expectNextToken(TokenType expected); + void expectNextSymbol(const std::string &symbol); + void skipWhitespace(); + void closeFile(); + + const char *nameOf(TokenType type) const; +}; + +} // namespace Config +} // namespace Monitor + +#endif diff --git a/include/monitor/config/Vault.h b/include/monitor/config/Vault.h new file mode 100644 index 0000000..1fd50d4 --- /dev/null +++ b/include/monitor/config/Vault.h @@ -0,0 +1,33 @@ +/** + Aesalon, a tool to visualize a program's behaviour at run-time. + Copyright (C) 2010, Aesalon Development Team. + + Aesalon is distributed under the terms of the GNU GPLv3. For more + licensing information, see the file LICENSE included with the distribution. + + @file include/monitor/config/Vault.h + +*/ + +#ifndef AesalonMonitor_Config_Vault_H +#define AesalonMonitor_Config_Vault_H + +#include + +namespace Monitor { +namespace Config { + +class Vault { +public: + virtual ~Vault() {} + + /** Returns the last value that @a key maps to. For all values, use @c match(). + */ + virtual std::string get(const std::string &key) = 0; + //virtual void match(const std::string &pattern, std::vector &keys) = 0; +}; + +} // namespace Config +} // namespace Monitor + +#endif diff --git a/include/monitor/module/Module.h b/include/monitor/module/Module.h index fb1018a..530a8ff 100644 --- a/include/monitor/module/Module.h +++ b/include/monitor/module/Module.h @@ -14,7 +14,7 @@ #include -#include "config/Store.h" +#include "config/Vault.h" namespace Monitor { namespace Module { @@ -23,7 +23,7 @@ class Module { private: std::string m_moduleName; public: - Module(Config::Store *store, const std::string &moduleName); + Module(Config::Vault *vault, const std::string &moduleName); ~Module(); }; diff --git a/include/monitor/program/Launcher.h b/include/monitor/program/Launcher.h index 9dffeb5..25e8b2b 100644 --- a/include/monitor/program/Launcher.h +++ b/include/monitor/program/Launcher.h @@ -12,17 +12,17 @@ #ifndef AesalonMonitor_Program_Launcher_H #define AesalonMonitor_Program_Launcher_H -#include "config/Store.h" +#include "config/Vault.h" namespace Monitor { namespace Program { class Launcher { private: - Config::Store *m_store; + Config::Vault *m_vault; char **m_argv; public: - Launcher(Config::Store *store, char **argv); + Launcher(Config::Vault *vault, char **argv); ~Launcher(); void startProcess(); diff --git a/monitor/src/Coordinator.cpp b/monitor/src/Coordinator.cpp index 8b17400..7347007 100644 --- a/monitor/src/Coordinator.cpp +++ b/monitor/src/Coordinator.cpp @@ -13,11 +13,13 @@ #include "Coordinator.h" #include "config/ArgumentParser.h" -#include "config/FileParser.h" +#include "config/Parser.h" #include "common/Config.h" #include "program/Launcher.h" #include "module/Module.h" +#include "config/ConcreteVault.h" + namespace Monitor { Coordinator *Coordinator::m_instance = NULL; @@ -32,46 +34,21 @@ Coordinator::~Coordinator() { void Coordinator::run() { parseConfigs(); - if(m_argv[m_argumentEndpoint] == NULL || m_store->item("help")->boolValue() + /*if(m_argv[m_argumentEndpoint] == NULL || m_store->item("help")->boolValue() || m_store->item("version")->boolValue()) { usage(!m_store->item("version")->boolValue()); return; } - Program::Launcher *launcher = new Program::Launcher(m_store, &m_argv[m_argumentEndpoint]); + Program::Launcher *launcher = new Program::Launcher(m_store, &m_argv[m_argumentEndpoint]);*/ } void Coordinator::parseConfigs() { - m_store = new Config::Store(); - /* Perform first pass through configuration . . . */ - Config::FileParser fp(m_store); - fp.parse(AesalonGlobalConfig); - fp.parse(AesalonUserConfig); - - Config::ArgumentParser ap(m_store, m_argv); - m_argumentEndpoint = ap.parse(); + Config::Parser parser; - - std::vector moduleList; - Config::Group *moduleGroup = m_store->group("modules"); - for(Config::Group::ItemMap::const_iterator i = moduleGroup->itemMap().begin(); - i != moduleGroup->itemMap().end(); ++i) { - - if(i->second->boolValue()) { - moduleList.push_back(i->first); - } - } - delete m_store; - - /* Perform second pass . . .*/ - m_store = new Config::Store(); - m_moduleList = new Module::List(); - for(std::vector::iterator i = moduleList.begin(); i != moduleList.end(); ++ i) { - std::string root = moduleRoot(*i); - Module::Module *module = new Module::Module(m_store, *i); - m_moduleList->addModule(module); - } + Config::Vault *vault = new Config::ConcreteVault(); + parser.parse(vault, /*AesalonLocalConfig*/ ".aesalon.conf"); } std::string Coordinator::moduleRoot(const std::string &moduleName) { diff --git a/monitor/src/SConscript b/monitor/src/SConscript index 6e41be0..837564c 100644 --- a/monitor/src/SConscript +++ b/monitor/src/SConscript @@ -1,6 +1,6 @@ Import("env") env.Append(CPPPATH = ["../../include/", "../../include/monitor/"]) -env.Append(CCFLAGS = ["-W", "-Wall"]) +env.Append(CCFLAGS = ["-W", "-Wall", "-g"]) env.Program(target = "aesalon", source = Glob("*.cpp") + Glob("*/*.cpp")) diff --git a/monitor/src/config/ArgumentParser.cpp b/monitor/src/config/ArgumentParser.cpp dissimilarity index 60% index bd3b5e4..771d91e 100644 --- a/monitor/src/config/ArgumentParser.cpp +++ b/monitor/src/config/ArgumentParser.cpp @@ -1,54 +1,36 @@ -/** - Aesalon, a tool to visualize a program's behaviour at run-time. - Copyright (C) 2010, Aesalon Development Team. - - Aesalon is distributed under the terms of the GNU GPLv3. For more - licensing information, see the file LICENSE included with the distribution. - - @file monitor/src/config/ArgumentParser.cpp - -*/ - -#include - -#include "config/ArgumentParser.h" -#include "common/ParsingException.h" - -namespace Monitor { -namespace Config { - -ArgumentParser::ArgumentParser(Store *store, char **argv) : m_store(store), m_argv(argv) { - -} - -ArgumentParser::~ArgumentParser() { - -} - -int ArgumentParser::parse() { - if(m_argv[0] == NULL) { - throw Common::ParsingException("Malformed argv given."); - } - - int i = 0; - - while(m_argv[++i] != NULL) { - if(m_argv[i][0] != '-' || m_argv[i][1] != '-') { - return i; - } - - std::string argument = &m_argv[i][2]; - if(argument.length() == 0) { - return i; - } - - std::string::size_type divider = argument.find('='); - Item *item = m_store->item(argument.substr(0, divider)); - if(divider == std::string::npos) item->setValue(true); - else item->setValue(argument.substr(divider+1)); - } - return i; -} - -} // namespace Config -} // namespace Monitor +/** + Aesalon, a tool to visualize a program's behaviour at run-time. + Copyright (C) 2010, Aesalon Development Team. + + Aesalon is distributed under the terms of the GNU GPLv3. For more + licensing information, see the file LICENSE included with the distribution. + + @file monitor/src/config/ArgumentParser.cpp + +*/ + +#include +#include + +#include "config/ArgumentParser.h" + +namespace Monitor { +namespace Config { + +int ArgumentParser::parse(Vault *vault, char **argv, int argc) { + int arg; + for(arg = 1; arg < argc; arg ++) { + if(std::strcmp(argv[arg], "--") == 0) { + arg ++; + break; + } + else if(std::strcmp(argv[arg], "--use-module") == 0) { + std::cout << "ArgumentParser: Using module " << argv[++arg] << std::endl; + } + } + + return arg; +} + +} // namespace Config +} // namespace Monitor diff --git a/include/monitor/config/ArgumentParser.h b/monitor/src/config/ConcreteVault.cpp similarity index 52% copy from include/monitor/config/ArgumentParser.h copy to monitor/src/config/ConcreteVault.cpp index 6c1ff65..28aaa96 100644 --- a/include/monitor/config/ArgumentParser.h +++ b/monitor/src/config/ConcreteVault.cpp @@ -5,30 +5,22 @@ Aesalon is distributed under the terms of the GNU GPLv3. For more licensing information, see the file LICENSE included with the distribution. - @file include/monitor/config/ArgumentParser.h + @file monitor/src/config/ConcreteVault.cpp */ -#ifndef AesalonMonitor_Config_ArgumentParser_H -#define AesalonMonitor_Config_ArgumentParser_H - -#include "Store.h" +#include "config/ConcreteVault.h" namespace Monitor { namespace Config { -class ArgumentParser { -private: - Store *m_store; - char **m_argv; -public: - ArgumentParser(Store *store, char **argv); - ~ArgumentParser(); - - int parse(); -}; +void ConcreteVault::set(const std::string &key, const std::string &value) { + m_data[key] = value; +} + +std::string ConcreteVault::get(const std::string &key) { + return m_data[key]; +} } // namespace Config } // namespace Monitor - -#endif diff --git a/monitor/src/config/Parser.cpp b/monitor/src/config/Parser.cpp new file mode 100644 index 0000000..f6c4534 --- /dev/null +++ b/monitor/src/config/Parser.cpp @@ -0,0 +1,202 @@ +/** + Aesalon, a tool to visualize a program's behaviour at run-time. + Copyright (C) 2010, Aesalon Development Team. + + Aesalon is distributed under the terms of the GNU GPLv3. For more + licensing information, see the file LICENSE included with the distribution. + + @file monitor/src/config/Parser.cpp + +*/ + +#include // for debugging +#include +#include +#include +#include + +#include "config/Parser.h" +#include "common/ParsingException.h" +#include "common/StreamAsString.h" + +namespace Monitor { +namespace Config { + +void Parser::parse(Vault *vault, const std::string &configFile) { + std::string currentModule; + + openFile(configFile); + + for(;;) { + TokenType tokenType; + std::string token = nextToken(tokenType); + if(tokenType == END_OF_FILE) break; + + //std::cout << '"' << token << '"' << " of type " << nameOf(tokenType) << std::endl; + + if(tokenType == WORD && token == "include") { + Parser().parse(vault, expectNextToken(QUOTED_WORD)); + expectNextSymbol(";"); + } + else if(tokenType == WORD && token == "module") { + currentModule = expectNextToken(WORD); + expectNextSymbol("{"); + } + else if(tokenType == SYMBOL && token == "}") { + if(currentModule != "") { + currentModule = ""; + } + else throw Common::ParsingException("Extra \"}\""); + } + else if(tokenType == WORD && token == "use") { + std::cout << "Parser: Using module \"" << expectNextToken(WORD) << "\"\n"; + expectNextSymbol(";"); + } + else if(tokenType == WORD) { + std::string op = expectNextToken(SYMBOL); + + do { + TokenType nextType; + std::string next = nextToken(nextType); + + //if(nextType == SYMBOL && next == ";") break; + + if(nextType == WORD || nextType == QUOTED_WORD) { + std::cout << "Set \"" << currentModule << "." << token << "\" to \"" + << next << "\" with operator " << op << std::endl; + } + else throw Common::ParsingException("Invalid RHS"); + + std::string sym = expectNextToken(SYMBOL); + if(sym == ";") break; + else if(sym == ",") {} + else { + throw Common::ParsingException(Common::StreamAsString() + << "Expected \",\" or \";\", got \"" << sym << "\""); + } + } while(true); + } + else { + throw Common::ParsingException(Common::StreamAsString() + << "Syntax error at token \"" << token << "\""); + } + //std::cout << "\"" << token << "\"\n"; + } + + closeFile(); +} + +void Parser::openFile(const std::string &configFile) { + m_stream = new std::ifstream(configFile.c_str()); + if(!m_stream->is_open()) { + std::cout << "Error opening config file \"" << configFile << "\"\n"; + } +} + +std::string Parser::nextToken(TokenType &type) { + std::ifstream &stream = *m_stream; + + skipWhitespace(); + + if(stream.eof()) { + type = END_OF_FILE; + return ""; + } + + if(stream.peek() == '#') { + std::string line; + std::getline(stream, line); + return nextToken(type); + } + else if(stream.peek() == '"') { + stream.get(); // skip " + + std::string word; + while(stream.peek() != '"') { + word += stream.get(); + } + + stream.get(); // skip " + + type = QUOTED_WORD; + return word; + } + else if(std::isalnum(stream.peek())) { + std::string word; + while(std::isalnum(stream.peek())) { + word += stream.get(); + } + + type = WORD; + return word; + } + else if(stream.peek() == '+') { + stream.get(); // skip '+' + if(stream.peek() == '=') { + stream.get(); // skip '=' + type = SYMBOL; + return "+="; + } + + std::string rest; + stream >> rest; + + throw Common::ParsingException(Common::StreamAsString() + << "Unrecognized token: \"+" << rest << "\""); + } + else { + std::string token; + token += stream.get(); + + type = SYMBOL; + return token; + } +} + +std::string Parser::expectNextToken(TokenType expected) { + TokenType actual; + std::string token = nextToken(actual); + + if(actual != expected) { + throw Common::ParsingException(Common::StreamAsString() + << "Expected " << nameOf(expected) << " token, found " << nameOf(actual) + << " token: \"" << token << "\""); + } + + return token; +} + +void Parser::expectNextSymbol(const std::string &symbol) { + std::string s = expectNextToken(SYMBOL); + if(symbol != s) { + throw Common::ParsingException(Common::StreamAsString() + << "Expected token \"" << symbol << "\", got \"" << s << "\""); + } +} + +void Parser::skipWhitespace() { + std::ifstream &stream = *m_stream; + + while(!stream.fail() && std::isspace(stream.peek())) { + stream.get(); + } +} + +void Parser::closeFile() { + delete m_stream; + m_stream = NULL; +} + +const char *Parser::nameOf(TokenType type) const { + static const char *name[] = { + "WORD", + "QUOTED_WORD", + "SYMBOL", + "END_OF_FILE" + }; + + return name[type]; +} + +} // namespace Config +} // namespace Monitor diff --git a/monitor/src/module/Module.cpp b/monitor/src/config/Vault.cpp similarity index 51% copy from monitor/src/module/Module.cpp copy to monitor/src/config/Vault.cpp index 71bb8c8..1384938 100644 --- a/monitor/src/module/Module.cpp +++ b/monitor/src/config/Vault.cpp @@ -5,22 +5,8 @@ Aesalon is distributed under the terms of the GNU GPLv3. For more licensing information, see the file LICENSE included with the distribution. - @file monitor/src/module/Module.cpp + @file monitor/src/config/Vault.cpp */ -#include "module/Module.h" - -namespace Monitor { -namespace Module { - -Module::Module(Config::Store *store, const std::string &moduleName) { - -} - -Module::~Module() { - -} - -} // namespace Module -} // namespace Monitor +#include "config/Vault.h" diff --git a/monitor/src/module/Module.cpp b/monitor/src/module/Module.cpp index 71bb8c8..9e52ba9 100644 --- a/monitor/src/module/Module.cpp +++ b/monitor/src/module/Module.cpp @@ -14,7 +14,7 @@ namespace Monitor { namespace Module { -Module::Module(Config::Store *store, const std::string &moduleName) { +Module::Module(Config::Vault *vault, const std::string &moduleName) { } diff --git a/monitor/src/program/Launcher.cpp b/monitor/src/program/Launcher.cpp index cf4d6c2..83753e5 100644 --- a/monitor/src/program/Launcher.cpp +++ b/monitor/src/program/Launcher.cpp @@ -14,7 +14,7 @@ namespace Monitor { namespace Program { -Launcher::Launcher(Config::Store *store, char **argv) : m_store(store), m_argv(argv) { +Launcher::Launcher(Config::Vault *vault, char **argv) : m_vault(vault), m_argv(argv) { } diff --git a/this.conf b/this.conf new file mode 100644 index 0000000..9434582 --- /dev/null +++ b/this.conf @@ -0,0 +1,4 @@ +module this { + YETANOTHERTHING += 0; +} +use this; -- 2.11.4.GIT