Blame lib/printf-args.c

Packit Service fdd496
/* Decomposed printf argument list.
Packit Service fdd496
   Copyright (C) 1999, 2002-2003, 2005-2007, 2009-2017 Free Software
Packit Service fdd496
   Foundation, Inc.
Packit Service fdd496
Packit Service fdd496
   This program is free software; you can redistribute it and/or modify
Packit Service fdd496
   it under the terms of the GNU General Public License as published by
Packit Service fdd496
   the Free Software Foundation; either version 3, or (at your option)
Packit Service fdd496
   any later version.
Packit Service fdd496
Packit Service fdd496
   This program is distributed in the hope that it will be useful,
Packit Service fdd496
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service fdd496
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service fdd496
   GNU General Public License for more details.
Packit Service fdd496
Packit Service fdd496
   You should have received a copy of the GNU General Public License along
Packit Service fdd496
   with this program; if not, see <http://www.gnu.org/licenses/>.  */
Packit Service fdd496
Packit Service fdd496
/* This file can be parametrized with the following macros:
Packit Service fdd496
     ENABLE_UNISTDIO    Set to 1 to enable the unistdio extensions.
Packit Service fdd496
     PRINTF_FETCHARGS   Name of the function to be defined.
Packit Service fdd496
     STATIC             Set to 'static' to declare the function static.  */
Packit Service fdd496
Packit Service fdd496
#ifndef PRINTF_FETCHARGS
Packit Service fdd496
# include <config.h>
Packit Service fdd496
#endif
Packit Service fdd496
Packit Service fdd496
/* Specification.  */
Packit Service fdd496
#ifndef PRINTF_FETCHARGS
Packit Service fdd496
# include "printf-args.h"
Packit Service fdd496
#endif
Packit Service fdd496
Packit Service fdd496
#ifdef STATIC
Packit Service fdd496
STATIC
Packit Service fdd496
#endif
Packit Service fdd496
int
Packit Service fdd496
PRINTF_FETCHARGS (va_list args, arguments *a)
Packit Service fdd496
{
Packit Service fdd496
  size_t i;
Packit Service fdd496
  argument *ap;
Packit Service fdd496
Packit Service fdd496
  for (i = 0, ap = &a->arg[0]; i < a->count; i++, ap++)
Packit Service fdd496
    switch (ap->type)
Packit Service fdd496
      {
Packit Service fdd496
      case TYPE_SCHAR:
Packit Service fdd496
        ap->a.a_schar = va_arg (args, /*signed char*/ int);
Packit Service fdd496
        break;
Packit Service fdd496
      case TYPE_UCHAR:
Packit Service fdd496
        ap->a.a_uchar = va_arg (args, /*unsigned char*/ int);
Packit Service fdd496
        break;
Packit Service fdd496
      case TYPE_SHORT:
Packit Service fdd496
        ap->a.a_short = va_arg (args, /*short*/ int);
Packit Service fdd496
        break;
Packit Service fdd496
      case TYPE_USHORT:
Packit Service fdd496
        ap->a.a_ushort = va_arg (args, /*unsigned short*/ int);
Packit Service fdd496
        break;
Packit Service fdd496
      case TYPE_INT:
Packit Service fdd496
        ap->a.a_int = va_arg (args, int);
Packit Service fdd496
        break;
Packit Service fdd496
      case TYPE_UINT:
Packit Service fdd496
        ap->a.a_uint = va_arg (args, unsigned int);
Packit Service fdd496
        break;
Packit Service fdd496
      case TYPE_LONGINT:
Packit Service fdd496
        ap->a.a_longint = va_arg (args, long int);
Packit Service fdd496
        break;
Packit Service fdd496
      case TYPE_ULONGINT:
Packit Service fdd496
        ap->a.a_ulongint = va_arg (args, unsigned long int);
Packit Service fdd496
        break;
Packit Service fdd496
#if HAVE_LONG_LONG_INT
Packit Service fdd496
      case TYPE_LONGLONGINT:
Packit Service fdd496
        ap->a.a_longlongint = va_arg (args, long long int);
Packit Service fdd496
        break;
Packit Service fdd496
      case TYPE_ULONGLONGINT:
Packit Service fdd496
        ap->a.a_ulonglongint = va_arg (args, unsigned long long int);
Packit Service fdd496
        break;
Packit Service fdd496
#endif
Packit Service fdd496
      case TYPE_DOUBLE:
Packit Service fdd496
        ap->a.a_double = va_arg (args, double);
Packit Service fdd496
        break;
Packit Service fdd496
      case TYPE_LONGDOUBLE:
Packit Service fdd496
        ap->a.a_longdouble = va_arg (args, long double);
Packit Service fdd496
        break;
Packit Service fdd496
      case TYPE_CHAR:
Packit Service fdd496
        ap->a.a_char = va_arg (args, int);
Packit Service fdd496
        break;
Packit Service fdd496
#if HAVE_WINT_T
Packit Service fdd496
      case TYPE_WIDE_CHAR:
Packit Service fdd496
        /* Although ISO C 99 7.24.1.(2) says that wint_t is "unchanged by
Packit Service fdd496
           default argument promotions", this is not the case in mingw32,
Packit Service fdd496
           where wint_t is 'unsigned short'.  */
Packit Service fdd496
        ap->a.a_wide_char =
Packit Service fdd496
          (sizeof (wint_t) < sizeof (int)
Packit Service fdd496
           ? (wint_t) va_arg (args, int)
Packit Service fdd496
           : va_arg (args, wint_t));
Packit Service fdd496
        break;
Packit Service fdd496
#endif
Packit Service fdd496
      case TYPE_STRING:
Packit Service fdd496
        ap->a.a_string = va_arg (args, const char *);
Packit Service fdd496
        /* A null pointer is an invalid argument for "%s", but in practice
Packit Service fdd496
           it occurs quite frequently in printf statements that produce
Packit Service fdd496
           debug output.  Use a fallback in this case.  */
Packit Service fdd496
        if (ap->a.a_string == NULL)
Packit Service fdd496
          ap->a.a_string = "(NULL)";
Packit Service fdd496
        break;
Packit Service fdd496
#if HAVE_WCHAR_T
Packit Service fdd496
      case TYPE_WIDE_STRING:
Packit Service fdd496
        ap->a.a_wide_string = va_arg (args, const wchar_t *);
Packit Service fdd496
        /* A null pointer is an invalid argument for "%ls", but in practice
Packit Service fdd496
           it occurs quite frequently in printf statements that produce
Packit Service fdd496
           debug output.  Use a fallback in this case.  */
Packit Service fdd496
        if (ap->a.a_wide_string == NULL)
Packit Service fdd496
          {
Packit Service fdd496
            static const wchar_t wide_null_string[] =
Packit Service fdd496
              {
Packit Service fdd496
                (wchar_t)'(',
Packit Service fdd496
                (wchar_t)'N', (wchar_t)'U', (wchar_t)'L', (wchar_t)'L',
Packit Service fdd496
                (wchar_t)')',
Packit Service fdd496
                (wchar_t)0
Packit Service fdd496
              };
Packit Service fdd496
            ap->a.a_wide_string = wide_null_string;
Packit Service fdd496
          }
Packit Service fdd496
        break;
Packit Service fdd496
#endif
Packit Service fdd496
      case TYPE_POINTER:
Packit Service fdd496
        ap->a.a_pointer = va_arg (args, void *);
Packit Service fdd496
        break;
Packit Service fdd496
      case TYPE_COUNT_SCHAR_POINTER:
Packit Service fdd496
        ap->a.a_count_schar_pointer = va_arg (args, signed char *);
Packit Service fdd496
        break;
Packit Service fdd496
      case TYPE_COUNT_SHORT_POINTER:
Packit Service fdd496
        ap->a.a_count_short_pointer = va_arg (args, short *);
Packit Service fdd496
        break;
Packit Service fdd496
      case TYPE_COUNT_INT_POINTER:
Packit Service fdd496
        ap->a.a_count_int_pointer = va_arg (args, int *);
Packit Service fdd496
        break;
Packit Service fdd496
      case TYPE_COUNT_LONGINT_POINTER:
Packit Service fdd496
        ap->a.a_count_longint_pointer = va_arg (args, long int *);
Packit Service fdd496
        break;
Packit Service fdd496
#if HAVE_LONG_LONG_INT
Packit Service fdd496
      case TYPE_COUNT_LONGLONGINT_POINTER:
Packit Service fdd496
        ap->a.a_count_longlongint_pointer = va_arg (args, long long int *);
Packit Service fdd496
        break;
Packit Service fdd496
#endif
Packit Service fdd496
#if ENABLE_UNISTDIO
Packit Service fdd496
      /* The unistdio extensions.  */
Packit Service fdd496
      case TYPE_U8_STRING:
Packit Service fdd496
        ap->a.a_u8_string = va_arg (args, const uint8_t *);
Packit Service fdd496
        /* A null pointer is an invalid argument for "%U", but in practice
Packit Service fdd496
           it occurs quite frequently in printf statements that produce
Packit Service fdd496
           debug output.  Use a fallback in this case.  */
Packit Service fdd496
        if (ap->a.a_u8_string == NULL)
Packit Service fdd496
          {
Packit Service fdd496
            static const uint8_t u8_null_string[] =
Packit Service fdd496
              { '(', 'N', 'U', 'L', 'L', ')', 0 };
Packit Service fdd496
            ap->a.a_u8_string = u8_null_string;
Packit Service fdd496
          }
Packit Service fdd496
        break;
Packit Service fdd496
      case TYPE_U16_STRING:
Packit Service fdd496
        ap->a.a_u16_string = va_arg (args, const uint16_t *);
Packit Service fdd496
        /* A null pointer is an invalid argument for "%lU", but in practice
Packit Service fdd496
           it occurs quite frequently in printf statements that produce
Packit Service fdd496
           debug output.  Use a fallback in this case.  */
Packit Service fdd496
        if (ap->a.a_u16_string == NULL)
Packit Service fdd496
          {
Packit Service fdd496
            static const uint16_t u16_null_string[] =
Packit Service fdd496
              { '(', 'N', 'U', 'L', 'L', ')', 0 };
Packit Service fdd496
            ap->a.a_u16_string = u16_null_string;
Packit Service fdd496
          }
Packit Service fdd496
        break;
Packit Service fdd496
      case TYPE_U32_STRING:
Packit Service fdd496
        ap->a.a_u32_string = va_arg (args, const uint32_t *);
Packit Service fdd496
        /* A null pointer is an invalid argument for "%llU", but in practice
Packit Service fdd496
           it occurs quite frequently in printf statements that produce
Packit Service fdd496
           debug output.  Use a fallback in this case.  */
Packit Service fdd496
        if (ap->a.a_u32_string == NULL)
Packit Service fdd496
          {
Packit Service fdd496
            static const uint32_t u32_null_string[] =
Packit Service fdd496
              { '(', 'N', 'U', 'L', 'L', ')', 0 };
Packit Service fdd496
            ap->a.a_u32_string = u32_null_string;
Packit Service fdd496
          }
Packit Service fdd496
        break;
Packit Service fdd496
#endif
Packit Service fdd496
      default:
Packit Service fdd496
        /* Unknown type.  */
Packit Service fdd496
        return -1;
Packit Service fdd496
      }
Packit Service fdd496
  return 0;
Packit Service fdd496
}