aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2014-01-13 17:48:55 -0800
committerAlon Zakai <alonzakai@gmail.com>2014-01-15 11:26:48 -0800
commitc5522c645635939ac49e6cfecb02a64e768a76d6 (patch)
tree5fd14a6d41e4966b8c49480ef0913d4c03033264
parent3753753c60a0b2ecb7ebd0475408c02cfff4ec91 (diff)
add musl fputws, fix vswprintf, add testing for fwprintf and swprintf as well1.8.14
-rwxr-xr-xemcc1
-rw-r--r--system/lib/libc/musl/src/stdio/fputws.c30
-rw-r--r--system/lib/libc/musl/src/stdio/vswprintf.c17
-rw-r--r--tests/core/test_wprintf.c50
-rw-r--r--tests/core/test_wprintf.out35
-rw-r--r--tools/shared.py2
6 files changed, 133 insertions, 2 deletions
diff --git a/emcc b/emcc
index fa59c358..f425ff4d 100755
--- a/emcc
+++ b/emcc
@@ -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()