/* -*- 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 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; }