/* -*- 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 // For open and friends #include #include #include #include // For vprintf and friends #include #ifndef XML // For XML #include #endif/*XML*/ #include 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 course) { state = UNDEFINED; t = NULL; current_macro = NULL; current_map = NULL; std::string file = XML"/"; file.append(course); file.append(".xml"); printf("Using template 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()); } TemplateParser::~TemplateParser() { if(fd != -1) close(fd); if(t) delete t; } void TemplateParser::characterData(std::string &data) { if(state == MAP) { // assert(current_macro->maps.size()); // No maps present! // current_macro->maps.back().attributes["lua"].append(data); assert(current_map); // No map present! current_map->attributes["lua"].append(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."); state = COURSE; assert(t); // A Template has not yet been allocated, cannot create course! t->course.attributes = attributes; return; } // Create macro and enable parsing of queries, maps and window if(name == "macro") { if(state != COURSE) error("macro found outside course."); state = MACRO; assert(t); // A Template has not yet been allocated, cannot create macro! Macro m; // m.attributes = attributes; t->course.macroes.push_back(m); current_macro = &(t->course.macroes.back()); 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 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); printf("%p %p\n", current); fflush(stdout); 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; printf("1 %d\n", widgetstack.size() ); fflush(stdout); Widget *parent = widgetstack.back(); printf("%d\n", parent->widgets.size()); fflush(stdout); parent->widgets.push_back(w); printf("2\n"); fflush(stdout); Widget *current = &(parent->widgets.back()); widgetstack.push_back(current); printf("3\n"); fflush(stdout); 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 == "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 == "window") state = MACRO; if(state == WINDOW) { printf("4\n"); fflush(stdout); assert(widgetstack.size()); // Widget stack is empty, cannot pop! widgetstack.pop_back(); printf("5\n"); fflush(stdout); if(widgetstack.size() == 0) state = MACRO; printf("6\n"); fflush(stdout); } } int TemplateParser::readData(char *data, size_t size) { if(fd == -1) 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; } Template *TemplateParser::getTemplate() { return t; } #ifdef TEST_TEMPLATEPARSER 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() { TemplateParser parser("example2"); parser.parse(); Template *t = parser.getTemplate(); printf("[Template]:\n"); print_attributes("\t-", t->attributes); printf("\t[Course]:\n"); print_attributes("\t\t-", t->course.attributes); printf("\t\t[Macroes]:\n"); std::vector< Macro >::iterator i = t->course.macroes.begin(); while(i != t->course.macroes.end()) { printf("\t\t\t[Macro]:\n"); print_attributes("\t\t\t\t-", (*i).attributes); std::vector< Query >::iterator qi = (*i).queries.begin(); while(qi != (*i).queries.end()) { printf("\t\t\t\t[Query]:\n"); print_attributes("\t\t\t\t\t-", (*qi).attributes); qi++; } std::vector< Map >::iterator mi = (*i).maps.begin(); while(mi != (*i).maps.end()) { printf("\t\t\t\t[Map]:\n"); print_attributes("\t\t\t\t\t-", (*mi).attributes); mi++; } i++; } return 0; } #endif/*TEST_TEMPLATEPARSER*/