// config.cc - Lecture de fichiers de configuration. // nono - programme du robot 2004. {{{ // // Copyright (C) 2004 Nicolas Schodet // // Robot APB Team/Efrei 2004. // Web: http://assos.efrei.fr/robot/ // Email: robot AT efrei DOT fr // // 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 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 this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // }}} #include "config.h" #include "config_lex.h" #include #include const char * ConfigError::what () const throw () { static char descr[1024]; if (!m_id) sprintf (descr, "%s: %s", m_file, m_descr); else sprintf (descr, "%s: %s: %s", m_file, m_id, m_descr); return descr; } // Constructeur, prend l'identificateur de configuration en paramètre (nom de // fichier). Config::Config (const char *filename) : m_filename (filename), m_type (-1) { #ifdef CONFIG_VARIANT if (config_yyopen (filename, wrap_handler, this) == -1) #else if (config_yyopen (filename, 0, 0) == -1) #endif m_type = 0; } // Destructeur. Config::~Config (void) { config_yyclose (); } // Attend un token, sinon, jette une exception. int Config::getNum (void) { if (m_type == -1) m_type = config_yylex (); if (m_type != NUM) throw ConfigError (m_filename.c_str (), "Nombre attendu.\n"); m_type = -1; return config_yylval.num; } const char * Config::getId (void) { if (m_type == -1) m_type = config_yylex (); if (m_type != ID) throw ConfigError (m_filename.c_str (), "Identificateur attendu.\n"); m_type = -1; return config_yylval.id; } void Config::getId (std::string &s) { if (m_type == -1) m_type = config_yylex (); if (m_type != ID) throw ConfigError (m_filename.c_str (), "Identificateur attendu.\n"); m_type = -1; s = config_yylval.id; } bool Config::getBool (void) { if (m_type == -1) m_type = config_yylex (); if (m_type != BOOL) throw ConfigError (m_filename.c_str (), "Booléen attendu.\n"); m_type = -1; return config_yylval.boolean; } double Config::getFloat (void) { if (m_type == -1) m_type = config_yylex (); if (m_type == FLOAT) { m_type = -1; return config_yylval.fl; } else if (m_type == NUM) { m_type = -1; return (double) config_yylval.num; } else throw ConfigError (m_filename.c_str (), "Flotant attendu.\n"); } void Config::getString (std::string &s) { if (m_type == -1) m_type = config_yylex (); if (m_type != STRING) throw ConfigError (m_filename.c_str (), "Chaîne de caractères attendue.\n"); m_type = -1; s = config_yylval.str; } void Config::getEof (void) { if (m_type == -1) m_type = config_yylex (); if (m_type) throw ConfigError (m_filename.c_str (), "Fin de fichier attendue.\n"); } // Retourne true si à la fin du fichier. bool Config::eof (void) { if (m_type == -1) m_type = config_yylex (); return m_type == 0; } // Vérifie si le prochain token est... bool Config::isId (const char *s) { if (m_type == -1) m_type = config_yylex (); if (m_type != ID) throw ConfigError (m_filename.c_str (), "Identificateur attendu.\n"); return strcmp (config_yylval.id, s) == 0; } bool Config::isId (void) { if (m_type == -1) m_type = config_yylex (); return m_type == ID; } // Lance une erreur, on a pas trouvé ce qu'on voulais. void Config::noId (void) { throw ConfigError (m_filename.c_str (), config_yylval.id, "Identificateur inconnu.\n"); } void Config::throwError (const char *msg) { throw ConfigError (m_filename.c_str (), msg); } // Appellé par le lexer pour changer de fichier. bool Config::wrap_handler (void *p) { Config *c = reinterpret_cast (p); return c->wrap (); } bool Config::wrap (void) { #ifdef CONFIG_VARIANT return (config_yyopen ((m_filename + "." CONFIG_VARIANT).c_str (), 0, 0) == -1) ? false : true; #else return false; #endif }