summaryrefslogtreecommitdiff
path: root/server/src/templateparser.cc
diff options
context:
space:
mode:
authordeva <deva>2008-05-12 09:57:10 +0000
committerdeva <deva>2008-05-12 09:57:10 +0000
commit0a65e89d97e5fdc77d179fa8ef937dda626f855e (patch)
tree65102affa3b15bf4c75b1a0dd623d787264e536a /server/src/templateparser.cc
parent088e153fefc48e3241964c7941a2ff8bc19b57ba (diff)
Made template parser
Diffstat (limited to 'server/src/templateparser.cc')
-rw-r--r--server/src/templateparser.cc223
1 files changed, 223 insertions, 0 deletions
diff --git a/server/src/templateparser.cc b/server/src/templateparser.cc
new file mode 100644
index 0000000..1e6ddc7
--- /dev/null
+++ b/server/src/templateparser.cc
@@ -0,0 +1,223 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * templateparser.cc
+ *
+ * Mon May 12 08:36:24 CEST 2008
+ * Copyright 2008 Bent Bisballe Nyeng, Lars Bisballe Jensen and Peter Skaarup
+ * deva@aasimon.org, elsenator@gmail.com and piparum@piparum.dk
+ ****************************************************************************/
+
+/*
+ * 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 "templateparser.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>
+
+void TemplateParser::error(char* fmt, ...)
+{
+ // TODO: Throw exception here.
+
+ fprintf(stderr, "Error in TemplateParser: ");
+
+ va_list argp;
+ va_start(argp, fmt);
+ vfprintf(stderr, fmt, argp);
+ va_end(argp);
+
+ fprintf(stderr, "\n");
+}
+
+TemplateParser::TemplateParser(std::string templatefile)
+{
+ state = UNDEFINED;
+ t = NULL;
+ current_macro = NULL;
+ current_map = NULL;
+ fd = open(templatefile.c_str(), O_RDONLY);
+ if(fd == -1) error("Could not open file %s", templatefile.c_str());
+}
+
+TemplateParser::~TemplateParser()
+{
+ if(fd != -1) close(fd);
+}
+
+void TemplateParser::startTag(std::string name, std::map< std::string, std::string> attributes)
+{
+ // Create template and enable parsing of macrosequences
+ 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 == "macrosequence") {
+ if(state != TEMPLATE) error("macrosequence found outside template.");
+ state = MACROSEQUENCE;
+
+ assert(t); // A Template has not yet been allocated, cannot create macrosequence!
+
+ t->macrosequence.attributes = attributes;
+
+ return;
+ }
+
+ // Create macro and enable parsing of queries, maps and window
+ if(name == "macro") {
+ if(state != MACROSEQUENCE) error("macro found outside macrosequence.");
+ state = MACRO;
+
+ assert(t); // A Template has not yet been allocated, cannot create macro!
+
+ Macro m;
+ m.attributes = attributes;
+ t->macrosequence.macroes.push_back(m);
+ current_macro = &(t->macrosequence.macroes.back());
+
+ return;
+ }
+
+ // Enable Query parsing
+ if(name == "queries") {
+ if(state != TEMPLATE) error("queries found outside template.");
+ 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 != TEMPLATE) error("maps found outside template.");
+ 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);
+
+ return;
+ }
+
+ // Enable widget parsing
+ if(name == "window") {
+ if(state != TEMPLATE) error("window found outside template.");
+ state = WINDOW;
+
+ assert(current_macro); // No macro is currently available, cannot create window!
+
+ current_macro->window.attributes = attributes;
+ widgetstack.push_back(&(current_macro->window));
+
+ 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;
+ widgetstack.back()->widgets.push_back(w);
+ widgetstack.push_back(&(widgetstack.back()->widgets.back()));
+
+ 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 == "macrosequence") state = TEMPLATE;
+ if(name == "macro") state = MACROSEQUENCE;
+ if(name == "queries") state = MACRO;
+ if(name == "query") state = QUERIES;
+ if(name == "maps") state = MACRO;
+ if(name == "map") state = MAPS;
+ if(name == "window") state = MACRO;
+
+ if(state == WINDOW) {
+ assert(widgetstack.size()); // Widget stack is empty, cannot pop!
+ widgetstack.pop_back();
+ }
+
+}
+
+int TemplateParser::readData(char *data, size_t size)
+{
+ if(fd == -1) return 0;
+ return read(fd, data, size);
+}
+
+Template *TemplateParser::getTemplate()
+{
+ return t;
+}