2 ******************************************************************************
4 * Copyright (C) 2001-2004, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 ******************************************************************************
11 * Modification History:
13 * Date Name Description
14 * 02/08/2001 george Creation. Copied from uprintf.c
15 * 03/27/2002 Mark Schneckloth Many fixes regarding alignment, null termination
16 * (mschneckloth@atomz.com) and other various problems.
17 * 08/07/2003 george Reunify printf implementations
18 *******************************************************************************
21 #include "unicode/utypes.h"
23 #if !UCONFIG_NO_FORMATTING
25 #include "unicode/ustdio.h"
26 #include "unicode/ustring.h"
27 #include "unicode/putil.h"
35 /* u_minstrncpy copies the minimum number of code units of (count or output->available) */
37 u_sprintf_write(void *context
,
41 u_localized_print_string
*output
= (u_localized_print_string
*)context
;
42 int32_t size
= ufmt_min(count
, output
->available
);
44 u_strncpy(output
->str
+ (output
->len
- output
->available
), str
, size
);
45 output
->available
-= size
;
50 u_sprintf_pad_and_justify(void *context
,
51 const u_printf_spec_info
*info
,
55 u_localized_print_string
*output
= (u_localized_print_string
*)context
;
58 resultLen
= ufmt_min(resultLen
, output
->available
);
60 /* pad and justify, if needed */
61 if(info
->fWidth
!= -1 && resultLen
< info
->fWidth
) {
62 int32_t paddingLeft
= info
->fWidth
- resultLen
;
63 int32_t outputPos
= output
->len
- output
->available
;
65 if (paddingLeft
+ resultLen
> output
->available
) {
66 paddingLeft
= output
->available
- resultLen
;
67 if (paddingLeft
< 0) {
70 /* paddingLeft = output->available - resultLen;*/
72 written
+= paddingLeft
;
76 written
+= u_sprintf_write(output
, result
, resultLen
);
77 u_memset(&output
->str
[outputPos
+ resultLen
], info
->fPadChar
, paddingLeft
);
78 output
->available
-= paddingLeft
;
82 u_memset(&output
->str
[outputPos
], info
->fPadChar
, paddingLeft
);
83 output
->available
-= paddingLeft
;
84 written
+= u_sprintf_write(output
, result
, resultLen
);
87 /* just write the formatted output */
89 written
= u_sprintf_write(output
, result
, resultLen
);
95 U_CAPI
int32_t U_EXPORT2
96 u_sprintf(UChar
*buffer
,
97 const char *patternSpecification
,
103 va_start(ap
, patternSpecification
);
104 written
= u_vsnprintf(buffer
, INT32_MAX
, patternSpecification
, ap
);
110 U_CAPI
int32_t U_EXPORT2
111 u_sprintf_u(UChar
*buffer
,
112 const UChar
*patternSpecification
,
118 va_start(ap
, patternSpecification
);
119 written
= u_vsnprintf_u(buffer
, INT32_MAX
, patternSpecification
, ap
);
125 U_CAPI
int32_t U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
126 u_vsprintf(UChar
*buffer
,
127 const char *patternSpecification
,
130 return u_vsnprintf(buffer
, INT32_MAX
, patternSpecification
, ap
);
133 U_CAPI
int32_t U_EXPORT2
134 u_snprintf(UChar
*buffer
,
136 const char *patternSpecification
,
142 va_start(ap
, patternSpecification
);
143 written
= u_vsnprintf(buffer
, count
, patternSpecification
, ap
);
149 U_CAPI
int32_t U_EXPORT2
150 u_snprintf_u(UChar
*buffer
,
152 const UChar
*patternSpecification
,
158 va_start(ap
, patternSpecification
);
159 written
= u_vsnprintf_u(buffer
, count
, patternSpecification
, ap
);
165 U_CAPI
int32_t U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
166 u_vsnprintf(UChar
*buffer
,
168 const char *patternSpecification
,
173 UChar patBuffer
[UFMT_DEFAULT_BUFFER_SIZE
];
174 int32_t size
= (int32_t)strlen(patternSpecification
) + 1;
176 /* convert from the default codepage to Unicode */
177 if (size
>= MAX_UCHAR_BUFFER_SIZE(patBuffer
)) {
178 pattern
= (UChar
*)uprv_malloc(size
* sizeof(UChar
));
186 u_charsToUChars(patternSpecification
, pattern
, size
);
189 written
= u_vsnprintf_u(buffer
, count
, pattern
, ap
);
192 if (pattern
!= patBuffer
) {
199 U_CAPI
int32_t U_EXPORT2
200 u_vsprintf_u(UChar
*buffer
,
201 const UChar
*patternSpecification
,
204 return u_vsnprintf_u(buffer
, INT32_MAX
, patternSpecification
, ap
);
207 static const u_printf_stream_handler g_sprintf_stream_handler
= {
209 u_sprintf_pad_and_justify
212 U_CAPI
int32_t U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
213 u_vsnprintf_u(UChar
*buffer
,
215 const UChar
*patternSpecification
,
218 int32_t written
= 0; /* haven't written anything yet */
220 u_localized_print_string outStr
;
228 outStr
.available
= count
;
230 if(u_locbund_init(&outStr
.fBundle
, "en_US_POSIX") == 0) {
234 /* parse and print the whole format string */
235 u_printf_parse(&g_sprintf_stream_handler
, patternSpecification
, &outStr
, &outStr
, &outStr
.fBundle
, &written
, ap
);
237 /* Terminate the buffer, if there's room. */
238 if (outStr
.available
> 0) {
239 buffer
[outStr
.len
- outStr
.available
] = 0x0000;
242 /* Release the cloned bundle, if we cloned it. */
243 u_locbund_close(&outStr
.fBundle
);
245 /* return # of UChars written */
249 #endif /* #if !UCONFIG_NO_FORMATTING */