summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordeva <deva>2008-06-04 11:41:46 +0000
committerdeva <deva>2008-06-04 11:41:46 +0000
commitdad77becc53e2f2c3b0880ee4fddd97d69099f94 (patch)
tree9b7889ef626c226632278bb71d690ced4ab823b1
parent294ed0c031072489f520c90e373b2f24aa16ed8c (diff)
Modulized the template/course/macro system.
-rw-r--r--server/Makefile.am4
-rw-r--r--server/configure.in2
-rw-r--r--server/src/Makefile.am10
-rw-r--r--server/src/luaquerymapper.cc2
-rw-r--r--server/src/macroparser.cc327
-rw-r--r--server/src/macroparser.h76
-rw-r--r--server/src/server.cc45
-rw-r--r--server/src/templateparser.cc163
-rw-r--r--server/src/templateparser.h1
-rw-r--r--server/xml/Makefile.am8
-rw-r--r--server/xml/commit.xml6
-rw-r--r--server/xml/example.xml55
-rw-r--r--server/xml/example2.xml107
-rw-r--r--server/xml/macros/.cvsignore2
-rw-r--r--server/xml/macros/Makefile.am7
-rw-r--r--server/xml/macros/example.xml58
-rw-r--r--server/xml/patient.xml10
-rw-r--r--server/xml/request.xml4
-rw-r--r--server/xml/templates/.cvsignore2
-rw-r--r--server/xml/templates/Makefile.am7
-rw-r--r--server/xml/templates/example.xml14
21 files changed, 538 insertions, 372 deletions
diff --git a/server/Makefile.am b/server/Makefile.am
index 8f5c037..6e7358b 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -1,6 +1,6 @@
AUTOMAKE_OPTIONS = gnu
-SUBDIRS = src etc man xml $(DOC_DIR)
-DISTDIRS = src etc man xml $(DOC_DIR)
+SUBDIRS = src etc man xml xml/templates xml/macros $(DOC_DIR)
+DISTDIRS = src etc man xml xml/templates xml/macros $(DOC_DIR)
.PHONY: doc
doc:
diff --git a/server/configure.in b/server/configure.in
index 01afcad..624df8e 100644
--- a/server/configure.in
+++ b/server/configure.in
@@ -192,5 +192,7 @@ AC_OUTPUT(
src/Makefile
etc/Makefile
man/Makefile
+ xml/templates/Makefile
+ xml/macros/Makefile
xml/Makefile)
diff --git a/server/src/Makefile.am b/server/src/Makefile.am
index c21b814..abf9da7 100644
--- a/server/src/Makefile.am
+++ b/server/src/Makefile.am
@@ -16,6 +16,7 @@ pracrod_SOURCES = \
journal_commit.cc \
log.cc \
luaquerymapper.cc \
+ macroparser.cc \
resumeparser.cc \
saxparser.cc \
server.cc \
@@ -35,6 +36,7 @@ EXTRA_DIST = \
journal_commit.h \
log.h \
luaquerymapper.h \
+ macroparser.h \
resumeparser.h \
saxparser.h \
server.h \
@@ -49,7 +51,8 @@ TESTFILES = \
test_luaquerymapper \
test_templateparser \
test_server \
- test_database
+ test_database \
+ test_macroparser
TESTLOGS = `for F in ${TESTFILES}; do echo $$F.log; done`
@@ -69,7 +72,10 @@ test_luaquerymapper: luaquerymapper.cc
@../../tools/test luaquerymapper.cc queryparser.cc queryhandler.cc tcpsocket.cc exception.cc uid.cc log.cc saxparser.cc -lexpat $(LUA_LIBS)
test_templateparser: templateparser.cc
- @../../tools/test templateparser.cc saxparser.cc -lexpat -DXML="\"../xml\""
+ @../../tools/test templateparser.cc saxparser.cc exception.cc log.cc -lexpat -DXML="\"../xml\""
+
+test_macroparser: macroparser.cc
+ @../../tools/test macroparser.cc saxparser.cc exception.cc log.cc -lexpat -DXML="\"../xml\""
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 -lexpat $(LUA_LIBS) $(CONFIG_LIBS) -DXML="\"../xml\""
diff --git a/server/src/luaquerymapper.cc b/server/src/luaquerymapper.cc
index 2de1d3c..df25778 100644
--- a/server/src/luaquerymapper.cc
+++ b/server/src/luaquerymapper.cc
@@ -115,7 +115,7 @@ Value LUAQueryMapper::map(const std::string &mapper)
lua_pcall(L, 0, LUA_MULTRET, 0);
// Check if app messed up the stack.
- if(lua_gettop(L) != clean_top) {
+ if(lua_gettop(L) != clean_top + 2) {
printf("LUA mapper messed up the stack (wrong number of return values)!\n");
lua_pop(L, lua_gettop(L) - clean_top);
Value v;
diff --git a/server/src/macroparser.cc b/server/src/macroparser.cc
new file mode 100644
index 0000000..6f4798e
--- /dev/null
+++ b/server/src/macroparser.cc
@@ -0,0 +1,327 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * macroparser.cc
+ *
+ * Wed Jun 4 11:57:38 CEST 2008
+ * Copyright 2008 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 "macroparser.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 "exception.h"
+
+void MacroParser::error(const char* fmt, ...)
+{
+ // TODO: Throw exception here.
+
+ fprintf(stderr, "Error in MacroParser: ");
+
+ va_list argp;
+ va_start(argp, fmt);
+ vfprintf(stderr, fmt, argp);
+ va_end(argp);
+
+ fprintf(stderr, "\n");
+
+ throw Exception("Error in MacroParser");
+}
+
+MacroParser::MacroParser(std::string macro)
+{
+ state = UNDEFINED;
+ m = NULL;
+ current_map = NULL;
+ current_luaprogram = NULL;
+
+ file = XML"/macros/" + macro + ".xml";
+
+ printf("Using macro file: %s\n", file.c_str());
+
+ fd = open(file.c_str(), O_RDONLY);
+ if(fd == -1) error("Could not open file %s", file.c_str());
+}
+
+MacroParser::~MacroParser()
+{
+ if(fd != -1) close(fd);
+ if(m) delete m;
+}
+
+void MacroParser::characterData(std::string &data)
+{
+ if(state == MAP) {
+ assert(current_map); // No map present!
+ current_map->attributes["lua"].append(data);
+ }
+
+ if(state == LUAPROGRAM) {
+ assert(current_luaprogram); // No lua program present!
+ current_luaprogram->attributes["lua"].append(data);
+ }
+}
+
+void MacroParser::startTag(std::string name, std::map< std::string, std::string> attributes)
+{
+ // Create macro and enable parsing of queries, maps and window
+ if(name == "macro") {
+ if(state != UNDEFINED) error("macro found not root tag.");
+ state = MACRO;
+
+ assert(!m); // A Macro has already been allocated, cannot create macro!
+
+ m = new Macro();
+ m->attributes = attributes;
+
+ return;
+ }
+
+ // Enable Query parsing
+ if(name == "queries") {
+ if(state != MACRO) error("queries found outside macro.");
+ state = QUERIES;
+
+ assert(m); // No macro is currently available, cannot create queries!
+
+ return;
+ }
+
+ // Create Query
+ if(name == "query") {
+ if(state != QUERIES) error("query found outside queries.");
+ state = QUERY;
+
+ assert(m); // No macro is currently available, cannot create query!
+
+ Query q;
+ q.attributes = attributes;
+ m->queries.push_back(q);
+
+ return;
+ }
+
+ // Enable Map parsing
+ if(name == "maps") {
+ if(state != MACRO) error("maps found outside macro.");
+ state = MAPS;
+
+ assert(m); // No macro is currently available, cannot create maps!
+
+ return;
+ }
+
+ // Create Query
+ if(name == "map") {
+ if(state != MAPS) error("map found outside maps.");
+ state = MAP;
+
+ assert(m); // No macro is currently available, cannot create map!
+
+ Map map;
+ map.attributes = attributes;
+ m->maps.push_back(map);
+ current_map = &(m->maps.back());
+
+ return;
+ }
+
+ // Enable LUA Program parsing
+ if(name == "luaprograms") {
+ if(state != MACRO) error("luaprograms found outside macro.");
+ state = LUAPROGRAMS;
+
+ assert(m); // No macro is currently available, cannot create maps!
+
+ return;
+ }
+
+ // Create Query
+ if(name == "luaprogram") {
+ if(state != LUAPROGRAMS) error("lua program found outside maps.");
+ state = LUAPROGRAM;
+
+ assert(m); // No macro is currently available, cannot create map!
+
+ LUAProgram l;
+ l.attributes = attributes;
+ m->luaprograms.push_back(l);
+ current_luaprogram = &(m->luaprograms.back());
+
+ return;
+ }
+
+ // Enable widget parsing
+ if(name == "window") {
+
+ if(state != MACRO) error("window found outside macro.");
+ state = WINDOW;
+
+ assert(m); // No macro is currently available, cannot create window!
+
+ m->window.attributes = attributes;
+ m->window.attributes["type"] = name;
+
+ Widget *current = &(m->window);
+ widgetstack.push_back(current);
+
+ return;
+ }
+
+ // TODO: We need to parse some (maybe even all) widgets in order to
+ // make db lookup of the previous values.
+ if(state == WINDOW) {
+
+ assert(widgetstack.size()); // Widget stack is empty, cannot create!
+
+ Widget w;
+ w.attributes = attributes;
+ w.attributes["type"] = name;
+
+ Widget *parent = widgetstack.back();
+ parent->widgets.push_back(w);
+
+ Widget *current = &(parent->widgets.back());
+ widgetstack.push_back(current);
+
+ return;
+ }
+
+
+ // Handle include
+ if(name == "include") {
+ return;
+ }
+
+ error("Unknown/illegal tag: %s", name.c_str());
+}
+
+void MacroParser::endTag(std::string name)
+{
+ if(name == "macro") {
+ state = UNDEFINED;
+ }
+ if(name == "queries") state = MACRO;
+ if(name == "query") state = QUERIES;
+ if(name == "maps") state = MACRO;
+ if(name == "map") {
+ current_map = NULL;
+ state = MAPS;
+ }
+ if(name == "luaprograms") state = MACRO;
+ if(name == "luaprogram") {
+ current_luaprogram = NULL;
+ state = LUAPROGRAMS;
+ }
+ if(name == "window") state = MACRO;
+
+ if(state == WINDOW) {
+ assert(widgetstack.size()); // Widget stack is empty, cannot pop!
+ widgetstack.pop_back();
+ if(widgetstack.size() == 0) state = MACRO;
+ }
+}
+
+int MacroParser::readData(char *data, size_t size)
+{
+ if(fd == -1) {
+ fprintf(stderr, "Invalid file descriptor.\n"); fflush(stderr);
+ return 0;
+ }
+ ssize_t r = read(fd, data, size);
+ if(r == -1) {
+ printf("Could not read...%s\n", strerror(errno)); fflush(stdout);
+ return 0;
+ }
+ return r;
+}
+
+void MacroParser::parseError(char *buf, size_t len, std::string error, int lineno)
+{
+ fprintf(stderr, "MacroParser[%s] error at line %d: %s\n", file.c_str(), lineno, error.c_str());
+ fprintf(stderr, "\tBuffer %u bytes: [", len);
+ if(fwrite(buf, len, 1, stderr) != len) {}
+ fprintf(stderr, "]\n");
+ fflush(stderr);
+}
+
+Macro *MacroParser::getMacro()
+{
+ return m;
+}
+
+#ifdef TEST_MACROPARSER
+
+void print_attributes(std::string prefix,
+ std::map< std::string, std::string > &att)
+{
+ std::map< std::string, std::string >::iterator i = att.begin();
+ while(i != att.end()) {
+ printf("%s %s = \"%s\"\n", prefix.c_str(), (*i).first.c_str(), (*i).second.c_str());
+ i++;
+ }
+}
+
+int main()
+{
+ MacroParser parser("example");
+ parser.parse();
+
+ Macro *m = parser.getMacro();
+
+ printf("\t\t\t[Macro]:\n");
+ print_attributes("\t\t\t\t-", m->attributes);
+
+ std::vector< Query >::iterator qi = m->queries.begin();
+ while(qi != m->queries.end()) {
+ printf("\t\t\t\t[Query]:\n");
+ print_attributes("\t\t\t\t\t-", (*qi).attributes);
+ qi++;
+ }
+
+ std::vector< Map >::iterator mi = m->maps.begin();
+ while(mi != m->maps.end()) {
+ printf("\t\t\t\t[Map]:\n");
+ print_attributes("\t\t\t\t\t-", (*mi).attributes);
+ mi++;
+ }
+
+ return 0;
+}
+
+#endif/*TEST_MACROPARSER*/
diff --git a/server/src/macroparser.h b/server/src/macroparser.h
new file mode 100644
index 0000000..0b755f0
--- /dev/null
+++ b/server/src/macroparser.h
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * macroparser.h
+ *
+ * Wed Jun 4 11:57:38 CEST 2008
+ * Copyright 2008 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_MACROPARSER_H__
+#define __PRACRO_MACROPARSER_H__
+
+#include "saxparser.h"
+#include "template.h"
+
+class MacroParser : public SAXParser {
+ typedef enum {
+ UNDEFINED,
+ MACRO,
+ QUERIES,
+ QUERY,
+ MAPS,
+ MAP,
+ WINDOW,
+ LUAPROGRAMS,
+ LUAPROGRAM
+ } ParserState;
+
+public:
+ MacroParser(std::string course);
+ ~MacroParser();
+
+ void characterData(std::string &data);
+ void startTag(std::string name, std::map< std::string, std::string> attributes);
+ void endTag(std::string name);
+ void parseError(char *buf, size_t len, std::string error, int lineno);
+
+ Macro *getMacro();
+
+protected:
+ int readData(char *data, size_t size);
+
+private:
+ int fd;
+
+ std::string file;
+
+ // Parser state data
+ ParserState state;
+ Macro *m;
+ Map *current_map;
+ LUAProgram *current_luaprogram;
+ std::vector< Widget* > widgetstack;
+
+ // Error callback function.
+ void error(const char* fmt, ...);
+};
+
+#endif/*__PRACRO_MACROPARSER_H__*/
diff --git a/server/src/server.cc b/server/src/server.cc
index 9229f28..9708f9f 100644
--- a/server/src/server.cc
+++ b/server/src/server.cc
@@ -39,6 +39,7 @@
#include "transaction.h"
#include "transactionparser.h"
#include "templateparser.h"
+#include "macroparser.h"
#include "queryhandler.h"
#include "queryparser.h"
#include "luaquerymapper.h"
@@ -49,17 +50,15 @@
static std::string error_box(std::string message)
{
- std::string errorbox;
-
- errorbox += " <course name=\"error\">\n";
- errorbox += " <macro name=\"error\">\n";
- errorbox += " <window caption=\"ERROR!\" height=\"240\" layout=\"vbox\" name=\"err\" width=\"320\">\n";
- errorbox += " <textedit name=\"errorlabel\" value=\"" + message + "\"/>\n";
- errorbox += " <button action=\"cancel\" caption=\"Luk\" name=\"cancel\"/>\n";
- errorbox += " </window>\n";
- errorbox += " </macro>\n";
- errorbox += " </course>\n";
-
+ std::string errorbox =
+ " <course name=\"error\">\n"
+ " <macro name=\"error\">\n"
+ " <window caption=\"ERROR!\" height=\"240\" layout=\"vbox\" name=\"error\" width=\"320\">\n"
+ " <textedit name=\"errorlabel\" value=\"" + message + "\"/>\n"
+ " <button action=\"cancel\" caption=\"Luk\" name=\"cancel\"/>\n"
+ " </window>\n"
+ " </macro>\n"
+ " </course>\n";
return errorbox;
}
@@ -115,6 +114,10 @@ static void connection(TCPSocket &socket)
Requests::iterator i = transaction.requests.begin();
while(i != transaction.requests.end()) {
Request &request = *i;
+
+ MacroParser mp(request.macro);
+ mp.parse();
+ Macro *m = mp.getMacro();
printf("Handling request - macro: %s, course: %s\n", request.macro.c_str(), request.course.c_str());
@@ -133,13 +136,14 @@ static void connection(TCPSocket &socket)
while(mi != templ->course.macroes.end()) {
Macro &macro = (*mi);
if(macro.attributes["name"] == request.macro) {
- std::vector< Query >::iterator qi = macro.queries.begin();
- while(qi != macro.queries.end()) {
+
+ std::vector< Query >::iterator qi = m->queries.begin();
+ while(qi != m->queries.end()) {
qh.addQuery(*qi);
- qi++;
+ qi++;
}
}
- mi++;
+ mi++;
}
std::string result = qh.exec();
@@ -166,12 +170,13 @@ static void connection(TCPSocket &socket)
socket.write("\">\n");
if(macro.attributes["name"] == request.macro) {
+
// Handle lua programs
- if(macro.luaprograms.size()) {
+ if(m->luaprograms.size()) {
socket.write(" <luaprograms>\n");
- std::vector< LUAProgram >::iterator lpi = macro.luaprograms.begin();
- while(lpi != macro.luaprograms.end()) {
+ std::vector< LUAProgram >::iterator lpi = m->luaprograms.begin();
+ while(lpi != m->luaprograms.end()) {
socket.write(" <luaprogram name=\"");
socket.write(lpi->attributes["name"]);
socket.write("\">\n");
@@ -186,7 +191,7 @@ static void connection(TCPSocket &socket)
socket.write(" </luaprograms>\n");
}
- widgetgenerator(socket, macro, lqm, db);
+ widgetgenerator(socket, *m, lqm, db);
}
socket.write(" </macro>\n");
@@ -208,7 +213,6 @@ static void connection(TCPSocket &socket)
void server()
{
- int PauseMode = 1;
int port;
try {
port = config()->lookup("port");
@@ -246,7 +250,6 @@ void server()
delete socket;
socket = new TCPSocket();
socket->listen(port);
- PauseMode = 0;
}
}
diff --git a/server/src/templateparser.cc b/server/src/templateparser.cc
index c67ba63..969b4bd 100644
--- a/server/src/templateparser.cc
+++ b/server/src/templateparser.cc
@@ -66,14 +66,12 @@ void TemplateParser::error(const char* fmt, ...)
TemplateParser::TemplateParser(std::string course)
{
state = UNDEFINED;
- t = NULL;
+ t = new Template();
current_macro = NULL;
current_map = NULL;
current_luaprogram = NULL;
- file = XML"/";
- file.append(course);
- file.append(".xml");
+ file = XML"/templates/" + course + ".xml";
printf("Using template file: %s\n", file.c_str());
@@ -84,7 +82,7 @@ TemplateParser::TemplateParser(std::string course)
TemplateParser::~TemplateParser()
{
if(fd != -1) close(fd);
- if(t) delete t;
+ delete t;
}
void TemplateParser::characterData(std::string &data)
@@ -102,22 +100,9 @@ void TemplateParser::characterData(std::string &data)
void TemplateParser::startTag(std::string name, std::map< std::string, std::string> attributes)
{
- // Create template and enable parsing of courses
- if(name == "template") {
- if(state != UNDEFINED) error("template found not in outer level.");
- state = TEMPLATE;
-
- assert(!t); // A Template has already been allocated!
-
- t = new Template();
- t->attributes = attributes;
-
- return;
- }
-
// Enable macro parsing
if(name == "course") {
- if(state != TEMPLATE) error("course found outside template.");
+ if(state != UNDEFINED) error("course found not a root node.");
state = COURSE;
assert(t); // A Template has not yet been allocated, cannot create course!
@@ -142,152 +127,16 @@ void TemplateParser::startTag(std::string name, std::map< std::string, std::stri
return;
}
- // Enable Query parsing
- if(name == "queries") {
- if(state != MACRO) error("queries found outside macro.");
- state = QUERIES;
-
- assert(current_macro); // No macro is currently available, cannot create queries!
-
- return;
- }
-
- // Create Query
- if(name == "query") {
- if(state != QUERIES) error("query found outside queries.");
- state = QUERY;
-
- assert(current_macro); // No macro is currently available, cannot create query!
-
- Query q;
- q.attributes = attributes;
- current_macro->queries.push_back(q);
-
- return;
- }
-
- // Enable Map parsing
- if(name == "maps") {
- if(state != MACRO) error("maps found outside macro.");
- state = MAPS;
-
- assert(current_macro); // No macro is currently available, cannot create maps!
-
- return;
- }
-
- // Create Query
- if(name == "map") {
- if(state != MAPS) error("map found outside maps.");
- state = MAP;
-
- assert(current_macro); // No macro is currently available, cannot create map!
-
- Map m;
- m.attributes = attributes;
- current_macro->maps.push_back(m);
- current_map = &(current_macro->maps.back());
-
- return;
- }
-
- // Enable LUA Program parsing
- if(name == "luaprograms") {
- if(state != MACRO) error("luaprograms found outside macro.");
- state = LUAPROGRAMS;
-
- assert(current_macro); // No macro is currently available, cannot create maps!
-
- return;
- }
-
- // Create Query
- if(name == "luaprogram") {
- if(state != LUAPROGRAMS) error("lua program found outside maps.");
- state = LUAPROGRAM;
-
- assert(current_macro); // No macro is currently available, cannot create map!
-
- LUAProgram l;
- l.attributes = attributes;
- current_macro->luaprograms.push_back(l);
- current_luaprogram = &(current_macro->luaprograms.back());
-
- return;
- }
-
- // Enable widget parsing
- if(name == "window") {
-
- if(state != MACRO) error("window found outside macro.");
- state = WINDOW;
-
- assert(current_macro); // No macro is currently available, cannot create window!
-
- current_macro->window.attributes = attributes;
- current_macro->window.attributes["type"] = name;
-
- Widget *current = &(current_macro->window);
- widgetstack.push_back(current);
-
- return;
- }
-
- // TODO: We need to parse some (maybe even all) widgets in order to
- // make db lookup of the previous values.
- if(state == WINDOW) {
-
- assert(widgetstack.size()); // Widget stack is empty, cannot create!
-
- Widget w;
- w.attributes = attributes;
- w.attributes["type"] = name;
-
- Widget *parent = widgetstack.back();
- parent->widgets.push_back(w);
-
- Widget *current = &(parent->widgets.back());
- widgetstack.push_back(current);
-
- return;
- }
-
-
- // Handle include
- if(name == "include") {
- return;
- }
-
error("Unknown/illegal tag: %s", name.c_str());
}
void TemplateParser::endTag(std::string name)
{
- if(name == "template") state = UNDEFINED;
- if(name == "course") state = TEMPLATE;
+ if(name == "course") state = UNDEFINED;
if(name == "macro") {
current_macro = NULL;
state = COURSE;
}
- if(name == "queries") state = MACRO;
- if(name == "query") state = QUERIES;
- if(name == "maps") state = MACRO;
- if(name == "map") {
- current_map = NULL;
- state = MAPS;
- }
- if(name == "luaprograms") state = MACRO;
- if(name == "luaprogram") {
- current_luaprogram = NULL;
- state = LUAPROGRAMS;
- }
- if(name == "window") state = MACRO;
-
- if(state == WINDOW) {
- assert(widgetstack.size()); // Widget stack is empty, cannot pop!
- widgetstack.pop_back();
- if(widgetstack.size() == 0) state = MACRO;
- }
}
int TemplateParser::readData(char *data, size_t size)
@@ -332,7 +181,7 @@ void print_attributes(std::string prefix,
int main()
{
- TemplateParser parser("example2");
+ TemplateParser parser("example");
parser.parse();
Template *t = parser.getTemplate();
diff --git a/server/src/templateparser.h b/server/src/templateparser.h
index 61ad42a..596bf27 100644
--- a/server/src/templateparser.h
+++ b/server/src/templateparser.h
@@ -32,7 +32,6 @@
typedef enum {
UNDEFINED,
- TEMPLATE,
COURSE,
MACRO,
QUERIES,
diff --git a/server/xml/Makefile.am b/server/xml/Makefile.am
index 62905db..a478a79 100644
--- a/server/xml/Makefile.am
+++ b/server/xml/Makefile.am
@@ -1,9 +1,5 @@
-EXTRA_DIST = \
- patient.xml \
- start.xml
+EXTRA_DIST =
xmldir = $(datadir)/xml
-xml_DATA = \
- patient.xml \
- start.xml
+xml_DATA =
diff --git a/server/xml/commit.xml b/server/xml/commit.xml
deleted file mode 100644
index 0e9ff86..0000000
--- a/server/xml/commit.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<commit name="test_macro" cpr="1505050505" version="1.0">
- <field name="visus_subjective" value="2.85"/>
- <field name="visus_objective" value="2.91"/>
- <field name="eye" value="osin"/>
-</commit>
diff --git a/server/xml/example.xml b/server/xml/example.xml
deleted file mode 100644
index b9974a8..0000000
--- a/server/xml/example.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<macro name="example" version="1.0"
- resume="Det koster 50$$\\100kr\nLinse: ${linse1}\n${linse_note}\nHævelse: ${radio}\n\n${spl_note}">
- <window name="mainwindow"
- caption="Fundus"
- width="500"
- height="560"
- layout="vbox">
- <include name="patient"/>
- <frame name="spl_frame" caption="Spl:" layout="vbox">
- <lineedit name="spl_note" regexp=".*" value="På begge sider alderssvarende forhold. Der er let katarakt, som dog ikke er operationskrævende." help="Hjælpenisse"/>
- </frame>
- <frame name="linse_frame" caption="Linser:" layout="vbox">
- <frame name="linse_framea" layout="hbox">
- <label name="a" width="300" caption="Linse1 er en lidt længere streng end de to andre:"/>
- <lineedit name="linse1" regexp="[0-9]{1,3}D" value="90K" help="Hjælpenisse"/>
- </frame>
- <frame name="linse_frameb" layout="hbox">
- <label name="b" width="300" caption="Linse2:"/>
- <lineedit name="linse2" regexp="[0-9]{1,3}D" value="90D" help="Hjælpenisse"/>
- </frame>
- <frame name="linse_framec" layout="hbox">
- <label name="c" width="300" caption="Linse3:"/>
- <lineedit name="linse3" regexp="[0-9]{1,3}D" value="90D" help="Hjælpenisse"/>
- </frame>
- </frame>
- <frame name="swelling_frame" layout="hbox">
- <label name="swelling" caption="Der findes central hævelse med:"/>
- <frame name="swelling_radios" layout="hbox">
- <radiobuttons name="radio" value="" layout="vbox" help="Hjælpenisse">
- <item caption="Radio Randblødning" value="rand"/>
- <item caption="Radio Exsudater" value="exsudater"/>
- <item caption="Radio Blahblah" value="blabla"/>
- </radiobuttons>
- <combobox name="combo" value="fiskesuppe" help="Hjælpenisse">
- <item caption="Combo Randblødning" value="rand"/>
- <item caption="Combo Exsudater" value="exsudater"/>
- <item caption="Combo Blahblah" value="blabla"/>
- <item caption="Combo Blahblah" value="fisk"/>
- </combobox>
- <listbox name="list" value="exsudate" help="Hjælpenisse">
- <item caption="List Randblødning" value="rand"/>
- <item caption="List Exsudater" value="exsudater"/>
- <item caption="List Blahblah" value="blabla"/>
- </listbox>
- </frame>
- </frame>
- <frame name="buttons" layout="hbox">
- <lineedit name="next_macro" regexp="[a-z_]+[a-z_0-9]*" value="example"/>
- <button name="cancel" caption="Annuller" action="cancel" help="Hjælpenisse"/>
- <button name="continue" caption="Fortsæt" action="continue" field="next_macro" help="Hjælpenisse"/>
- <button name="commit" caption="Godkend" action="commit" help="Hjælpenisse"/>
- </frame>
- </window>
-</macro>
diff --git a/server/xml/example2.xml b/server/xml/example2.xml
deleted file mode 100644
index 826b694..0000000
--- a/server/xml/example2.xml
+++ /dev/null
@@ -1,107 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<template name="testcourse">
- <course name="example2">
- <macro name="example1" version="1.0"
- resume="${linse1}${linse2}">
- <queries>
- <query class="lensmeter" ttl="10000" automap="true"/>
- </queries>
- <maps>
- <map name="axis">
- -- LUA program
- return math.pi, 1234567890
- </map>
- <map name="right.axis" uses="lensmeter, lensmeter.right.axis">
- -- LUA program
- right_axis = 0
- if( lensmeter.right.axis ) right_axis = lensmeter.right.axis.value
- return right_axis, lensmeter.right.sphere.timestamp
- </map>
- <map name="cyl">
- -- LUA program
- return lensmeter.right.cyl.value, lensmeter.right.cyl.timestamp
- </map>
- </maps>
- <luaprograms>
- <luaprogram name="theanswer">
- fisk = getValue('sphere')
- if( tonumber(fisk) == tonumber(value) )
- then
- setValue('cyl', value)
- return true
- else
- return false
- end
- </luaprogram>
- </luaprograms>
- <window name="mainwindow"
- caption="Fundus"
- width="500"
- height="560"
- layout="vbox">
- <frame name="linse_frame" caption="Linser:" layout="vbox">
- <frame name="linse_framea" layout="hbox">
- <label name="a" width="300" caption="Akse rotation:"/>
- <lineedit name="axis" regexp="[24]*" map="axis" lua="theanswer" value="244"/>
- </frame>
- <frame name="linse_frameb" layout="hbox">
- <label name="b" width="300" caption="Sphere:"/>
- <lineedit name="sphere" regexp="[24]*" map="sphere" value="42"/>
- </frame>
- <frame name="linse_framec" layout="hbox">
- <label name="c" width="300" caption="Cyl:"/>
- <lineedit name="cyl" regexp="[24]*" map="cyl" value=""/>
- </frame>
- </frame>
- <frame name="buttons" layout="hbox">
- <button name="cancel" caption="Annuller" action="cancel"/>
- <button name="commit" caption="Godkend" action="commit"/>
- </frame>
- </window>
- </macro>
- <macro name="example2" version="1.0"
- resume="${linse1}${linse2}">
- <queries>
- <query device_id="lensmeter" device_type="lensmeter" class="lensmeter" ttl="10000"/>
- </queries>
- <maps>
- <map name="axis">
- -- LUA program
- return right.axis
- </map>
- <map name="sphere">
- -- LUA program
- return right.sphere
- </map>
- <map name="cyl">
- -- LUA program
- return right.cyl
- </map>
- </maps>
- <window name="mainwindow"
- caption="Fundus"
- width="500"
- height="560"
- layout="vbox">
- <frame name="linse_frame" caption="Linser:" layout="vbox">
- <frame name="linse_framea" layout="hbox">
- <label name="a" width="300" caption="Akse rotation:"/>
- <lineedit name="linse1" regexp="[0-9]{1,3}" map="axis" value="90K"/>
- </frame>
- <frame name="linse_frameb" layout="hbox">
- <label name="b" width="300" caption="Sphere:"/>
- <lineedit name="linse2" regexp="[0-9]{1,3}" map="sphere" value="90K"/>
- </frame>
- <frame name="linse_framec" layout="hbox">
- <label name="c" width="300" caption="Sphere:"/>
- <lineedit name="linse3" regexp="[0-9]{1,3}" map="cyl" value="90K"/>
- </frame>
- </frame>
- <frame name="buttons" layout="hbox">
- <button name="cancel" caption="Annuller" action="cancel"/>
- <button name="commit" caption="Godkend" action="commit"/>
- </frame>
- </window>
- </macro>
- </course>
-</template>
diff --git a/server/xml/macros/.cvsignore b/server/xml/macros/.cvsignore
new file mode 100644
index 0000000..3dda729
--- /dev/null
+++ b/server/xml/macros/.cvsignore
@@ -0,0 +1,2 @@
+Makefile.in
+Makefile
diff --git a/server/xml/macros/Makefile.am b/server/xml/macros/Makefile.am
new file mode 100644
index 0000000..8056e2a
--- /dev/null
+++ b/server/xml/macros/Makefile.am
@@ -0,0 +1,7 @@
+EXTRA_DIST = \
+ example.xml
+
+xmldir = $(datadir)/xml/macros
+
+xml_DATA = \
+ example.xml
diff --git a/server/xml/macros/example.xml b/server/xml/macros/example.xml
new file mode 100644
index 0000000..ce6e2c0
--- /dev/null
+++ b/server/xml/macros/example.xml
@@ -0,0 +1,58 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<macro name="example" version="1.0" resume="${linse1}${linse2}">
+ <queries>
+ <query class="lensmeter" ttl="10000" automap="true"/>
+ </queries>
+ <maps>
+ <map name="axis">
+ -- LUA program
+ return math.pi, 1234567890
+ </map>
+ <map name="right.axis" uses="lensmeter, lensmeter.right.axis">
+ -- LUA program
+ right_axis = 0
+ if( lensmeter.right.axis ) right_axis = lensmeter.right.axis.value
+ return right_axis, lensmeter.right.sphere.timestamp
+ </map>
+ <map name="cyl">
+ -- LUA program
+ return lensmeter.right.cyl.value, lensmeter.right.cyl.timestamp
+ </map>
+ </maps>
+ <luaprograms>
+ <luaprogram name="theanswer">
+ fisk = getValue('sphere')
+ if( tonumber(fisk) == tonumber(value) )
+ then
+ setValue('cyl', value)
+ return true
+ else
+ return false
+ end
+ </luaprogram>
+ </luaprograms>
+ <window name="mainwindow"
+ caption="Fundus"
+ width="500"
+ height="560"
+ layout="vbox">
+ <frame name="linse_frame" caption="Linser:" layout="vbox">
+ <frame name="linse_framea" layout="hbox">
+ <label name="a" width="300" caption="Akse rotation:"/>
+ <lineedit name="axis" regexp="[24]*" map="axis" lua="theanswer" value="244"/>
+ </frame>
+ <frame name="linse_frameb" layout="hbox">
+ <label name="b" width="300" caption="Sphere:"/>
+ <lineedit name="sphere" regexp="[24]*" map="sphere" value="42"/>
+ </frame>
+ <frame name="linse_framec" layout="hbox">
+ <label name="c" width="300" caption="Cyl:"/>
+ <lineedit name="cyl" regexp="[24]*" map="cyl" value=""/>
+ </frame>
+ </frame>
+ <frame name="buttons" layout="hbox">
+ <button name="cancel" caption="Annuller" action="cancel"/>
+ <button name="commit" caption="Godkend" action="commit"/>
+ </frame>
+ </window>
+</macro>
diff --git a/server/xml/patient.xml b/server/xml/patient.xml
deleted file mode 100644
index 8be7e7f..0000000
--- a/server/xml/patient.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<macro name="patient" version="1.0">
- <frame name="cpr_frame" caption="CPR og navn" layout="vbox">
- <lineedit name="patient_cpr" regexp="\d{6}-{0,1}\d{4}" value="1505050505"/>
- <lineedit name="patient_navn" regexp=".+" value="Birger Fiskenolder"/>
- </frame>
- <frame name="name_frame" caption="Noter" layout="vbox">
- <lineedit name="patient_note" regexp=".*" value="Noget note om et eller andet"/>
- </frame>
-</macro>
diff --git a/server/xml/request.xml b/server/xml/request.xml
deleted file mode 100644
index 369d5ea..0000000
--- a/server/xml/request.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<request cpr="1505050505" version="1.0">
- <macro name="example"/>
-</request>
diff --git a/server/xml/templates/.cvsignore b/server/xml/templates/.cvsignore
new file mode 100644
index 0000000..3dda729
--- /dev/null
+++ b/server/xml/templates/.cvsignore
@@ -0,0 +1,2 @@
+Makefile.in
+Makefile
diff --git a/server/xml/templates/Makefile.am b/server/xml/templates/Makefile.am
new file mode 100644
index 0000000..7d487a6
--- /dev/null
+++ b/server/xml/templates/Makefile.am
@@ -0,0 +1,7 @@
+EXTRA_DIST = \
+ example.xml
+
+xmldir = $(datadir)/xml/templates
+
+xml_DATA = \
+ example.xml
diff --git a/server/xml/templates/example.xml b/server/xml/templates/example.xml
new file mode 100644
index 0000000..2fdbb9c
--- /dev/null
+++ b/server/xml/templates/example.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<course name="example" version="1.0">
+ <!-- There can be several macros in a single course -->
+
+ <!-- <macro name="example" required="true"></macro> -->
+
+ <!--
+ <macro name="example">
+ <dependency name="example"/>
+ </macro>
+ -->
+ <macro name="example"/>
+
+</course>