Browse Source

[libc] Add support for "%lc" and "%ls" format specifiers

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 years ago
parent
commit
58ed3b1cee
2 changed files with 32 additions and 5 deletions
  1. 31
    5
      src/core/vsprintf.c
  2. 1
    0
      src/include/stddef.h

+ 31
- 5
src/core/vsprintf.c View File

@@ -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
 

+ 1
- 0
src/include/stddef.h View File

@@ -26,5 +26,6 @@ FILE_LICENCE ( GPL2_ONLY );
26 26
 #define __WCHAR_TYPE__ long int
27 27
 #endif
28 28
 typedef __WCHAR_TYPE__ wchar_t;
29
+typedef __WINT_TYPE__ wint_t;
29 30
 
30 31
 #endif /* STDDEF_H */

Loading…
Cancel
Save