From deb83ba347b13c6245131d2dbf25b70e53f92d05 Mon Sep 17 00:00:00 2001
From: Arthur Redondy <redondy@enseirb-matmeca.fr>
Date: Fri, 27 Mar 2009 20:47:42 +0000
Subject: [PATCH] amelioration de la gestion des erreurs et des warnings du
 parser + amelioration de la robustesse du parser + petites autres
 modifications dans le parser

---
 src/message/Errors.cpp                 | 31 +++++++++++++---------
 src/message/Errors.hpp                 | 36 +++++++++++++++++++++++---
 src/parser/Definition.cpp              | 14 ++++++++++
 src/parser/Definition.hpp              |  8 ++++--
 src/parser/Line.hpp                    |  1 -
 src/parser/ParserDefinitionDecoder.cpp | 19 +++++++++-----
 src/parser/ParserEventDecoder.cpp      | 18 ++++++-------
 src/parser/ParserEventDecoder.hpp      |  1 -
 src/parser/ParserPaje.cpp              | 19 ++++++++------
 src/parser/TokenSource.cpp             | 25 +++++++++---------
 src/parser/TokenSource.hpp             |  2 +-
 11 files changed, 117 insertions(+), 57 deletions(-)

diff --git a/src/message/Errors.cpp b/src/message/Errors.cpp
index 42dc78c3..6e65f52c 100644
--- a/src/message/Errors.cpp
+++ b/src/message/Errors.cpp
@@ -5,31 +5,38 @@ using namespace std;
 std::queue<std::string> Error::_errors;
 std::queue<std::string> Error::_warnings;
 
+const string Error::_PARSE = "expected \" before end of file";
+const string Error::_MMAP = "mmap error";
+const string Error::_EMPTY_FILE = "empty file";
+const string Error::_FSTAT = "status file error";
+const string Error::_OPEN = "open file error";
+const string Error::_MUNMAP = "munmap error";
 const string Error::_EXPECT_END_DEF = "expected %EndEventDef";
 const string Error::_EXPECT_EVENT_DEF = "expected %EventDef";
 const string Error::_EXPECT_NAME_DEF = "the definition is not named";
 const string Error::_EXPECT_ID_DEF = "the definition is not identified";
+const string Error::_UNKNOWN_ID_DEF = "there is no definition with the identity: ";
 const string Error::_EXTRA_TOKEN_IN_DEF = "there are too much token";
-const string Error::_UNKNOWN_EVENT_DEF = "unknown fields on event ";
+const string Error::_UNKNOWN_EVENT_DEF = "the following event doesn't match with any event known: ";
 const string Error::_FIELD_TYPE_MISSING = "a field type is missing ";
 const string Error::_FIELD_TYPE_UNKNOWN = "a field type is unknown ";
 const string Error::_EMPTY_DEF = "a definition line is empty";
-const string Error::_INCOMPATIBLE_VALUE_IN_EVENT = "incompatible value : ";
+const string Error::_INCOMPATIBLE_VALUE_IN_EVENT = "incompatible value: ";
 const string Error::_UNKNOWN_TYPE_IN_EVENT = "unknown type : ";
-const string Error::_UNKNOWN_EVENT_IN_PARSER_DEF_NOT_FOUND = "unknown field for the event. Should have been found on the definition parser : ";
-const string Error::_UNKNOWN_LINE = "the content of the line is unknown, must quit";
+const string Error::_UNKNOWN_EVENT_IN_PARSER_DEF_NOT_FOUND = "unknown event name: ";
 const string Error::_BAD_FILE_EXTENSION = "the extension of the file is not .trace";
 const string Error::_LINE_TOO_LONG_EVENT = "extra token(s)";
+const string Error::_LINE_TOO_SHORT_EVENT = "missing field value(s) in an event";
 
 const string Error::_UNKNOWN_CONTAINER_TYPE = "Unknown container type : ";
-const string Error::_UNKNOWN_CONTAINER = "Unknown container : ";
-const string Error::_UNKNOWN_EVENT_TYPE = "Unknown event type : ";
-const string Error::_UNKNOWN_EVENT = "Unknown event : ";
-const string Error::_UNKNOWN_STATE_TYPE = "Unknown state type : ";
-const string Error::_UNKNOWN_VARIABLE_TYPE = "Unknown variable type : ";
-const string Error::_UNKNOWN_LINK_TYPE = "Unknown link type : ";
-const string Error::_UNKNOWN_ENTITY_TYPE = "Unknown entity type : ";
-const string Error::_UNKNOWN_ENTITY_VALUE = "Unknown entity value : ";
+const string Error::_UNKNOWN_CONTAINER = "Unknown container: ";
+const string Error::_UNKNOWN_EVENT_TYPE = "Unknown event type: ";
+const string Error::_UNKNOWN_EVENT = "Unknown event: ";
+const string Error::_UNKNOWN_STATE_TYPE = "Unknown state type: ";
+const string Error::_UNKNOWN_VARIABLE_TYPE = "Unknown variable type: ";
+const string Error::_UNKNOWN_LINK_TYPE = "Unknown link type: ";
+const string Error::_UNKNOWN_ENTITY_TYPE = "Unknown entity type: ";
+const string Error::_UNKNOWN_ENTITY_VALUE = "Unknown entity value: ";
 
 int Error::_priority_printable_min;
 
diff --git a/src/message/Errors.hpp b/src/message/Errors.hpp
index 4b4265c2..a14ee6e1 100644
--- a/src/message/Errors.hpp
+++ b/src/message/Errors.hpp
@@ -50,6 +50,30 @@ public:
     /*
      * Kind of errors known
      */
+    /*!
+     * \brief Define the error when expected the character " (before the end of the file).
+     */
+    const static std::string _PARSE;
+    /*!
+     * \brief Define the error when the mmap function fails.
+     */
+    const static std::string _MMAP;
+    /*!
+     * \brief Define the error when the file is empty.
+     */
+    const static std::string _EMPTY_FILE;
+    /*!
+     * \brief Define the error when the fstat function fails.
+     */
+    const static std::string _FSTAT;
+    /*!
+     * \brief Define the error when the open function fails.
+     */
+    const static std::string _OPEN;
+    /*!
+     * \brief Define the error when the munmap function fails.
+     */
+    const static std::string _MUNMAP;
     /*!
      * \brief Define the error when missing the end of a definition.
      */
@@ -66,6 +90,10 @@ public:
      * \brief Define the error when missing the identity of a definition.
      */
     const static std::string _EXPECT_ID_DEF;
+    /*!
+     * \brief Define the error when the identity of a definition doesn't match with any definition defined.
+     */
+    const static std::string _UNKNOWN_ID_DEF;
     /*!
      * \brief Define the error when some extra characters are ignored at the end of a line in a definition.
      */
@@ -98,10 +126,6 @@ public:
      * \brief Define the error when an event is not reconized by the parser.
      */
     const static std::string _UNKNOWN_EVENT_IN_PARSER_DEF_NOT_FOUND;
-    /*!
-     * \brief Define the error when the parser can't parse a line.
-     */
-    const static std::string _UNKNOWN_LINE;
     /*!
      * \brief Define the error when the file which has to be parse doesn't have the right extension.
      */
@@ -110,6 +134,10 @@ public:
      * \brief Define the error when some extra characters are ignored at the end of the line event.
      */
     const static std::string _LINE_TOO_LONG_EVENT;
+    /*!
+     * \brief Define the error when some field values are missing for an event.
+     */
+    const static std::string _LINE_TOO_SHORT_EVENT;
 
     //////
     /// Errors from undefined entities
diff --git a/src/parser/Definition.cpp b/src/parser/Definition.cpp
index 20467e50..5bb1122a 100644
--- a/src/parser/Definition.cpp
+++ b/src/parser/Definition.cpp
@@ -27,7 +27,21 @@ void Definition::print() const{
 	cout << " " << _fields[i]._name << " " << _fields[i]._type << endl;
     }
     cout << "______" << endl;
+}
+
+string Definition::print_string() const{
+    string definition ("");
+    definition += _event_name;
 
+    const unsigned int field_size = _fields.size();
+    for(unsigned int i = 0 ; i < field_size ; i ++){
+	definition += "\n";
+        definition += _fields[i]._name;
+        definition += " ";
+        definition += _fields[i]._type;
+    }
+    definition += "\n";
+    return definition;
 }
 
 const vector<Field> &Definition::get_fields() const{
diff --git a/src/parser/Definition.hpp b/src/parser/Definition.hpp
index 825fc77f..54646115 100644
--- a/src/parser/Definition.hpp
+++ b/src/parser/Definition.hpp
@@ -65,8 +65,6 @@ public:
      */
     void store(std::string name, std::string type);
 
-
-
     /*!
      * \fn print() const
      * \brief display the definitions
@@ -74,6 +72,12 @@ public:
      */
     void print() const;
 
+    /*!
+     * \fn print() const
+     * \brief display the definitions in a string
+     * \return the string with informations about the definition
+     */
+    std::string print_string() const;
 
     /*!
      * \fn : get_fields() const
diff --git a/src/parser/Line.hpp b/src/parser/Line.hpp
index 8a722a90..d9926c21 100644
--- a/src/parser/Line.hpp
+++ b/src/parser/Line.hpp
@@ -8,7 +8,6 @@
 
 #include "TokenSource.hpp"
 
-#define BUFFSIZE 256
 
 
 /*! \class Line Line.hpp "../parser/src/Line.hpp"
diff --git a/src/parser/ParserDefinitionDecoder.cpp b/src/parser/ParserDefinitionDecoder.cpp
index 330193bc..dab13048 100644
--- a/src/parser/ParserDefinitionDecoder.cpp
+++ b/src/parser/ParserDefinitionDecoder.cpp
@@ -13,13 +13,15 @@ int ParserDefinitionDecoder::definitions_number(){
 void ParserDefinitionDecoder::enter_definition(Line &line){
     
     if(_state == _IN_A_DEFINITION){
-        Error::set_and_print(Error::_EXPECT_EVENT_DEF, line.get_line_count(), Error::_ERROR);
+        Error::set_and_print(Error::_EXPECT_END_DEF, line.get_line_count(), Error::_WARNING);
+        leave_definition(line);
     }
 
     string definition_name;
 
     if(!line.item(2, definition_name)){
         Error::set_and_print(Error::_EXPECT_NAME_DEF, line.get_line_count(), Error::_ERROR);
+        return;
     }
   
     unsigned int definition_identity;
@@ -50,19 +52,16 @@ void ParserDefinitionDecoder::enter_definition(Line &line){
 void ParserDefinitionDecoder::leave_definition(Line &line){
     
     if(_state != _IN_A_DEFINITION){
-        Error::set_and_print(Error::_EXPECT_EVENT_DEF, line.get_line_count(), Error::_ERROR);
+        Error::set_and_print(Error::_EXPECT_EVENT_DEF, line.get_line_count(), Error::_WARNING);
         return;
     }
     
     _state = _OUT_A_DEFINITION;
     if(!_definitions[_current_definition].check_definition()){
-        Error::set_and_print(Error::_UNKNOWN_EVENT_DEF + _definitions[_current_definition].get_event_name(), line.get_line_count(), Error::_ERROR);
+        Error::set_and_print(Error::_UNKNOWN_EVENT_DEF + _definitions[_current_definition].print_string(), line.get_line_count(), Error::_ERROR);
+       _definitions.erase(_current_definition);
         return;
     }
-
-    if(line.length() > 2){
-        Error::set_and_print(Error::_EXTRA_TOKEN_IN_DEF, line.get_line_count(), Error::_WARNING);
-    }
 }
 
 void ParserDefinitionDecoder::add_field_to_definition(std::string& first_token,Line& line){
@@ -100,6 +99,9 @@ void ParserDefinitionDecoder::store_definition(Line &line){
     }
     else if (first_token == "EndEventDef"){
         leave_definition(line);
+        if(line.length() > 2){
+            Error::set_and_print(Error::_EXTRA_TOKEN_IN_DEF, line.get_line_count(), Error::_WARNING);
+    }
     }
     else{
         add_field_to_definition(first_token,line);
@@ -108,6 +110,9 @@ void ParserDefinitionDecoder::store_definition(Line &line){
 }
 
 Definition& ParserDefinitionDecoder::get_definition(unsigned int i){
+    if (_definitions.count(i) != 1) {
+        throw i;
+    }
     return _definitions[i];
 }
 
diff --git a/src/parser/ParserEventDecoder.cpp b/src/parser/ParserEventDecoder.cpp
index b81f9768..6da8c8b1 100644
--- a/src/parser/ParserEventDecoder.cpp
+++ b/src/parser/ParserEventDecoder.cpp
@@ -34,7 +34,7 @@ void ParserEventDecoder::store_event(const Definition &definition, Line &line, T
 
         string current_value;
         if (!line.item(i, current_value)) {
-            Error::set_and_print(Error::_INCOMPATIBLE_VALUE_IN_EVENT + current_value, line.get_line_count(), Error::_WARNING);
+            Error::set_and_print(Error::_LINE_TOO_SHORT_EVENT, line.get_line_count(), Error::_WARNING);
             return;
         }
 
@@ -66,7 +66,7 @@ void ParserEventDecoder::store_event(const Definition &definition, Line &line, T
 
         else if (fields[i-1]._name == "Time") {
             if(!Date::instantiate(current_value, time)) {
-                Error::set_and_print(Error::_INCOMPATIBLE_VALUE_IN_EVENT + current_value, line.get_line_count(), Error::_WARNING);
+                Error::set_and_print(Error::_INCOMPATIBLE_VALUE_IN_EVENT + current_value + " (expecting a \"date\")", line.get_line_count(), Error::_WARNING);
                 return;
             }
         }
@@ -82,7 +82,7 @@ void ParserEventDecoder::store_event(const Definition &definition, Line &line, T
         else if (fields[i-1]._name == "Value") {
             if(fields[i-1]._type == "double") {
                 if(!Double::instantiate(current_value, value_double)) {
-                    Error::set_and_print(Error::_INCOMPATIBLE_VALUE_IN_EVENT + current_value, line.get_line_count(), Error::_WARNING);
+                    Error::set_and_print(Error::_INCOMPATIBLE_VALUE_IN_EVENT + current_value + " (expecting a \"double\")", line.get_line_count(), Error::_WARNING);
                     return;
                 }
             }
@@ -110,7 +110,7 @@ void ParserEventDecoder::store_event(const Definition &definition, Line &line, T
             else if(fields[i-1]._type == "double") {
                 Double value;
                 if(!Double::instantiate(current_value, value)) {
-                    Error::set_and_print(Error::_INCOMPATIBLE_VALUE_IN_EVENT + current_value, line.get_line_count(), Error::_WARNING);
+                    Error::set_and_print(Error::_INCOMPATIBLE_VALUE_IN_EVENT + current_value + " (expecting a \"double\")", line.get_line_count(), Error::_WARNING);
                     return;
                 }
                 extra_fields[fields[i-1]._name] = new Double(value);
@@ -118,7 +118,7 @@ void ParserEventDecoder::store_event(const Definition &definition, Line &line, T
             else if(fields[i-1]._type == "hex") {
                 Hex value;
                 if(!Hex::instantiate(current_value, value)) {
-                    Error::set_and_print(Error::_INCOMPATIBLE_VALUE_IN_EVENT + current_value, line.get_line_count(), Error::_WARNING);
+                    Error::set_and_print(Error::_INCOMPATIBLE_VALUE_IN_EVENT + current_value + " (expecting a \"hex\")", line.get_line_count(), Error::_WARNING);
                     return;
                 }
                 extra_fields[fields[i-1]._name] = new Hex(value);
@@ -126,7 +126,7 @@ void ParserEventDecoder::store_event(const Definition &definition, Line &line, T
             else if(fields[i-1]._type == "date") {
                 Date value;
                 if(!Date::instantiate(current_value, value)) {
-                    Error::set_and_print(Error::_INCOMPATIBLE_VALUE_IN_EVENT + current_value, line.get_line_count(), Error::_WARNING);
+                    Error::set_and_print(Error::_INCOMPATIBLE_VALUE_IN_EVENT + current_value + " (expecting a \"date\")", line.get_line_count(), Error::_WARNING);
                     return;
                 }
                 extra_fields[fields[i-1]._name] = new Date(value);
@@ -134,7 +134,7 @@ void ParserEventDecoder::store_event(const Definition &definition, Line &line, T
             else if(fields[i-1]._type == "int") {
                 Integer value;
                 if(!Integer::instantiate(current_value, value)) {
-                    Error::set_and_print(Error::_INCOMPATIBLE_VALUE_IN_EVENT + current_value, line.get_line_count(), Error::_WARNING);
+                    Error::set_and_print(Error::_INCOMPATIBLE_VALUE_IN_EVENT + current_value + " (expecting an \"int\")", line.get_line_count(), Error::_WARNING);
                     return;
                 }
                 extra_fields[fields[i-1]._name] = new Integer(value);
@@ -142,13 +142,13 @@ void ParserEventDecoder::store_event(const Definition &definition, Line &line, T
             else if(fields[i-1]._type == "color") {
                 Color value;
                 if(!Color::instantiate(current_value, value)) {
-                    Error::set_and_print(Error::_INCOMPATIBLE_VALUE_IN_EVENT + current_value, line.get_line_count(), Error::_WARNING);
+                    Error::set_and_print(Error::_INCOMPATIBLE_VALUE_IN_EVENT + current_value + " (expecting a \"color\")", line.get_line_count(), Error::_WARNING);
                     return;
                 }
                 extra_fields[fields[i-1]._name] = new Color(value);
             }
             else {
-                Error::set_and_print(Error::_UNKNOWN_TYPE_IN_EVENT + current_value, line.get_line_count(), Error::_WARNING);
+                Error::set_and_print(Error::_UNKNOWN_TYPE_IN_EVENT + fields[i-1]._type, line.get_line_count(), Error::_WARNING);
                 return;
             }
         }
diff --git a/src/parser/ParserEventDecoder.hpp b/src/parser/ParserEventDecoder.hpp
index 613dd1d1..a21c083a 100644
--- a/src/parser/ParserEventDecoder.hpp
+++ b/src/parser/ParserEventDecoder.hpp
@@ -8,7 +8,6 @@
 #include "Line.hpp"
 
 #ifndef VITE_DEBUG
-  #include "../trace/values/Values.hpp"
   #include "../trace/Trace.hpp"
   #include "../message/Errors.hpp"
 #else
diff --git a/src/parser/ParserPaje.cpp b/src/parser/ParserPaje.cpp
index 0d8c9f8a..e007bf4b 100644
--- a/src/parser/ParserPaje.cpp
+++ b/src/parser/ParserPaje.cpp
@@ -31,15 +31,18 @@ void ParserPaje::parse(string filename, Trace &trace){
     	else {
             // We check if we have an event identifier
             if(sscanf(event_identity_string.c_str(), "%d", &event_identity) != 1){
-                Error::set_and_print(Error::_EXPECT_ID_DEF, line.get_line_count(), Error::_ERROR);
-                // We flush the errors
-                Error::flush_in_file("log.txt");
-                
-                // The line can not be recognised by the parser Paje, we can not continue.
-                throw Error::_UNKNOWN_LINE;
-                //return ;
+                Error::set_and_print(Error::_EXPECT_ID_DEF, line.get_line_count(), Error::_WARNING);
+                continue;
             }
-            parserevent->store_event(parserdefinition->get_definition(event_identity),
+            Definition current_definition;
+            try {
+                current_definition = parserdefinition->get_definition(event_identity);
+            }
+            catch (unsigned int) {
+                Error::set_and_print(Error::_UNKNOWN_ID_DEF + event_identity_string, line.get_line_count(), Error::_WARNING);
+                continue;
+            }
+            parserevent->store_event(current_definition,
                                      line,
                                      trace);
         }
diff --git a/src/parser/TokenSource.cpp b/src/parser/TokenSource.cpp
index 17fa7051..b4f54de7 100644
--- a/src/parser/TokenSource.cpp
+++ b/src/parser/TokenSource.cpp
@@ -18,7 +18,7 @@ TokenSource::~TokenSource(){
     _file.close();
 #else
      if (munmap(_buffer, _filesize) == -1){
-       *Message::get_instance() << "munmap error" << Message::endw;
+       Error::set_and_print(Error::_MUNMAP, Error::_WARNING);
      }
      close(_fd);
 #endif
@@ -34,25 +34,26 @@ void TokenSource::open(const char *filename){
     fill_buffer();
 #else
     if ((_fd = ::open(filename, O_RDONLY)) == -1){
-      *Message::get_instance() << "open file error" << Message::ende; 
-      exit(-1);
+      //Error::set_and_print(Error::_OPEN, Error::_ERROR);
+      throw Error::_OPEN;
     }
 
     struct stat buf;
     if(fstat(_fd, &buf) == -1){
-      *Message::get_instance() << "status file error" << Message::ende; 
-      exit(-1);
+      //Error::set_and_print(Error::_FSTAT, Error::_ERROR);
+      throw Error::_FSTAT;
     }
 
     _filesize = buf.st_size;
 
     if(_filesize == 0){
-      *Message::get_instance() << "empty file" << Message::endw;
+      //Error::set_and_print(Error::_EMPTY_FILE, Error::_ERROR);
+      throw Error::_EMPTY_FILE;
     }
 
     if ((_buffer = (char *)mmap(0, _filesize, PROT_READ, MAP_PRIVATE, _fd, 0)) == MAP_FAILED){
-      *Message::get_instance() << "mmap error" << Message::ende;
-      exit(-1);
+      //Error::set_and_print(Error::_MMAP, Error::_ERROR);
+      throw Error::_MMAP;
     }
 #endif
 }
@@ -95,15 +96,15 @@ void TokenSource::build_composite_token() {
 #ifdef WIN32
     if (_cursor == _buffer_size) {
         if (!fill_buffer()) {
-	        *Message::get_instance() << "found \" at end of file" << Message::endw;
-            return;
+	    Error::set_and_print(Error::_FSTAT, Error::_WARNING);
+	    return;
         }
         _cursor = 0;
     }
 #else
     if (ensure_capacity()){
-      *Message::get_instance() << "found \" at end of file" << Message::endw;
-      return;
+        Error::set_and_print(Error::_FSTAT, Error::_WARNING);
+	return;
     }
 #endif
     do {
diff --git a/src/parser/TokenSource.hpp b/src/parser/TokenSource.hpp
index e6e9e85c..5527b9cf 100644
--- a/src/parser/TokenSource.hpp
+++ b/src/parser/TokenSource.hpp
@@ -4,7 +4,7 @@
 #include <string>
 #include <iostream>
 
-#include "../message/Message.hpp"
+#include "../message/Errors.hpp"
 
 #ifdef WIN32 // They do not have mmap
     #define BUFFER_SIZE 2048
-- 
GitLab