/* -*- 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 #include "macroparser.h" #include "configuration.h" #include // For assert #include // For open and friends #include #include #include #include // For vprintf and friends #include #ifndef XML // For XML #include #endif/*XML*/ #include #include #include "exception.h" void MacroParser::error(const char* fmt, ...) { ERR(macro, "Error in MacroParser: "); { char *p; va_list argp; va_start(argp, fmt); if(vasprintf(&p, fmt, argp) != -1) { ERR(macro, "%p", p); throw Exception("Error in MacroParser: " + std::string(p)); free(p); } va_end(argp); } } MacroParser::MacroParser(std::string macrofile) { state = UNDEFINED; m = NULL; current_map = NULL; current_script = NULL; current_resume_script = NULL; file = macrofile; DEBUG(macro, "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 == RESUME_SCRIPT) { assert(current_resume_script); // No macro present! current_resume_script->code.append(data); } if(state == MAP) { assert(current_map); // No map present! current_map->attributes["lua"].append(data); } if(state == SCRIPT) { assert(current_script); // No script present! current_script->code.append(data); } if(state == COMMIT_SCRIPT) { assert(current_commit_script); // No script present! current_commit_script->code.append(data); } } void MacroParser::startTag(std::string name, attributes_t &attr) { // Create macro and enable parsing of queries, maps and widgets 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(); if(attr.find("name") != attr.end()) m->name = attr["name"]; if(attr.find("version") != attr.end()) m->version = attr["version"]; return; } // Enable resume parsing if(name == "resume") { if(state != MACRO) error("resume found outside macro."); state = RESUME; m->resume.attributes = attr; assert(m); // No macro is currently available, cannot create resume! return; } // Enable oncommit parsing if(name == "oncommit") { if(state != MACRO) error("oncommit found outside macro."); state = COMMIT_SCRIPTS; m->resume.attributes = attr; assert(m); // No macro is currently available, cannot create resume! 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 = attr; 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 = attr; m->maps.push_back(map); current_map = &(m->maps.back()); return; } // Enable script parsing if(name == "scripts") { if(state != MACRO) error("scripts found outside macro."); state = SCRIPTS; assert(m); // No macro is currently available, cannot create maps! return; } // Create script if(name == "script") { assert(m); // No macro is currently available, cannot create script! switch(state) { case SCRIPTS: { state = SCRIPT; Script s; s.attributes = attr; m->scripts.push_back(s); current_script = &(m->scripts.back()); } break; case RESUME: { state = RESUME_SCRIPT; Script s; s.attributes = attr; m->resume_scripts.push_back(s); current_resume_script = &(m->resume_scripts.back()); } break; case COMMIT_SCRIPTS: { state = COMMIT_SCRIPT; Script s; s.attributes = attr; m->commit_scripts.push_back(s); current_commit_script = &(m->commit_scripts.back()); } break; default: error("