summaryrefslogtreecommitdiff
path: root/server/src/macro_parser.cc
diff options
context:
space:
mode:
authordeva <deva>2007-09-24 12:47:16 +0000
committerdeva <deva>2007-09-24 12:47:16 +0000
commita3cb015e6b69821062306981924a43a5487f3b5d (patch)
treefcacf4cab2bf2d188775b11f2f53fbf5a9235d7a /server/src/macro_parser.cc
parent574f7c69a0cb7d3af3e20d740e6202d2faaf2718 (diff)
Server now parses XML and handles include.
Diffstat (limited to 'server/src/macro_parser.cc')
-rw-r--r--server/src/macro_parser.cc170
1 files changed, 170 insertions, 0 deletions
diff --git a/server/src/macro_parser.cc b/server/src/macro_parser.cc
new file mode 100644
index 0000000..c317482
--- /dev/null
+++ b/server/src/macro_parser.cc
@@ -0,0 +1,170 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * macro_parser.cc
+ *
+ * Mon Sep 24 10:49:55 CEST 2007
+ * Copyright 2007 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 "macro_parser.h"
+
+// For XML
+#include <config.h>
+
+// For open, read and close
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <expat.h>
+
+#include <string>
+#include <map>
+
+class MacroParser {
+public:
+ Macro *macro;
+ std::vector< Widget* > stack;
+ bool done;
+};
+
+static void start_hndl(void *p, const char *el, const char **attr)
+{
+ MacroParser *parser = (MacroParser*)XML_GetUserData(p);
+
+ printf("Start tag [%s]\n", el);
+
+ // Convert to comfy C++ values...
+ std::string name = el;
+ std::map< std::string, std::string > attributes;
+
+ while(*attr) {
+ std::string at_name = *attr;
+ attr++;
+ std::string at_value = *attr;
+ attr++;
+
+ attributes.insert(make_pair(at_name, at_value));
+ }
+
+ // Do something reasonable with them...
+
+ if(name == "include") {
+
+ Macro inc;
+ parse_macro(attributes["name"], inc);
+
+ WidgetList::iterator w = inc.widgets.front().widgets.begin();
+ while(w != inc.widgets.front().widgets.end()) {
+ parser->stack.back()->widgets.push_back(*w);
+ w++;
+ }
+
+ return; // Don't do further parsing of this tag.
+ }
+
+ Widget widget;
+ widget.type = name;
+
+ Widget *wp;
+
+ if(parser->stack.size() > 0) {// We only pushback the child if there is a parent.
+ parser->stack.back()->widgets.push_back(widget);
+ wp = &parser->stack.back()->widgets.back();
+ } else {
+ parser->macro->widgets.push_back(widget);
+ wp = &parser->macro->widgets.back();
+ }
+ parser->stack.push_back(wp);
+
+ std::map< std::string, std::string >::iterator i = attributes.begin();
+ while(i != attributes.end()) {
+ WidgetProperty prop;
+ prop.name = i->first;
+ prop.value = i->second;
+
+ wp->properties.push_back(prop);
+
+ i++;
+ }
+}
+
+static void end_hndl(void *p, const char *el)
+{
+ MacroParser *parser = (MacroParser*)XML_GetUserData(p);
+
+ printf("End tag [%s]\n", el);
+
+ if(std::string("include") != el) parser->stack.pop_back();
+
+ if(!strcmp(el, "macro")) parser->done = true;
+}
+
+void parse_macro(std::string name, Macro &macro)
+{
+
+ XML_Parser p = XML_ParserCreate(NULL);
+ if (! p) {
+ fprintf(stderr, "Couldn't allocate memory for parser\n");
+ // throw Exception(...);
+ return;
+ }
+
+ MacroParser parser;
+ parser.macro = &macro;
+ parser.done = false;
+
+ XML_SetUserData(p, &parser);
+ XML_UseParserAsHandlerArg(p);
+ XML_SetElementHandler(p, start_hndl, end_hndl);
+
+ std::string macrofile = std::string(XML) + "/" + name + ".xml";
+ int fd = open(macrofile.c_str(), O_RDONLY);
+
+ if(fd == -1) {
+ printf("Cannot open file \"%s\"...", macrofile.c_str());
+ printf("failed!\n");
+ return;
+ }
+
+ while(!parser.done) {
+ char buf[32];
+ int len;
+
+ memset(buf, 0, sizeof(buf));
+ len = read(fd, buf, sizeof(buf) - 1);
+
+ parser.done = len == 0;
+
+ if (! XML_Parse(p, buf, len, parser.done)) {
+ fprintf(stderr, "Parse error at line %d:\n%s\n",
+ XML_GetCurrentLineNumber(p),
+ XML_ErrorString(XML_GetErrorCode(p)));
+ // throw Exception(...);
+ return;
+ }
+ }
+
+ // printf("%d requests\n", transaction.requests.size());
+}