diff --git a/core/logic/smn_string.cpp b/core/logic/smn_string.cpp index 2a9402ad..76ff2e05 100644 --- a/core/logic/smn_string.cpp +++ b/core/logic/smn_string.cpp @@ -194,80 +194,12 @@ static cell_t sm_formatex(IPluginContext *pCtx, const cell_t *params) return static_cast(res); } -class StaticCharBuf -{ - char *buffer; - size_t max_size; -public: - StaticCharBuf() : buffer(NULL), max_size(0) - { - } - ~StaticCharBuf() - { - free(buffer); - } - char* GetWithSize(size_t len) - { - if (len > max_size) - { - buffer = (char *)realloc(buffer, len); - max_size = len; - } - return buffer; - } -}; - -static char g_formatbuf[2048]; -static StaticCharBuf g_extrabuf; static cell_t sm_format(IPluginContext *pCtx, const cell_t *params) { - char *buf, *fmt, *destbuf; - cell_t start_addr, end_addr, maxparam; - size_t res, maxlen; - int arg = 4; - bool copy = false; - char *__copy_buf; - - pCtx->LocalToString(params[1], &destbuf); - pCtx->LocalToString(params[3], &fmt); - - maxlen = static_cast(params[2]); - start_addr = params[1]; - end_addr = params[1] + maxlen; - maxparam = params[0]; - - for (cell_t i=3; i<=maxparam; i++) - { - if ((params[i] >= start_addr) && (params[i] <= end_addr)) - { - copy = true; - break; - } - } - - if (copy) - { - if (maxlen > sizeof(g_formatbuf)) - { - __copy_buf = g_extrabuf.GetWithSize(maxlen); - } - else - { - __copy_buf = g_formatbuf; - } - } - - buf = (copy) ? __copy_buf : destbuf; - res = atcprintf(buf, maxlen, fmt, pCtx, params, &arg); - - if (copy) - { - memcpy(destbuf, __copy_buf, res+1); - } - - return static_cast(res); + return InternalFormat(pCtx, params, 0); } +static char g_vformatbuf[2048]; static cell_t sm_vformat(IPluginContext *pContext, const cell_t *params) { int vargPos = static_cast(params[4]); @@ -301,7 +233,7 @@ static cell_t sm_vformat(IPluginContext *pContext, const cell_t *params) if (copy) { - destination = g_formatbuf; + destination = g_vformatbuf; } else { pContext->LocalToString(params[1], &destination); } @@ -313,7 +245,7 @@ static cell_t sm_vformat(IPluginContext *pContext, const cell_t *params) /* Perform copy-on-write if we need to */ if (copy) { - pContext->StringToLocal(params[1], maxlen, g_formatbuf); + pContext->StringToLocal(params[1], maxlen, g_vformatbuf); } return total; diff --git a/core/logic/stringutil.cpp b/core/logic/stringutil.cpp index 7d5050e2..d4c32d78 100644 --- a/core/logic/stringutil.cpp +++ b/core/logic/stringutil.cpp @@ -29,11 +29,13 @@ * Version: $Id$ */ +#include "common_logic.h" #include #include #include #include #include "stringutil.h" +#include "sprintf.h" #include #include "TextParsers.h" @@ -361,3 +363,76 @@ char *UTIL_TrimWhitespace(char *str, size_t &len) return str; } +class StaticCharBuf +{ + char *buffer; + size_t max_size; +public: + StaticCharBuf() : buffer(NULL), max_size(0) + { + } + ~StaticCharBuf() + { + free(buffer); + } + char* GetWithSize(size_t len) + { + if (len > max_size) + { + buffer = (char *)realloc(buffer, len); + max_size = len; + } + return buffer; + } +}; + +static char g_formatbuf[2048]; +static StaticCharBuf g_extrabuf; +cell_t InternalFormat(IPluginContext *pCtx, const cell_t *params, int start) +{ + char *buf, *fmt, *destbuf; + cell_t start_addr, end_addr, maxparam; + size_t res, maxlen; + int arg = start + 4; + bool copy = false; + char *__copy_buf; + + pCtx->LocalToString(params[start + 1], &destbuf); + pCtx->LocalToString(params[start + 3], &fmt); + + maxlen = static_cast(params[start + 2]); + start_addr = params[start + 1]; + end_addr = params[start + 1] + maxlen; + maxparam = params[0]; + + for (cell_t i = (start + 3); i <= maxparam; i++) + { + if ((params[i] >= start_addr) && (params[i] <= end_addr)) + { + copy = true; + break; + } + } + + if (copy) + { + if (maxlen > sizeof(g_formatbuf)) + { + __copy_buf = g_extrabuf.GetWithSize(maxlen); + } + else + { + __copy_buf = g_formatbuf; + } + } + + buf = (copy) ? __copy_buf : destbuf; + res = atcprintf(buf, maxlen, fmt, pCtx, params, &arg); + + if (copy) + { + memcpy(destbuf, __copy_buf, res+1); + } + + return static_cast(res); +} diff --git a/core/logic/stringutil.h b/core/logic/stringutil.h index 558ab37c..94b3a688 100644 --- a/core/logic/stringutil.h +++ b/core/logic/stringutil.h @@ -43,5 +43,9 @@ size_t UTIL_DecodeHexString(unsigned char *buffer, size_t maxlength, const char void UTIL_StripExtension(const char *in, char *out, int outSize); char *UTIL_TrimWhitespace(char *str, size_t &len); +// Internal copying Format helper, expects (char[] buffer, int maxlength, const char[] format, any ...) starting at |start| +// i.e. you can stuff your own params before |buffer|. +cell_t InternalFormat(IPluginContext *pCtx, const cell_t *params, int start); + #endif /* _INCLUDE_SOURCEMOD_COMMON_STRINGUTIL_H_ */