VirtualBox

Changeset 58809 in vbox for trunk/src/VBox/ValidationKit


Ignore:
Timestamp:
Nov 21, 2015 7:28:49 PM (9 years ago)
Author:
vboxsync
Message:

bs3kit: Watcom intrinsics (no 64-bit division yet) and printf.

Location:
trunk/src/VBox/ValidationKit/bootsectors/bs3kit
Files:
14 added
5 edited
1 copied
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk

    r58808 r58809  
    446446        bs3-cmn-Panic.asm \
    447447        bs3-cmn-PrintChr.asm \
    448         bs3-cmn-PrintF.c \
     448        bs3-cmn-Printf.c \
    449449        bs3-cmn-PrintU32.asm \
    450450        bs3-cmn-PrintX32.asm \
     
    452452       bs3-cmn-PrintStrColonSpaces.asm \
    453453       bs3-cmn-PrintStrSpacesColonSpace.c \
     454       bs3-cmn-StrFormatV.c \
     455       bs3-cmn-StrPrintf.c \
    454456       bs3-cmn-StrLen.c \
    455457       bs3-cmn-StrNLen.c \
     
    488490        bs3-system-data.asm \
    489491        bs3-rm-InitMemory.c \
    490         bs3-cmn-hexdigits.c
     492        bs3-cmn-hexdigits.c \
     493        bs3-wc16-U8DR.asm \
     494        bs3-wc16-U8DQ.asm \
     495        bs3-wc16-I8DR.asm \
     496        bs3-wc16-I8DQ.asm \
     497        bs3-wc16-I8RS.asm \
     498        bs3-wc16-U8RS.asm \
     499        bs3-wc16-U8LS.asm \
     500        bs3-wc16-U4D.asm \
     501        bs3-wc16-I4D.asm \
    491502
    492503# The 32-bit BS3Kit library.
     
    495506bs3kit-common-32_DEFS     = TMPL_PE32 BS3_CMN_ONLY
    496507bs3kit-common-32_ASDEFS   = RT_ASMDEFS_INC_FIRST_FILE
    497 bs3kit-common-32_SOURCES  = $(VBOX_BS3KIT_COMMON_SOURCES)
     508bs3kit-common-32_SOURCES  = $(VBOX_BS3KIT_COMMON_SOURCES) \
     509        bs3-wc32-U8D.asm \
     510        bs3-wc32-I8D.asm \
     511        bs3-wc32-I8RS.asm \
     512        bs3-wc32-U8RS.asm \
     513        bs3-wc32-U8LS.asm \
    498514
    499515# The 64-bit BS3Kit library.
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/VBoxBs3ObjConverter.cpp

    r58808 r58809  
    516516    "\x05" "__I4D",
    517517    "\x05" "__I4M",
     518    "\x05" "__I8D",
    518519    "\x06" "__I8DQ",
    519520    "\x07" "__I8DQE",
     
    530531    "\x05" "__U4D",
    531532    "\x05" "__U4M",
     533    "\x05" "__U8D",
    532534    "\x06" "__U8DQ",
    533535    "\x07" "__U8DQE",
     
    617619                                && memcmp(&g_apszExtDefRenames[i][1], pchName, cch) == 0)
    618620                            {
    619                                 pchName[0] = fProbably32bit ? '3' : '1';
    620                                 pchName[1] = fProbably32bit ? '2' : '6';
     621                                pchName[0] = fProbably32bit ? '?' : '_';
     622                                pchName[1] = fProbably32bit ? '?' : '?';
    621623                                break;
    622624                            }
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-Printf.c

    r58806 r58809  
    11/* $Id$ */
    22/** @file
    3  * BS3Kit - Bs3PrintF
     3 * BS3Kit - Bs3Printf, Bs3PrintfV
    44 */
    55
     
    2929
    3030
    31 #define STR_F_CAPITAL         0x0001
    32 #define STR_F_LEFT            0x0002
    33 #define STR_F_ZEROPAD         0x0004
    34 #define STR_F_SPECIAL         0x0008
    35 #define STR_F_VALSIGNED       0x0010
    36 #define STR_F_PLUS            0x0020
    37 #define STR_F_BLANK           0x0040
    38 #define STR_F_WIDTH           0x0080
    39 #define STR_F_PRECISION       0x0100
    40 #define STR_F_THOUSAND_SEP    0x0200
    41 
    42 
    43 static size_t bs3PrintFormatString(const char *psz, size_t cchMax, uint16_t fFlags, int cchWidth, int cchPrecision)
     31BS3_DECL(size_t) bs3PrintFmtOutput(char ch, void *pvUser)
    4432{
    45     size_t cchRet;
    46     if (cchMax == ~(size_t)0)
    47         cchMax = Bs3StrNLen(psz, cchMax);
    48     cchRet = cchMax;
    49 
    50     /** @todo this is kind of crude, full fleged formatting can wait.  */
    51     while (cchMax-- > 0)
    52         Bs3PrintChr(*psz++);
    53 
    54     return cchRet;
     33    if (ch)
     34    {
     35        if (ch != '\n')
     36            Bs3PrintChr('\r');
     37        Bs3PrintChr(ch);
     38        return 1;
     39    }
     40    NOREF(pvUser);
     41    return 0;
    5542}
    5643
    5744
    58 static size_t bs3PrintFormatU64(char szTmp[64], uint64_t uValue, unsigned uBase, uint16_t fFlags, int cchWidth, int cchPrecision)
     45BS3_DECL(size_t) Bs3PrintfV(const char BS3_FAR *pszFormat, va_list va)
    5946{
    60 #if 0
    61     const char *pachDigits = !(fFlags & STR_F_CAPITAL) ? BS3_DATA_NM(g_achBs3HexDigits) : BS3_DATA_NM(g_achBs3HexDigitsUpper);
    62     char       *psz = &szTmp[64];
    63 
    64     *--psz = '\0';
    65     if (uBase == 10)
    66     {
    67         do
    68         {
    69             *--psz = pachDigits[uValue % 10];
    70             uValue /= 10;
    71         } while (uValue > 0);
    72     }
    73     else
    74     {
    75         unsigned const cShift = uBase == 8 ? 2 : 3;
    76         unsigned const fMask  = uBase == 8 ? 7 : 15;
    77         do
    78         {
    79             *--psz = pachDigits[uValue & fMask];
    80             uValue >>= cShift;
    81         } while (uValue > 0);
    82     }
    83     return bs3PrintFormatString(psz, &szTmp[63] - psz, 0, 0, 0);
    84 #else
    85     return 0;
    86 #endif
    87 }
    88 
    89 #if ARCH_BITS == 64
    90 # define bs3PrintFormatU32 bs3PrintFormatU64
    91 # define bs3PrintFormatU16 bs3PrintFormatU64
    92 
    93 #else
    94 static size_t bs3PrintFormatU32(char szTmp[64], uint32_t uValue, unsigned uBase, uint16_t fFlags, int cchWidth, int cchPrecision)
    95 {
    96     const char *pachDigits = !(fFlags & STR_F_CAPITAL) ? BS3_DATA_NM(g_achBs3HexDigits) : BS3_DATA_NM(g_achBs3HexDigitsUpper);
    97     char       *psz = &szTmp[64];
    98 
    99     *--psz = '\0';
    100     if (uBase == 10)
    101     {
    102         do
    103         {
    104             *--psz = pachDigits[uValue % 10];
    105             uValue /= 10;
    106         } while (uValue > 0);
    107     }
    108     else
    109     {
    110         unsigned const cShift = uBase == 8 ? 2 : 3;
    111         unsigned const fMask  = uBase == 8 ? 7 : 15;
    112         do
    113         {
    114             *--psz = pachDigits[uValue & fMask];
    115             uValue >>= cShift;
    116         } while (uValue > 0);
    117     }
    118     return bs3PrintFormatString(psz, &szTmp[63] - psz, 0, 0, 0);
    119 }
    120 
    121 # if ARCH_BITS == 16
    122 static size_t bs3PrintFormatU16(char szTmp[64], uint16_t uValue, unsigned uBase, uint16_t fFlags, int cchWidth, int cchPrecision)
    123 {
    124     if (uBase == 10)
    125     {
    126         const char *pachDigits = !(fFlags & STR_F_CAPITAL) ? BS3_DATA_NM(g_achBs3HexDigits) : BS3_DATA_NM(g_achBs3HexDigitsUpper);
    127         char       *psz = &szTmp[64];
    128 
    129         *--psz = '\0';
    130         do
    131         {
    132             *--psz = pachDigits[uValue % 10];
    133             uValue /= 10;
    134         } while (uValue > 0);
    135         return bs3PrintFormatString(psz, &szTmp[63] - psz, 0, 0, 0);
    136     }
    137     /* 32-bit shifting is reasonably cheap, so combine with 32-bit. */
    138     return bs3PrintFormatU32(szTmp, uValue, uBase, fFlags, cchWidth, cchPrecision);
    139 }
    140 # endif /* 16-bit */
    141 #endif /* !64-bit */
    142 
    143 
    144 static size_t bs3PrintFormatS64(char szTmp[64], int16_t iValue, uint16_t fFlags, int cchWidth, int cchPrecision)
    145 {
    146     /** @todo this is kind of crude, full fleged formatting can wait.  */
    147     size_t cchRet = 0;
    148     if (iValue < 0)
    149     {
    150         Bs3PrintChr('-');
    151         cchRet++;
    152     }
    153     cchRet += bs3PrintFormatU64(szTmp, iValue, 10, fFlags & ~STR_F_VALSIGNED, cchWidth, cchPrecision);
    154     return cchRet;
     47    return Bs3StrFormatV(pszFormat, va, bs3PrintFmtOutput, NULL);
    15548}
    15649
    15750
    158 static size_t bs3PrintFormatS32(char szTmp[64], int16_t iValue, uint16_t fFlags, int cchWidth, int cchPrecision)
    159 {
    160     /** @todo this is kind of crude, full fleged formatting can wait.  */
    161     size_t cchRet = 0;
    162     if (iValue < 0)
    163     {
    164         Bs3PrintChr('-');
    165         cchRet++;
    166     }
    167     cchRet += bs3PrintFormatU32(szTmp, iValue, 10, fFlags & ~STR_F_VALSIGNED, cchWidth, cchPrecision);
    168     return cchRet;
    169 }
    170 
    171 
    172 #if ARCH_BITS == 16
    173 static size_t bs3PrintFormatS16(char szTmp[64], int16_t iValue, uint16_t fFlags, int cchWidth, int cchPrecision)
    174 {
    175     /** @todo this is kind of crude, full fleged formatting can wait.  */
    176     size_t cchRet = 0;
    177     if (iValue < 0)
    178     {
    179         Bs3PrintChr('-');
    180         cchRet++;
    181     }
    182     cchRet += bs3PrintFormatU16(szTmp, iValue, 10, fFlags & ~STR_F_VALSIGNED, cchWidth, cchPrecision);
    183     return cchRet;
    184 }
    185 #endif
    186 
    187 
    188 
    189 
    190 
    191 BS3_DECL(size_t) Bs3PrintFV(const char BS3_FAR *pszFormat, va_list va)
    192 {
    193     size_t cchRet = 0;
    194     char ch;
    195     while ((ch = *pszFormat++) != '\0')
    196     {
    197         unsigned int    fFlags;
    198         int             cchWidth;
    199         int             cchPrecision;
    200         char            chArgSize;
    201         char            szTmp[64];
    202 
    203         /*
    204          * Deal with plain chars.
    205          */
    206         if (ch != '%')
    207         {
    208             if (ch == '\n')
    209                 Bs3PrintChr('\r');
    210             Bs3PrintChr(ch);
    211             cchRet++;
    212             continue;
    213         }
    214 
    215         ch = *pszFormat++;
    216         if (ch == '%')
    217         {
    218             Bs3PrintChr(ch);
    219             cchRet++;
    220             continue;
    221         }
    222 
    223         /*
    224          * Flags.
    225          */
    226         fFlags = 0;
    227         for (;;)
    228         {
    229             unsigned int fThis;
    230             switch (ch)
    231             {
    232                 default:    fThis = 0;                  break;
    233                 case '#':   fThis = STR_F_SPECIAL;      break;
    234                 case '-':   fThis = STR_F_LEFT;         break;
    235                 case '+':   fThis = STR_F_PLUS;         break;
    236                 case ' ':   fThis = STR_F_BLANK;        break;
    237                 case '0':   fThis = STR_F_ZEROPAD;      break;
    238                 case '\'':  fThis = STR_F_THOUSAND_SEP; break;
    239             }
    240             if (!fThis)
    241                 break;
    242             fFlags |= fThis;
    243             ch = *pszFormat++;
    244         }
    245 
    246         /*
    247          * Width.
    248          */
    249         cchWidth = 0;
    250         if (RT_C_IS_DIGIT(ch))
    251         {
    252             do
    253             {
    254                 cchWidth *= 10;
    255                 cchWidth  = ch - '0';
    256                 ch = *pszFormat++;
    257             } while (RT_C_IS_DIGIT(ch));
    258             fFlags |= STR_F_WIDTH;
    259         }
    260         else if (ch == '*')
    261         {
    262             cchWidth = va_arg(va, int);
    263             if (cchWidth < 0)
    264             {
    265                 cchWidth = -cchWidth;
    266                 fFlags |= STR_F_LEFT;
    267             }
    268             fFlags |= STR_F_WIDTH;
    269         }
    270 
    271         /*
    272          * Precision
    273          */
    274         cchPrecision = 0;
    275         if (RT_C_IS_DIGIT(ch))
    276         {
    277             do
    278             {
    279                 cchPrecision *= 10;
    280                 cchPrecision  = ch - '0';
    281                 ch = *pszFormat++;
    282             } while (RT_C_IS_DIGIT(ch));
    283             fFlags |= STR_F_PRECISION;
    284         }
    285         else if (ch == '*')
    286         {
    287             cchPrecision = va_arg(va, int);
    288             if (cchPrecision < 0)
    289                 cchPrecision = 0;
    290             fFlags |= STR_F_PRECISION;
    291         }
    292 
    293         /*
    294          * Argument size.
    295          */
    296         chArgSize = ch;
    297         switch (ch)
    298         {
    299             default:
    300                 chArgSize = 0;
    301                 break;
    302 
    303             case 'z':
    304             case 'L':
    305             case 'j':
    306             case 't':
    307                 ch = *pszFormat++;
    308                 break;
    309 
    310             case 'l':
    311                 ch = *pszFormat++;
    312                 if (ch == 'l')
    313                 {
    314                     chArgSize = 'L';
    315                     ch = *pszFormat++;
    316                 }
    317                 break;
    318 
    319             case 'h':
    320                 ch = *pszFormat++;
    321                 if (ch == 'h')
    322                 {
    323                     chArgSize = 'H';
    324                     ch = *pszFormat++;
    325                 }
    326                 break;
    327         }
    328 
    329         /*
    330          * The type.
    331          */
    332         switch (ch)
    333         {
    334             /*
    335              * Char
    336              */
    337             case 'c':
    338                 szTmp[0] = va_arg(va, int /*char*/);
    339                 szTmp[1] = '\0';
    340                 cchRet += bs3PrintFormatString(szTmp, 1, fFlags, cchWidth, cchPrecision);
    341                 break;
    342 
    343             /*
    344              * String.
    345              */
    346             case 's':
    347             {
    348                 const char BS3_FAR *psz = va_arg(va, const char BS3_FAR *);
    349                 if (psz == NULL)
    350                     psz = "<NULL>";
    351                 cchRet += bs3PrintFormatString(psz, ~(size_t)0, fFlags, cchWidth, cchPrecision);
    352                 break;
    353             }
    354 
    355             /*
    356              * Signed integers.
    357              */
    358             case 'i':
    359             case 'd':
    360                 fFlags |= STR_F_VALSIGNED;
    361                 switch (chArgSize)
    362                 {
    363                     case 0:
    364                     case 'h': /* signed short should be promoted to int or be the same as int */
    365                     case 'H': /* signed char should be promoted to int. */
    366                     {
    367                         signed int iValue = va_arg(va, signed int);
    368 #if ARCH_BITS == 16
    369                         cchRet += bs3PrintFormatS16(szTmp, iValue, fFlags, cchWidth, cchPrecision);
    370 #else
    371                         cchRet += bs3PrintFormatS32(szTmp, iValue, fFlags, cchWidth, cchPrecision);
    372 #endif
    373                         break;
    374                     }
    375                     case 'l':
    376                     {
    377                         signed long lValue = va_arg(va, signed long);
    378                         if (sizeof(lValue) == 4)
    379                             cchRet += bs3PrintFormatS32(szTmp, lValue, fFlags, cchWidth, cchPrecision);
    380                         else
    381                             cchRet += bs3PrintFormatS64(szTmp, lValue, fFlags, cchWidth, cchPrecision);
    382                         break;
    383                     }
    384                     case 'L':
    385                     {
    386                         unsigned long long ullValue = va_arg(va, unsigned long long);
    387                         cchRet += bs3PrintFormatS64(szTmp, ullValue, fFlags, cchWidth, cchPrecision);
    388                         break;
    389                     }
    390                 }
    391                 break;
    392 
    393             /*
    394              * Unsigned integers.
    395              */
    396             case 'X':
    397                 fFlags |= STR_F_CAPITAL;
    398             case 'x':
    399             case 'u':
    400             {
    401                 unsigned uBase = ch = 'u' ? 10 : 16;
    402                 switch (chArgSize)
    403                 {
    404                     case 0:
    405                     case 'h': /* unsigned short should be promoted to int or be the same as int */
    406                     case 'H': /* unsigned char should be promoted to int. */
    407                     {
    408                         unsigned int uValue = va_arg(va, unsigned int);
    409 #if ARCH_BITS == 16
    410                         cchRet += bs3PrintFormatU16(szTmp, uValue, uBase, fFlags, cchWidth, cchPrecision);
    411 #else
    412                         cchRet += bs3PrintFormatU32(szTmp, uValue, uBase, fFlags, cchWidth, cchPrecision);
    413 #endif
    414                         break;
    415                     }
    416                     case 'l':
    417                     {
    418                         unsigned long ulValue = va_arg(va, unsigned long);
    419                         if (sizeof(ulValue) == 4)
    420                             cchRet += bs3PrintFormatU32(szTmp, ulValue, uBase, fFlags, cchWidth, cchPrecision);
    421                         else
    422                             cchRet += bs3PrintFormatU64(szTmp, ulValue, uBase, fFlags, cchWidth, cchPrecision);
    423                         break;
    424                     }
    425                     case 'L':
    426                     {
    427                         unsigned long long ullValue = va_arg(va, unsigned long long);
    428                         cchRet += bs3PrintFormatU64(szTmp, ullValue, uBase, fFlags, cchWidth, cchPrecision);
    429                         break;
    430                     }
    431                 }
    432                 break;
    433             }
    434 
    435             /*
    436              * Our stuff.
    437              */
    438             case 'R':
    439             {
    440                 unsigned uBase;
    441                 ch = *pszFormat++;
    442                 switch (ch)
    443                 {
    444                     case 'I':
    445                         fFlags |= STR_F_VALSIGNED;
    446                         /* fall thru */
    447                     case 'U':
    448                         uBase = 10;
    449                         break;
    450                     case 'X':
    451                         uBase = 16;
    452                         break;
    453                     default:
    454                         uBase = 0;
    455                         break;
    456                 }
    457                 if (uBase)
    458                 {
    459                     ch = *pszFormat++;
    460                     switch (ch)
    461                     {
    462 #if ARCH_BITS != 16
    463                         case '3':
    464                         case '1': /* Will an unsigned 16-bit value always be promoted
    465                                      to a 16-bit unsigned int. It certainly will be promoted to a 32-bit int. */
    466                             pszFormat++; /* Assumes (1)'6' or (3)'2' */
    467 #else
    468                         case '1':
    469                             pszFormat++; /* Assumes (1)'6' */
    470 #endif
    471                         case '8': /* An unsigned 8-bit value should be promoted to int, which is at least 16-bit. */
    472                         {
    473                             unsigned int uValue = va_arg(va, unsigned int);
    474 #if ARCH_BITS == 16
    475                             cchRet += bs3PrintFormatU16(szTmp, uValue, uBase, fFlags, cchWidth, cchPrecision);
    476 #else
    477                             cchRet += bs3PrintFormatU32(szTmp, uValue, uBase, fFlags, cchWidth, cchPrecision);
    478 #endif
    479                             break;
    480                         }
    481 #if ARCH_BITS == 16
    482                         case '3':
    483                         {
    484                             uint32_t uValue = va_arg(va, uint32_t);
    485                             pszFormat++;
    486                             cchRet += bs3PrintFormatU32(szTmp, uValue, uBase, fFlags, cchWidth, cchPrecision);
    487                             break;
    488                         }
    489 #endif
    490                         case '6':
    491                         {
    492                             uint64_t uValue = va_arg(va, uint64_t);
    493                             pszFormat++;
    494                             cchRet += bs3PrintFormatU64(szTmp, uValue, uBase, fFlags, cchWidth, cchPrecision);
    495                             break;
    496                         }
    497                     }
    498                 }
    499                 break;
    500             }
    501 
    502             /*
    503              * Pointers.
    504              */
    505             case 'P':
    506                 fFlags |= STR_F_CAPITAL;
    507                 /* fall thru */
    508             case 'p':
    509             {
    510                 void BS3_FAR *pv = va_arg(va, void BS3_FAR *);
    511 #if ARCH_BITS == 16
    512                 cchRet += bs3PrintFormatU16(szTmp, BS3_FP_SEG(pv), 16, fFlags, fFlags & STR_F_SPECIAL ? 6 : 4, 0);
    513                 Bs3PrintChr(':');
    514                 cchRet += 1;
    515                 cchRet += bs3PrintFormatU16(szTmp, BS3_FP_OFF(pv), 16, fFlags & ~STR_F_SPECIAL, 4, 0);
    516 #elif ARCH_BITS == 32
    517                 cchRet += bs3PrintFormatU32(szTmp, (uintptr_t)pv, 16, fFlags | STR_F_SPECIAL, 10, 0);
    518 #elif ARCH_BITS == 64
    519                 cchRet += bs3PrintFormatU64(szTmp, (uintptr_t)pv, 16, fFlags | STR_F_SPECIAL | STR_F_THOUSAND_SEP, 19, 0);
    520 #else
    521 # error "Undefined or invalid ARCH_BITS."
    522 #endif
    523                 break;
    524             }
    525 
    526         }
    527     }
    528     return cchRet;
    529 }
    530 
    531 
    532 BS3_DECL(size_t) Bs3PrintF(const char BS3_FAR *pszFormat, ...)
     51BS3_DECL(size_t) Bs3Printf(const char BS3_FAR *pszFormat, ...)
    53352{
    53453    size_t cchRet;
    53554    va_list va;
    53655    va_start(va, pszFormat);
    537     cchRet = Bs3PrintFV(pszFormat, va);
     56    cchRet = Bs3StrFormatV(pszFormat, va, bs3PrintFmtOutput, NULL);
    53857    va_end(va);
    53958    return cchRet;
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-StrFormatV.c

    r58806 r58809  
    11/* $Id$ */
    22/** @file
    3  * BS3Kit - Bs3PrintF
     3 * BS3Kit - Bs3StrFormatV
    44 */
    55
     
    2525 */
    2626
     27
     28/*********************************************************************************************************************************
     29*   Header Files                                                                                                                 *
     30*********************************************************************************************************************************/
    2731#include "bs3kit-template-header.h"
    2832#include <iprt/ctype.h>
    2933
    3034
    31 #define STR_F_CAPITAL         0x0001
    32 #define STR_F_LEFT            0x0002
    33 #define STR_F_ZEROPAD         0x0004
    34 #define STR_F_SPECIAL         0x0008
    35 #define STR_F_VALSIGNED       0x0010
    36 #define STR_F_PLUS            0x0020
    37 #define STR_F_BLANK           0x0040
    38 #define STR_F_WIDTH           0x0080
    39 #define STR_F_PRECISION       0x0100
    40 #define STR_F_THOUSAND_SEP    0x0200
    41 
    42 
    43 static size_t bs3PrintFormatString(const char *psz, size_t cchMax, uint16_t fFlags, int cchWidth, int cchPrecision)
    44 {
    45     size_t cchRet;
    46     if (cchMax == ~(size_t)0)
    47         cchMax = Bs3StrNLen(psz, cchMax);
    48     cchRet = cchMax;
    49 
    50     /** @todo this is kind of crude, full fleged formatting can wait.  */
    51     while (cchMax-- > 0)
    52         Bs3PrintChr(*psz++);
    53 
    54     return cchRet;
     35/*********************************************************************************************************************************
     36*   Defined Constants And Macros                                                                                                 *
     37*********************************************************************************************************************************/
     38#define STR_F_CAPITAL           0x0001
     39#define STR_F_LEFT              0x0002
     40#define STR_F_ZEROPAD           0x0004
     41#define STR_F_SPECIAL           0x0008
     42#define STR_F_VALSIGNED         0x0010
     43#define STR_F_PLUS              0x0020
     44#define STR_F_BLANK             0x0040
     45#define STR_F_WIDTH             0x0080
     46#define STR_F_PRECISION         0x0100
     47#define STR_F_THOUSAND_SEP      0x0200
     48#define STR_F_NEGATIVE          0x0400 /**< Used to indicated '-' must be printed. */
     49
     50
     51/*********************************************************************************************************************************
     52*   Structures and Typedefs                                                                                                      *
     53*********************************************************************************************************************************/
     54/** Size of the temporary buffer. */
     55#define BS3FMT_TMP_SIZE    64
     56
     57/**
     58 * BS3kit string format state.
     59 */
     60typedef struct BS3FMTSTATE
     61{
     62    /** The output function. */
     63    PFNBS3STRFORMATOUTPUT pfnOutput;
     64    /** User argument for pfnOutput. */
     65    void BS3_FAR  *pvUser;
     66
     67    /** STR_F_XXX flags.   */
     68    unsigned        fFlags;
     69    /** The width when STR_F_WIDTH is specific. */
     70    int             cchWidth;
     71    /** The width when STR_F_PRECISION is specific. */
     72    int             cchPrecision;
     73    /** The number format base. */
     74    unsigned        uBase;
     75    /** Temporary buffer. */
     76    char            szTmp[BS3FMT_TMP_SIZE];
     77} BS3FMTSTATE;
     78/** Pointer to a BS3Kit string formatter state. */
     79typedef BS3FMTSTATE *PBS3FMTSTATE;
     80
     81
     82
     83/*********************************************************************************************************************************
     84*   Internal Functions                                                                                                           *
     85*********************************************************************************************************************************/
     86#if ARCH_BITS != 64
     87static size_t bs3StrFormatU32(PBS3FMTSTATE pState, uint32_t uValue);
     88#endif
     89
     90
     91
     92/**
     93 * Formats a number string.
     94 *
     95 * @returns Number of chars printed.
     96 * @param   pState              The string formatter state.
     97 * @param   pszNumber           The formatted number string.
     98 * @param   cchNumber           The length of the number.
     99 */
     100static size_t bs3StrFormatNumberString(PBS3FMTSTATE pState, char const *pszNumber, size_t cchNumber)
     101{
     102    /*
     103     * Calc the length of the core number with prefixes.
     104     */
     105    size_t cchActual = 0;
     106    size_t cchRet = cchNumber;
     107
     108    /* Accunt for sign char. */
     109    cchRet += !!(pState->fFlags & (STR_F_NEGATIVE | STR_F_PLUS | STR_F_BLANK));
     110
     111    /* Account for the hex prefix: '0x' or '0X' */
     112    if (pState->fFlags & STR_F_SPECIAL)
     113    {
     114        cchRet += 2;
     115        BS3_ASSERT(pState->uBase == 16);
     116    }
     117
     118    /* Account for thousand separators (applied while printing). */
     119    if (pState->fFlags & STR_F_THOUSAND_SEP)
     120        cchRet += (cchNumber - 1) / (pState->uBase == 10 ? 3 : 8);
     121
     122    /*
     123     * Do left blank padding.
     124     */
     125    if ((pState->fFlags & (STR_F_ZEROPAD | STR_F_LEFT | STR_F_WIDTH)) == STR_F_WIDTH)
     126        while (cchRet < pState->cchWidth)
     127        {
     128            cchActual += pState->pfnOutput(' ', pState->pvUser);
     129            cchRet++;
     130        }
     131
     132    /*
     133     * Sign indicator / space.
     134     */
     135    if (pState->fFlags & (STR_F_NEGATIVE | STR_F_PLUS | STR_F_BLANK))
     136    {
     137        char ch;
     138        if (pState->fFlags & STR_F_NEGATIVE)
     139            ch = '-';
     140        else if (pState->fFlags & STR_F_PLUS)
     141            ch = '+';
     142        else
     143            ch = ' ';
     144        cchActual += pState->pfnOutput(ch, pState->pvUser);
     145    }
     146
     147    /*
     148     * Hex prefix.
     149     */
     150    if (pState->fFlags & STR_F_SPECIAL)
     151    {
     152        cchActual += pState->pfnOutput(0, pState->pvUser);
     153        cchActual += pState->pfnOutput(!(pState->fFlags & STR_F_CAPITAL) ? 'x' : 'X', pState->pvUser);
     154    }
     155
     156    /*
     157     * Zero padding.
     158     */
     159    if (pState->fFlags & STR_F_ZEROPAD)
     160        while (cchRet < pState->cchWidth)
     161        {
     162            cchActual += pState->pfnOutput('0', pState->pvUser);
     163            cchRet++;
     164        }
     165
     166    /*
     167     * Output the number.
     168     */
     169    if (   !(pState->fFlags & STR_F_THOUSAND_SEP)
     170        || cchNumber < 4)
     171        while (cchNumber-- > 0)
     172            cchActual += pState->pfnOutput(*pszNumber++, pState->pvUser);
     173    else
     174    {
     175        char const      chSep    = pState->uBase == 10 ? ' ' : '\'';
     176        unsigned const  cchEvery = pState->uBase == 10 ? 3   : 8;
     177        unsigned        cchLeft  = --cchNumber % cchEvery;
     178
     179        cchActual += pState->pfnOutput(*pszNumber++, pState->pvUser);
     180        while (cchNumber-- > 0)
     181        {
     182            if (cchLeft == 0)
     183            {
     184                cchActual += pState->pfnOutput(chSep, pState->pvUser);
     185                cchLeft = cchEvery;
     186            }
     187            cchLeft--;
     188            cchActual += pState->pfnOutput(*pszNumber++, pState->pvUser);
     189        }
     190    }
     191
     192    /*
     193     * Do right blank padding.
     194     */
     195    if ((pState->fFlags & (STR_F_ZEROPAD | STR_F_LEFT | STR_F_WIDTH)) == (STR_F_WIDTH | STR_F_LEFT))
     196        while (cchRet < pState->cchWidth)
     197        {
     198            cchActual += pState->pfnOutput(' ', pState->pvUser);
     199            cchRet++;
     200        }
     201
     202    return cchActual;
    55203}
    56204
    57205
    58 static size_t bs3PrintFormatU64(char szTmp[64], uint64_t uValue, unsigned uBase, uint16_t fFlags, int cchWidth, int cchPrecision)
    59 {
    60 #if 0
    61     const char *pachDigits = !(fFlags & STR_F_CAPITAL) ? BS3_DATA_NM(g_achBs3HexDigits) : BS3_DATA_NM(g_achBs3HexDigitsUpper);
    62     char       *psz = &szTmp[64];
     206/**
     207 * Format a 64-bit number.
     208 *
     209 * @returns Number of characters.
     210 * @param   pState          The string formatter state.
     211 * @param   uValue          The value.
     212 */
     213static size_t bs3StrFormatU64(PBS3FMTSTATE pState, uint64_t uValue)
     214{
     215#if ARCH_BITS != 64
     216    /* Avoid 64-bit division by formatting 64-bit numbers as hex if they're higher than _4G. */
     217    if (   pState->uBase == 10
     218        && !(uValue >> 32)) /* uValue <= UINT32_MAX does not work, trouble with 64-bit compile time math! */
     219        return bs3StrFormatU32(pState, uValue);
     220    pState->fFlags |= STR_F_SPECIAL;
     221    pState->uBase = 16;
     222#endif
     223
     224    {
     225        const char *pachDigits = !(pState->fFlags & STR_F_CAPITAL)
     226                               ? BS3_DATA_NM(g_achBs3HexDigits) : BS3_DATA_NM(g_achBs3HexDigitsUpper);
     227        char       *psz = &pState->szTmp[BS3FMT_TMP_SIZE];
     228
     229        *--psz = '\0';
     230#if ARCH_BITS == 64
     231        if (pState->uBase == 10)
     232        {
     233            do
     234            {
     235                *--psz = pachDigits[uValue % 10];
     236                uValue /= 10;
     237            } while (uValue > 0);
     238        }
     239        else
     240#endif
     241        {
     242            BS3_ASSERT(pState->uBase == 16);
     243            do
     244            {
     245                *--psz = pachDigits[uValue & 0xf];
     246                uValue >>= 4;
     247            } while (uValue > 0);
     248        }
     249        return bs3StrFormatNumberString(pState, psz, &pState->szTmp[BS3FMT_TMP_SIZE - 1] - psz);
     250    }
     251}
     252
     253
     254/**
     255 * Format a 32-bit number.
     256 *
     257 * @returns Number of characters.
     258 * @param   pState          The string formatter state.
     259 * @param   uValue          The value.
     260 */
     261static size_t bs3StrFormatU32(PBS3FMTSTATE pState, uint32_t uValue)
     262{
     263#if ARCH_BITS < 64
     264    const char *pachDigits = !(pState->fFlags & STR_F_CAPITAL)
     265                           ? BS3_DATA_NM(g_achBs3HexDigits) : BS3_DATA_NM(g_achBs3HexDigitsUpper);
     266    char       *psz = &pState->szTmp[BS3FMT_TMP_SIZE];
    63267
    64268    *--psz = '\0';
    65     if (uBase == 10)
     269    if (pState->uBase == 10)
    66270    {
    67271        do
     
    73277    else
    74278    {
    75         unsigned const cShift = uBase == 8 ? 2 : 3;
    76         unsigned const fMask  = uBase == 8 ? 7 : 15;
     279        BS3_ASSERT(pState->uBase == 16);
    77280        do
    78281        {
    79             *--psz = pachDigits[uValue & fMask];
    80             uValue >>= cShift;
     282            *--psz = pachDigits[uValue & 0xf];
     283            uValue >>= 4;
    81284        } while (uValue > 0);
    82285    }
    83     return bs3PrintFormatString(psz, &szTmp[63] - psz, 0, 0, 0);
     286    return bs3StrFormatNumberString(pState, psz, &pState->szTmp[BS3FMT_TMP_SIZE - 1] - psz);
     287
    84288#else
    85     return 0;
     289    /* We've got native 64-bit division, save space. */
     290    return bs3StrFormatU64(pState, uValue);
    86291#endif
    87292}
    88293
    89 #if ARCH_BITS == 64
    90 # define bs3PrintFormatU32 bs3PrintFormatU64
    91 # define bs3PrintFormatU16 bs3PrintFormatU64
    92 
    93 #else
    94 static size_t bs3PrintFormatU32(char szTmp[64], uint32_t uValue, unsigned uBase, uint16_t fFlags, int cchWidth, int cchPrecision)
    95 {
    96     const char *pachDigits = !(fFlags & STR_F_CAPITAL) ? BS3_DATA_NM(g_achBs3HexDigits) : BS3_DATA_NM(g_achBs3HexDigitsUpper);
    97     char       *psz = &szTmp[64];
    98 
    99     *--psz = '\0';
    100     if (uBase == 10)
    101     {
     294
     295#if ARCH_BITS == 16
     296/**
     297 * Format a 16-bit number.
     298 *
     299 * @returns Number of characters.
     300 * @param   pState          The string formatter state.
     301 * @param   uValue          The value.
     302 */
     303static size_t bs3StrFormatU16(PBS3FMTSTATE pState, uint16_t uValue)
     304{
     305    if (pState->uBase == 10)
     306    {
     307        const char *pachDigits = !(pState->fFlags & STR_F_CAPITAL)
     308                               ? BS3_DATA_NM(g_achBs3HexDigits) : BS3_DATA_NM(g_achBs3HexDigitsUpper);
     309        char       *psz = &pState->szTmp[BS3FMT_TMP_SIZE];
     310
     311        *--psz = '\0';
    102312        do
    103313        {
     
    105315            uValue /= 10;
    106316        } while (uValue > 0);
    107     }
    108     else
    109     {
    110         unsigned const cShift = uBase == 8 ? 2 : 3;
    111         unsigned const fMask  = uBase == 8 ? 7 : 15;
    112         do
    113         {
    114             *--psz = pachDigits[uValue & fMask];
    115             uValue >>= cShift;
    116         } while (uValue > 0);
    117     }
    118     return bs3PrintFormatString(psz, &szTmp[63] - psz, 0, 0, 0);
     317        return bs3StrFormatNumberString(pState, psz, &pState->szTmp[BS3FMT_TMP_SIZE - 1] - psz);
     318    }
     319
     320    /*
     321     * 32-bit shifting is reasonably cheap and inlined, so combine with 32-bit.
     322     */
     323    return bs3StrFormatU32(pState, uValue);
    119324}
    120 
    121 # if ARCH_BITS == 16
    122 static size_t bs3PrintFormatU16(char szTmp[64], uint16_t uValue, unsigned uBase, uint16_t fFlags, int cchWidth, int cchPrecision)
    123 {
    124     if (uBase == 10)
    125     {
    126         const char *pachDigits = !(fFlags & STR_F_CAPITAL) ? BS3_DATA_NM(g_achBs3HexDigits) : BS3_DATA_NM(g_achBs3HexDigitsUpper);
    127         char       *psz = &szTmp[64];
    128 
    129         *--psz = '\0';
    130         do
    131         {
    132             *--psz = pachDigits[uValue % 10];
    133             uValue /= 10;
    134         } while (uValue > 0);
    135         return bs3PrintFormatString(psz, &szTmp[63] - psz, 0, 0, 0);
    136     }
    137     /* 32-bit shifting is reasonably cheap, so combine with 32-bit. */
    138     return bs3PrintFormatU32(szTmp, uValue, uBase, fFlags, cchWidth, cchPrecision);
     325#endif
     326
     327
     328static size_t bs3StrFormatS64(PBS3FMTSTATE pState, int32_t iValue)
     329{
     330    if (iValue < 0)
     331    {
     332        iValue = -iValue;
     333        pState->fFlags |= STR_F_NEGATIVE;
     334    }
     335    return bs3StrFormatU64(pState, iValue);
    139336}
    140 # endif /* 16-bit */
    141 #endif /* !64-bit */
    142 
    143 
    144 static size_t bs3PrintFormatS64(char szTmp[64], int16_t iValue, uint16_t fFlags, int cchWidth, int cchPrecision)
    145 {
    146     /** @todo this is kind of crude, full fleged formatting can wait.  */
    147     size_t cchRet = 0;
     337
     338
     339static size_t bs3StrFormatS32(PBS3FMTSTATE pState, int32_t iValue)
     340{
    148341    if (iValue < 0)
    149342    {
    150         Bs3PrintChr('-');
    151         cchRet++;
    152     }
    153     cchRet += bs3PrintFormatU64(szTmp, iValue, 10, fFlags & ~STR_F_VALSIGNED, cchWidth, cchPrecision);
    154     return cchRet;
     343        iValue = -iValue;
     344        pState->fFlags |= STR_F_NEGATIVE;
     345    }
     346    return bs3StrFormatU32(pState, iValue);
    155347}
    156348
    157349
    158 static size_t bs3PrintFormatS32(char szTmp[64], int16_t iValue, uint16_t fFlags, int cchWidth, int cchPrecision)
    159 {
    160     /** @todo this is kind of crude, full fleged formatting can wait.  */
    161     size_t cchRet = 0;
     350#if ARCH_BITS == 16
     351static size_t bs3StrFormatS16(PBS3FMTSTATE pState, int16_t iValue)
     352{
    162353    if (iValue < 0)
    163354    {
    164         Bs3PrintChr('-');
    165         cchRet++;
    166     }
    167     cchRet += bs3PrintFormatU32(szTmp, iValue, 10, fFlags & ~STR_F_VALSIGNED, cchWidth, cchPrecision);
    168     return cchRet;
     355        iValue = -iValue;
     356        pState->fFlags |= STR_F_NEGATIVE;
     357    }
     358    return bs3StrFormatU16(pState, iValue);
    169359}
    170 
    171 
    172 #if ARCH_BITS == 16
    173 static size_t bs3PrintFormatS16(char szTmp[64], int16_t iValue, uint16_t fFlags, int cchWidth, int cchPrecision)
    174 {
    175     /** @todo this is kind of crude, full fleged formatting can wait.  */
    176     size_t cchRet = 0;
    177     if (iValue < 0)
    178     {
    179         Bs3PrintChr('-');
    180         cchRet++;
    181     }
    182     cchRet += bs3PrintFormatU16(szTmp, iValue, 10, fFlags & ~STR_F_VALSIGNED, cchWidth, cchPrecision);
    183     return cchRet;
    184 }
    185 #endif
    186 
    187 
    188 
    189 
    190 
    191 BS3_DECL(size_t) Bs3PrintFV(const char BS3_FAR *pszFormat, va_list va)
    192 {
    193     size_t cchRet = 0;
    194     char ch;
     360#endif
     361
     362
     363BS3_DECL(size_t) Bs3StrFormatV(const char BS3_FAR *pszFormat, va_list va, PFNBS3STRFORMATOUTPUT pfnOutput, void *pvUser)
     364{
     365    BS3FMTSTATE State;
     366    size_t      cchRet = 0;
     367    char        ch;
     368
     369    State.pfnOutput = pfnOutput;
     370    State.pvUser    = pvUser;
     371
    195372    while ((ch = *pszFormat++) != '\0')
    196373    {
    197         unsigned int    fFlags;
    198         int             cchWidth;
    199         int             cchPrecision;
    200         char            chArgSize;
    201         char            szTmp[64];
     374        char        chArgSize;
    202375
    203376        /*
     
    206379        if (ch != '%')
    207380        {
    208             if (ch == '\n')
    209                 Bs3PrintChr('\r');
    210             Bs3PrintChr(ch);
    211             cchRet++;
     381            cchRet += State.pfnOutput(ch, State.pvUser);
    212382            continue;
    213383        }
     
    216386        if (ch == '%')
    217387        {
    218             Bs3PrintChr(ch);
    219             cchRet++;
     388            cchRet += State.pfnOutput(ch, State.pvUser);
    220389            continue;
    221390        }
     
    224393         * Flags.
    225394         */
    226         fFlags = 0;
     395        State.fFlags = 0;
    227396        for (;;)
    228397        {
     
    240409            if (!fThis)
    241410                break;
    242             fFlags |= fThis;
     411            State.fFlags |= fThis;
    243412            ch = *pszFormat++;
    244413        }
     
    247416         * Width.
    248417         */
    249         cchWidth = 0;
     418        State.cchWidth = 0;
    250419        if (RT_C_IS_DIGIT(ch))
    251420        {
    252421            do
    253422            {
    254                 cchWidth *= 10;
    255                 cchWidth  = ch - '0';
     423                State.cchWidth *= 10;
     424                State.cchWidth  = ch - '0';
    256425                ch = *pszFormat++;
    257426            } while (RT_C_IS_DIGIT(ch));
    258             fFlags |= STR_F_WIDTH;
     427            State.fFlags |= STR_F_WIDTH;
    259428        }
    260429        else if (ch == '*')
    261430        {
    262             cchWidth = va_arg(va, int);
    263             if (cchWidth < 0)
    264             {
    265                 cchWidth = -cchWidth;
    266                 fFlags |= STR_F_LEFT;
     431            State.cchWidth = va_arg(va, int);
     432            if (State.cchWidth < 0)
     433            {
     434                State.cchWidth = -State.cchWidth;
     435                State.fFlags |= STR_F_LEFT;
    267436            }
    268             fFlags |= STR_F_WIDTH;
     437            State.fFlags |= STR_F_WIDTH;
    269438        }
    270439
     
    272441         * Precision
    273442         */
    274         cchPrecision = 0;
     443        State.cchPrecision = 0;
    275444        if (RT_C_IS_DIGIT(ch))
    276445        {
    277446            do
    278447            {
    279                 cchPrecision *= 10;
    280                 cchPrecision  = ch - '0';
     448                State.cchPrecision *= 10;
     449                State.cchPrecision  = ch - '0';
    281450                ch = *pszFormat++;
    282451            } while (RT_C_IS_DIGIT(ch));
    283             fFlags |= STR_F_PRECISION;
     452            State.fFlags |= STR_F_PRECISION;
    284453        }
    285454        else if (ch == '*')
    286455        {
    287             cchPrecision = va_arg(va, int);
    288             if (cchPrecision < 0)
    289                 cchPrecision = 0;
    290             fFlags |= STR_F_PRECISION;
     456            State.cchPrecision = va_arg(va, int);
     457            if (State.cchPrecision < 0)
     458                State.cchPrecision = 0;
     459            State.fFlags |= STR_F_PRECISION;
    291460        }
    292461
     
    336505             */
    337506            case 'c':
    338                 szTmp[0] = va_arg(va, int /*char*/);
    339                 szTmp[1] = '\0';
    340                 cchRet += bs3PrintFormatString(szTmp, 1, fFlags, cchWidth, cchPrecision);
    341                 break;
     507            {
     508                char ch = va_arg(va, int /*char*/);
     509                cchRet += State.pfnOutput(ch, State.pvUser);
     510                break;
     511            }
    342512
    343513            /*
     
    347517            {
    348518                const char BS3_FAR *psz = va_arg(va, const char BS3_FAR *);
    349                 if (psz == NULL)
     519                size_t              cch;
     520                if (psz != NULL)
     521                    cch = Bs3StrNLen(psz, State.fFlags & STR_F_PRECISION ? RT_ABS(State.cchPrecision) : ~(size_t)0);
     522                else
     523                {
    350524                    psz = "<NULL>";
    351                 cchRet += bs3PrintFormatString(psz, ~(size_t)0, fFlags, cchWidth, cchPrecision);
     525                    cch = 6;
     526                }
     527
     528                if ((State.fFlags & (STR_F_LEFT | STR_F_WIDTH)) == STR_F_WIDTH)
     529                    while (--State.cchWidth >= cch)
     530                        cchRet += State.pfnOutput(' ', State.pvUser);
     531
     532                cchRet += cch;
     533                while (cch-- > 0)
     534                    cchRet += State.pfnOutput(*psz++, State.pvUser);
     535
     536                if ((State.fFlags & (STR_F_LEFT | STR_F_WIDTH)) == (STR_F_LEFT | STR_F_WIDTH))
     537                    while (--State.cchWidth >= cch)
     538                        cchRet += State.pfnOutput(' ', State.pvUser);
    352539                break;
    353540            }
     
    358545            case 'i':
    359546            case 'd':
    360                 fFlags |= STR_F_VALSIGNED;
     547                State.fFlags &= ~STR_F_SPECIAL;
     548                State.fFlags |= STR_F_VALSIGNED;
     549                State.uBase   = 10;
    361550                switch (chArgSize)
    362551                {
     
    367556                        signed int iValue = va_arg(va, signed int);
    368557#if ARCH_BITS == 16
    369                         cchRet += bs3PrintFormatS16(szTmp, iValue, fFlags, cchWidth, cchPrecision);
     558                        cchRet += bs3StrFormatS16(&State, iValue);
    370559#else
    371                         cchRet += bs3PrintFormatS32(szTmp, iValue, fFlags, cchWidth, cchPrecision);
     560                        cchRet += bs3StrFormatS32(&State, iValue);
    372561#endif
    373562                        break;
     
    377566                        signed long lValue = va_arg(va, signed long);
    378567                        if (sizeof(lValue) == 4)
    379                             cchRet += bs3PrintFormatS32(szTmp, lValue, fFlags, cchWidth, cchPrecision);
     568                            cchRet += bs3StrFormatS32(&State, lValue);
    380569                        else
    381                             cchRet += bs3PrintFormatS64(szTmp, lValue, fFlags, cchWidth, cchPrecision);
     570                            cchRet += bs3StrFormatS64(&State, lValue);
    382571                        break;
    383572                    }
     
    385574                    {
    386575                        unsigned long long ullValue = va_arg(va, unsigned long long);
    387                         cchRet += bs3PrintFormatS64(szTmp, ullValue, fFlags, cchWidth, cchPrecision);
     576                        cchRet += bs3StrFormatS64(&State, ullValue);
    388577                        break;
    389578                    }
     
    395584             */
    396585            case 'X':
    397                 fFlags |= STR_F_CAPITAL;
     586                State.fFlags |= STR_F_CAPITAL;
    398587            case 'x':
    399588            case 'u':
    400589            {
    401                 unsigned uBase = ch = 'u' ? 10 : 16;
     590                if (ch == 'u')
     591                {
     592                    State.uBase   = 10;
     593                    State.fFlags &= ~(STR_F_PLUS | STR_F_BLANK | STR_F_SPECIAL);
     594                }
     595                else
     596                {
     597                    State.uBase   = 16;
     598                    State.fFlags &= ~(STR_F_PLUS | STR_F_BLANK);
     599                }
    402600                switch (chArgSize)
    403601                {
     
    408606                        unsigned int uValue = va_arg(va, unsigned int);
    409607#if ARCH_BITS == 16
    410                         cchRet += bs3PrintFormatU16(szTmp, uValue, uBase, fFlags, cchWidth, cchPrecision);
     608                        cchRet += bs3StrFormatU16(&State, uValue);
    411609#else
    412                         cchRet += bs3PrintFormatU32(szTmp, uValue, uBase, fFlags, cchWidth, cchPrecision);
     610                        cchRet += bs3StrFormatU32(&State, uValue);
    413611#endif
    414612                        break;
     
    418616                        unsigned long ulValue = va_arg(va, unsigned long);
    419617                        if (sizeof(ulValue) == 4)
    420                             cchRet += bs3PrintFormatU32(szTmp, ulValue, uBase, fFlags, cchWidth, cchPrecision);
     618                            cchRet += bs3StrFormatU32(&State, ulValue);
    421619                        else
    422                             cchRet += bs3PrintFormatU64(szTmp, ulValue, uBase, fFlags, cchWidth, cchPrecision);
     620                            cchRet += bs3StrFormatU64(&State, ulValue);
    423621                        break;
    424622                    }
     
    426624                    {
    427625                        unsigned long long ullValue = va_arg(va, unsigned long long);
    428                         cchRet += bs3PrintFormatU64(szTmp, ullValue, uBase, fFlags, cchWidth, cchPrecision);
     626                        cchRet += bs3StrFormatU64(&State, ullValue);
    429627                        break;
    430628                    }
     
    438636            case 'R':
    439637            {
    440                 unsigned uBase;
    441638                ch = *pszFormat++;
    442639                switch (ch)
    443640                {
    444641                    case 'I':
    445                         fFlags |= STR_F_VALSIGNED;
    446                         /* fall thru */
     642                        State.fFlags |= STR_F_VALSIGNED;
     643                        State.uBase  &= ~STR_F_SPECIAL;
     644                        State.uBase   = 10;
     645                        break;
    447646                    case 'U':
    448                         uBase = 10;
     647                        State.fFlags &= ~(STR_F_PLUS | STR_F_BLANK | STR_F_SPECIAL);
     648                        State.uBase   = 10;
    449649                        break;
    450650                    case 'X':
    451                         uBase = 16;
     651                        State.fFlags &= ~(STR_F_PLUS | STR_F_BLANK);
     652                        State.uBase   = 16;
    452653                        break;
    453654                    default:
    454                         uBase = 0;
    455                         break;
    456                 }
    457                 if (uBase)
     655                        State.uBase  = 0;
     656                        break;
     657                }
     658                if (State.uBase)
    458659                {
    459660                    ch = *pszFormat++;
     
    473674                            unsigned int uValue = va_arg(va, unsigned int);
    474675#if ARCH_BITS == 16
    475                             cchRet += bs3PrintFormatU16(szTmp, uValue, uBase, fFlags, cchWidth, cchPrecision);
     676                            cchRet += bs3StrFormatU16(&State, uValue);
    476677#else
    477                             cchRet += bs3PrintFormatU32(szTmp, uValue, uBase, fFlags, cchWidth, cchPrecision);
     678                            cchRet += bs3StrFormatU32(&State, uValue);
    478679#endif
    479680                            break;
     
    484685                            uint32_t uValue = va_arg(va, uint32_t);
    485686                            pszFormat++;
    486                             cchRet += bs3PrintFormatU32(szTmp, uValue, uBase, fFlags, cchWidth, cchPrecision);
     687                            cchRet += bs3StrFormatU32(&State, uValue);
    487688                            break;
    488689                        }
     
    492693                            uint64_t uValue = va_arg(va, uint64_t);
    493694                            pszFormat++;
    494                             cchRet += bs3PrintFormatU64(szTmp, uValue, uBase, fFlags, cchWidth, cchPrecision);
     695                            cchRet += bs3StrFormatU64(&State, uValue);
    495696                            break;
    496697                        }
     
    504705             */
    505706            case 'P':
    506                 fFlags |= STR_F_CAPITAL;
     707                State.fFlags |= STR_F_CAPITAL;
    507708                /* fall thru */
    508709            case 'p':
    509710            {
    510711                void BS3_FAR *pv = va_arg(va, void BS3_FAR *);
     712                State.uBase   = 16;
     713                State.fFlags &= ~(STR_F_PLUS | STR_F_BLANK);
    511714#if ARCH_BITS == 16
    512                 cchRet += bs3PrintFormatU16(szTmp, BS3_FP_SEG(pv), 16, fFlags, fFlags & STR_F_SPECIAL ? 6 : 4, 0);
    513                 Bs3PrintChr(':');
    514                 cchRet += 1;
    515                 cchRet += bs3PrintFormatU16(szTmp, BS3_FP_OFF(pv), 16, fFlags & ~STR_F_SPECIAL, 4, 0);
     715                State.fFlags |= STR_F_ZEROPAD;
     716                State.cchWidth = State.fFlags & STR_F_SPECIAL ? 6: 4;
     717                cchRet += bs3StrFormatU16(&State, BS3_FP_SEG(pv));
     718                cchRet += State.pfnOutput(':', State.pvUser);
     719                cchRet += bs3StrFormatU16(&State, BS3_FP_OFF(pv));
    516720#elif ARCH_BITS == 32
    517                 cchRet += bs3PrintFormatU32(szTmp, (uintptr_t)pv, 16, fFlags | STR_F_SPECIAL, 10, 0);
     721                State.fFlags |= STR_F_SPECIAL | STR_F_ZEROPAD;
     722                State.cchWidth = 10;
     723                cchRet += bs3StrFormatU32(&State, (uintptr_t)pv);
    518724#elif ARCH_BITS == 64
    519                 cchRet += bs3PrintFormatU64(szTmp, (uintptr_t)pv, 16, fFlags | STR_F_SPECIAL | STR_F_THOUSAND_SEP, 19, 0);
     725                State.fFlags |= STR_F_SPECIAL | STR_F_ZEROPAD | STR_F_THOUSAND_SEP;
     726                State.cchWidth = 19;
     727                cchRet += bs3StrFormatU64(&State, (uintptr_t)pv);
    520728#else
    521729# error "Undefined or invalid ARCH_BITS."
     
    526734        }
    527735    }
     736
     737    /*
     738     * Termination call.
     739     */
     740    cchRet += State.pfnOutput(0, State.pvUser);
     741
    528742    return cchRet;
    529743}
    530744
    531 
    532 BS3_DECL(size_t) Bs3PrintF(const char BS3_FAR *pszFormat, ...)
    533 {
    534     size_t cchRet;
    535     va_list va;
    536     va_start(va, pszFormat);
    537     cchRet = Bs3PrintFV(pszFormat, va);
    538     va_end(va);
    539     return cchRet;
    540 }
    541 
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-first-rm.asm

    r58799 r58809  
    141141extern BS3_CMN_NM(Bs3Shutdown)
    142142extern NAME(Main_rm)
    143 extern _Bs3PrintF_c32
    144143
    145144BS3_BEGIN_SYSTEM16
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-shutdown.c

    r58799 r58809  
    2323Bs3PrintStr("\r\n");
    2424
    25 Bs3PrintF("Bs3PrintF: RX32=%RX32\n", UINT32_C(0xfdb97531));
     25Bs3Printf("Bs3Printf: RX32=%#'RX32 string='%s' d=%d p=%p\n", UINT32_C(0xfdb97531), "my string", 42, Main_rm);
    2626
    2727pvTmp2 = Bs3MemAlloc(BS3MEMKIND_REAL, _4K);
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3kit.h

    r58799 r58809  
    937937
    938938/**
    939  * Converts a 64-bit unsigned integer to a string.
    940  *
    941  * @returns The length for the formatted string.
    942  * @param   pszDst      The destination buffer.  Caller is responsible for
    943  *                      ensuring sufficient space.
    944  * @param   uValue      The 64-bit value.
    945  * @param   uBase       The base to format the number in: 2, 8,10 or 16.
    946  */
    947 BS3_DECL(size_t) Bs3FormatU64_c16(char BS3_FAR *pszDst, uint64_t uValue, unsigned uBase);
    948 BS3_DECL(size_t) Bs3FormatU64_c32(char BS3_FAR *pszDst, uint64_t uValue, unsigned uBase); /**< @copydoc Bs3FormatU64_c16 */
    949 BS3_DECL(size_t) Bs3FormatU64_c64(char BS3_FAR *pszDst, uint64_t uValue, unsigned uBase); /**< @copydoc Bs3FormatU64_c16 */
    950 #define Bs3FormatU64 BS3_CMN_NM(Bs3FormatU64) /**< Selects #Bs3FormatU64_c16, #Bs3FormatU64_c32 or #Bs3FormatU64_c64. */
    951 
    952 /**
    953939 * Formats and prints a string to the screen.
    954940 *
    955  * @param   pszFormat       The format string.  See #Bs3PrintFV for supported
    956  *                          format types and flags.
     941 * See #Bs3StrFormatV_c16 for supported format types.
     942 *
     943 * @param   pszFormat       The format string.
    957944 * @param   ...             Format arguments.
    958945 */
    959 BS3_DECL(size_t) Bs3PrintF_c16(const char BS3_FAR *pszFormat, ...);
    960 BS3_DECL(size_t) Bs3PrintF_c32(const char BS3_FAR *pszFormat, ...); /**< @copydoc Bs3PrintF_c16 */
    961 BS3_DECL(size_t) Bs3PrintF_c64(const char BS3_FAR *pszFormat, ...); /**< @copydoc Bs3PrintF_c16 */
    962 #define Bs3PrintF BS3_CMN_NM(Bs3PrintF) /**< Selects #Bs3PrintF_c16, #Bs3PrintF_c32 or #Bs3PrintF_c64. */
     946BS3_DECL(size_t) Bs3Printf_c16(const char BS3_FAR *pszFormat, ...);
     947BS3_DECL(size_t) Bs3Printf_c32(const char BS3_FAR *pszFormat, ...); /**< @copydoc Bs3Printf_c16 */
     948BS3_DECL(size_t) Bs3Printf_c64(const char BS3_FAR *pszFormat, ...); /**< @copydoc Bs3Printf_c16 */
     949#define Bs3Printf BS3_CMN_NM(Bs3Printf) /**< Selects #Bs3Printf_c16, #Bs3Printf_c32 or #Bs3Printf_c64. */
    963950
    964951/**
    965952 * Formats and prints a string to the screen, va_list version.
     953 *
     954 * See #Bs3Format_c16 for supported format types.
     955 *
     956 * @param   pszFormat       The format string.
     957 * @param   va              Format arguments.
     958 */
     959BS3_DECL(size_t) Bs3PrintfV_c16(const char BS3_FAR *pszFormat, va_list va);
     960BS3_DECL(size_t) Bs3PrintfV_c32(const char BS3_FAR *pszFormat, va_list va); /**< @copydoc Bs3PrintfV_c16 */
     961BS3_DECL(size_t) Bs3PrintfV_c64(const char BS3_FAR *pszFormat, va_list va); /**< @copydoc Bs3PrintfV_c16 */
     962#define Bs3PrintfV BS3_CMN_NM(Bs3PrintfV) /**< Selects #Bs3PrintfV_c16, #Bs3PrintfV_c32 or #Bs3PrintfV_c64. */
     963
     964/**
     965 * Prints a string to the screen.
     966 *
     967 * @param   pszString       The string to print.
     968 */
     969BS3_DECL(void) Bs3PrintStr_c16(const char BS3_FAR *pszString);
     970BS3_DECL(void) Bs3PrintStr_c32(const char BS3_FAR *pszString); /**< @copydoc Bs3PrintStr_c16 */
     971BS3_DECL(void) Bs3PrintStr_c64(const char BS3_FAR *pszString); /**< @copydoc Bs3PrintStr_c16 */
     972#define Bs3PrintStr BS3_CMN_NM(Bs3PrintStr) /**< Selects #Bs3PrintStr_c16, #Bs3PrintStr_c32 or #Bs3PrintStr_c64. */
     973
     974/**
     975 * Prints a char to the screen.
     976 *
     977 * @param   ch              The character to print.
     978 */
     979BS3_DECL(void) Bs3PrintChr_c16(char ch);
     980BS3_DECL(void) Bs3PrintChr_c32(char ch); /**< @copydoc Bs3PrintChr_c16 */
     981BS3_DECL(void) Bs3PrintChr_c64(char ch); /**< @copydoc Bs3PrintChr_c16 */
     982#define Bs3PrintChr BS3_CMN_NM(Bs3PrintChr) /**< Selects #Bs3PrintChr_c16, #Bs3PrintChr_c32 or #Bs3PrintChr_c64. */
     983
     984
     985/**
     986 * Pointer to a #Bs3StrFormatV output function.
     987 *
     988 * @returns Number of characters written.
     989 * @param   ch      The character to write. Zero in the final call.
     990 * @param   pvUser  User argument supplied to #Bs3StrFormatV.
     991 */
     992typedef size_t (BS3_CALL *PFNBS3STRFORMATOUTPUT)(char ch, void *pvUser);
     993
     994/**
     995 * Formats a string, sending the output to @a pfnOutput.
    966996 *
    967997 * Supported types:
     
    9761006 *      - %s (far pointer)
    9771007 *
    978  * @param   pszFormat       The format string.  See #Bs3PrintFV for supported
    979  *                          format types and flags.
    980  * @param   va              Format arguments.
    981  */
    982 BS3_DECL(size_t) Bs3PrintFV_c16(const char BS3_FAR *pszFormat, va_list va);
    983 BS3_DECL(size_t) Bs3PrintFV_c32(const char BS3_FAR *pszFormat, va_list va); /**< @copydoc Bs3PrintFV_c16 */
    984 BS3_DECL(size_t) Bs3PrintFV_c64(const char BS3_FAR *pszFormat, va_list va); /**< @copydoc Bs3PrintFV_c16 */
    985 #define Bs3PrintFV BS3_CMN_NM(Bs3PrintFV) /**< Selects #Bs3PrintFV_c16, #Bs3PrintFV_c32 or #Bs3PrintFV_c64. */
    986 
    987 /**
    988  * Prints a string to the screen.
    989  *
    990  * @param   pszString       The string to print.
    991  */
    992 BS3_DECL(void) Bs3PrintStr_c16(const char BS3_FAR *pszString);
    993 BS3_DECL(void) Bs3PrintStr_c32(const char BS3_FAR *pszString); /**< @copydoc Bs3PrintStr_c16 */
    994 BS3_DECL(void) Bs3PrintStr_c64(const char BS3_FAR *pszString); /**< @copydoc Bs3PrintStr_c16 */
    995 #define Bs3PrintStr BS3_CMN_NM(Bs3PrintStr) /**< Selects #Bs3PrintStr_c16, #Bs3PrintStr_c32 or #Bs3PrintStr_c64. */
    996 
    997 /**
    998  * Prints a char to the screen.
    999  *
    1000  * @param   ch              The character to print.
    1001  */
    1002 BS3_DECL(void) Bs3PrintChr_c16(char ch);
    1003 BS3_DECL(void) Bs3PrintChr_c32(char ch); /**< @copydoc Bs3PrintChr_c16 */
    1004 BS3_DECL(void) Bs3PrintChr_c64(char ch); /**< @copydoc Bs3PrintChr_c16 */
    1005 #define Bs3PrintChr BS3_CMN_NM(Bs3PrintChr) /**< Selects #Bs3PrintChr_c16, #Bs3PrintChr_c32 or #Bs3PrintChr_c64. */
     1008 * @returns Sum of @a pfnOutput return values.
     1009 * @param   pszFormat   The format string.
     1010 * @param   va          Format arguments.
     1011 * @param   pfnOutput   The output function.
     1012 * @param   pvUser      The user argument for the output function.
     1013 */
     1014BS3_DECL(size_t) Bs3StrFormatV_c16(const char BS3_FAR *pszFormat, va_list va, PFNBS3STRFORMATOUTPUT pfnOutput, void *pvUser);
     1015/** @copydoc Bs3StrFormatV_c16  */
     1016BS3_DECL(size_t) Bs3StrFormatV_c32(const char BS3_FAR *pszFormat, va_list va, PFNBS3STRFORMATOUTPUT pfnOutput, void *pvUser);
     1017/** @copydoc Bs3StrFormatV_c16  */
     1018BS3_DECL(size_t) Bs3StrFormatV_c64(const char BS3_FAR *pszFormat, va_list va, PFNBS3STRFORMATOUTPUT pfnOutput, void *pvUser);
     1019#define Bs3StrFormatV BS3_CMN_NM(Bs3StrFormatV) /**< Selects #Bs3StrFormatV_c16, #Bs3StrFormatV_c32 or #Bs3StrFormatV_c64. */
     1020
     1021/**
     1022 * Formats a string into a buffer.
     1023 *
     1024 * See #Bs3Format_c16 for supported format types.
     1025 *
     1026 * @returns The length of the formatted string (excluding terminator).
     1027 *          This will be higher or equal to @c cbBuf in case of an overflow.
     1028 * @param   pszBuf      The output buffer.
     1029 * @param   cbBuf       The size of the output buffer.
     1030 * @param   pszFormat   The format string.
     1031 * @param   va          Format arguments.
     1032 */
     1033BS3_DECL(size_t) Bs3StrPrintfV_c16(char BS3_FAR *pszBuf, size_t cbBuf, const char BS3_FAR *pszFormat, va_list va);
     1034/** @copydoc Bs3StrPrintfV_c16  */
     1035BS3_DECL(size_t) Bs3StrPrintfV_c32(char BS3_FAR *pszBuf, size_t cbBuf, const char BS3_FAR *pszFormat, va_list va);
     1036/** @copydoc Bs3StrPrintfV_c16  */
     1037BS3_DECL(size_t) Bs3StrPrintfV_c64(char BS3_FAR *pszBuf, size_t cbBuf, const char BS3_FAR *pszFormat, va_list va);
     1038#define Bs3StrPrintfV BS3_CMN_NM(Bs3StrPrintfV) /**< Selects #Bs3StrPrintfV_c16, #Bs3StrPrintfV_c32 or #Bs3StrPrintfV_c64. */
     1039
     1040/**
     1041 * Formats a string into a buffer.
     1042 *
     1043 * See #Bs3Format_c16 for supported format types.
     1044 *
     1045 * @returns The length of the formatted string (excluding terminator).
     1046 *          This will be higher or equal to @c cbBuf in case of an overflow.
     1047 * @param   pszBuf      The output buffer.
     1048 * @param   cbBuf       The size of the output buffer.
     1049 * @param   pszFormat   The format string.
     1050 * @param   ...         Format arguments.
     1051 */
     1052BS3_DECL(size_t) Bs3StrPrintf_c16(char BS3_FAR *pszBuf, size_t cbBuf, const char BS3_FAR *pszFormat, ...);
     1053/** @copydoc Bs3StrPrintf_c16  */
     1054BS3_DECL(size_t) Bs3StrPrintf_c32(char BS3_FAR *pszBuf, size_t cbBuf, const char BS3_FAR *pszFormat, ...);
     1055/** @copydoc Bs3StrPrintf_c16  */
     1056BS3_DECL(size_t) Bs3StrPrintf_c64(char BS3_FAR *pszBuf, size_t cbBuf, const char BS3_FAR *pszFormat, ...);
     1057#define Bs3StrPrintf BS3_CMN_NM(Bs3StrPrintf) /**< Selects #Bs3StrPrintf_c16, #Bs3StrPrintf_c32 or #Bs3StrPrintf_c64. */
    10061058
    10071059
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette