OSDN Git Service

2006-06-12 Paolo Carlini <pcarlini@suse.de>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / config / locale / gnu / c_locale.h
index 55e160e..c5a301f 100644 (file)
@@ -1,6 +1,7 @@
 // Wrapper for underlying C-language localization -*- C++ -*-
 
-// Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
+// Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
 #pragma GCC system_header
 
 #include <cstring>              // get std::strlen
-#include <cstdio>               // get std::snprintf or std::sprintf
+#include <cstdio>               // get std::vsnprintf or std::vsprintf
 #include <clocale>
 #include <langinfo.h>          // For codecvt
 #include <iconv.h>             // For codecvt using iconv, iconv_t
 #include <libintl.h>           // For messages
+#include <cstdarg>
 
 #define _GLIBCXX_C_LOCALE_GNU 1
 
@@ -61,42 +63,44 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 
   typedef __locale_t           __c_locale;
 
-  // Convert numeric value of type _Tv to string and return length of
-  // string.  If snprintf is available use it, otherwise fall back to
-  // the unsafe sprintf which, in general, can be dangerous and should
-  // be avoided.
-  template<typename _Tv>
-    int
-    __convert_from_v(char* __out, 
-                    const int __size __attribute__ ((__unused__)),
-                    const char* __fmt,
+  // Convert numeric value of type double and long double to string and
+  // return length of string.  If vsnprintf is available use it, otherwise
+  // fall back to the unsafe vsprintf which, in general, can be dangerous
+  // and should be avoided.
+  inline int
+  __convert_from_v(const __c_locale& __cloc __attribute__ ((__unused__)),
+                  char* __out,
+                  const int __size __attribute__ ((__unused__)),
+                  const char* __fmt, ...)
+  {
 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
-                    _Tv __v, const __c_locale& __cloc, int __prec)
-    {
-      __c_locale __old = __gnu_cxx::__uselocale(__cloc);
+    __c_locale __old = __gnu_cxx::__uselocale(__cloc);
 #else
-                    _Tv __v, const __c_locale&, int __prec)
-    {
-      char* __old = std::setlocale(LC_ALL, NULL);
-      char* __sav = new char[std::strlen(__old) + 1];
-      std::strcpy(__sav, __old);
-      std::setlocale(LC_ALL, "C");
+    char* __old = std::setlocale(LC_ALL, NULL);
+    char* __sav = new char[std::strlen(__old) + 1];
+    std::strcpy(__sav, __old);
+    std::setlocale(LC_ALL, "C");
 #endif
 
+    va_list __args;
+    va_start(__args, __fmt);
+
 #ifdef _GLIBCXX_USE_C99
-      const int __ret = std::snprintf(__out, __size, __fmt, __prec, __v);
+    const int __ret = std::vsnprintf(__out, __size, __fmt, __args);
 #else
-      const int __ret = std::sprintf(__out, __fmt, __prec, __v);
+    const int __ret = std::vsprintf(__out, __fmt, __args);
 #endif
 
+    va_end(__args);
+
 #if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
-      __gnu_cxx::__uselocale(__old);
+    __gnu_cxx::__uselocale(__old);
 #else
-      std::setlocale(LC_ALL, __sav);
-      delete [] __sav;
+    std::setlocale(LC_ALL, __sav);
+    delete [] __sav;
 #endif
-      return __ret;
-    }
+    return __ret;
+  }
 
 _GLIBCXX_END_NAMESPACE