Blame gst/printf/vasnprintf.c

Packit Service 963350
/* vsprintf with automatic memory allocation.
Packit Service 963350
   Copyright (C) 1999, 2002-2003 Free Software Foundation, Inc.
Packit Service 963350
Packit Service 963350
   This program is free software; you can redistribute it and/or modify it
Packit Service 963350
   under the terms of the GNU Library General Public License as published
Packit Service 963350
   by the Free Software Foundation; either version 2, or (at your option)
Packit Service 963350
   any later version.
Packit Service 963350
Packit Service 963350
   This program is distributed in the hope that it will be useful,
Packit Service 963350
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 963350
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 963350
   Library General Public License for more details.
Packit Service 963350
Packit Service 963350
   You should have received a copy of the GNU Library General Public
Packit Service 963350
   License along with this program; if not, write to the Free Software
Packit Service 963350
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
Packit Service 963350
   USA.  */
Packit Service 963350
Packit Service 963350
#ifndef _WIN32
Packit Service 963350
/* Tell glibc's <stdio.h> to provide a prototype for snprintf().
Packit Service 963350
   This must come before <config.h> because <config.h> may include
Packit Service 963350
   <features.h>, and once <features.h> has been included, it's too late.  */
Packit Service 963350
#ifndef _GNU_SOURCE
Packit Service 963350
# define _GNU_SOURCE    1
Packit Service 963350
#endif
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
#ifdef HAVE_CONFIG_H
Packit Service 963350
# include <config.h>
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
#include "gst-printf.h"
Packit Service 963350
Packit Service 963350
/* Specification.  */
Packit Service 963350
#include "vasnprintf.h"
Packit Service 963350
Packit Service 963350
#include <stdio.h>              /* snprintf(), sprintf() */
Packit Service 963350
#include <stdlib.h>             /* abort(), malloc(), realloc(), free() */
Packit Service 963350
#include <string.h>             /* memcpy(), strlen() */
Packit Service 963350
#include <errno.h>              /* errno */
Packit Service 963350
#include <limits.h>             /* CHAR_BIT */
Packit Service 963350
#include <float.h>              /* DBL_MAX_EXP, LDBL_MAX_EXP */
Packit Service 963350
#include "printf-parse.h"
Packit Service 963350
#include "printf-extension.h"
Packit Service 963350
Packit Service 963350
#ifdef HAVE_WCHAR_T
Packit Service 963350
# ifdef HAVE_WCSLEN
Packit Service 963350
#  define local_wcslen wcslen
Packit Service 963350
# else
Packit Service 963350
   /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
Packit Service 963350
      a dependency towards this library, here is a local substitute.
Packit Service 963350
      Define this substitute only once, even if this file is included
Packit Service 963350
      twice in the same compilation unit.  */
Packit Service 963350
#  ifndef local_wcslen_defined
Packit Service 963350
#   define local_wcslen_defined 1
Packit Service 963350
static size_t
Packit Service 963350
local_wcslen (const wchar_t * s)
Packit Service 963350
{
Packit Service 963350
  const wchar_t *ptr;
Packit Service 963350
Packit Service 963350
  for (ptr = s; *ptr != (wchar_t) 0; ptr++);
Packit Service 963350
  return ptr - s;
Packit Service 963350
}
Packit Service 963350
#  endif
Packit Service 963350
# endif
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
/* For those losing systems which don't have 'alloca' we have to add
Packit Service 963350
   some additional code emulating it.  */
Packit Service 963350
#if defined (alloca) || defined (GLIB_HAVE_ALLOCA_H)
Packit Service 963350
# define freea(p)               /* nothing */
Packit Service 963350
#else
Packit Service 963350
# define alloca(n) malloc (n)
Packit Service 963350
# define freea(p) free (p)
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
#ifndef HAVE_LONG_LONG_FORMAT
Packit Service 963350
static inline int
Packit Service 963350
print_long_long (char *buf,
Packit Service 963350
    int len,
Packit Service 963350
    int width,
Packit Service 963350
    int precision,
Packit Service 963350
    unsigned long flags, char conversion, unsigned long long number)
Packit Service 963350
{
Packit Service 963350
  int negative = FALSE;
Packit Service 963350
  char buffer[128];
Packit Service 963350
  char *bufferend;
Packit Service 963350
  char *pointer;
Packit Service 963350
  int base;
Packit Service 963350
  static const char *upper = "0123456789ABCDEFX";
Packit Service 963350
  static const char *lower = "0123456789abcdefx";
Packit Service 963350
  const char *digits;
Packit Service 963350
  int i;
Packit Service 963350
  char *p;
Packit Service 963350
  int count;
Packit Service 963350
Packit Service 963350
#define EMIT(c)           \
Packit Service 963350
  if (p - buf == len - 1) \
Packit Service 963350
    {                     \
Packit Service 963350
      *p++ = '\0';        \
Packit Service 963350
      return len;         \
Packit Service 963350
    }                     \
Packit Service 963350
  else                    \
Packit Service 963350
    *p++ = c;
Packit Service 963350
Packit Service 963350
  p = buf;
Packit Service 963350
Packit Service 963350
  switch (conversion) {
Packit Service 963350
    case 'o':
Packit Service 963350
      base = 8;
Packit Service 963350
      digits = lower;
Packit Service 963350
      negative = FALSE;
Packit Service 963350
      break;
Packit Service 963350
    case 'x':
Packit Service 963350
      base = 16;
Packit Service 963350
      digits = lower;
Packit Service 963350
      negative = FALSE;
Packit Service 963350
      break;
Packit Service 963350
    case 'X':
Packit Service 963350
      base = 16;
Packit Service 963350
      digits = upper;
Packit Service 963350
      negative = FALSE;
Packit Service 963350
      break;
Packit Service 963350
    case 'u':
Packit Service 963350
      base = 10;
Packit Service 963350
      digits = lower;
Packit Service 963350
      negative = FALSE;
Packit Service 963350
      break;
Packit Service 963350
    default:
Packit Service 963350
      base = 10;
Packit Service 963350
      digits = lower;
Packit Service 963350
      negative = (long long) number < 0;
Packit Service 963350
      if (negative)
Packit Service 963350
        number = -((long long) number);
Packit Service 963350
      break;
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  /* Build number */
Packit Service 963350
  pointer = bufferend = &buffer[sizeof (buffer) - 1];
Packit Service 963350
  *pointer-- = '\0';
Packit Service 963350
  for (i = 1; i < (int) sizeof (buffer); i++) {
Packit Service 963350
    *pointer-- = digits[number % base];
Packit Service 963350
    number /= base;
Packit Service 963350
    if (number == 0)
Packit Service 963350
      break;
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  /* Adjust width */
Packit Service 963350
  width -= (bufferend - pointer) - 1;
Packit Service 963350
Packit Service 963350
  /* Adjust precision */
Packit Service 963350
  if (precision != -1) {
Packit Service 963350
    precision -= (bufferend - pointer) - 1;
Packit Service 963350
    if (precision < 0)
Packit Service 963350
      precision = 0;
Packit Service 963350
    flags |= FLAG_ZERO;
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  /* Adjust width further */
Packit Service 963350
  if (negative || (flags & FLAG_SHOWSIGN) || (flags & FLAG_SPACE))
Packit Service 963350
    width--;
Packit Service 963350
  if (flags & FLAG_ALT) {
Packit Service 963350
    switch (base) {
Packit Service 963350
      case 16:
Packit Service 963350
        width -= 2;
Packit Service 963350
        break;
Packit Service 963350
      case 8:
Packit Service 963350
        width--;
Packit Service 963350
        break;
Packit Service 963350
      default:
Packit Service 963350
        break;
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  /* Output prefixes spaces if needed */
Packit Service 963350
  if (!((flags & FLAG_LEFT) || ((flags & FLAG_ZERO) && (precision == -1)))) {
Packit Service 963350
    count = (precision == -1) ? 0 : precision;
Packit Service 963350
    while (width-- > count)
Packit Service 963350
      *p++ = ' ';
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  /* width has been adjusted for signs and alternatives */
Packit Service 963350
  if (negative) {
Packit Service 963350
    EMIT ('-');
Packit Service 963350
  } else if (flags & FLAG_SHOWSIGN) {
Packit Service 963350
    EMIT ('+');
Packit Service 963350
  } else if (flags & FLAG_SPACE) {
Packit Service 963350
    EMIT (' ');
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  if (flags & FLAG_ALT) {
Packit Service 963350
    switch (base) {
Packit Service 963350
      case 8:
Packit Service 963350
        EMIT ('0');
Packit Service 963350
        break;
Packit Service 963350
      case 16:
Packit Service 963350
        EMIT ('0');
Packit Service 963350
        EMIT (digits[16]);
Packit Service 963350
        break;
Packit Service 963350
      default:
Packit Service 963350
        break;
Packit Service 963350
    }                           /* switch base */
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  /* Output prefixed zero padding if needed */
Packit Service 963350
  if (flags & FLAG_ZERO) {
Packit Service 963350
    if (precision == -1)
Packit Service 963350
      precision = width;
Packit Service 963350
    while (precision-- > 0) {
Packit Service 963350
      EMIT ('0');
Packit Service 963350
      width--;
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  /* Output the number itself */
Packit Service 963350
  while (*(++pointer)) {
Packit Service 963350
    EMIT (*pointer);
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  /* Output trailing spaces if needed */
Packit Service 963350
  if (flags & FLAG_LEFT) {
Packit Service 963350
    while (width-- > 0)
Packit Service 963350
      EMIT (' ');
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  EMIT ('\0');
Packit Service 963350
Packit Service 963350
  return p - buf - 1;
Packit Service 963350
}
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
static void
Packit Service 963350
printf_postprocess_args (char_directives * directives, arguments * arguments)
Packit Service 963350
{
Packit Service 963350
  int i;
Packit Service 963350
Packit Service 963350
  for (i = 0; i < directives->count; ++i) {
Packit Service 963350
    char_directive *dp;
Packit Service 963350
    argument *a;
Packit Service 963350
Packit Service 963350
    dp = &directives->dir[i];
Packit Service 963350
Packit Service 963350
    /* %% has no arguments, for example */
Packit Service 963350
    if (dp->arg_index < 0)
Packit Service 963350
      continue;
Packit Service 963350
Packit Service 963350
    a = &arguments->arg[dp->arg_index];
Packit Service 963350
Packit Service 963350
    if (a->type == TYPE_POINTER_EXT) {
Packit Service 963350
      char fmt[4];
Packit Service 963350
Packit Service 963350
      fmt[0] = 'p';
Packit Service 963350
      fmt[1] = POINTER_EXT_SIGNIFIER_CHAR;
Packit Service 963350
      fmt[2] = dp->ptr_ext_char;
Packit Service 963350
      fmt[3] = '\0';
Packit Service 963350
Packit Service 963350
      a->ext_string =
Packit Service 963350
          __gst_printf_pointer_extension_serialize (fmt, a->a.a_pointer);
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
char *
Packit Service 963350
vasnprintf (char *resultbuf, size_t * lengthp, const char *format, va_list args)
Packit Service 963350
{
Packit Service 963350
  char_directives d;
Packit Service 963350
  arguments a;
Packit Service 963350
Packit Service 963350
  if (printf_parse (format, &d, &a) < 0) {
Packit Service 963350
    errno = EINVAL;
Packit Service 963350
    return NULL;
Packit Service 963350
  }
Packit Service 963350
#define CLEANUP()                         \
Packit Service 963350
  free (d.dir);                           \
Packit Service 963350
  if (a.arg) {                            \
Packit Service 963350
    while (a.count--) {                   \
Packit Service 963350
      if (a.arg[a.count].ext_string)      \
Packit Service 963350
        free (a.arg[a.count].ext_string); \
Packit Service 963350
    }                                     \
Packit Service 963350
    free (a.arg);                         \
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  if (printf_fetchargs (args, &a) < 0) {
Packit Service 963350
    CLEANUP ();
Packit Service 963350
    errno = EINVAL;
Packit Service 963350
    return NULL;
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  /* collect TYPE_POINTER_EXT argument strings */
Packit Service 963350
  printf_postprocess_args (&d, &a);
Packit Service 963350
Packit Service 963350
  {
Packit Service 963350
    char *buf =
Packit Service 963350
        (char *) alloca (7 + d.max_width_length + d.max_precision_length + 6);
Packit Service 963350
    const char *cp;
Packit Service 963350
    unsigned int i;
Packit Service 963350
    char_directive *dp;
Packit Service 963350
    /* Output string accumulator.  */
Packit Service 963350
    char *result;
Packit Service 963350
    size_t allocated;
Packit Service 963350
    size_t length;
Packit Service 963350
Packit Service 963350
    if (resultbuf != NULL) {
Packit Service 963350
      result = resultbuf;
Packit Service 963350
      allocated = *lengthp;
Packit Service 963350
    } else {
Packit Service 963350
      result = NULL;
Packit Service 963350
      allocated = 0;
Packit Service 963350
    }
Packit Service 963350
    length = 0;
Packit Service 963350
    /* Invariants:
Packit Service 963350
       result is either == resultbuf or == NULL or malloc-allocated.
Packit Service 963350
       If length > 0, then result != NULL.  */
Packit Service 963350
Packit Service 963350
#define ENSURE_ALLOCATION(needed) \
Packit Service 963350
    if ((needed) > allocated)						\
Packit Service 963350
      {									\
Packit Service 963350
	char *memory;							\
Packit Service 963350
									\
Packit Service 963350
	allocated = (allocated > 0 ? 2 * allocated : 12);		\
Packit Service 963350
	if ((needed) > allocated)					\
Packit Service 963350
	  allocated = (needed);						\
Packit Service 963350
	if (result == resultbuf || result == NULL)			\
Packit Service 963350
	  memory = (char *) malloc (allocated);				\
Packit Service 963350
	else								\
Packit Service 963350
	  memory = (char *) realloc (result, allocated);		\
Packit Service 963350
									\
Packit Service 963350
	if (memory == NULL)						\
Packit Service 963350
	  {								\
Packit Service 963350
	    if (!(result == resultbuf || result == NULL))		\
Packit Service 963350
	      free (result);						\
Packit Service 963350
	    freea (buf);						\
Packit Service 963350
	    CLEANUP ();							\
Packit Service 963350
	    errno = ENOMEM;						\
Packit Service 963350
	    return NULL;						\
Packit Service 963350
	  }								\
Packit Service 963350
	if (result == resultbuf && length > 0)				\
Packit Service 963350
	  memcpy (memory, result, length);				\
Packit Service 963350
	result = memory;						\
Packit Service 963350
      }
Packit Service 963350
Packit Service 963350
    for (cp = format, i = 0, dp = &d.dir[0];; cp = dp->dir_end, i++, dp++) {
Packit Service 963350
      if (cp != dp->dir_start) {
Packit Service 963350
        size_t n = dp->dir_start - cp;
Packit Service 963350
Packit Service 963350
        ENSURE_ALLOCATION (length + n);
Packit Service 963350
        memcpy (result + length, cp, n);
Packit Service 963350
        length += n;
Packit Service 963350
      }
Packit Service 963350
      if (i == d.count)
Packit Service 963350
        break;
Packit Service 963350
Packit Service 963350
      /* Execute a single directive.  */
Packit Service 963350
      if (dp->conversion == '%') {
Packit Service 963350
        if (!(dp->arg_index < 0))
Packit Service 963350
          abort ();
Packit Service 963350
        ENSURE_ALLOCATION (length + 1);
Packit Service 963350
        result[length] = '%';
Packit Service 963350
        length += 1;
Packit Service 963350
      } else {
Packit Service 963350
        if (!(dp->arg_index >= 0))
Packit Service 963350
          abort ();
Packit Service 963350
Packit Service 963350
        if (dp->conversion == 'n') {
Packit Service 963350
          switch (a.arg[dp->arg_index].type) {
Packit Service 963350
            case TYPE_COUNT_SCHAR_POINTER:
Packit Service 963350
              *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
Packit Service 963350
              break;
Packit Service 963350
            case TYPE_COUNT_SHORT_POINTER:
Packit Service 963350
              *a.arg[dp->arg_index].a.a_count_short_pointer = length;
Packit Service 963350
              break;
Packit Service 963350
            case TYPE_COUNT_INT_POINTER:
Packit Service 963350
              *a.arg[dp->arg_index].a.a_count_int_pointer = length;
Packit Service 963350
              break;
Packit Service 963350
            case TYPE_COUNT_LONGINT_POINTER:
Packit Service 963350
              *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
Packit Service 963350
              break;
Packit Service 963350
#ifdef HAVE_LONG_LONG
Packit Service 963350
            case TYPE_COUNT_LONGLONGINT_POINTER:
Packit Service 963350
              *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
Packit Service 963350
              break;
Packit Service 963350
#endif
Packit Service 963350
            default:
Packit Service 963350
              abort ();
Packit Service 963350
          }
Packit Service 963350
        } else {
Packit Service 963350
          arg_type type = a.arg[dp->arg_index].type;
Packit Service 963350
          char *p;
Packit Service 963350
          unsigned int prefix_count;
Packit Service 963350
          int prefixes[2];
Packit Service 963350
#ifndef HAVE_SNPRINTF
Packit Service 963350
          unsigned int tmp_length;
Packit Service 963350
          char tmpbuf[700];
Packit Service 963350
          char *tmp;
Packit Service 963350
Packit Service 963350
          /* Allocate a temporary buffer of sufficient size for calling
Packit Service 963350
             sprintf.  */
Packit Service 963350
          {
Packit Service 963350
            unsigned int width;
Packit Service 963350
            unsigned int precision;
Packit Service 963350
Packit Service 963350
            width = 0;
Packit Service 963350
            if (dp->width_start != dp->width_end) {
Packit Service 963350
              if (dp->width_arg_index >= 0) {
Packit Service 963350
                int arg;
Packit Service 963350
Packit Service 963350
                if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
Packit Service 963350
                  abort ();
Packit Service 963350
                arg = a.arg[dp->width_arg_index].a.a_int;
Packit Service 963350
                width = (arg < 0 ? -arg : arg);
Packit Service 963350
              } else {
Packit Service 963350
                const char *digitp = dp->width_start;
Packit Service 963350
Packit Service 963350
                do
Packit Service 963350
                  width = width * 10 + (*digitp++ - '0');
Packit Service 963350
                while (digitp != dp->width_end);
Packit Service 963350
              }
Packit Service 963350
            }
Packit Service 963350
Packit Service 963350
            precision = 6;
Packit Service 963350
            if (dp->precision_start != dp->precision_end) {
Packit Service 963350
              if (dp->precision_arg_index >= 0) {
Packit Service 963350
                int arg;
Packit Service 963350
Packit Service 963350
                if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
Packit Service 963350
                  abort ();
Packit Service 963350
                arg = a.arg[dp->precision_arg_index].a.a_int;
Packit Service 963350
                precision = (arg < 0 ? 0 : arg);
Packit Service 963350
              } else {
Packit Service 963350
                const char *digitp = dp->precision_start + 1;
Packit Service 963350
Packit Service 963350
                precision = 0;
Packit Service 963350
                while (digitp != dp->precision_end)
Packit Service 963350
                  precision = precision * 10 + (*digitp++ - '0');
Packit Service 963350
              }
Packit Service 963350
            }
Packit Service 963350
Packit Service 963350
            switch (dp->conversion) {
Packit Service 963350
              case 'd':
Packit Service 963350
              case 'i':
Packit Service 963350
              case 'u':
Packit Service 963350
# ifdef HAVE_LONG_LONG
Packit Service 963350
                if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
Packit Service 963350
                  tmp_length = (unsigned int) (sizeof (unsigned long long) * CHAR_BIT * 0.30103 /* binary -> decimal */
Packit Service 963350
                      * 2       /* estimate for FLAG_GROUP */
Packit Service 963350
                      )
Packit Service 963350
                      + 1       /* turn floor into ceil */
Packit Service 963350
                      + 1;      /* account for leading sign */
Packit Service 963350
                else
Packit Service 963350
# endif
Packit Service 963350
                if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
Packit Service 963350
                  tmp_length = (unsigned int) (sizeof (unsigned long) * CHAR_BIT * 0.30103      /* binary -> decimal */
Packit Service 963350
                      * 2       /* estimate for FLAG_GROUP */
Packit Service 963350
                      )
Packit Service 963350
                      + 1       /* turn floor into ceil */
Packit Service 963350
                      + 1;      /* account for leading sign */
Packit Service 963350
                else
Packit Service 963350
                  tmp_length = (unsigned int) (sizeof (unsigned int) * CHAR_BIT * 0.30103       /* binary -> decimal */
Packit Service 963350
                      * 2       /* estimate for FLAG_GROUP */
Packit Service 963350
                      )
Packit Service 963350
                      + 1       /* turn floor into ceil */
Packit Service 963350
                      + 1;      /* account for leading sign */
Packit Service 963350
                break;
Packit Service 963350
Packit Service 963350
              case 'o':
Packit Service 963350
# ifdef HAVE_LONG_LONG
Packit Service 963350
                if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
Packit Service 963350
                  tmp_length = (unsigned int) (sizeof (unsigned long long) * CHAR_BIT * 0.333334        /* binary -> octal */
Packit Service 963350
                      )
Packit Service 963350
                      + 1       /* turn floor into ceil */
Packit Service 963350
                      + 1;      /* account for leading sign */
Packit Service 963350
                else
Packit Service 963350
# endif
Packit Service 963350
                if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
Packit Service 963350
                  tmp_length = (unsigned int) (sizeof (unsigned long) * CHAR_BIT * 0.333334     /* binary -> octal */
Packit Service 963350
                      )
Packit Service 963350
                      + 1       /* turn floor into ceil */
Packit Service 963350
                      + 1;      /* account for leading sign */
Packit Service 963350
                else
Packit Service 963350
                  tmp_length = (unsigned int) (sizeof (unsigned int) * CHAR_BIT * 0.333334      /* binary -> octal */
Packit Service 963350
                      )
Packit Service 963350
                      + 1       /* turn floor into ceil */
Packit Service 963350
                      + 1;      /* account for leading sign */
Packit Service 963350
                break;
Packit Service 963350
Packit Service 963350
              case 'x':
Packit Service 963350
              case 'X':
Packit Service 963350
# ifdef HAVE_LONG_LONG
Packit Service 963350
                if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
Packit Service 963350
                  tmp_length = (unsigned int) (sizeof (unsigned long long) * CHAR_BIT * 0.25    /* binary -> hexadecimal */
Packit Service 963350
                      )
Packit Service 963350
                      + 1       /* turn floor into ceil */
Packit Service 963350
                      + 2;      /* account for leading sign or alternate form */
Packit Service 963350
                else
Packit Service 963350
# endif
Packit Service 963350
# ifdef HAVE_INT64_AND_I64
Packit Service 963350
                if (type == TYPE_INT64 || type == TYPE_UINT64)
Packit Service 963350
                  tmp_length = (unsigned int) (sizeof (unsigned __int64) * CHAR_BIT * 0.25      /* binary -> hexadecimal */
Packit Service 963350
                      )
Packit Service 963350
                      + 1       /* turn floor into ceil */
Packit Service 963350
                      + 2;      /* account for leading sign or alternate form */
Packit Service 963350
                else
Packit Service 963350
# endif
Packit Service 963350
                if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
Packit Service 963350
                  tmp_length = (unsigned int) (sizeof (unsigned long) * CHAR_BIT * 0.25 /* binary -> hexadecimal */
Packit Service 963350
                      )
Packit Service 963350
                      + 1       /* turn floor into ceil */
Packit Service 963350
                      + 2;      /* account for leading sign or alternate form */
Packit Service 963350
                else
Packit Service 963350
                  tmp_length = (unsigned int) (sizeof (unsigned int) * CHAR_BIT * 0.25  /* binary -> hexadecimal */
Packit Service 963350
                      )
Packit Service 963350
                      + 1       /* turn floor into ceil */
Packit Service 963350
                      + 2;      /* account for leading sign or alternate form */
Packit Service 963350
                break;
Packit Service 963350
Packit Service 963350
              case 'f':
Packit Service 963350
              case 'F':
Packit Service 963350
# ifdef HAVE_LONG_DOUBLE
Packit Service 963350
                if (type == TYPE_LONGDOUBLE)
Packit Service 963350
                  tmp_length = (unsigned int) (LDBL_MAX_EXP * 0.30103   /* binary -> decimal */
Packit Service 963350
                      * 2       /* estimate for FLAG_GROUP */
Packit Service 963350
                      )
Packit Service 963350
                      + 1       /* turn floor into ceil */
Packit Service 963350
                      + precision + 10; /* sign, decimal point etc. */
Packit Service 963350
                else
Packit Service 963350
# endif
Packit Service 963350
                  tmp_length = (unsigned int) (DBL_MAX_EXP * 0.30103    /* binary -> decimal */
Packit Service 963350
                      * 2       /* estimate for FLAG_GROUP */
Packit Service 963350
                      )
Packit Service 963350
                      + 1       /* turn floor into ceil */
Packit Service 963350
                      + precision + 10; /* sign, decimal point etc. */
Packit Service 963350
                break;
Packit Service 963350
Packit Service 963350
              case 'e':
Packit Service 963350
              case 'E':
Packit Service 963350
              case 'g':
Packit Service 963350
              case 'G':
Packit Service 963350
              case 'a':
Packit Service 963350
              case 'A':
Packit Service 963350
                tmp_length = precision + 12;    /* sign, decimal point, exponent etc. */
Packit Service 963350
                break;
Packit Service 963350
Packit Service 963350
              case 'c':
Packit Service 963350
# ifdef HAVE_WINT_T
Packit Service 963350
                if (type == TYPE_WIDE_CHAR)
Packit Service 963350
                  tmp_length = MB_CUR_MAX;
Packit Service 963350
                else
Packit Service 963350
# endif
Packit Service 963350
                  tmp_length = 1;
Packit Service 963350
                break;
Packit Service 963350
Packit Service 963350
              case 's':
Packit Service 963350
# ifdef HAVE_WCHAR_T
Packit Service 963350
                if (type == TYPE_WIDE_STRING)
Packit Service 963350
                  tmp_length = (a.arg[dp->arg_index].a.a_wide_string == NULL ? 6        /* wcslen(L"(null)") */
Packit Service 963350
                      : local_wcslen (a.arg[dp->arg_index].a.a_wide_string))
Packit Service 963350
                      * MB_CUR_MAX;
Packit Service 963350
                else
Packit Service 963350
# endif
Packit Service 963350
                  tmp_length = a.arg[dp->arg_index].a.a_string == NULL ? 6      /* strlen("(null)") */
Packit Service 963350
                      : strlen (a.arg[dp->arg_index].a.a_string);
Packit Service 963350
                break;
Packit Service 963350
Packit Service 963350
              case 'p':
Packit Service 963350
                tmp_length = (unsigned int) (sizeof (void *) * CHAR_BIT * 0.25  /* binary -> hexadecimal */
Packit Service 963350
                    )
Packit Service 963350
                    + 1         /* turn floor into ceil */
Packit Service 963350
                    + 2;        /* account for leading 0x */
Packit Service 963350
Packit Service 963350
                /* make sure we always have enough space for a plain %p, so + */
Packit Service 963350
                if (dp->flags & FLAG_PTR_EXT && a.arg[dp->arg_index].ext_string)
Packit Service 963350
                  tmp_length += strlen (a.arg[dp->arg_index].ext_string);
Packit Service 963350
                break;
Packit Service 963350
Packit Service 963350
              default:
Packit Service 963350
                abort ();
Packit Service 963350
            }
Packit Service 963350
Packit Service 963350
            if (tmp_length < width)
Packit Service 963350
              tmp_length = width;
Packit Service 963350
Packit Service 963350
            tmp_length++;       /* account for trailing NUL */
Packit Service 963350
          }
Packit Service 963350
Packit Service 963350
          if (tmp_length <= sizeof (tmpbuf))
Packit Service 963350
            tmp = tmpbuf;
Packit Service 963350
          else {
Packit Service 963350
            tmp = (char *) malloc (tmp_length);
Packit Service 963350
            if (tmp == NULL) {
Packit Service 963350
              /* Out of memory.  */
Packit Service 963350
              if (!(result == resultbuf || result == NULL))
Packit Service 963350
                free (result);
Packit Service 963350
              freea (buf);
Packit Service 963350
              CLEANUP ();
Packit Service 963350
              errno = ENOMEM;
Packit Service 963350
              return NULL;
Packit Service 963350
            }
Packit Service 963350
          }
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
          /* Construct the format string for calling snprintf or
Packit Service 963350
             sprintf.  */
Packit Service 963350
          p = buf;
Packit Service 963350
          *p++ = '%';
Packit Service 963350
          if (dp->flags & FLAG_GROUP)
Packit Service 963350
            *p++ = '\'';
Packit Service 963350
          if (dp->flags & FLAG_LEFT)
Packit Service 963350
            *p++ = '-';
Packit Service 963350
          if (dp->flags & FLAG_SHOWSIGN)
Packit Service 963350
            *p++ = '+';
Packit Service 963350
          if (dp->flags & FLAG_SPACE)
Packit Service 963350
            *p++ = ' ';
Packit Service 963350
          if (dp->flags & FLAG_ALT)
Packit Service 963350
            *p++ = '#';
Packit Service 963350
          if (dp->flags & FLAG_ZERO)
Packit Service 963350
            *p++ = '0';
Packit Service 963350
          if (dp->width_start != dp->width_end) {
Packit Service 963350
            size_t n = dp->width_end - dp->width_start;
Packit Service 963350
            memcpy (p, dp->width_start, n);
Packit Service 963350
            p += n;
Packit Service 963350
          }
Packit Service 963350
          if (dp->precision_start != dp->precision_end) {
Packit Service 963350
            size_t n = dp->precision_end - dp->precision_start;
Packit Service 963350
            memcpy (p, dp->precision_start, n);
Packit Service 963350
            p += n;
Packit Service 963350
          }
Packit Service 963350
Packit Service 963350
          switch (type) {
Packit Service 963350
#ifdef HAVE_INT64_AND_I64
Packit Service 963350
            case TYPE_INT64:
Packit Service 963350
            case TYPE_UINT64:
Packit Service 963350
              *p++ = 'I';
Packit Service 963350
              *p++ = '6';
Packit Service 963350
              *p++ = '4';
Packit Service 963350
              break;
Packit Service 963350
#endif
Packit Service 963350
#ifdef HAVE_LONG_LONG
Packit Service 963350
            case TYPE_LONGLONGINT:
Packit Service 963350
            case TYPE_ULONGLONGINT:
Packit Service 963350
#ifdef HAVE_INT64_AND_I64       /* The system (sn)printf uses %I64. Also assume
Packit Service 963350
                                 * that long long == __int64.
Packit Service 963350
                                 */
Packit Service 963350
              *p++ = 'I';
Packit Service 963350
              *p++ = '6';
Packit Service 963350
              *p++ = '4';
Packit Service 963350
              break;
Packit Service 963350
#else
Packit Service 963350
              *p++ = 'l';
Packit Service 963350
               /*FALLTHROUGH*/
Packit Service 963350
#endif
Packit Service 963350
#endif
Packit Service 963350
            case TYPE_LONGINT:
Packit Service 963350
            case TYPE_ULONGINT:
Packit Service 963350
#ifdef HAVE_WINT_T
Packit Service 963350
            case TYPE_WIDE_CHAR:
Packit Service 963350
#endif
Packit Service 963350
#ifdef HAVE_WCHAR_T
Packit Service 963350
            case TYPE_WIDE_STRING:
Packit Service 963350
#endif
Packit Service 963350
              *p++ = 'l';
Packit Service 963350
              break;
Packit Service 963350
#ifdef HAVE_LONG_DOUBLE
Packit Service 963350
            case TYPE_LONGDOUBLE:
Packit Service 963350
              *p++ = 'L';
Packit Service 963350
              break;
Packit Service 963350
#endif
Packit Service 963350
            default:
Packit Service 963350
              break;
Packit Service 963350
          }
Packit Service 963350
          *p = dp->conversion;
Packit Service 963350
#ifdef HAVE_SNPRINTF
Packit Service 963350
          p[1] = '%';
Packit Service 963350
          p[2] = 'n';
Packit Service 963350
          p[3] = '\0';
Packit Service 963350
#else
Packit Service 963350
          p[1] = '\0';
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
          /* Construct the arguments for calling snprintf or sprintf.  */
Packit Service 963350
          prefix_count = 0;
Packit Service 963350
          if (dp->width_arg_index >= 0) {
Packit Service 963350
            if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
Packit Service 963350
              abort ();
Packit Service 963350
            prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
Packit Service 963350
          }
Packit Service 963350
          if (dp->precision_arg_index >= 0) {
Packit Service 963350
            if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
Packit Service 963350
              abort ();
Packit Service 963350
            prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
Packit Service 963350
          }
Packit Service 963350
#ifdef HAVE_SNPRINTF
Packit Service 963350
          /* Prepare checking whether snprintf returns the count
Packit Service 963350
             via %n.  */
Packit Service 963350
          ENSURE_ALLOCATION (length + 1);
Packit Service 963350
          result[length] = '\0';
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
          for (;;) {
Packit Service 963350
            size_t maxlen;
Packit Service 963350
            int count;
Packit Service 963350
#ifdef HAVE_SNPRINTF
Packit Service 963350
            int retcount;
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
            maxlen = allocated - length;
Packit Service 963350
            count = -1;
Packit Service 963350
Packit Service 963350
#ifdef HAVE_SNPRINTF
Packit Service 963350
            retcount = 0;
Packit Service 963350
Packit Service 963350
#define SNPRINTF_BUF(arg) \
Packit Service 963350
		    switch (prefix_count)				    \
Packit Service 963350
		      {							    \
Packit Service 963350
		      case 0:						    \
Packit Service 963350
			retcount = snprintf (result + length, maxlen, buf,  \
Packit Service 963350
					     arg, &count);		    \
Packit Service 963350
			break;						    \
Packit Service 963350
		      case 1:						    \
Packit Service 963350
			retcount = snprintf (result + length, maxlen, buf,  \
Packit Service 963350
					     prefixes[0], arg, &count);	    \
Packit Service 963350
			break;						    \
Packit Service 963350
		      case 2:						    \
Packit Service 963350
			retcount = snprintf (result + length, maxlen, buf,  \
Packit Service 963350
					     prefixes[0], prefixes[1], arg, \
Packit Service 963350
					     &count);			    \
Packit Service 963350
			break;						    \
Packit Service 963350
		      default:						    \
Packit Service 963350
			abort ();					    \
Packit Service 963350
		      }
Packit Service 963350
#else
Packit Service 963350
#define SNPRINTF_BUF(arg) \
Packit Service 963350
		    switch (prefix_count)				    \
Packit Service 963350
		      {							    \
Packit Service 963350
		      case 0:						    \
Packit Service 963350
			count = sprintf (tmp, buf, arg);		    \
Packit Service 963350
			break;						    \
Packit Service 963350
		      case 1:						    \
Packit Service 963350
			count = sprintf (tmp, buf, prefixes[0], arg);	    \
Packit Service 963350
			break;						    \
Packit Service 963350
		      case 2:						    \
Packit Service 963350
			count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
Packit Service 963350
					 arg);				    \
Packit Service 963350
			break;						    \
Packit Service 963350
		      default:						    \
Packit Service 963350
			abort ();					    \
Packit Service 963350
		      }
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
            switch (type) {
Packit Service 963350
              case TYPE_SCHAR:
Packit Service 963350
              {
Packit Service 963350
                int arg = a.arg[dp->arg_index].a.a_schar;
Packit Service 963350
                SNPRINTF_BUF (arg);
Packit Service 963350
              }
Packit Service 963350
                break;
Packit Service 963350
              case TYPE_UCHAR:
Packit Service 963350
              {
Packit Service 963350
                unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
Packit Service 963350
                SNPRINTF_BUF (arg);
Packit Service 963350
              }
Packit Service 963350
                break;
Packit Service 963350
              case TYPE_SHORT:
Packit Service 963350
              {
Packit Service 963350
                int arg = a.arg[dp->arg_index].a.a_short;
Packit Service 963350
                SNPRINTF_BUF (arg);
Packit Service 963350
              }
Packit Service 963350
                break;
Packit Service 963350
              case TYPE_USHORT:
Packit Service 963350
              {
Packit Service 963350
                unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
Packit Service 963350
                SNPRINTF_BUF (arg);
Packit Service 963350
              }
Packit Service 963350
                break;
Packit Service 963350
              case TYPE_INT:
Packit Service 963350
              {
Packit Service 963350
                int arg = a.arg[dp->arg_index].a.a_int;
Packit Service 963350
                SNPRINTF_BUF (arg);
Packit Service 963350
              }
Packit Service 963350
                break;
Packit Service 963350
              case TYPE_UINT:
Packit Service 963350
              {
Packit Service 963350
                unsigned int arg = a.arg[dp->arg_index].a.a_uint;
Packit Service 963350
                SNPRINTF_BUF (arg);
Packit Service 963350
              }
Packit Service 963350
                break;
Packit Service 963350
              case TYPE_LONGINT:
Packit Service 963350
              {
Packit Service 963350
                long int arg = a.arg[dp->arg_index].a.a_longint;
Packit Service 963350
                SNPRINTF_BUF (arg);
Packit Service 963350
              }
Packit Service 963350
                break;
Packit Service 963350
              case TYPE_ULONGINT:
Packit Service 963350
              {
Packit Service 963350
                unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
Packit Service 963350
                SNPRINTF_BUF (arg);
Packit Service 963350
              }
Packit Service 963350
                break;
Packit Service 963350
#ifdef HAVE_INT64_AND_I64
Packit Service 963350
              case TYPE_INT64:
Packit Service 963350
              {
Packit Service 963350
                __int64 arg = a.arg[dp->arg_index].a.a_int64;
Packit Service 963350
                SNPRINTF_BUF (arg);
Packit Service 963350
              }
Packit Service 963350
                break;
Packit Service 963350
              case TYPE_UINT64:
Packit Service 963350
              {
Packit Service 963350
                unsigned __int64 arg = a.arg[dp->arg_index].a.a_uint64;
Packit Service 963350
                SNPRINTF_BUF (arg);
Packit Service 963350
              }
Packit Service 963350
                break;
Packit Service 963350
#endif
Packit Service 963350
#ifdef HAVE_LONG_LONG
Packit Service 963350
#ifndef HAVE_LONG_LONG_FORMAT
Packit Service 963350
              case TYPE_LONGLONGINT:
Packit Service 963350
              case TYPE_ULONGLONGINT:
Packit Service 963350
              {
Packit Service 963350
                unsigned long long int arg =
Packit Service 963350
                    a.arg[dp->arg_index].a.a_ulonglongint;
Packit Service 963350
                int width;
Packit Service 963350
                int precision;
Packit Service 963350
Packit Service 963350
                width = 0;
Packit Service 963350
                if (dp->width_start != dp->width_end) {
Packit Service 963350
                  if (dp->width_arg_index >= 0) {
Packit Service 963350
                    int arg;
Packit Service 963350
Packit Service 963350
                    if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
Packit Service 963350
                      abort ();
Packit Service 963350
                    arg = a.arg[dp->width_arg_index].a.a_int;
Packit Service 963350
                    width = (arg < 0 ? -arg : arg);
Packit Service 963350
                  } else {
Packit Service 963350
                    const char *digitp = dp->width_start;
Packit Service 963350
Packit Service 963350
                    do
Packit Service 963350
                      width = width * 10 + (*digitp++ - '0');
Packit Service 963350
                    while (digitp != dp->width_end);
Packit Service 963350
                  }
Packit Service 963350
                }
Packit Service 963350
Packit Service 963350
                precision = -1;
Packit Service 963350
                if (dp->precision_start != dp->precision_end) {
Packit Service 963350
                  if (dp->precision_arg_index >= 0) {
Packit Service 963350
                    int arg;
Packit Service 963350
Packit Service 963350
                    if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
Packit Service 963350
                      abort ();
Packit Service 963350
                    arg = a.arg[dp->precision_arg_index].a.a_int;
Packit Service 963350
                    precision = (arg < 0 ? 0 : arg);
Packit Service 963350
                  } else {
Packit Service 963350
                    const char *digitp = dp->precision_start + 1;
Packit Service 963350
Packit Service 963350
                    precision = 0;
Packit Service 963350
                    do
Packit Service 963350
                      precision = precision * 10 + (*digitp++ - '0');
Packit Service 963350
                    while (digitp != dp->precision_end);
Packit Service 963350
                  }
Packit Service 963350
                }
Packit Service 963350
#ifdef HAVE_SNPRINTF
Packit Service 963350
                count = print_long_long (result + length, maxlen,
Packit Service 963350
                    width, precision, dp->flags, dp->conversion, arg);
Packit Service 963350
#else
Packit Service 963350
                count = print_long_long (tmp, tmp_length,
Packit Service 963350
                    width, precision, dp->flags, dp->conversion, arg);
Packit Service 963350
#endif
Packit Service 963350
              }
Packit Service 963350
                break;
Packit Service 963350
#else
Packit Service 963350
              case TYPE_LONGLONGINT:
Packit Service 963350
              {
Packit Service 963350
                long long int arg = a.arg[dp->arg_index].a.a_longlongint;
Packit Service 963350
                SNPRINTF_BUF (arg);
Packit Service 963350
              }
Packit Service 963350
                break;
Packit Service 963350
              case TYPE_ULONGLONGINT:
Packit Service 963350
              {
Packit Service 963350
                unsigned long long int arg =
Packit Service 963350
                    a.arg[dp->arg_index].a.a_ulonglongint;
Packit Service 963350
                SNPRINTF_BUF (arg);
Packit Service 963350
              }
Packit Service 963350
                break;
Packit Service 963350
#endif
Packit Service 963350
#endif
Packit Service 963350
              case TYPE_DOUBLE:
Packit Service 963350
              {
Packit Service 963350
                double arg = a.arg[dp->arg_index].a.a_double;
Packit Service 963350
                SNPRINTF_BUF (arg);
Packit Service 963350
              }
Packit Service 963350
                break;
Packit Service 963350
#ifdef HAVE_LONG_DOUBLE
Packit Service 963350
              case TYPE_LONGDOUBLE:
Packit Service 963350
              {
Packit Service 963350
                long double arg = a.arg[dp->arg_index].a.a_longdouble;
Packit Service 963350
                SNPRINTF_BUF (arg);
Packit Service 963350
              }
Packit Service 963350
                break;
Packit Service 963350
#endif
Packit Service 963350
              case TYPE_CHAR:
Packit Service 963350
              {
Packit Service 963350
                int arg = a.arg[dp->arg_index].a.a_char;
Packit Service 963350
                SNPRINTF_BUF (arg);
Packit Service 963350
              }
Packit Service 963350
                break;
Packit Service 963350
#ifdef HAVE_WINT_T
Packit Service 963350
              case TYPE_WIDE_CHAR:
Packit Service 963350
              {
Packit Service 963350
                wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
Packit Service 963350
                SNPRINTF_BUF (arg);
Packit Service 963350
              }
Packit Service 963350
                break;
Packit Service 963350
#endif
Packit Service 963350
              case TYPE_STRING:
Packit Service 963350
              {
Packit Service 963350
                const char *arg = a.arg[dp->arg_index].a.a_string == NULL
Packit Service 963350
                    ? "(null)" : a.arg[dp->arg_index].a.a_string;
Packit Service 963350
                SNPRINTF_BUF (arg);
Packit Service 963350
              }
Packit Service 963350
                break;
Packit Service 963350
#ifdef HAVE_WCHAR_T
Packit Service 963350
              case TYPE_WIDE_STRING:
Packit Service 963350
              {
Packit Service 963350
                const wchar_t *arg =
Packit Service 963350
                    a.arg[dp->arg_index].a.a_wide_string ==
Packit Service 963350
                    NULL ? L"(null)" : a.arg[dp->arg_index].a.a_wide_string;
Packit Service 963350
                SNPRINTF_BUF (arg);
Packit Service 963350
              }
Packit Service 963350
                break;
Packit Service 963350
#endif
Packit Service 963350
              case TYPE_POINTER:
Packit Service 963350
              {
Packit Service 963350
                void *arg = a.arg[dp->arg_index].a.a_pointer;
Packit Service 963350
                SNPRINTF_BUF (arg);
Packit Service 963350
              }
Packit Service 963350
                break;
Packit Service 963350
              case TYPE_POINTER_EXT:
Packit Service 963350
              {
Packit Service 963350
                void *arg = a.arg[dp->arg_index].a.a_pointer;
Packit Service 963350
Packit Service 963350
                if (a.arg[dp->arg_index].ext_string != NULL) {
Packit Service 963350
                  arg = a.arg[dp->arg_index].ext_string;
Packit Service 963350
                  *p = 's';
Packit Service 963350
                }
Packit Service 963350
Packit Service 963350
                SNPRINTF_BUF (arg);
Packit Service 963350
              }
Packit Service 963350
                break;
Packit Service 963350
              default:
Packit Service 963350
                abort ();
Packit Service 963350
            }
Packit Service 963350
Packit Service 963350
#ifdef HAVE_SNPRINTF
Packit Service 963350
            /* Portability: Not all implementations of snprintf()
Packit Service 963350
               are ISO C 99 compliant.  Determine the number of
Packit Service 963350
               bytes that snprintf() has produced or would have
Packit Service 963350
               produced.  */
Packit Service 963350
            if (count >= 0) {
Packit Service 963350
              /* Verify that snprintf() has NUL-terminated its
Packit Service 963350
                 result.  */
Packit Service 963350
              if (count < maxlen && result[length + count] != '\0')
Packit Service 963350
                abort ();
Packit Service 963350
              /* Portability hack.  */
Packit Service 963350
              if (retcount > count)
Packit Service 963350
                count = retcount;
Packit Service 963350
            } else {
Packit Service 963350
              /* snprintf() doesn't understand the '%n'
Packit Service 963350
                 directive.  */
Packit Service 963350
              if (p[1] != '\0') {
Packit Service 963350
                /* Don't use the '%n' directive; instead, look
Packit Service 963350
                   at the snprintf() return value.  */
Packit Service 963350
                p[1] = '\0';
Packit Service 963350
                continue;
Packit Service 963350
              }
Packit Service 963350
              count = retcount;
Packit Service 963350
            }
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
            /* Attempt to handle failure.  */
Packit Service 963350
            if (count < 0) {
Packit Service 963350
              if (!(result == resultbuf || result == NULL))
Packit Service 963350
                free (result);
Packit Service 963350
              freea (buf);
Packit Service 963350
              CLEANUP ();
Packit Service 963350
              errno = EINVAL;
Packit Service 963350
              return NULL;
Packit Service 963350
            }
Packit Service 963350
#ifndef HAVE_SNPRINTF
Packit Service 963350
            if (count >= tmp_length)
Packit Service 963350
              /* tmp_length was incorrectly calculated - fix the
Packit Service 963350
                 code above!  */
Packit Service 963350
              abort ();
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
            /* Make room for the result.  */
Packit Service 963350
            if (count >= maxlen) {
Packit Service 963350
              /* Need at least count bytes.  But allocate
Packit Service 963350
                 proportionally, to avoid looping eternally if
Packit Service 963350
                 snprintf() reports a too small count.  */
Packit Service 963350
              size_t n = length + count;
Packit Service 963350
Packit Service 963350
              if (n < 2 * allocated)
Packit Service 963350
                n = 2 * allocated;
Packit Service 963350
Packit Service 963350
              ENSURE_ALLOCATION (n);
Packit Service 963350
#ifdef HAVE_SNPRINTF
Packit Service 963350
              continue;
Packit Service 963350
#endif
Packit Service 963350
            }
Packit Service 963350
#ifdef HAVE_SNPRINTF
Packit Service 963350
            /* The snprintf() result did fit.  */
Packit Service 963350
#else
Packit Service 963350
            /* Append the sprintf() result.  */
Packit Service 963350
            memcpy (result + length, tmp, count);
Packit Service 963350
            if (tmp != tmpbuf)
Packit Service 963350
              free (tmp);
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
            length += count;
Packit Service 963350
            break;
Packit Service 963350
          }
Packit Service 963350
        }
Packit Service 963350
      }
Packit Service 963350
    }
Packit Service 963350
Packit Service 963350
    /* Add the final NUL.  */
Packit Service 963350
    ENSURE_ALLOCATION (length + 1);
Packit Service 963350
    result[length] = '\0';
Packit Service 963350
Packit Service 963350
    if (result != resultbuf && length + 1 < allocated) {
Packit Service 963350
      /* Shrink the allocated memory if possible.  */
Packit Service 963350
      char *memory;
Packit Service 963350
Packit Service 963350
      memory = (char *) realloc (result, length + 1);
Packit Service 963350
      if (memory != NULL)
Packit Service 963350
        result = memory;
Packit Service 963350
    }
Packit Service 963350
Packit Service 963350
    freea (buf);
Packit Service 963350
    CLEANUP ();
Packit Service 963350
    *lengthp = length;
Packit Service 963350
    return result;
Packit Service 963350
  }
Packit Service 963350
}