Good evening,

i would suggest (as i think) relatively simple solutions for two things.

1. The problem that streaming to lyxerr always evaluates the things that are to be written to the stream even if the stream does not write anything to std::cout.

How does it work basically?

instead of the well known form

lyxerr[Debug::INIT] << "LyX: Warning: Ignore last file: " << tmp << endl;

write

lyxerr[Debug::INIT] && msg << "LyX: Warning: Ignore last file: " << tmp << 
EndMsg;

In the second case lyxerr[Debug::INIT] returns true if the output is enabled and false otherwise. The part after the && is only executed when lyxerr[Debug::INIT] is true. msg has to be derived from std::ostream. It works because EndMsg has a special type (an enum type) and the operator<< is overloaded for this type to return a bool. Thus short circuit evaluation applies.

2. There is a simple program called debugview (from former sysinternals, now from microsoft) free for download that can be used to display messages from other applications. It just has to be started - no installation is required.

If a windows application calls OutputDebugString(xxx) the string xxx is displayed in the debugview window. Now if the stream "msg" is a std::stringstream then the overloaded operator<< sends its contents to OutputDebugString() and clears the stream for the next message.

In the attached example application i went even further and derived another class from std::stringstream that adds a tag to the message and indents the message. Therefore a NewLine type similar to the EndMsg type has been introduced. The output in the debugview window is also attached.

comments are welcome

Bernhard


<<attachment: debugview.jpg>>

// test1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <ostream>
#include <string>
#include <sstream>
#include <windows.h>

///
enum ErrCommit {
        EndMsg
};
///
enum ErrNewLine {
        NewLine
};
///
void errorMessage(std::string msg) {
        /// output to stdout
        std::cout << msg << std::endl << std::endl;
        /// output to debugview
        OutputDebugString(msg.c_str());
}
///
class formattedDebugStream : public std::stringstream {

public:
        ///
        formattedDebugStream(std::string tag)
                : std::stringstream(), space_(tag.length(), ' '), tag_(tag) { 
                str("");
                *this << tag_;
        }

        ///
        void commit() { 
                errorMessage(str());
                str("");
                *this << tag_;
        }
        
        ///
        void newline() { *this << std::endl << space_; }

private:
        ///
        std::string tag_;
        ///
        std::string space_;
};

///
bool operator<<(std::ostream &os, ErrCommit) {
        formattedDebugStream *dbg = dynamic_cast<formattedDebugStream *>(&os);
        if (!dbg) {
                std::stringstream *sstr = dynamic_cast<std::stringstream 
*>(&os);
                if (!sstr) {
                        os << std::endl;
                } else {
                        errorMessage(sstr->str());
                        sstr->str("");
                }
        } else {
                dbg->commit();
        }
        return true;
}

///
std::ostream & operator<<(std::ostream &os, ErrNewLine) {
        formattedDebugStream *dbg = dynamic_cast<formattedDebugStream *>(&os);
        if (!dbg) {
                os << std::endl;
        } else {
                dbg->newline();
        }
        return os;
}

int _tmain(int argc, _TCHAR* argv[])
{

        formattedDebugStream err("ERROR: ");
        formattedDebugStream inf("INFO: ");
        formattedDebugStream dbg("DEBUG: ");
        formattedDebugStream wrn("WARNING: ");
        formattedDebugStream msg("");
        std::stringstream sstr;

        bool out = true;
        bool quiet = false;

        out && inf << "for information." << NewLine 
                           << "you see?" << EndMsg;
        out && wrn << "you" << NewLine 
                << "better" << std::endl 
                           << "be" << NewLine 
                           << "careful" << EndMsg;
        quiet && err << "you cannot see this." << EndMsg;
        out && err << "this is an error for you." << EndMsg;
        out && dbg << "this should happen " << 0 << " times!" << EndMsg;
        out && dbg << "this also should happen " << 0 << " times!" << EndMsg;
        out && msg << "this is just a message" << NewLine 
                       << "without a tag." << NewLine 
                           << "thus it has no space on the left side." << 
EndMsg;

        out && sstr << "Standard stream works as well." << NewLine
                        << "But without any formatting" << EndMsg;
        return 0;
}

Reply via email to