X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Flisp%2Fparser.cpp;h=2a09de80f3a101564c753523a3a80261f385f1e4;hb=f2d761ff31e00ea72783878b7e1586a357e15d5a;hp=526d57a3c0625562e66551d7fc2d31c9f34b4b74;hpb=78d47dc66f5ada145de0700b84cefb7334befe73;p=supertux.git diff --git a/src/lisp/parser.cpp b/src/lisp/parser.cpp index 526d57a3c..2a09de80f 100644 --- a/src/lisp/parser.cpp +++ b/src/lisp/parser.cpp @@ -1,12 +1,10 @@ -// $Id$ -// // SuperTux // Copyright (C) 2006 Matthias Braun // -// This program 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. +// This program 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 3 of the License, or +// (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -14,41 +12,61 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#include +// along with this program. If not, see . #include #include -#include -#include -#include - -#include "tinygettext/tinygettext.hpp" -#include "physfs/physfs_stream.hpp" -#include "parser.hpp" -#include "lisp.hpp" - -namespace lisp -{ - -Parser::Parser(bool translate) - : lexer(0), dictionary_manager(0), dictionary(0) +#include +#include + +#include "lisp/lisp.hpp" +#include "lisp/parser.hpp" +#include "util/gettext.hpp" +#include "util/obstackpp.hpp" +#include "physfs/ifile_stream.hpp" +#include "physfs/ifile_streambuf.hpp" +#include "supertux/globals.hpp" + +#include "supertux/gameconfig.hpp" + +namespace lisp { + +Parser::Parser(bool translate) : + lexer(0), + filename(), + dictionary_manager(0), + dictionary(0), + token(), + searchpath(), + obst() { if(translate) { - dictionary_manager = new TinyGetText::DictionaryManager(); + dictionary_manager = new tinygettext::DictionaryManager(); dictionary_manager->set_charset("UTF-8"); + if (g_config) { + if (g_config->locale != "") { + dictionary_manager->set_language(tinygettext::Language::from_name(g_config->locale)); + } + else if(g_dictionary_manager && g_dictionary_manager->get_language()) { + // Language set to auto-detect? + dictionary_manager->set_language(g_dictionary_manager->get_language()); + } + } } + + obstack_init(&obst); + searchpath = PHYSFS_getSearchPath(); } Parser::~Parser() { + obstack_free(&obst, NULL); delete lexer; delete dictionary_manager; + PHYSFS_freeList(searchpath); } -static std::string dirname(std::string filename) +static std::string dirname(const std::string& filename) { std::string::size_type p = filename.find_last_of('/'); if(p == std::string::npos) @@ -57,35 +75,41 @@ static std::string dirname(std::string filename) return filename.substr(0, p+1); } -Lisp* -Parser::parse(const std::string& filename) +const Lisp* +Parser::parse(const std::string& filename_) { - IFileStreambuf ins(filename); + IFileStreambuf ins(filename_); std::istream in(&ins); - this->filename = filename; if(!in.good()) { std::stringstream msg; - msg << "Parser problem: Couldn't open file '" << filename << "'."; + msg << "Parser problem: Couldn't open file '" << filename_ << "'."; throw std::runtime_error(msg.str()); } if(dictionary_manager) { - dictionary_manager->add_directory(dirname(filename)); + std::string rel_dir = dirname (filename_); + for(char** i = searchpath; *i != NULL; i++) + { + std::string abs_dir = std::string (*i) + PHYSFS_getDirSeparator () + rel_dir; + dictionary_manager->add_directory (abs_dir); + } dictionary = & (dictionary_manager->get_dictionary()); } - return parse(in); + return parse(in, filename_); } -Lisp* -Parser::parse(std::istream& stream) +const Lisp* +Parser::parse(std::istream& stream, const std::string& sourcename) { delete lexer; lexer = new Lexer(stream); + this->filename = sourcename; token = lexer->getNextToken(); - Lisp* result = new Lisp(Lisp::TYPE_CONS); + + Lisp* result = new(obst) Lisp(Lisp::TYPE_CONS); result->v.cons.car = read(); result->v.cons.cdr = 0; @@ -96,27 +120,27 @@ Parser::parse(std::istream& stream) } void -Parser::parse_error(const char* msg) +Parser::parse_error(const char* msg) const { std::stringstream emsg; emsg << "Parse Error at '" << filename << "' line " << lexer->getLineNumber() - << ": " << msg; + << ": " << msg; throw std::runtime_error(emsg.str()); } -Lisp* +const Lisp* Parser::read() { Lisp* result; switch(token) { case Lexer::TOKEN_EOF: { - parse_error("Unexpected EOF."); + parse_error("Unexpected EOF."); } case Lexer::TOKEN_CLOSE_PAREN: { parse_error("Unexpected ')'."); } case Lexer::TOKEN_OPEN_PAREN: { - result = new Lisp(Lisp::TYPE_CONS); + result = new(obst) Lisp(Lisp::TYPE_CONS); token = lexer->getNextToken(); if(token == Lexer::TOKEN_CLOSE_PAREN) { @@ -126,25 +150,25 @@ Parser::read() } if(token == Lexer::TOKEN_SYMBOL && - strcmp(lexer->getString(), "_") == 0) { + strcmp(lexer->getString(), "_") == 0) { // evaluate translation function (_ str) in place here token = lexer->getNextToken(); if(token != Lexer::TOKEN_STRING) - parse_error("Expected string after '(_'"); + parse_error("Expected string after '(_'"); - result = new Lisp(Lisp::TYPE_STRING); + result = new(obst) Lisp(Lisp::TYPE_STRING); if(dictionary) { std::string translation = dictionary->translate(lexer->getString()); - result->v.string = new char[translation.size()+1]; + result->v.string = new(obst) char[translation.size()+1]; memcpy(result->v.string, translation.c_str(), translation.size()+1); } else { size_t len = strlen(lexer->getString()) + 1; - result->v.string = new char[len]; + result->v.string = new(obst) char[len]; memcpy(result->v.string, lexer->getString(), len); } token = lexer->getNextToken(); if(token != Lexer::TOKEN_CLOSE_PAREN) - parse_error("Expected ')' after '(_ string'"); + parse_error("Expected ')' after '(_ string'"); break; } @@ -155,45 +179,47 @@ Parser::read() cur->v.cons.cdr = 0; break; } - cur->v.cons.cdr = new Lisp(Lisp::TYPE_CONS); - cur = cur->v.cons.cdr; + Lisp *newcur = new(obst) Lisp(Lisp::TYPE_CONS); + cur->v.cons.cdr = newcur; + cur = newcur; } while(1); break; } case Lexer::TOKEN_SYMBOL: { - result = new Lisp(Lisp::TYPE_SYMBOL); + result = new(obst) Lisp(Lisp::TYPE_SYMBOL); size_t len = strlen(lexer->getString()) + 1; - result->v.string = new char[len]; + result->v.string = new(obst) char[len]; memcpy(result->v.string, lexer->getString(), len); break; } case Lexer::TOKEN_STRING: { - result = new Lisp(Lisp::TYPE_STRING); + result = new(obst) Lisp(Lisp::TYPE_STRING); size_t len = strlen(lexer->getString()) + 1; - result->v.string = new char[len]; + result->v.string = new(obst) char[len]; memcpy(result->v.string, lexer->getString(), len); break; } case Lexer::TOKEN_INTEGER: - result = new Lisp(Lisp::TYPE_INTEGER); - sscanf(lexer->getString(), "%d", &result->v.integer); + result = new(obst) Lisp(Lisp::TYPE_INTEGER); + result->v.integer = atoi(lexer->getString()); break; case Lexer::TOKEN_REAL: - result = new Lisp(Lisp::TYPE_REAL); - sscanf(lexer->getString(), "%f", &result->v.real); + result = new(obst) Lisp(Lisp::TYPE_REAL); + result->v.real = strtof(lexer->getString(), NULL); break; case Lexer::TOKEN_TRUE: - result = new Lisp(Lisp::TYPE_BOOLEAN); + result = new(obst) Lisp(Lisp::TYPE_BOOLEAN); result->v.boolean = true; break; case Lexer::TOKEN_FALSE: - result = new Lisp(Lisp::TYPE_BOOLEAN); + result = new(obst) Lisp(Lisp::TYPE_BOOLEAN); result->v.boolean = false; break; default: // this should never happen + result = NULL; assert(false); } @@ -202,3 +228,5 @@ Parser::read() } } // end of namespace lisp + +/* EOF */