Skip to content

Commit

Permalink
LogBuffer: Improved output formatting with word wrapping
Browse files Browse the repository at this point in the history
  • Loading branch information
skyjake committed Mar 28, 2012
1 parent 4ca874e commit 2a40aa9
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 15 deletions.
74 changes: 60 additions & 14 deletions doomsday/libdeng2/src/core/logbuffer.cpp
Expand Up @@ -30,8 +30,6 @@
using namespace de;

const Time::Delta FLUSH_INTERVAL = .2;
const duint SIMPLE_INDENT = 30;
const duint RULER_LENGTH = 98 - SIMPLE_INDENT;

LogBuffer* LogBuffer::_appBuffer = 0;

Expand Down Expand Up @@ -122,6 +120,8 @@ void LogBuffer::enable(Log::LogLevel overLevel)

void LogBuffer::setOutputFile(const String& path)
{
flush();

if(_outputFile)
{
delete _outputFile;
Expand All @@ -130,7 +130,7 @@ void LogBuffer::setOutputFile(const String& path)
if(path.isEmpty()) return;

_outputFile = new QFile(path);
if(/*!*/_outputFile->open(QFile::Text | QFile::WriteOnly))
if(!_outputFile->open(QFile::Text | QFile::WriteOnly))
{
delete _outputFile;
_outputFile = 0;
Expand Down Expand Up @@ -162,19 +162,65 @@ void LogBuffer::flush()
}
*/

#ifndef _DEBUG
const duint MAX_LENGTH = 109;
const duint SIMPLE_INDENT = 30;
#else
const duint MAX_LENGTH = 89;
const duint SIMPLE_INDENT = 4;
#endif
const duint RULER_LENGTH = MAX_LENGTH - SIMPLE_INDENT - 1;

DENG2_FOR_EACH(i, _toBeFlushed, EntryList::iterator)
{
// Error messages will go to stderr instead of stdout.
QList<QTextStream*> os;
os << ((*i)->level() >= Log::ERROR? errs.data() : outs.data()) << fs.data();

#ifndef _DEBUG
String message = (*i)->asText();
#else
// In a release build we can dispense with the metadata.
String message = (*i)->asText(LogEntry::Simple);
#endif

// Print line by line.
String::size_type pos = 0;
while(pos != String::npos)
{
String::size_type next = message.indexOf('\n', pos);
duint lineLen = (next == String::npos? message.size() - pos : next - pos);
const duint maxLen = (pos > 0? MAX_LENGTH - SIMPLE_INDENT : MAX_LENGTH);
if(lineLen > maxLen)
{
// Wrap overly long lines.
next = pos + maxLen;
lineLen = maxLen;

// Maybe there's whitespace we can wrap at.
int checkPos = pos + maxLen;
while(checkPos > pos)
{
if(message[checkPos].isSpace() ||
(message[checkPos].isPunct() && message[checkPos] != '.' &&
message[checkPos] != ','))
{
if(!message[checkPos].isSpace())
{
// Include the punctuation on this line.
checkPos++;
}

// Break here.
next = checkPos;
lineLen = checkPos - pos;
break;
}
checkPos--;
}
}

// For lines other than the first one, print an indentation.
if(pos > 0)
{
foreach(QTextStream* stream, os)
Expand All @@ -189,19 +235,18 @@ void LogBuffer::flush()
}
*/
}
String lineText = message.substr(pos, next != String::npos? next - pos + 1 : next);

String lineText = message.substr(pos, lineLen);

// Check for formatting symbols.
if(lineText == "$R")
{
lineText = String(RULER_LENGTH, '-');
}
lineText.replace("$R", String(RULER_LENGTH, '-'));

foreach(QTextStream* stream, os)
{
if(!stream) continue;
*stream << lineText;
}

/*
if(writer)
{
Expand All @@ -210,14 +255,15 @@ void LogBuffer::flush()
*/

pos = next;
if(pos != String::npos) pos++;
}
if(pos != String::npos && message[pos].isSpace()) pos++; // Skip whitespace.

foreach(QTextStream* stream, os)
{
if(!stream) continue;
*stream << "\n";
foreach(QTextStream* stream, os)
{
if(!stream) continue;
*stream << "\n";
}
}

/*
if(writer)
{
Expand Down
2 changes: 1 addition & 1 deletion doomsday/libdeng2/src/legacy/legacycore.cpp
Expand Up @@ -179,7 +179,7 @@ void LegacyCore::printLogFragment(const char* text)
while((pos = d->currentLogLine.find('\n')) != std::string::npos)
{
LOG_MSG(d->currentLogLine.substr(0, pos).c_str());
d->currentLogLine.erase(0, pos);
d->currentLogLine.erase(0, pos + 1);
}
}

Expand Down

0 comments on commit 2a40aa9

Please sign in to comment.