|
@@ -22,6 +22,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
22
|
22
|
#include <stdarg.h>
|
23
|
23
|
#include <stdio.h>
|
24
|
24
|
#include <errno.h>
|
|
25
|
+#include <wchar.h>
|
25
|
26
|
#include <ipxe/vsprintf.h>
|
26
|
27
|
|
27
|
28
|
/** @file */
|
|
@@ -185,6 +186,7 @@ size_t vcprintf ( struct printf_context *ctx, const char *fmt, va_list args ) {
|
185
|
186
|
char *ptr;
|
186
|
187
|
char tmp_buf[32]; /* 32 is enough for all numerical formats.
|
187
|
188
|
* Insane width fields could overflow this buffer. */
|
|
189
|
+ wchar_t *wptr;
|
188
|
190
|
|
189
|
191
|
/* Initialise context */
|
190
|
192
|
ctx->len = 0;
|
|
@@ -234,11 +236,26 @@ size_t vcprintf ( struct printf_context *ctx, const char *fmt, va_list args ) {
|
234
|
236
|
/* Process conversion specifier */
|
235
|
237
|
ptr = tmp_buf + sizeof ( tmp_buf ) - 1;
|
236
|
238
|
*ptr = '\0';
|
|
239
|
+ wptr = NULL;
|
237
|
240
|
if ( *fmt == 'c' ) {
|
238
|
|
- cputchar ( ctx, va_arg ( args, unsigned int ) );
|
|
241
|
+ if ( length < &type_sizes[LONG_LEN] ) {
|
|
242
|
+ cputchar ( ctx, va_arg ( args, unsigned int ) );
|
|
243
|
+ } else {
|
|
244
|
+ wchar_t wc;
|
|
245
|
+ size_t len;
|
|
246
|
+
|
|
247
|
+ wc = va_arg ( args, wint_t );
|
|
248
|
+ len = wcrtomb ( tmp_buf, wc, NULL );
|
|
249
|
+ tmp_buf[len] = '\0';
|
|
250
|
+ ptr = tmp_buf;
|
|
251
|
+ }
|
239
|
252
|
} else if ( *fmt == 's' ) {
|
240
|
|
- ptr = va_arg ( args, char * );
|
241
|
|
- if ( ! ptr )
|
|
253
|
+ if ( length < &type_sizes[LONG_LEN] ) {
|
|
254
|
+ ptr = va_arg ( args, char * );
|
|
255
|
+ } else {
|
|
256
|
+ wptr = va_arg ( args, wchar_t * );
|
|
257
|
+ }
|
|
258
|
+ if ( ( ptr == NULL ) && ( wptr == NULL ) )
|
242
|
259
|
ptr = "<NULL>";
|
243
|
260
|
} else if ( *fmt == 'p' ) {
|
244
|
261
|
intptr_t ptrval;
|
|
@@ -271,8 +288,17 @@ size_t vcprintf ( struct printf_context *ctx, const char *fmt, va_list args ) {
|
271
|
288
|
*(--ptr) = *fmt;
|
272
|
289
|
}
|
273
|
290
|
/* Write out conversion result */
|
274
|
|
- for ( ; *ptr ; ptr++ ) {
|
275
|
|
- cputchar ( ctx, *ptr );
|
|
291
|
+ if ( wptr == NULL ) {
|
|
292
|
+ for ( ; *ptr ; ptr++ ) {
|
|
293
|
+ cputchar ( ctx, *ptr );
|
|
294
|
+ }
|
|
295
|
+ } else {
|
|
296
|
+ for ( ; *wptr ; wptr++ ) {
|
|
297
|
+ size_t len = wcrtomb ( tmp_buf, *wptr, NULL );
|
|
298
|
+ for ( ptr = tmp_buf ; len-- ; ptr++ ) {
|
|
299
|
+ cputchar ( ctx, *ptr );
|
|
300
|
+ }
|
|
301
|
+ }
|
276
|
302
|
}
|
277
|
303
|
}
|
278
|
304
|
|