Back to index

glibc  2.9
Defines | Functions
printf_size.c File Reference
#include <ctype.h>
#include <ieee754.h>
#include <math.h>
#include <printf.h>
#include <libioP.h>

Go to the source code of this file.

Defines

#define PUT(f, s, n)   _IO_sputn (f, s, n)
#define PAD(f, c, n)   (wide ? _IO_wpadn (f, c, n) : INTUSE(_IO_padn) (f, c, n))
#define putc(c, f)
#define size_t   _IO_size_t
#define FILE   _IO_FILE
#define outchar(ch)
#define PRINT(ptr, wptr, len)
#define PADN(ch, len)
#define BINARY_UNITS   " kmgtpezy"
#define DECIMAL_UNITS   " KMGTPEZY"

Functions

int __printf_fp (FILE *fp, const struct printf_info *info, const void *const *args)
int __printf_size (FILE *fp, const struct printf_info *info, const void *const *args)
 ldbl_strong_alias (__printf_size, printf_size)
int printf_size_info (const struct printf_info *info, size_t n, int *argtypes)

Define Documentation

#define BINARY_UNITS   " kmgtpezy"
#define DECIMAL_UNITS   " KMGTPEZY"
#define FILE   _IO_FILE

Definition at line 39 of file printf_size.c.

#define outchar (   ch)
Value:
do                                                                   \
    {                                                                \
      register const int outc = (ch);                                       \
      if (putc (outc, fp) == EOF)                                    \
       return -1;                                                    \
      ++done;                                                        \
    } while (0)

Definition at line 43 of file printf_size.c.

#define PAD (   f,
  c,
  n 
)    (wide ? _IO_wpadn (f, c, n) : INTUSE(_IO_padn) (f, c, n))

Definition at line 32 of file printf_size.c.

#define PADN (   ch,
  len 
)
Value:
do                                                                   \
    {                                                                \
      if (PAD (fp, ch, len) != len)                                         \
       return -1;                                                    \
      done += len;                                                   \
    }                                                                \
  while (0)

Definition at line 74 of file printf_size.c.

#define PRINT (   ptr,
  wptr,
  len 
)
Value:
do                                                                   \
    {                                                                \
      register size_t outlen = (len);                                       \
      if (len > 20)                                                  \
       {                                                             \
         if (PUT (fp, wide ? (const char *) wptr : ptr, outlen) != outlen)   \
           return -1;                                                       \
         ptr += outlen;                                              \
         done += outlen;                                             \
       }                                                             \
      else                                                           \
       {                                                             \
         if (wide)                                                   \
           while (outlen-- > 0)                                      \
             outchar (*wptr++);                                      \
         else                                                        \
           while (outlen-- > 0)                                      \
             outchar (*ptr++);                                              \
       }                                                             \
    } while (0)

Definition at line 52 of file printf_size.c.

#define PUT (   f,
  s,
  n 
)    _IO_sputn (f, s, n)

Definition at line 31 of file printf_size.c.

#define putc (   c,
  f 
)
Value:
(wide \
                  ? (int)_IO_putwc_unlocked (c, f) : _IO_putc_unlocked (c, f))

Definition at line 36 of file printf_size.c.

#define size_t   _IO_size_t

Definition at line 38 of file printf_size.c.


Function Documentation

int __printf_fp ( FILE fp,
const struct printf_info info,
const void *const args 
)

Definition at line 5 of file nldbl-printf_fp.c.

{
  return __nldbl___printf_fp (fp, info, args);
}
int __printf_size ( FILE fp,
const struct printf_info info,
const void *const args 
)

Definition at line 89 of file printf_size.c.

{
  /* Units for the both formats.  */
#define BINARY_UNITS " kmgtpezy"
#define DECIMAL_UNITS       " KMGTPEZY"
  static const char units[2][sizeof (BINARY_UNITS)] =
  {
    BINARY_UNITS,    /* For binary format.  */
    DECIMAL_UNITS    /* For decimal format.  */
  };
  const char *tag = units[isupper (info->spec) != 0];
  int divisor = isupper (info->spec) ? 1000 : 1024;

  /* The floating-point value to output.  */
  union
    {
      union ieee754_double dbl;
      union ieee854_long_double ldbl;
    }
  fpnum;
  const void *ptr = &fpnum;

  int negative = 0;

  /* "NaN" or "Inf" for the special cases.  */
  const char *special = NULL;
  const wchar_t *wspecial = NULL;

  struct printf_info fp_info;
  int done = 0;
  int wide = info->wide;


  /* Fetch the argument value.     */
#ifndef __NO_LONG_DOUBLE_MATH
  if (info->is_long_double && sizeof (long double) > sizeof (double))
    {
      fpnum.ldbl.d = *(const long double *) args[0];

      /* Check for special values: not a number or infinity.  */
      if (__isnanl (fpnum.ldbl.d))
       {
         special = "nan";
         wspecial = L"nan";
         negative = 0;
       }
      else if (__isinfl (fpnum.ldbl.d))
       {
         special = "inf";
         wspecial = L"inf";

         negative = fpnum.ldbl.d < 0;
       }
      else
       while (fpnum.ldbl.d >= divisor && tag[1] != '\0')
         {
           fpnum.ldbl.d /= divisor;
           ++tag;
         }
    }
  else
#endif /* no long double */
    {
      fpnum.dbl.d = *(const double *) args[0];

      /* Check for special values: not a number or infinity.  */
      if (__isnan (fpnum.dbl.d))
       {
         special = "nan";
         wspecial = L"nan";
         negative = 0;
       }
      else if (__isinf (fpnum.dbl.d))
       {
         special = "inf";
         wspecial = L"inf";

         negative = fpnum.dbl.d < 0;
       }
      else
       while (fpnum.dbl.d >= divisor && tag[1] != '\0')
         {
           fpnum.dbl.d /= divisor;
           ++tag;
         }
    }

  if (special)
    {
      int width = info->prec > info->width ? info->prec : info->width;

      if (negative || info->showsign || info->space)
       --width;
      width -= 3;

      if (!info->left && width > 0)
       PADN (' ', width);

      if (negative)
       outchar ('-');
      else if (info->showsign)
       outchar ('+');
      else if (info->space)
       outchar (' ');

      PRINT (special, wspecial, 3);

      if (info->left && width > 0)
       PADN (' ', width);

      return done;
    }

  /* Prepare to print the number.  We want to use `__printf_fp' so we
     have to prepare a `printf_info' structure.  */
  fp_info = *info;
  fp_info.spec = 'f';
  fp_info.prec = info->prec < 0 ? 3 : info->prec;
  fp_info.wide = wide;

  if (fp_info.left && fp_info.pad == L' ')
    {
      /* We must do the padding ourself since the unit character must
        be placed before the padding spaces.  */
      fp_info.width = 0;

      done = __printf_fp (fp, &fp_info, &ptr);
      if (done > 0)
       {
         outchar (*tag);
         if (info->width > done)
           PADN (' ', info->width - done);
       }
    }
  else
    {
      /* We can let __printf_fp do all the printing and just add our
        unit character afterwards.  */
      fp_info.width = info->width - 1;

      done = __printf_fp (fp, &fp_info, &ptr);
      if (done > 0)
       outchar (*tag);
    }

  return done;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int printf_size_info ( const struct printf_info info,
size_t  n,
int argtypes 
)

Definition at line 242 of file printf_size.c.

{
  /* We need only one double or long double argument.  */
  if (n >= 1)
    argtypes[0] = PA_DOUBLE | (info->is_long_double ? PA_FLAG_LONG_DOUBLE : 0);

  return 1;
}