From ce33ba0328284cbe15175c3c9b0ed682ccddc6c4 Mon Sep 17 00:00:00 2001 From: skyjake Date: Fri, 22 Mar 2013 19:42:34 +0200 Subject: [PATCH] Refactor|libdeng2: String pattern formatting moved to its own method Pattern formatting does not belong in LogEntry::asText(). Also fixed a bug in detecting an escaped format character (%%). --- doomsday/libdeng2/include/de/core/log.h | 3 -- doomsday/libdeng2/include/de/data/string.h | 13 +++++ doomsday/libdeng2/src/core/log.cpp | 29 ++--------- doomsday/libdeng2/src/data/string.cpp | 58 +++++++++++++++++++--- 4 files changed, 66 insertions(+), 37 deletions(-) diff --git a/doomsday/libdeng2/include/de/core/log.h b/doomsday/libdeng2/include/de/core/log.h index 19b1e76989..acd115ba4d 100644 --- a/doomsday/libdeng2/include/de/core/log.h +++ b/doomsday/libdeng2/include/de/core/log.h @@ -310,9 +310,6 @@ class DENG2_PUBLIC LogEntry : public Lockable, public ISerializable }; Q_DECLARE_FLAGS(Flags, Flag) - /// The format string has incorrect syntax. @ingroup errors - DENG2_ERROR(IllegalFormatError); - typedef QList Args; public: diff --git a/doomsday/libdeng2/include/de/data/string.h b/doomsday/libdeng2/include/de/data/string.h index 9d5f19a065..1911a4a456 100644 --- a/doomsday/libdeng2/include/de/data/string.h +++ b/doomsday/libdeng2/include/de/data/string.h @@ -21,6 +21,7 @@ #define LIBDENG2_STRING_H #include +#include #include "../libdeng2.h" #include "../Block" @@ -68,6 +69,8 @@ class DENG2_PUBLIC String : public QString virtual ddouble asNumber() const = 0; }; + typedef QList PatternArgs; + typedef dint size_type; public: @@ -130,6 +133,16 @@ class DENG2_PUBLIC String : public QString */ String operator / (String const &path) const; + /** + * Applies pattern formatting using the string as a format string. + * + * @param args List of arguments. + * + * @return String with placeholders replaced using the arguments. + * @see patternFormat() + */ + String operator % (PatternArgs args) const; + /** * Does a record member concatenation on a variable name. Record members * use '.' as the separator character. diff --git a/doomsday/libdeng2/src/core/log.cpp b/doomsday/libdeng2/src/core/log.cpp index a022a801e0..21b50f3edb 100644 --- a/doomsday/libdeng2/src/core/log.cpp +++ b/doomsday/libdeng2/src/core/log.cpp @@ -372,32 +372,9 @@ String LogEntry::asText(Flags const &formattingFlags, int shortenSection) const } else { - Args::const_iterator arg = _args.begin(); - - DENG2_FOR_EACH_CONST(String, i, _format) - { - if(*i == '%') - { - if(arg == _args.end()) - { - // Out of args. - throw IllegalFormatError("LogEntry::asText", "Ran out of arguments"); - } - - output << String::patternFormat(i, _format.end(), **arg); - ++arg; - } - else - { - output << *i; - } - } - - // Just append the rest of the arguments without special instructions. - for(; arg != _args.end(); ++arg) - { - output << **arg; - } + String::PatternArgs patArgs; + DENG2_FOR_EACH_CONST(Args, i, _args) patArgs << *i; + output << _format % patArgs; } if(flags & Styled) diff --git a/doomsday/libdeng2/src/data/string.cpp b/doomsday/libdeng2/src/data/string.cpp index 49667530a4..89bdfc2382 100644 --- a/doomsday/libdeng2/src/data/string.cpp +++ b/doomsday/libdeng2/src/data/string.cpp @@ -98,6 +98,51 @@ String String::operator / (String const &path) const return concatenatePath(path); } +String String::operator % (PatternArgs args) const +{ + String result; + QTextStream output(&result); + + PatternArgs::const_iterator arg = args.begin(); + + DENG2_FOR_EACH_CONST(String, i, *this) + { + if(*i == '%') + { + String::const_iterator next = i; + advanceFormat(next, end()); + if(*next == '%') + { + // Escaped. + output << *next; + ++i; + continue; + } + + if(arg == args.end()) + { + // Out of args. + throw IllegalPatternError("String::operator %", "Ran out of arguments"); + } + + output << patternFormat(i, end(), **arg); + ++arg; + } + else + { + output << *i; + } + } + + // Just append the rest of the arguments without special instructions. + for(; arg != args.end(); ++arg) + { + output << (*arg)->asText(); + } + + return result; +} + String String::concatenatePath(String const &other, QChar dirChar) const { if(QDir::isAbsolutePath(other)) @@ -425,16 +470,16 @@ String String::patternFormat(String::const_iterator &formatIter, { advanceFormat(formatIter, formatEnd); + QString result; + QTextStream output(&result); + // An argument comes here. bool rightAlign = true; dint maxWidth = 0; dint minWidth = 0; - if(*formatIter == '%') - { - // Escaped. - return String(1, *formatIter); - } + DENG2_ASSERT(*formatIter != '%'); + if(*formatIter == '-') { // Left aligned. @@ -464,9 +509,6 @@ String String::patternFormat(String::const_iterator &formatIter, } // Finally, the type formatting. - QString result; - QTextStream output(&result); - switch((*formatIter).toLatin1()) { case 's':