Merge branch 'logger' into trikiSA
This commit is contained in:
commit
f969590595
3 changed files with 177 additions and 121 deletions
|
|
@ -37,13 +37,17 @@ Caner Candan <caner.candan@thalesgroup.com>
|
||||||
#include <cstdio> // used to define EOF
|
#include <cstdio> // used to define EOF
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <algorithm> // std::find
|
||||||
|
|
||||||
#include "eoLogger.h"
|
#include "eoLogger.h"
|
||||||
|
|
||||||
/* TODO?
|
|
||||||
- changer oprateurs
|
#ifdef USE_SET
|
||||||
- virer la structure "file"
|
typedef std::set<std::ostream*>::iterator StreamIter;
|
||||||
*/
|
#else
|
||||||
|
typedef std::vector<std::ostream*>::iterator StreamIter;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void eoLogger::_init()
|
void eoLogger::_init()
|
||||||
{
|
{
|
||||||
|
|
@ -61,7 +65,7 @@ void eoLogger::_init()
|
||||||
}
|
}
|
||||||
|
|
||||||
eoLogger::eoLogger() :
|
eoLogger::eoLogger() :
|
||||||
std::ostream(NULL),
|
std::ostream(NULL),
|
||||||
|
|
||||||
_verbose("quiet", "verbose", "Set the verbose level", 'v'),
|
_verbose("quiet", "verbose", "Set the verbose level", 'v'),
|
||||||
_printVerboseLevels(false, "print-verbose-levels", "Print verbose levels", 'l'),
|
_printVerboseLevels(false, "print-verbose-levels", "Print verbose levels", 'l'),
|
||||||
|
|
@ -71,16 +75,15 @@ eoLogger::eoLogger() :
|
||||||
_contextLevel(eo::quiet),
|
_contextLevel(eo::quiet),
|
||||||
_obuf(_contextLevel, _selectedLevel)
|
_obuf(_contextLevel, _selectedLevel)
|
||||||
{
|
{
|
||||||
std::ostream::init(&_obuf);
|
std::ostream::init(&_obuf);
|
||||||
_init();
|
_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
eoLogger::~eoLogger()
|
eoLogger::~eoLogger()
|
||||||
{
|
{
|
||||||
//redirect(NULL);
|
if (_obuf._ownedFileStream != NULL) {
|
||||||
if (_obuf._ownedFileStream != NULL) {
|
delete _obuf._ownedFileStream;
|
||||||
delete _obuf._ownedFileStream;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void eoLogger::_createParameters( eoParser& parser )
|
void eoLogger::_createParameters( eoParser& parser )
|
||||||
|
|
@ -161,29 +164,68 @@ eoLogger& operator<<(eoLogger& l, eo::setlevel v)
|
||||||
|
|
||||||
eoLogger& operator<<(eoLogger& l, std::ostream& os)
|
eoLogger& operator<<(eoLogger& l, std::ostream& os)
|
||||||
{
|
{
|
||||||
l._obuf._outStream = &os;
|
#warning deprecated
|
||||||
|
l.addRedirect(os);
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
void eoLogger::redirect(std::ostream& os)
|
void eoLogger::redirect(std::ostream& os)
|
||||||
{
|
{
|
||||||
if (_obuf._ownedFileStream != NULL) {
|
doRedirect(&os);
|
||||||
delete _obuf._ownedFileStream;
|
}
|
||||||
_obuf._ownedFileStream = NULL;
|
|
||||||
}
|
void eoLogger::doRedirect(std::ostream* os)
|
||||||
_obuf._outStream = &os;
|
{
|
||||||
|
if (_obuf._ownedFileStream != NULL) {
|
||||||
|
delete _obuf._ownedFileStream;
|
||||||
|
_obuf._ownedFileStream = NULL;
|
||||||
|
}
|
||||||
|
_obuf._outStreams.clear();
|
||||||
|
if (os != NULL)
|
||||||
|
#ifdef USE_SET
|
||||||
|
_obuf._outStreams.insert(os);
|
||||||
|
#else
|
||||||
|
_obuf._outStreams.push_back(os);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void eoLogger::addRedirect(std::ostream& os)
|
||||||
|
{
|
||||||
|
bool already_there = tryRemoveRedirect(&os);
|
||||||
|
#ifdef USE_SET
|
||||||
|
_obuf._outStreams.insert(&os);
|
||||||
|
#else
|
||||||
|
_obuf._outStreams.push_back(&os);
|
||||||
|
#endif
|
||||||
|
if (already_there)
|
||||||
|
eo::log << eo::warnings << "Cannot redirect the logger to a stream it is already redirected to." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void eoLogger::removeRedirect(std::ostream& os)
|
||||||
|
{
|
||||||
|
if (!tryRemoveRedirect(&os))
|
||||||
|
eo::log << eo::warnings << "Cannot remove from the logger a stream it was not redirected to.";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool eoLogger::tryRemoveRedirect(std::ostream* os)
|
||||||
|
{
|
||||||
|
StreamIter it = find(_obuf._outStreams.begin(), _obuf._outStreams.end(), os);
|
||||||
|
if (it == _obuf._outStreams.end())
|
||||||
|
return false;
|
||||||
|
_obuf._outStreams.erase(it);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void eoLogger::redirect(const char * filename)
|
void eoLogger::redirect(const char * filename)
|
||||||
{
|
{
|
||||||
std::ofstream * os;
|
std::ofstream * os;
|
||||||
if (filename == NULL) {
|
if (filename == NULL) {
|
||||||
os = NULL;
|
os = NULL;
|
||||||
} else {
|
} else {
|
||||||
os = new std::ofstream(filename);
|
os = new std::ofstream(filename);
|
||||||
}
|
}
|
||||||
redirect(*os);
|
doRedirect(os);
|
||||||
_obuf._ownedFileStream = os;
|
_obuf._ownedFileStream = os;
|
||||||
}
|
}
|
||||||
|
|
||||||
void eoLogger::redirect(const std::string& filename)
|
void eoLogger::redirect(const std::string& filename)
|
||||||
|
|
@ -194,18 +236,29 @@ void eoLogger::redirect(const std::string& filename)
|
||||||
|
|
||||||
eoLogger::outbuf::outbuf(const eo::Levels& contexlvl,
|
eoLogger::outbuf::outbuf(const eo::Levels& contexlvl,
|
||||||
const eo::Levels& selectedlvl)
|
const eo::Levels& selectedlvl)
|
||||||
: _outStream(&std::cout), _ownedFileStream(NULL), _contextLevel(contexlvl), _selectedLevel(selectedlvl)
|
:
|
||||||
{}
|
#ifndef USE_SET
|
||||||
|
_outStreams(1, &std::cout),
|
||||||
|
#endif
|
||||||
|
_ownedFileStream(NULL), _contextLevel(contexlvl), _selectedLevel(selectedlvl)
|
||||||
|
{
|
||||||
|
#ifdef USE_SET
|
||||||
|
_outStreams.insert(&std::cout);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int eoLogger::outbuf::overflow(int_type c)
|
int eoLogger::outbuf::overflow(int_type c)
|
||||||
{
|
{
|
||||||
if (_selectedLevel >= _contextLevel)
|
if (_selectedLevel >= _contextLevel)
|
||||||
{
|
{
|
||||||
if (_outStream && c != EOF)
|
for (StreamIter it = _outStreams.begin(); it != _outStreams.end(); it++)
|
||||||
{
|
{
|
||||||
(*_outStream) << (char) c;
|
if (c != EOF)
|
||||||
}
|
{
|
||||||
}
|
(**it) << (char) c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*-
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
(c) Thales group, 2010
|
(c) Thales group, 2010
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
|
|
@ -30,56 +31,7 @@ Caner Candan <caner.candan@thalesgroup.com>
|
||||||
|
|
||||||
Global logger for EO.
|
Global logger for EO.
|
||||||
|
|
||||||
Here's an example explaning how to use eoLogger:
|
For an example explaning how to use eoLogger, please refer to paradiseo/eo/test/t-eoLogger.cpp
|
||||||
\code
|
|
||||||
#include <eo>
|
|
||||||
|
|
||||||
int main(int ac, char** av)
|
|
||||||
{
|
|
||||||
// We are declaring the usual eoParser class
|
|
||||||
eoParser parser(ac, av);
|
|
||||||
|
|
||||||
// This call is important to allow -v parameter to change user level.
|
|
||||||
make_verbose(parser);
|
|
||||||
|
|
||||||
// At this time we are switching to warning message and messages
|
|
||||||
// which are going to follow it are going to be warnings message too.
|
|
||||||
// These messages can be displayed only if the user level (sets with
|
|
||||||
// eo::setlevel function) is set to eo::warnings.
|
|
||||||
eo::log << eo::warnings;
|
|
||||||
|
|
||||||
// With the following eo::file function we are defining that
|
|
||||||
// all future logs are going to this new file resource which is
|
|
||||||
// test.txt
|
|
||||||
eo::log << eo::file("test.txt") << "In FILE" << std::endl;
|
|
||||||
|
|
||||||
// Now we are changing again the resources destination to cout which
|
|
||||||
// is the standard output.
|
|
||||||
eo::log << std::cout << "In COUT" << std::endl;
|
|
||||||
|
|
||||||
// Here are 2 differents examples of how to set the errors user level
|
|
||||||
// in using either a string or an identifier.
|
|
||||||
eo::log << eo::setlevel("errors");
|
|
||||||
eo::log << eo::setlevel(eo::errors);
|
|
||||||
|
|
||||||
// Now we are writting a message, that will be displayed only if we are above the "quiet" level
|
|
||||||
eo::log << eo::quiet << "1) Must be in quiet mode to see that" << std::endl;
|
|
||||||
|
|
||||||
// And so on...
|
|
||||||
eo::log << eo::setlevel(eo::warnings) << eo::warnings << "2) Must be in warnings mode to see that" << std::endl;
|
|
||||||
|
|
||||||
eo::log << eo::setlevel(eo::logging);
|
|
||||||
|
|
||||||
eo::log << eo::errors;
|
|
||||||
eo::log << "3) Must be in errors mode to see that";
|
|
||||||
eo::log << std::endl;
|
|
||||||
|
|
||||||
eo::log << eo::debug << 4 << ')'
|
|
||||||
<< " Must be in debug mode to see that\n";
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
@{
|
@{
|
||||||
*/
|
*/
|
||||||
|
|
@ -96,6 +48,18 @@ Caner Candan <caner.candan@thalesgroup.com>
|
||||||
#include "eoObject.h"
|
#include "eoObject.h"
|
||||||
#include "eoParser.h"
|
#include "eoParser.h"
|
||||||
|
|
||||||
|
#define USE_SET // defines if a set is to be used instead of a vector for storing streams the logger is redirected to
|
||||||
|
#undef USE_SET
|
||||||
|
/* expriments have shown that here a vector is by far faster than a set even if O(n),
|
||||||
|
* because it needs less dynamic allocations, uses less memory and less instructions
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_SET
|
||||||
|
#include <set>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace eo
|
namespace eo
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
@ -111,16 +75,6 @@ namespace eo
|
||||||
debug,
|
debug,
|
||||||
xdebug};
|
xdebug};
|
||||||
|
|
||||||
/**
|
|
||||||
* file
|
|
||||||
* this structure combined with the friend operator<< below is an easy way to select a file as output.
|
|
||||||
*
|
|
||||||
struct file
|
|
||||||
{
|
|
||||||
explicit file(const std::string f);
|
|
||||||
const std::string _f;
|
|
||||||
};*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* setlevel
|
* setlevel
|
||||||
* this structure combined with the friend operator<< below is an easy way to set a verbose level.
|
* this structure combined with the friend operator<< below is an easy way to set a verbose level.
|
||||||
|
|
@ -182,6 +136,12 @@ private:
|
||||||
//! used by the set of ctors to initiate some useful variables
|
//! used by the set of ctors to initiate some useful variables
|
||||||
void _init();
|
void _init();
|
||||||
|
|
||||||
|
//! helper function regrouping redirection operations; takes a pointer because can be given NULL
|
||||||
|
void doRedirect(std::ostream*);
|
||||||
|
|
||||||
|
//! helper function searching for a stream and removing it, returning true if successful, false otherwise
|
||||||
|
bool tryRemoveRedirect(std::ostream*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* outbuf
|
* outbuf
|
||||||
|
|
@ -191,7 +151,14 @@ private:
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
outbuf(const eo::Levels& contexlvl, const eo::Levels& selectedlvl);
|
outbuf(const eo::Levels& contexlvl, const eo::Levels& selectedlvl);
|
||||||
std::ostream * _outStream;
|
//std::ostream * _outStream;
|
||||||
|
|
||||||
|
#ifdef USE_SET
|
||||||
|
std::set<std::ostream*> _outStreams;
|
||||||
|
#else
|
||||||
|
std::vector<std::ostream*> _outStreams;
|
||||||
|
#endif
|
||||||
|
|
||||||
std::ofstream * _ownedFileStream;
|
std::ofstream * _ownedFileStream;
|
||||||
protected:
|
protected:
|
||||||
virtual int overflow(int_type c);
|
virtual int overflow(int_type c);
|
||||||
|
|
@ -220,20 +187,32 @@ public:
|
||||||
friend eoLogger& operator<<(eoLogger&, eo::setlevel);
|
friend eoLogger& operator<<(eoLogger&, eo::setlevel);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DEPRECATED: Use instead the redirectTo method
|
* DEPRECATED: Use instead the redirect or addRedirect method; has the same effect as addRedirect
|
||||||
* operator<< used there to be able to use std::cout to say that we wish to redirect back the buffer to a standard output.
|
|
||||||
*/
|
*/
|
||||||
//! in order to use stream style to go back to a standart output defined by STL
|
|
||||||
//! and to get retro-compatibility
|
|
||||||
#warning deprecated
|
|
||||||
friend eoLogger& operator<<(eoLogger&, std::ostream&);
|
friend eoLogger& operator<<(eoLogger&, std::ostream&);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redirects the logger to a given output stream. Closing the stream and returning its memory is at the charge of the caller,
|
* Redirects the logger to a given output stream.
|
||||||
|
* Closing the stream and returning its memory is at the charge of the caller,
|
||||||
* but should not be done while the log is still redirected to it.
|
* but should not be done while the log is still redirected to it.
|
||||||
|
* This resets all previous redirections set up with redirect and add_redirect.
|
||||||
*/
|
*/
|
||||||
void redirect(std::ostream&);
|
void redirect(std::ostream&);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a redirection from the logger to a given output stream.
|
||||||
|
* Closing the stream and returning its memory is at the charge of the caller,
|
||||||
|
* but should not be done while the log is still redirected to it.
|
||||||
|
* This does not reset previous redirections, which remain active.
|
||||||
|
*/
|
||||||
|
void addRedirect(std::ostream&);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a redirection from the logger to the given output stream.
|
||||||
|
* This only resets the redirection to the stream passed in argument.
|
||||||
|
*/
|
||||||
|
void removeRedirect(std::ostream&);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redirects the logger to a file using a filename.
|
* Redirects the logger to a file using a filename.
|
||||||
* Closing the file will be done automatically when the logger is redirected again or destroyed.
|
* Closing the file will be done automatically when the logger is redirected again or destroyed.
|
||||||
|
|
|
||||||
|
|
@ -7,50 +7,75 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static void test();
|
||||||
|
|
||||||
int main(int ac, char** av)
|
int main(int ac, char** av)
|
||||||
{
|
{
|
||||||
eoParser parser(ac, av);
|
eoParser parser(ac, av);
|
||||||
|
|
||||||
if (parser.userNeedsHelp())
|
if (parser.userNeedsHelp())
|
||||||
{
|
{
|
||||||
parser.printHelp(std::cout);
|
parser.printHelp(std::cout);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
make_help(parser);
|
make_help(parser);
|
||||||
make_verbose(parser);
|
make_verbose(parser);
|
||||||
|
|
||||||
|
test();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test()
|
||||||
|
{
|
||||||
eo::log << eo::setlevel(eo::debug);
|
eo::log << eo::setlevel(eo::debug);
|
||||||
|
|
||||||
eo::log << eo::warnings;
|
eo::log << eo::warnings;
|
||||||
|
|
||||||
eo::log << "We are writing on the default output stream" << std::endl;
|
eo::log << "We are writing on the default output stream" << std::endl;
|
||||||
|
|
||||||
//eo::log << eo::file("test.txt") << "In FILE" << std::endl;
|
{
|
||||||
|
eo::log.redirect("logtest.txt");
|
||||||
|
eo::log << "In FILE" << std::endl;
|
||||||
|
std::ofstream ofs("logtest2.txt"); // closed and destroyed at the en of the scope
|
||||||
|
eo::log.addRedirect(ofs);
|
||||||
|
eo::log << "In FILE 2" << std::endl;
|
||||||
|
eo::log.removeRedirect(ofs); // must be removed because the associated stream is closed
|
||||||
|
}
|
||||||
|
|
||||||
std::ofstream ofs("logtest.txt");
|
std::ifstream ifs("logtest2.txt"); // stream to logtest2.txt is closed, we can start reading
|
||||||
//eo::log << ofs << "In FILE" << std::endl;
|
std::string line;
|
||||||
eo::log.redirect(ofs);
|
assert(std::getline(ifs, line));
|
||||||
eo::log << "In FILE" << std::endl;
|
assert(line == "In FILE 2");
|
||||||
|
assert(!std::getline(ifs, line));
|
||||||
eo::log.redirect("logtest2.txt");
|
|
||||||
eo::log << "In FILE 2" << std::endl;
|
|
||||||
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
//eo::log << oss << "In STRINGSTREAM";
|
eo::log.addRedirect(oss);
|
||||||
eo::log.redirect(oss);
|
eo::log << "In STRINGSTREAM";
|
||||||
eo::log << oss << "In STRINGSTREAM";
|
|
||||||
|
|
||||||
//ofs << oss;
|
|
||||||
std::cout << "Content of ostringstream: " << oss.str() << std::endl;
|
std::cout << "Content of ostringstream: " << oss.str() << std::endl;
|
||||||
|
assert(oss.str() == "In STRINGSTREAM");
|
||||||
|
|
||||||
//eo::log << std::cout << "on COUT" << std::endl;
|
eo::log.redirect(std::cout); // removes all previously redirected streams; closes the file logtest.txt
|
||||||
eo::log.redirect(std::cout);
|
|
||||||
eo::log << "on COUT" << std::endl;
|
eo::log << "on COUT" << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
ifs.close();
|
||||||
|
ifs.open("logtest.txt");
|
||||||
|
assert(std::getline(ifs, line));
|
||||||
|
assert(line == "In FILE");
|
||||||
|
assert(std::getline(ifs, line));
|
||||||
|
assert(line == "In FILE 2");
|
||||||
|
assert(std::getline(ifs, line));
|
||||||
|
assert(line == "In STRINGSTREAM");
|
||||||
|
assert(!std::getline(ifs, line));
|
||||||
|
|
||||||
|
|
||||||
eo::log << eo::setlevel("errors");
|
eo::log << eo::setlevel("errors");
|
||||||
eo::log << eo::setlevel(eo::errors);
|
eo::log << eo::setlevel(eo::errors);
|
||||||
|
|
||||||
|
|
@ -65,9 +90,8 @@ int main(int ac, char** av)
|
||||||
eo::log << std::endl;
|
eo::log << std::endl;
|
||||||
|
|
||||||
eo::log << eo::debug << 4 << ')'
|
eo::log << eo::debug << 4 << ')'
|
||||||
<< "4) in debug mode\n";
|
<< "4) in debug mode\n";
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue