Commit ed35063b authored by Mathieu Faverge's avatar Mathieu Faverge

Update the ViTe parser / still have to correct some little memory leaks and...

Update the ViTe parser / still have to correct some little memory leaks and the error handler need really to be changed
parent 8fda7ef6
......@@ -48,7 +48,6 @@ SET(VITE_HDRS
common/Tools.hpp
common/Info.hpp
common/Session.hpp
common/trace.h
common/Memory.hpp
# Data structure headers
trace/values/Color.hpp
......
......@@ -47,8 +47,7 @@
#include <sstream>
#include <queue>
/* -- */
#include <QObject>
#define MyString(str) QObject::tr(str).toStdString()
#include "common.hpp"
/* -- */
#include "interface/Interface.hpp"
/* -- */
......@@ -67,45 +66,46 @@ const int Error::_EVERYTHING = 0;
const int Error::_WARNING = 1;
const int Error::_ERROR = 2;
string Error::_content = MyString("");
const string Error::_PARSE = MyString("expected \" before end of file");
const string Error::_MMAP = MyString("mmap error");
const string Error::_EMPTY_FILE = MyString("empty file");
const string Error::_FSTAT = MyString("status file error");
const string Error::_OPEN = MyString("open file error");
const string Error::_MUNMAP = MyString("munmap error");
const string Error::_EXPECT_END_DEF = MyString("expected %EndEventDef");
const string Error::_EXPECT_EVENT_DEF = MyString("expected %EventDef");
const string Error::_EXPECT_NAME_DEF = MyString("the definition is not named");
const string Error::_EXPECT_ID_DEF = MyString("the definition is not identified");
const string Error::_UNKNOWN_ID_DEF = MyString("there is no definition with the identity: ");
const string Error::_EXTRA_TOKEN = MyString("extra token(s) ignored");
const string Error::_UNKNOWN_EVENT_DEF = MyString("the following event doesn't match with any event known: ");
const string Error::_FIELD_TYPE_MISSING = MyString("a field type is missing ");
const string Error::_FIELD_TYPE_UNKNOWN = MyString("the following field type is unknown: ");
const string Error::_EMPTY_DEF = MyString("a definition line is empty");
const string Error::_INCOMPATIBLE_VALUE_IN_EVENT = MyString("incompatible value: ");
const string Error::_BAD_FILE_EXTENSION = MyString("the extension of the file is not .trace");
const string Error::_LINE_TOO_SHORT_EVENT = MyString("missing field value(s) in an event");
const string Error::_UNKNOWN_CONTAINER_TYPE = MyString("Unknown container type: ");
const string Error::_UNKNOWN_CONTAINER = MyString("Unknown container: ");
const string Error::_UNKNOWN_EVENT_TYPE = MyString("Unknown event type: ");
const string Error::_UNKNOWN_STATE_TYPE = MyString("Unknown state type: ");
const string Error::_UNKNOWN_VARIABLE_TYPE = MyString("Unknown variable type: ");
const string Error::_UNKNOWN_LINK_TYPE = MyString("Unknown link type: ");
const string Error::_UNKNOWN_ENTITY_TYPE = MyString("Unknown entity type: ");
const string Error::_UNKNOWN_ENTITY_VALUE = MyString("Unknown entity value: ");
const string Error::_EVENT_ALREADY_DEF = MyString("Event trid is already defined");
const string Error::_FIELD_NAME_MISSING = MyString("Field's name is missing");
const string Error::_FIELD_NOT_ALLOWED = MyString("This type is not allowed for this field");
const string Error::_EVENT_NOT_CORRECT = MyString("The definition of this event is not correct : ");
string Error::_content = "";
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 = "extra token(s) ignored";
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 = "the following 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::_BAD_FILE_EXTENSION = "the extension of the file is not .trace";
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_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::_EVENT_ALREADY_DEF = "Event trid is already defined";
const string Error::_FIELD_NAME_MISSING = "Field's name is missing";
const string Error::_FIELD_NOT_ALLOWED = "This type is not allowed for this field";
const string Error::_EVENT_NOT_CORRECT = "The definition of this event is not correct : ";
void Error::set(const string kind_of_error, const int priority){
Error::_content = kind_of_error;
switch(priority){
case _WARNING:
Error::_warnings.push(Error::_content);
......
......@@ -46,12 +46,16 @@
** The defines and includes.
*/
#ifndef MAX
#define MAX(a,b) ( a > b ) ? a : b
#endif
#ifdef MEMORY_USAGE
#include <cstdio>
#include <iostream>
#include "common/common.hpp"
#include "common/trace.h"
#include "common/TraceMemory.hpp"
#include "common/Tools.hpp"
#if (defined _PTHREAD_H) || (defined MEMORY_THREADED)
#include <pthread.h>
......
......@@ -44,8 +44,10 @@
#include <iostream>
#include <sstream>
/* -- */
#include <QObject>
#include "common.hpp"
/* -- */
#ifdef VITE_DEBUG
/* Test mode */
class Interface {
......@@ -122,7 +124,7 @@ std::ostream &operator<<(std::ostream &out, Message::end_error_t) {
interface->error(message->str());
message->str(""); // flush the stream
} else {
std::cerr << QObject::tr("Warning: no interface designed to display messages.").toStdString() << std::endl;
vite_error("Warning: no interface designed to display messages.");
}
return out;
}
......@@ -135,7 +137,7 @@ std::ostream &operator<<(std::ostream &out, Message::end_warning_t) {
interface->warning(message->str());
message->str(""); // flush the stream
} else {
std::cerr << QObject::tr("Warning: no interface designed to display messages.").toStdString() << std::endl;
vite_error("Warning: no interface designed to display messages.");
}
return out;
}
......@@ -148,7 +150,7 @@ std::ostream &operator<<(std::ostream &out, Message::end_information_t) {
interface->information(message->str());
message->str(""); // flush the stream
} else {
std::cerr << QObject::tr("Warning: no interface designed to display messages.").toStdString() << std::endl;
vite_error("Warning: no interface designed to display messages.");
}
return out;
}
......@@ -162,7 +164,7 @@ std::ostream &operator<<(std::ostream &out, Message::end_selection_information_t
interface->selection_information(message->str());
message->str(""); // flush the stream
} else {
std::cerr << QObject::tr("Warning: no interface designed to display messages.").toStdString() << std::endl;
vite_error("Warning: no interface designed to display messages.");
}
return out;
}
......@@ -44,13 +44,10 @@
#include <cstdio>
#include <iostream>
/* -- */
#include <QString>
#include <QFileInfo>
#include <QObject> // For translations
/* -- */
#include <locale.h> // For dots or commas separator in double numbers
#include <time.h>
/* -- */
#include "common.hpp"
#include "Tools.hpp"
/* -- */
using namespace std;
......@@ -74,14 +71,14 @@ double convert_to_double(const string arg){
if(is_english_system_needed) {
if((setlocale(LC_NUMERIC, "C") == NULL) &&
(setlocale(LC_NUMERIC, "en_GB.UTF-8") == NULL)){
cerr << QObject::tr("The locale en_GB.UTF-8 is unavailable so the decimal pointed will not be printed").toStdString() << endl;
vite_warning("The locale en_GB.UTF-8 is unavailable so the decimal pointed will not be printed");
}
}
else {
if ((setlocale(LC_NUMERIC, "fr_FR.UTF-8") == NULL) &&
(setlocale(LC_NUMERIC, "French") == NULL)){
cerr << QObject::tr("The locale fr_FR.UTF-8 is unavailable so the decimal with comma will not be printed").toStdString() << endl;
vite_warning("The locale fr_FR.UTF-8 is unavailable so the decimal with comma will not be printed");
}
}
......@@ -94,11 +91,6 @@ double convert_to_double(const string arg){
}
}
const QString stripped_name(const QString &fullFileName) {
return QFileInfo(fullFileName).fileName();
}
double clockGet (void)
{
#ifdef _MSC_VER
......
......@@ -48,8 +48,6 @@
#ifndef TOOLS_HPP
#define TOOLS_HPP
#include <QString>
/*!
* \fn convert_to_double(const std::string args)
* \brief Convert the string in double
......@@ -69,11 +67,4 @@ double convert_to_double(const std::string args);
*/
double clockGet (void);
/*!
* \fn stripped_name(const QString &fullFileName)
* \brief return the name of the file without its directory
* \param fullFileName the complete filename.
*/
const QString stripped_name(const QString &fullFileName);
#endif // TOOLS_HPP
/*
File: trace.h
trace instruction for different format
Authors:
Mathieu Faverge - faverge@labri.fr
Dates:
Varsion 0.0 - from 12 apr 2008
to 12 apr 2008
*/
#ifndef TRACE_H
#define TRACE_H
/**
*
* @file Trace.hpp
*
* ViTE project.
* ViTE is a Visualizer for Execution Traces provided by INRIA Bordeaux Sud-Ouest.
*
* Macros to trace ViTE memory consuption.
*
* @version 1.2.0
* @author Mathieu Faverge
* @date 2010-08-01
*
**/
#ifndef TRACEMEMORY_HPP
#define TRACEMEMORY_HPP
typedef enum Trace_State {
STATE_ALLOC = 27,
......@@ -20,20 +22,12 @@ typedef enum Trace_State {
/*
* Common part :
* - TraceFmt_t fmt : Format de trace
* - FILE *file : fichier de trace
* - double time : timestamp
* - INT procnum
* - INT thrdnum
* State :
* - INT level : niveau de trace (+il est grand plus c'est dtaill)
* - Trace_State_T state : Etat dans lequel se retrouve le proc
* - INT id : identifiant de la tche
* Comm :
* - INT dest/src : destinataire ou source du message
* - Trace_Comm_t Type : type de communication
* - INT id : identifiant du message
* - INT size : taille du message
* - FILE *file : fichier de trace
* - double time : timestamp
* - INT procnum
* - INT thrdnum
* - Trace_State_T state : ALLOC or FREE
* - INT memory : amount of memory allocated or free
*/
#define trace_start(file, time, procnum, thrdnum) \
......@@ -46,4 +40,4 @@ typedef enum Trace_State {
fprintf(file, "%9.9lf %ld 0 0 4 %ld %f\n", \
(double)time, (long)procnum, (long)state, (double)memory/(1<<20));
#endif /* TRACE_H */
#endif /* TRACEMEMORY_H */
......@@ -109,4 +109,8 @@ typedef double Times;
#define M_PI 3.14159265358979323846
#endif
/* TODO : move this somewhere else when we will have the message handler */
#define vite_warning(str) std::cerr << str << std::endl;
#define vite_error(str) std::cerr << str << std::endl;
#endif /* COMMON_H */
......@@ -982,7 +982,7 @@ void Interface_graphic::update_recent_files_menu() {
}
_recent_file_actions[i] = new QAction(this);
_recent_file_actions[i]->setVisible(true);
const QString text = tr("&%1 %2").arg(i+1).arg(stripped_name(filenames[i]));
const QString text = tr("&%1 %2").arg(i+1).arg( QFileInfo(filenames[i]).fileName() );
_recent_file_actions[i]->setText(text);
_recent_file_actions[i]->setData(filenames[i]);
connect(_recent_file_actions[i], SIGNAL(triggered()),
......
......@@ -47,8 +47,6 @@
#include <set>
#include <map>
/* -- */
#include <QObject>
/* -- */
#include "parser/PajeDefinition.hpp"
/* -- */
using namespace std;
......@@ -98,6 +96,6 @@ bool check_definition(PajeDefinition *def) {
if ( (fdpresent & def->_fdrequired) == def->_fdrequired )
return true;
else
return false;
return false;
}
}
......@@ -134,7 +134,7 @@ int PajeFileManager::get_line(PajeLine *lineptr) {
for(i = 0; (i < _PAJE_BUFSIZE) && ((c != '\n') && (c != '\0')) && (itks < _PAJE_NBMAXTKS); i++) {
c = _line[i];
switch (c) {
// It's the end of the line, we just add the end caractere
// for the last token and increase the counter
......@@ -230,7 +230,7 @@ int PajeFileManager::get_line(PajeLine *lineptr) {
break;
}
}
// We remove the last token if it is empty
if ((itks > 0) && (_tokens[itks-1][0] == '\0'))
itks--;
......@@ -239,6 +239,7 @@ int PajeFileManager::get_line(PajeLine *lineptr) {
lineptr->_id = _lineid;
lineptr->_nbtks = _nbtks;
lineptr->_tokens = _tokens;
return _lineid;
}
......
......@@ -40,7 +40,6 @@
** - VUCHENER Clément
**
*/
#include <string>
#include <map>
#include <set>
......@@ -238,7 +237,6 @@ void ParserEventPaje::store_event(const PajeLine *line,
Error::set(Error::_FIELD_TYPE_UNKNOWN, line->_id, Error::_WARNING);
return;
}
// if(!value->is_correct()) { // Check if the value is correct or not
// Error::set(Error::_INCOMPATIBLE_VALUE_IN_EVENT + fvalue + " (expecting a \"" + ftype + "\")",
......@@ -261,7 +259,6 @@ void ParserEventPaje::store_event(const PajeLine *line,
alias_name.set_alias(alias);
alias_name.set_name(name);
switch( def->_id ) {
case _PajeDefineContainerType :
{
......
......@@ -40,7 +40,7 @@
** - VUCHENER Clément
**
*/
#include <iostream>
#include <fstream>
#include <string>
#include <set>
......@@ -84,14 +84,20 @@ void ParserPaje::parse(Trace &trace,
static const string PERCENT = "%";
PajeLine_t line;
#ifdef DBG_PARSER_PAJE
int lineid = 0;
#endif
// Open the trace
try {
_file = new PajeFileManager(_file_to_parse.c_str());
} catch (const char *) {
delete _file;
_file = NULL;
_is_canceled = true;
finish();
trace.finish();
std::cerr << "Cannot open file " << _file_to_parse.c_str() << std::endl;
Error::set(Error::_OPEN, 0, Error::_WARNING);
return;
}
......@@ -99,12 +105,17 @@ void ParserPaje::parse(Trace &trace,
while( (!(_file->eof())) && !(_is_canceled) ) {
try {
_file->get_line(&line);
#ifdef DBG_PARSER_PAJE
_file->print_line();
#endif
if ( (lineid+1) == _file->get_line(&line) )
{
_file->print_line();
lineid++;
}
#else
_file->get_line(&line);
#endif
}
catch(char *){
catch(char *str){
continue;
}
......@@ -121,11 +132,14 @@ void ParserPaje::parse(Trace &trace,
_ParserEvent->store_event(&line, trace);
}
}
finish();
if(finish_trace_after_parse) {
finish();
trace.finish();
}
delete _file;
_file = NULL;
}
......
......@@ -41,6 +41,7 @@
**
*/
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
......@@ -86,7 +87,19 @@ void ParserVite::parse(Trace &trace,
PajeDefinition *def;
ParserPaje parserpaje(_file_to_parse);
int i, nblnks;
QStringList file_event_names;
QString name;
stack<Container *> CTstack;
const Container::Vector *root_containers;
const map<std::string, Value *> *extra_fields;
String *filename_String = NULL;
map<string, Value *>::const_iterator fnamefield;
// Store the abosute directory of the first file for relative path in the others
QString absdir = QFileInfo(_file_to_parse.c_str()).absolutePath();
// Parse the first file with definitions
try {
parserpaje.parse(trace, false);
......@@ -96,122 +109,67 @@ void ParserVite::parse(Trace &trace,
trace.finish();
return ;
}
// We get the directory name
QFileInfo fileinfo(QString::fromStdString(_file_to_parse));
QDir directory = fileinfo.absoluteDir();
// We get all the filenames by searching them in the containers stored previously
QStringList file_event_names;
QString name;
stack<Container *> containers;
const Container::Vector *root_containers = trace.get_root_containers();
const map<std::string, Value *> *extra_fields;
String *filename_String = NULL;
map<string, Value *>::const_iterator field;
for (Container::VectorIt it = root_containers->begin();
it != root_containers->end(); ++ it) {
containers.push(*it);
}
while (!containers.empty()) {
Container *c = containers.top();
containers.pop();
extra_fields = c->get_extra_fields();
field = extra_fields->find(string("Filename"));
// Search the filename
if (field != extra_fields->end()) {
filename_String = (String *)(*field).second;
name = QString::fromStdString(filename_String->to_string());
}
else {
name = "";
}
if(name != "") {
file_event_names << name;
}
// We add the children
Container::VectorIt children_end = c->get_children()->end();
for (Container::VectorIt i = c->get_children()->begin();
i != children_end; ++ i) {
containers.push(*i);
}
}
/*const*/ ParserDefinitionPaje *parser_defs = parserpaje.get_parser_def();
ParserEventPaje parserevent(parser_defs);
#ifdef DBG_PARSER_VITE
std::cerr << "First file parsed" << std::endl;
std::cerr << "Add container : ";
#endif
QStringList::const_iterator it_end = file_event_names.constEnd();
for (QStringList::const_iterator it = file_event_names.constBegin() ; it != it_end ; ++ it) {
string event_filename = (directory.absolutePath()+QDir::separator()+(*it)).toStdString();
fileman.open(event_filename.c_str());
// Open the subfile
if(!fileman.is_open()) {
Error::set(Error::_OPEN, Error::_WARNING);
continue;
}
// Parse the subfile
while( (!(fileman.eof()) || _is_canceled)) {
fileman.get_line(&line);
// If it's an empty line
if (line._nbtks == 0) {
continue;
}
// The line starts by a '%' : it's a definition
else if(line._tokens[0][0] == '%') {
// WARNING Message to change
Error::set(Error::_EXPECT_ID_DEF, line._id, Error::_WARNING);
continue;
}
else {
// We check if we have an event identifier
if(sscanf(line._tokens[0], "%u", &eventid) != 1){
Error::set(Error::_EXPECT_ID_DEF, line._id, Error::_WARNING);
continue;
}
try {
def = parser_defs->getDefFromTrid(eventid);
}
catch (unsigned int) {
Error::set(Error::_UNKNOWN_ID_DEF + line._tokens[0], line._id, Error::_WARNING);
continue;
}
// If it is a end link we wait for the begin (PajeStartLink)
if(strcmp(def->_name, "PajeEndLink") == 0) {
// WARNING Don't work like this, PajeLine structure doesn't store the file line
_end_link.push_back(line);
continue;
}
parserevent.store_event(&line, trace);
}
}
/* Loop over root containers to add them in the stack */
root_containers = trace.get_root_containers();
fileman.close();
for (Container::VectorIt it = root_containers->begin();
it != root_containers->end(); it++) {
#ifdef DBG_PARSER_VITE
std::cerr << "+";
#endif
CTstack.push(*it);
}
// We end the links
nblnks = _end_link.size();
// WARNING Don't work like this, PajeLine structure doesn't store the file line
// This work is already done, the parserevent should keep the endlink
for(i = 0 ; i < nblnks ; i ++) {
line = _end_link[i];
parserevent.store_event(&line, trace);
line.free_mem();
#ifdef DBG_PARSER_VITE
std::cerr << std::endl;
#endif
/* Deep-First search over container to parse extra files */
while ( ! CTstack.empty()) {
Container *c = CTstack.top();
CTstack.pop();
extra_fields = c->get_extra_fields();
fnamefield = extra_fields->find(string("FileName"));
// Search the filename
if (fnamefield != extra_fields->end()) {
name = QString::fromStdString( ((String *)(*fnamefield).second)->to_string() );
}
else {
name = "";
}
if(name != "") {
#ifdef DBG_PARSER_VITE
std::cerr << ( (absdir + QDir::separator() + name).toStdString() ) << std::endl;
#endif
parserpaje.set_file_to_parse( (absdir + QDir::separator() + name).toStdString() );
try {
parserpaje.parse(trace, false);
}
catch(...) {
finish();
trace.finish();
return ;
}
}
// We add the children
Container::VectorIt children_end = c->get_children()->end();
for (Container::VectorIt i = c->get_children()->begin();
i != children_end; ++ i) {
CTstack.push(*i);
}
}
finish();
if(finish_trace_after_parse) {
......
......@@ -70,6 +70,10 @@ public:
*/
ParserVite();
ParserVite(const std::string &filename);
/*!
* \fn ~ParserVite()
*/
~ParserVite();
/*!
......
......@@ -40,6 +40,7 @@
** - VUCHENER Clément
**
*/
#include <iostream>
#include <string>
#include <map>
#include <list>
......@@ -172,31 +173,62 @@ void Container::new_event(Date time, EventType *type, EntityValue *value, map<st
}
void Container::start_link(Date time, LinkType *type, Container *source, EntityValue *value, String key, map<std::string, Value *> &opt) {
current_link_t t(time, type, source, value, opt);
_current_links[key] = t;
void Container::start_link(Date time, LinkType *type, Container *source,
EntityValue *value, String key, map<std::string, Value *> &opt)
{
map<String, current_link_t, String::less_than>::iterator i = _current_links.find(key);
if (i == _current_links.end())
{
current_link_t t(time, type, source, value, opt);
_current_links[key] = t;
}
else
{
for (map<string, Value *>::const_iterator j = opt.begin();
j != opt.end(); j++)
{
(*i).second.opt[(*j).first] = (*j).second;
}
_links.push_back(new Link(
time,
(*i).second.start,
type,
this,
source,
(*i).second.source,
value,
(*i).second.opt));
_current_links.erase(i);
}
}
void Container::end_link(Date time, Container *destination, String key, map<string, Value *> &opt) {
map<String, current_link_t, String::less_than>::iterator i = _current_links.find(key);
if (i == _current_links.end())
return;
for (map<string, Value *>::const_iterator j = opt.begin();
j != opt.end();
j++)
(*i).second.opt[(*j).first] = (*j).second;
_links.push_back(new Link(
(*i).second.start,
time,
(*i).second.type,
this,
(*i).second.source,
destination,