diff options
Diffstat (limited to 'base/string_util.cc')
-rw-r--r-- | base/string_util.cc | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/base/string_util.cc b/base/string_util.cc index 7208cd0..0a930d9 100644 --- a/base/string_util.cc +++ b/base/string_util.cc @@ -259,6 +259,48 @@ class WStringToDoubleTraits { } // namespace +namespace base { + +bool IsWprintfFormatPortable(const wchar_t* format) { + for (const wchar_t* position = format; *position != '\0'; ++position) { + + if (*position == '%') { + bool in_specification = true; + bool modifier_l = false; + while (in_specification) { + // Eat up characters until reaching a known specifier. + if (*++position == '\0') { + // The format string ended in the middle of a specification. Call + // it portable because no unportable specifications were found. The + // string is equally broken on all platforms. + return true; + } + + if (*position == 'l') { + // 'l' is the only thing that can save the 's' and 'c' specifiers. + modifier_l = true; + } else if (((*position == 's' || *position == 'c') && !modifier_l) || + *position == 'S' || *position == 'C' || *position == 'F' || + *position == 'D' || *position == 'O' || *position == 'U') { + // Not portable. + return false; + } + + if (wcschr(L"diouxXeEfgGaAcspn%", *position)) { + // Portable, keep scanning the rest of the format string. + in_specification = false; + } + } + } + + } + + return true; +} + +} // namespace base + + const std::string& EmptyString() { return *Singleton<std::string>::get(); } |