/***************************************************************************
 *
 * num_put.cpp
 *
 * $Id$
 *
 ***************************************************************************
 *
 * Licensed to the Apache Software  Foundation (ASF) under one or more
 * contributor  license agreements.  See  the NOTICE  file distributed
 * with  this  work  for  additional information  regarding  copyright
 * ownership.   The ASF  licenses this  file to  you under  the Apache
 * License, Version  2.0 (the  License); you may  not use  this file
 * except in  compliance with the License.   You may obtain  a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the  License is distributed on an  "AS IS" BASIS,
 * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY  KIND, either  express or
 * implied.   See  the License  for  the  specific language  governing
 * permissions and limitations under the License.
 *
 * Copyright 2001-2006 Rogue Wave Software.
 * 
 **************************************************************************/

#define _RWSTD_LIB_SRC
#include <rw/_defs.h>

#include <limits>     // for numeric_limits

#include <stdio.h>    // for snprintf()
#include <string.h>   // for memmove(), memset()

#include <loc/_num_put.h>

#include "strtol.h"   // for __rw_digit_map


#ifndef _RWSTD_NO_SNPRINTF
   // cast away constness of the format argument to prevent errors
   // on platforms such as HP-UX 11.00 that incorrectly declare it
   // without the const qualifier
#  define _SNPRINTF(buf, size, fmt, arg)   \
     snprintf (buf, size, _RWSTD_CONST_CAST (char*, fmt), arg)
#else   // _RWSTD_NO_SNPRINTF
#  ifndef _RWSTD_NO_SNPRINTF_IN_LIBC

#    undef snprintf
#    define snprintf                         _RWSTD_LIBC_SYM (snprintf)
#    define _SNPRINTF(buf, size, fmt, arg)   snprintf (buf, size, fmt, arg)

extern "C" {

_RWSTD_DLLIMPORT int
snprintf (char*, _RWSTD_SIZE_T, const char*, ...) _LIBC_THROWS ();

}   // extern "C"

#  else   // if defined (_RWSTD_NO_SNPRINTF_IN_LIBC)
#    define _SNPRINTF(buf, ignore, fmt, arg) sprintf (buf, fmt, arg)
#  endif   // _RWSTD_NO_SNPRINTF_IN_LIBC
#endif   // _RWSTD_NO_SNPRINTF

_RWSTD_NAMESPACE (__rw) { 

static const char __rw_digits[] =
    "0123456789abcdefghijklmnopqrstuvwxyz"
    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";


const char*
__rw_get_stdio_fmat (char buf [32], int type, unsigned fmtflags,
                     _STD::streamsize prec);


#ifdef _RWSTD_LONG_LONG


typedef _RWSTD_LONG_LONG          _LLong;
typedef unsigned _RWSTD_LONG_LONG _ULLong;


static _RWSTD_SIZE_T
__rw_btoa (char *buf, _ULLong i, unsigned base)
{
    _RWSTD_ASSERT (base && base <= 36);

    const _RWSTD_SIZE_T dig = _STD::numeric_limits<_ULLong>::digits + 0U;

    char*             end   = buf + dig;
    const char* const begin = end;

    _ULLong tmp;
    do {
        tmp = i / base;

        // PA RISC has no integer divide, optimize the modulo operator
        // this is also faster than computing the modulo on i86, and
        // faster than calling ldiv()
        *--end = __rw_digits [i - tmp * base];
    } while ((i = tmp));

    const _RWSTD_SIZE_T len = begin - end;

   memmove (buf, end, len);

    return len;
}


static _RWSTD_SIZE_T
__rw_dtoa (char *buf, _ULLong i, unsigned flags)
{
    // get the maximum number of decimal digits for an unsigned long
    // with the largest magnitude, plus 1 for the (optional) sign
    const _RWSTD_SIZE_T dig10 = _STD::numeric_limits<_ULLong>::digits10 + 2U;

    char*             end   = buf + dig10;
    const char* const begin = end;

    _ULLong tmp;
    do {
        tmp = i / 10;

        // PA RISC has no integer divide, optimize the modulo operator
        // this is also faster than computing the modulo on i86, and
        // faster than calling ldiv()
        *--end = __rw_digits [i - tmp * 10];
    } while ((i = tmp));


    if (flags & _RWSTD_IOS_SHOWPOS)
        *--end = '+';

    const _RWSTD_SIZE_T len = begin - end;

   memmove (buf, end, len);

    return len;
}


static inline _RWSTD_SIZE_T
__rw_dtoa (char *buf, _LLong i, unsigned flags)
{
    if (i < 0) {
        flags  &= ~_RWSTD_IOS_SHOWPOS;
        *buf++  = '-';
        return 1 + __rw_dtoa (buf, _RWSTD_STATIC_CAST (_ULLong, -i), flags);
    }
        
    return __rw_dtoa (buf, _RWSTD_STATIC_CAST (_ULLong, i), flags);
}


static _RWSTD_SIZE_T
__rw_itoa (char *buf, _ULLong i, unsigned flags)
{
    const char* const pdigs = flags & _RWSTD_IOS_UPPERCASE ?
        __rw_digits + 36 : __rw_digits;

    const _LLong base = (flags >> _RWSTD_IOS_BASEOFF) - _LLong (1);

    int bits;

    char *end = buf;

    switch (base) {

    case  1: bits = 1; break;
    case  3: bits = 2; break;
    case  7:
        bits = 3;
        if (i && flags & _RWSTD_IOS_SHOWBASE)
            *end++ = '0';
        break;

    case 9:
        return __rw_dtoa (end, i, flags);

    case 15:
        bits = 4;
        if (i && flags & _RWSTD_IOS_SHOWBASE) {
            *end++ = '0';
            *end++ = pdigs [33];   // 'X' or 'x'
        }
        break;

    case 31: bits = 5; break;

    default:
        _RWSTD_ASSERT (base >= 0 && base <= _RWSTD_UINT_MAX);

        return __rw_btoa (buf, i, unsigned (base));
    }

    // maximum number of base-digits
    const int digits =
        (_STD::numeric_limits<_ULLong>::digits + bits - 1) / bits;

    int j;

    // skip leading zeros
    if (i) {
        for (j = digits - 1; j && !(i & (base << j * bits)); --j);
    }
    else
        j = 0;

    // format the remaining digits
    do {
        const int dig = int ((i & (base << j * bits)) >> j * bits);

        _RWSTD_ASSERT (dig >= 0 && dig < 36);

        *end++ = pdigs [dig];
    } while (j--);

    return end - buf;
}


static inline _RWSTD_SIZE_T
__rw_itoa (char *buf, _LLong i, unsigned flags)
{
    if (10 == flags >> _RWSTD_IOS_BASEOFF)
        return __rw_dtoa (buf, i, flags);

    return __rw_itoa (buf, _RWSTD_STATIC_CAST (_ULLong, i), flags);
}


#endif   // _RWSTD_LONG_LONG


static _RWSTD_SIZE_T
__rw_btoa (char *buf, unsigned long i, unsigned base)
{
    _RWSTD_ASSERT (base && base <= 36);

    const _RWSTD_SIZE_T dig = _STD::numeric_limits<unsigned long>::digits + 0U;

    char*             end   = buf + dig;
    const char* const begin = end;

    unsigned long tmp;
    do {
        tmp = i / base;

        // PA RISC has no integer divide, optimize the modulo operator
        // this is also faster than computing the modulo on i86, and
        // faster than calling ldiv()
        *--end = __rw_digits [i - tmp * base];
    } while ((i = tmp));

    const _RWSTD_SIZE_T len = begin - end;

   memmove (buf, end, len);

    return len;
}


static  inline _RWSTD_SIZE_T
__rw_dtoa (char *buf, unsigned long i, unsigned flags)
{
    // get the maximum number of decimal digits for an unsigned long
    // with the largest magnitude, plus 1 for the (optional) sign
    const _RWSTD_SIZE_T dig10 =
        _STD::numeric_limits<unsigned long>::digits10 + 2U;

    char*             end   = buf + dig10;
    const char* const begin = end;

    unsigned long tmp;
    do {
        tmp = i / 10;

        // PA RISC has no integer divide, optimize the modulo operator
        // this is also faster than computing the modulo on i86, and
        // faster than calling ldiv()
        *--end = __rw_digits [i - tmp * 10];
    } while ((i = tmp));


    // prepend a sign if necessary
    if (flags & _RWSTD_IOS_SHOWPOS)
        *--end = '+';

    // move the contents of the buffer to the beginning
    const _RWSTD_SIZE_T len = begin - end;

   memmove (buf, end, len);

    return len;
}


static inline _RWSTD_SIZE_T
__rw_dtoa (char *buf, long i, unsigned flags)
{
    if (i < 0) {
        flags  &= ~_RWSTD_IOS_SHOWPOS;
        *buf++  = '-';
        return 1 + __rw_dtoa (buf, _RWSTD_STATIC_CAST (unsigned long, -i),
                              flags);
    }
        
    return __rw_dtoa (buf, _RWSTD_STATIC_CAST (unsigned long, i), flags);
}


// convert unsigned long to a roman number
static _RWSTD_SIZE_T
__rw_utor (char *buf, unsigned long i, unsigned flags)
{
    //                          01234560123456
    static const char lit [] = "ivxlcdmIVXLCDM";

    if (0 == i || i > 4999)
        return __rw_dtoa (buf, i, flags);

    const char* const pdigs = flags & _RWSTD_IOS_UPPERCASE ? lit + 7 : lit;

    const char *begin = buf;

    for (; i >= 1000; i -= 1000)
        *buf++ = pdigs [6];   // 'M'

    for (unsigned long j = 0, ord = 100; j != 6; j += 2, ord /= 10) {

        unsigned long fact;

        if (i >= (fact = 9 * ord)) {
            *buf++ = pdigs [4 - j];   // {C,X,I}
            *buf++ = pdigs [6 - j];   // {M,C,X}
            i -= fact;
        }
        else if (i >= (fact = 5 * ord)) {
            *buf++ = pdigs [5 - j];   // {D,L,V}
            for (i -= fact; i >= ord; i -= ord)
                *buf++ = pdigs [4 - j];   // {C,X,I}
        }
        else if (i >= (fact = 4 * ord)) {
            *buf++ = pdigs [4 - j];   // {C,X,I}
            *buf++ = pdigs [5 - j];   // {D,L,V}
            i -= fact;
        }
        else {
            for (; i >= ord; i -= ord)
                *buf++ = pdigs [4 - j];   // {C,X,I}
        }
    }

    return buf - begin;
}


static _RWSTD_SIZE_T
__rw_itoa (char *buf, unsigned long i, unsigned flags)
{
    const char* const pdigs = flags & _RWSTD_IOS_UPPERCASE ?
        __rw_digits + 36 : __rw_digits;

    const int basemask = (flags >> _RWSTD_IOS_BASEOFF) - 1;

    int bits;

    char *end = buf;

    switch (basemask) {
    case  -1: case 9:
        return __rw_dtoa (end, i, flags);

    case 0:
        return __rw_utor (end, i, flags);

    case  1: bits = 1; break;
    case  3: bits = 2; break;
    case  7:
        bits = 3;
        if (i && flags & _RWSTD_IOS_SHOWBASE)
            *end++ = '0';
        break;

    case 15:
        bits = 4;
        if (i && flags & _RWSTD_IOS_SHOWBASE) {
            *end++ = '0';
            *end++ = pdigs [33];   // 'X' or 'x'
        }
        break;

    case 31:
        bits = 5; break;

    default:
        return __rw_btoa (buf, i, basemask + 1);
    }

    int j;

    // skip leading zeros
    if (i) {
        // maximum number of digits in the given base (basemask + 1)
        const int digits =
            (_STD::numeric_limits<unsigned long>::digits + bits - 1) / bits;

        for (j = digits - 1; !(i & (long (basemask) << j * bits)); --j);
    }
    else
        j = 0;

    do {
        const int dig = int ((i >> (j * bits)) & basemask);

        _RWSTD_ASSERT (dig >= 0 && dig <= basemask);

        *end++ = pdigs [dig];
    } while (j--);

    return end - buf;
}


static inline _RWSTD_SIZE_T
__rw_itoa (char *buf, long i, unsigned flags)
{
    if (10 == flags >> _RWSTD_IOS_BASEOFF)
        return __rw_dtoa (buf, i, flags);

    return __rw_itoa (buf, _RWSTD_STATIC_CAST (unsigned long, i), flags);
}


_RWSTD_EXPORT _RWSTD_SIZE_T
__rw_put_groups (char **pbuf, _RWSTD_SIZE_T len, _RWSTD_SIZE_T bufsize,
                 const char *end, const char *grouping)
{
    _RWSTD_ASSERT (0 != *pbuf);
    _RWSTD_ASSERT (0 != grouping);

    _RWSTD_UNUSED (bufsize);

    if (end) {
        // for floats, find the decimal point or one of { 'e', 'E' }
        end = strchr (*pbuf, '.');
        if (!end) {
            // try the comma in case sprintf() was used after
            // a call setlocale() that changed '.' to ','
            end = strchr (*pbuf, ',');
            if (!end)
                end = strpbrk (*pbuf, "Ee");
        }
    }

    if (!end) {
        // no decimal point for all other types
        end = *pbuf + len;
    }

    typedef unsigned char UChar;

    char *pd = *pbuf;   // pointer to the integral part (past any prefix)

    if (43 /* '-' or '+' */ == __rw_digit_map [UChar (*pd)])
        ++pd;
    else if ('0' == *pd) {
        ++pd;

        if (33 /* 'X' or 'x' */ == __rw_digit_map [UChar (*pd)])
            ++pd;
    }

    _RWSTD_SIZE_T ngrps  = 0;   // number of complete groups
    _RWSTD_SIZE_T grplen = 0;   // length of complete groups

    // compute the amount of buffer space needed for group separators
    const char *pg = grouping;
    for ( ; ; ++ngrps) {

        UChar grp = UChar (*pg);

        if (0 == grp) {
            // '\0' causes the last grouping to be repeated
            grp = UChar (pg [-1]);
        }
        else if (_RWSTD_CHAR_MAX == grp) {
            // _RWSTD_CHAR_MAX terminates the grouping algorithm
            break;
        }
        else
            ++pg;

        if (grplen + grp >= _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, end - pd))
            break;

        grplen += grp;
    }

    pg   = grouping;   // reset to point to the first grouping
    end += ngrps;      // adjust the new position of the decimal point
    len += ngrps;      // adjust the length of buffer

    grplen = *pg++;    // length of the first grouping

    const bool no_groups = '\0' == **pbuf;

    // copy buffer onto itself starting with the rightmost digit,
    // inserting thousands_sep placeholders (';') according to
    // `grouping' in the integral portion of the number
    // using ';' rather than ',' to prevent potential collisions
    // with a comma inserted by sprintf() in some locales
    for (pd = *pbuf + (len - 1); pd != *pbuf && ngrps; --pd) {
        if (pd >= end) {
            // copy the fractional part (if any) of the number
            *pd = pd [-_RWSTD_STATIC_CAST (_RWSTD_PTRDIFF_T, ngrps)];
        }
        else {
            if ((_RWSTD_SIZE_T)(end - pd) == grplen + 1) {
                // insert throusands separator and compute
                // the offset of the next separator
                *pd = ';';
                --ngrps;

                if (_RWSTD_CHAR_MAX == *pg)
                    break;

                // '\0' forces the repetition of the last grouping
                grplen += (*pg ? *pg++ : pg [-1]) + 1;
            }
            else {
                // copy the integral part
                *pd = pd [-_RWSTD_STATIC_CAST (_RWSTD_PTRDIFF_T, ngrps)];
            }
        }
    }

    if (no_groups) {

        pd = *pbuf;

        // replace each group including the thousands_sep placeholder
        // in the buffer with its size
        for (char *ps = *pbuf, *last = *pbuf; ; ++pd) {

            if (pd == *pbuf + len) {
                // append the size of the last group, set `len', and break
                *ps++ = char (pd - last);
                len   = ps - *pbuf;
                break;
            }

            if (';' == *pd) {
                // replace group with it size
                *ps++ = char (pd - last);
                last  = pd + 1;
            }
        }
    }

    return len;
}


static inline void
__rw_fix_flt (char *&end, _RWSTD_SIZE_T &len, unsigned flags)
{
#if defined (_WIN32) || defined (_WIN64)

    if (len > 5) {
        // make Win32 output conform to C99 printf() requirements
        // on the exponent: The exponent always contains at least
        // two digits, and only as many more digits as necessary
        // to represent the exponent.
        if (('e' == end [-5] || 'E' == end [-5]) && '0' == end [-3]) {
            end [-3] = end [-2];
            end [-2] = end [-1];
            --len;
            --end;
        }
        else if ('#' == end [-4]) {
            // normalize the format of infinity to conform to C99

            const char str[] = "iInNfF";

            const bool cap = !!(flags & _RWSTD_IOS_UPPERCASE);

            end [-6] = str [cap + 0];
            end [-5] = str [cap + 2];
            end [-4] = str [cap + 4];
            end -= 3;
            len -= 3;
        }
        else if ('#' == end [-5]) {
            // normalize the format of NaN to conform to C99

            const char str[] = "nNaA";

            const bool cap = !!(flags & _RWSTD_IOS_UPPERCASE);

            end [-7] = str [cap + 0];
            end [-6] = str [cap + 2];
            end [-5] = str [cap + 0];
            end -= 4;
            len -= 4;
        }
    }

#else

    // normalize the format of infinity and NaN to one of
    // { INF, inf, NAN, nan, NANQ, nanq, NANS, nans }
    // for portability
    char* beg = end - len;

    typedef unsigned char UChar;

    // is there a sign?
    bool sgn = false;

    if (43 /* '+' or '-' */ == __rw_digit_map [UChar (*beg)]) {
        sgn = true;
        ++beg;
    }

    const char* pstr;

    switch (__rw_digit_map [UChar (*beg)]) {

    case 18 /* 'I' or 'i' */ :
        pstr = "iInNfF\0\0";
        len  = 3;
        break;

    case 23 /* 'N' or 'n' */ : {

        // distinguish between quiet and signaling NaN

        // FIXME: do this portably, regardless of printf output
        // (some libc, such as Solaris, output the same string
        // for both quiet and signaling NaN; others, such as
        // AIX, output NaNQ and NaNS, respectively)

        const UChar last = __rw_digit_map [UChar (*(end - 1))];
        if (26 /* 'Q' or 'q' */ == last) {
            pstr = "nNaAnNqQ";
            len  = 4;
        }
        else if (28 /* 'S' or 's' */ == last) {
            pstr = "nNaAnNsS";
            len  = 4;
        }
        else {
            pstr = "nNaAnN\0\0";
            len  = 3;
        }
        break;
    }

    default:
        return;
    }

    const bool cap = !!(flags & _RWSTD_IOS_UPPERCASE);

    beg [0] = pstr [cap + 0];
    beg [1] = pstr [cap + 2];
    beg [2] = pstr [cap + 4];
    beg [3] = pstr [cap + 6];

    end = beg + 3 + ('\0' != beg [3]);

    // increase the length by one for the sign
    if (sgn)
        ++len;

#endif   // _WIN{32,64}

}



_RWSTD_EXPORT _RWSTD_SIZE_T
__rw_put_num (char **pbuf, _RWSTD_SIZE_T bufsize,
              unsigned flags, int type, _RWSTD_STREAMSIZE prec,
              const void *pval, const char *grouping)
{
    char              fmtbuf [32];   // buffer for stdio format specifier
    const char       *fmt = 0;       // stdio format specifier
    char* const       buf = *pbuf;   // saved value of *pbuf
    char             *end = 0;       // decimal point
    _RWSTD_SIZE_T     len;           // length of formatted number
    _RWSTD_STREAMSIZE fpr;           // special case floating point precision

    typedef _RWSTD_SIZE_T SizeT;

    switch (type) {

    case __rw_facet::_C_bool:
        if (flags & _RWSTD_IOS_BOOLALPHA) {
            // no output
            len  = 0;
            *buf = '\0';
            break;
        }
        // else fall through...

    case __rw_facet::_C_short:
    case __rw_facet::_C_int:
    case __rw_facet::_C_long:
        len = __rw_itoa (buf, _RWSTD_REINTERPRET_CAST (long, pval), flags);
        break;

    case __rw_facet::_C_ushort:
    case __rw_facet::_C_uint:
    case __rw_facet::_C_ulong:
        // unsigned output behaves analogously printf() with %u
        // note that the plus in "%+u" is meaningless (i.e., the
        // sign is only used in signed conversions; 7.19 6.1, p6
        // of C99: The result of a signed conversion always begins
        // with a plus or minus sign.)
        len = __rw_itoa (buf, _RWSTD_REINTERPRET_CAST (unsigned long, pval),
                         flags & ~_RWSTD_IOS_SHOWPOS);
        break;

#ifdef _RWSTD_LONG_LONG

    case __rw_facet::_C_llong:
        len = __rw_itoa (buf, *(const _LLong*)pval, flags);
        break;

    case __rw_facet::_C_ullong:
        len = __rw_itoa (buf, *(const _ULLong*)pval,
                         flags & ~_RWSTD_IOS_SHOWPOS);
        break;

#endif   // _RWSTD_LONG_LONG

    case __rw_facet::_C_float | __rw_facet::_C_ptr:
        fpr = prec < 0 && flags & _RWSTD_IOS_FIXED ? 0 : prec;
        fmt = __rw_get_stdio_fmat (fmtbuf, type & ~__rw_facet::_C_ptr,
                                   flags, fpr);
        for (; ;) {
            len = SizeT (_SNPRINTF (*pbuf, bufsize, fmt,
                                    *(const float*)pval));

            if (len >= bufsize) {
                if (*pbuf != buf)
                    delete[] *pbuf;

                *pbuf = new char [bufsize = len + 1 ? len + 1 : bufsize * 2];
            }
            else {
                _RWSTD_ASSERT (len > 0);

                break;
            }
        }

        end = *pbuf + len;

        // fix up output to conform to C99
        __rw_fix_flt (end, len, flags);
        break;

    case __rw_facet::_C_double | __rw_facet::_C_ptr:
        fpr = prec < 0 && flags & _RWSTD_IOS_FIXED ? 0 : prec;
        fmt = __rw_get_stdio_fmat (fmtbuf, type & ~__rw_facet::_C_ptr,
                                   flags, fpr);

        for ( ; ; ) {
            len = SizeT (_SNPRINTF (*pbuf, bufsize, fmt,
                                    *(const double*)pval));

            if (len >= bufsize) {
                if (*pbuf != buf)
                    delete[] *pbuf;

                *pbuf = new char [bufsize = len + 1 ? len + 1 : bufsize * 2];
            }
            else {
                _RWSTD_ASSERT (len > 0);

                break;
            }
        }

        end = *pbuf + len;

        // fix up output to conform to C99
        __rw_fix_flt (end, len, flags);
        break;

#ifndef _RWSTD_NO_LONG_DOUBLE

    case __rw_facet::_C_ldouble | __rw_facet::_C_ptr:
        fpr = prec < 0 && flags & _RWSTD_IOS_FIXED ? 0 : prec;
        fmt = __rw_get_stdio_fmat (fmtbuf, type & ~__rw_facet::_C_ptr,
                                   flags, fpr);

        for ( ; ; ) {
            len = SizeT (_SNPRINTF (*pbuf, bufsize, fmt,
                                    *(const long double*)pval));
            if (len >= bufsize) {
                if (*pbuf != buf)
                    delete[] *pbuf;

                *pbuf = new char [bufsize = len + 1 ? len + 1 : bufsize * 2];
            }
            else {
                _RWSTD_ASSERT (len > 0);

                break;
            }
        }

        end = *pbuf + len;

        // fix up output to conform to C99
        __rw_fix_flt (end, len, flags);
        break;

#endif   // _RWSTD_NO_LONG_DOUBLE

    case __rw_facet::_C_pvoid:
        if (pval) {
            fmt = __rw_get_stdio_fmat (fmtbuf, type, flags, prec);
            len = SizeT (_SNPRINTF (buf, bufsize, fmt, pval));
        }
        else {
            // prevent GNU libc from formatting null pointers as "(nil)"
            *buf = '0';
            len  = 1;
        }

        // prevent grouping
        grouping = "";
        break;

    default:
        _RWSTD_ASSERT (!"logic error: bad type");
        len = 0;   // silence used before initialized warnings
    }

    if (prec < 0 && flags & _RWSTD_IOS_FIXED) {

        // extension: when ios::fixed is set, negative precision inserts
        // a decimal_point placeholder `prec' positions before the least
        // significant digit

        const bool sign = '-' == **pbuf || '+' == **pbuf;

        char* const beg = *pbuf + sign;

        char *src;   // first of the digits to move
        char *dst;   // where to move the first digit
        char *dp;    // where to insert the decimal point

        const _RWSTD_PTRDIFF_T ndigs = len - sign;

        _RWSTD_SIZE_T nfill;   // the number of 0's to insert
        _RWSTD_SIZE_T nmove;   // the number of digits to move

        if (-prec >= ndigs) {

            // insert 0's in addition to the decimal point
            // e.g., "1234" with prec == -6 yields "0.01234"

            nmove = ndigs;
            nfill = -prec - ndigs + 2;

            dst = beg + nfill;
            src = beg;
            dp  = beg + 1;

            // adjust the length of the block
            len += nfill;
        }
        else {

            // insert decimal point into the string of digits
            // e.g., "1234" with prec == -3 yields "1.234"

            nfill = 0;
            nmove = SizeT (-prec);

            src = beg + (ndigs + prec);
            dst = src + 1;
            dp  = src;

            ++len;   // grow the length
        }

        // move a block of digits to make room for 0's, if any,
        // and the decimal point placeholder
       memmove (dst, src, nmove);
       memset (beg, '0', nfill);

        *dp = '.';
        end = *pbuf + len;
    }

    // insert commas as thousands separators if grouping is required
    // integral and floating point types only (i.e., not for pointers)
    if (len > 1 && *grouping && _RWSTD_CHAR_MAX != *grouping)
        len = __rw_put_groups (pbuf, len, bufsize, end, grouping);

    // verify that the buffer hasn't overrun
    _RWSTD_ASSERT (len <= bufsize);

    return len;
}


}   // namespace __rw
