diff options
author | Alon Zakai <alonzakai@gmail.com> | 2014-01-13 17:48:55 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2014-01-15 11:26:48 -0800 |
commit | c5522c645635939ac49e6cfecb02a64e768a76d6 (patch) | |
tree | 5fd14a6d41e4966b8c49480ef0913d4c03033264 | |
parent | 3753753c60a0b2ecb7ebd0475408c02cfff4ec91 (diff) |
add musl fputws, fix vswprintf, add testing for fwprintf and swprintf as well1.8.14
-rwxr-xr-x | emcc | 1 | ||||
-rw-r--r-- | system/lib/libc/musl/src/stdio/fputws.c | 30 | ||||
-rw-r--r-- | system/lib/libc/musl/src/stdio/vswprintf.c | 17 | ||||
-rw-r--r-- | tests/core/test_wprintf.c | 50 | ||||
-rw-r--r-- | tests/core/test_wprintf.out | 35 | ||||
-rw-r--r-- | tools/shared.py | 2 |
6 files changed, 133 insertions, 2 deletions
@@ -1595,6 +1595,7 @@ try: 'vwprintf.c', 'wprintf.c', 'fputwc.c', + 'fputws.c', ]], ['stdlib', [ 'ecvt.c', diff --git a/system/lib/libc/musl/src/stdio/fputws.c b/system/lib/libc/musl/src/stdio/fputws.c new file mode 100644 index 00000000..70e004c9 --- /dev/null +++ b/system/lib/libc/musl/src/stdio/fputws.c @@ -0,0 +1,30 @@ +#include "stdio_impl.h" +#include <wchar.h> + +int fputws(const wchar_t *restrict ws, FILE *restrict f) +{ + unsigned char buf[BUFSIZ]; + size_t l=0; + + FLOCK(f); + +#if 0 // XXX EMSCRIPTEN + f->mode |= f->mode+1; +#endif + + while (ws && (l = wcsrtombs((void *)buf, (void*)&ws, sizeof buf, 0))+1 > 1) +#if 0 // XXX EMSCRIPTEN + if (__fwritex(buf, l, f) < l) { +#else + if (fwrite(buf, 1, l, f) < l) { +#endif + FUNLOCK(f); + return -1; + } + + FUNLOCK(f); + + return l; /* 0 or -1 */ +} + +weak_alias(fputws, fputws_unlocked); diff --git a/system/lib/libc/musl/src/stdio/vswprintf.c b/system/lib/libc/musl/src/stdio/vswprintf.c index 7d237bae..e906f7ae 100644 --- a/system/lib/libc/musl/src/stdio/vswprintf.c +++ b/system/lib/libc/musl/src/stdio/vswprintf.c @@ -29,6 +29,7 @@ static size_t sw_write(FILE *f, const unsigned char *s, size_t l) int vswprintf(wchar_t *restrict s, size_t n, const wchar_t *restrict fmt, va_list ap) { +#if 0 // XXX EMSCRIPTEN int r; FILE f; unsigned char buf[256]; @@ -50,4 +51,20 @@ int vswprintf(wchar_t *restrict s, size_t n, const wchar_t *restrict fmt, va_lis r = vfwprintf(&f, fmt, ap); sw_write(&f, 0, 0); return r>=n ? -1 : r; +#else + // XXX EMSCRIPTEN: use memfs through libc fs + // we write to a file, which is in multibyte, then we read, then expand to widechar + #define TEMPFILE "emscripten.vswprintf.temp.buffer" + FILE *f = fopen(TEMPFILE, "wb"); + int r = vfwprintf(f, fmt, ap); + fclose(f); + f = fopen(TEMPFILE, "rb"); + char buffer[r+1]; + fread(buffer, 1, r, f); + fclose(f); + remove(TEMPFILE); + buffer[r] = 0; + r = mbstowcs(s, buffer, n); + return r>=n ? -1 : r; +#endif } diff --git a/tests/core/test_wprintf.c b/tests/core/test_wprintf.c index e938bf69..b5f8d6ab 100644 --- a/tests/core/test_wprintf.c +++ b/tests/core/test_wprintf.c @@ -1,7 +1,44 @@ +#include <stdio.h> +#include <string.h> +#include <stdarg.h> #include <wchar.h> -int main() +void PrintWide ( const wchar_t * format, ... ) { + wchar_t buffer[256]; + memset(buffer, 0, 256); + va_list args; + va_start ( args, format ); + wprintf(L"format starts with 0x%x\n", *(int*)format); + wprintf(L"fmt continues with 0x%x\n", *(((int*)format) + 1)); + wprintf(L"fmt continues with 0x%x\n", *(((int*)format) + 2)); + int r = vswprintf ( buffer, 256, format, args ); + wprintf(L"vswprintf told us %d\n", r); + wprintf(L"vswoutput st-rts with 0x%x\n", *(int*)buffer); + wprintf(L"vsw continues with 0x%x\n", *(((int*)buffer) + 1)); + wprintf(L"vsw continues with 0x%x\n", *(((int*)buffer) + 2)); + wprintf(buffer); + va_end ( args ); +} + +int main () +{ + FILE *f = fopen("test.dat", "wb"); + int num = fwprintf(f, L"hello %d", 5); + wprintf(L"fwprintf told us %d\n", num); + fclose(f); + f = fopen("test.dat", "rb"); + fseek(f, 0, SEEK_END); + int size = ftell(f); + fclose(f); + wprintf(L"file size is %d\n", size); + + wchar_t str[] = L"test string has %d wide characters.\n"; + wprintf(L"str starts with 0x%x\n", *(int*)str); + wprintf(L"str continues with 0x%x\n", *(((int*)str) + 1)); + wprintf(L"str continues with 0x%x\n", *(((int*)str) + 2)); + PrintWide ( str, wcslen(str) ); + wprintf (L"Characters: %lc %lc \n", L'a', 65); wprintf (L"Decimals: %d %ld\n", 1977, 650000L); wprintf (L"Preceding with blanks: %10d \n", 1977); @@ -10,6 +47,17 @@ int main() wprintf (L"floats: %4.2f %+.0e %E \n", 3.1416, 3.1416, 3.1416); wprintf (L"Width trick: %*d \n", 5, 10); wprintf (L"%ls \n", L"A wide string"); + + wchar_t buffer [100]; + memset(buffer, 0, sizeof(buffer)); + int cx; + cx = swprintf(buffer, 100, L"The half of %d is %d", 80, 80/2); + wprintf(L"swprintf told us %d\n", cx); + for (int i = 0; i < 10; i++) wprintf(L"pre %d\n", ((int*)buffer)[i]); + swprintf (buffer+cx, 100-cx-1, L", and the half of that is %d.\n", 80/2/2); + for (int i = 0; i < 10; i++) wprintf(L"post %d\n", ((int*)buffer)[i]); + wprintf(buffer); + return 0; } diff --git a/tests/core/test_wprintf.out b/tests/core/test_wprintf.out index f85abebb..e074743d 100644 --- a/tests/core/test_wprintf.out +++ b/tests/core/test_wprintf.out @@ -1,3 +1,16 @@ +fwprintf told us 7 +file size is 7 +str starts with 0x74 +str continues with 0x65 +str continues with 0x73 +format starts with 0x74 +fmt continues with 0x65 +fmt continues with 0x73 +vswprintf told us 36 +vswoutput st-rts with 0x74 +vsw continues with 0x65 +vsw continues with 0x73 +test string has 36 wide characters. Characters: a A Decimals: 1977 650000 Preceding with blanks: 1977 @@ -6,3 +19,25 @@ Some different radixes: 100 64 144 0x64 0144 floats: 3.14 +3e+00 3.141600E+00 Width trick: 10 A wide string +swprintf told us 20 +pre 84 +pre 104 +pre 101 +pre 32 +pre 104 +pre 97 +pre 108 +pre 102 +pre 32 +pre 111 +post 84 +post 104 +post 101 +post 32 +post 104 +post 97 +post 108 +post 102 +post 32 +post 111 +The half of 80 is 40, and the half of that is 20. diff --git a/tools/shared.py b/tools/shared.py index 68b037f6..6e74227a 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -345,7 +345,7 @@ def find_temp_directory(): # we re-check sanity when the settings are changed) # We also re-check sanity and clear the cache when the version changes -EMSCRIPTEN_VERSION = '1.8.13' +EMSCRIPTEN_VERSION = '1.8.14' def generate_sanity(): return EMSCRIPTEN_VERSION + '|' + get_llvm_target() + '|' + LLVM_ROOT + '|' + get_clang_version() |