diff --git a/eo/src/utils/eoLogger.cpp b/eo/src/utils/eoLogger.cpp index 1330c5323..79813137c 100644 --- a/eo/src/utils/eoLogger.cpp +++ b/eo/src/utils/eoLogger.cpp @@ -40,11 +40,13 @@ Caner Candan #include "eoLogger.h" +/* TODO? +- changer oprateurs +- virer la structure "file" +*/ + void eoLogger::_init() { - _standard_io_streams[&std::cout] = 1; - _standard_io_streams[&std::clog] = 2; - _standard_io_streams[&std::cerr] = 2; // /!\ If you want to add a level dont forget to add it at the header file in the enumerator Levels @@ -55,6 +57,7 @@ void eoLogger::_init() addLevel("logging", eo::logging); addLevel("debug", eo::debug); addLevel("xdebug", eo::xdebug); + } eoLogger::eoLogger() : @@ -66,33 +69,18 @@ eoLogger::eoLogger() : _selectedLevel(eo::progress), _contextLevel(eo::quiet), - _fd(2), - _obuf(_fd, _contextLevel, _selectedLevel) + _obuf(_contextLevel, _selectedLevel) { std::ostream::init(&_obuf); _init(); } -eoLogger::eoLogger(eo::file file) : - std::ostream(NULL), - - _verbose("quiet", "verbose", "Set the verbose level", 'v'), - _printVerboseLevels(false, "print-verbose-levels", "Print verbose levels", 'l'), - _output("", "output", "Redirect a standard output to a file", 'o'), - - _selectedLevel(eo::progress), - _contextLevel(eo::quiet), - _fd(2), - _obuf(_fd, _contextLevel, _selectedLevel) -{ - std::ostream::init(&_obuf); - _init(); - *this << file; -} - eoLogger::~eoLogger() { - if (_fd > 2) { ::close(_fd); } + //redirect(NULL); + if (_obuf._ownedFileStream != NULL) { + delete _obuf._ownedFileStream; + } } void eoLogger::_createParameters( eoParser& parser ) @@ -110,19 +98,21 @@ void eoLogger::_createParameters( eoParser& parser ) //------------------------------------------------------------------ - // we're gonna redirect the log to the given filename if -o is used. + // we redirect the log to the given filename if -o is used. //------------------------------------------------------------------ if ( ! _output.value().empty() ) { - eo::log << eo::file( _output.value() ); + redirect(_output.value()); } + + //------------------------------------------------------------------ //------------------------------------------------------------------ - // we're gonna print the list of levels if -l parameter is used. + // we print the list of levels if -l parameter is used. //------------------------------------------------------------------ if ( _printVerboseLevels.value() ) @@ -163,12 +153,6 @@ eoLogger& operator<<(eoLogger& l, const eo::Levels lvl) return l; } -eoLogger& operator<<(eoLogger& l, eo::file f) -{ - l._fd = ::open(f._f.c_str(), O_WRONLY | O_APPEND | O_CREAT, 0644); - return l; -} - eoLogger& operator<<(eoLogger& l, eo::setlevel v) { l._selectedLevel = (v._lvl < 0 ? l._levels[v._v] : v._lvl); @@ -177,26 +161,49 @@ eoLogger& operator<<(eoLogger& l, eo::setlevel v) eoLogger& operator<<(eoLogger& l, std::ostream& os) { - if (l._standard_io_streams.find(&os) != l._standard_io_streams.end()) - { - l._fd = l._standard_io_streams[&os]; - } + l._obuf._outStream = &os; return l; } -eoLogger::outbuf::outbuf(const int& fd, - const eo::Levels& contexlvl, +void eoLogger::redirect(std::ostream& os) +{ + if (_obuf._ownedFileStream != NULL) { + delete _obuf._ownedFileStream; + _obuf._ownedFileStream = NULL; + } + _obuf._outStream = &os; +} + +void eoLogger::redirect(const char * filename) +{ + std::ofstream * os; + if (filename == NULL) { + os = NULL; + } else { + os = new std::ofstream(filename); + } + redirect(*os); + _obuf._ownedFileStream = os; +} + +void eoLogger::redirect(const std::string& filename) +{ + redirect(filename.c_str()); +} + + +eoLogger::outbuf::outbuf(const eo::Levels& contexlvl, const eo::Levels& selectedlvl) - : _fd(fd), _contextLevel(contexlvl), _selectedLevel(selectedlvl) + : _outStream(&std::cout), _ownedFileStream(NULL), _contextLevel(contexlvl), _selectedLevel(selectedlvl) {} int eoLogger::outbuf::overflow(int_type c) { if (_selectedLevel >= _contextLevel) { - if (_fd >= 0 && c != EOF) + if (_outStream && c != EOF) { - ::write(_fd, &c, 1); + (*_outStream) << (char) c; } } return c; @@ -204,10 +211,6 @@ int eoLogger::outbuf::overflow(int_type c) namespace eo { - file::file(const std::string f) - : _f(f) - {} - setlevel::setlevel(const std::string v) : _v(v), _lvl((Levels)-1) {} diff --git a/eo/src/utils/eoLogger.h b/eo/src/utils/eoLogger.h index 9ac1c2115..e655848c7 100644 --- a/eo/src/utils/eoLogger.h +++ b/eo/src/utils/eoLogger.h @@ -91,6 +91,7 @@ Caner Candan #include #include #include +#include #include "eoObject.h" #include "eoParser.h" @@ -113,12 +114,12 @@ namespace eo /** * 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 @@ -146,7 +147,7 @@ public: eoLogger(); //! overidded ctor in order to instanciate a logger with a file define in parameter - eoLogger(eo::file file); + //eoLogger(eo::file file); //! dtor ~eoLogger(); @@ -189,11 +190,12 @@ private: class outbuf : public std::streambuf { public: - outbuf(const int& fd, const eo::Levels& contexlvl, const eo::Levels& selectedlvl); + outbuf(const eo::Levels& contexlvl, const eo::Levels& selectedlvl); + std::ostream * _outStream; + std::ofstream * _ownedFileStream; protected: virtual int overflow(int_type c); private: - const int& _fd; const eo::Levels& _contextLevel; const eo::Levels& _selectedLevel; }; @@ -211,12 +213,6 @@ public: //! in order to use stream style to define the context verbose level where the following logs will be saved friend eoLogger& operator<<(eoLogger&, const eo::Levels); - /** - * operator<< used there to set a filename through the class file. - */ - //! in order to use stream style to define a file to dump instead the standart output - friend eoLogger& operator<<(eoLogger&, eo::file); - /** * operator<< used there to set a verbose level through the class setlevel. */ @@ -224,12 +220,27 @@ public: friend eoLogger& operator<<(eoLogger&, eo::setlevel); /** + * DEPRECATED: Use instead the redirectTo method * 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&); + /** + * 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. + */ + void redirect(std::ostream&); + + /** + * Redirects the logger to a file using a filename. + * Closing the file will be done automatically when the logger is redirected again or destroyed. + */ + void redirect(const char * filename); + void redirect(const std::string& filename); + private: friend void make_verbose(eoParser&); @@ -244,13 +255,7 @@ private: eo::Levels _contextLevel; /** - * _fd in storing the file descriptor at this place we can disable easily the buffer in - * changing the value at -1. It is used by operator <<. - */ - int _fd; - - /** - * _obuf std::ostream mandates to use a buffer. _obuf is a outbuf inheriting of std::streambuf. + * _obuf std::ostream mandates to use a buffer. _obuf is a outbuf inheriting from std::streambuf. */ outbuf _obuf; diff --git a/eo/test/t-eoLogger.cpp b/eo/test/t-eoLogger.cpp index 198a88720..a1ea4b60c 100644 --- a/eo/test/t-eoLogger.cpp +++ b/eo/test/t-eoLogger.cpp @@ -3,6 +3,10 @@ //----------------------------------------------------------------------------- #include +//#include +#include +#include +#include //----------------------------------------------------------------------------- @@ -25,8 +29,27 @@ int main(int ac, char** av) eo::log << "We are writing on the default output stream" << std::endl; - eo::log << eo::file("test.txt") << "In FILE" << std::endl; - eo::log << std::cout << "on COUT" << std::endl; + //eo::log << eo::file("test.txt") << "In FILE" << std::endl; + + std::ofstream ofs("logtest.txt"); + //eo::log << ofs << "In FILE" << std::endl; + eo::log.redirect(ofs); + eo::log << "In FILE" << std::endl; + + eo::log.redirect("logtest2.txt"); + eo::log << "In FILE 2" << std::endl; + + std::ostringstream oss; + //eo::log << oss << "In STRINGSTREAM"; + eo::log.redirect(oss); + eo::log << oss << "In STRINGSTREAM"; + + //ofs << oss; + std::cout << "Content of ostringstream: " << oss.str() << std::endl; + + //eo::log << std::cout << "on COUT" << std::endl; + eo::log.redirect(std::cout); + eo::log << "on COUT" << std::endl; eo::log << eo::setlevel("errors"); eo::log << eo::setlevel(eo::errors);