-
Notifications
You must be signed in to change notification settings - Fork 576
Fix langinfo(ALT_DIGITS) #21833
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix langinfo(ALT_DIGITS) #21833
Conversation
d4df740
to
9e7376a
Compare
I found https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html when looking today:
though glibc doesn't follow this. (I don't expect any action on this comment) |
I changed the comments in |
This and the next commit fix the incorrect behavior that perl has always had for nl_langinfo(ALT_DIGITS). If there are no alternate digits, an empty string is returned by nl_langinfo when there are no such alternate digits. This should also be the case on platforms where we emulate nl_langinfo, but instead "0" was being returned. This commit makes things consistent. The next commit adds tests
This has never worked properly before in Perl. The code is returning the result of the libc function nl_langinfo(). The documentation for it that I have found (and presumably my predecessors) is very unclear. But what actually happens (from using gdb) is that the return is very C unfriendly. Instead of returning a NUL-terminated string, it returns 100 (perhaps fewer) NUL-terminated strings in a row. When it is fewer (given the few examples I've seen), the final one ends with two NULs in a row. (I can't think of a way for it to work and be otherwise). The 100th one doesn't necessarily have two terminating NULs. Prior to this commit, only the string for the zeroth digit was returned; now the entire ALT_DIGIT string sequence is returned, forcing a double NUL at the end of the final one. This information is accessible in several ways. Via XS, one can use any of several functions, including the newly introduced sv_langinfo(), returning an SV, which allows for easier handling of embedded NULs. (Otherwise in XS, using the functions that return a char*, one has to look for the double-NUL.) From Perl-space, the access is via I18N::Langinfo, which behind the scenes also uses an SV. The documentation added in this commit gives advice for how to turn the return into an @array for more convenient access.
The glibc ALT_DIGITS bug is mentioned in passing here though this mostly talks about a similar bug with ERA. |
This has never worked properly before in Perl. The code is returning
the result of the libc function nl_langinfo(). The documentation for it
that I have found (and presumably my predecessors) is very unclear. But
what actually happens (from using gdb) is that the return is very C
unfriendly.
Instead of returning a NUL-terminated string, it returns 100 (perhaps
fewer) NUL-terminated strings in a row. When it is fewer (given the
few examples I've seen), the final one ends with two NULs in a row. (I
can't think of a way for it to work and be otherwise). The 100th one
doesn't necessarily have two terminating NULs.
Prior to this commit, only the string for the zeroth digit was returned;
now the entire ALT_DIGIT string sequence is returned, forcing a double
NUL at the end of the final one.
This information is accessible in several ways. Via XS, one can use any
of several functions, including the newly introduced sv_langinfo(),
returning an SV, which allows for easier handling of embedded NULs.
(Otherwise in XS, using the functions that return a char*, one has to
look for the double-NUL.)
From Perl-space, the access is via I18N::Langinfo, which behind the
scenes also uses an SV. The documentation added in this commit gives
advice for how to turn the return into an
@array
for more convenientaccess.