diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 7a07cd59e..6d2436824 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -85,7 +85,7 @@ add_component_dir (esmterrain ) add_component_dir (misc - utf8stream stringops resourcehelpers rng + utf8stream stringops resourcehelpers rng messageformatparser ) IF(NOT WIN32 AND NOT APPLE) diff --git a/components/compiler/lineparser.cpp b/components/compiler/lineparser.cpp index ce1e1e463..a5b67f58b 100644 --- a/components/compiler/lineparser.cpp +++ b/components/compiler/lineparser.cpp @@ -140,30 +140,9 @@ namespace Compiler if (mState==MessageState || mState==MessageCommaState) { - std::string arguments; - - for (std::size_t i=0; i +#include #include +#include #include "parser.hpp" #include "exprparser.hpp" @@ -74,6 +76,24 @@ namespace Compiler void reset(); ///< Reset parser to clean state. }; + + class GetArgumentsFromMessageFormat : public ::Misc::MessageFormatParser + { + private: + std::string mArguments; + + protected: + virtual void visitedPlaceholder(Placeholder placeholder, char padding, int width, int precision); + virtual void visitedCharacter(char c) {} + + public: + virtual void process(const std::string& message) + { + mArguments.clear(); + ::Misc::MessageFormatParser::process(message); + } + std::string getArguments() const { return mArguments; } + }; } #endif diff --git a/components/interpreter/miscopcodes.hpp b/components/interpreter/miscopcodes.hpp index c49bbeb01..9d62b60aa 100644 --- a/components/interpreter/miscopcodes.hpp +++ b/components/interpreter/miscopcodes.hpp @@ -13,67 +13,89 @@ #include "defines.hpp" #include +#include namespace Interpreter { - inline std::string formatMessage (const std::string& message, Runtime& runtime) + class RuntimeMessageFormatter : public Misc::MessageFormatParser { - std::string formattedMessage; - - for (std::size_t i=0; i= '0' && m[i] <= '9') + { + width = width * 10 + (m[i] - '0'); + widthSet = true; + ++i; + } + + if (i < m.size()) + { + int precision = 0; + bool precisionSet = false; + if (m[i] == '.') + { + while (++i < m.size() && m[i] >= '0' && m[i] <= '9') + { + precision = precision * 10 + (m[i] - '0'); + precisionSet = true; + } + } + + if (i < m.size()) + { + width = (widthSet) ? width : -1; + precision = (precisionSet) ? precision : -1; + + if (m[i] == 'S' || m[i] == 's') + visitedPlaceholder(StringPlaceholder, pad, width, precision); + else if (m[i] == 'g' || m[i] == 'G') + visitedPlaceholder(IntegerPlaceholder, pad, width, precision); + else if (m[i] == 'f' || m[i] == 'F') + visitedPlaceholder(FloatPlaceholder, pad, width, precision); + } + } + } + } + } + else + { + visitedCharacter(m[i]); + } + } + } +} diff --git a/components/misc/messageformatparser.hpp b/components/misc/messageformatparser.hpp new file mode 100644 index 000000000..48faff714 --- /dev/null +++ b/components/misc/messageformatparser.hpp @@ -0,0 +1,26 @@ +#ifndef OPENMW_COMPONENTS_MISC_MESSAGEFORMATPARSER_H +#define OPENMW_COMPONENTS_MISC_MESSAGEFORMATPARSER_H + +#include + +namespace Misc +{ + class MessageFormatParser + { + protected: + enum Placeholder + { + StringPlaceholder, + IntegerPlaceholder, + FloatPlaceholder + }; + + virtual void visitedPlaceholder(Placeholder placeholder, char padding, int width, int precision) = 0; + virtual void visitedCharacter(char c) = 0; + + public: + virtual void process(const std::string& message); + }; +} + +#endif