Blame stdio-common/printf_fphex.c

Packit Service 82fcde
/* Print floating point number in hexadecimal notation according to ISO C99.
Packit Service 82fcde
   Copyright (C) 1997-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#include <array_length.h>
Packit Service 82fcde
#include <ctype.h>
Packit Service 82fcde
#include <ieee754.h>
Packit Service 82fcde
#include <math.h>
Packit Service 82fcde
#include <printf.h>
Packit Service 82fcde
#include <stdlib.h>
Packit Service 82fcde
#include <stdio.h>
Packit Service 82fcde
#include <string.h>
Packit Service 82fcde
#include <wchar.h>
Packit Service 82fcde
#include <_itoa.h>
Packit Service 82fcde
#include <_itowa.h>
Packit Service 82fcde
#include <locale/localeinfo.h>
Packit Service 82fcde
#include <stdbool.h>
Packit Service 82fcde
#include <rounding-mode.h>
Packit Service 82fcde
Packit Service 82fcde
#if __HAVE_DISTINCT_FLOAT128
Packit Service 82fcde
# include "ieee754_float128.h"
Packit Service 82fcde
# include <ldbl-128/printf_fphex_macros.h>
Packit Service 82fcde
# define PRINT_FPHEX_FLOAT128 \
Packit Service 82fcde
   PRINT_FPHEX (_Float128, fpnum.flt128, ieee854_float128, \
Packit Service 82fcde
		IEEE854_FLOAT128_BIAS)
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* #define NDEBUG 1*/		/* Undefine this for debugging assertions.  */
Packit Service 82fcde
#include <assert.h>
Packit Service 82fcde
Packit Service 82fcde
#include <libioP.h>
Packit Service 82fcde
#define PUT(f, s, n) _IO_sputn (f, s, n)
Packit Service 82fcde
#define PAD(f, c, n) (wide ? _IO_wpadn (f, c, n) : _IO_padn (f, c, n))
Packit Service 82fcde
#undef putc
Packit Service 82fcde
#define putc(c, f) (wide \
Packit Service 82fcde
		     ? (int)_IO_putwc_unlocked (c, f) : _IO_putc_unlocked (c, f))
Packit Service 82fcde
Packit Service 82fcde

Packit Service 82fcde
/* Macros for doing the actual output.  */
Packit Service 82fcde
Packit Service 82fcde
#define outchar(ch)							      \
Packit Service 82fcde
  do									      \
Packit Service 82fcde
    {									      \
Packit Service 82fcde
      const int outc = (ch);						      \
Packit Service 82fcde
      if (putc (outc, fp) == EOF)					      \
Packit Service 82fcde
	return -1;							      \
Packit Service 82fcde
      ++done;								      \
Packit Service 82fcde
    } while (0)
Packit Service 82fcde
Packit Service 82fcde
#define PRINT(ptr, wptr, len)						      \
Packit Service 82fcde
  do									      \
Packit Service 82fcde
    {									      \
Packit Service 82fcde
      size_t outlen = (len);						      \
Packit Service 82fcde
      if (wide)								      \
Packit Service 82fcde
	while (outlen-- > 0)						      \
Packit Service 82fcde
	  outchar (*wptr++);						      \
Packit Service 82fcde
      else								      \
Packit Service 82fcde
	while (outlen-- > 0)						      \
Packit Service 82fcde
	  outchar (*ptr++);						      \
Packit Service 82fcde
    } while (0)
Packit Service 82fcde
Packit Service 82fcde
#define PADN(ch, len)							      \
Packit Service 82fcde
  do									      \
Packit Service 82fcde
    {									      \
Packit Service 82fcde
      if (PAD (fp, ch, len) != len)					      \
Packit Service 82fcde
	return -1;							      \
Packit Service 82fcde
      done += len;							      \
Packit Service 82fcde
    }									      \
Packit Service 82fcde
  while (0)
Packit Service 82fcde
Packit Service 82fcde
#ifndef MIN
Packit Service 82fcde
# define MIN(a,b) ((a)<(b)?(a):(b))
Packit Service 82fcde
#endif
Packit Service 82fcde

Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
__printf_fphex (FILE *fp,
Packit Service 82fcde
		const struct printf_info *info,
Packit Service 82fcde
		const void *const *args)
Packit Service 82fcde
{
Packit Service 82fcde
  /* The floating-point value to output.  */
Packit Service 82fcde
  union
Packit Service 82fcde
    {
Packit Service 82fcde
      union ieee754_double dbl;
Packit Service 82fcde
      long double ldbl;
Packit Service 82fcde
#if __HAVE_DISTINCT_FLOAT128
Packit Service 82fcde
      _Float128 flt128;
Packit Service 82fcde
#endif
Packit Service 82fcde
    }
Packit Service 82fcde
  fpnum;
Packit Service 82fcde
Packit Service 82fcde
  /* Locale-dependent representation of decimal point.	*/
Packit Service 82fcde
  const char *decimal;
Packit Service 82fcde
  wchar_t decimalwc;
Packit Service 82fcde
Packit Service 82fcde
  /* "NaN" or "Inf" for the special cases.  */
Packit Service 82fcde
  const char *special = NULL;
Packit Service 82fcde
  const wchar_t *wspecial = NULL;
Packit Service 82fcde
Packit Service 82fcde
  /* Buffer for the generated number string for the mantissa.  The
Packit Service 82fcde
     maximal size for the mantissa is 128 bits.  */
Packit Service 82fcde
  char numbuf[32];
Packit Service 82fcde
  char *numstr;
Packit Service 82fcde
  char *numend;
Packit Service 82fcde
  wchar_t wnumbuf[32];
Packit Service 82fcde
  wchar_t *wnumstr;
Packit Service 82fcde
  wchar_t *wnumend;
Packit Service 82fcde
  int negative;
Packit Service 82fcde
Packit Service 82fcde
  /* The maximal exponent of two in decimal notation has 5 digits.  */
Packit Service 82fcde
  char expbuf[5];
Packit Service 82fcde
  char *expstr;
Packit Service 82fcde
  wchar_t wexpbuf[5];
Packit Service 82fcde
  wchar_t *wexpstr;
Packit Service 82fcde
  int expnegative;
Packit Service 82fcde
  int exponent;
Packit Service 82fcde
Packit Service 82fcde
  /* Non-zero is mantissa is zero.  */
Packit Service 82fcde
  int zero_mantissa;
Packit Service 82fcde
Packit Service 82fcde
  /* The leading digit before the decimal point.  */
Packit Service 82fcde
  char leading;
Packit Service 82fcde
Packit Service 82fcde
  /* Precision.  */
Packit Service 82fcde
  int precision = info->prec;
Packit Service 82fcde
Packit Service 82fcde
  /* Width.  */
Packit Service 82fcde
  int width = info->width;
Packit Service 82fcde
Packit Service 82fcde
  /* Number of characters written.  */
Packit Service 82fcde
  int done = 0;
Packit Service 82fcde
Packit Service 82fcde
  /* Nonzero if this is output on a wide character stream.  */
Packit Service 82fcde
  int wide = info->wide;
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
  /* Figure out the decimal point character.  */
Packit Service 82fcde
  if (info->extra == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
Packit Service 82fcde
      decimalwc = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
Packit Service 82fcde
    }
Packit Service 82fcde
  else
Packit Service 82fcde
    {
Packit Service 82fcde
      decimal = _NL_CURRENT (LC_MONETARY, MON_DECIMAL_POINT);
Packit Service 82fcde
      decimalwc = _NL_CURRENT_WORD (LC_MONETARY,
Packit Service 82fcde
				    _NL_MONETARY_DECIMAL_POINT_WC);
Packit Service 82fcde
    }
Packit Service 82fcde
  /* The decimal point character must never be zero.  */
Packit Service 82fcde
  assert (*decimal != '\0' && decimalwc != L'\0');
Packit Service 82fcde
Packit Service 82fcde
#define PRINTF_FPHEX_FETCH(FLOAT, VAR)					\
Packit Service 82fcde
  {									\
Packit Service 82fcde
    (VAR) = *(const FLOAT *) args[0];					\
Packit Service 82fcde
									\
Packit Service 82fcde
    /* Check for special values: not a number or infinity.  */		\
Packit Service 82fcde
    if (isnan (VAR))							\
Packit Service 82fcde
      {									\
Packit Service 82fcde
	if (isupper (info->spec))					\
Packit Service 82fcde
	  {								\
Packit Service 82fcde
	    special = "NAN";						\
Packit Service 82fcde
	    wspecial = L"NAN";						\
Packit Service 82fcde
	  }								\
Packit Service 82fcde
	else								\
Packit Service 82fcde
	  {								\
Packit Service 82fcde
	    special = "nan";						\
Packit Service 82fcde
	    wspecial = L"nan";						\
Packit Service 82fcde
	  }								\
Packit Service 82fcde
      }									\
Packit Service 82fcde
    else								\
Packit Service 82fcde
      {									\
Packit Service 82fcde
	if (isinf (VAR))						\
Packit Service 82fcde
	  {								\
Packit Service 82fcde
	    if (isupper (info->spec))					\
Packit Service 82fcde
	      {								\
Packit Service 82fcde
		special = "INF";					\
Packit Service 82fcde
		wspecial = L"INF";					\
Packit Service 82fcde
	      }								\
Packit Service 82fcde
	    else							\
Packit Service 82fcde
	      {								\
Packit Service 82fcde
		special = "inf";					\
Packit Service 82fcde
		wspecial = L"inf";					\
Packit Service 82fcde
	      }								\
Packit Service 82fcde
	  }								\
Packit Service 82fcde
      }									\
Packit Service 82fcde
    negative = signbit (VAR);						\
Packit Service 82fcde
  }
Packit Service 82fcde
Packit Service 82fcde
  /* Fetch the argument value.	*/
Packit Service 82fcde
#if __HAVE_DISTINCT_FLOAT128
Packit Service 82fcde
  if (info->is_binary128)
Packit Service 82fcde
    PRINTF_FPHEX_FETCH (_Float128, fpnum.flt128)
Packit Service 82fcde
  else
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifndef __NO_LONG_DOUBLE_MATH
Packit Service 82fcde
  if (info->is_long_double && sizeof (long double) > sizeof (double))
Packit Service 82fcde
    PRINTF_FPHEX_FETCH (long double, fpnum.ldbl)
Packit Service 82fcde
  else
Packit Service 82fcde
#endif
Packit Service 82fcde
    PRINTF_FPHEX_FETCH (double, fpnum.dbl.d)
Packit Service 82fcde
Packit Service 82fcde
#undef PRINTF_FPHEX_FETCH
Packit Service 82fcde
Packit Service 82fcde
  if (special)
Packit Service 82fcde
    {
Packit Service 82fcde
      int width = info->width;
Packit Service 82fcde
Packit Service 82fcde
      if (negative || info->showsign || info->space)
Packit Service 82fcde
	--width;
Packit Service 82fcde
      width -= 3;
Packit Service 82fcde
Packit Service 82fcde
      if (!info->left && width > 0)
Packit Service 82fcde
	PADN (' ', width);
Packit Service 82fcde
Packit Service 82fcde
      if (negative)
Packit Service 82fcde
	outchar ('-');
Packit Service 82fcde
      else if (info->showsign)
Packit Service 82fcde
	outchar ('+');
Packit Service 82fcde
      else if (info->space)
Packit Service 82fcde
	outchar (' ');
Packit Service 82fcde
Packit Service 82fcde
      PRINT (special, wspecial, 3);
Packit Service 82fcde
Packit Service 82fcde
      if (info->left && width > 0)
Packit Service 82fcde
	PADN (' ', width);
Packit Service 82fcde
Packit Service 82fcde
      return done;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
#if __HAVE_DISTINCT_FLOAT128
Packit Service 82fcde
  if (info->is_binary128)
Packit Service 82fcde
    PRINT_FPHEX_FLOAT128;
Packit Service 82fcde
  else
Packit Service 82fcde
#endif
Packit Service 82fcde
  if (info->is_long_double == 0 || sizeof (double) == sizeof (long double))
Packit Service 82fcde
    {
Packit Service 82fcde
      /* We have 52 bits of mantissa plus one implicit digit.  Since
Packit Service 82fcde
	 52 bits are representable without rest using hexadecimal
Packit Service 82fcde
	 digits we use only the implicit digits for the number before
Packit Service 82fcde
	 the decimal point.  */
Packit Service 82fcde
      unsigned long long int num;
Packit Service 82fcde
Packit Service 82fcde
      num = (((unsigned long long int) fpnum.dbl.ieee.mantissa0) << 32
Packit Service 82fcde
	     | fpnum.dbl.ieee.mantissa1);
Packit Service 82fcde
Packit Service 82fcde
      zero_mantissa = num == 0;
Packit Service 82fcde
Packit Service 82fcde
      if (sizeof (unsigned long int) > 6)
Packit Service 82fcde
	{
Packit Service 82fcde
	  wnumstr = _itowa_word (num, wnumbuf + (sizeof wnumbuf) / sizeof (wchar_t), 16,
Packit Service 82fcde
				 info->spec == 'A');
Packit Service 82fcde
	  numstr = _itoa_word (num, numbuf + sizeof numbuf, 16,
Packit Service 82fcde
			       info->spec == 'A');
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  wnumstr = _itowa (num, wnumbuf + sizeof wnumbuf / sizeof (wchar_t), 16,
Packit Service 82fcde
			    info->spec == 'A');
Packit Service 82fcde
	  numstr = _itoa (num, numbuf + sizeof numbuf, 16,
Packit Service 82fcde
			  info->spec == 'A');
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* Fill with zeroes.  */
Packit Service 82fcde
      while (wnumstr > wnumbuf + (sizeof wnumbuf - 52) / sizeof (wchar_t))
Packit Service 82fcde
	{
Packit Service 82fcde
	  *--wnumstr = L'0';
Packit Service 82fcde
	  *--numstr = '0';
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      leading = fpnum.dbl.ieee.exponent == 0 ? '0' : '1';
Packit Service 82fcde
Packit Service 82fcde
      exponent = fpnum.dbl.ieee.exponent;
Packit Service 82fcde
Packit Service 82fcde
      if (exponent == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (zero_mantissa)
Packit Service 82fcde
	    expnegative = 0;
Packit Service 82fcde
	  else
Packit Service 82fcde
	    {
Packit Service 82fcde
	      /* This is a denormalized number.  */
Packit Service 82fcde
	      expnegative = 1;
Packit Service 82fcde
	      exponent = IEEE754_DOUBLE_BIAS - 1;
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
      else if (exponent >= IEEE754_DOUBLE_BIAS)
Packit Service 82fcde
	{
Packit Service 82fcde
	  expnegative = 0;
Packit Service 82fcde
	  exponent -= IEEE754_DOUBLE_BIAS;
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  expnegative = 1;
Packit Service 82fcde
	  exponent = -(exponent - IEEE754_DOUBLE_BIAS);
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
#ifdef PRINT_FPHEX_LONG_DOUBLE
Packit Service 82fcde
  else
Packit Service 82fcde
    PRINT_FPHEX_LONG_DOUBLE;
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
  /* Look for trailing zeroes.  */
Packit Service 82fcde
  if (! zero_mantissa)
Packit Service 82fcde
    {
Packit Service 82fcde
      wnumend = array_end (wnumbuf);
Packit Service 82fcde
      numend = array_end (numbuf);
Packit Service 82fcde
      while (wnumend[-1] == L'0')
Packit Service 82fcde
	{
Packit Service 82fcde
	  --wnumend;
Packit Service 82fcde
	  --numend;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      bool do_round_away = false;
Packit Service 82fcde
Packit Service 82fcde
      if (precision != -1 && precision < numend - numstr)
Packit Service 82fcde
	{
Packit Service 82fcde
	  char last_digit = precision > 0 ? numstr[precision - 1] : leading;
Packit Service 82fcde
	  char next_digit = numstr[precision];
Packit Service 82fcde
	  int last_digit_value = (last_digit >= 'A' && last_digit <= 'F'
Packit Service 82fcde
				  ? last_digit - 'A' + 10
Packit Service 82fcde
				  : (last_digit >= 'a' && last_digit <= 'f'
Packit Service 82fcde
				     ? last_digit - 'a' + 10
Packit Service 82fcde
				     : last_digit - '0'));
Packit Service 82fcde
	  int next_digit_value = (next_digit >= 'A' && next_digit <= 'F'
Packit Service 82fcde
				  ? next_digit - 'A' + 10
Packit Service 82fcde
				  : (next_digit >= 'a' && next_digit <= 'f'
Packit Service 82fcde
				     ? next_digit - 'a' + 10
Packit Service 82fcde
				     : next_digit - '0'));
Packit Service 82fcde
	  bool more_bits = ((next_digit_value & 7) != 0
Packit Service 82fcde
			    || precision + 1 < numend - numstr);
Packit Service 82fcde
	  int rounding_mode = get_rounding_mode ();
Packit Service 82fcde
	  do_round_away = round_away (negative, last_digit_value & 1,
Packit Service 82fcde
				      next_digit_value >= 8, more_bits,
Packit Service 82fcde
				      rounding_mode);
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      if (precision == -1)
Packit Service 82fcde
	precision = numend - numstr;
Packit Service 82fcde
      else if (do_round_away)
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* Round up.  */
Packit Service 82fcde
	  int cnt = precision;
Packit Service 82fcde
	  while (--cnt >= 0)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      char ch = numstr[cnt];
Packit Service 82fcde
	      /* We assume that the digits and the letters are ordered
Packit Service 82fcde
		 like in ASCII.  This is true for the rest of GNU, too.  */
Packit Service 82fcde
	      if (ch == '9')
Packit Service 82fcde
		{
Packit Service 82fcde
		  wnumstr[cnt] = (wchar_t) info->spec;
Packit Service 82fcde
		  numstr[cnt] = info->spec;	/* This is tricky,
Packit Service 82fcde
						   think about it!  */
Packit Service 82fcde
		  break;
Packit Service 82fcde
		}
Packit Service 82fcde
	      else if (tolower (ch) < 'f')
Packit Service 82fcde
		{
Packit Service 82fcde
		  ++numstr[cnt];
Packit Service 82fcde
		  ++wnumstr[cnt];
Packit Service 82fcde
		  break;
Packit Service 82fcde
		}
Packit Service 82fcde
	      else
Packit Service 82fcde
		{
Packit Service 82fcde
		  numstr[cnt] = '0';
Packit Service 82fcde
		  wnumstr[cnt] = L'0';
Packit Service 82fcde
		}
Packit Service 82fcde
	    }
Packit Service 82fcde
	  if (cnt < 0)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      /* The mantissa so far was fff...f  Now increment the
Packit Service 82fcde
		 leading digit.  Here it is again possible that we
Packit Service 82fcde
		 get an overflow.  */
Packit Service 82fcde
	      if (leading == '9')
Packit Service 82fcde
		leading = info->spec;
Packit Service 82fcde
	      else if (tolower (leading) < 'f')
Packit Service 82fcde
		++leading;
Packit Service 82fcde
	      else
Packit Service 82fcde
		{
Packit Service 82fcde
		  leading = '1';
Packit Service 82fcde
		  if (expnegative)
Packit Service 82fcde
		    {
Packit Service 82fcde
		      exponent -= 4;
Packit Service 82fcde
		      if (exponent <= 0)
Packit Service 82fcde
			{
Packit Service 82fcde
			  exponent = -exponent;
Packit Service 82fcde
			  expnegative = 0;
Packit Service 82fcde
			}
Packit Service 82fcde
		    }
Packit Service 82fcde
		  else
Packit Service 82fcde
		    exponent += 4;
Packit Service 82fcde
		}
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
  else
Packit Service 82fcde
    {
Packit Service 82fcde
      if (precision == -1)
Packit Service 82fcde
	precision = 0;
Packit Service 82fcde
      numend = numstr;
Packit Service 82fcde
      wnumend = wnumstr;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* Now we can compute the exponent string.  */
Packit Service 82fcde
  expstr = _itoa_word (exponent, expbuf + sizeof expbuf, 10, 0);
Packit Service 82fcde
  wexpstr = _itowa_word (exponent,
Packit Service 82fcde
			 wexpbuf + sizeof wexpbuf / sizeof (wchar_t), 10, 0);
Packit Service 82fcde
Packit Service 82fcde
  /* Now we have all information to compute the size.  */
Packit Service 82fcde
  width -= ((negative || info->showsign || info->space)
Packit Service 82fcde
	    /* Sign.  */
Packit Service 82fcde
	    + 2    + 1 + 0 + precision + 1 + 1
Packit Service 82fcde
	    /* 0x    h   .   hhh         P   ExpoSign.  */
Packit Service 82fcde
	    + ((expbuf + sizeof expbuf) - expstr));
Packit Service 82fcde
	    /* Exponent.  */
Packit Service 82fcde
Packit Service 82fcde
  /* Count the decimal point.
Packit Service 82fcde
     A special case when the mantissa or the precision is zero and the `#'
Packit Service 82fcde
     is not given.  In this case we must not print the decimal point.  */
Packit Service 82fcde
  if (precision > 0 || info->alt)
Packit Service 82fcde
    width -= wide ? 1 : strlen (decimal);
Packit Service 82fcde
Packit Service 82fcde
  if (!info->left && info->pad != '0' && width > 0)
Packit Service 82fcde
    PADN (' ', width);
Packit Service 82fcde
Packit Service 82fcde
  if (negative)
Packit Service 82fcde
    outchar ('-');
Packit Service 82fcde
  else if (info->showsign)
Packit Service 82fcde
    outchar ('+');
Packit Service 82fcde
  else if (info->space)
Packit Service 82fcde
    outchar (' ');
Packit Service 82fcde
Packit Service 82fcde
  outchar ('0');
Packit Service 82fcde
  if ('X' - 'A' == 'x' - 'a')
Packit Service 82fcde
    outchar (info->spec + ('x' - 'a'));
Packit Service 82fcde
  else
Packit Service 82fcde
    outchar (info->spec == 'A' ? 'X' : 'x');
Packit Service 82fcde
Packit Service 82fcde
  if (!info->left && info->pad == '0' && width > 0)
Packit Service 82fcde
    PADN ('0', width);
Packit Service 82fcde
Packit Service 82fcde
  outchar (leading);
Packit Service 82fcde
Packit Service 82fcde
  if (precision > 0 || info->alt)
Packit Service 82fcde
    {
Packit Service 82fcde
      const wchar_t *wtmp = &decimalwc;
Packit Service 82fcde
      PRINT (decimal, wtmp, wide ? 1 : strlen (decimal));
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (precision > 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      ssize_t tofill = precision - (numend - numstr);
Packit Service 82fcde
      PRINT (numstr, wnumstr, MIN (numend - numstr, precision));
Packit Service 82fcde
      if (tofill > 0)
Packit Service 82fcde
	PADN ('0', tofill);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if ('P' - 'A' == 'p' - 'a')
Packit Service 82fcde
    outchar (info->spec + ('p' - 'a'));
Packit Service 82fcde
  else
Packit Service 82fcde
    outchar (info->spec == 'A' ? 'P' : 'p');
Packit Service 82fcde
Packit Service 82fcde
  outchar (expnegative ? '-' : '+');
Packit Service 82fcde
Packit Service 82fcde
  PRINT (expstr, wexpstr, (expbuf + sizeof expbuf) - expstr);
Packit Service 82fcde
Packit Service 82fcde
  if (info->left && info->pad != '0' && width > 0)
Packit Service 82fcde
    PADN (info->pad, width);
Packit Service 82fcde
Packit Service 82fcde
  return done;
Packit Service 82fcde
}