|
|
@@ -19,7 +19,7 @@ |
|
|
|
// Contains some utilities to work with std::string objects. |
|
|
|
// |
|
|
|
|
|
|
|
#include "features.h" |
|
|
|
#include "../features.h" |
|
|
|
|
|
|
|
#include <vector> // std::vector |
|
|
|
#include <string> // std::basic_string |
|
|
@@ -149,7 +149,7 @@ std::basic_string<T> toupper(T const *s) |
|
|
|
|
|
|
|
// Format a string, printf-style |
|
|
|
template<typename T = char> |
|
|
|
std::basic_string<T> vformat(char const *format, va_list ap) |
|
|
|
std::basic_string<T> vformat(char const *fmt, va_list ap) |
|
|
|
{ |
|
|
|
va_list ap2; |
|
|
|
#if defined va_copy || !defined _MSC_VER |
|
|
@@ -161,7 +161,7 @@ std::basic_string<T> vformat(char const *format, va_list ap) |
|
|
|
|
|
|
|
// vsnprintf() tells us how many characters we need, not counting |
|
|
|
// the terminating null character. |
|
|
|
size_t needed = vsnprintf(nullptr, 0, format, ap2); |
|
|
|
size_t needed = vsnprintf(nullptr, 0, fmt, ap2); |
|
|
|
|
|
|
|
#if defined va_copy || !defined _MSC_VER |
|
|
|
// do not call va_end() if va_copy() wasn't called. |
|
|
@@ -170,17 +170,17 @@ std::basic_string<T> vformat(char const *format, va_list ap) |
|
|
|
|
|
|
|
std::string ret; |
|
|
|
ret.resize(needed); |
|
|
|
vsnprintf(&ret[0], needed + 1, format, ap); |
|
|
|
vsnprintf(&ret[0], needed + 1, fmt, ap); |
|
|
|
|
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
template<typename T = char> lol_attr_printf_format(1, 2) |
|
|
|
std::basic_string<T> format(T const *format, ...) |
|
|
|
std::basic_string<T> format(T const *fmt, ...) |
|
|
|
{ |
|
|
|
va_list ap; |
|
|
|
va_start(ap, format); |
|
|
|
std::string ret = vformat(format, ap); |
|
|
|
va_start(ap, fmt); |
|
|
|
std::string ret = vformat(fmt, ap); |
|
|
|
va_end(ap); |
|
|
|
return ret; |
|
|
|
} |