1 #include "ace/OS_NS_stdio.h"
2 #include "ace/OS_NS_Thread.h"
4 #if !defined (ACE_HAS_INLINED_OSCALLS)
5 # include "ace/OS_NS_stdio.inl"
6 #endif /* ACE_HAS_INLINED_OSCALLS */
8 #if !defined (ACE_LACKS_STDINT_H)
12 #include "ace/Malloc_Base.h"
18 #ifndef ACE_LACKS_WCHAR_H
22 # if defined (ACE_WIN32)
24 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
25 ACE_TEXT_OSVERSIONINFO
ACE_OS::win32_versioninfo_
;
26 HINSTANCE
ACE_OS::win32_resource_module_
;
27 ACE_END_VERSIONED_NAMESPACE_DECL
29 # if defined (ACE_HAS_DLL) && (ACE_HAS_DLL == 1)
30 // This function is called by the OS when the ACE DLL is loaded. We
31 // use it to determine the default module containing ACE's resources.
32 extern "C" BOOL WINAPI
DllMain(HINSTANCE instance
, DWORD reason
, LPVOID
)
34 if (reason
== DLL_PROCESS_ATTACH
)
36 # if defined (ACE_DISABLES_THREAD_LIBRARY_CALLS) && (ACE_DISABLES_THREAD_LIBRARY_CALLS == 1)
37 ::DisableThreadLibraryCalls (instance
);
38 # endif /* ACE_DISABLES_THREAD_LIBRARY_CALLS */
39 ACE_OS::set_win32_resource_module(instance
);
41 else if (reason
== DLL_THREAD_DETACH
)
43 ACE_OS::cleanup_tss (0);
47 # endif /* ACE_HAS_DLL && ACE_HAS_DLL == 1 */
48 # endif /* ACE_WIN32 */
50 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
55 ace_flock_t::dump () const
57 #if defined (ACE_HAS_DUMP)
58 ACE_OS_TRACE ("ACE_OS::ace_flock_t::dump");
61 ACELIB_DEBUG ((LM_DEBUG
, ACE_BEGIN_DUMP
, this));
62 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("handle_ = %u"), this->handle_
));
63 # if defined (ACE_WIN32)
64 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nInternal = %d"),
65 this->overlapped_
.Internal
));
66 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nInternalHigh = %d"),
67 this->overlapped_
.InternalHigh
));
68 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nOffsetHigh = %d"),
69 this->overlapped_
.OffsetHigh
));
70 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nhEvent = %d"),
71 this->overlapped_
.hEvent
));
73 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nl_whence = %d"),
74 this->lock_
.l_whence
));
75 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nl_start = %d"), this->lock_
.l_start
));
76 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nl_len = %d"), this->lock_
.l_len
));
77 ACELIB_DEBUG ((LM_DEBUG
, ACE_TEXT ("\nl_type = %d"), this->lock_
.l_type
));
78 # endif /* ACE_WIN32 */
79 ACELIB_DEBUG ((LM_DEBUG
, ACE_END_DUMP
));
81 #endif /* ACE_HAS_DUMP */
84 } /* namespace ACE_OS */
86 /*****************************************************************************/
89 #if defined (ACE_WIN32)
92 /// Translate fopen's mode char to open's mode. This helper function
93 /// is here to avoid maintaining several pieces of identical code.
95 fopen_mode_to_open_mode_converter (ACE_TCHAR x
, int & hmode
)
100 if (ACE_BIT_DISABLED (hmode
, _O_RDWR
))
102 ACE_CLR_BITS (hmode
, _O_WRONLY
);
103 ACE_SET_BITS (hmode
, _O_RDONLY
);
107 if (ACE_BIT_DISABLED (hmode
, _O_RDWR
))
109 ACE_CLR_BITS (hmode
, _O_RDONLY
);
110 ACE_SET_BITS (hmode
, _O_WRONLY
);
112 ACE_SET_BITS (hmode
, _O_CREAT
| _O_TRUNC
);
115 if (ACE_BIT_DISABLED (hmode
, _O_RDWR
))
117 ACE_CLR_BITS (hmode
, _O_RDONLY
);
118 ACE_SET_BITS (hmode
, _O_WRONLY
);
120 ACE_SET_BITS (hmode
, _O_CREAT
| _O_APPEND
);
123 ACE_CLR_BITS (hmode
, _O_RDONLY
| _O_WRONLY
);
124 ACE_SET_BITS (hmode
, _O_RDWR
);
127 ACE_CLR_BITS (hmode
, _O_BINARY
);
128 ACE_SET_BITS (hmode
, _O_TEXT
);
131 ACE_CLR_BITS (hmode
, _O_TEXT
);
132 ACE_SET_BITS (hmode
, _O_BINARY
);
136 } // Close anonymous namespace
139 ACE_OS::fopen (const char *filename
,
140 const ACE_TCHAR
*mode
)
142 ACE_OS_TRACE ("ACE_OS::fopen");
143 #if defined (ACE_LACKS_FOPEN)
144 ACE_UNUSED_ARG (filename
);
145 ACE_UNUSED_ARG (mode
);
146 ACE_NOTSUP_RETURN (0);
150 // Let the chips fall where they may if the user passes in a NULL
151 // mode string. Convert to an empty mode string to prevent a
153 ACE_TCHAR
const empty_mode
[] = ACE_TEXT ("");
157 for (ACE_TCHAR
const* mode_ptr
= mode
; *mode_ptr
!= 0; ++mode_ptr
)
158 fopen_mode_to_open_mode_converter (*mode_ptr
, hmode
);
160 ACE_HANDLE
const handle
= ACE_OS::open (filename
, hmode
);
161 if (handle
!= ACE_INVALID_HANDLE
)
163 hmode
&= _O_TEXT
| _O_RDONLY
| _O_APPEND
;
165 int const fd
= ::_open_osfhandle (intptr_t (handle
), hmode
);
169 # if defined (ACE_HAS_NONCONST_FDOPEN) && !defined (ACE_USES_WCHAR)
170 FILE * const fp
= ::_fdopen (fd
, const_cast<ACE_TCHAR
*> (mode
));
171 # elif defined (ACE_HAS_NONCONST_FDOPEN) && defined (ACE_USES_WCHAR)
172 FILE * const fp
= ::_wfdopen (fd
, const_cast<ACE_TCHAR
*> (mode
));
173 # elif defined (ACE_USES_WCHAR)
174 FILE * const fp
= ::_wfdopen (fd
, mode
);
176 FILE * const fp
= ::fdopen (fd
, mode
);
177 # endif /* defined(ACE_HAS_NONCONST_FDOPEN) && !defined (ACE_USES_WCHAR)) */
185 ACE_OS::close (handle
);
191 #if defined (ACE_HAS_WCHAR)
193 ACE_OS::fopen (const char *filename
,
194 const ACE_ANTI_TCHAR
*mode
)
196 return ACE_OS::fopen (filename
, ACE_TEXT_ANTI_TO_TCHAR (mode
));
200 ACE_OS::fopen (const wchar_t *filename
,
201 const ACE_ANTI_TCHAR
*mode
)
203 return ACE_OS::fopen (filename
, ACE_TEXT_ANTI_TO_TCHAR (mode
));
207 ACE_OS::fopen (const wchar_t *filename
,
208 const ACE_TCHAR
*mode
)
210 ACE_OS_TRACE ("ACE_OS::fopen");
211 #if defined (ACE_LACKS_FOPEN)
212 ACE_UNUSED_ARG (filename
);
213 ACE_UNUSED_ARG (mode
);
214 ACE_NOTSUP_RETURN (0);
218 for (const ACE_TCHAR
*mode_ptr
= mode
; *mode_ptr
!= 0; mode_ptr
++)
219 fopen_mode_to_open_mode_converter (*mode_ptr
, hmode
);
221 ACE_HANDLE handle
= ACE_OS::open (filename
, hmode
);
222 if (handle
!= ACE_INVALID_HANDLE
)
224 hmode
&= _O_TEXT
| _O_RDONLY
| _O_APPEND
;
226 int const fd
= ::_open_osfhandle (intptr_t (handle
), hmode
);
230 # if defined (ACE_HAS_NONCONST_FDOPEN) && !defined (ACE_USES_WCHAR)
231 FILE *fp
= ::_fdopen (fd
, const_cast<char *> (mode
));
232 # elif defined (ACE_HAS_NONCONST_FDOPEN) && defined (ACE_USES_WCHAR)
233 FILE *fp
= ::_wfdopen (fd
, const_cast<wchar_t *> (mode
));
234 # elif defined (ACE_USES_WCHAR)
235 FILE *fp
= ::_wfdopen (fd
, mode
);
237 FILE *fp
= ::fdopen (fd
, mode
);
238 # endif /* defined(ACE_HAS_NONCONST_FDOPEN) && !defined (ACE_USES_WCHAR)) */
246 ACE_OS::close (handle
);
251 #endif /* ACE_HAS_WCHAR */
253 #endif /* ACE_WIN32 */
255 #ifndef ACE_STDIO_USE_STDLIB_FOR_VARARGS
256 // The following *printf functions aren't inline because
259 ACE_OS::fprintf (FILE *fp
, const char *format
, ...)
261 // ACE_OS_TRACE ("ACE_OS::fprintf");
262 #if defined (ACE_LACKS_VA_FUNCTIONS)
264 ACE_UNUSED_ARG (format
);
265 ACE_NOTSUP_RETURN (-1);
268 va_start (ap
, format
);
269 int const result
= ACE_OS::vfprintf (fp
, format
, ap
);
272 #endif /* ACE_LACKS_VA_FUNCTIONS */
274 #endif /* ACE_STDIO_USE_STDLIB_FOR_VARARGS */
276 #if defined (ACE_HAS_WCHAR)
278 ACE_OS::fprintf (FILE *fp
, const wchar_t *format
, ...)
280 // ACE_OS_TRACE ("ACE_OS::fprintf");
281 #if defined (ACE_LACKS_VA_FUNCTIONS)
283 ACE_UNUSED_ARG (format
);
284 ACE_NOTSUP_RETURN (-1);
287 va_start (ap
, format
);
288 int const result
= ACE_OS::vfprintf (fp
, format
, ap
);
291 #endif /* ACE_LACKS_VA_FUNCTIONS */
293 #endif /* ACE_HAS_WCHAR */
296 ACE_OS::asprintf (char **bufp
, const char *format
, ...)
298 // ACE_OS_TRACE ("ACE_OS::asprintf");
299 #if defined (ACE_LACKS_VA_FUNCTIONS)
300 ACE_UNUSED_ARG (bufp
);
301 ACE_UNUSED_ARG (format
);
302 ACE_NOTSUP_RETURN (-1);
305 va_start (ap
, format
);
306 int const result
= ACE_OS::vasprintf (bufp
, format
, ap
);
309 #endif /* ACE_LACKS_VA_FUNCTIONS */
312 #if defined (ACE_HAS_WCHAR)
314 ACE_OS::asprintf (wchar_t **bufp
, const wchar_t *format
, ...)
316 // ACE_OS_TRACE ("ACE_OS::asprintf");
317 #if defined (ACE_LACKS_VA_FUNCTIONS)
318 ACE_UNUSED_ARG (bufp
);
319 ACE_UNUSED_ARG (format
);
320 ACE_NOTSUP_RETURN (-1);
323 va_start (ap
, format
);
324 int const result
= ACE_OS::vasprintf (bufp
, format
, ap
);
327 #endif /* ACE_LACKS_VA_FUNCTIONS */
329 #endif /* ACE_HAS_WCHAR */
331 #if !defined ACE_FACE_DEV || !defined ACE_STDIO_USE_STDLIB_FOR_VARARGS
333 ACE_OS::printf (const char *format
, ...)
335 // ACE_OS_TRACE ("ACE_OS::printf");
336 #if defined (ACE_LACKS_VA_FUNCTIONS)
337 ACE_UNUSED_ARG (format
);
338 ACE_NOTSUP_RETURN (-1);
341 va_start (ap
, format
);
342 int const result
= ACE_OS::vprintf (format
, ap
);
345 #endif /* ACE_LACKS_VA_FUNCTIONS */
347 #endif /* !ACE_FACE_DEV || !ACE_STDIO_USE_STDLIB_FOR_VARARGS */
349 #if defined (ACE_HAS_WCHAR)
351 ACE_OS::printf (const wchar_t *format
, ...)
353 // ACE_OS_TRACE ("ACE_OS::printf");
354 #if defined (ACE_LACKS_VA_FUNCTIONS)
355 ACE_UNUSED_ARG (format
);
356 ACE_NOTSUP_RETURN (-1);
359 va_start (ap
, format
);
360 int const result
= ACE_OS::vprintf (format
, ap
);
363 #endif /* ACE_LACKS_VA_FUNCTIONS */
365 #endif /* ACE_HAS_WCHAR */
367 #if !defined ACE_STDIO_USE_STDLIB_FOR_VARARGS || defined ACE_LACKS_SNPRINTF
369 ACE_OS::snprintf (char *buf
, size_t maxlen
, const char *format
, ...)
371 // ACE_OS_TRACE ("ACE_OS::snprintf");
372 #if defined (ACE_LACKS_VA_FUNCTIONS)
373 ACE_UNUSED_ARG (buf
);
374 ACE_UNUSED_ARG (maxlen
);
375 ACE_UNUSED_ARG (format
);
376 ACE_NOTSUP_RETURN (-1);
379 va_start (ap
, format
);
380 int const result
= ACE_OS::vsnprintf (buf
, maxlen
, format
, ap
);
383 #endif /* ACE_LACKS_VA_FUNCTIONS */
385 #endif /* ACE_STDIO_USE_STDLIB_FOR_VARARGS */
387 #if defined (ACE_HAS_WCHAR)
389 ACE_OS::snprintf (wchar_t *buf
, size_t maxlen
, const wchar_t *format
, ...)
391 // ACE_OS_TRACE ("ACE_OS::snprintf");
392 #if defined (ACE_LACKS_VA_FUNCTIONS)
393 ACE_UNUSED_ARG (buf
);
394 ACE_UNUSED_ARG (maxlen
);
395 ACE_UNUSED_ARG (format
);
396 ACE_NOTSUP_RETURN (-1);
399 va_start (ap
, format
);
400 int const result
= ACE_OS::vsnprintf (buf
, maxlen
, format
, ap
);
403 #endif /* ACE_LACKS_VA_FUNCTIONS */
405 #endif /* ACE_HAS_WCHAR */
408 ACE_OS::sprintf (char *buf
, const char *format
, ...)
410 // ACE_OS_TRACE ("ACE_OS::sprintf");
411 #if defined (ACE_LACKS_VA_FUNCTIONS)
412 ACE_UNUSED_ARG (buf
);
413 ACE_UNUSED_ARG (format
);
414 ACE_NOTSUP_RETURN (-1);
417 va_start (ap
, format
);
418 int const result
= ACE_OS::vsprintf (buf
, format
, ap
);
421 #endif /* ACE_LACKS_VA_FUNCTIONS */
424 #if defined (ACE_HAS_WCHAR)
426 ACE_OS::sprintf (wchar_t *buf
, const wchar_t *format
, ...)
428 // ACE_OS_TRACE ("ACE_OS::sprintf");
429 #if defined (ACE_LACKS_VA_FUNCTIONS)
430 ACE_UNUSED_ARG (buf
);
431 ACE_UNUSED_ARG (format
);
432 ACE_NOTSUP_RETURN (-1);
435 va_start (ap
, format
);
436 int const result
= ACE_OS::vsprintf (buf
, format
, ap
);
439 #endif /* ACE_LACKS_VA_FUNCTIONS */
441 #endif /* ACE_HAS_WCHAR */
443 #if !defined (ACE_HAS_VASPRINTF) && !defined (ACE_LACKS_VA_COPY)
445 ACE_OS::vasprintf_emulation(char **bufp
, const char *format
, va_list argptr
)
448 va_copy (ap
, argptr
);
449 int size
= ACE_OS::vsnprintf (0, 0, format
, ap
);
454 char *buf
= reinterpret_cast<char*>(ACE_OS::malloc(size
+ 1));
459 va_copy (aq
, argptr
);
460 size
= ACE_OS::vsnprintf(buf
, size
+ 1, format
, aq
);
471 #if !defined (ACE_HAS_VASWPRINTF) && !defined (ACE_LACKS_VA_COPY)
472 #if defined (ACE_HAS_WCHAR)
474 ACE_OS::vaswprintf_emulation(wchar_t **bufp
, const wchar_t *format
, va_list argptr
)
477 va_copy (ap
, argptr
);
478 int size
= ACE_OS::vsnprintf(0, 0, format
, ap
);
483 wchar_t *buf
= reinterpret_cast<wchar_t*>
484 (ACE_OS::malloc((size
+ 1) * sizeof(wchar_t)));
489 va_copy (aq
, argptr
);
490 size
= ACE_OS::vsnprintf(buf
, size
+ 1, format
, aq
);
499 #endif /* ACE_HAS_WCHAR */
500 #endif /* !ACE_HAS_VASPRINTF */
502 #if defined (ACE_HAS_VSNPRINTF_EMULATION)
504 #ifdef ACE_LACKS_WCHAR_H
506 #elif !defined ACE_LACKS_WCHAR_STD_NAMESPACE
508 # ifndef ACE_LACKS_WCSRTOMBS
509 using std::wcsrtombs
;
513 namespace { // helpers for vsnprintf_emulation
514 enum Flag
{ SNPRINTF_NONE
, SNPRINTF_GROUP
, SNPRINTF_LEFT
,
515 SNPRINTF_SIGN
= 4, SNPRINTF_SPACE
= 8, SNPRINTF_ALT
= 0x10,
516 SNPRINTF_ZERO
= 0x20, SNPRINTF_CHAR
= 0x40, SNPRINTF_SHORT
= 0x80,
517 SNPRINTF_LONG
= 0x100, SNPRINTF_LONGLONG
= 0x200, SNPRINTF_INTMAX
= 0x400,
518 SNPRINTF_SIZET
= 0x800, SNPRINTF_PTRDIFF
= 0x1000,
519 SNPRINTF_LONGDOUBLE
= 0x2000, SNPRINTF_UCASE
= 0x4000,
520 SNPRINTF_UNSIGNED
= 0x8000, SNPRINTF_NEGATIVE
= 0x10000,
521 SNPRINTF_EXPONENT
= 0x20000, SNPRINTF_FLEXPONENT
= 0x40000,
522 SNPRINTF_HEXPONENT
= 0x80000,
523 SNPRINTF_LARGE_INT
= (SNPRINTF_LONG
|SNPRINTF_LONGLONG
|SNPRINTF_INTMAX
|
524 SNPRINTF_SIZET
|SNPRINTF_PTRDIFF
)
527 struct Snprintf_Flags
530 : val_ (SNPRINTF_NONE
)
533 explicit Snprintf_Flags (const char *&fmt
)
534 : val_ (SNPRINTF_NONE
)
536 this->parse_flags (fmt
);
537 if (this->has (SNPRINTF_LEFT
))
538 this->remove (SNPRINTF_ZERO
);
539 if (this->has (SNPRINTF_SIGN
))
540 this->remove (SNPRINTF_SPACE
);
543 void parse_flags (const char *&fmt
)
549 // ' used as a flag is a POSIX extension to ISO std C
550 case '\'': this->add (SNPRINTF_GROUP
); break;
551 case '-': this->add (SNPRINTF_LEFT
); break;
552 case '+': this->add (SNPRINTF_SIGN
); break;
553 case ' ': this->add (SNPRINTF_SPACE
); break;
554 case '#': this->add (SNPRINTF_ALT
); break;
555 case '0': this->add (SNPRINTF_ZERO
); break;
561 void parse_length (const char *&fmt
)
563 if (fmt
[0] == 'h' && fmt
[1] == 'h')
564 this->add (SNPRINTF_CHAR
), fmt
+= 2;
565 else if (fmt
[0] == 'h')
566 this->add (SNPRINTF_SHORT
), ++fmt
;
567 else if (fmt
[0] == 'l' && fmt
[1] == 'l')
568 this->add (SNPRINTF_LONGLONG
), fmt
+= 2;
569 else if (fmt
[0] == 'l')
570 this->add (SNPRINTF_LONG
), ++fmt
;
571 else if (fmt
[0] == 'j')
572 this->add (SNPRINTF_INTMAX
), ++fmt
;
573 else if (fmt
[0] == 'z')
574 this->add (SNPRINTF_SIZET
), ++fmt
;
575 else if (fmt
[0] == 't')
576 this->add (SNPRINTF_PTRDIFF
), ++fmt
;
577 else if (fmt
[0] == 'L')
578 this->add (SNPRINTF_LONGDOUBLE
), ++fmt
;
585 this->add (SNPRINTF_LEFT
);
590 template <typename T
>
595 this->add (SNPRINTF_NEGATIVE
);
600 void conv_spec (char &c
)
602 if (std::isupper (c
))
604 if (c
== 'C' || c
== 'S') // C,S specs are POSIX extensions
605 this->add (SNPRINTF_LONG
);
607 this->add (SNPRINTF_UCASE
);
608 c
= std::tolower (c
);
613 case 'o': case 'u': case 'x': this->add (SNPRINTF_UNSIGNED
); break;
614 case 'p': this->add (SNPRINTF_ALT
); break;
615 case 'e': this->add (SNPRINTF_EXPONENT
); break;
616 case 'g': this->add (SNPRINTF_FLEXPONENT
); break;
617 case 'a': this->add (SNPRINTF_HEXPONENT
); break;
622 void add (Flag f
) { this->val_
|= f
; }
623 void remove (Flag f
) { this->val_
&= ~f
; }
624 bool has (Flag f
) const { return (this->val_
& f
) == f
; }
625 bool has_some (Flag f
) const { return this->val_
& f
; }
629 struct Snprintf_Digit_Grouping
631 Snprintf_Digit_Grouping (Snprintf_Flags flags
, const char *grouping
,
633 : grouping_ (flags
.has (SNPRINTF_GROUP
) ? grouping
: 0)
634 , separator_ (flags
.has (SNPRINTF_GROUP
) ? *grouping
: CHAR_MAX
)
635 , next_sep_ (this->separator_
)
636 , thousands_ (thousands
)
638 if (!this->separator_
)
641 this->separator_
= this->next_sep_
= CHAR_MAX
;
645 int separators_needed (int digits
) const
647 if (!this->grouping_
)
649 const char *grouping
= this->grouping_
;
650 int group
= *grouping
;
652 while (group
> 0 && group
< CHAR_MAX
&& digits
> group
)
662 bool next (char *&buf
)
664 const bool separate
= this->next_sep_
== 0;
667 *--buf
= this->thousands_
;
668 if (this->grouping_
[1])
669 this->separator_
= *++this->grouping_
;
670 this->next_sep_
= this->separator_
;
672 if (this->next_sep_
> 0 && this->next_sep_
< CHAR_MAX
)
677 const char *grouping_
;
678 int separator_
, next_sep_
;
679 const char thousands_
;
682 struct Snprintf_Buffer
684 Snprintf_Buffer (char *buf
, size_t max
)
686 , avail_ (max
- 1) // last byte is not available for writes, must be null
690 void out (const char *s
, size_t n
)
694 const size_t m
= n
> this->avail_
? this->avail_
: n
;
695 ACE_OS::memcpy (this->buf_
, s
, m
);
701 void fill (char c
, size_t n
)
705 const size_t m
= n
> this->avail_
? this->avail_
: n
;
706 ACE_OS::memset (this->buf_
, c
, m
);
712 void pad (const char *s
, size_t n
, Snprintf_Flags flags
, int width
)
714 const int used
= static_cast<int> (n
);
715 if (!flags
.has (SNPRINTF_LEFT
) && width
> used
)
716 this->fill (' ', width
- used
);
718 if (flags
.has (SNPRINTF_LEFT
) && width
> used
)
719 this->fill (' ', width
- used
);
722 void conv_int (ACE_UINT64 val
, Snprintf_Flags flags
,
723 int width
, int precision
, int base
= 10)
725 if (val
== 0 && precision
== 0)
727 if (flags
.has (SNPRINTF_SPACE
) && !flags
.has (SNPRINTF_UNSIGNED
))
729 if (flags
.has (SNPRINTF_ALT
) && base
== 8)
735 flags
.remove (SNPRINTF_ZERO
);
739 #ifdef ACE_LACKS_LOCALECONV
740 static const char thousands_sep
= 0;
741 static const char grouping
[] = "";
746 const std::lconv
*const conv
= std::localeconv ();
747 const char thousands_sep
=
748 conv
&& *conv
->thousands_sep
? *conv
->thousands_sep
: ',';
749 const char *grouping
= conv
? conv
->grouping
: "";
753 flags
.remove (SNPRINTF_GROUP
);
754 Snprintf_Digit_Grouping
dg (flags
, grouping
, thousands_sep
);
757 char *it
= buf
+ sizeof buf
;
758 const char a
= flags
.has (SNPRINTF_UCASE
) ? 'A' : 'a';
761 for (ACE_UINT64 v
= val
; v
; v
/= base
)
765 *--it
= static_cast<char> (v
% base
< 10 ?
766 '0' + v
% base
: a
+ v
% base
- 10);
769 const int digits
= static_cast<int> (buf
+ sizeof buf
- it
- sep_chars
);
771 if (base
== 8 && flags
.has (SNPRINTF_ALT
) && precision
<= digits
)
772 precision
= digits
+ 1;
774 if (flags
.has (SNPRINTF_NEGATIVE
))
776 else if (flags
.has (SNPRINTF_SPACE
) && !flags
.has (SNPRINTF_UNSIGNED
))
778 else if (flags
.has (SNPRINTF_SIGN
) && !flags
.has (SNPRINTF_UNSIGNED
))
781 const bool has_sign
= it
< buf
+ sizeof buf
- digits
- sep_chars
;
783 if (val
!= 0 && base
== 16 && flags
.has (SNPRINTF_ALT
))
785 *--it
= flags
.has (SNPRINTF_UCASE
) ? 'X' : 'x';
791 if (flags
.has (SNPRINTF_ZERO
) || precision
> digits
)
793 if (precision
> digits
)
794 padding
= precision
- digits
;
796 const int prefix
= has_sign
? 1 : (has_0x
? 2 : 0);
797 if (flags
.has (SNPRINTF_ZERO
) && width
> digits
+ sep_chars
+ prefix
)
798 padding
= width
- digits
- prefix
- sep_chars
;
800 if (!flags
.has (SNPRINTF_LEFT
) && digits
+ padding
+ prefix
< width
)
802 this->fill (' ', width
- digits
- padding
- prefix
- sep_chars
);
806 this->out (it
, prefix
);
808 this->fill ('0', padding
);
812 this->pad (it
, buf
+ sizeof buf
- it
, flags
, width
- padding
);
815 void conv_float (long double val
, Snprintf_Flags flags
,
816 int width
, int precision
)
818 char buf
[LDBL_MAX_10_EXP
+ 2];
821 // Find the sign bit manually, signbit() is only available with C99/C++11
822 const void *const ptr
= &val
;
823 const char *const pval
= static_cast<const char *> (ptr
);
824 #if ACE_BYTE_ORDER == ACE_LITTLE_ENDIAN
825 # if defined LDBL_MANT_DIG && LDBL_MANT_DIG == 64
826 # define SIGN_OFFSET 9
828 # define SIGN_OFFSET (ACE_SIZEOF_LONG_DOUBLE - 1)
831 # define SIGN_OFFSET 0
833 if (pval
[SIGN_OFFSET
] & 0x80)
834 val
= -val
, *it
++ = '-';
835 else if (flags
.has (SNPRINTF_SIGN
))
837 else if (flags
.has (SNPRINTF_SPACE
))
839 const bool has_sign
= it
> buf
;
841 if (!(val
>= -(std::numeric_limits
<long double>::max
)()
842 && val
<= (std::numeric_limits
<long double>::max
)()))
845 ACE_OS::strcpy (it
, flags
.has (SNPRINTF_UCASE
) ? "NAN" : "nan");
847 ACE_OS::strcpy (it
, flags
.has (SNPRINTF_UCASE
) ? "INF" : "inf");
848 this->conv_str (buf
, flags
, width
, -1);
852 #ifdef ACE_LACKS_LOCALECONV
853 static const char radix
= '.', thousands_sep
= 0;
854 static const char grouping
[] = "";
856 const std::lconv
*const conv
= std::localeconv ();
857 const char radix
= conv
? *conv
->decimal_point
: '.';
858 const char thousands_sep
=
859 conv
&& *conv
->thousands_sep
? *conv
->thousands_sep
: ',';
860 const char *grouping
= conv
? conv
->grouping
: "";
863 const long double log
= val
> 0 ? std::log10 (val
) : 0;
864 int dig_left
= static_cast<int> (1 + ((val
>= 1) ? log
: 0));
865 int exp
= static_cast<int> (std::floor (log
));
867 if (flags
.has (SNPRINTF_FLEXPONENT
))
869 const int p
= precision
> 0 ? precision
: (precision
< 0 ? 6 : 1);
871 if (exp
< p
&& exp
>= -4)
874 flags
.add (SNPRINTF_EXPONENT
);
877 if (flags
.has (SNPRINTF_EXPONENT
))
880 val
/= std::pow (10.L
, exp
);
883 if (flags
.has (SNPRINTF_HEXPONENT
))
886 *it
++ = flags
.has (SNPRINTF_UCASE
) ? 'X' : 'x';
887 long double mant
= std::frexp (val
, &exp
);
890 const char a
= flags
.has (SNPRINTF_UCASE
) ? 'A' : 'a';
891 *it
++ = hex_digit (mant
, a
);
892 if (precision
>= 0 || flags
.has (SNPRINTF_ALT
) || mant
> 0)
894 for (int i
= 0; i
< precision
|| precision
== -1; ++i
)
896 if ((precision
== -1 && mant
== 0) || it
== buf
+ sizeof buf
- 8)
898 *it
++ = hex_digit (mant
, a
);
900 flags
.add (SNPRINTF_EXPONENT
);
901 *it
++ = flags
.has (SNPRINTF_UCASE
) ? 'P' : 'p';
905 #if (defined __MINGW32__ && defined __x86_64__) \
906 || (defined ACE_VXWORKS && !defined __RTP__)
907 // Avoid std::modf(long double, long double*) on MinGW-W64 64-bit:
908 // see https://sourceforge.net/p/mingw-w64/bugs/478
910 double frac_part
= std::modf (static_cast<double> (val
), &int_part
);
912 long double int_part
;
913 long double frac_part
= std::modf (val
, &int_part
);
916 Snprintf_Digit_Grouping
dg (flags
, grouping
, thousands_sep
);
917 dig_left
+= dg
.separators_needed (dig_left
);
919 for (char *dec
= it
+ dig_left
; dec
> it
; int_part
/= 10)
922 *--dec
= '0' + static_cast<int> (std::fmod (int_part
, 10));
926 const char *const frac_start
= it
;
930 if (precision
> 0 || flags
.has (SNPRINTF_ALT
))
933 for (int i
= 0; i
< precision
&& it
< buf
+ sizeof buf
; ++i
)
936 const int digit
= static_cast<int> (frac_part
);
941 if (flags
.has (SNPRINTF_FLEXPONENT
) && !flags
.has (SNPRINTF_ALT
))
943 for (char *f
= it
- 1; f
>= frac_start
; --f
)
945 if (*f
== '0' || *f
== radix
)
957 if (flags
.has (SNPRINTF_EXPONENT
))
959 if (!flags
.has (SNPRINTF_HEXPONENT
))
960 *it
++ = flags
.has (SNPRINTF_UCASE
) ? 'E' : 'e';
961 Snprintf_Buffer
sb (it
, buf
+ sizeof buf
- it
);
962 Snprintf_Flags exp_flags
;
963 exp_flags
.add (SNPRINTF_SIGN
);
964 exp_flags
.value (exp
);
965 const int exp_prec
= flags
.has (SNPRINTF_HEXPONENT
) ? 1 : 2;
966 sb
.conv_int (exp
, exp_flags
, -1, exp_prec
);
970 int used
= static_cast<int> (it
- buf
);
971 const char *const end
= it
;
973 if (flags
.has (SNPRINTF_ZERO
) && used
< width
)
976 this->fill (*it
++, 1);
977 if (flags
.has (SNPRINTF_HEXPONENT
))
978 this->out (it
, 2), it
+= 2;
980 this->fill ('0', width
- used
);
984 this->pad (it
, end
- it
, flags
, width
);
987 static char hex_digit (long double &mant
, char a
)
990 int m
= static_cast<int> (mant
);
992 return m
< 10 ? '0' + m
: a
+ m
- 10;
995 void conv_char (unsigned char c
, Snprintf_Flags flags
, int width
)
997 this->pad (reinterpret_cast<char *> (&c
), 1, flags
, width
);
1000 void conv_str (const char *str
, Snprintf_Flags flags
,
1001 int width
, int precision
)
1003 const size_t len
= ACE_OS::strlen (str
),
1004 n
= (precision
>= 0 && precision
< int (len
)) ? precision
: len
;
1005 this->pad (str
, n
, flags
, width
);
1008 void conv_str (const wchar_t *str
, Snprintf_Flags flags
,
1009 int width
, int precision
)
1011 #ifdef ACE_LACKS_WCSRTOMBS
1012 ACE_UNUSED_ARG (str
);
1013 this->conv_str ("(error: no wide string conversion)",
1014 flags
, width
, precision
);
1016 std::mbstate_t mbstate
= std::mbstate_t ();
1017 const size_t n
= 1 + wcsrtombs (0, &str
, 0, &mbstate
);
1018 char *buf
= static_cast<char *> (ACE_Allocator::instance ()->malloc (n
));
1021 wcsrtombs (buf
, &str
, n
, &mbstate
);
1022 this->conv_str (buf
, flags
, width
, precision
);
1024 ACE_Allocator::instance ()->free (buf
);
1029 size_t avail_
, written_
;
1033 # define ACE_SNPRINTF_EOVERFLOW EOVERFLOW
1035 # define ACE_SNPRINTF_EOVERFLOW EINVAL
1038 int snprintf_read_int (const char *&fmt
)
1041 const unsigned long i
= ACE_OS::strtoul (fmt
, &end
, 10);
1045 errno
= ACE_SNPRINTF_EOVERFLOW
;
1048 return static_cast<int> (i
);
1051 int snprintf_positional (const char *&fmt
)
1053 const char *f
= fmt
;
1054 const int i
= snprintf_read_int (f
);
1055 if (i
> 0 && *f
== '$')
1063 struct Snprintf_Positional_Args
1065 Snprintf_Positional_Args ()
1066 : pos_arg_ (this->pos_storage_
)
1070 ~Snprintf_Positional_Args ()
1072 if (this->pos_arg_
!= this->pos_storage_
)
1073 ACE_Allocator::instance ()->free (this->pos_arg_
);
1076 struct Positional_Arg
1084 PA_INT
, PA_LONG
, PA_LONGLONG
, PA_INTMAX
, PA_PTRDIFF
, PA_SSIZE
,
1085 PA_UINT
, PA_ULONG
, PA_ULONGLONG
, PA_UINTMAX
, PA_UPTRDIFF
, PA_SIZE
,
1086 PA_WINT
, PA_DOUBLE
, PA_LONGDOUBLE
,
1087 PA_PCHAR
, PA_PWCHAR
, PA_PVOID
,
1088 PA_PINT
, PA_PINTMAX
, PA_PLONG
, PA_PLONGLONG
, PA_PPTRDIFF
, PA_PSHORT
,
1089 PA_PSCHAR
, PA_PSSIZE
1102 static void conv_storage_needed (const char *fmt
, int &storage_needed
)
1104 while (const char *f
= ACE_OS::strpbrk (fmt
, "*%"))
1106 if (!*f
|| *f
== '%')
1108 const int p
= snprintf_positional (++f
);
1109 if (p
> storage_needed
)
1115 void scan (int n
, const char *fmt
, va_list ap
)
1117 int storage_needed
= n
;
1118 const char *f
= fmt
;
1119 conv_storage_needed (f
, storage_needed
);
1120 while (const char *const pct
= ACE_OS::strchr (f
, '%'))
1125 const int p
= snprintf_positional (++f
);
1126 if (p
> storage_needed
)
1128 conv_storage_needed (f
, storage_needed
);
1131 if (size_t (storage_needed
) >
1132 sizeof this->pos_storage_
/ sizeof (Positional_Arg
))
1133 this->pos_arg_
= static_cast<Positional_Arg
*> (
1134 ACE_Allocator::instance ()->calloc (
1135 sizeof (Positional_Arg
) * storage_needed
));
1140 static const char digits
[] = "0123456789";
1141 f
+= ACE_OS::strspn (f
, "-+ #0'");
1143 (*this)[snprintf_positional (++f
)].type_
= Positional_Arg::PA_INT
;
1145 f
+= ACE_OS::strspn (f
, digits
);
1147 if (f
[0] == '.' && f
[1] == '*')
1150 (*this)[snprintf_positional (f
)].type_
= Positional_Arg::PA_INT
;
1155 f
+= ACE_OS::strspn (f
, digits
);
1158 Snprintf_Flags flags
;
1159 flags
.parse_length (f
);
1164 if (flags
.has (SNPRINTF_LONG
))
1165 (*this)[n
].type_
= Positional_Arg::PA_LONG
;
1166 else if (flags
.has (SNPRINTF_LONGLONG
))
1167 (*this)[n
].type_
= Positional_Arg::PA_LONGLONG
;
1168 else if (flags
.has (SNPRINTF_INTMAX
))
1169 (*this)[n
].type_
= Positional_Arg::PA_INTMAX
;
1170 else if (flags
.has (SNPRINTF_SIZET
))
1171 (*this)[n
].type_
= Positional_Arg::PA_SSIZE
;
1172 else if (flags
.has (SNPRINTF_PTRDIFF
))
1173 (*this)[n
].type_
= Positional_Arg::PA_PTRDIFF
;
1175 (*this)[n
].type_
= Positional_Arg::PA_INT
;
1177 case 'o': case 'u': case 'x': case 'X':
1178 if (flags
.has (SNPRINTF_LONG
))
1179 (*this)[n
].type_
= Positional_Arg::PA_ULONG
;
1180 else if (flags
.has (SNPRINTF_LONGLONG
))
1181 (*this)[n
].type_
= Positional_Arg::PA_ULONGLONG
;
1182 else if (flags
.has (SNPRINTF_INTMAX
))
1183 (*this)[n
].type_
= Positional_Arg::PA_UINTMAX
;
1184 else if (flags
.has (SNPRINTF_SIZET
))
1185 (*this)[n
].type_
= Positional_Arg::PA_SIZE
;
1186 else if (flags
.has (SNPRINTF_PTRDIFF
))
1187 (*this)[n
].type_
= Positional_Arg::PA_UPTRDIFF
;
1189 (*this)[n
].type_
= Positional_Arg::PA_UINT
;
1191 case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
1193 (*this)[n
].type_
= flags
.has (SNPRINTF_LONGDOUBLE
) ?
1194 Positional_Arg::PA_LONGDOUBLE
: Positional_Arg::PA_DOUBLE
;
1197 (*this)[n
].type_
= flags
.has (SNPRINTF_LONG
) ?
1198 Positional_Arg::PA_WINT
: Positional_Arg::PA_INT
;
1201 (*this)[n
].type_
= Positional_Arg::PA_WINT
;
1204 (*this)[n
].type_
= flags
.has (SNPRINTF_LONG
) ?
1205 Positional_Arg::PA_PWCHAR
: Positional_Arg::PA_PCHAR
;
1208 (*this)[n
].type_
= Positional_Arg::PA_PWCHAR
;
1211 (*this)[n
].type_
= Positional_Arg::PA_PVOID
;
1214 if (flags
.has (SNPRINTF_LONG
))
1215 (*this)[n
].type_
= Positional_Arg::PA_PLONG
;
1216 else if (flags
.has (SNPRINTF_LONGLONG
))
1217 (*this)[n
].type_
= Positional_Arg::PA_PLONGLONG
;
1218 else if (flags
.has (SNPRINTF_INTMAX
))
1219 (*this)[n
].type_
= Positional_Arg::PA_PINTMAX
;
1220 else if (flags
.has (SNPRINTF_SIZET
))
1221 (*this)[n
].type_
= Positional_Arg::PA_PSSIZE
;
1222 else if (flags
.has (SNPRINTF_PTRDIFF
))
1223 (*this)[n
].type_
= Positional_Arg::PA_PPTRDIFF
;
1224 else if (flags
.has (SNPRINTF_SHORT
))
1225 (*this)[n
].type_
= Positional_Arg::PA_PSHORT
;
1226 else if (flags
.has (SNPRINTF_CHAR
))
1227 (*this)[n
].type_
= Positional_Arg::PA_PSCHAR
;
1229 (*this)[n
].type_
= Positional_Arg::PA_PINT
;
1235 // Find the next conversion and set n to the positional arg number
1237 f
= ACE_OS::strchr (f
+ 1, '%');
1238 while (f
&& f
[1] == '%' && ++f
);
1242 n
= snprintf_positional (++f
);
1245 for (int i
= 1; i
<= storage_needed
; ++i
)
1246 switch ((*this)[i
].type_
)
1248 case Positional_Arg::PA_INT
:
1249 (*this)[i
].i
= va_arg (ap
, int);
1251 case Positional_Arg::PA_LONG
:
1252 (*this)[i
].i64
= va_arg (ap
, long);
1254 case Positional_Arg::PA_LONGLONG
:
1255 (*this)[i
].i64
= va_arg (ap
, long long);
1257 #ifndef ACE_LACKS_STDINT_H
1258 case Positional_Arg::PA_INTMAX
:
1259 (*this)[i
].i64
= va_arg (ap
, intmax_t);
1262 case Positional_Arg::PA_PTRDIFF
:
1263 (*this)[i
].i64
= va_arg (ap
, ptrdiff_t);
1265 case Positional_Arg::PA_SSIZE
:
1266 (*this)[i
].i64
= va_arg (ap
, ssize_t
);
1268 case Positional_Arg::PA_UINT
:
1269 (*this)[i
].ui64
= va_arg (ap
, unsigned int);
1271 case Positional_Arg::PA_ULONG
:
1272 (*this)[i
].ui64
= va_arg (ap
, unsigned long);
1274 case Positional_Arg::PA_ULONGLONG
:
1275 (*this)[i
].ui64
= va_arg (ap
, unsigned long long);
1277 #ifndef ACE_LACKS_STDINT_H
1278 case Positional_Arg::PA_UINTMAX
:
1279 (*this)[i
].ui64
= va_arg (ap
, uintmax_t);
1282 case Positional_Arg::PA_UPTRDIFF
:
1283 (*this)[i
].ui64
= static_cast<uintptr_t> (va_arg (ap
, ptrdiff_t));
1285 case Positional_Arg::PA_SIZE
:
1286 (*this)[i
].ui64
= va_arg (ap
, size_t);
1289 #define ACE_WINT_T_VA_ARG int
1291 #define ACE_WINT_T_VA_ARG wint_t
1293 case Positional_Arg::PA_WINT
:
1294 (*this)[i
].ui64
= va_arg (ap
, ACE_WINT_T_VA_ARG
);
1296 case Positional_Arg::PA_DOUBLE
:
1297 (*this)[i
].f
= va_arg (ap
, double);
1299 case Positional_Arg::PA_LONGDOUBLE
:
1300 (*this)[i
].f
= va_arg (ap
, long double);
1302 case Positional_Arg::PA_PCHAR
:
1303 (*this)[i
].p
= va_arg (ap
, char *);
1305 case Positional_Arg::PA_PWCHAR
:
1306 (*this)[i
].p
= va_arg (ap
, wchar_t *);
1308 case Positional_Arg::PA_PVOID
:
1309 (*this)[i
].p
= va_arg (ap
, void *);
1311 case Positional_Arg::PA_PINT
:
1312 (*this)[i
].p
= va_arg (ap
, int *);
1314 #ifndef ACE_LACKS_STDINT_H
1315 case Positional_Arg::PA_PINTMAX
:
1316 (*this)[i
].p
= va_arg (ap
, intmax_t *);
1319 case Positional_Arg::PA_PLONG
:
1320 (*this)[i
].p
= va_arg (ap
, long *);
1322 case Positional_Arg::PA_PLONGLONG
:
1323 (*this)[i
].p
= va_arg (ap
, long long *);
1325 case Positional_Arg::PA_PPTRDIFF
:
1326 (*this)[i
].p
= va_arg (ap
, ptrdiff_t *);
1328 case Positional_Arg::PA_PSHORT
:
1329 (*this)[i
].p
= va_arg (ap
, short *);
1331 case Positional_Arg::PA_PSCHAR
:
1332 (*this)[i
].p
= va_arg (ap
, signed char *);
1334 case Positional_Arg::PA_PSSIZE
:
1335 (*this)[i
].p
= va_arg (ap
, ssize_t
*);
1340 this->scanned_
= true;
1343 Positional_Arg
&operator[] (int idx
)
1345 return this->pos_arg_
[idx
- 1];
1348 Positional_Arg pos_storage_
[10], *pos_arg_
;
1352 Snprintf_Positional_Args (const Snprintf_Positional_Args
&);
1353 Snprintf_Positional_Args
& operator= (const Snprintf_Positional_Args
&);
1358 ACE_OS::vsnprintf_emulation (char *buf
, size_t max
, const char *fmt
, va_list ap
)
1362 errno
= ACE_SNPRINTF_EOVERFLOW
;
1366 Snprintf_Buffer
sb (buf
, max
);
1367 Snprintf_Positional_Args pos_arg
;
1369 while (const char *const pct
= ACE_OS::strchr (fmt
, '%'))
1371 // Output up to next % in format string
1372 const bool escaped
= pct
[1] == '%';
1373 const size_t non_conv
= pct
- fmt
+ escaped
;
1374 sb
.out (fmt
, non_conv
);
1375 fmt
+= 1 + non_conv
;
1379 // Check if positional args are used (%1$d)
1380 const int posn
= snprintf_positional (fmt
);
1381 if (posn
&& !pos_arg
.scanned_
)
1382 pos_arg
.scan (posn
, fmt
, ap
); // POSIX extension
1384 // Parse flags (+- #'0)
1385 Snprintf_Flags
flags (fmt
);
1387 // Parse field width (integer, *, or *n$)
1388 static const int WIDTH_PREC_UNSPEC
= -1;
1389 int width
= WIDTH_PREC_UNSPEC
;
1393 const int width_p
= snprintf_positional (fmt
);
1394 width
= width_p
? pos_arg
[width_p
].i
: va_arg (ap
, int);
1395 flags
.width (width
);
1397 else if (*fmt
>= '1' && *fmt
<= '9')
1399 width
= snprintf_read_int (fmt
);
1404 // Parse precision (.integer, .*, or .*n$)
1405 int precision
= WIDTH_PREC_UNSPEC
;
1406 if (fmt
[0] == '.' && fmt
[1] == '*')
1409 const int prec_p
= snprintf_positional (fmt
);
1410 precision
= prec_p
? pos_arg
[prec_p
].i
: va_arg (ap
, int);
1412 precision
= WIDTH_PREC_UNSPEC
;
1414 else if (*fmt
== '.')
1416 precision
= snprintf_read_int (++fmt
);
1417 if (precision
== -1)
1421 flags
.parse_length (fmt
);
1423 // would be nice to have a helper function for this, but va_list
1424 // can't portably be passed to another function (even by pointer)
1425 #ifdef ACE_LACKS_STDINT_H
1426 # define GET_UNSIGNED_INTMAX
1428 # define GET_UNSIGNED_INTMAX \
1429 else if (flags.has (SNPRINTF_INTMAX)) \
1430 val = va_arg (ap, uintmax_t);
1432 #define GET_UNSIGNED_VA \
1434 val = pos_arg[posn].ui64; \
1435 else if (flags.has (SNPRINTF_LONGLONG)) \
1436 val = va_arg (ap, unsigned long long); \
1437 else if (flags.has (SNPRINTF_LONG)) \
1438 val = va_arg (ap, unsigned long); \
1439 GET_UNSIGNED_INTMAX \
1440 else if (flags.has (SNPRINTF_SIZET)) \
1441 val = va_arg (ap, size_t); \
1442 else if (flags.has (SNPRINTF_PTRDIFF)) \
1443 val = static_cast<uintptr_t> (va_arg (ap, ptrdiff_t)); \
1445 val = va_arg (ap, unsigned int); \
1446 if (flags.has (SNPRINTF_SHORT)) \
1447 val = static_cast<unsigned short> (val); \
1448 else if (flags.has (SNPRINTF_CHAR)) \
1449 val = static_cast<unsigned char> (val)
1451 #define GET_ARG(MEMBER, TYPE) \
1452 (posn ? static_cast<TYPE> (pos_arg[posn].MEMBER) : va_arg (ap, TYPE))
1457 wchar_t tmp_wstr
[2] = {};
1459 // Parse conversion specifier (diouxXfFeEgGaAcCsSpn) and convert arg
1461 flags
.conv_spec (spec
);
1466 sval
= flags
.has_some (SNPRINTF_LARGE_INT
)
1467 ? pos_arg
[posn
].i64
: pos_arg
[posn
].i
;
1468 else if (flags
.has (SNPRINTF_LONGLONG
))
1469 sval
= va_arg (ap
, long long);
1470 else if (flags
.has (SNPRINTF_LONG
))
1471 sval
= va_arg (ap
, long);
1472 #ifndef ACE_LACKS_STDINT_H
1473 else if (flags
.has (SNPRINTF_INTMAX
))
1474 sval
= va_arg (ap
, intmax_t);
1476 else if (flags
.has (SNPRINTF_SIZET
))
1477 sval
= va_arg (ap
, ssize_t
);
1478 else if (flags
.has (SNPRINTF_PTRDIFF
))
1479 sval
= va_arg (ap
, ptrdiff_t);
1481 sval
= va_arg (ap
, int);
1483 if (flags
.has (SNPRINTF_SHORT
))
1484 sval
= static_cast<short> (sval
);
1485 else if (flags
.has (SNPRINTF_CHAR
))
1486 sval
= static_cast<signed char> (sval
);
1489 sb
.conv_int (sval
, flags
, width
, precision
);
1494 sb
.conv_int (val
, flags
, width
, precision
, 8);
1499 sb
.conv_int (val
, flags
, width
, precision
);
1504 sb
.conv_int (val
, flags
, width
, precision
, 16);
1508 fval
= posn
? pos_arg
[posn
].f
:
1509 (flags
.has (SNPRINTF_LONGDOUBLE
) ? va_arg (ap
, long double)
1510 : va_arg (ap
, double));
1511 sb
.conv_float (fval
, flags
, width
, precision
);
1515 fval
= posn
? pos_arg
[posn
].f
:
1516 (flags
.has (SNPRINTF_LONGDOUBLE
) ? va_arg (ap
, long double)
1517 : va_arg (ap
, double));
1518 sb
.conv_float (fval
, flags
, width
, precision
);
1522 fval
= posn
? pos_arg
[posn
].f
:
1523 (flags
.has (SNPRINTF_LONGDOUBLE
) ? va_arg (ap
, long double)
1524 : va_arg (ap
, double));
1525 sb
.conv_float (fval
, flags
, width
, precision
);
1529 fval
= posn
? pos_arg
[posn
].f
:
1530 (flags
.has (SNPRINTF_LONGDOUBLE
) ? va_arg (ap
, long double)
1531 : va_arg (ap
, double));
1532 sb
.conv_float (fval
, flags
, width
, precision
);
1536 if (flags
.has (SNPRINTF_LONG
))
1538 *tmp_wstr
= static_cast<wchar_t> (
1539 posn
? pos_arg
[posn
].ui64
: va_arg (ap
, ACE_WINT_T_VA_ARG
));
1540 sb
.conv_str (tmp_wstr
, flags
, width
, precision
);
1543 sb
.conv_char (static_cast<unsigned char> (GET_ARG (i
, int)),
1548 if (flags
.has (SNPRINTF_LONG
))
1549 sb
.conv_str (GET_ARG (p
, const wchar_t *), flags
, width
, precision
);
1551 sb
.conv_str (GET_ARG (p
, const char *), flags
, width
, precision
);
1555 val
= reinterpret_cast<ACE_UINT64
> (GET_ARG (p
, void *));
1556 sb
.conv_int (val
, flags
, width
, precision
, 16);
1560 if (flags
.has (SNPRINTF_LONGLONG
))
1561 *GET_ARG (p
, long long *) = sb
.written_
;
1562 else if (flags
.has (SNPRINTF_LONG
))
1563 *GET_ARG (p
, long *) = static_cast<long> (sb
.written_
);
1564 #ifndef ACE_LACKS_STDINT_H
1565 else if (flags
.has (SNPRINTF_INTMAX
))
1566 *GET_ARG (p
, intmax_t *) = sb
.written_
;
1568 else if (flags
.has (SNPRINTF_SIZET
))
1569 *GET_ARG (p
, ssize_t
*) = sb
.written_
;
1570 else if (flags
.has (SNPRINTF_PTRDIFF
))
1571 *GET_ARG (p
, ptrdiff_t *) = sb
.written_
;
1572 else if (flags
.has (SNPRINTF_SHORT
))
1573 *GET_ARG (p
, short *) = static_cast<short> (sb
.written_
);
1574 else if (flags
.has (SNPRINTF_CHAR
))
1575 *GET_ARG (p
, signed char *) =
1576 static_cast<signed char> (sb
.written_
);
1578 *GET_ARG (p
, int *) = static_cast<int> (sb
.written_
);
1586 // Output remaining part of format string
1587 sb
.out (fmt
, ACE_OS::strlen (fmt
));
1589 return static_cast<int> (sb
.written_
);
1591 #endif // ACE_HAS_VSNPRINTF_EMULATION
1593 ACE_END_VERSIONED_NAMESPACE_DECL