diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index 580711163..25676eec6 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -1096,6 +1096,75 @@ kwsys_stl::string SystemTools::CropString(const kwsys_stl::string& s, return n; } +//---------------------------------------------------------------------------- +int SystemTools::EstimateFormatLength(const char *format, va_list ap) +{ + if (!format) + { + return 0; + } + + // Quick-hack attempt at estimating the length of the string. + // Should never under-estimate. + + // Start with the length of the format string itself. + + int length = strlen(format); + + // Increase the length for every argument in the format. + + const char* cur = format; + while(*cur) + { + if(*cur++ == '%') + { + // Skip "%%" since it doesn't correspond to a va_arg. + if(*cur != '%') + { + while(!int(isalpha(*cur))) + { + ++cur; + } + switch (*cur) + { + case 's': + { + // Check the length of the string. + char* s = va_arg(ap, char*); + if(s) + { + length += strlen(s); + } + } break; + case 'e': + case 'f': + case 'g': + { + // Assume the argument contributes no more than 64 characters. + length += 64; + + // Eat the argument. + static_cast(va_arg(ap, double)); + } break; + default: + { + // Assume the argument contributes no more than 64 characters. + length += 64; + + // Eat the argument. + static_cast(va_arg(ap, int)); + } break; + } + } + + // Move past the characters just tested. + ++cur; + } + } + + return length; +} + // convert windows slashes to unix slashes void SystemTools::ConvertToUnixSlashes(kwsys_stl::string& path) { diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in index 522410d4e..2656e33e8 100644 --- a/Source/kwsys/SystemTools.hxx.in +++ b/Source/kwsys/SystemTools.hxx.in @@ -22,6 +22,7 @@ #include <@KWSYS_NAMESPACE@/Configure.h> #include +#include #if defined( _MSC_VER ) typedef unsigned short mode_t; @@ -188,6 +189,17 @@ public: static char* AppendStrings( const char* str1, const char* str2, const char* str3); + /** + * Estimate the length of the string that will be produced + * from printing the given format string and arguments. The + * returned length will always be at least as large as the string + * that will result from printing. + * WARNING: since va_arg is called to iterate of the argument list, + * you will not be able to use this 'ap' anymore from the beginning. + * It's up to you to call va_end though. + */ + static int EstimateFormatLength(const char *format, va_list ap); + /** ----------------------------------------------------------------- * Filename Manipulation Routines * -----------------------------------------------------------------