VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-StrFormatV.c@ 106215

Last change on this file since 106215 was 106061, checked in by vboxsync, 3 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.7 KB
Line 
1/* $Id: bs3-cmn-StrFormatV.c 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * BS3Kit - Bs3StrFormatV
4 */
5
6/*
7 * Copyright (C) 2007-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37
38/*********************************************************************************************************************************
39* Header Files *
40*********************************************************************************************************************************/
41#include "bs3kit-template-header.h"
42#include <iprt/ctype.h>
43
44
45/*********************************************************************************************************************************
46* Defined Constants And Macros *
47*********************************************************************************************************************************/
48#define STR_F_CAPITAL 0x0001
49#define STR_F_LEFT 0x0002
50#define STR_F_ZEROPAD 0x0004
51#define STR_F_SPECIAL 0x0008
52#define STR_F_VALSIGNED 0x0010
53#define STR_F_PLUS 0x0020
54#define STR_F_BLANK 0x0040
55#define STR_F_WIDTH 0x0080
56#define STR_F_PRECISION 0x0100
57#define STR_F_THOUSAND_SEP 0x0200
58#define STR_F_NEGATIVE 0x0400 /**< Used to indicated '-' must be printed. */
59
60
61/*********************************************************************************************************************************
62* Structures and Typedefs *
63*********************************************************************************************************************************/
64/** Size of the temporary buffer. */
65#define BS3FMT_TMP_SIZE 64
66
67/**
68 * BS3kit string format state.
69 */
70typedef struct BS3FMTSTATE
71{
72 /** The output function. */
73 PFNBS3STRFORMATOUTPUT pfnOutput;
74 /** User argument for pfnOutput. */
75 void BS3_FAR *pvUser;
76
77 /** STR_F_XXX flags. */
78 unsigned fFlags;
79 /** The width when STR_F_WIDTH is specific. */
80 int cchWidth;
81 /** The width when STR_F_PRECISION is specific. */
82 int cchPrecision;
83 /** The number format base. */
84 unsigned uBase;
85 /** Temporary buffer. */
86 char szTmp[BS3FMT_TMP_SIZE];
87} BS3FMTSTATE;
88/** Pointer to a BS3Kit string formatter state. */
89typedef BS3FMTSTATE BS3_FAR *PBS3FMTSTATE;
90
91
92
93/*********************************************************************************************************************************
94* Internal Functions *
95*********************************************************************************************************************************/
96#if ARCH_BITS != 64
97static size_t bs3StrFormatU32(PBS3FMTSTATE pState, uint32_t uValue);
98#endif
99
100
101
102/**
103 * Formats a number string.
104 *
105 * @returns Number of chars printed.
106 * @param pState The string formatter state.
107 * @param pszNumber The formatted number string.
108 * @param cchNumber The length of the number.
109 */
110static size_t bs3StrFormatNumberString(PBS3FMTSTATE pState, char const BS3_FAR *pszNumber, size_t cchNumber)
111{
112 /*
113 * Calc the length of the core number with prefixes.
114 */
115 size_t cchActual = 0;
116 size_t cchRet = cchNumber;
117
118 /* Accunt for sign char. */
119 cchRet += !!(pState->fFlags & (STR_F_NEGATIVE | STR_F_PLUS | STR_F_BLANK));
120
121 /* Account for the hex prefix: '0x' or '0X' */
122 if (pState->fFlags & STR_F_SPECIAL)
123 {
124 cchRet += 2;
125 BS3_ASSERT(pState->uBase == 16);
126 }
127
128 /* Account for thousand separators (applied while printing). */
129 if (pState->fFlags & STR_F_THOUSAND_SEP)
130 cchRet += (cchNumber - 1) / (pState->uBase == 10 ? 3 : 8);
131
132 /*
133 * Do left blank padding.
134 */
135 if ((pState->fFlags & (STR_F_ZEROPAD | STR_F_LEFT | STR_F_WIDTH)) == STR_F_WIDTH)
136 while (cchRet < pState->cchWidth)
137 {
138 cchActual += pState->pfnOutput(' ', pState->pvUser);
139 cchRet++;
140 }
141
142 /*
143 * Sign indicator / space.
144 */
145 if (pState->fFlags & (STR_F_NEGATIVE | STR_F_PLUS | STR_F_BLANK))
146 {
147 char ch;
148 if (pState->fFlags & STR_F_NEGATIVE)
149 ch = '-';
150 else if (pState->fFlags & STR_F_PLUS)
151 ch = '+';
152 else
153 ch = ' ';
154 cchActual += pState->pfnOutput(ch, pState->pvUser);
155 }
156
157 /*
158 * Hex prefix.
159 */
160 if (pState->fFlags & STR_F_SPECIAL)
161 {
162 cchActual += pState->pfnOutput('0', pState->pvUser);
163 cchActual += pState->pfnOutput(!(pState->fFlags & STR_F_CAPITAL) ? 'x' : 'X', pState->pvUser);
164 }
165
166 /*
167 * Zero padding.
168 */
169 if (pState->fFlags & STR_F_ZEROPAD)
170 while (cchRet < pState->cchWidth)
171 {
172 cchActual += pState->pfnOutput('0', pState->pvUser);
173 cchRet++;
174 }
175
176 /*
177 * Output the number.
178 */
179 if ( !(pState->fFlags & STR_F_THOUSAND_SEP)
180 || cchNumber < 4)
181 while (cchNumber-- > 0)
182 cchActual += pState->pfnOutput(*pszNumber++, pState->pvUser);
183 else
184 {
185 char const chSep = pState->uBase == 10 ? ' ' : '\'';
186 unsigned const cchEvery = pState->uBase == 10 ? 3 : 8;
187 unsigned cchLeft = --cchNumber % cchEvery;
188
189 cchActual += pState->pfnOutput(*pszNumber++, pState->pvUser);
190 while (cchNumber-- > 0)
191 {
192 if (cchLeft == 0)
193 {
194 cchActual += pState->pfnOutput(chSep, pState->pvUser);
195 cchLeft = cchEvery;
196 }
197 cchLeft--;
198 cchActual += pState->pfnOutput(*pszNumber++, pState->pvUser);
199 }
200 }
201
202 /*
203 * Do right blank padding.
204 */
205 if ((pState->fFlags & (STR_F_ZEROPAD | STR_F_LEFT | STR_F_WIDTH)) == (STR_F_WIDTH | STR_F_LEFT))
206 while (cchRet < pState->cchWidth)
207 {
208 cchActual += pState->pfnOutput(' ', pState->pvUser);
209 cchRet++;
210 }
211
212 return cchActual;
213}
214
215
216/**
217 * Format a 64-bit number.
218 *
219 * @returns Number of characters.
220 * @param pState The string formatter state.
221 * @param uValue The value.
222 */
223static size_t bs3StrFormatU64(PBS3FMTSTATE pState, uint64_t uValue)
224{
225#if ARCH_BITS != 64
226 /* Avoid 64-bit division by formatting 64-bit numbers as hex if they're higher than _4G. */
227 if (pState->uBase == 10)
228 {
229 if (!(uValue >> 32)) /* uValue <= UINT32_MAX does not work, trouble with 64-bit compile time math! */
230 return bs3StrFormatU32(pState, uValue);
231 pState->fFlags |= STR_F_SPECIAL;
232 pState->uBase = 16;
233 }
234#endif
235
236 {
237 const char BS3_FAR *pachDigits = !(pState->fFlags & STR_F_CAPITAL) ? g_achBs3HexDigits : g_achBs3HexDigitsUpper;
238 char BS3_FAR *psz = &pState->szTmp[BS3FMT_TMP_SIZE];
239
240 *--psz = '\0';
241#if ARCH_BITS == 64
242 if (pState->uBase == 10)
243 {
244 do
245 {
246 *--psz = pachDigits[uValue % 10];
247 uValue /= 10;
248 } while (uValue > 0);
249 }
250 else
251#endif
252 {
253 BS3_ASSERT(pState->uBase == 16);
254 do
255 {
256 *--psz = pachDigits[uValue & 0xf];
257 uValue >>= 4;
258 } while (uValue > 0);
259 }
260 return bs3StrFormatNumberString(pState, psz, &pState->szTmp[BS3FMT_TMP_SIZE - 1] - psz);
261 }
262}
263
264
265/**
266 * Format a 32-bit number.
267 *
268 * @returns Number of characters.
269 * @param pState The string formatter state.
270 * @param uValue The value.
271 */
272static size_t bs3StrFormatU32(PBS3FMTSTATE pState, uint32_t uValue)
273{
274#if ARCH_BITS < 64
275 const char BS3_FAR *pachDigits = !(pState->fFlags & STR_F_CAPITAL) ? g_achBs3HexDigits : g_achBs3HexDigitsUpper;
276 char BS3_FAR *psz = &pState->szTmp[BS3FMT_TMP_SIZE];
277
278 *--psz = '\0';
279 if (pState->uBase == 10)
280 {
281 do
282 {
283 *--psz = pachDigits[uValue % 10];
284 uValue /= 10;
285 } while (uValue > 0);
286 }
287 else
288 {
289 BS3_ASSERT(pState->uBase == 16);
290 do
291 {
292 *--psz = pachDigits[uValue & 0xf];
293 uValue >>= 4;
294 } while (uValue > 0);
295 }
296 return bs3StrFormatNumberString(pState, psz, &pState->szTmp[BS3FMT_TMP_SIZE - 1] - psz);
297
298#else
299 /* We've got native 64-bit division, save space. */
300 return bs3StrFormatU64(pState, uValue);
301#endif
302}
303
304
305#if ARCH_BITS == 16
306/**
307 * Format a 16-bit number.
308 *
309 * @returns Number of characters.
310 * @param pState The string formatter state.
311 * @param uValue The value.
312 */
313static size_t bs3StrFormatU16(PBS3FMTSTATE pState, uint16_t uValue)
314{
315 if (pState->uBase == 10)
316 {
317 const char BS3_FAR *pachDigits = !(pState->fFlags & STR_F_CAPITAL)
318 ? g_achBs3HexDigits : g_achBs3HexDigitsUpper;
319 char BS3_FAR *psz = &pState->szTmp[BS3FMT_TMP_SIZE];
320
321 *--psz = '\0';
322 do
323 {
324 *--psz = pachDigits[uValue % 10];
325 uValue /= 10;
326 } while (uValue > 0);
327 return bs3StrFormatNumberString(pState, psz, &pState->szTmp[BS3FMT_TMP_SIZE - 1] - psz);
328 }
329
330 /*
331 * 32-bit shifting is reasonably cheap and inlined, so combine with 32-bit.
332 */
333 return bs3StrFormatU32(pState, uValue);
334}
335#endif
336
337
338static size_t bs3StrFormatS64(PBS3FMTSTATE pState, int32_t iValue)
339{
340 if (iValue < 0)
341 {
342 iValue = -iValue;
343 pState->fFlags |= STR_F_NEGATIVE;
344 }
345 return bs3StrFormatU64(pState, iValue);
346}
347
348
349static size_t bs3StrFormatS32(PBS3FMTSTATE pState, int32_t iValue)
350{
351 if (iValue < 0)
352 {
353 iValue = -iValue;
354 pState->fFlags |= STR_F_NEGATIVE;
355 }
356 return bs3StrFormatU32(pState, iValue);
357}
358
359
360#if ARCH_BITS == 16
361static size_t bs3StrFormatS16(PBS3FMTSTATE pState, int16_t iValue)
362{
363 if (iValue < 0)
364 {
365 iValue = -iValue;
366 pState->fFlags |= STR_F_NEGATIVE;
367 }
368 return bs3StrFormatU16(pState, iValue);
369}
370#endif
371
372
373#undef Bs3StrFormatV
374BS3_CMN_DEF(size_t, Bs3StrFormatV,(const char BS3_FAR *pszFormat, va_list BS3_FAR va,
375 PFNBS3STRFORMATOUTPUT pfnOutput, void BS3_FAR *pvUser))
376{
377 BS3FMTSTATE State;
378 size_t cchRet = 0;
379 char ch;
380#if ARCH_BITS == 16
381 typedef int SIZE_CHECK_TYPE1[sizeof(va) == 4 && sizeof(va[0]) == 4];
382#endif
383
384 State.pfnOutput = pfnOutput;
385 State.pvUser = pvUser;
386
387 while ((ch = *pszFormat++) != '\0')
388 {
389 char chArgSize;
390
391 /*
392 * Deal with plain chars.
393 */
394 if (ch != '%')
395 {
396 cchRet += State.pfnOutput(ch, State.pvUser);
397 continue;
398 }
399
400 ch = *pszFormat++;
401 if (ch == '%')
402 {
403 cchRet += State.pfnOutput(ch, State.pvUser);
404 continue;
405 }
406
407 /*
408 * Flags.
409 */
410 State.fFlags = 0;
411 for (;;)
412 {
413 unsigned int fThis;
414 switch (ch)
415 {
416 default: fThis = 0; break;
417 case '#': fThis = STR_F_SPECIAL; break;
418 case '-': fThis = STR_F_LEFT; break;
419 case '+': fThis = STR_F_PLUS; break;
420 case ' ': fThis = STR_F_BLANK; break;
421 case '0': fThis = STR_F_ZEROPAD; break;
422 case '\'': fThis = STR_F_THOUSAND_SEP; break;
423 }
424 if (!fThis)
425 break;
426 State.fFlags |= fThis;
427 ch = *pszFormat++;
428 }
429
430 /*
431 * Width.
432 */
433 State.cchWidth = 0;
434 if (RT_C_IS_DIGIT(ch))
435 {
436 do
437 {
438 State.cchWidth *= 10;
439 State.cchWidth += ch - '0';
440 ch = *pszFormat++;
441 } while (RT_C_IS_DIGIT(ch));
442 State.fFlags |= STR_F_WIDTH;
443 }
444 else if (ch == '*')
445 {
446 State.cchWidth = va_arg(va, int);
447 if (State.cchWidth < 0)
448 {
449 State.cchWidth = -State.cchWidth;
450 State.fFlags |= STR_F_LEFT;
451 }
452 State.fFlags |= STR_F_WIDTH;
453 ch = *pszFormat++;
454 }
455
456 /*
457 * Precision
458 */
459 State.cchPrecision = 0;
460 if (ch == '.')
461 {
462 ch = *pszFormat++;
463 if (RT_C_IS_DIGIT(ch))
464 {
465 do
466 {
467 State.cchPrecision *= 10;
468 State.cchPrecision += ch - '0';
469 ch = *pszFormat++;
470 } while (RT_C_IS_DIGIT(ch));
471 State.fFlags |= STR_F_PRECISION;
472 }
473 else if (ch == '*')
474 {
475 State.cchPrecision = va_arg(va, int);
476 if (State.cchPrecision < 0)
477 State.cchPrecision = 0;
478 State.fFlags |= STR_F_PRECISION;
479 ch = *pszFormat++;
480 }
481 }
482
483 /*
484 * Argument size.
485 */
486 chArgSize = ch;
487 switch (ch)
488 {
489 default:
490 chArgSize = 0;
491 break;
492
493 case 'z':
494 case 'L':
495 case 'j':
496 case 't':
497 ch = *pszFormat++;
498 break;
499
500 case 'l':
501 ch = *pszFormat++;
502 if (ch == 'l')
503 {
504 chArgSize = 'L';
505 ch = *pszFormat++;
506 }
507 break;
508
509 case 'h':
510 ch = *pszFormat++;
511 if (ch == 'h')
512 {
513 chArgSize = 'H';
514 ch = *pszFormat++;
515 }
516 break;
517 }
518
519 /*
520 * The type.
521 */
522 switch (ch)
523 {
524 /*
525 * Char
526 */
527 case 'c':
528 {
529 char ch = va_arg(va, int /*char*/);
530 cchRet += State.pfnOutput(ch, State.pvUser);
531 break;
532 }
533
534 /*
535 * String.
536 */
537 case 's':
538 {
539 const char BS3_FAR *psz = va_arg(va, const char BS3_FAR *);
540 size_t cch;
541 if (psz != NULL)
542 cch = Bs3StrNLen(psz, State.fFlags & STR_F_PRECISION ? RT_ABS(State.cchPrecision) : ~(size_t)0);
543 else
544 {
545 psz = "<NULL>";
546 cch = 6;
547 }
548
549 if ((State.fFlags & (STR_F_LEFT | STR_F_WIDTH)) == STR_F_WIDTH)
550 while (--State.cchWidth >= cch)
551 cchRet += State.pfnOutput(' ', State.pvUser);
552
553 while (cch-- > 0)
554 cchRet += State.pfnOutput(*psz++, State.pvUser);
555
556 if ((State.fFlags & (STR_F_LEFT | STR_F_WIDTH)) == (STR_F_LEFT | STR_F_WIDTH))
557 while (--State.cchWidth >= cch)
558 cchRet += State.pfnOutput(' ', State.pvUser);
559 break;
560 }
561
562 /*
563 * Signed integers.
564 */
565 case 'i':
566 case 'd':
567 State.fFlags &= ~STR_F_SPECIAL;
568 State.fFlags |= STR_F_VALSIGNED;
569 State.uBase = 10;
570 switch (chArgSize)
571 {
572 case 0:
573 case 'h': /* signed short should be promoted to int or be the same as int */
574 case 'H': /* signed char should be promoted to int. */
575 {
576 signed int iValue = va_arg(va, signed int);
577#if ARCH_BITS == 16
578 cchRet += bs3StrFormatS16(&State, iValue);
579#else
580 cchRet += bs3StrFormatS32(&State, iValue);
581#endif
582 break;
583 }
584 case 'l':
585 {
586 signed long lValue = va_arg(va, signed long);
587 if (sizeof(lValue) == 4)
588 cchRet += bs3StrFormatS32(&State, lValue);
589 else
590 cchRet += bs3StrFormatS64(&State, lValue);
591 break;
592 }
593 case 'L':
594 {
595 unsigned long long ullValue = va_arg(va, unsigned long long);
596 cchRet += bs3StrFormatS64(&State, ullValue);
597 break;
598 }
599 }
600 break;
601
602 /*
603 * Unsigned integers.
604 */
605 case 'X':
606 State.fFlags |= STR_F_CAPITAL;
607 case 'x':
608 case 'u':
609 {
610 if (ch == 'u')
611 {
612 State.uBase = 10;
613 State.fFlags &= ~(STR_F_PLUS | STR_F_BLANK | STR_F_SPECIAL);
614 }
615 else
616 {
617 State.uBase = 16;
618 State.fFlags &= ~(STR_F_PLUS | STR_F_BLANK);
619 }
620 switch (chArgSize)
621 {
622 case 0:
623 case 'h': /* unsigned short should be promoted to int or be the same as int */
624 case 'H': /* unsigned char should be promoted to int. */
625 {
626 unsigned int uValue = va_arg(va, unsigned int);
627#if ARCH_BITS == 16
628 cchRet += bs3StrFormatU16(&State, uValue);
629#else
630 cchRet += bs3StrFormatU32(&State, uValue);
631#endif
632 break;
633 }
634 case 'l':
635 {
636 unsigned long ulValue = va_arg(va, unsigned long);
637 if (sizeof(ulValue) == 4)
638 cchRet += bs3StrFormatU32(&State, ulValue);
639 else
640 cchRet += bs3StrFormatU64(&State, ulValue);
641 break;
642 }
643 case 'L':
644 {
645 unsigned long long ullValue = va_arg(va, unsigned long long);
646 cchRet += bs3StrFormatU64(&State, ullValue);
647 break;
648 }
649 }
650 break;
651 }
652
653 /*
654 * Our stuff.
655 */
656 case 'R':
657 {
658 ch = *pszFormat++;
659 switch (ch)
660 {
661 case 'I':
662 State.fFlags |= STR_F_VALSIGNED;
663 State.uBase &= ~STR_F_SPECIAL;
664 State.uBase = 10;
665 break;
666 case 'U':
667 State.fFlags &= ~(STR_F_PLUS | STR_F_BLANK | STR_F_SPECIAL);
668 State.uBase = 10;
669 break;
670 case 'X':
671 State.fFlags &= ~(STR_F_PLUS | STR_F_BLANK);
672 State.uBase = 16;
673 break;
674 case 'h':
675 ch = *pszFormat++;
676 if (ch == 'x')
677 {
678 /* Hex dumping. */
679 uint8_t const BS3_FAR *pbHex = va_arg(va, uint8_t const BS3_FAR *);
680 if (State.cchPrecision < 0)
681 State.cchPrecision = 16;
682 ch = *pszFormat++;
683 if (ch == 's' || ch == 'd')
684 {
685 /* %Rhxd is currently implemented as %Rhxs. */
686 while (State.cchPrecision-- > 0)
687 {
688 uint8_t b = *pbHex++;
689 State.pfnOutput(g_achBs3HexDigits[b >> 4], State.pvUser);
690 State.pfnOutput(g_achBs3HexDigits[b & 0x0f], State.pvUser);
691 if (State.cchPrecision)
692 State.pfnOutput(' ', State.pvUser);
693 }
694 }
695 }
696 State.uBase = 0;
697 break;
698 default:
699 State.uBase = 0;
700 break;
701 }
702 if (State.uBase)
703 {
704 ch = *pszFormat++;
705 switch (ch)
706 {
707#if ARCH_BITS != 16
708 case '3':
709 case '1': /* Will an unsigned 16-bit value always be promoted
710 to a 16-bit unsigned int. It certainly will be promoted to a 32-bit int. */
711 pszFormat++; /* Assumes (1)'6' or (3)'2' */
712#else
713 case '1':
714 pszFormat++; /* Assumes (1)'6' */
715#endif
716 case '8': /* An unsigned 8-bit value should be promoted to int, which is at least 16-bit. */
717 {
718 unsigned int uValue = va_arg(va, unsigned int);
719#if ARCH_BITS == 16
720 cchRet += bs3StrFormatU16(&State, uValue);
721#else
722 cchRet += bs3StrFormatU32(&State, uValue);
723#endif
724 break;
725 }
726#if ARCH_BITS == 16
727 case '3':
728 {
729 uint32_t uValue = va_arg(va, uint32_t);
730 pszFormat++;
731 cchRet += bs3StrFormatU32(&State, uValue);
732 break;
733 }
734#endif
735 case '6':
736 {
737 uint64_t uValue = va_arg(va, uint64_t);
738 pszFormat++;
739 cchRet += bs3StrFormatU64(&State, uValue);
740 break;
741 }
742 }
743 }
744 break;
745 }
746
747 /*
748 * Pointers.
749 */
750 case 'P':
751 State.fFlags |= STR_F_CAPITAL;
752 RT_FALL_THRU();
753 case 'p':
754 {
755 void BS3_FAR *pv = va_arg(va, void BS3_FAR *);
756 State.uBase = 16;
757 State.fFlags &= ~(STR_F_PLUS | STR_F_BLANK);
758#if ARCH_BITS == 16
759 State.fFlags |= STR_F_ZEROPAD;
760 State.cchWidth = State.fFlags & STR_F_SPECIAL ? 6: 4;
761 cchRet += bs3StrFormatU16(&State, BS3_FP_SEG(pv));
762 cchRet += State.pfnOutput(':', State.pvUser);
763 cchRet += bs3StrFormatU16(&State, BS3_FP_OFF(pv));
764#elif ARCH_BITS == 32
765 State.fFlags |= STR_F_SPECIAL | STR_F_ZEROPAD;
766 State.cchWidth = 10;
767 cchRet += bs3StrFormatU32(&State, (uintptr_t)pv);
768#elif ARCH_BITS == 64
769 State.fFlags |= STR_F_SPECIAL | STR_F_ZEROPAD | STR_F_THOUSAND_SEP;
770 State.cchWidth = 19;
771 cchRet += bs3StrFormatU64(&State, (uintptr_t)pv);
772#else
773# error "Undefined or invalid ARCH_BITS."
774#endif
775 break;
776 }
777
778 }
779 }
780
781 /*
782 * Termination call.
783 */
784 cchRet += State.pfnOutput(0, State.pvUser);
785
786 return cchRet;
787}
788
Note: See TracBrowser for help on using the repository browser.

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