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
 #include <stdarg.h>
22
 #include <stdarg.h>
23
 #include <stdio.h>
23
 #include <stdio.h>
24
 #include <errno.h>
24
 #include <errno.h>
25
+#include <wchar.h>
25
 #include <ipxe/vsprintf.h>
26
 #include <ipxe/vsprintf.h>
26
 
27
 
27
 /** @file */
28
 /** @file */
185
 	char *ptr;
186
 	char *ptr;
186
 	char tmp_buf[32]; /* 32 is enough for all numerical formats.
187
 	char tmp_buf[32]; /* 32 is enough for all numerical formats.
187
 			   * Insane width fields could overflow this buffer. */
188
 			   * Insane width fields could overflow this buffer. */
189
+	wchar_t *wptr;
188
 
190
 
189
 	/* Initialise context */
191
 	/* Initialise context */
190
 	ctx->len = 0;
192
 	ctx->len = 0;
234
 		/* Process conversion specifier */
236
 		/* Process conversion specifier */
235
 		ptr = tmp_buf + sizeof ( tmp_buf ) - 1;
237
 		ptr = tmp_buf + sizeof ( tmp_buf ) - 1;
236
 		*ptr = '\0';
238
 		*ptr = '\0';
239
+		wptr = NULL;
237
 		if ( *fmt == 'c' ) {
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
 		} else if ( *fmt == 's' ) {
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
 				ptr = "<NULL>";
259
 				ptr = "<NULL>";
243
 		} else if ( *fmt == 'p' ) {
260
 		} else if ( *fmt == 'p' ) {
244
 			intptr_t ptrval;
261
 			intptr_t ptrval;
271
 			*(--ptr) = *fmt;
288
 			*(--ptr) = *fmt;
272
 		}
289
 		}
273
 		/* Write out conversion result */
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
 #define __WCHAR_TYPE__ long int
26
 #define __WCHAR_TYPE__ long int
27
 #endif
27
 #endif
28
 typedef __WCHAR_TYPE__ wchar_t;
28
 typedef __WCHAR_TYPE__ wchar_t;
29
+typedef __WINT_TYPE__ wint_t;
29
 
30
 
30
 #endif /* STDDEF_H */
31
 #endif /* STDDEF_H */

Loading…
Cancel
Save