Exemplo n.º 1
0
static void prejustify(FAR struct lib_outstream_s *obj, uint8_t fmt,
                       uint8_t flags, int fieldwidth, int valwidth)
{
  int i;

  switch (fmt)
    {
      default:
      case FMT_RJUST:
        if (IS_SIGNED(flags))
          {
            valwidth++;
          }

        for (i = fieldwidth - valwidth; i > 0; i--)
          {
            obj->put(obj, ' ');
          }

        if (IS_NEGATE(flags))
          {
            obj->put(obj, '-');
          }
        else if (IS_SHOWPLUS(flags))
          {
            obj->put(obj, '+');
          }
        break;

      case FMT_RJUST0:
         if (IS_NEGATE(flags))
          {
            obj->put(obj, '-');
            valwidth++;
          }
        else if (IS_SHOWPLUS(flags))
          {
            obj->put(obj, '+');
            valwidth++;
          }

        for (i = fieldwidth - valwidth; i > 0; i--)
          {
            obj->put(obj, '0');
          }
        break;

      case FMT_LJUST:
         if (IS_NEGATE(flags))
          {
            obj->put(obj, '-');
          }
        else if (IS_SHOWPLUS(flags))
          {
            obj->put(obj, '+');
          }
        break;
    }
}
static void lib_dtoa(FAR struct lib_outstream_s *obj, int fmt, int prec,
                     uint8_t flags, double value)
{
  FAR char *digits;     /* String returned by __dtoa */
  FAR char *digalloc;   /* Copy of digits to be freed after usage */
  FAR char *rve;        /* Points to the end of the return value */
  int  expt;            /* Integer value of exponent */
  int  numlen;          /* Actual number of digits returned by cvt */
  int  nchars;          /* Number of characters to print */
  int  dsgn;            /* Unused sign indicator */
  int  i;

  /* Special handling for NaN and Infinity */

  if (isnan(value))
    {
      lib_dtoa_string(obj, "NaN");
      return;
    }

  if (isinf(value))
    {
      if (value < 0.0)
        {
          obj->put(obj, '-');
        }

      lib_dtoa_string(obj, "Infinity");
      return;
    }

  /* Non-zero... positive or negative */

  if (value < 0)
    {
      value = -value;
      SET_NEGATE(flags);
    }

  /* Perform the conversion */

  digits   = __dtoa(value, 3, prec, &expt, &dsgn, &rve);
  digalloc = digits;
  numlen   = rve - digits;

  if (IS_NEGATE(flags))
    {
      obj->put(obj, '-');
    }
  else if (IS_SHOWPLUS(flags))
    {
      obj->put(obj, '+');
    }

  /* Special case exact zero or the case where the number is smaller than
   * the print precision.
   */

  if (value == 0 || expt < -prec)
    {
      /* kludge for __dtoa irregularity */

      obj->put(obj, '0');

      /* A decimal point is printed only in the alternate form or if a
       * particular precision is requested.
       */

      if (prec > 0 || IS_ALTFORM(flags))
        {
          obj->put(obj, '.');

          /* Always print at least one digit to the right of the decimal point. */

          prec = MAX(1, prec);
        }
    }

  /* A non-zero value will be printed */

  else
    {

      /* Handle the case where the value is less than 1.0 (in magnitude) and
       * will need a leading zero.
       */

      if (expt <= 0)
        {
          /* Print a single zero to the left of the decimal point */

          obj->put(obj, '0');

          /* Print the decimal point */

          obj->put(obj, '.');

          /* Print any leading zeros to the right of the decimal point */

          if (expt < 0)
            {
              nchars = MIN(-expt, prec);
              zeroes(obj, nchars);
              prec -= nchars;
            }
        }

      /* Handle the general case where the value is greater than 1.0 (in
       * magnitude).
       */

      else
        {
          /* Print the integer part to the left of the decimal point */

          for (i = expt; i > 0; i--)
            {
              if (*digits != '\0')
                {
                  obj->put(obj, *digits);
                  digits++;
                }
              else
                {
                  obj->put(obj, '0');
                }
            }

          /* Get the length of the fractional part */

          numlen -= expt;

          /* If there is no fractional part, then a decimal point is printed
           * only in the alternate form or if a particular precision is
           * requested.
           */

          if (numlen > 0 || prec > 0 || IS_ALTFORM(flags))
            {
              /* Print the decimal point */

              obj->put(obj, '.');

              /* Always print at least one digit to the right of the decimal
               * point.
               */

              prec = MAX(1, prec);
            }
        }

      /* If a precision was specified, then limit the number digits to the
       * right of the decimal point.
       */

      if (prec > 0)
        {
          nchars = MIN(numlen, prec);
        }
      else
        {
          nchars = numlen;
        }

      /* Print the fractional part to the right of the decimal point */

      for (i = nchars; i > 0; i--)
        {
          obj->put(obj, *digits);
          digits++;
        }

      /* Decremnt to get the number of trailing zeroes to print */

      prec -= nchars;
    }

  /* Finally, print any trailing zeroes */

  zeroes(obj, prec);

  /* Is this memory supposed to be freed or not? */

#if 0
  if (digalloc)
    {
      lib_free(digalloc);
    }
#endif
}