From 426194305cecf47c4f6ee27d6c2f3431de61f630 Mon Sep 17 00:00:00 2001 From: schodet Date: Tue, 5 Apr 2005 22:04:03 +0000 Subject: Fix du test pour les IntList. FloatList en double (oui, le nom est trompeur). Bug avec str. Parsage de chaîne et changement de la règle "input". Support des commentaires. --- 2005/i/robert/src/config/config.hh | 2 +- 2005/i/robert/src/config/config_data.cc | 49 +++++++++++++++++++++++----- 2005/i/robert/src/config/config_data.hh | 10 ++++-- 2005/i/robert/src/config/lexer.ll | 19 ++++++----- 2005/i/robert/src/config/parser.yy | 6 ++-- 2005/i/robert/src/config/test_config_data.cc | 17 +++++++++- 6 files changed, 79 insertions(+), 24 deletions(-) (limited to '2005/i/robert/src/config') diff --git a/2005/i/robert/src/config/config.hh b/2005/i/robert/src/config/config.hh index 55263a4..766a70f 100644 --- a/2005/i/robert/src/config/config.hh +++ b/2005/i/robert/src/config/config.hh @@ -33,7 +33,7 @@ class Config { public: typedef std::list IntList; - typedef std::list FloatList; + typedef std::list FloatList; typedef std::list StringList; }; diff --git a/2005/i/robert/src/config/config_data.cc b/2005/i/robert/src/config/config_data.cc index e737bed..33a78c0 100644 --- a/2005/i/robert/src/config/config_data.cc +++ b/2005/i/robert/src/config/config_data.cc @@ -22,9 +22,9 @@ // 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 "config.hh" +#include "config_data.hh" +#include "parser_extra.hh" #include "parser.hh" #include "lexer.hh" @@ -35,14 +35,14 @@ /// ligne de commande. ConfigData::ConfigData (int &argc, char **&argv) { - parse ("rc/config"); + init (argc, argv, "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); + init (argc, argv, file); } /// Récupère une valeur de configuration. @@ -64,11 +64,18 @@ ConfigData::add (const std::string &id, any &val) a.swap (val); } +/// Initialise (lit la ligne de commande et les fichiers de config. +void +ConfigData::init (int &argc, char **&argv, const std::string &file) +{ + parseFile (file); +} + int yyparse (void *); -/// Lance le parseur. +/// Lance le parseur sur un fichier. void -ConfigData::parse (const std::string &file) +ConfigData::parseFile (const std::string &file) { FILE *f; f = fopen (file.c_str (), "r"); @@ -76,7 +83,7 @@ ConfigData::parse (const std::string &file) throw std::runtime_error ("can not open config file \"" + file + "\""); try { - // Crée un scaner, initialise son tampon d'entré, puis parse. + // Crée un scanner, initialise son tampon d'entré, puis parse. yyscan_t scanner; YY_BUFFER_STATE buf; ParserExtra pe (*this); @@ -99,6 +106,32 @@ ConfigData::parse (const std::string &file) fclose (f); } +/// Lance le parseur sur une chaîne. +void +ConfigData::parseString (const std::string &s) +{ + try + { + // Crée un scanner, 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_scan_bytes (s.data (), s.size (), 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) + { + throw std::runtime_error ("in config string \"" + s + "\": " + + e.what ()); + } +} + /* Shut up warning for this wrongly declared static function. */ static int yy_init_globals (yyscan_t yyscanner) diff --git a/2005/i/robert/src/config/config_data.hh b/2005/i/robert/src/config/config_data.hh index bf62bd8..0d0944e 100644 --- a/2005/i/robert/src/config/config_data.hh +++ b/2005/i/robert/src/config/config_data.hh @@ -56,10 +56,14 @@ class ConfigData template void add (const std::string &id, const T &val); private: - /// Lance le parseur. - void parse (const std::string &file); + /// Initialise (lit la ligne de commande et les fichiers de config. + void init (int &argc, char **&argv, const std::string &file); + /// Lance le parseur sur un fichier. + void parseFile (const std::string &file); + /// Lance le parseur sur une chaîne. + void parseString (const std::string &s); }; -#include "config/config_data.tcc" +#include "config_data.tcc" #endif // config_data_hh diff --git a/2005/i/robert/src/config/lexer.ll b/2005/i/robert/src/config/lexer.ll index 93173f9..96a90b3 100644 --- a/2005/i/robert/src/config/lexer.ll +++ b/2005/i/robert/src/config/lexer.ll @@ -34,7 +34,7 @@ %option bison-bridge %option noyywrap nodefault nounput -%x str +%x strst INTDEC [+-]?[0-9]+ INTHEX "0x"[0-9a-fA-F]+ @@ -71,7 +71,7 @@ FLOATNUM {FLOAT1}|{FLOAT2} } \" { - BEGIN(str); + BEGIN(strst); yyextra->tmp.clear (); } @@ -81,6 +81,7 @@ FLOATNUM {FLOAT1}|{FLOAT2} "data:" return DATA; [ \t]+ /* Skip. */ +#.* /* Skip comments. */ . { yylval->c = yytext[0]; @@ -88,18 +89,18 @@ FLOATNUM {FLOAT1}|{FLOAT2} 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 { +\\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; } diff --git a/2005/i/robert/src/config/parser.yy b/2005/i/robert/src/config/parser.yy index fe1ca60..4bd744f 100644 --- a/2005/i/robert/src/config/parser.yy +++ b/2005/i/robert/src/config/parser.yy @@ -78,8 +78,8 @@ void yyerror (const char *); %% input: - /* Nothing. */ - | input confitem '\n' + confitem + | input '\n' confitem | input '\n' ; @@ -130,3 +130,5 @@ yy_init_globals (yyscan_t yyscanner) return yy_init_globals (yyscanner); } +/* vim:ft=yacc: +*/ diff --git a/2005/i/robert/src/config/test_config_data.cc b/2005/i/robert/src/config/test_config_data.cc index 87e36ea..49fc425 100644 --- a/2005/i/robert/src/config/test_config_data.cc +++ b/2005/i/robert/src/config/test_config_data.cc @@ -23,6 +23,10 @@ // // }}} #include "config_data.hh" +#include "config.hh" + +#include +#include int main (int argc, char **argv) @@ -32,7 +36,18 @@ main (int argc, char **argv) ConfigData cd (argc, argv); for (int i = 1; i < argc; ++i) { - std::cout << cd.get (argv[i]) << std::endl; + const any &a = cd.get (argv[i]); + if (a.type () == typeid (Config::IntList)) + { + const Config::IntList &il = any_cast (a); + std::copy (il.begin (), il.end (), + std::ostream_iterator (std::cout, " ")); + std::cout << std::endl; + } + else + { + std::cout << cd.get (argv[i]) << std::endl; + } } } catch (const std::exception &e) -- cgit v1.2.3