From dad77becc53e2f2c3b0880ee4fddd97d69099f94 Mon Sep 17 00:00:00 2001 From: deva Date: Wed, 4 Jun 2008 11:41:46 +0000 Subject: Modulized the template/course/macro system. --- server/Makefile.am | 4 +- server/configure.in | 2 + server/src/Makefile.am | 10 +- server/src/luaquerymapper.cc | 2 +- server/src/macroparser.cc | 327 +++++++++++++++++++++++++++++++++++++++ server/src/macroparser.h | 76 +++++++++ server/src/server.cc | 45 +++--- server/src/templateparser.cc | 163 +------------------ server/src/templateparser.h | 1 - server/xml/Makefile.am | 8 +- server/xml/commit.xml | 6 - server/xml/example.xml | 55 ------- server/xml/example2.xml | 107 ------------- server/xml/macros/.cvsignore | 2 + server/xml/macros/Makefile.am | 7 + server/xml/macros/example.xml | 58 +++++++ server/xml/patient.xml | 10 -- server/xml/request.xml | 4 - server/xml/templates/.cvsignore | 2 + server/xml/templates/Makefile.am | 7 + server/xml/templates/example.xml | 14 ++ 21 files changed, 538 insertions(+), 372 deletions(-) create mode 100644 server/src/macroparser.cc create mode 100644 server/src/macroparser.h delete mode 100644 server/xml/commit.xml delete mode 100644 server/xml/example.xml delete mode 100644 server/xml/example2.xml create mode 100644 server/xml/macros/.cvsignore create mode 100644 server/xml/macros/Makefile.am create mode 100644 server/xml/macros/example.xml delete mode 100644 server/xml/patient.xml delete mode 100644 server/xml/request.xml create mode 100644 server/xml/templates/.cvsignore create mode 100644 server/xml/templates/Makefile.am create mode 100644 server/xml/templates/example.xml 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 + +// For open and friends +#include +#include +#include +#include + +// For vprintf and friends +#include + +#ifndef XML +// For XML +#include +#endif/*XML*/ + +#include + +#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 += " \n"; - errorbox += " \n"; - errorbox += " \n"; - errorbox += " \n"; - errorbox += "