GLib: implement GMutex natively on Linux
[platform/upstream/glib.git] / glib / gnulib / vasnprintf.c
index b95e119..ee0a43a 100644 (file)
    Library General Public License for more details.
 
    You should have received a copy of the GNU Library General Public
-   License along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-   USA.  */
+   License along with this program; if not, see <http://www.gnu.org/licenses/>.  */
 
+#ifndef _WIN32
 /* Tell glibc's <stdio.h> to provide a prototype for snprintf().
    This must come before <config.h> because <config.h> may include
    <features.h>, and once <features.h> has been included, it's too late.  */
 #ifndef _GNU_SOURCE
 # define _GNU_SOURCE    1
 #endif
+#endif
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 #include <float.h>     /* DBL_MAX_EXP, LDBL_MAX_EXP */
 #include "printf-parse.h"
 
+#ifdef HAVE_WCHAR_T
+# ifdef HAVE_WCSLEN
+#  define local_wcslen wcslen
+# else
+   /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
+      a dependency towards this library, here is a local substitute.
+      Define this substitute only once, even if this file is included
+      twice in the same compilation unit.  */
+#  ifndef local_wcslen_defined
+#   define local_wcslen_defined 1
+static size_t
+local_wcslen (const wchar_t *s)
+{
+  const wchar_t *ptr;
+
+  for (ptr = s; *ptr != (wchar_t) 0; ptr++)
+    ;
+  return ptr - s;
+}
+#  endif
+# endif
+#endif
+
 /* For those losing systems which don't have 'alloca' we have to add
    some additional code emulating it.  */ 
 #ifdef HAVE_ALLOCA 
@@ -480,6 +503,16 @@ vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args)
                          + 2; /* account for leading sign or alternate form */
                      else
 # endif
+# ifdef HAVE_INT64_AND_I64
+                     if (type == TYPE_INT64 || type == TYPE_UINT64)
+                       tmp_length =
+                         (unsigned int) (sizeof (unsigned __int64) * CHAR_BIT
+                                         * 0.25 /* binary -> hexadecimal */
+                                         )
+                         + 1 /* turn floor into ceil */
+                         + 2; /* account for leading sign or alternate form */
+                     else
+# endif
                      if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
                        tmp_length =
                          (unsigned int) (sizeof (unsigned long) * CHAR_BIT
@@ -539,11 +572,15 @@ vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args)
 # ifdef HAVE_WCHAR_T
                      if (type == TYPE_WIDE_STRING)
                        tmp_length =
-                         wcslen (a.arg[dp->arg_index].a.a_wide_string)
+                         (a.arg[dp->arg_index].a.a_wide_string == NULL
+                         ? 6 /* wcslen(L"(null)") */
+                          : local_wcslen (a.arg[dp->arg_index].a.a_wide_string)) 
                          * MB_CUR_MAX;
                      else
 # endif
-                       tmp_length = strlen (a.arg[dp->arg_index].a.a_string);
+                       tmp_length = a.arg[dp->arg_index].a.a_string == NULL
+                         ? 6 /* strlen("(null)") */
+                         : strlen (a.arg[dp->arg_index].a.a_string);
                      break;
 
                    case 'p':
@@ -690,13 +727,16 @@ vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args)
                  {
                    size_t maxlen;
                    int count;
+#if HAVE_SNPRINTF
                    int retcount;
+#endif
 
                    maxlen = allocated - length;
                    count = -1;
-                   retcount = 0;
 
 #if HAVE_SNPRINTF
+                   retcount = 0;
+
 #define SNPRINTF_BUF(arg) \
                    switch (prefix_count)                                   \
                      {                                                     \
@@ -853,11 +893,19 @@ vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args)
                                }
                            }
                          
-                         count = print_long_long (result + length, maxlen,
+#if HAVE_SNPRINTF
+                         count = print_long_long (result + length, maxlen,
+                                                  width, precision,
+                                                  dp->flags,
+                                                  dp->conversion,
+                                                  arg);
+#else
+                         count = print_long_long (tmp, tmp_length,
                                                   width, precision,
                                                   dp->flags,
                                                   dp->conversion,
                                                   arg);
+#endif
                        }
                        break;
 #else
@@ -905,14 +953,18 @@ vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args)
 #endif
                      case TYPE_STRING:
                        {
-                         const char *arg = a.arg[dp->arg_index].a.a_string;
+                         const char *arg = a.arg[dp->arg_index].a.a_string == NULL
+                           ? "(null)"
+                           : a.arg[dp->arg_index].a.a_string;
                          SNPRINTF_BUF (arg);
                        }
                        break;
 #ifdef HAVE_WCHAR_T
                      case TYPE_WIDE_STRING:
                        {
-                         const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
+                         const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string == NULL
+                           ? L"(null)"
+                           : a.arg[dp->arg_index].a.a_wide_string;
                          SNPRINTF_BUF (arg);
                        }
                        break;