From 4b2f35d007639332d30ed561dabd1b1967f50f10 Mon Sep 17 00:00:00 2001 From: schodet Date: Sun, 13 Mar 2005 20:09:04 +0000 Subject: Ajout de config. --- 2005/i/robert/src/config/Makefile.defs | 11 +++ 2005/i/robert/src/config/config.hh | 40 ++++++++ 2005/i/robert/src/config/config_data.cc | 108 ++++++++++++++++++++++ 2005/i/robert/src/config/config_data.hh | 65 +++++++++++++ 2005/i/robert/src/config/config_data.tcc | 45 +++++++++ 2005/i/robert/src/config/lexer.ll | 111 ++++++++++++++++++++++ 2005/i/robert/src/config/parser.yy | 132 +++++++++++++++++++++++++++ 2005/i/robert/src/config/parser_extra.hh | 47 ++++++++++ 2005/i/robert/src/config/test_config_data.cc | 44 +++++++++ 9 files changed, 603 insertions(+) create mode 100644 2005/i/robert/src/config/Makefile.defs create mode 100644 2005/i/robert/src/config/config.hh create mode 100644 2005/i/robert/src/config/config_data.cc create mode 100644 2005/i/robert/src/config/config_data.hh create mode 100644 2005/i/robert/src/config/config_data.tcc create mode 100644 2005/i/robert/src/config/lexer.ll create mode 100644 2005/i/robert/src/config/parser.yy create mode 100644 2005/i/robert/src/config/parser_extra.hh create mode 100644 2005/i/robert/src/config/test_config_data.cc (limited to '2005/i/robert/src/config') diff --git a/2005/i/robert/src/config/Makefile.defs b/2005/i/robert/src/config/Makefile.defs new file mode 100644 index 0000000..816946f --- /dev/null +++ b/2005/i/robert/src/config/Makefile.defs @@ -0,0 +1,11 @@ +PROGRAMS += test_config_data + +config_OBJECTS = lexer.o parser.o config_data.o + +test_config_data_OBJECTS = $(config_OBJECTS) test_config_data.o + +test_config_data: $(test_config_data_OBJECTS) + +parser.hh: parser.cc + +lexer.hh: lexer.cc diff --git a/2005/i/robert/src/config/config.hh b/2005/i/robert/src/config/config.hh new file mode 100644 index 0000000..55263a4 --- /dev/null +++ b/2005/i/robert/src/config/config.hh @@ -0,0 +1,40 @@ +#ifndef config_hh +#define config_hh +// config.hh +// robert - programme du robot 2005. {{{ +// +// Copyright (C) 2005 Nicolas Schodet +// +// Robot APB Team/Efrei 2005. +// 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 +#include + +/// Class to access config. +class Config +{ + public: + typedef std::list IntList; + typedef std::list FloatList; + typedef std::list StringList; +}; + +#endif // config_hh diff --git a/2005/i/robert/src/config/config_data.cc b/2005/i/robert/src/config/config_data.cc new file mode 100644 index 0000000..e737bed --- /dev/null +++ b/2005/i/robert/src/config/config_data.cc @@ -0,0 +1,108 @@ +// config_data.cc +// robert - programme du robot 2005. {{{ +// +// Copyright (C) 2005 Nicolas Schodet +// +// Robot APB Team/Efrei 2005. +// 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/config.hh" +#include "config/config_data.hh" +#include "config/parser_extra.hh" +#include "parser.hh" +#include "lexer.hh" + +#include + +/// Constructeur. Traite les arguments de la ligne de commande et lit le +/// fichier de configuration. Les arguments traités sont retiré de la +/// ligne de commande. +ConfigData::ConfigData (int &argc, char **&argv) +{ + parse ("rc/config"); +} + +/// Constructeur. Fourni en plus un fichier de configuration différent de +/// celui par défaut. +ConfigData::ConfigData (int &argc, char **&argv, const std::string &file) +{ + parse (file); +} + +/// Récupère une valeur de configuration. +const any & +ConfigData::get (const std::string &id) const +{ + Data::const_iterator i = data_.find (id); + if (i == data_.end ()) + throw std::runtime_error (id + ": config item not found"); + return i->second; +} + +/// Ajoute une valeur de configuration. VAL prend l'ancienne valeur ou un any +/// vide. +void +ConfigData::add (const std::string &id, any &val) +{ + any &a = data_[id]; + a.swap (val); +} + +int yyparse (void *); + +/// Lance le parseur. +void +ConfigData::parse (const std::string &file) +{ + FILE *f; + f = fopen (file.c_str (), "r"); + if (!f) + throw std::runtime_error ("can not open config file \"" + file + "\""); + try + { + // Crée un scaner, initialise son tampon d'entré, puis parse. + yyscan_t scanner; + YY_BUFFER_STATE buf; + ParserExtra pe (*this); + yylex_init (&scanner); + yyset_extra (&pe, scanner); + buf = yy_create_buffer (f, YY_READ_BUF_SIZE, scanner); + yy_switch_to_buffer (buf, scanner); + int ret = yyparse (scanner); + yy_delete_buffer (buf, scanner); + yylex_destroy (scanner); + if (ret) + throw std::runtime_error ("parse error"); + } + catch (const std::runtime_error &e) + { + fclose (f); + throw std::runtime_error ("in config file \"" + file + "\": " + + e.what ()); + } + fclose (f); +} + +/* Shut up warning for this wrongly declared static function. */ +static int +yy_init_globals (yyscan_t yyscanner) +{ + return yy_init_globals (yyscanner); +} + diff --git a/2005/i/robert/src/config/config_data.hh b/2005/i/robert/src/config/config_data.hh new file mode 100644 index 0000000..bf62bd8 --- /dev/null +++ b/2005/i/robert/src/config/config_data.hh @@ -0,0 +1,65 @@ +#ifndef config_data_hh +#define config_data_hh +// config_data.hh +// robert - programme du robot 2005. {{{ +// +// Copyright (C) 2005 Nicolas Schodet +// +// Robot APB Team/Efrei 2005. +// 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 "utils/any.hh" + +#include +#include + +/// Classe contenant les informations de configuration. +class ConfigData +{ + typedef std::map Data; + Data data_; + public: + /// Constructeur. Traite les arguments de la ligne de commande et lit le + /// fichier de configuration. Les arguments traités sont retiré de la + /// ligne de commande. + ConfigData (int &argc, char **&argv); + /// Constructeur. Fourni en plus un fichier de configuration différent de + /// celui par défaut. + ConfigData (int &argc, char **&argv, const std::string &file); + /// Récupère une valeur de configuration, fonction générique. + template + const T &get (const std::string &id) const; + /// Récupère une valeur de configuration. + const any &get (const std::string &id) const; + /// Ajoute une valeur de configuration. VAL prend l'ancienne valeur ou un + /// any vide. + void add (const std::string &id, any &val); + /// Ajoute une valeur de configuration, fonction générique. Attention, + /// cette fonction est plus couteuse car elle fait une copie de + /// la valeur. + template + void add (const std::string &id, const T &val); + private: + /// Lance le parseur. + void parse (const std::string &file); +}; + +#include "config/config_data.tcc" + +#endif // config_data_hh diff --git a/2005/i/robert/src/config/config_data.tcc b/2005/i/robert/src/config/config_data.tcc new file mode 100644 index 0000000..4abad34 --- /dev/null +++ b/2005/i/robert/src/config/config_data.tcc @@ -0,0 +1,45 @@ +// config_data.tcc +// robert - programme du robot 2005. {{{ +// +// Copyright (C) 2005 Nicolas Schodet +// +// Robot APB Team/Efrei 2005. +// 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. +// +// }}} + +/// Récupère une valeur de configuration, fonction générique. +template +const T & +ConfigData::get (const std::string &id) const +{ + const any &a = get (id); + return any_cast (a); +} + +/// Ajoute une valeur de configuration, fonction générique. Attention, +/// cette fonction est plus couteuse car elle fait une copie de +/// la valeur. +template +void +ConfigData::add (const std::string &id, const T &val) +{ + any a (val); + add (id, a); +} + diff --git a/2005/i/robert/src/config/lexer.ll b/2005/i/robert/src/config/lexer.ll new file mode 100644 index 0000000..93173f9 --- /dev/null +++ b/2005/i/robert/src/config/lexer.ll @@ -0,0 +1,111 @@ +%{ +// robert - programme du robot 2005. {{{ +// +// Copyright (C) 2005 Nicolas Schodet +// +// Robot APB Team/Efrei 2005. +// 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/config.hh" +#include "config/parser_extra.hh" +#include "utils/any.hh" +#include "parser.hh" +%} + +%option reentrant +%option header-file="lexer.hh" +%option outfile="lexer.cc" +%option bison-bridge +%option noyywrap nodefault nounput + +%x str + +INTDEC [+-]?[0-9]+ +INTHEX "0x"[0-9a-fA-F]+ +INTNUM {INTDEC}|{INTHEX} +FLOAT1 [+-]?\.[0-9]+ +FLOAT2 [+-]?[0-9]+\.[0-9]* +FLOATNUM {FLOAT1}|{FLOAT2} + +%% + +"true"|"on" { + yylval->b = true; + return BOOLEAN; +} + +"false"|"off" { + yylval->b = false; + return BOOLEAN; +} + +[a-zA-Z][_a-zA-Z0-9.-]* { + yylval->s = new std::string (yytext); + return ID; +} + +{FLOATNUM} { + yylval->f = strtod (yytext, 0); + return FLOAT; +} + +{INTNUM} { + yylval->i = strtol (yytext, 0, 0); + return INT; +} + +\" { + BEGIN(str); + yyextra->tmp.clear (); +} + +[=\n()] return yytext[0]; + +"img:" return IMG; +"data:" return DATA; + +[ \t]+ /* Skip. */ + +. { + yylval->c = yytext[0]; + std::cout << "UNKNOWN " << yytext[0] << std::endl; + return UNKNOWN; +} + +\" { + BEGIN (INITIAL); + yylval->s = new std::string (yyextra->tmp); + return STRING; +} + +\\n yyextra->tmp += '\n'; +\\r yyextra->tmp += '\r'; +\\t yyextra->tmp += '\t'; +\\(.|\n) yyextra->tmp += yytext[1]; +. yyextra->tmp += yytext[0]; +\n { + yylval->c = yytext[0]; + return UNKNOWN; +} + + +%% + +/* vim:ft=lex: +*/ diff --git a/2005/i/robert/src/config/parser.yy b/2005/i/robert/src/config/parser.yy new file mode 100644 index 0000000..fe1ca60 --- /dev/null +++ b/2005/i/robert/src/config/parser.yy @@ -0,0 +1,132 @@ +%{ +// robert - programme du robot 2005. {{{ +// +// Copyright (C) 2005 Nicolas Schodet +// +// Robot APB Team/Efrei 2005. +// 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. +// +// }}} +#define YYPARSE_PARAM scanner +#define YYLEX_PARAM scanner + +#include "config/config.hh" +#include "config/config_data.hh" +#include "config/parser_extra.hh" + +// Fichiers d'en-tête générés. +#include "parser.hh" +#include "lexer.hh" + +#include // XXX à virer. + +void yyerror (const char *); + +#undef yyextra +#define yyextra (yyget_extra (scanner)) + +%} + +%error-verbose +%pure-parser +%defines +%union { + char c; + int i; + double f; + bool b; + std::string *s; + struct { + any *a; + Config::IntList *il; + Config::FloatList *fl; + Config::StringList *sl; + } a; +} + +%token UNKNOWN +%token INT +%token FLOAT +%token ID STRING +%token BOOLEAN +%token IMG DATA + +%type int_list +//%type float_list +//%type string_list + +%destructor { delete $$; } ID STRING +%destructor { delete $$.a; } int_list +//%destructor { delete $$.a; } float_list +//%destructor { delete $$.a; } string_list + +%% + +input: + /* Nothing. */ + | input confitem '\n' + | input '\n' +; + +confitem: + ID '=' INT { + yyextra->configData.add (*$1, $3); + delete $1; + } + | ID '=' FLOAT { + yyextra->configData.add (*$1, $3); + delete $1; + } + | ID '=' STRING { + yyextra->configData.add (*$1, *$3); + delete $1; + delete $3; + } + | ID '=' '(' int_list ')' { + yyextra->configData.add (*$1, *$4.a); + delete $1; + delete $4.a; + } +; + +int_list: + INT { + $$.a = new any (Config::IntList ()); + $$.il = any_cast ($$.a); + $$.il->push_back ($1); + } + | int_list INT { + $1.il->push_back ($2); + $$ = $1; + } +; + +%% + +void yyerror (const char *e) +{ + std::cerr << e << std::endl; +} + +/* Shut up warning for this wrongly declared static function. */ +static int +yy_init_globals (yyscan_t yyscanner) +{ + return yy_init_globals (yyscanner); +} + diff --git a/2005/i/robert/src/config/parser_extra.hh b/2005/i/robert/src/config/parser_extra.hh new file mode 100644 index 0000000..aa5f80f --- /dev/null +++ b/2005/i/robert/src/config/parser_extra.hh @@ -0,0 +1,47 @@ +#ifndef parser_extra_hh +#define parser_extra_hh +// parser_extra.hh +// robert - programme du robot 2005. {{{ +// +// Copyright (C) 2005 Nicolas Schodet +// +// Robot APB Team/Efrei 2005. +// 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 + +class ConfigData; + +/// Structure d'information passée au parser. +struct ParserExtra +{ + /// Chaîne temporaire utilisée pendant l'analyse lexicale. + std::string tmp; + /// Référence vers le ConfigData qui doit recevoir la configuration. + ConfigData &configData; + public: + /// Constructeur pour initialiser la référence. + ParserExtra (ConfigData &configData_) + : configData (configData_) + { } +}; + +#define YY_EXTRA_TYPE ParserExtra * + +#endif // parser_extra_hh diff --git a/2005/i/robert/src/config/test_config_data.cc b/2005/i/robert/src/config/test_config_data.cc new file mode 100644 index 0000000..87e36ea --- /dev/null +++ b/2005/i/robert/src/config/test_config_data.cc @@ -0,0 +1,44 @@ +// test_config_data.cc +// robert - programme du robot 2005. {{{ +// +// Copyright (C) 2005 Nicolas Schodet +// +// Robot APB Team/Efrei 2005. +// 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_data.hh" + +int +main (int argc, char **argv) +{ + try + { + ConfigData cd (argc, argv); + for (int i = 1; i < argc; ++i) + { + std::cout << cd.get (argv[i]) << std::endl; + } + } + catch (const std::exception &e) + { + std::cerr << e.what () << std::endl; + return 1; + } + return 0; +} -- cgit v1.2.3