2 ******************************************************************************
4 * Copyright (C) 2001-2008, 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
;
57 int32_t lengthOfResult
= resultLen
;
59 resultLen
= ufmt_min(resultLen
, output
->available
);
61 /* pad and justify, if needed */
62 if(info
->fWidth
!= -1 && resultLen
< info
->fWidth
) {
63 int32_t paddingLeft
= info
->fWidth
- resultLen
;
64 int32_t outputPos
= output
->len
- output
->available
;
66 if (paddingLeft
+ resultLen
> output
->available
) {
67 paddingLeft
= output
->available
- resultLen
;
68 if (paddingLeft
< 0) {
71 /* paddingLeft = output->available - resultLen;*/
73 written
+= paddingLeft
;
77 written
+= u_sprintf_write(output
, result
, resultLen
);
78 u_memset(&output
->str
[outputPos
+ resultLen
], info
->fPadChar
, paddingLeft
);
79 output
->available
-= paddingLeft
;
83 u_memset(&output
->str
[outputPos
], info
->fPadChar
, paddingLeft
);
84 output
->available
-= paddingLeft
;
85 written
+= u_sprintf_write(output
, result
, resultLen
);
88 /* just write the formatted output */
90 written
= u_sprintf_write(output
, result
, resultLen
);
93 if (written
>= 0 && lengthOfResult
> written
) {
94 return lengthOfResult
;
100 U_CAPI
int32_t U_EXPORT2
101 u_sprintf(UChar
*buffer
,
102 const char *patternSpecification
,
108 va_start(ap
, patternSpecification
);
109 written
= u_vsnprintf(buffer
, INT32_MAX
, patternSpecification
, ap
);
115 U_CAPI
int32_t U_EXPORT2
116 u_sprintf_u(UChar
*buffer
,
117 const UChar
*patternSpecification
,
123 va_start(ap
, patternSpecification
);
124 written
= u_vsnprintf_u(buffer
, INT32_MAX
, patternSpecification
, ap
);
130 U_CAPI
int32_t U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
131 u_vsprintf(UChar
*buffer
,
132 const char *patternSpecification
,
135 return u_vsnprintf(buffer
, INT32_MAX
, patternSpecification
, ap
);
138 U_CAPI
int32_t U_EXPORT2
139 u_snprintf(UChar
*buffer
,
141 const char *patternSpecification
,
147 va_start(ap
, patternSpecification
);
148 written
= u_vsnprintf(buffer
, count
, patternSpecification
, ap
);
154 U_CAPI
int32_t U_EXPORT2
155 u_snprintf_u(UChar
*buffer
,
157 const UChar
*patternSpecification
,
163 va_start(ap
, patternSpecification
);
164 written
= u_vsnprintf_u(buffer
, count
, patternSpecification
, ap
);
170 U_CAPI
int32_t U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
171 u_vsnprintf(UChar
*buffer
,
173 const char *patternSpecification
,
178 UChar patBuffer
[UFMT_DEFAULT_BUFFER_SIZE
];
179 int32_t size
= (int32_t)strlen(patternSpecification
) + 1;
181 /* convert from the default codepage to Unicode */
182 if (size
>= MAX_UCHAR_BUFFER_SIZE(patBuffer
)) {
183 pattern
= (UChar
*)uprv_malloc(size
* sizeof(UChar
));
191 u_charsToUChars(patternSpecification
, pattern
, size
);
194 written
= u_vsnprintf_u(buffer
, count
, pattern
, ap
);
197 if (pattern
!= patBuffer
) {
204 U_CAPI
int32_t U_EXPORT2
205 u_vsprintf_u(UChar
*buffer
,
206 const UChar
*patternSpecification
,
209 return u_vsnprintf_u(buffer
, INT32_MAX
, patternSpecification
, ap
);
212 static const u_printf_stream_handler g_sprintf_stream_handler
= {
214 u_sprintf_pad_and_justify
217 U_CAPI
int32_t U_EXPORT2
/* U_CAPI ... U_EXPORT2 added by Peter Kirk 17 Nov 2001 */
218 u_vsnprintf_u(UChar
*buffer
,
220 const UChar
*patternSpecification
,
223 int32_t written
= 0; /* haven't written anything yet */
224 int32_t result
= 0; /* test the return value of u_printf_parse */
226 u_localized_print_string outStr
;
234 outStr
.available
= count
;
236 if(u_locbund_init(&outStr
.fBundle
, "en_US_POSIX") == 0) {
240 /* parse and print the whole format string */
241 result
= u_printf_parse(&g_sprintf_stream_handler
, patternSpecification
, &outStr
, &outStr
, &outStr
.fBundle
, &written
, ap
);
243 /* Terminate the buffer, if there's room. */
244 if (outStr
.available
> 0) {
245 buffer
[outStr
.len
- outStr
.available
] = 0x0000;
248 /* Release the cloned bundle, if we cloned it. */
249 u_locbund_close(&outStr
.fBundle
);
255 /* return # of UChars written */
259 #endif /* #if !UCONFIG_NO_FORMATTING */