From 7e349e2789a633a6014baea63aeb7932e024c917 Mon Sep 17 00:00:00 2001 From: deva Date: Wed, 22 Jul 2009 15:00:29 +0000 Subject: Changed the way the macros are looked up in the filesystem (now they are parsed and indexed using version numbers). Updated all unit tests, to compile and run again. --- server/src/Makefile.am | 48 +++++++---- server/src/luaquerymapper.cc | 23 +++--- server/src/macroheaderparser.cc | 149 +++++++++++++++++++++++++++++++++++ server/src/macroheaderparser.h | 62 +++++++++++++++ server/src/macrolist.cc | 114 +++++++++++++++++++++++++++ server/src/macrolist.h | 47 +++++++++++ server/src/macroparser.cc | 14 ++-- server/src/macroparser.h | 2 +- server/src/macrotool_dump.cc | 2 +- server/src/macrotool_fieldnames.cc | 2 +- server/src/macrotool_filehandler.cc | 13 ++- server/src/macrotool_util.cc | 2 +- server/src/macrotool_util.h | 1 - server/src/pracrodaopgsql.cc | 21 ++++- server/src/queryhandlerpentominos.cc | 9 +-- server/src/queryhandlerpracro.cc | 21 +++++ server/src/queryparser.cc | 14 ++-- server/src/server.cc | 41 +++++++--- server/src/templateparser.cc | 15 ++-- server/src/version.cc | 143 +++++++++++++++++++++++++++++++++ server/src/version.h | 49 ++++++++++++ 21 files changed, 719 insertions(+), 73 deletions(-) create mode 100644 server/src/macroheaderparser.cc create mode 100644 server/src/macroheaderparser.h create mode 100644 server/src/macrolist.cc create mode 100644 server/src/macrolist.h create mode 100644 server/src/version.cc create mode 100644 server/src/version.h diff --git a/server/src/Makefile.am b/server/src/Makefile.am index 0589630..99863f0 100644 --- a/server/src/Makefile.am +++ b/server/src/Makefile.am @@ -20,6 +20,8 @@ pracrod_SOURCES = \ log.cc \ luaquerymapper.cc \ luaresume.cc \ + macroheaderparser.cc \ + macrolist.cc \ macroparser.cc \ pracrodao.cc \ pracrodaopgsql.cc \ @@ -30,6 +32,7 @@ pracrod_SOURCES = \ transactionparser.cc \ tcpsocket.cc \ utf8.cc \ + version.cc \ widgetgenerator.cc \ xml_encode_decode.cc @@ -45,6 +48,8 @@ macrotool_SOURCES = \ database.cc \ exception.cc \ log.cc \ + macroheaderparser.cc \ + macrolist.cc \ macroparser.cc \ macrotool_dump.cc \ macrotool_fieldnames.cc \ @@ -53,7 +58,8 @@ macrotool_SOURCES = \ pracrodao.cc \ pracrodaopgsql.cc \ saxparser.cc \ - templateparser.cc + templateparser.cc \ + version.cc EXTRA_DIST = \ configuration.h \ @@ -71,6 +77,8 @@ EXTRA_DIST = \ log.h \ luaquerymapper.h \ luaresume.h \ + macroheaderparser.h \ + macrolist.h \ macroparser.h \ macrotool_dump.h \ macrotool_fieldnames.h \ @@ -85,17 +93,20 @@ EXTRA_DIST = \ transactionparser.h \ tcpsocket.h \ utf8.h \ + version.h \ widgetgenerator.h \ xml_encode_decode.h TESTFILES = \ + test_version \ + test_macrolist \ test_queryhandlerpentominos \ test_queryhandlerpracro \ test_queryparser \ test_luaquerymapper \ test_templateparser \ test_server \ - test_database \ + test_pracrodaopgsql \ test_macroparser \ test_xml_encode_decode \ test_journal_commit @@ -103,42 +114,51 @@ TESTFILES = \ TESTLOGS = `for F in ${TESTFILES}; do echo $$F.log; done` +BASICS = "-I.. -DHAVE_CONFIG_H exception.cc log.cc debug.cc configuration.cc utf8.cc" +PARSERBASICS = "saxparser.cc -lexpat" +DBBASICS = "database.cc pracrodao.cc pracrodaopgsql.cc $(PQXX_LIBS) $(PQXX_CXXFLAGS)" + test: $(TESTFILES) @echo "All tests done." test_clean: rm -f $(TESTFILES) +test_version: version.cc + @../../tools/test version.cc + +test_macrolist: macrolist.cc + @../../tools/test macrolist.cc version.cc macroheaderparser.cc $(PARSERBASICS) $(BASICS) + test_queryhandlerpentominos: queryhandlerpentominos.cc - @../../tools/test queryhandlerpentominos.cc tcpsocket.cc exception.cc log.cc + @../../tools/test queryhandlerpentominos.cc tcpsocket.cc queryparser.cc $(PARSERBASICS) $(BASICS) test_queryhandlerpracro: queryhandlerpracro.cc - @../../tools/test queryhandlerpracro.cc tcpsocket.cc exception.cc log.cc + @../../tools/test queryhandlerpracro.cc tcpsocket.cc queryparser.cc $(DBBASICS) $(PARSERBASICS) $(BASICS) test_queryparser: queryparser.cc - @../../tools/test queryparser.cc queryhandler.cc tcpsocket.cc exception.cc log.cc saxparser.cc -lexpat + @../../tools/test queryparser.cc queryhandlerpentominos.cc tcpsocket.cc $(BASICS) $(PARSERBASICS) test_luaquerymapper: luaquerymapper.cc - @../../tools/test luaquerymapper.cc queryparser.cc queryhandler.cc tcpsocket.cc exception.cc log.cc saxparser.cc -lexpat $(LUA_LIBS) + @../../tools/test luaquerymapper.cc queryparser.cc queryhandlerpentominos.cc tcpsocket.cc $(BASICS) $(PARSERBASICS) $(LUA_LIBS) test_templateparser: templateparser.cc - @../../tools/test templateparser.cc saxparser.cc exception.cc log.cc -lexpat -DXML="\"../xml\"" + @../../tools/test templateparser.cc $(PARSERBASICS) $(BASICS) test_macroparser: macroparser.cc - @../../tools/test macroparser.cc saxparser.cc exception.cc log.cc -lexpat -DXML="\"../xml\"" + @../../tools/test macroparser.cc $(PARSERBASICS) $(BASICS) test_server: server.cc - @../../tools/test server.cc templateparser.cc saxparser.cc queryparser.cc queryhandler.cc luaquerymapper.cc tcpsocket.cc exception.cc log.cc configuration.cc transactionparser.cc widgetgenerator.cc database.cc macroparser.cc xml_encode_decode.cc -lexpat $(LUA_LIBS) $(CONFIG_LIBS) $(PQXX_LIBS) $(PQXX_CXXFLAGS) -DXML="\"../xml\"" - -#killall -9 test_server + @../../tools/test server.cc templateparser.cc queryparser.cc queryhandlerpentominos.cc journal_commit.cc macrolist.cc queryhandlerpracro.cc macroheaderparser.cc version.cc resumeparser.cc luaquerymapper.cc tcpsocket.cc $(BASICS) transactionparser.cc widgetgenerator.cc database.cc pracrodao.cc pracrodaopgsql.cc luaresume.cc macroparser.cc xml_encode_decode.cc $(PARSERBASICS) $(LUA_LIBS) $(CONFIG_LIBS) $(PQXX_LIBS) $(PQXX_CXXFLAGS) + @sleep 1s; killall -9 test_server -test_database: database.cc - @../../tools/test database.cc $(PQXX_LIBS) $(PQXX_CXXFLAGS) -I.. +test_pracrodaopgsql: pracrodaopgsql.cc + @../../tools/test pracrodaopgsql.cc pracrodao.cc $(BASICS) $(PQXX_LIBS) $(PQXX_CXXFLAGS) -I.. test_xml_encode_decode: xml_encode_decode.cc @../../tools/test xml_encode_decode.cc test_journal_commit: journal_commit.cc - @../../tools/test journal_commit.cc debug.cc -I.. + @../../tools/test journal_commit.cc templateparser.cc $(PARSERBASICS) $(BASICS) CLEANFILES = $(TESTFILES) $(TESTLOGS) *~ diff --git a/server/src/luaquerymapper.cc b/server/src/luaquerymapper.cc index bec9640..d6ec531 100644 --- a/server/src/luaquerymapper.cc +++ b/server/src/luaquerymapper.cc @@ -46,7 +46,7 @@ static std::string loadresultstring(QueryResult &res, std::string group = "") std::map< std::string, QueryResult >::iterator g = res.groups.begin(); while(g != res.groups.end()) { - s += group + (*g).first + " = {}\n"; + if(group + (*g).first != "") s += group + (*g).first + " = {}\n"; s += loadresultstring((*g).second, group + (*g).first + "."); g++; } @@ -170,36 +170,33 @@ void LUAQueryMapper::error(std::string message) #ifdef TEST_LUAQUERYMAPPER -#include "queryhandler.h" +#include "queryhandlerpentominos.h" #include "queryparser.h" +#include "tcpsocket.h" int main() { TCPSocket s; s.connect("localhost", 11108); - QueryHandler qh(&s, "2003791613"); + QueryHandlerPentominos qh(&s, "2003791613"); Query q1; q1.attributes["device_id"] = "lensmeter"; q1.attributes["device_type"] = "lensmeter"; - std::string res = qh.exec(); + QueryResult res = qh.exec(q1); - printf("%s\n", res.c_str()); + printf("%s\n", loadresultstring(res).c_str()); - QueryParser e(res); - e.parse(); + LUAQueryMapper mapper; + mapper.addQueryResult(res); - printf("%s\n", loadresultstring(e.result).c_str()); - - LUAQueryMapper mapper(e.result); - - std::string luamap = "return right.sphere, 0"; + std::string luamap = "return status.errstr.value, 0, 0"; Value value = mapper.map(luamap); printf("%s : %s, %lu\n", luamap.c_str(), value.value.c_str(), value.timestamp); - luamap = "return math.sin(right.cyl) * 2, 0"; + luamap = "return math.sin(status.errstr.timestamp) * 2, 0, 0"; value = mapper.map(luamap); printf("%s : %s, %lu\n", luamap.c_str(), value.value.c_str(), value.timestamp); diff --git a/server/src/macroheaderparser.cc b/server/src/macroheaderparser.cc new file mode 100644 index 0000000..4c61929 --- /dev/null +++ b/server/src/macroheaderparser.cc @@ -0,0 +1,149 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * macroheaderparser.cc + * + * Wed Jul 22 08:42:23 CEST 2009 + * Copyright 2009 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Pracro. + * + * Pracro is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Pracro 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Pracro; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include "debug.h" +#include "macroheaderparser.h" +#include "configuration.h" + +#include + +// For assert +#include + +// For open and friends +#include +#include +#include +#include + +// For vprintf and friends +#include + +#ifndef XML +// For XML +#include +#endif/*XML*/ + +#include +#include + +#include "exception.h" + +void MacroHeaderParser::error(const char* fmt, ...) +{ + // TODO: Throw exception here. + + PRACRO_ERR_LOG(macro, "Error in MacroHeaderParser: "); + + { + va_list argp; + va_start(argp, fmt); + PRACRO_ERR_LOG_VA(macro, fmt, argp); + va_end(argp); + + fprintf(stderr, "\n"); + } + + { + char *p; + va_list argp; + va_start(argp, fmt); + if(vasprintf(&p, fmt, argp) != -1) { + throw Exception("Error in MacroHeaderParser: " + std::string(p)); + free(p); + } + va_end(argp); + } + +} + +MacroHeaderParser::MacroHeaderParser(std::string macrofile) +{ + m = NULL; + + file = macrofile; + + PRACRO_DEBUG(macro, "Using macro file: %s\n", macrofile.c_str()); + + fd = open(macrofile.c_str(), O_RDONLY); + if(fd == -1) error("Could not open file %s", macrofile.c_str()); +} + +MacroHeaderParser::~MacroHeaderParser() +{ + if(fd != -1) close(fd); + if(m) delete m; +} + +void MacroHeaderParser::startTag(std::string name, std::map< std::string, std::string> attributes) +{ + // Create macro and enable parsing of queries, maps and window + if(name == "macro") { + assert(!m); // A Macro has already been allocated, cannot create macro! + m = new Macro(); + m->attributes = attributes; + } +} + +int MacroHeaderParser::readData(char *data, size_t size) +{ + if(m) return 0; // If m is allocated, it means that we have parsed the macro + // tag, and can dismiss the rest of the document. + + if(fd == -1) { + PRACRO_ERR_LOG(macro, "Invalid file descriptor.\n"); + return 0; + } + ssize_t r = read(fd, data, size); + if(r == -1) { + PRACRO_ERR_LOG(macro, "Could not read...%s\n", strerror(errno)); + return 0; + } + return r; +} + +void MacroHeaderParser::parseError(char *buf, size_t len, std::string error, int lineno) +{ + if(m) return; // Ignore "unclosed token" errors when the macro tag has been parsed. + + PRACRO_ERR_LOG(macro, "MacroHeaderParser[%s] error at line %d: %s\n", file.c_str(), lineno, error.c_str()); + PRACRO_ERR_LOG(macro, "\tBuffer %u bytes: [", len); + if(fwrite(buf, len, 1, stderr) != len) {} + PRACRO_ERR_LOG(macro, "]\n"); + + char *slineno; + if(asprintf(&slineno, " at line %d\n", lineno) != -1) { + throw Exception(error + slineno); + free(slineno); + } + +} + +Macro *MacroHeaderParser::getMacro() +{ + return m; +} diff --git a/server/src/macroheaderparser.h b/server/src/macroheaderparser.h new file mode 100644 index 0000000..28c5578 --- /dev/null +++ b/server/src/macroheaderparser.h @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * macroheaderparser.h + * + * Wed Jul 22 08:42:23 CEST 2009 + * Copyright 2009 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Pracro. + * + * Pracro is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Pracro 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Pracro; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#ifndef __PRACRO_MACROHEADERPARSER_H__ +#define __PRACRO_MACROHEADERPARSER_H__ + +#include "saxparser.h" +#include "template.h" + +class MacroHeaderParser : public SAXParser { +public: + MacroHeaderParser(std::string macrofile); + ~MacroHeaderParser(); + + void startTag(std::string name, std::map< std::string, std::string> attributes); + void parseError(char *buf, size_t len, std::string error, int lineno); + + /** + * Get a pointer to the parsed macro. + * NOTE: The allocated memory for the macro is owned by the parser, and will be + * freed upon parser deletion. + * @return A pointer to the macro or NULL on error. + */ + Macro *getMacro(); + +protected: + int readData(char *data, size_t size); + +private: + int fd; + Macro *m; + + std::string file; + // Error callback function. + void error(const char* fmt, ...); +}; + +#endif/*__PRACRO_MACROHEADERPARSER_H__*/ diff --git a/server/src/macrolist.cc b/server/src/macrolist.cc new file mode 100644 index 0000000..8207b06 --- /dev/null +++ b/server/src/macrolist.cc @@ -0,0 +1,114 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * macrolist.cc + * + * Wed Jul 22 10:26:40 CEST 2009 + * Copyright 2009 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Pracro. + * + * Pracro is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Pracro 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Pracro; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include "macrolist.h" + +#include +#include + +#include "debug.h" +#include "macroheaderparser.h" + +static std::vector listdir(std::string path) +{ + std::vector files; + + DIR* dir = opendir(path.c_str()); + if(!dir) { + PRACRO_ERR(dump, "Could not open directory: %s\n", path.c_str()); + return files; + } + + struct dirent *d; + while((d = readdir(dir)) != 0) { + //if(d->d_type == DT_DIR) { + std::string name = d->d_name; + if(name.length() >= 4 && name.substr(name.length() - 4) == ".xml") + files.push_back(name); + //} + } + closedir(dir); + + return files; +} + +MacroList::MacroList(std::string macropath) +{ + this->macropath = macropath; + std::vector macros = listdir(macropath); + std::vector::iterator i = macros.begin(); + while(i != macros.end()) { + MacroHeaderParser parser(macropath + "/" + *i); + parser.parse(); + Macro *macro = parser.getMacro(); + (*this)[macro->attributes["name"]][Version(macro->attributes["version"])] = *i; + i++; + } +} + +std::string MacroList::getLatestVersion(std::string macro) +{ + if(find(macro) == end()) return ""; + MacroListItem mli = (*this)[macro]; + if(mli.size() == 0) return ""; + printf("Search for %s - found %s v%s\n", + macro.c_str(), + (macropath + "/" + mli.begin()->second).c_str(), + ((std::string)mli.begin()->first).c_str()); + return macropath + "/" + mli.begin()->second; +} + +#ifdef TEST_MACROLIST + +int main() +{ + MacroList lst("/home"); + + lst["macro1"][Version("1.0")] = "macro1-1.0.xml"; + lst["macro1"][Version("1.1")] = "macro1-1.1.xml"; + lst["macro1"][Version("1.1.1")] = "macro1-1.1.1.xml"; + lst["macro1"][Version("1.2")] = "macro1-1.2.xml"; + lst["macro2"][Version("1.0")] = "macro2.xml"; + lst["macro3"][Version("1.0")] = "macro3.xml"; + + MacroList::iterator i = lst.begin(); + while(i != lst.end()) { + MacroListItem::iterator j = i->second.begin(); + while(j != i->second.end()) { + printf("%s - v%s file: %s\n", + i->first.c_str(), + ((std::string)j->first).c_str(), + j->second.c_str()); + j++; + } + i++; + } + + return 0; +} + +#endif/*TEST_MACROLIST*/ diff --git a/server/src/macrolist.h b/server/src/macrolist.h new file mode 100644 index 0000000..278bc07 --- /dev/null +++ b/server/src/macrolist.h @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * macrolist.h + * + * Wed Jul 22 10:26:40 CEST 2009 + * Copyright 2009 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Pracro. + * + * Pracro is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Pracro 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Pracro; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#ifndef __PRACRO_MACROLIST_H__ +#define __PRACRO_MACROLIST_H__ + +#include +#include +#include "version.h" + +typedef std::map MacroListItem; + +class MacroList : public std::map { +public: + MacroList(std::string macropath); + + std::string getLatestVersion(std::string macro); + +private: + std::string macropath; +}; + +#endif/*__PRACRO_MACROLIST_H__*/ diff --git a/server/src/macroparser.cc b/server/src/macroparser.cc index 0f7ed76..921e4f0 100644 --- a/server/src/macroparser.cc +++ b/server/src/macroparser.cc @@ -80,15 +80,14 @@ void MacroParser::error(const char* fmt, ...) } -MacroParser::MacroParser(std::string macro, bool abspath) +MacroParser::MacroParser(std::string macrofile) { state = UNDEFINED; m = NULL; current_map = NULL; current_script = NULL; - if(!abspath) file = Conf::xml_basedir + "/macros/" + macro + ".xml"; - else file = macro; + file = macrofile; PRACRO_DEBUG(macro, "Using macro file: %s\n", file.c_str()); @@ -341,7 +340,8 @@ void print_attributes(std::string prefix, int main() { - MacroParser parser("example"); + try { + MacroParser parser("../xml/macros/example.xml"); parser.parse(); Macro *m = parser.getMacro(); @@ -362,7 +362,11 @@ int main() print_attributes("\t\t\t\t\t-", (*mi).attributes); mi++; } - + } catch(Exception &e) { + printf("ERROR: %s\n", e.what()); + return 1; + } + return 0; } diff --git a/server/src/macroparser.h b/server/src/macroparser.h index 3867ca1..9d90ff1 100644 --- a/server/src/macroparser.h +++ b/server/src/macroparser.h @@ -45,7 +45,7 @@ class MacroParser : public SAXParser { } ParserState; public: - MacroParser(std::string macro, bool abspath = false); + MacroParser(std::string macrofile); ~MacroParser(); void characterData(std::string &data); diff --git a/server/src/macrotool_dump.cc b/server/src/macrotool_dump.cc index 370397a..920d4b6 100644 --- a/server/src/macrotool_dump.cc +++ b/server/src/macrotool_dump.cc @@ -73,7 +73,7 @@ static std::map macroList() while(mfs != macrofiles.end()) { std::string name = mfs->substr(0, mfs->length() - 4); - MacroParser parser(name); + MacroParser parser(Conf::xml_basedir + "/macros/" + *mfs); parser.parse(); Macro *macro = parser.getMacro(); diff --git a/server/src/macrotool_fieldnames.cc b/server/src/macrotool_fieldnames.cc index 3c3f8b7..d7cc7f9 100644 --- a/server/src/macrotool_fieldnames.cc +++ b/server/src/macrotool_fieldnames.cc @@ -78,7 +78,7 @@ static std::map > getMacroRefsList() while(mfs != macrofiles.end()) { std::string name = mfs->substr(0, mfs->length() - 4); - MacroParser parser(name); + MacroParser parser(Conf::xml_basedir + "/macros/" + *mfs); parser.parse(); Macro *macro = parser.getMacro(); diff --git a/server/src/macrotool_filehandler.cc b/server/src/macrotool_filehandler.cc index 524761c..4caa889 100644 --- a/server/src/macrotool_filehandler.cc +++ b/server/src/macrotool_filehandler.cc @@ -30,6 +30,7 @@ #include #include +#include "macroheaderparser.h" #include "macroparser.h" #include "template.h" @@ -61,9 +62,10 @@ static bool check(std::string file, std::string *name = NULL, std::string *versi static bool check(std::string file, std::string *name, std::string *version) { try { - MacroParser parser(file, true); + MacroHeaderParser parser(file); parser.parse(); Macro *macro = parser.getMacro(); + if(!macro) { printf("Macro malformed!\n"); return false; @@ -83,14 +85,18 @@ static bool check(std::string file, std::string *name, std::string *version) return true; } +#define SZ 1000 static bool macro_exists(std::string name, std::string version, std::string &clashfile) { std::vector macrofiles = getMacros(); + + for(int prut = 0; prut < SZ; prut++) { std::vector::iterator mfs = macrofiles.begin(); while(mfs != macrofiles.end()) { std::string macroname = mfs->substr(0, mfs->length() - 4); - MacroParser parser(macroname); + MacroHeaderParser parser(Conf::xml_basedir + "/macros/" + *mfs); + //MacroParser parser(macroname); parser.parse(); Macro *macro = parser.getMacro(); @@ -102,7 +108,8 @@ static bool macro_exists(std::string name, std::string version, std::string &cla mfs++; } - + } + printf("Parsed %d files\n", macrofiles.size() * SZ); return false; } diff --git a/server/src/macrotool_util.cc b/server/src/macrotool_util.cc index fa066aa..d6446f7 100644 --- a/server/src/macrotool_util.cc +++ b/server/src/macrotool_util.cc @@ -34,7 +34,7 @@ #include "configuration.h" -std::vector listdir(std::string path) +static std::vector listdir(std::string path) { std::vector files; diff --git a/server/src/macrotool_util.h b/server/src/macrotool_util.h index 1725f23..2e41f6b 100644 --- a/server/src/macrotool_util.h +++ b/server/src/macrotool_util.h @@ -31,7 +31,6 @@ #include #include -std::vector listdir(std::string path); std::vector getMacros(); std::vector getTemplates(); diff --git a/server/src/pracrodaopgsql.cc b/server/src/pracrodaopgsql.cc index 7159b03..c1ec9b1 100644 --- a/server/src/pracrodaopgsql.cc +++ b/server/src/pracrodaopgsql.cc @@ -60,7 +60,7 @@ PracroDAOPgsql::PracroDAOPgsql(std::string _host, std::string _port, std::string PracroDAOPgsql::~PracroDAOPgsql() { - if(conn) delete conn; + if(conn) delete conn; } void PracroDAOPgsql::commitTransaction(std::string user, std::string patientid, Macro &_macro, Fields &fields, time_t now) @@ -305,3 +305,22 @@ std::vector PracroDAOPgsql::getFieldnames() } #endif/*WITHOUT_DB*/ + +#ifdef TEST_PRACRODAOPGSQL + +#include "configuration.h" +#include "exception.h" + +int main() +{ +#ifndef WITHOUT_DB + try { + PracroDAOPgsql db(Conf::database_addr, "", Conf::database_user, Conf::database_passwd, ""); + } catch(Exception &e) { + printf("ERROR: %s\n", e.what()); + return 1; + } +#endif/*WITHOUT_DB*/ + return 0; +} +#endif/*TEST_PRACRODAOPGSQL*/ diff --git a/server/src/queryhandlerpentominos.cc b/server/src/queryhandlerpentominos.cc index acca840..f70033d 100644 --- a/server/src/queryhandlerpentominos.cc +++ b/server/src/queryhandlerpentominos.cc @@ -228,7 +228,7 @@ QueryResult QueryHandlerPentominos::exec(Query &query) return result; } -#ifdef TEST_QUERYHANDLER +#ifdef TEST_QUERYHANDLERPENTOMINOS int main() { @@ -240,11 +240,10 @@ int main() Query q1; q1.attributes["device_id"] = "lensmeter"; q1.attributes["device_type"] = "lensmeter"; - qh.addQuery(q1); + QueryResult res = qh.exec(q1); + res.print(); - std::string res = qh.exec(); - return 0; } -#endif/*TEST_QUERYHANDLER*/ +#endif/*TEST_QUERYHANDLERPENTOMINOS*/ diff --git a/server/src/queryhandlerpracro.cc b/server/src/queryhandlerpracro.cc index 3dd5b52..ab1466e 100644 --- a/server/src/queryhandlerpracro.cc +++ b/server/src/queryhandlerpracro.cc @@ -60,3 +60,24 @@ QueryResult QueryHandlerPracro::exec(Query &query) return result; } + +#ifdef TEST_QUERYHANDLERPRACRO + +#include "configuration.h" + +int main() +{ + Database db("pgsql", Conf::database_addr, "", Conf::database_user, Conf::database_passwd, ""); + + QueryHandlerPracro qh(&db, "2003791613"); + + Query q1; + q1.attributes["device_id"] = "lensmeter"; + q1.attributes["device_type"] = "lensmeter"; + QueryResult res = qh.exec(q1); + res.print(); + + return 0; +} + +#endif/*TEST_QUERYHANDLERPRACRO*/ diff --git a/server/src/queryparser.cc b/server/src/queryparser.cc index 76b24a6..2b0dbdc 100644 --- a/server/src/queryparser.cc +++ b/server/src/queryparser.cc @@ -80,7 +80,8 @@ void QueryParser::parseError(char *buf, size_t len, std::string error, int linen #ifdef TEST_QUERYPARSER -#include "queryhandler.h" +#include "queryhandlerpentominos.h" +#include "tcpsocket.h" static std::string loadresultstring(QueryResult &res, std::string group = "") { @@ -107,20 +108,15 @@ int main() TCPSocket s; s.connect("localhost", 11108); - QueryHandler qh(&s, "2003791613"); + QueryHandlerPentominos qh(&s, "2003791613"); Query q1; q1.attributes["device_id"] = "lensmeter"; q1.attributes["device_type"] = "lensmeter"; - std::string res = qh.exec(); + QueryResult res = qh.exec(q1); - printf("%s\n", res.c_str()); - - QueryParser e(res); - e.parse(); - - printf("%s\n", loadresultstring(e.result).c_str()); + printf("%s\n", loadresultstring(res).c_str()); return 0; } diff --git a/server/src/server.cc b/server/src/server.cc index 2641b8a..6e480ed 100644 --- a/server/src/server.cc +++ b/server/src/server.cc @@ -54,6 +54,9 @@ #include "journal_commit.h" #include "xml_encode_decode.h" +#include "macrolist.h" +#include "version.h" + static std::string error_box(std::string message) { std::string errorbox = @@ -79,7 +82,8 @@ public: static std::string handleTransaction(Transaction *transaction, TCPSocket *pentominos_socket, Database *db, - JournalWriter &journalwriter) + JournalWriter &journalwriter, + MacroList ¯olist) { std::string answer; answer += "\n"; @@ -93,8 +97,8 @@ static std::string handleTransaction(Transaction *transaction, Commits::iterator i = transaction->commits.begin(); while(i != transaction->commits.end()) { Commit &commit = *i; - - MacroParser mp(commit.macro); + + MacroParser mp(macrolist.getLatestVersion(commit.macro)); mp.parse(); Macro *macro = mp.getMacro(); @@ -173,7 +177,7 @@ static std::string handleTransaction(Transaction *transaction, ) { foundmacro = true; - MacroParser mp(macro.attributes["name"]); + MacroParser mp(macrolist.getLatestVersion(macro.attributes["name"])); mp.parse(); Macro *m = mp.getMacro(); answer += " caption=\"" + m->window.attributes["caption"] + "\""; @@ -225,7 +229,7 @@ static std::string handleTransaction(Transaction *transaction, answer += widgetgenerator(transaction->cpr, *m, lqm, db); } else { // only find macro title - MacroParser mp(macro.attributes["name"]); + MacroParser mp(macrolist.getLatestVersion(macro.attributes["name"])); mp.parse(); Macro *m = mp.getMacro(); answer += " caption=\"" + m->window.attributes["caption"] + "\""; @@ -275,6 +279,21 @@ static void handleConnection(TCPSocket *socket) JournalWriter journalwriter(Conf::journal_commit_addr.c_str(), Conf::journal_commit_port); + MacroList macrolist(Conf::xml_basedir + "/macros"); + + MacroList::iterator i = macrolist.begin(); + while(i != macrolist.end()) { + MacroListItem::iterator j = i->second.begin(); + while(j != i->second.end()) { + PRACRO_DEBUG(server, "%s - v%s file: %s\n", + i->first.c_str(), + ((std::string)j->first).c_str(), + j->second.c_str()); + j++; + } + i++; + } + ssize_t size; char buf[4096]; @@ -300,7 +319,7 @@ static void handleConnection(TCPSocket *socket) if(parser->parse(buf, size)) { PRACRO_DEBUG(server, "Got complete XML document %d bytes used, %d bytes in current buffer.\n", parser->usedBytes(), size); - socket->write(handleTransaction(transaction, &pentominos_socket, db, journalwriter)); + socket->write(handleTransaction(transaction, &pentominos_socket, db, journalwriter, macrolist)); size = size - parser->usedBytes(); delete transaction; transaction = NULL; @@ -398,6 +417,8 @@ void server() #ifdef TEST_SERVER +bool pracro_is_running = true; + char request[] = "\n" "\n" @@ -406,9 +427,6 @@ char request[] = int main() { - Configuration conf("../etc/pracrod.conf"); - initConfig(&conf); - switch(fork()) { case -1: // error return 1; @@ -420,13 +438,12 @@ int main() default: // parent { TCPSocket socket; - int port = config()->lookup("port"); - socket.connect("localhost", port); + socket.connect("localhost", Conf::server_port); socket.write(request); char buf[32]; memset(buf, 0, sizeof(buf)); - while(socket.read(buf, 31)) { + while(socket.read(buf, 31, 1000)) { printf(buf); fflush(stdout); memset(buf, 0, sizeof(buf)); } diff --git a/server/src/templateparser.cc b/server/src/templateparser.cc index d40bc1e..8db6bbf 100644 --- a/server/src/templateparser.cc +++ b/server/src/templateparser.cc @@ -40,11 +40,6 @@ // For vprintf and friends #include -#ifndef XML -// For XML -#include -#endif/*XML*/ - #include #include @@ -82,7 +77,11 @@ TemplateParser::TemplateParser(std::string course) t = new Template(); current_macro = NULL; +#ifndef TEST_TEMPLATEPARSER file = Conf::xml_basedir + "/templates/" + course + ".xml"; +#else + file = "../xml/templates/" + course + ".xml"; +#endif/*TEST_TEMPLATEPARSER*/ PRACRO_DEBUG(macro, "Using template file: %s\n", file.c_str()); @@ -183,6 +182,7 @@ void print_attributes(std::string prefix, int main() { + try { TemplateParser parser("example"); parser.parse(); @@ -217,7 +217,10 @@ int main() i++; } - + } catch(Exception &e) { + printf("ERROR: %s\n", e.what()); + return 1; + } return 0; } diff --git a/server/src/version.cc b/server/src/version.cc new file mode 100644 index 0000000..e2c64ec --- /dev/null +++ b/server/src/version.cc @@ -0,0 +1,143 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * version.cc + * + * Wed Jul 22 11:41:32 CEST 2009 + * Copyright 2009 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Pracro. + * + * Pracro is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Pracro 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Pracro; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include "version.h" + +Version::Version(std::string v) +{ + memset(version, 0, sizeof(version)); + set(v); +} + +void Version::set(std::string v) +{ + std::string num; + size_t idx = 0; + for(size_t i = 0; i < v.length(); i++) { + if(v[i] == '.') { + if(idx > 2) printf("Too long\n"); + version[idx] = atoi(num.c_str()); + idx++; + num = ""; + } else if(v[i] >= '0' && v[i] <= '9') { + num.append(1, v[i]); + } else { + printf("Illigal character: [%c]\n", v[i]); + } + } + if(idx > 2) printf("Too long\n"); + version[idx] = atoi(num.c_str()); +} + +Version::operator std::string() const +{ + std::string v; + char *buf; + if(patch()) asprintf(&buf, "%d.%d.%d", major(), minor(), patch()); + else asprintf(&buf, "%d.%d", major(), minor()); + v = buf; + free(buf); + return v; +} + +void Version::operator=(std::string v) +{ + set(v); +} + +bool Version::operator<(const Version &other) const +{ + if(other.major() < major()) return true; + if(other.major() > major()) return false; + if(other.minor() < minor()) return true; + if(other.minor() > minor()) return false; + if(other.patch() < patch()) return true; + if(other.patch() > patch()) return false; + return false; +} + +size_t Version::major() const +{ + return version[0]; +} + +size_t Version::minor() const +{ + return version[1]; +} + +size_t Version::patch() const +{ + return version[2]; +} + +#ifdef TEST_VERSION + +#include + +int main() +{ + Version v1("1.2.3"); + printf("Version: %s\n", ((std::string)v1).c_str()); + if((std::string)v1 != "1.2.3") return 1; + + Version v2("1.2"); + printf("Version: %s\n", ((std::string)v2).c_str()); + if((std::string)v2 != "1.2") return 1; + + Version v3("1"); + printf("Version: %s\n", ((std::string)v3).c_str()); + if((std::string)v3 != "1.0") return 1; + + Version v4("1.2.3.4"); // too long + printf("Version: %s\n", ((std::string)v4).c_str()); + if((std::string)v4 != "1.2.3") return 1; + + Version v5("1.2.a"); // illigal character + printf("Version: %s\n", ((std::string)v5).c_str()); + if((std::string)v5 != "1.2") return 1; + + std::set versions; + versions.insert(Version("1.0")); + versions.insert(Version("1.0.0")); + versions.insert(Version("2.0")); + versions.insert(Version("1.1")); + versions.insert(Version("0.1")); + versions.insert(Version("1.0.1")); + versions.insert(Version("1.0.3")); + versions.insert(Version("1.0.2")); + + std::set::iterator i = versions.begin(); + while(i != versions.end()) { + printf("%s\n", ((std::string)*i).c_str()); + i++; + } + + return 0; +} + +#endif/*TEST_VERSION*/ diff --git a/server/src/version.h b/server/src/version.h new file mode 100644 index 0000000..fa86deb --- /dev/null +++ b/server/src/version.h @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * version.h + * + * Wed Jul 22 11:41:32 CEST 2009 + * Copyright 2009 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Pracro. + * + * Pracro is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Pracro 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Pracro; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#ifndef __PRACRO_VERSION_H__ +#define __PRACRO_VERSION_H__ + +#include + +class Version { +public: + Version(std::string v); + operator std::string() const; + void operator=(std::string v); + bool operator<(const Version &other) const; + + size_t major() const; + size_t minor() const; + size_t patch() const; + +private: + void set(std::string v); + size_t version[3]; +}; + +#endif/*__PRACRO_VERSION_H__*/ -- cgit v1.2.3