11 #include <stk_util/util/TeeStreambuf.hpp> 12 #include <stk_util/util/IndentStreambuf.hpp> 30 LogStream(
const std::string &path, std::ostream *output_stream, std::ofstream *file_stream)
32 m_ostream(output_stream),
33 m_ofstream(file_stream)
39 std::ostream * m_ostream;
40 std::ofstream * m_ofstream;
43 LogStream(
const LogStream &);
44 void operator = (
const LogStream &);
47 #ifdef __INTEL_COMPILER 49 #pragma warning(disable: 444) 51 struct LogStreamMap :
public std::map<std::string, LogStream *>
58 LogStream *log_stream = (*begin()).second;
64 #ifdef __INTEL_COMPILER 68 struct OStreamTeeStreambuf
70 OStreamTeeStreambuf(std::ostream &output_stream)
71 : m_ostream(&output_stream),
72 m_origRdbuf(output_stream.rdbuf()),
75 m_ostream->rdbuf(m_teeStreambuf);
78 ~OStreamTeeStreambuf();
80 std::ostream * m_ostream;
81 std::streambuf * m_origRdbuf;
85 OStreamTeeStreambuf(
const OStreamTeeStreambuf &);
86 void operator = (
const OStreamTeeStreambuf &);
89 #ifdef __INTEL_COMPILER 91 #pragma warning(disable: 444) 93 struct OStreamTeeStreambufMap :
public std::map<std::string, OStreamTeeStreambuf *>
95 OStreamTeeStreambufMap()
98 ~OStreamTeeStreambufMap() {
106 #ifdef __INTEL_COMPILER 111 get_file_stream_map()
113 static LogStreamMap s_logFileStreamMap;
115 return s_logFileStreamMap;
119 OStreamTeeStreambufMap &
120 get_ostream_tee_streambuf_map()
122 static OStreamTeeStreambufMap s_ostreamTeeStreambufMap;
124 return s_ostreamTeeStreambufMap;
128 LogStream::~LogStream()
135 OStreamTeeStreambufMap &ostream_tee_streambuf_map = get_ostream_tee_streambuf_map();
137 for (OStreamTeeStreambufMap::iterator it = ostream_tee_streambuf_map.begin(); it != ostream_tee_streambuf_map.end(); ++it)
138 (*it).second->m_teeStreambuf->remove(m_ofstream);
145 OStreamTeeStreambuf::~OStreamTeeStreambuf()
149 m_ostream->rdbuf(m_origRdbuf);
153 OStreamTeeStreambufMap &ostream_tee_streambuf_map = get_ostream_tee_streambuf_map();
155 for (OStreamTeeStreambufMap::iterator it = ostream_tee_streambuf_map.begin(); it != ostream_tee_streambuf_map.end(); ++it)
156 (*it).second->m_teeStreambuf->remove(m_ostream);
158 delete m_teeStreambuf;
166 const std::string & name,
167 const std::string & path)
169 LogStreamMap &file_stream_map = get_file_stream_map();
173 std::ofstream *file_stream =
new std::ofstream(path.c_str());
175 if(!file_stream->good()) {
177 std::ostringstream s;
178 s <<
"Cannot open output log file '" << path <<
"' directory does not exist or is write protected.";
180 throw std::runtime_error(s.str());
185 file_stream_map[name] =
new LogStream(path, file_stream, file_stream);
191 const std::string & name)
193 LogStreamMap &file_stream_map = get_file_stream_map();
195 LogStreamMap::iterator it = file_stream_map.find(name);
197 if (it != file_stream_map.end()) {
199 file_stream_map.erase(it);
207 const std::string & name)
209 LogStreamMap &file_stream_map = get_file_stream_map();
211 LogStreamMap::iterator it = file_stream_map.find(name);
213 if (it != file_stream_map.end()) {
214 std::ostringstream s;
215 s <<
"Log ostream " << name <<
" has already been registered";
222 file_stream_map[name] =
new LogStream(name, &os, 0);
231 LogStreamMap &file_stream_map = get_file_stream_map();
233 for (LogStreamMap::iterator it = file_stream_map.begin(); it != file_stream_map.end(); ++it) {
234 if ((*it).second->m_ostream == &os) {
236 file_stream_map.erase(it);
241 OStreamTeeStreambufMap &ostream_tee_streambuf_map = get_ostream_tee_streambuf_map();
243 for (OStreamTeeStreambufMap::iterator it = ostream_tee_streambuf_map.begin(); it != ostream_tee_streambuf_map.end(); ++it)
244 (*it).second->m_teeStreambuf->remove(&os);
250 const std::string & name)
252 static std::string not_found =
"";
254 LogStreamMap &file_stream_map = get_file_stream_map();
256 LogStreamMap::iterator it = file_stream_map.find(name);
258 return it == file_stream_map.end() ? not_found : (*it).second->m_path;
264 const std::string & name)
266 LogStreamMap &file_stream_map = get_file_stream_map();
268 LogStreamMap::iterator it = file_stream_map.find(name);
270 return it == file_stream_map.end() ? 0 : (*it).second->m_ostream;
277 const std::string & name)
279 OStreamTeeStreambufMap &ostream_tee_streambuf_map = get_ostream_tee_streambuf_map();
283 OStreamTeeStreambufMap::iterator it = ostream_tee_streambuf_map.find(name);
285 if (it != ostream_tee_streambuf_map.end()) {
289 std::ostringstream s;
290 s <<
"Output stream " << name <<
" has already been registered";
292 throw std::runtime_error(s.str());
295 ostream_tee_streambuf_map[name] =
new OStreamTeeStreambuf(os);
303 OStreamTeeStreambufMap &ostream_tee_streambuf_map = get_ostream_tee_streambuf_map();
305 for (OStreamTeeStreambufMap::iterator it = ostream_tee_streambuf_map.begin(); it != ostream_tee_streambuf_map.end(); ++it)
306 (*it).second->m_teeStreambuf->remove(&os);
308 for (OStreamTeeStreambufMap::iterator it = ostream_tee_streambuf_map.begin(); it != ostream_tee_streambuf_map.end(); ++it) {
309 if ((*it).second->m_ostream == &os) {
311 ostream_tee_streambuf_map.erase(it);
321 const std::string & name)
323 OStreamTeeStreambufMap &ostream_tee_streambuf_map = get_ostream_tee_streambuf_map();
325 OStreamTeeStreambufMap::iterator it = ostream_tee_streambuf_map.find(name);
327 return it == ostream_tee_streambuf_map.end() ? 0 : (*it).second->m_ostream;
332 get_ostream_tee_streambuf(
333 const std::string & name)
335 OStreamTeeStreambufMap &ostream_tee_streambuf_map = get_ostream_tee_streambuf_map();
337 OStreamTeeStreambufMap::iterator it = ostream_tee_streambuf_map.find(name);
339 return it == ostream_tee_streambuf_map.end() ? 0 : (*it).second->m_teeStreambuf;
345 const std::string & name)
347 OStreamTeeStreambufMap &ostream_tee_streambuf_map = get_ostream_tee_streambuf_map();
349 OStreamTeeStreambufMap::iterator it = ostream_tee_streambuf_map.find(name);
351 return it == ostream_tee_streambuf_map.end() ? 0 : (*it).second->m_ostream;
357 const std::string & name)
370 virtual void execute() = 0;
373 #ifdef __INTEL_COMPILER 374 #pragma warning(push) 375 #pragma warning(disable: 444) 377 struct CommandList :
public std::list<Command *>
380 :
std::list<Command *>()
385 for (std::list<Command *>::iterator it = begin(); it != end(); ++it)
389 #ifdef __INTEL_COMPILER 397 const std::string & tee_ostream_name)
399 tee_streambuf *osb = get_ostream_tee_streambuf(tee_ostream_name);
402 std::ostringstream s;
404 s <<
"Output stream " << tee_ostream_name <<
" has not been registered for output logging";
405 throw std::runtime_error(s.str());
414 const std::string & ostream_name)
422 std::ostringstream s;
424 s <<
"Log file '" << ostream_name <<
"' has not been registered";
425 throw std::runtime_error(s.str());
432 struct OpenLog :
public Command
435 const std::string &name,
436 const std::string &path)
444 virtual void execute() {
453 struct CloseLog :
public Command
456 const std::string &name)
463 virtual void execute() {
471 struct ClearTeeOStream :
public Command
474 const std::string & tee_ostream_name)
475 : m_teeOStreamName(tee_ostream_name)
478 virtual ~ClearTeeOStream()
481 virtual void execute() {
482 parse_tee_streambuf(m_teeOStreamName).clear();
485 std::string m_teeOStreamName;
489 struct AddTeeOStream :
public Command
492 const std::string & tee_ostream_name,
493 const std::string & ostream_name)
494 : m_teeOStreamName(tee_ostream_name),
495 m_ostreamName(ostream_name)
498 virtual ~AddTeeOStream()
501 virtual void execute() {
502 if (m_ostreamName !=
"null")
503 parse_tee_streambuf(m_teeOStreamName).add(parse_ostream(m_ostreamName));
506 std::string m_teeOStreamName;
507 std::string m_ostreamName;
511 struct RemoveTeeOStream :
public Command
514 const std::string & tee_ostream_name,
515 const std::string & ostream_name)
516 : m_teeOStreamName(tee_ostream_name),
517 m_ostreamName(ostream_name)
520 virtual ~RemoveTeeOStream()
523 virtual void execute() {
524 parse_tee_streambuf(m_teeOStreamName).remove(parse_ostream(m_ostreamName));
527 std::string m_teeOStreamName;
528 std::string m_ostreamName;
543 parse_output_description(
544 const std::string & output_description,
545 CommandList & command_list)
547 typedef std::pair<const char *, const char *> Token;
548 typedef std::list<Token> TokenList;
550 command_list.clear();
554 for (
const char *c = output_description.c_str(); *c; ) {
555 if (std::isspace(*c))
558 else if (*c ==
'>' || *c ==
'+' || *c ==
'-' || *c ==
'=') {
559 tokens.push_back(Token(c, c + 1));
563 else if (*c ==
'\"') {
564 const char *d = c + 1;
565 while (*d && *d !=
'\"')
567 tokens.push_back(Token(c + 1, d));
573 while (std::isgraph(*d) && *d !=
'+' && *d !=
'-' &&*d !=
'=' && *d !=
'>')
575 tokens.push_back(Token(c, d));
580 for (TokenList::iterator it = tokens.begin(); it != tokens.end(); ) {
581 std::string name((*it).first, (*it).second);
583 ++it;
if (it == tokens.end())
break;
584 std::string operation((*it).first, (*it).second);
586 if (operation ==
"=") {
587 ++it;
if (it == tokens.end())
break;
588 std::string path((*it).first, (*it).second);
590 command_list.push_back(
new OpenLog(name, path));
592 command_list.push_back(
new CloseLog(name));
593 ++it;
if (it == tokens.end())
break;
596 else if (operation ==
">") {
597 parse_tee_streambuf(name);
599 ++it;
if (it == tokens.end())
break;
600 std::string token(std::string((*it).first, (*it).second));
601 if (token !=
"+" && token !=
"-") {
602 std::string ostream_name(std::string((*it).first, (*it).second));
604 command_list.push_back(
new ClearTeeOStream(name));
605 command_list.push_back(
new AddTeeOStream(name, ostream_name));
606 ++it;
if (it == tokens.end())
break;
609 while (it != tokens.end()) {
610 token = std::string((*it).first, (*it).second);
612 ++it;
if (it == tokens.end())
break;
613 std::string ostream_name(std::string((*it).first, (*it).second));
615 command_list.push_back(
new AddTeeOStream(name, ostream_name));
616 ++it;
if (it == tokens.end())
break;
619 else if (token ==
"-") {
620 ++it;
if (it == tokens.end())
break;
621 std::string ostream_name(std::string((*it).first, (*it).second));
623 command_list.push_back(
new RemoveTeeOStream(name, ostream_name));
624 ++it;
if (it == tokens.end())
break;
635 const CommandList & command_list)
637 for (CommandList::const_iterator it = command_list.begin(); it != command_list.end(); ++it)
645 const std::string & output_description)
647 stk_classic::CommandList command_list;
649 parse_output_description(output_description, command_list);
650 execute(command_list);
659 static std::ostream s_out(std::cout.rdbuf());
667 static std::ostream s_pout(std::cout.rdbuf());
675 static std::ostream s_dout(std::cout.rdbuf());
683 static std::ostream s_tout(std::cout.rdbuf());
692 static std::ostream s_dwout(&s_dwoutStreambuf);
std::ostream & dout()
Diagnostic output stream.
std::ostream & dwout()
Diagnostic writer stream.
const std::string & get_log_path(const std::string &name)
Function get_log_path returns the file path of the log file with the specified name from the log file...
std::ostream & pout()
Per-processor output stream (See RuntimeDeferredx)
std::ostream & out()
Normal output stream.
stk_classic::basic_tee_streambuf< char, std::char_traits< char > > tee_streambuf
Tee stream buffer for char.
void create_log_file(const std::string &name, const std::string &path)
Function create_log_file opens a log file at the specified path and adds it to the registry of log fi...
Class basic_indent_streambuf implements a output streambuf that performs indentation, blank line removal and outline bracing, sending the result character stream to another output stream buffer.
void close_log_file(const std::string &name)
Function close_log_file close the log file with the specified name and removes it from the registry o...
std::ostream * get_ostream_ostream(const std::string &name)
Function get_ostream_streambuf locates the output stream registered with the specified name...
std::ostream * get_ostream_tee_ostream(const std::string &name)
Function get_ostream_tee_streambuf locates the tee streambuf registered with the specified name...
void bind_output_streams(const std::string &output_description)
Function bind_output_streams parses the output_description and opens and registers the log streams an...
bool is_registered_ostream(const std::string &name)
Function is_registered_ostream returns true if an output stream of the specified name is registered...
std::ostream & tout()
Regression test textual output stream.
std::ostream * get_log_ostream(const std::string &name)
Function get_log_file_ostream return the output stream of the log file with the specified name from t...
void unregister_ostream(std::ostream &os)
Function unregister_ostream unregisters an output stream.
void unregister_log_ostream(std::ostream &os)
Function register_log_ostream takes an existing std::ostream and makes it available for output redire...
void register_log_ostream(std::ostream &os, const std::string &name)
Function register_log_ostream takes an existing std::ostream and makes it available for output redire...
void register_ostream(std::ostream &os, const std::string &name)
Function register_ostream registers an output stream with the output stream registry. The registration process creates an intermediate tee streambuf.