예제 #1
0
static void ptohex(FAR struct lib_outstream_s *obj, uint8_t flags, FAR void *p)
{
  union
  {
    uint32_t  dw;
    FAR void *p;
  } u;
  uint8_t bits;

  /* Check for alternate form */

  if (IS_ALTFORM(flags))
    {
      /* Prefix the number with "0x" */

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

  u.dw = 0;
  u.p  = p;

  for (bits = 8*sizeof(void *); bits > 0; bits -= 4)
    {
      uint8_t nibble = (uint8_t)((u.dw >> (bits - 4)) & 0xf);
      if (nibble < 10)
        {
          obj->put(obj, nibble + '0');
        }
      else
        {
          obj->put(obj, nibble + 'a' - 10);
        }
    }
}
예제 #2
0
static void llutoascii(FAR struct lib_outstream_s *obj, uint8_t fmt, uint8_t flags, unsigned long long lln)
{
  /* Perform the integer conversion according to the format specifier */

  switch (fmt)
    {
      case 'd':
      case 'i':
        /* Signed base 10 */
        {
#ifdef CONFIG_NOPRINTF_FIELDWIDTH
          if ((long long)lln < 0)
            {
              obj->put(obj, '-');
              lln    = (unsigned long long)(-(long long)lln);
            }
          else if (IS_SHOWPLUS(flags))
            {
              obj->put(obj, '+');
            }
#endif
          /* Convert the unsigned value to a string. */

          llutodec(obj, (unsigned long long)lln);
        }
        break;

      case 'u':
        /* Unigned base 10 */
        {
#ifdef CONFIG_NOPRINTF_FIELDWIDTH
          if (IS_SHOWPLUS(flags))
            {
              obj->put(obj, '+');
            }
#endif
          /* Convert the unsigned value to a string. */

          llutodec(obj, (unsigned long long)lln);
        }
        break;

      case 'x':
      case 'X':
        /* Hexadecimal */
        {
          /* Check for alternate form */

          if (IS_ALTFORM(flags))
            {
              /* Prefix the number with "0x" */

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

          /* Convert the unsigned value to a string. */

          if (fmt == 'X')
            {
              llutohex(obj, (unsigned long long)lln, 'A');
            }
          else
            {
              llutohex(obj, (unsigned long long)lln, 'a');
            }
        }
        break;

      case 'o':
        /* Octal */
         {
           /* Check for alternate form */

           if (IS_ALTFORM(flags))
             {
               /* Prefix the number with '0' */

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

           /* Convert the unsigned value to a string. */

           llutooct(obj, (unsigned long long)lln);
         }
         break;

      case 'b':
        /* Binary */
        {
          /* Convert the unsigned value to a string. */

          llutobin(obj, (unsigned long long)lln);
        }
        break;

      case 'p':
      default:
        break;
    }
}
예제 #3
0
static char* cvt(double value, int ndigits, int flags, char *sign,
                 int *decpt, int ch, int *length)
{
  int mode, dsgn;
  char *digits, *bp, *rve;

  if (ch == 'f')
    {
      mode = 3;               /* ndigits after the decimal point */
    }
  else
    {
      /* To obtain ndigits after the decimal point for the 'e' and 'E'
       * formats, round to ndigits + 1 significant figures.
       */

      if (ch == 'e' || ch == 'E')
        {
          ndigits++;
        }
      mode = 2;               /* ndigits significant digits */
    }

  if (value < 0)
    {
      value = -value;
      *sign = '-';
    }
  else
    {
      *sign = '\000';
    }

  digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve);
  if ((ch != 'g' && ch != 'G') || IS_ALTFORM(flags))
    {
      /* Print trailing zeros */

      bp = digits + ndigits;
      if (ch == 'f')
        {
          if (*digits == '0' && value)
            {
              *decpt = -ndigits + 1;
            }
          bp += *decpt;
        }

      if (value == 0)
        {
	  /* kludge for __dtoa irregularity */

          rve = bp;
        }

      while (rve < bp)
        {
          *rve++ = '0';
        }
    }

  *length = rve - digits;
  return digits;
}
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
}
예제 #5
0
static void lib_dtoa(FAR struct lib_outstream_s *obj, int ch, int prec,
                     uint8_t flags, double _double)
{
  FAR char *cp;              /* Handy char pointer (short term usage) */
  FAR char *cp_free = NULL;  /* BIONIC: copy of cp to be freed after usage */
  char expstr[7];            /* Buffer for exponent string */
  char sign;                 /* Temporary negative sign for floats */
  int  expt;                 /* Integer value of exponent */
  int  expsize = 0;          /* Character count for expstr */
  int  ndig;                 /* Actual number of digits returned by cvt */
  int  size;                 /* Size of converted field or string */
  int  i;

  cp = cvt(_double, prec, flags, &sign, &expt, ch, &ndig);
  cp_free = cp;

  if (ch == 'g' || ch == 'G')
    {
      /* 'g' or 'G' fmt */

      if (expt <= -4 || expt > prec)
        {
          ch = (ch == 'g') ? 'e' : 'E';
        }
      else
        {
          ch = 'g';
        }
    }

  if (ch <= 'e')
    {
      /* 'e' or 'E' fmt */

      --expt;
      expsize = exponent(expstr, expt, ch);
      size = expsize + ndig;
      if (ndig > 1 || IS_ALTFORM(flags))
        {
          ++size;
        }
    }
  else if (ch == 'f')
    {
      /* f fmt */

      if (expt > 0)
        {
          size = expt;
          if (prec || IS_ALTFORM(flags))
            {
              size += prec + 1;
            }
        }
      else  /* "0.X" */
        {
            size = prec + 2;
        }
    }
  else if (expt >= ndig)
    {
      /* fixed g fmt */

      size = expt;
      if (IS_ALTFORM(flags))
        {
          ++size;
        }
    }
  else
    {
      size = ndig + (expt > 0 ? 1 : 2 - expt);
    }

  if (sign)
    {
      obj->put(obj, '-');
    }

  if (_double == 0)
    {
      /* kludge for __dtoa irregularity */

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

          i = ndig - 1;
          while (i > 0)
            {
              obj->put(obj, '0');
              i--;
            }
        }
    }
  else if (expt <= 0)
    {
      obj->put(obj, '0');
      obj->put(obj, '.');

      i = ndig;
      while (i > 0)
        {
          obj->put(obj, *cp);
          i--;
          cp++;
        }
    }
  else if (expt >= ndig)
    {
      i = ndig;
      while (i > 0)
        {
          obj->put(obj, *cp);
          i--;
          cp++;
        }

      i = expt - ndig;
      while (i > 0)
        {
          obj->put(obj, '0');
          i--;
        }

      if (IS_ALTFORM(flags))
        {
          obj->put(obj, '.');
        }
    }
  else
    {
      /* print the integer */

      i = expt;
      while (i > 0)
        {
          obj->put(obj, *cp);
          i--;
          cp++;
        }

      /* print the decimal place */

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

      /* print the decimal */

      i = ndig - expt;
      while (i > 0)
        {
          obj->put(obj, *cp);
          i--;
          cp++;
        }
    }
}