summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordeva <deva>2009-07-22 15:00:29 +0000
committerdeva <deva>2009-07-22 15:00:29 +0000
commit7e349e2789a633a6014baea63aeb7932e024c917 (patch)
tree0b7b20adf693e3991f4410368255fd05aa8aab0d
parent8109ada79a24f03e00ebc199ebfdb58e70b054d9 (diff)
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.
-rw-r--r--server/src/Makefile.am48
-rw-r--r--server/src/luaquerymapper.cc23
-rw-r--r--server/src/macroheaderparser.cc149
-rw-r--r--server/src/macroheaderparser.h62
-rw-r--r--server/src/macrolist.cc114
-rw-r--r--server/src/macrolist.h47
-rw-r--r--server/src/macroparser.cc14
-rw-r--r--server/src/macroparser.h2
-rw-r--r--server/src/macrotool_dump.cc2
-rw-r--r--server/src/macrotool_fieldnames.cc2
-rw-r--r--server/src/macrotool_filehandler.cc13
-rw-r--r--server/src/macrotool_util.cc2
-rw-r--r--server/src/macrotool_util.h1
-rw-r--r--server/src/pracrodaopgsql.cc21
-rw-r--r--server/src/queryhandlerpentominos.cc9
-rw-r--r--server/src/queryhandlerpracro.cc21
-rw-r--r--server/src/queryparser.cc14
-rw-r--r--server/src/server.cc41
-rw-r--r--server/src/templateparser.cc15
-rw-r--r--server/src/version.cc143
-rw-r--r--server/src/version.h49
21 files changed, 719 insertions, 73 deletions
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 <stdio.h>
+
+// For assert
+#include <assert.h>
+
+// For open and friends
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+// For vprintf and friends
+#include <stdarg.h>
+
+#ifndef XML
+// For XML
+#include <config.h>
+#endif/*XML*/
+
+#include <errno.h>
+#include <string.h>
+
+#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 <sys/types.h>
+#include <dirent.h>
+
+#include "debug.h"
+#include "macroheaderparser.h"
+
+static std::vector<std::string> listdir(std::string path)
+{
+ std::vector<std::string> 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<std::string> macros = listdir(macropath);
+ std::vector<std::string>::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 <map>
+#include <string>
+#include "version.h"
+
+typedef std::map<Version, std::string> MacroListItem;
+
+class MacroList : public std::map<std::string, MacroListItem > {
+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<std::string, struct _macro> 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<std::string, std::vector<std::string> > 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 <fstream>
#include <ios>
+#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<std::string> macrofiles = getMacros();
+
+ for(int prut = 0; prut < SZ; prut++) {
std::vector<std::string>::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<std::string> listdir(std::string path)
+static std::vector<std::string> listdir(std::string path)
{
std::vector<std::string> 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 <vector>
#include <string>
-std::vector<std::string> listdir(std::string path);
std::vector<std::string> getMacros();
std::vector<std::string> 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<Fieldname> 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 &macrolist)
{
std::string answer;
answer += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\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[] =
"<?xml version='1.0' encoding='UTF-8'?>\n"
"<pracro cpr=\"2003791613\" version=\"1.0\">\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 <stdarg.h>
-#ifndef XML
-// For XML
-#include <config.h>
-#endif/*XML*/
-
#include <errno.h>
#include <string.h>
@@ -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 <set>
+
+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<Version> 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<Version>::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 <string>
+
+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__*/