diff --git a/SystemTools.cxx b/SystemTools.cxx
index f52cdba93d09dd03615dd9e0617e1d0ebe756d6c..9cd5c8e59bc19b90fc89d75b4708d795de535c9a 100644
--- a/SystemTools.cxx
+++ b/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<void>(va_arg(ap, double));
+          } break;
+          default:
+          {
+          // Assume the argument contributes no more than 64 characters.
+          length += 64;
+            
+          // Eat the argument.
+          static_cast<void>(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/SystemTools.hxx.in b/SystemTools.hxx.in
index 4707518a3b27bd222c190eab83b2dae39827fd84..3fae5a39e3a793baec6498ae41ba169441339d58 100644
--- a/SystemTools.hxx.in
+++ b/SystemTools.hxx.in
@@ -22,6 +22,7 @@
 #include <@KWSYS_NAMESPACE@/Configure.h>
 
 #include <sys/types.h>
+#include <stdarg.h>
 
 #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
    *  -----------------------------------------------------------------