Skip to content

Commit

Permalink
add musl fputws, fix vswprintf, add testing for fwprintf and swprintf…
Browse files Browse the repository at this point in the history
… as well
  • Loading branch information
kripken committed Jan 15, 2014
1 parent 3753753 commit c5522c6
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 2 deletions.
1 change: 1 addition & 0 deletions emcc
Original file line number Diff line number Diff line change
Expand Up @@ -1595,6 +1595,7 @@ try:
'vwprintf.c',
'wprintf.c',
'fputwc.c',
'fputws.c',
]],
['stdlib', [
'ecvt.c',
Expand Down
30 changes: 30 additions & 0 deletions system/lib/libc/musl/src/stdio/fputws.c
Original file line number Diff line number Diff line change
@@ -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);
17 changes: 17 additions & 0 deletions system/lib/libc/musl/src/stdio/vswprintf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand All @@ -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
}
50 changes: 49 additions & 1 deletion tests/core/test_wprintf.c
Original file line number Diff line number Diff line change
@@ -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);
Expand All @@ -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;
}

35 changes: 35 additions & 0 deletions tests/core/test_wprintf.out
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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.
2 changes: 1 addition & 1 deletion tools/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down

0 comments on commit c5522c6

Please sign in to comment.