aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemcc1
-rw-r--r--src/library.js6
-rw-r--r--system/lib/libc/musl/readme.txt3
-rw-r--r--system/lib/libc/musl/src/internal/stdio_impl.h6
-rw-r--r--system/lib/libc/musl/src/stdio/fputwc.c39
-rw-r--r--tests/core/test_wprintf.c15
-rw-r--r--tests/core/test_wprintf.out8
-rw-r--r--tests/test_core.py6
-rw-r--r--tools/shared.py2
9 files changed, 84 insertions, 2 deletions
diff --git a/emcc b/emcc
index 4d6b8a73..8bfa0942 100755
--- a/emcc
+++ b/emcc
@@ -1593,6 +1593,7 @@ try:
'vswprintf.c',
'vwprintf.c',
'wprintf.c',
+ 'fputwc.c',
]],
['stdlib', [
'ecvt.c',
diff --git a/src/library.js b/src/library.js
index c41a8cda..69569601 100644
--- a/src/library.js
+++ b/src/library.js
@@ -9172,6 +9172,10 @@ LibraryManager.library = {
tempRet0 = 0;
return (high >>> (bits - 32))|0;
},
+
+ // misc shims for musl
+ __lockfile: function() { return 1 },
+ __unlockfile: function(){},
};
function autoAddDeps(object, name) {
@@ -9184,7 +9188,7 @@ function autoAddDeps(object, name) {
}
// Add aborting stubs for various libc stuff needed by libc++
-['pthread_cond_signal', 'pthread_equal', 'pthread_join', 'pthread_detach', 'catgets', 'catopen', 'catclose', 'fputwc', '__lockfile', '__unlockfile'].forEach(function(aborter) {
+['pthread_cond_signal', 'pthread_equal', 'pthread_join', 'pthread_detach', 'catgets', 'catopen', 'catclose'].forEach(function(aborter) {
LibraryManager.library[aborter] = function aborting_stub() { throw 'TODO: ' + aborter };
});
diff --git a/system/lib/libc/musl/readme.txt b/system/lib/libc/musl/readme.txt
index 9ca04036..5e6f8389 100644
--- a/system/lib/libc/musl/readme.txt
+++ b/system/lib/libc/musl/readme.txt
@@ -7,3 +7,6 @@ Differences from upstream musl include:
ino_t, dev_t, blkcnt_t, fsblkcnt_t, fsfilcnt_t, rlim_t.
* We don't define _POSIX_SHARED_MEMORY_OBJECTS.
* We flag __assert_fail as _Noreturn.
+* Disable FLOCK, FUNLOCK and FFINALLOCK
+* Simplify fputwc to not rely on musl stream internals
+
diff --git a/system/lib/libc/musl/src/internal/stdio_impl.h b/system/lib/libc/musl/src/internal/stdio_impl.h
index 2083b2fe..6bcd44dc 100644
--- a/system/lib/libc/musl/src/internal/stdio_impl.h
+++ b/system/lib/libc/musl/src/internal/stdio_impl.h
@@ -7,9 +7,15 @@
#define UNGET 8
+#if 1 // XXX EMSCRIPTEN
+#define FFINALLOCK(f) 0
+#define FLOCK(f) 0
+#define FUNLOCK(f) 0
+#else
#define FFINALLOCK(f) ((f)->lock>=0 ? __lockfile((f)) : 0)
#define FLOCK(f) int __need_unlock = ((f)->lock>=0 ? __lockfile((f)) : 0)
#define FUNLOCK(f) if (__need_unlock) __unlockfile((f)); else
+#endif
#define F_PERM 1
#define F_NORD 4
diff --git a/system/lib/libc/musl/src/stdio/fputwc.c b/system/lib/libc/musl/src/stdio/fputwc.c
new file mode 100644
index 00000000..11db2804
--- /dev/null
+++ b/system/lib/libc/musl/src/stdio/fputwc.c
@@ -0,0 +1,39 @@
+#include "stdio_impl.h"
+#include <wchar.h>
+#include <limits.h>
+#include <ctype.h>
+
+wint_t __fputwc_unlocked(wchar_t c, FILE *f)
+{
+ char mbc[MB_LEN_MAX];
+ int l;
+
+ f->mode |= f->mode+1;
+
+ if (isascii(c)) {
+#if 0 // XXX EMSCRIPTEN
+ c = putc_unlocked(c, f);
+ } else if (f->wpos + MB_LEN_MAX < f->wend) {
+ l = wctomb((void *)f->wpos, c);
+ if (l < 0) c = WEOF;
+ else f->wpos += l;
+#else
+ c = fputc(c, f);
+#endif
+ } else {
+ l = wctomb(mbc, c);
+ if (l < 0 || __fwritex((void *)mbc, l, f) < l) c = WEOF;
+ }
+ return c;
+}
+
+wint_t fputwc(wchar_t c, FILE *f)
+{
+ FLOCK(f);
+ c = __fputwc_unlocked(c, f);
+ FUNLOCK(f);
+ return c;
+}
+
+weak_alias(__fputwc_unlocked, fputwc_unlocked);
+weak_alias(__fputwc_unlocked, putwc_unlocked);
diff --git a/tests/core/test_wprintf.c b/tests/core/test_wprintf.c
new file mode 100644
index 00000000..e938bf69
--- /dev/null
+++ b/tests/core/test_wprintf.c
@@ -0,0 +1,15 @@
+#include <wchar.h>
+
+int main()
+{
+ 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);
+ wprintf (L"Preceding with zeros: %010d \n", 1977);
+ wprintf (L"Some different radixes: %d %x %o %#x %#o \n", 100, 100, 100, 100, 100);
+ 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");
+ return 0;
+}
+
diff --git a/tests/core/test_wprintf.out b/tests/core/test_wprintf.out
new file mode 100644
index 00000000..f85abebb
--- /dev/null
+++ b/tests/core/test_wprintf.out
@@ -0,0 +1,8 @@
+Characters: a A
+Decimals: 1977 650000
+Preceding with blanks: 1977
+Preceding with zeros: 0000001977
+Some different radixes: 100 64 144 0x64 0144
+floats: 3.14 +3e+00 3.141600E+00
+Width trick: 10
+A wide string
diff --git a/tests/test_core.py b/tests/test_core.py
index c89e785e..d7bebdc6 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -4090,6 +4090,12 @@ def process(filename):
self.do_run(open(path_from_root('tests', 'utf32.cpp')).read(), 'OK.')
self.do_run(open(path_from_root('tests', 'utf32.cpp')).read(), 'OK.', args=['-fshort-wchar'])
+ def test_wprintf(self):
+ if self.emcc_args is None: return self.skip('requires libcxx')
+ test_path = path_from_root('tests', 'core', 'test_wprintf')
+ src, output = (test_path + s for s in ('.c', '.out'))
+ self.do_run_from_file(src, output)
+
def test_direct_string_constant_usage(self):
if self.emcc_args is None: return self.skip('requires libcxx')
diff --git a/tools/shared.py b/tools/shared.py
index 32f8f797..5f7e591c 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.8'
+EMSCRIPTEN_VERSION = '1.8.9'
def generate_sanity():
return EMSCRIPTEN_VERSION + '|' + get_llvm_target() + '|' + LLVM_ROOT + '|' + get_clang_version()