VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/string/strformatrt.cpp@ 45256

Last change on this file since 45256 was 45236, checked in by vboxsync, 12 years ago

Runtime: fixed %Rhxd

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 52.4 KB
Line 
1/* $Id: strformatrt.cpp 45236 2013-03-28 15:05:36Z vboxsync $ */
2/** @file
3 * IPRT - IPRT String Formatter Extensions.
4 */
5
6/*
7 * Copyright (C) 2006-2012 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#define LOG_GROUP RTLOGGROUP_STRING
32#include <iprt/string.h>
33#ifndef RT_NO_EXPORT_SYMBOL
34# define RT_NO_EXPORT_SYMBOL /* don't slurp <linux/module.h> which then again
35 slurps arch-specific headers defining symbols */
36#endif
37#include "internal/iprt.h"
38
39#include <iprt/log.h>
40#include <iprt/assert.h>
41#include <iprt/string.h>
42#include <iprt/stdarg.h>
43#ifdef IN_RING3
44# include <iprt/thread.h>
45# include <iprt/err.h>
46#endif
47#include <iprt/ctype.h>
48#include <iprt/time.h>
49#include <iprt/net.h>
50#include <iprt/path.h>
51#include <iprt/asm.h>
52#define STRFORMAT_WITH_X86
53#ifdef STRFORMAT_WITH_X86
54# include <iprt/x86.h>
55#endif
56#include "internal/string.h"
57
58
59
60/**
61 * Callback to format iprt formatting extentions.
62 * See @ref pg_rt_str_format for a reference on the format types.
63 *
64 * @returns The number of bytes formatted.
65 * @param pfnOutput Pointer to output function.
66 * @param pvArgOutput Argument for the output function.
67 * @param ppszFormat Pointer to the format string pointer. Advance this till the char
68 * after the format specifier.
69 * @param pArgs Pointer to the argument list. Use this to fetch the arguments.
70 * @param cchWidth Format Width. -1 if not specified.
71 * @param cchPrecision Format Precision. -1 if not specified.
72 * @param fFlags Flags (RTSTR_NTFS_*).
73 * @param chArgSize The argument size specifier, 'l' or 'L'.
74 */
75DECLHIDDEN(size_t) rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **ppszFormat, va_list *pArgs,
76 int cchWidth, int cchPrecision, unsigned fFlags, char chArgSize)
77{
78 const char *pszFormatOrg = *ppszFormat;
79 char ch = *(*ppszFormat)++;
80 size_t cch;
81 char szBuf[80];
82
83 if (ch == 'R')
84 {
85 ch = *(*ppszFormat)++;
86 switch (ch)
87 {
88 /*
89 * Groups 1 and 2.
90 */
91 case 'T':
92 case 'G':
93 case 'H':
94 case 'R':
95 case 'C':
96 case 'I':
97 case 'X':
98 case 'U':
99 {
100 /*
101 * Interpret the type.
102 */
103 typedef enum
104 {
105 RTSF_INT,
106 RTSF_INTW,
107 RTSF_BOOL,
108 RTSF_FP16,
109 RTSF_FP32,
110 RTSF_FP64,
111 RTSF_IPV4,
112 RTSF_IPV6,
113 RTSF_MAC,
114 RTSF_NETADDR,
115 RTSF_UUID
116 } RTSF;
117 static const struct
118 {
119 uint8_t cch; /**< the length of the string. */
120 char sz[10]; /**< the part following 'R'. */
121 uint8_t cb; /**< the size of the type. */
122 uint8_t u8Base; /**< the size of the type. */
123 RTSF enmFormat; /**< The way to format it. */
124 uint16_t fFlags; /**< additional RTSTR_F_* flags. */
125 }
126 /** Sorted array of types, looked up using binary search! */
127 s_aTypes[] =
128 {
129#define STRMEM(str) sizeof(str) - 1, str
130 { STRMEM("Ci"), sizeof(RTINT), 10, RTSF_INT, RTSTR_F_VALSIGNED },
131 { STRMEM("Cp"), sizeof(RTCCPHYS), 16, RTSF_INTW, 0 },
132 { STRMEM("Cr"), sizeof(RTCCUINTREG), 16, RTSF_INTW, 0 },
133 { STRMEM("Cu"), sizeof(RTUINT), 10, RTSF_INT, 0 },
134 { STRMEM("Cv"), sizeof(void *), 16, RTSF_INTW, 0 },
135 { STRMEM("Cx"), sizeof(RTUINT), 16, RTSF_INT, 0 },
136 { STRMEM("Gi"), sizeof(RTGCINT), 10, RTSF_INT, RTSTR_F_VALSIGNED },
137 { STRMEM("Gp"), sizeof(RTGCPHYS), 16, RTSF_INTW, 0 },
138 { STRMEM("Gr"), sizeof(RTGCUINTREG), 16, RTSF_INTW, 0 },
139 { STRMEM("Gu"), sizeof(RTGCUINT), 10, RTSF_INT, 0 },
140 { STRMEM("Gv"), sizeof(RTGCPTR), 16, RTSF_INTW, 0 },
141 { STRMEM("Gx"), sizeof(RTGCUINT), 16, RTSF_INT, 0 },
142 { STRMEM("Hi"), sizeof(RTHCINT), 10, RTSF_INT, RTSTR_F_VALSIGNED },
143 { STRMEM("Hp"), sizeof(RTHCPHYS), 16, RTSF_INTW, 0 },
144 { STRMEM("Hr"), sizeof(RTHCUINTREG), 16, RTSF_INTW, 0 },
145 { STRMEM("Hu"), sizeof(RTHCUINT), 10, RTSF_INT, 0 },
146 { STRMEM("Hv"), sizeof(RTHCPTR), 16, RTSF_INTW, 0 },
147 { STRMEM("Hx"), sizeof(RTHCUINT), 16, RTSF_INT, 0 },
148 { STRMEM("I16"), sizeof(int16_t), 10, RTSF_INT, RTSTR_F_VALSIGNED },
149 { STRMEM("I32"), sizeof(int32_t), 10, RTSF_INT, RTSTR_F_VALSIGNED },
150 { STRMEM("I64"), sizeof(int64_t), 10, RTSF_INT, RTSTR_F_VALSIGNED },
151 { STRMEM("I8"), sizeof(int8_t), 10, RTSF_INT, RTSTR_F_VALSIGNED },
152 { STRMEM("Rv"), sizeof(RTRCPTR), 16, RTSF_INTW, 0 },
153 { STRMEM("Tbool"), sizeof(bool), 10, RTSF_BOOL, 0 },
154 { STRMEM("Tfile"), sizeof(RTFILE), 10, RTSF_INT, 0 },
155 { STRMEM("Tfmode"), sizeof(RTFMODE), 16, RTSF_INTW, 0 },
156 { STRMEM("Tfoff"), sizeof(RTFOFF), 10, RTSF_INT, RTSTR_F_VALSIGNED },
157 { STRMEM("Tfp16"), sizeof(RTFAR16), 16, RTSF_FP16, RTSTR_F_ZEROPAD },
158 { STRMEM("Tfp32"), sizeof(RTFAR32), 16, RTSF_FP32, RTSTR_F_ZEROPAD },
159 { STRMEM("Tfp64"), sizeof(RTFAR64), 16, RTSF_FP64, RTSTR_F_ZEROPAD },
160 { STRMEM("Tgid"), sizeof(RTGID), 10, RTSF_INT, RTSTR_F_VALSIGNED },
161 { STRMEM("Tino"), sizeof(RTINODE), 16, RTSF_INTW, 0 },
162 { STRMEM("Tint"), sizeof(RTINT), 10, RTSF_INT, RTSTR_F_VALSIGNED },
163 { STRMEM("Tiop"), sizeof(RTIOPORT), 16, RTSF_INTW, 0 },
164 { STRMEM("Tldrm"), sizeof(RTLDRMOD), 16, RTSF_INTW, 0 },
165 { STRMEM("Tmac"), sizeof(PCRTMAC), 16, RTSF_MAC, 0 },
166 { STRMEM("Tnaddr"), sizeof(PCRTNETADDR), 10, RTSF_NETADDR,0 },
167 { STRMEM("Tnaipv4"), sizeof(RTNETADDRIPV4), 10, RTSF_IPV4, 0 },
168 { STRMEM("Tnaipv6"), sizeof(PCRTNETADDRIPV6),16, RTSF_IPV6, 0 },
169 { STRMEM("Tnthrd"), sizeof(RTNATIVETHREAD), 16, RTSF_INTW, 0 },
170 { STRMEM("Tproc"), sizeof(RTPROCESS), 16, RTSF_INTW, 0 },
171 { STRMEM("Tptr"), sizeof(RTUINTPTR), 16, RTSF_INTW, 0 },
172 { STRMEM("Treg"), sizeof(RTCCUINTREG), 16, RTSF_INTW, 0 },
173 { STRMEM("Tsel"), sizeof(RTSEL), 16, RTSF_INTW, 0 },
174 { STRMEM("Tsem"), sizeof(RTSEMEVENT), 16, RTSF_INTW, 0 },
175 { STRMEM("Tsock"), sizeof(RTSOCKET), 10, RTSF_INT, 0 },
176 { STRMEM("Tthrd"), sizeof(RTTHREAD), 16, RTSF_INTW, 0 },
177 { STRMEM("Tuid"), sizeof(RTUID), 10, RTSF_INT, RTSTR_F_VALSIGNED },
178 { STRMEM("Tuint"), sizeof(RTUINT), 10, RTSF_INT, 0 },
179 { STRMEM("Tunicp"), sizeof(RTUNICP), 16, RTSF_INTW, RTSTR_F_ZEROPAD },
180 { STRMEM("Tutf16"), sizeof(RTUTF16), 16, RTSF_INTW, RTSTR_F_ZEROPAD },
181 { STRMEM("Tuuid"), sizeof(PCRTUUID), 16, RTSF_UUID, 0 },
182 { STRMEM("Txint"), sizeof(RTUINT), 16, RTSF_INT, 0 },
183 { STRMEM("U16"), sizeof(uint16_t), 10, RTSF_INT, 0 },
184 { STRMEM("U32"), sizeof(uint32_t), 10, RTSF_INT, 0 },
185 { STRMEM("U64"), sizeof(uint64_t), 10, RTSF_INT, 0 },
186 { STRMEM("U8"), sizeof(uint8_t), 10, RTSF_INT, 0 },
187 { STRMEM("X16"), sizeof(uint16_t), 16, RTSF_INT, 0 },
188 { STRMEM("X32"), sizeof(uint32_t), 16, RTSF_INT, 0 },
189 { STRMEM("X64"), sizeof(uint64_t), 16, RTSF_INT, 0 },
190 { STRMEM("X8"), sizeof(uint8_t), 16, RTSF_INT, 0 },
191#undef STRMEM
192 };
193 static const char s_szNull[] = "<NULL>";
194
195 const char *pszType = *ppszFormat - 1;
196 int iStart = 0;
197 int iEnd = RT_ELEMENTS(s_aTypes) - 1;
198 int i = RT_ELEMENTS(s_aTypes) / 2;
199
200 union
201 {
202 uint8_t u8;
203 uint16_t u16;
204 uint32_t u32;
205 uint64_t u64;
206 int8_t i8;
207 int16_t i16;
208 int32_t i32;
209 int64_t i64;
210 RTFAR16 fp16;
211 RTFAR32 fp32;
212 RTFAR64 fp64;
213 bool fBool;
214 PCRTMAC pMac;
215 RTNETADDRIPV4 Ipv4Addr;
216 PCRTNETADDRIPV6 pIpv6Addr;
217 PCRTNETADDR pNetAddr;
218 PCRTUUID pUuid;
219 } u;
220
221 AssertMsg(!chArgSize, ("Not argument size '%c' for RT types! '%.10s'\n", chArgSize, pszFormatOrg));
222
223 /*
224 * Lookup the type - binary search.
225 */
226 for (;;)
227 {
228 int iDiff = strncmp(pszType, s_aTypes[i].sz, s_aTypes[i].cch);
229 if (!iDiff)
230 break;
231 if (iEnd == iStart)
232 {
233 AssertMsgFailed(("Invalid format type '%.10s'!\n", pszFormatOrg));
234 return 0;
235 }
236 if (iDiff < 0)
237 iEnd = i - 1;
238 else
239 iStart = i + 1;
240 if (iEnd < iStart)
241 {
242 AssertMsgFailed(("Invalid format type '%.10s'!\n", pszFormatOrg));
243 return 0;
244 }
245 i = iStart + (iEnd - iStart) / 2;
246 }
247
248 /*
249 * Advance the format string and merge flags.
250 */
251 *ppszFormat += s_aTypes[i].cch - 1;
252 fFlags |= s_aTypes[i].fFlags;
253
254 /*
255 * Fetch the argument.
256 * It's important that a signed value gets sign-extended up to 64-bit.
257 */
258 RT_ZERO(u);
259 if (fFlags & RTSTR_F_VALSIGNED)
260 {
261 switch (s_aTypes[i].cb)
262 {
263 case sizeof(int8_t):
264 u.i64 = va_arg(*pArgs, /*int8_t*/int);
265 fFlags |= RTSTR_F_8BIT;
266 break;
267 case sizeof(int16_t):
268 u.i64 = va_arg(*pArgs, /*int16_t*/int);
269 fFlags |= RTSTR_F_16BIT;
270 break;
271 case sizeof(int32_t):
272 u.i64 = va_arg(*pArgs, int32_t);
273 fFlags |= RTSTR_F_32BIT;
274 break;
275 case sizeof(int64_t):
276 u.i64 = va_arg(*pArgs, int64_t);
277 fFlags |= RTSTR_F_64BIT;
278 break;
279 default:
280 AssertMsgFailed(("Invalid format error, size %d'!\n", s_aTypes[i].cb));
281 break;
282 }
283 }
284 else
285 {
286 switch (s_aTypes[i].cb)
287 {
288 case sizeof(uint8_t):
289 u.u8 = va_arg(*pArgs, /*uint8_t*/unsigned);
290 fFlags |= RTSTR_F_8BIT;
291 break;
292 case sizeof(uint16_t):
293 u.u16 = va_arg(*pArgs, /*uint16_t*/unsigned);
294 fFlags |= RTSTR_F_16BIT;
295 break;
296 case sizeof(uint32_t):
297 u.u32 = va_arg(*pArgs, uint32_t);
298 fFlags |= RTSTR_F_32BIT;
299 break;
300 case sizeof(uint64_t):
301 u.u64 = va_arg(*pArgs, uint64_t);
302 fFlags |= RTSTR_F_64BIT;
303 break;
304 case sizeof(RTFAR32):
305 u.fp32 = va_arg(*pArgs, RTFAR32);
306 break;
307 case sizeof(RTFAR64):
308 u.fp64 = va_arg(*pArgs, RTFAR64);
309 break;
310 default:
311 AssertMsgFailed(("Invalid format error, size %d'!\n", s_aTypes[i].cb));
312 break;
313 }
314 }
315
316 /*
317 * Format the output.
318 */
319 switch (s_aTypes[i].enmFormat)
320 {
321 case RTSF_INT:
322 {
323 cch = RTStrFormatNumber(szBuf, u.u64, s_aTypes[i].u8Base, cchWidth, cchPrecision, fFlags);
324 break;
325 }
326
327 /* hex which defaults to max width. */
328 case RTSF_INTW:
329 {
330 Assert(s_aTypes[i].u8Base == 16);
331 if (cchWidth < 0)
332 {
333 cchWidth = s_aTypes[i].cb * 2 + (fFlags & RTSTR_F_SPECIAL ? 2 : 0);
334 fFlags |= RTSTR_F_ZEROPAD;
335 }
336 cch = RTStrFormatNumber(szBuf, u.u64, s_aTypes[i].u8Base, cchWidth, cchPrecision, fFlags);
337 break;
338 }
339
340 case RTSF_BOOL:
341 {
342 static const char s_szTrue[] = "true ";
343 static const char s_szFalse[] = "false";
344 if (u.u64 == 1)
345 return pfnOutput(pvArgOutput, s_szTrue, sizeof(s_szTrue) - 1);
346 if (u.u64 == 0)
347 return pfnOutput(pvArgOutput, s_szFalse, sizeof(s_szFalse) - 1);
348 /* invalid boolean value */
349 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "!%lld!", u.u64);
350 }
351
352 case RTSF_FP16:
353 {
354 fFlags &= ~(RTSTR_F_VALSIGNED | RTSTR_F_BIT_MASK | RTSTR_F_WIDTH | RTSTR_F_PRECISION | RTSTR_F_THOUSAND_SEP);
355 cch = RTStrFormatNumber(&szBuf[0], u.fp16.sel, 16, 4, -1, fFlags | RTSTR_F_16BIT);
356 Assert(cch == 4);
357 szBuf[4] = ':';
358 cch = RTStrFormatNumber(&szBuf[5], u.fp16.off, 16, 4, -1, fFlags | RTSTR_F_16BIT);
359 Assert(cch == 4);
360 cch = 4 + 1 + 4;
361 break;
362 }
363 case RTSF_FP32:
364 {
365 fFlags &= ~(RTSTR_F_VALSIGNED | RTSTR_F_BIT_MASK | RTSTR_F_WIDTH | RTSTR_F_PRECISION | RTSTR_F_THOUSAND_SEP);
366 cch = RTStrFormatNumber(&szBuf[0], u.fp32.sel, 16, 4, -1, fFlags | RTSTR_F_16BIT);
367 Assert(cch == 4);
368 szBuf[4] = ':';
369 cch = RTStrFormatNumber(&szBuf[5], u.fp32.off, 16, 8, -1, fFlags | RTSTR_F_32BIT);
370 Assert(cch == 8);
371 cch = 4 + 1 + 8;
372 break;
373 }
374 case RTSF_FP64:
375 {
376 fFlags &= ~(RTSTR_F_VALSIGNED | RTSTR_F_BIT_MASK | RTSTR_F_WIDTH | RTSTR_F_PRECISION | RTSTR_F_THOUSAND_SEP);
377 cch = RTStrFormatNumber(&szBuf[0], u.fp64.sel, 16, 4, -1, fFlags | RTSTR_F_16BIT);
378 Assert(cch == 4);
379 szBuf[4] = ':';
380 cch = RTStrFormatNumber(&szBuf[5], u.fp64.off, 16, 16, -1, fFlags | RTSTR_F_64BIT);
381 Assert(cch == 16);
382 cch = 4 + 1 + 16;
383 break;
384 }
385
386 case RTSF_IPV4:
387 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
388 "%u.%u.%u.%u",
389 u.Ipv4Addr.au8[0],
390 u.Ipv4Addr.au8[1],
391 u.Ipv4Addr.au8[2],
392 u.Ipv4Addr.au8[3]);
393
394 case RTSF_IPV6:
395 {
396 if (VALID_PTR(u.pIpv6Addr))
397 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
398 "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
399 u.pIpv6Addr->au8[0],
400 u.pIpv6Addr->au8[1],
401 u.pIpv6Addr->au8[2],
402 u.pIpv6Addr->au8[3],
403 u.pIpv6Addr->au8[4],
404 u.pIpv6Addr->au8[5],
405 u.pIpv6Addr->au8[6],
406 u.pIpv6Addr->au8[7],
407 u.pIpv6Addr->au8[8],
408 u.pIpv6Addr->au8[9],
409 u.pIpv6Addr->au8[10],
410 u.pIpv6Addr->au8[11],
411 u.pIpv6Addr->au8[12],
412 u.pIpv6Addr->au8[13],
413 u.pIpv6Addr->au8[14],
414 u.pIpv6Addr->au8[15]);
415 return pfnOutput(pvArgOutput, s_szNull, sizeof(s_szNull) - 1);
416 }
417
418 case RTSF_MAC:
419 {
420 if (VALID_PTR(u.pMac))
421 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
422 "%02x:%02x:%02x:%02x:%02x:%02x",
423 u.pMac->au8[0],
424 u.pMac->au8[1],
425 u.pMac->au8[2],
426 u.pMac->au8[3],
427 u.pMac->au8[4],
428 u.pMac->au8[5]);
429 return pfnOutput(pvArgOutput, s_szNull, sizeof(s_szNull) - 1);
430 }
431
432 case RTSF_NETADDR:
433 {
434 if (VALID_PTR(u.pNetAddr))
435 {
436 switch (u.pNetAddr->enmType)
437 {
438 case RTNETADDRTYPE_IPV4:
439 if (u.pNetAddr->uPort == RTNETADDR_PORT_NA)
440 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
441 "%u.%u.%u.%u",
442 u.pNetAddr->uAddr.IPv4.au8[0],
443 u.pNetAddr->uAddr.IPv4.au8[1],
444 u.pNetAddr->uAddr.IPv4.au8[2],
445 u.pNetAddr->uAddr.IPv4.au8[3]);
446 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
447 "%u.%u.%u.%u:%u",
448 u.pNetAddr->uAddr.IPv4.au8[0],
449 u.pNetAddr->uAddr.IPv4.au8[1],
450 u.pNetAddr->uAddr.IPv4.au8[2],
451 u.pNetAddr->uAddr.IPv4.au8[3],
452 u.pNetAddr->uPort);
453
454 case RTNETADDRTYPE_IPV6:
455 if (u.pNetAddr->uPort == RTNETADDR_PORT_NA)
456 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
457 "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
458 u.pNetAddr->uAddr.IPv6.au8[0],
459 u.pNetAddr->uAddr.IPv6.au8[1],
460 u.pNetAddr->uAddr.IPv6.au8[2],
461 u.pNetAddr->uAddr.IPv6.au8[3],
462 u.pNetAddr->uAddr.IPv6.au8[4],
463 u.pNetAddr->uAddr.IPv6.au8[5],
464 u.pNetAddr->uAddr.IPv6.au8[6],
465 u.pNetAddr->uAddr.IPv6.au8[7],
466 u.pNetAddr->uAddr.IPv6.au8[8],
467 u.pNetAddr->uAddr.IPv6.au8[9],
468 u.pNetAddr->uAddr.IPv6.au8[10],
469 u.pNetAddr->uAddr.IPv6.au8[11],
470 u.pNetAddr->uAddr.IPv6.au8[12],
471 u.pNetAddr->uAddr.IPv6.au8[13],
472 u.pNetAddr->uAddr.IPv6.au8[14],
473 u.pNetAddr->uAddr.IPv6.au8[15]);
474 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
475 "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x %u",
476 u.pNetAddr->uAddr.IPv6.au8[0],
477 u.pNetAddr->uAddr.IPv6.au8[1],
478 u.pNetAddr->uAddr.IPv6.au8[2],
479 u.pNetAddr->uAddr.IPv6.au8[3],
480 u.pNetAddr->uAddr.IPv6.au8[4],
481 u.pNetAddr->uAddr.IPv6.au8[5],
482 u.pNetAddr->uAddr.IPv6.au8[6],
483 u.pNetAddr->uAddr.IPv6.au8[7],
484 u.pNetAddr->uAddr.IPv6.au8[8],
485 u.pNetAddr->uAddr.IPv6.au8[9],
486 u.pNetAddr->uAddr.IPv6.au8[10],
487 u.pNetAddr->uAddr.IPv6.au8[11],
488 u.pNetAddr->uAddr.IPv6.au8[12],
489 u.pNetAddr->uAddr.IPv6.au8[13],
490 u.pNetAddr->uAddr.IPv6.au8[14],
491 u.pNetAddr->uAddr.IPv6.au8[15],
492 u.pNetAddr->uPort);
493
494 case RTNETADDRTYPE_MAC:
495 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
496 "%02x:%02x:%02x:%02x:%02x:%02x",
497 u.pNetAddr->uAddr.Mac.au8[0],
498 u.pNetAddr->uAddr.Mac.au8[1],
499 u.pNetAddr->uAddr.Mac.au8[2],
500 u.pNetAddr->uAddr.Mac.au8[3],
501 u.pNetAddr->uAddr.Mac.au8[4],
502 u.pNetAddr->uAddr.Mac.au8[5]);
503
504 default:
505 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
506 "unsupported-netaddr-type=%u", u.pNetAddr->enmType);
507
508 }
509 }
510 return pfnOutput(pvArgOutput, s_szNull, sizeof(s_szNull) - 1);
511 }
512
513 case RTSF_UUID:
514 {
515 if (VALID_PTR(u.pUuid))
516 {
517 /* cannot call RTUuidToStr because of GC/R0. */
518 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
519 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
520 RT_H2LE_U32(u.pUuid->Gen.u32TimeLow),
521 RT_H2LE_U16(u.pUuid->Gen.u16TimeMid),
522 RT_H2LE_U16(u.pUuid->Gen.u16TimeHiAndVersion),
523 u.pUuid->Gen.u8ClockSeqHiAndReserved,
524 u.pUuid->Gen.u8ClockSeqLow,
525 u.pUuid->Gen.au8Node[0],
526 u.pUuid->Gen.au8Node[1],
527 u.pUuid->Gen.au8Node[2],
528 u.pUuid->Gen.au8Node[3],
529 u.pUuid->Gen.au8Node[4],
530 u.pUuid->Gen.au8Node[5]);
531 }
532 return pfnOutput(pvArgOutput, s_szNull, sizeof(s_szNull) - 1);
533 }
534
535 default:
536 AssertMsgFailed(("Internal error %d\n", s_aTypes[i].enmFormat));
537 return 0;
538 }
539
540 /*
541 * Finally, output the formatted string and return.
542 */
543 return pfnOutput(pvArgOutput, szBuf, cch);
544 }
545
546
547 /* Group 3 */
548
549 /*
550 * Base name printing.
551 */
552 case 'b':
553 {
554 switch (*(*ppszFormat)++)
555 {
556 case 'n':
557 {
558 const char *pszLastSep;
559 const char *psz = pszLastSep = va_arg(*pArgs, const char *);
560 if (!VALID_PTR(psz))
561 return pfnOutput(pvArgOutput, "<null>", sizeof("<null>") - 1);
562
563 while ((ch = *psz) != '\0')
564 {
565 if (RTPATH_IS_SEP(ch))
566 {
567 do
568 psz++;
569 while ((ch = *psz) != '\0' && RTPATH_IS_SEP(ch));
570 if (!ch)
571 break;
572 pszLastSep = psz;
573 }
574 psz++;
575 }
576
577 return pfnOutput(pvArgOutput, pszLastSep, psz - pszLastSep);
578 }
579
580 default:
581 AssertMsgFailed(("Invalid status code format type '%.10s'!\n", pszFormatOrg));
582 break;
583 }
584 break;
585 }
586
587
588 /*
589 * Pretty function / method name printing.
590 */
591 case 'f':
592 {
593 switch (*(*ppszFormat)++)
594 {
595 /*
596 * Pretty function / method name printing.
597 * This isn't 100% right (see classic signal prototype) and it assumes
598 * standardized names, but it'll do for today.
599 */
600 case 'n':
601 {
602 const char *pszStart;
603 const char *psz = pszStart = va_arg(*pArgs, const char *);
604 if (!VALID_PTR(psz))
605 return pfnOutput(pvArgOutput, "<null>", sizeof("<null>") - 1);
606
607 while ((ch = *psz) != '\0' && ch != '(')
608 {
609 if (RT_C_IS_BLANK(ch))
610 {
611 psz++;
612 while ((ch = *psz) != '\0' && (RT_C_IS_BLANK(ch) || ch == '('))
613 psz++;
614 if (ch)
615 pszStart = psz;
616 }
617 else if (ch == '(')
618 break;
619 else
620 psz++;
621 }
622
623 return pfnOutput(pvArgOutput, pszStart, psz - pszStart);
624 }
625
626 default:
627 AssertMsgFailed(("Invalid status code format type '%.10s'!\n", pszFormatOrg));
628 break;
629 }
630 break;
631 }
632
633
634 /*
635 * hex dumping and COM/XPCOM.
636 */
637 case 'h':
638 {
639 switch (*(*ppszFormat)++)
640 {
641 /*
642 * Hex stuff.
643 */
644 case 'x':
645 {
646 uint8_t *pu8 = va_arg(*pArgs, uint8_t *);
647 if (cchPrecision <= 0)
648 cchPrecision = 16;
649 if (pu8)
650 {
651 switch (*(*ppszFormat)++)
652 {
653 /*
654 * Regular hex dump.
655 */
656 case 'd':
657 {
658 int off = 0;
659 cch = 0;
660
661 if (cchWidth <= 0)
662 cchWidth = 16;
663
664 while (off < cchPrecision)
665 {
666 int i;
667 cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%s%0*p %04x:", off ? "\n" : "", sizeof(pu8) * 2, (uintptr_t)pu8, off);
668 for (i = 0; i < cchWidth && off + i < cchPrecision ; i++)
669 cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0,
670 off + i < cchPrecision ? !(i & 7) && i ? "-%02x" : " %02x" : " ", pu8[i]);
671 while (i++ < cchWidth)
672 cch += pfnOutput(pvArgOutput, " ", 3);
673
674 cch += pfnOutput(pvArgOutput, " ", 1);
675
676 for (i = 0; i < cchWidth && off + i < cchPrecision; i++)
677 {
678 uint8_t u8 = pu8[i];
679 cch += pfnOutput(pvArgOutput, u8 < 127 && u8 >= 32 ? (const char *)&u8 : ".", 1);
680 }
681
682 /* next */
683 pu8 += cchWidth;
684 off += cchWidth;
685 }
686 return cch;
687 }
688
689 /*
690 * Hex string.
691 */
692 case 's':
693 {
694 if (cchPrecision-- > 0)
695 {
696 cch = RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%02x", *pu8++);
697 for (; cchPrecision > 0; cchPrecision--, pu8++)
698 cch += RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, " %02x", *pu8);
699 return cch;
700 }
701 break;
702 }
703
704 default:
705 AssertMsgFailed(("Invalid status code format type '%.10s'!\n", pszFormatOrg));
706 break;
707 }
708 }
709 else
710 return pfnOutput(pvArgOutput, "<null>", sizeof("<null>") - 1);
711 break;
712 }
713
714
715#ifdef IN_RING3
716 /*
717 * XPCOM / COM status code: %Rhrc, %Rhrf, %Rhra
718 * ASSUMES: If Windows Then COM else XPCOM.
719 */
720 case 'r':
721 {
722 uint32_t hrc = va_arg(*pArgs, uint32_t);
723 PCRTCOMERRMSG pMsg = RTErrCOMGet(hrc);
724 switch (*(*ppszFormat)++)
725 {
726 case 'c':
727 return pfnOutput(pvArgOutput, pMsg->pszDefine, strlen(pMsg->pszDefine));
728 case 'f':
729 return pfnOutput(pvArgOutput, pMsg->pszMsgFull,strlen(pMsg->pszMsgFull));
730 case 'a':
731 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%s (0x%08X) - %s", pMsg->pszDefine, hrc, pMsg->pszMsgFull);
732 default:
733 AssertMsgFailed(("Invalid status code format type '%.10s'!\n", pszFormatOrg));
734 return 0;
735 }
736 break;
737 }
738#endif /* IN_RING3 */
739
740 default:
741 AssertMsgFailed(("Invalid status code format type '%.10s'!\n", pszFormatOrg));
742 return 0;
743
744 }
745 break;
746 }
747
748 /*
749 * iprt status code: %Rrc, %Rrs, %Rrf, %Rra.
750 */
751 case 'r':
752 {
753 int rc = va_arg(*pArgs, int);
754#ifdef IN_RING3 /* we don't want this anywhere else yet. */
755 PCRTSTATUSMSG pMsg = RTErrGet(rc);
756 switch (*(*ppszFormat)++)
757 {
758 case 'c':
759 return pfnOutput(pvArgOutput, pMsg->pszDefine, strlen(pMsg->pszDefine));
760 case 's':
761 return pfnOutput(pvArgOutput, pMsg->pszMsgShort, strlen(pMsg->pszMsgShort));
762 case 'f':
763 return pfnOutput(pvArgOutput, pMsg->pszMsgFull, strlen(pMsg->pszMsgFull));
764 case 'a':
765 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%s (%d) - %s", pMsg->pszDefine, rc, pMsg->pszMsgFull);
766 default:
767 AssertMsgFailed(("Invalid status code format type '%.10s'!\n", pszFormatOrg));
768 return 0;
769 }
770#else /* !IN_RING3 */
771 switch (*(*ppszFormat)++)
772 {
773 case 'c':
774 case 's':
775 case 'f':
776 case 'a':
777 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%d", rc);
778 default:
779 AssertMsgFailed(("Invalid status code format type '%.10s'!\n", pszFormatOrg));
780 return 0;
781 }
782#endif /* !IN_RING3 */
783 break;
784 }
785
786#if defined(IN_RING3)
787 /*
788 * Windows status code: %Rwc, %Rwf, %Rwa
789 */
790 case 'w':
791 {
792 long rc = va_arg(*pArgs, long);
793# if defined(RT_OS_WINDOWS)
794 PCRTWINERRMSG pMsg = RTErrWinGet(rc);
795# endif
796 switch (*(*ppszFormat)++)
797 {
798# if defined(RT_OS_WINDOWS)
799 case 'c':
800 return pfnOutput(pvArgOutput, pMsg->pszDefine, strlen(pMsg->pszDefine));
801 case 'f':
802 return pfnOutput(pvArgOutput, pMsg->pszMsgFull,strlen(pMsg->pszMsgFull));
803 case 'a':
804 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "%s (0x%08X) - %s", pMsg->pszDefine, rc, pMsg->pszMsgFull);
805# else
806 case 'c':
807 case 'f':
808 case 'a':
809 return RTStrFormat(pfnOutput, pvArgOutput, NULL, 0, "0x%08X", rc);
810# endif
811 default:
812 AssertMsgFailed(("Invalid status code format type '%.10s'!\n", pszFormatOrg));
813 return 0;
814 }
815 break;
816 }
817#endif /* IN_RING3 */
818
819 /*
820 * Group 4, structure dumpers.
821 */
822 case 'D':
823 {
824 /*
825 * Interpret the type.
826 */
827 typedef enum
828 {
829 RTST_TIMESPEC
830 } RTST;
831/** Set if it's a pointer */
832#define RTST_FLAGS_POINTER RT_BIT(0)
833 static const struct
834 {
835 uint8_t cch; /**< the length of the string. */
836 char sz[16-2]; /**< the part following 'R'. */
837 uint8_t cb; /**< the size of the argument. */
838 uint8_t fFlags; /**< RTST_FLAGS_* */
839 RTST enmType; /**< The structure type. */
840 }
841 /** Sorted array of types, looked up using binary search! */
842 s_aTypes[] =
843 {
844#define STRMEM(str) sizeof(str) - 1, str
845 { STRMEM("Dtimespec"), sizeof(PCRTTIMESPEC), RTST_FLAGS_POINTER, RTST_TIMESPEC},
846#undef STRMEM
847 };
848 const char *pszType = *ppszFormat - 1;
849 int iStart = 0;
850 int iEnd = RT_ELEMENTS(s_aTypes) - 1;
851 int i = RT_ELEMENTS(s_aTypes) / 2;
852
853 union
854 {
855 const void *pv;
856 uint64_t u64;
857 PCRTTIMESPEC pTimeSpec;
858 } u;
859
860 AssertMsg(!chArgSize, ("Not argument size '%c' for RT types! '%.10s'\n", chArgSize, pszFormatOrg));
861
862 /*
863 * Lookup the type - binary search.
864 */
865 for (;;)
866 {
867 int iDiff = strncmp(pszType, s_aTypes[i].sz, s_aTypes[i].cch);
868 if (!iDiff)
869 break;
870 if (iEnd == iStart)
871 {
872 AssertMsgFailed(("Invalid format type '%.10s'!\n", pszFormatOrg));
873 return 0;
874 }
875 if (iDiff < 0)
876 iEnd = i - 1;
877 else
878 iStart = i + 1;
879 if (iEnd < iStart)
880 {
881 AssertMsgFailed(("Invalid format type '%.10s'!\n", pszFormatOrg));
882 return 0;
883 }
884 i = iStart + (iEnd - iStart) / 2;
885 }
886 *ppszFormat += s_aTypes[i].cch - 1;
887
888 /*
889 * Fetch the argument.
890 */
891 u.u64 = 0;
892 switch (s_aTypes[i].cb)
893 {
894 case sizeof(const void *):
895 u.pv = va_arg(*pArgs, const void *);
896 break;
897 default:
898 AssertMsgFailed(("Invalid format error, size %d'!\n", s_aTypes[i].cb));
899 break;
900 }
901
902 /*
903 * If it's a pointer, we'll check if it's valid before going on.
904 */
905 if ((s_aTypes[i].fFlags & RTST_FLAGS_POINTER) && !VALID_PTR(u.pv))
906 return pfnOutput(pvArgOutput, "<null>", sizeof("<null>") - 1);
907
908 /*
909 * Format the output.
910 */
911 switch (s_aTypes[i].enmType)
912 {
913 case RTST_TIMESPEC:
914 return RTStrFormat(pfnOutput, pvArgOutput, NULL, NULL, "%'lld ns", RTTimeSpecGetNano(u.pTimeSpec));
915
916 default:
917 AssertMsgFailed(("Invalid/unhandled enmType=%d\n", s_aTypes[i].enmType));
918 break;
919 }
920 break;
921 }
922
923#ifdef IN_RING3
924 /*
925 * Group 5, XML / HTML escapers.
926 */
927 case 'M':
928 {
929 char chWhat = (*ppszFormat)[0];
930 bool fAttr = chWhat == 'a';
931 char chType = (*ppszFormat)[1];
932 AssertMsgBreak(chWhat == 'a' || chWhat == 'e', ("Invalid IPRT format type '%.10s'!\n", pszFormatOrg));
933 *ppszFormat += 2;
934 switch (chType)
935 {
936 case 's':
937 {
938 static const char s_szElemEscape[] = "<>&\"'";
939 static const char s_szAttrEscape[] = "<>&\"\n\r"; /* more? */
940 const char * const pszEscape = fAttr ? s_szAttrEscape : s_szElemEscape;
941 size_t const cchEscape = (fAttr ? RT_ELEMENTS(s_szAttrEscape) : RT_ELEMENTS(s_szElemEscape)) - 1;
942 size_t cchOutput = 0;
943 const char *pszStr = va_arg(*pArgs, char *);
944 ssize_t cchStr;
945 ssize_t offCur;
946 ssize_t offLast;
947
948 if (!VALID_PTR(pszStr))
949 pszStr = "<NULL>";
950 cchStr = RTStrNLen(pszStr, (unsigned)cchPrecision);
951
952 if (fAttr)
953 cchOutput += pfnOutput(pvArgOutput, "\"", 1);
954 if (!(fFlags & RTSTR_F_LEFT))
955 while (--cchWidth >= cchStr)
956 cchOutput += pfnOutput(pvArgOutput, " ", 1);
957
958 offLast = offCur = 0;
959 while (offCur < cchStr)
960 {
961 if (memchr(pszEscape, pszStr[offCur], cchEscape))
962 {
963 if (offLast < offCur)
964 cchOutput += pfnOutput(pvArgOutput, &pszStr[offLast], offCur - offLast);
965 switch (pszStr[offCur])
966 {
967 case '<': cchOutput += pfnOutput(pvArgOutput, "&lt;", 4); break;
968 case '>': cchOutput += pfnOutput(pvArgOutput, "&gt;", 4); break;
969 case '&': cchOutput += pfnOutput(pvArgOutput, "&amp;", 5); break;
970 case '\'': cchOutput += pfnOutput(pvArgOutput, "&apos;", 6); break;
971 case '"': cchOutput += pfnOutput(pvArgOutput, "&quot;", 6); break;
972 case '\n': cchOutput += pfnOutput(pvArgOutput, "&#xA;", 5); break;
973 case '\r': cchOutput += pfnOutput(pvArgOutput, "&#xD;", 5); break;
974 default:
975 AssertFailed();
976 }
977 offLast = offCur + 1;
978 }
979 offCur++;
980 }
981 if (offLast < offCur)
982 cchOutput += pfnOutput(pvArgOutput, &pszStr[offLast], offCur - offLast);
983
984 while (--cchWidth >= cchStr)
985 cchOutput += pfnOutput(pvArgOutput, " ", 1);
986 if (fAttr)
987 cchOutput += pfnOutput(pvArgOutput, "\"", 1);
988 return cchOutput;
989 }
990
991 default:
992 AssertMsgFailed(("Invalid IPRT format type '%.10s'!\n", pszFormatOrg));
993 }
994 break;
995 }
996#endif /* IN_RING3 */
997
998
999 /*
1000 * Groups 6 - CPU Architecture Register Formatters.
1001 * "%RAarch[reg]"
1002 */
1003 case 'A':
1004 {
1005 char const * const pszArch = *ppszFormat;
1006 const char *pszReg = pszArch;
1007 size_t cchOutput = 0;
1008 int cPrinted = 0;
1009 size_t cchReg;
1010
1011 /* Parse out the */
1012 while ((ch = *pszReg++) && ch != '[')
1013 { /* nothing */ }
1014 AssertMsgBreak(ch == '[', ("Malformed IPRT architecture register format type '%.10s'!\n", pszFormatOrg));
1015
1016 cchReg = 0;
1017 while ((ch = pszReg[cchReg]) && ch != ']')
1018 cchReg++;
1019 AssertMsgBreak(ch == ']', ("Malformed IPRT architecture register format type '%.10s'!\n", pszFormatOrg));
1020
1021 *ppszFormat = &pszReg[cchReg + 1];
1022
1023
1024#define REG_EQUALS(a_szReg) (sizeof(a_szReg) - 1 == cchReg && !strncmp(a_szReg, pszReg, sizeof(a_szReg) - 1))
1025#define REG_OUT_BIT(a_uVal, a_fBitMask, a_szName) \
1026 do { \
1027 if ((a_uVal) & (a_fBitMask)) \
1028 { \
1029 if (!cPrinted++) \
1030 cchOutput += pfnOutput(pvArgOutput, "{" a_szName, sizeof(a_szName)); \
1031 else \
1032 cchOutput += pfnOutput(pvArgOutput, "," a_szName, sizeof(a_szName)); \
1033 (a_uVal) &= ~(a_fBitMask); \
1034 } \
1035 } while (0)
1036#define REG_OUT_CLOSE(a_uVal) \
1037 do { \
1038 if ((a_uVal)) \
1039 { \
1040 cchOutput += pfnOutput(pvArgOutput, !cPrinted ? "{unkn=" : ",unkn=", 6); \
1041 cch = RTStrFormatNumber(&szBuf[0], (a_uVal), 16, 1, -1, fFlags); \
1042 cchOutput += pfnOutput(pvArgOutput, szBuf, cch); \
1043 cPrinted++; \
1044 } \
1045 if (cPrinted) \
1046 cchOutput += pfnOutput(pvArgOutput, "}", 1); \
1047 } while (0)
1048
1049
1050 if (0)
1051 { /* dummy */ }
1052#ifdef STRFORMAT_WITH_X86
1053 /*
1054 * X86 & AMD64.
1055 */
1056 else if ( pszReg - pszArch == 3 + 1
1057 && pszArch[0] == 'x'
1058 && pszArch[1] == '8'
1059 && pszArch[2] == '6')
1060 {
1061 if (REG_EQUALS("cr0"))
1062 {
1063 uint64_t cr0 = va_arg(*pArgs, uint64_t);
1064 fFlags |= RTSTR_F_64BIT;
1065 cch = RTStrFormatNumber(&szBuf[0], cr0, 16, 8, -1, fFlags | RTSTR_F_ZEROPAD);
1066 cchOutput += pfnOutput(pvArgOutput, szBuf, cch);
1067 REG_OUT_BIT(cr0, X86_CR0_PE, "PE");
1068 REG_OUT_BIT(cr0, X86_CR0_MP, "MP");
1069 REG_OUT_BIT(cr0, X86_CR0_EM, "EM");
1070 REG_OUT_BIT(cr0, X86_CR0_TS, "DE");
1071 REG_OUT_BIT(cr0, X86_CR0_ET, "ET");
1072 REG_OUT_BIT(cr0, X86_CR0_NE, "NE");
1073 REG_OUT_BIT(cr0, X86_CR0_WP, "WP");
1074 REG_OUT_BIT(cr0, X86_CR0_AM, "AM");
1075 REG_OUT_BIT(cr0, X86_CR0_NW, "NW");
1076 REG_OUT_BIT(cr0, X86_CR0_CD, "CD");
1077 REG_OUT_BIT(cr0, X86_CR0_PG, "PG");
1078 REG_OUT_CLOSE(cr0);
1079 }
1080 else if (REG_EQUALS("cr4"))
1081 {
1082 uint64_t cr4 = va_arg(*pArgs, uint64_t);
1083 fFlags |= RTSTR_F_64BIT;
1084 cch = RTStrFormatNumber(&szBuf[0], cr4, 16, 8, -1, fFlags | RTSTR_F_ZEROPAD);
1085 cchOutput += pfnOutput(pvArgOutput, szBuf, cch);
1086 REG_OUT_BIT(cr4, X86_CR4_VME, "VME");
1087 REG_OUT_BIT(cr4, X86_CR4_PVI, "PVI");
1088 REG_OUT_BIT(cr4, X86_CR4_TSD, "TSD");
1089 REG_OUT_BIT(cr4, X86_CR4_DE, "DE");
1090 REG_OUT_BIT(cr4, X86_CR4_PSE, "PSE");
1091 REG_OUT_BIT(cr4, X86_CR4_PAE, "PAE");
1092 REG_OUT_BIT(cr4, X86_CR4_MCE, "MCE");
1093 REG_OUT_BIT(cr4, X86_CR4_PGE, "PGE");
1094 REG_OUT_BIT(cr4, X86_CR4_PCE, "PCE");
1095 REG_OUT_BIT(cr4, X86_CR4_OSFSXR, "OSFSXR");
1096 REG_OUT_BIT(cr4, X86_CR4_OSXMMEEXCPT, "OSXMMEEXCPT");
1097 REG_OUT_BIT(cr4, X86_CR4_VMXE, "VMXE");
1098 REG_OUT_BIT(cr4, X86_CR4_SMXE, "SMXE");
1099 REG_OUT_BIT(cr4, X86_CR4_PCIDE, "PCIDE");
1100 REG_OUT_BIT(cr4, X86_CR4_OSXSAVE, "OSXSAVE");
1101 REG_OUT_BIT(cr4, X86_CR4_SMEP, "SMPE");
1102 REG_OUT_CLOSE(cr4);
1103 }
1104 else
1105 AssertMsgFailed(("Unknown x86 register specified in '%.10s'!\n", pszFormatOrg));
1106 }
1107#endif
1108 else
1109 AssertMsgFailed(("Unknown architecture specified in '%.10s'!\n", pszFormatOrg));
1110#undef REG_OUT_BIT
1111#undef REG_OUT_CLOSE
1112#undef REG_EQUALS
1113 return cchOutput;
1114 }
1115
1116 /*
1117 * Invalid/Unknown. Bitch about it.
1118 */
1119 default:
1120 AssertMsgFailed(("Invalid IPRT format type '%.10s'!\n", pszFormatOrg));
1121 break;
1122 }
1123 }
1124 else
1125 AssertMsgFailed(("Invalid IPRT format type '%.10s'!\n", pszFormatOrg));
1126
1127 NOREF(pszFormatOrg);
1128 return 0;
1129}
1130
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