Files
TrinityCore/externals/g3dlite/format.cpp
click f867f6d7a8 Get g3dlib, zlib and jemalloc to build again
--HG--
branch : trunk
rename : opt/cleanup/tab2spaces.sh => contrib/cleanup/tab2spaces.sh
rename : opt/cleanup/whitespace.sh => contrib/cleanup/whitespace.sh
rename : opt/conf_merge/README => contrib/conf_merge/README
rename : opt/conf_merge/index.php => contrib/conf_merge/index.php
rename : opt/conf_merge/merge.php => contrib/conf_merge/merge.php
rename : doc/AuctionHouseBot.txt => docs/AuctionHouseBot.txt
rename : doc/DocStructure.dox => docs/DocStructure.dox
rename : doc/Doxyfile.in => docs/Doxyfile.in
rename : doc/EventAI.txt => docs/EventAI.txt
rename : doc/HowToScript.txt => docs/HowToScript.txt
rename : doc/TextTables.txt => docs/TextTables.txt
rename : doc/UnixInstall.txt => docs/UnixInstall.txt
rename : externals/jemalloc/include/internal/arena.h => externals/jemalloc/jemalloc/internal/arena.h
rename : externals/jemalloc/include/internal/base.h => externals/jemalloc/jemalloc/internal/base.h
rename : externals/jemalloc/include/internal/chunk.h => externals/jemalloc/jemalloc/internal/chunk.h
rename : externals/jemalloc/include/internal/chunk_dss.h => externals/jemalloc/jemalloc/internal/chunk_dss.h
rename : externals/jemalloc/include/internal/chunk_mmap.h => externals/jemalloc/jemalloc/internal/chunk_mmap.h
rename : externals/jemalloc/include/internal/chunk_swap.h => externals/jemalloc/jemalloc/internal/chunk_swap.h
rename : externals/jemalloc/include/internal/ckh.h => externals/jemalloc/jemalloc/internal/ckh.h
rename : externals/jemalloc/include/internal/ctl.h => externals/jemalloc/jemalloc/internal/ctl.h
rename : externals/jemalloc/include/internal/extent.h => externals/jemalloc/jemalloc/internal/extent.h
rename : externals/jemalloc/include/internal/hash.h => externals/jemalloc/jemalloc/internal/hash.h
rename : externals/jemalloc/include/internal/huge.h => externals/jemalloc/jemalloc/internal/huge.h
rename : externals/jemalloc/include/internal/jemalloc_internal.h => externals/jemalloc/jemalloc/internal/jemalloc_internal.h
rename : externals/jemalloc/include/internal/jemalloc_internal.h.in => externals/jemalloc/jemalloc/internal/jemalloc_internal.h.in
rename : externals/jemalloc/include/internal/mb.h => externals/jemalloc/jemalloc/internal/mb.h
rename : externals/jemalloc/include/internal/mutex.h => externals/jemalloc/jemalloc/internal/mutex.h
rename : externals/jemalloc/include/internal/prof.h => externals/jemalloc/jemalloc/internal/prof.h
rename : externals/jemalloc/include/internal/ql.h => externals/jemalloc/jemalloc/internal/ql.h
rename : externals/jemalloc/include/internal/qr.h => externals/jemalloc/jemalloc/internal/qr.h
rename : externals/jemalloc/include/internal/rb.h => externals/jemalloc/jemalloc/internal/rb.h
rename : externals/jemalloc/include/internal/stats.h => externals/jemalloc/jemalloc/internal/stats.h
rename : externals/jemalloc/include/internal/tcache.h => externals/jemalloc/jemalloc/internal/tcache.h
rename : externals/jemalloc/include/internal/totally_not_p_r_n.h => externals/jemalloc/jemalloc/internal/totally_not_p_r_n.h
rename : externals/jemalloc/include/jemalloc.h => externals/jemalloc/jemalloc/jemalloc.h
rename : externals/jemalloc/include/jemalloc.h.in => externals/jemalloc/jemalloc/jemalloc.h.in
rename : externals/jemalloc/include/jemalloc_defs.h => externals/jemalloc/jemalloc/jemalloc_defs.h
rename : externals/jemalloc/include/jemalloc_defs.h.in => externals/jemalloc/jemalloc/jemalloc_defs.h.in
2010-06-08 08:04:26 +02:00

165 lines
4.3 KiB
C++

/**
@file format.cpp
@author Morgan McGuire, graphics3d.com
@created 2000-09-09
@edited 2006-08-14
*/
#include "G3D/format.h"
#include "G3D/platform.h"
#include "G3D/System.h"
#ifdef _MSC_VER
// disable: "C++ exception handler used"
# pragma warning (push)
# pragma warning (disable : 4530)
#endif // _MSC_VER
// If your platform does not have vsnprintf, you can find a
// implementation at http://www.ijs.si/software/snprintf/
namespace G3D {
std::string __cdecl format(const char* fmt,...) {
va_list argList;
va_start(argList,fmt);
std::string result = vformat(fmt, argList);
va_end(argList);
return result;
}
#if defined(_MSC_VER) && (_MSC_VER >= 1300)
// Both MSVC seems to use the non-standard vsnprintf
// so we are using vscprintf to determine buffer size, however
// only MSVC7 and up headers include vscprintf for some reason.
std::string vformat(const char *fmt, va_list argPtr) {
// We draw the line at a 1MB string.
const int maxSize = 1000000;
// If the string is less than 161 characters,
// allocate it on the stack because this saves
// the malloc/free time.
const int bufSize = 161;
char stackBuffer[bufSize];
// MSVC does not support va_copy
int actualSize = _vscprintf(fmt, argPtr) + 1;
if (actualSize > bufSize) {
// Now use the heap.
char* heapBuffer = NULL;
if (actualSize < maxSize) {
heapBuffer = (char*)System::malloc(maxSize + 1);
_vsnprintf(heapBuffer, maxSize, fmt, argPtr);
heapBuffer[maxSize] = '\0';
} else {
heapBuffer = (char*)System::malloc(actualSize);
vsprintf(heapBuffer, fmt, argPtr);
}
std::string formattedString(heapBuffer);
System::free(heapBuffer);
return formattedString;
} else {
vsprintf(stackBuffer, fmt, argPtr);
return std::string(stackBuffer);
}
}
#elif defined(_MSC_VER) && (_MSC_VER < 1300)
std::string vformat(const char *fmt, va_list argPtr) {
// We draw the line at a 1MB string.
const int maxSize = 1000000;
// If the string is less than 161 characters,
// allocate it on the stack because this saves
// the malloc/free time.
const int bufSize = 161;
char stackBuffer[bufSize];
// MSVC6 doesn't support va_copy, however it also seems to compile
// correctly if we just pass our argument list along. Note that
// this whole code block is only compiled if we're on MSVC6 anyway
int actualWritten = _vsnprintf(stackBuffer, bufSize, fmt, argPtr);
// Not a big enough buffer, bufSize characters written
if (actualWritten == -1) {
int heapSize = 512;
double powSize = 1.0;
char* heapBuffer = (char*)System::malloc(heapSize);
while ((_vsnprintf(heapBuffer, heapSize, fmt, argPtr) == -1) &&
(heapSize < maxSize)) {
heapSize = iCeil(heapSize * ::pow((double)2.0, powSize++));
heapBuffer = (char*)System::realloc(heapBuffer, heapSize);
}
heapBuffer[heapSize-1] = '\0';
std::string heapString(heapBuffer);
System::free(heapBuffer);
return heapString;
} else {
return std::string(stackBuffer);
}
}
#else
// glibc 2.1 has been updated to the C99 standard
std::string vformat(const char* fmt, va_list argPtr) {
// If the string is less than 161 characters,
// allocate it on the stack because this saves
// the malloc/free time. The number 161 is chosen
// to support two lines of text on an 80 character
// console (plus the null terminator).
const int bufSize = 161;
char stackBuffer[bufSize];
va_list argPtrCopy;
va_copy(argPtrCopy, argPtr);
int numChars = vsnprintf(stackBuffer, bufSize, fmt, argPtrCopy);
va_end(argPtrCopy);
if (numChars >= bufSize) {
// We didn't allocate a big enough string.
char* heapBuffer = (char*)System::malloc((numChars + 1) * sizeof(char));
debugAssert(heapBuffer);
int numChars2 = vsnprintf(heapBuffer, numChars + 1, fmt, argPtr);
debugAssert(numChars2 == numChars);
(void)numChars2;
std::string result(heapBuffer);
System::free(heapBuffer);
return result;
} else {
return std::string(stackBuffer);
}
}
#endif
} // namespace
#ifdef _MSC_VER
# pragma warning (pop)
#endif