diff options
Diffstat (limited to 'server/src')
| -rw-r--r-- | server/src/Makefile.am | 10 | ||||
| -rw-r--r-- | server/src/luaquerymapper.cc | 2 | ||||
| -rw-r--r-- | server/src/macroparser.cc | 327 | ||||
| -rw-r--r-- | server/src/macroparser.h | 76 | ||||
| -rw-r--r-- | server/src/server.cc | 45 | ||||
| -rw-r--r-- | server/src/templateparser.cc | 163 | ||||
| -rw-r--r-- | server/src/templateparser.h | 1 | 
7 files changed, 442 insertions, 182 deletions
| 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 ¯o = (*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, | 
