Skip to content

Conversation

@SaraBaradaran
Copy link

Functions wcstod(), wcstof(), and wcstold() convert a wide-character string into a double, float, and long double, respectively. Emscripten only supports wcstold() and I received the following errors when I compiled a code that calls two other functions:

  1. error: no member named 'wcstof_l' in the global namespace; did you mean 'wcstold_l'?
  2. error: no member named 'wcstod_l' in the global namespace; did you mean 'wcstold_l'?

This pull request adds two functions wcstod() and wcstof().

Add wcstod() and wcstof() functions for wide-character string to double and float conversion.
@sbc100
Copy link
Collaborator

sbc100 commented Jan 28, 2024

If we do want to add these function I think its the musl here where they should live (system/lib/libc/musl/include/wchar.h).

However it looks like the _l versions are windows only. They are not part of either musl or glibc as far as I can tell.

Do you know where the reference to wcstof_l is coming from? Is that code generally portable to non-windows targets?

@kangtastic
Copy link
Contributor

Just passing by, but locale-aware wcstoX_l versions of wcstoX aren't Windows-only. They're also present in glibc's <wchar.h> with __USE_GNU and on BSD/OSX in <xlocale.h>.

@sbc100
Copy link
Collaborator

sbc100 commented Jan 30, 2024

Just passing by, but locale-aware wcstoX_l versions of wcstoX aren't Windows-only. They're also present in glibc's <wchar.h> with __USE_GNU and on BSD/OSX in <xlocale.h>.

Oh I see, these are GNU extensions, but they don't exist in musl.

We could had them either directly to system/lib/libc/musl/include/wchar.h or too system/include/compat/wchar.h (which doesn't exist yet).

It looks like musl already implements some string functions that do take locale, so it should be easy enough to mimic those:

#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
size_t wcsftime_l (wchar_t *__restrict, size_t, const wchar_t *__restrict, const struct tm *__restrict, locale_t);
#endif
#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
|| defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
FILE *open_wmemstream(wchar_t **, size_t *);
size_t mbsnrtowcs(wchar_t *__restrict, const char **__restrict, size_t, size_t, mbstate_t *__restrict);
size_t wcsnrtombs(char *__restrict, const wchar_t **__restrict, size_t, size_t, mbstate_t *__restrict);
wchar_t *wcsdup(const wchar_t *);
size_t wcsnlen (const wchar_t *, size_t);
wchar_t *wcpcpy (wchar_t *__restrict, const wchar_t *__restrict);
wchar_t *wcpncpy (wchar_t *__restrict, const wchar_t *__restrict, size_t);
int wcscasecmp(const wchar_t *, const wchar_t *);
int wcscasecmp_l(const wchar_t *, const wchar_t *, locale_t);
int wcsncasecmp(const wchar_t *, const wchar_t *, size_t);
int wcsncasecmp_l(const wchar_t *, const wchar_t *, size_t, locale_t);
int wcscoll_l(const wchar_t *, const wchar_t *, locale_t);
size_t wcsxfrm_l(wchar_t *__restrict, const wchar_t *__restrict, size_t, locale_t);

@kangtastic
Copy link
Contributor

kangtastic commented Jan 30, 2024

Yes, I didn't mean to imply they weren't vendor extensions. It seems like they'd be best placed in musl upstream, but small libc's never implement "proper" locale support due to the added code size/maintenance burden, and, well, they kinda have a point 🤷

As I understand it, implementing these as thin wrappers over their non-_l counterparts means only "123,456.789"L and not e.g. "123.456,789"L or "1,23,456.789"L are parsed to 123456.789. But that's probably good enough without the aforementioned "proper" locale support.

@sbc100
Copy link
Collaborator

sbc100 commented Jan 30, 2024

@SaraBaradaran could you update this PR to modify system/lib/libc/musl/include/wchar.h instead? (or create a new system/include/compat/wchar.h)?

@SaraBaradaran
Copy link
Author

@SaraBaradaran could you update this PR to modify system/lib/libc/musl/include/wchar.h instead? (or create a new system/include/compat/wchar.h)?

Sure!

@SaraBaradaran
Copy link
Author

SaraBaradaran commented Jan 31, 2024

Currently, wcstold_l is defined in system/lib/libcxx/include/__support/musl/xlocale.h, but wcstof_l and wcstod_l do not exist. So, we should also remove wcstold_l from xlocale.h and transfer it to system/lib/libc/musl/include/wchar.h or to system/include/compat/wchar.h as you mentioned. Otherwise, there will be a kind of inconsistency.
Also, the first time I encountered this problem was when I compiled https://github.com/eliaskosunen/scnlib using Emscripten. If you look at /scnlib/src/scn/impl/reader/float_reader.cpp they are using xlocale.h. So, for projects like this, if we define these functions only in wchar.h they still could not be compiled. What do you think in this case?

@sbc100
Copy link
Collaborator

sbc100 commented Jan 31, 2024

Ah, so perhaps the best place would be to put them in ./system/include/compat/xlocale.h?

I'm a little confused how this works on glibc BTW, since glibc doesn't seem to have xlocale.h at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants