In perl.git, the branch blead has been updated

<https://perl5.git.perl.org/perl.git/commitdiff/8d72e74e3dc5017c5a3fade48e0c74109c297ebc?hp=5d70f8f9a94124c9e77138d92611f5765f8793ad>

- Log -----------------------------------------------------------------
commit 8d72e74e3dc5017c5a3fade48e0c74109c297ebc
Author: Karl Williamson <k...@cpan.org>
Date:   Thu Mar 8 13:00:40 2018 -0700

    Langinfo: Implement CODESET on Windows
    
    This applies to I18N::Langinfo, and the API function Perl_langinfo.
    Windows doesn't have nl_langinfo, so an emulation is used.  It turns out
    that it is easy to emulate the behavior for the CODESET item on Windows,
    as that vendor has kept things consistent.

commit 472be41b7bb1dab634c9b2b1655a206eea17f7d6
Author: Karl Williamson <k...@cpan.org>
Date:   Wed Mar 7 22:48:55 2018 -0700

    PATCH: [perl #127288] I18N::Langinfo sets UTF-8 bit
    
    This commit will turn UTF-8 on in the returned SV if its string is legal
    UTF-8 containing something besides ASCII, and the locale is a UTF-8 one.
    It is based on the patch included in the ticket, but is generalized to
    handle edge cases.

commit 13a5f6feb6a027d1f26e17b55ba95120cacaf024
Author: Karl Williamson <k...@cpan.org>
Date:   Wed Mar 7 12:04:00 2018 -0700

    I18N::Langinfo: fix pod nits
    
    Removing trailing space; fix typo, clarify

commit c3997e39b6a1f4b4b51aa6f192c7d5f1be7d711b
Author: Karl Williamson <k...@cpan.org>
Date:   Wed Mar 7 12:11:26 2018 -0700

    perlapi: Clarifications to Perl_langinfo

commit 6201c2203671c3e78f25fa02205bd962d5bd92b1
Author: Karl Williamson <k...@cpan.org>
Date:   Thu Mar 8 10:59:53 2018 -0700

    Actually make I18N::Langinfo avail on all platforms
    
    I thought I had done this earlier, but testing on Windows demonstrated
    that I hadn't.
    
    While at it, move the details in the docs for Perl_langinfo to the
    module's pod.
    
    This doesn't follow the paradigm for putting the Configure stuff in all
    the related configure files, but I saw no point to doing so.  If you are
    reading this because I was wrong, feel free to ticket it or fix it.

commit 4e6826bf86819426cea8be0677b2a3282834ced5
Author: Karl Williamson <k...@cpan.org>
Date:   Thu Mar 8 10:51:09 2018 -0700

    Change enum names for new locale function parameters
    
    Earlier in the 5.27 series, I introduced Perl_langinfo which calls
    the system nl_langinfo() on platforms that have it, and emulates it
    otherwise.  For each enum parameter 'foo', I made an equivalent
    parameter PERL_foo.  I did this so that no conflicts would arise if
    any 'foo' were negative.  This is less than ideal to have to rename the
    parameters.
    
    In looking further, I realized that perl has always excluded the
    possibility of negative values for 'foo', so my precaution is
    unnecessary.  And before this new code is released is the time to fix up
    the interface.

commit 4806e6cd41dafb8b1e990f0c6d1d5ff8b3f64fb6
Author: Karl Williamson <k...@cpan.org>
Date:   Wed Mar 7 12:08:01 2018 -0700

    APItest/t/locale.t: Store hash return for readability

commit cb2a626de53c9b7ef6e1cfa9eda8939968d486ec
Author: Karl Williamson <k...@cpan.org>
Date:   Wed Mar 7 12:05:46 2018 -0700

    APItest/t/locale.t: Sort some tests
    
    These now appear in the file in their logical order

-----------------------------------------------------------------------

Summary of changes:
 Configure                      |   8 +-
 README.symbian                 |   2 +-
 embed.fnc                      |   3 +-
 embed.h                        |   2 +-
 ext/I18N-Langinfo/Langinfo.pm  | 104 ++++++++--
 ext/I18N-Langinfo/Langinfo.xs  |  76 ++++++-
 ext/I18N-Langinfo/t/Langinfo.t |  80 ++++++-
 ext/XS-APItest/t/locale.t      |  24 +--
 locale.c                       | 323 ++++++++++++++---------------
 perl_langinfo.h                | 459 +++++++++++++++--------------------------
 pod/perldelta.pod              |  16 +-
 proto.h                        |   2 +-
 symbian/install.cfg            |   2 +-
 win32/FindExt.pm               |   3 +-
 14 files changed, 601 insertions(+), 503 deletions(-)

diff --git a/Configure b/Configure
index 135ba4e8b8..e7c61871d6 100755
--- a/Configure
+++ b/Configure
@@ -229,6 +229,7 @@ extensions=''
 known_extensions=''
 nonxs_ext=''
 static_ext=''
+usei18n_lang=''
 useopcode=''
 useposix=''
 extras=''
@@ -1464,6 +1465,8 @@ ignore_versioned_solibs=''
 ccname=''
 ccversion=''
 perllibs=''
+: set usei18n_lang=false in your hint file to disable the I18N_Langinfo 
extension.
+usei18n_lang=true
 : set useposix=false in your hint file to disable the POSIX extension.
 useposix=true
 : set useopcode=false in your hint file to disable the Opcode extension.
@@ -23273,8 +23276,8 @@ for xxx in $xs_extensions ; do
                esac
                ;;
        I18N/Langinfo|i18n_lan)
-               case "$i_langinfo$d_nl_langinfo" in
-               $define$define) avail_ext="$avail_ext $xxx" ;;
+               case "$usei18n_lang" in
+               true|define|y) avail_ext="$avail_ext $xxx" ;;
                esac
                ;;
        IPC/SysV|ipc/sysv)
@@ -24820,6 +24823,7 @@ usedevel='$usedevel'
 usedl='$usedl'
 usedtrace='$usedtrace'
 usefaststdio='$usefaststdio'
+usei18n_lang='$i18n_lang'
 useithreads='$useithreads'
 usekernprocpathname='$usekernprocpathname'
 uselargefiles='$uselargefiles'
diff --git a/README.symbian b/README.symbian
index c111f30391..cb4a42ff94 100644
--- a/README.symbian
+++ b/README.symbian
@@ -367,7 +367,7 @@ The Symbian port is licensed under the same terms as Perl 
itself.
  - The following extensions are missing for various technical
    reasons:
    B ByteLoader Devel::DProf Devel::PPPort Encode GDBM_File
-   I18N::Langinfo IPC::SysV NDBM_File Opcode PerlIO::encoding POSIX
+   IPC::SysV NDBM_File Opcode PerlIO::encoding POSIX
    re Safe Sys::Hostname Sys::Syslog
    threads threads::shared Unicode::Normalize
  - Using MakeMaker or the Module::* to build and install modules
diff --git a/embed.fnc b/embed.fnc
index 6c4f859583..5adc705e4a 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -2831,7 +2831,8 @@ snR       |char * |setlocale_debug_string |const int 
category                 \
 #if        defined(USE_LOCALE)         \
     && (   defined(PERL_IN_LOCALE_C)   \
         || defined(PERL_IN_MG_C)       \
-       || defined (PERL_EXT_POSIX))
+       || defined (PERL_EXT_POSIX)     \
+       || defined (PERL_EXT_LANGINFO))
 ApM    |bool   |_is_cur_LC_category_utf8|int category
 #endif
 
diff --git a/embed.h b/embed.h
index 9bc1fdb3cc..b95410ce2e 100644
--- a/embed.h
+++ b/embed.h
@@ -877,7 +877,7 @@
 #define sv_dup(a,b)            Perl_sv_dup(aTHX_ a,b)
 #define sv_dup_inc(a,b)                Perl_sv_dup_inc(aTHX_ a,b)
 #endif
-#if defined(USE_LOCALE)                    && (   defined(PERL_IN_LOCALE_C)    
        || defined(PERL_IN_MG_C)                || defined (PERL_EXT_POSIX))
+#if defined(USE_LOCALE)                    && (   defined(PERL_IN_LOCALE_C)    
        || defined(PERL_IN_MG_C)                || defined (PERL_EXT_POSIX)     
        || defined (PERL_EXT_LANGINFO))
 #define _is_cur_LC_category_utf8(a)    Perl__is_cur_LC_category_utf8(aTHX_ a)
 #endif
 #if defined(USE_LOCALE_COLLATE)
diff --git a/ext/I18N-Langinfo/Langinfo.pm b/ext/I18N-Langinfo/Langinfo.pm
index 7a7005f7ab..e9e84d28c2 100644
--- a/ext/I18N-Langinfo/Langinfo.pm
+++ b/ext/I18N-Langinfo/Langinfo.pm
@@ -72,7 +72,7 @@ our @EXPORT_OK = qw(
        YESSTR
 );
 
-our $VERSION = '0.15';
+our $VERSION = '0.16';
 
 XSLoader::load();
 
@@ -113,11 +113,11 @@ answers for a yes/no question in the current locale.
 In other words, in the "C" (or English) locale the above will probably
 print something like:
 
-    Sun? [yes/no] 
+    Sun? [yes/no]
 
 but under a French locale
 
-    dim? [oui/non] 
+    dim? [oui/non]
 
 The usually available constants are
 
@@ -140,12 +140,17 @@ for the date-time, date, and time formats used by the 
strftime() function
 for the locales for which it makes sense to have ante meridiem and post
 meridiem time formats,
 
-    CODESET CRNCYSTR RADIXCHAR
+    CODESET CRNCYSTR
 
 for the character code set being used (such as "ISO8859-1", "cp850",
-"koi8-r", "sjis", "utf8", etc.), for the currency string, for the
+"koi8-r", "sjis", "utf8", etc.), for the currency string
+
+    ALT_DIGITS RADIXCHAR THOUSEP
+
+for an alternate representation of digits, for the
 radix character used between the integer and the fractional part
-of decimal numbers (yes, this is redundant with POSIX::localeconv())
+of decimal numbers, the group separator string for large-ish floating point
+numbers  (yes, the final two are redundant with POSIX::localeconv())
 
     YESSTR YESEXPR NOSTR NOEXPR
 
@@ -153,22 +158,79 @@ for the affirmative and negative responses and 
expressions, and
 
     ERA ERA_D_FMT ERA_D_T_FMT ERA_T_FMT
 
-for the Japanese Emperor eras (naturally only defined under Japanese locales).
+for the eras based on typically some ruler, such as the Japanese Emperor
+(naturally only defined in the appropriate locales).
 
-See your L<langinfo(3)> for more information about the available
-constants.  (Often this means having to look directly at the
-F<langinfo.h> C header file.)
+Starting in Perl 5.28, this module is available even on systems that lack a
+nativeC<nl_langinfo>.  On such systems, it uses various methods to construct
+what that function, if present, would return.  But there are potential
+glitches.  These are the items that could be different:
+
+=over
+
+=item C<ERA>
+
+Unimplemented, so returns C<"">.
+
+=item C<CODESET>
+
+Unimplemented, except on Windows, due to the vagaries of vendor locale names,
+returning C<""> on non-Windows.
+
+=item C<YESEXPR>
+
+=item C<YESSTR>
+
+=item C<NOEXPR>
+
+=item C<NOSTR>
+
+Only the values for English are returned.  C<YESSTR> and C<NOSTR> have been
+removed from POSIX 2008, and are retained here for backwards compatibility.
+Your platform's C<nl_langinfo> may not support them.
+
+=item C<D_FMT>
+
+Always evaluates to C<%x>, the locale's appropriate date representation.
 
-Note that unfortunately none of the above constants are guaranteed
-to be available on a particular platform.  To be on the safe side
-you can wrap the import in an eval like this:
+=item C<T_FMT>
 
-    eval {
-        require I18N::Langinfo;
-        I18N::Langinfo->import(qw(langinfo CODESET));
-        $codeset = langinfo(CODESET()); # note the ()
-    };
-    if ($@) { ... failed ... }
+Always evaluates to C<%X>, the locale's appropriate time representation.
+
+=item C<D_T_FMT>
+
+Always evaluates to C<%c>, the locale's appropriate date and time
+representation.
+
+=item C<CRNCYSTR>
+
+The return may be incorrect for those rare locales where the currency symbol
+replaces the radix character.
+Send email to L<mailto:perl...@perl.org> if you have examples of it needing
+to work differently.
+
+=item C<ALT_DIGITS>
+
+Currently this gives the same results as Linux does.
+Send email to L<mailto:perl...@perl.org> if you have examples of it needing
+to work differently.
+
+=item C<ERA_D_FMT>
+
+=item C<ERA_T_FMT>
+
+=item C<ERA_D_T_FMT>
+
+=item C<T_FMT_AMPM>
+
+These are derived by using C<strftime()>, and not all versions of that function
+know about them.  C<""> is returned for these on such systems.
+
+=back
+
+See your L<nl_langinfo(3)> for more information about the available
+constants.  (Often this means having to look directly at the
+F<langinfo.h> C header file.)
 
 =head2 EXPORT
 
@@ -187,13 +249,13 @@ The langinfo() is just a wrapper for the C nl_langinfo() 
interface.
 
 =head1 AUTHOR
 
-Jarkko Hietaniemi, E<lt>j...@hut.fie<gt>
+Jarkko Hietaniemi, E<lt>j...@hut.fie<gt>.  Now maintained by Perl 5 porters.
 
 =head1 COPYRIGHT AND LICENSE
 
 Copyright 2001 by Jarkko Hietaniemi
 
 This library is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself. 
+it under the same terms as Perl itself.
 
 =cut
diff --git a/ext/I18N-Langinfo/Langinfo.xs b/ext/I18N-Langinfo/Langinfo.xs
index aae48c2b28..904b424b19 100644
--- a/ext/I18N-Langinfo/Langinfo.xs
+++ b/ext/I18N-Langinfo/Langinfo.xs
@@ -1,4 +1,6 @@
 #define PERL_NO_GET_CONTEXT
+#define PERL_EXT
+#define PERL_EXT_LANGINFO
 
 #include "EXTERN.h"
 #include "perl.h"
@@ -7,6 +9,8 @@
 #ifdef I_LANGINFO
 #   define __USE_GNU 1 /* Enables YESSTR, otherwise only __YESSTR. */
 #   include <langinfo.h>
+#else
+#   include <perl_langinfo.h>
 #endif
 
 #include "const-c.inc"
@@ -20,17 +24,77 @@ INCLUDE: const-xs.inc
 SV*
 langinfo(code)
        int     code
+  PREINIT:
+        const   char * value;
+        STRLEN  len;
   PROTOTYPE: _
   CODE:
 #ifdef HAS_NL_LANGINFO
        if (code < 0) {
            SETERRNO(EINVAL, LIB_INVARG);
            RETVAL = &PL_sv_undef;
-       } else {
-            RETVAL = newSVpv(Perl_langinfo(code), 0);
-        }
-#else
-       croak("nl_langinfo() not implemented on this architecture");
+       } else
 #endif
+        {
+            value = Perl_langinfo(code);
+            len = strlen(value);
+            RETVAL = newSVpvn(Perl_langinfo(code), len);
+
+            /* Now see if the UTF-8 flag should be turned on */
+#ifdef USE_LOCALE_CTYPE     /* No utf8 strings if not using LC_CTYPE */
+
+            /* If 'value' is ASCII or not legal UTF-8, the flag doesn't get
+             * turned on, so skip the followin code */
+            if (is_utf8_non_invariant_string((U8 *) value, len)) {
+                int category;
+
+                /* Check if the locale is a UTF-8 one.  The returns from
+                 * Perl_langinfo() are in different locale categories, so 
check the
+                 * category corresponding to this item */
+                switch (code) {
+
+                    /* This should always return ASCII, so we could instead
+                     * legitimately panic here, but soldier on */
+                    case CODESET:
+                        category = LC_CTYPE;
+                        break;
+
+                    case RADIXCHAR:
+                    case THOUSEP:
+#  ifdef USE_LOCALE_NUMERIC
+                        category = LC_NUMERIC;
+#  else
+                        /* Not ideal, but the best we can do on such a 
platform */
+                        category = LC_CTYPE;
+#  endif
+                        break;
+
+                    case CRNCYSTR:
+#  ifdef USE_LOCALE_MONETARY
+                        category = LC_MONETARY;
+#  else
+                        category = LC_CTYPE;
+#  endif
+                        break;
+
+                    default:
+#  ifdef USE_LOCALE_TIME
+                        category = LC_TIME;
+#  else
+                        category = LC_CTYPE;
+#  endif
+                        break;
+                }
+
+                /* Here the return is legal UTF-8.  Turn on that flag if the
+                 * locale is UTF-8.  (Otherwise, could just be a coincidence.)
+                 * */
+                if (_is_cur_LC_category_utf8(category)) {
+                    SvUTF8_on(RETVAL);
+                }
+            }
+#endif /* USE_LOCALE_CTYPE */
+        }
+
   OUTPUT:
-       RETVAL
+        RETVAL
diff --git a/ext/I18N-Langinfo/t/Langinfo.t b/ext/I18N-Langinfo/t/Langinfo.t
index 10a660e6d6..a26abb5ac6 100644
--- a/ext/I18N-Langinfo/t/Langinfo.t
+++ b/ext/I18N-Langinfo/t/Langinfo.t
@@ -7,7 +7,12 @@ require "../../t/loc_tools.pl";
 plan skip_all => "I18N::Langinfo or POSIX unavailable" 
     if $Config{'extensions'} !~ m!\bI18N/Langinfo\b!;
 
-my @constants = qw(ABDAY_1 DAY_1 ABMON_1 MON_1 RADIXCHAR AM_STR THOUSEP 
D_T_FMT D_FMT T_FMT);
+my @times  = qw( MON_1 MON_2 MON_3 MON_4 MON_5 MON_6 MON_7
+                 MON_8 MON_9 MON_10 MON_11 MON_12
+                 DAY_1 DAY_2 DAY_3 DAY_4 DAY_5 DAY_6 DAY_7);
+my @constants = qw(ABDAY_1 DAY_1 ABMON_1 RADIXCHAR AM_STR THOUSEP D_T_FMT
+                   D_FMT T_FMT);
+push @constants, @times;
 
 my %want =
     (
@@ -21,9 +26,9 @@ my %want =
 
 my @want = sort keys %want;
 
-plan tests => 1 + 3 * @constants + keys(@want) + 1;
+plan tests => 1 + 3 * @constants + keys(@want) + 1 + 2;
 
-use_ok('I18N::Langinfo', 'langinfo', @constants);
+use_ok('I18N::Langinfo', 'langinfo', @constants, 'CRNCYSTR');
 
 use POSIX;
 setlocale(LC_ALL, "C");
@@ -69,3 +74,72 @@ SKIP: {
     is (langinfo(&RADIXCHAR), ",",
         "Returns ',' for decimal pt for locale '$comma_locale'");
 }
+
+SKIP: {
+
+    my $found_time = 0;
+    my $found_monetary = 0;
+    my @locales = find_locales( [ 'LC_TIME', 'LC_CTYPE', 'LC_MONETARY' ]);
+
+    while (defined (my $utf8_locale = find_utf8_ctype_locale(\@locales))) {
+        if (! $found_time) {
+            setlocale(&LC_TIME, $utf8_locale);
+            foreach my $time_item (@times) {
+                my $eval_string = "langinfo(&$time_item)";
+                my $time_name = eval $eval_string;
+                if ($@) {
+                    fail("'$eval_string' failed: $@");
+                    last SKIP;
+                }
+                if (! defined $time_name) {
+                    fail("'$eval_string' returned undef");
+                    last SKIP;
+                }
+                if ($time_name eq "") {
+                    fail("'$eval_string' returned an empty name");
+                    last SKIP;
+                }
+
+                if ($time_name =~ /\P{ASCII}/) {
+                    ok(utf8::is_utf8($time_name), "The name for '$time_item' 
in $utf8_locale is a UTF8 string");
+                    $found_time = 1;
+                    last;
+                }
+            }
+        }
+
+        if (! $found_monetary) {
+            setlocale(&LC_MONETARY, $utf8_locale);
+            my $eval_string = "langinfo(&CRNCYSTR)";
+            my $symbol = eval $eval_string;
+            if ($@) {
+                fail("'$eval_string' failed: $@");
+                last SKIP;
+            }
+            if (! defined $symbol) {
+                fail("'$eval_string' returned undef");
+                last SKIP;
+            }
+            if ($symbol =~ /\P{ASCII}/) {
+                ok(utf8::is_utf8($symbol), "The name for 'CRNCYSTR' in 
$utf8_locale is a UTF8 string");
+                $found_monetary = 1;
+            }
+        }
+
+        last if $found_monetary && $found_time;
+
+        # Remove this locale from the list, and loop to find another utf8
+        # locale
+        @locales = grep { $_ ne $utf8_locale } @locales;
+    }
+
+    if ($found_time + $found_monetary < 2) {
+        my $message = "";
+        $message .= "time name" unless $found_time;
+        if (! $found_monetary) {
+            $message .= " nor" if $message;
+            "monetary name";
+        }
+        skip("Couldn't find a locale with a non-ascii $message", 2 - 
$found_time - $found_monetary);
+    }
+}
diff --git a/ext/XS-APItest/t/locale.t b/ext/XS-APItest/t/locale.t
index 02fb918862..9d338323c2 100644
--- a/ext/XS-APItest/t/locale.t
+++ b/ext/XS-APItest/t/locale.t
@@ -42,9 +42,6 @@ my %correct_C_responses = (
                             ABDAY_6 => 'Fri',
                             ABDAY_7 => 'Sat',
                             ABMON_1 => 'Jan',
-                            ABMON_10 => 'Oct',
-                            ABMON_11 => 'Nov',
-                            ABMON_12 => 'Dec',
                             ABMON_2 => 'Feb',
                             ABMON_3 => 'Mar',
                             ABMON_4 => 'Apr',
@@ -53,6 +50,9 @@ my %correct_C_responses = (
                             ABMON_7 => 'Jul',
                             ABMON_8 => 'Aug',
                             ABMON_9 => 'Sep',
+                            ABMON_10 => 'Oct',
+                            ABMON_11 => 'Nov',
+                            ABMON_12 => 'Dec',
                             ALT_DIGITS => undef,
                             AM_STR => 'AM',
                             CODESET => undef,
@@ -71,9 +71,6 @@ my %correct_C_responses = (
                             ERA_D_T_FMT => undef,
                             ERA_T_FMT => undef,
                             MON_1 => 'January',
-                            MON_10 => 'October',
-                            MON_11 => 'November',
-                            MON_12 => 'December',
                             MON_2 => 'February',
                             MON_3 => 'March',
                             MON_4 => 'April',
@@ -82,6 +79,9 @@ my %correct_C_responses = (
                             MON_7 => 'July',
                             MON_8 => 'August',
                             MON_9 => 'September',
+                            MON_10 => 'October',
+                            MON_11 => 'November',
+                            MON_12 => 'December',
                             NOEXPR => undef,
                             NOSTR => undef,
                             PM_STR => 'PM',
@@ -113,11 +113,11 @@ SKIP: {
     # For non-nl_langinfo systems, those values are arbitrary negative numbers
     # set in the header.  Otherwise they are the nl_langinfo approved values,
     # which for the moment is the item name.
-    # The relevant lines look like: #  define PERL_YESSTR -54
+    # The relevant lines look like: #  define YESSTR -54
     while (<$fh>) {
         chomp;
         next unless / - \d+ $ /x;
-        s/ ^ .* PERL_ //x;
+        s/ ^ \# \s* define \s*//x;
         m/ (.*) \  (.*) /x;
         $items{$1} = ($has_nl_langinfo)
                      ? $1       # Yields 'YESSTR'
@@ -129,13 +129,13 @@ SKIP: {
 
     foreach my $formal_item (sort keys %items) {
         if (exists $correct_C_responses{$formal_item}) {
+            my $correct = $correct_C_responses{$formal_item};
             my $item = eval $items{$formal_item};
             skip "This platform apparently doesn't support $formal_item", 1 if 
$@;
             my $result = test_Perl_langinfo($item);
-            if (defined $correct_C_responses{$formal_item}) {
-                is ($result,
-                    $correct_C_responses{$formal_item},
-                    "Returns expected value ('$result') for $formal_item");
+            if (defined $correct) {
+                is ($result, $correct,
+                    "Returns expected value" . "('$correct') for 
$formal_item");
             }
             else {
                 ok (defined $result,
diff --git a/locale.c b/locale.c
index ca163cda21..277e038327 100644
--- a/locale.c
+++ b/locale.c
@@ -1259,7 +1259,7 @@ S_set_numeric_radix(pTHX_ const bool use_locale)
                                     || defined(HAS_NL_LANGINFO))
 
     const char * radix = (use_locale)
-                         ? my_nl_langinfo(PERL_RADIXCHAR, FALSE)
+                         ? my_nl_langinfo(RADIXCHAR, FALSE)
                                         /* FALSE => already in dest locale */
                          : ".";
 
@@ -1347,10 +1347,9 @@ S_new_numeric(pTHX_ const char *newnum)
     /* If its name isn't C nor POSIX, it could still be indistinguishable from
      * them */
     if (! PL_numeric_standard) {
-        PL_numeric_standard = cBOOL(strEQ(".", my_nl_langinfo(PERL_RADIXCHAR,
+        PL_numeric_standard = cBOOL(strEQ(".", my_nl_langinfo(RADIXCHAR,
                                             FALSE /* Don't toggle locale */  ))
-                                 && strEQ("",  my_nl_langinfo(PERL_THOUSEP,
-                                                              FALSE)));
+                                 && strEQ("",  my_nl_langinfo(THOUSEP, 
FALSE)));
     }
 
     /* Save the new name if it isn't the same as the previous one, if any */
@@ -1693,7 +1692,7 @@ S_new_ctype(pTHX_ const char *newctype)
 
             Perl_sv_catpvf(aTHX_ PL_warn_locale, "; codeset=%s",
                                     /* parameter FALSE is a don't care here */
-                                    my_nl_langinfo(PERL_CODESET, FALSE));
+                                    my_nl_langinfo(CODESET, FALSE));
 
 #  endif
 
@@ -2313,79 +2312,26 @@ But most importantly, it works on systems that don't 
have C<nl_langinfo>, such
 as Windows, hence makes your code more portable.  Of the fifty-some possible
 items specified by the POSIX 2008 standard,
 L<http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/langinfo.h.html>,
-only two are completely unimplemented (though the loss of one of these is
-significant).  It uses various techniques to recover the other items, including
-calling C<L<localeconv(3)>>, and C<L<strftime(3)>>, both of which are specified
-in C89, so should be always be available.  Later C<strftime()> versions have
-additional capabilities; C<""> is returned for those not available on your
-system.
+only one is completely unimplemented, though on non-Windows platforms, another
+significant one is also not implemented).  It uses various techniques to
+recover the other items, including calling C<L<localeconv(3)>>, and
+C<L<strftime(3)>>, both of which are specified in C89, so should be always be
+available.  Later C<strftime()> versions have additional capabilities; C<""> is
+returned for those not available on your system.
 
 It is important to note that when called with an item that is recovered by
 using C<localeconv>, the buffer from any previous explicit call to
 C<localeconv> will be overwritten.  This means you must save that buffer's
-contents if you need to access them after a call to this function.
+contents if you need to access them after a call to this function.  (But note
+that you might not want to be using C<localeconv()> directly anyway, because of
+issues like the ones listed in the second item of this list (above) for
+C<RADIXCHAR> and C<THOUSEP>.  You can use the methods given in L<perlcall> to
+call L<POSIX/localeconv> and avoid all the issues, but then you have a hash to
+unpack).
 
-The details for those items which may differ from what this emulation returns
-and what a native C<nl_langinfo()> would return are:
-
-=over
-
-=item C<CODESET>
-
-=item C<ERA>
-
-Unimplemented, so returns C<"">.
-
-=item C<YESEXPR>
-
-=item C<YESSTR>
-
-=item C<NOEXPR>
-
-=item C<NOSTR>
-
-Only the values for English are returned.  C<YESSTR> and C<NOSTR> have been
-removed from POSIX 2008, and are retained here for backwards compatibility.
-Your platform's C<nl_langinfo> may not support them.
-
-=item C<D_FMT>
-
-Always evaluates to C<%x>, the locale's appropriate date representation.
-
-=item C<T_FMT>
-
-Always evaluates to C<%X>, the locale's appropriate time representation.
-
-=item C<D_T_FMT>
-
-Always evaluates to C<%c>, the locale's appropriate date and time
-representation.
-
-=item C<CRNCYSTR>
-
-The return may be incorrect for those rare locales where the currency symbol
-replaces the radix character.
-Send email to L<mailto:perl...@perl.org> if you have examples of it needing
-to work differently.
-
-=item C<ALT_DIGITS>
-
-Currently this gives the same results as Linux does.
-Send email to L<mailto:perl...@perl.org> if you have examples of it needing
-to work differently.
-
-=item C<ERA_D_FMT>
-
-=item C<ERA_T_FMT>
-
-=item C<ERA_D_T_FMT>
-
-=item C<T_FMT_AMPM>
-
-These are derived by using C<strftime()>, and not all versions of that function
-know about them.  C<""> is returned for these on such systems.
-
-=back
+The details for those items which may deviate from what this emulation returns
+and what a native C<nl_langinfo()> would return are specified in
+L<I18N::Langinfo>.
 
 =back
 
@@ -2396,12 +2342,8 @@ C<nl_langinfo()>, you must
 
 before the C<perl.h> C<#include>.  You can replace your C<langinfo.h>
 C<#include> with this one.  (Doing it this way keeps out the symbols that plain
-C<langinfo.h> imports into the namespace for code that doesn't need it.)
-
-You also should not use the bare C<langinfo.h> item names, but should preface
-them with C<PERL_>, so use C<PERL_RADIXCHAR> instead of plain C<RADIXCHAR>.
-The C<PERL_I<foo>> versions will also work for this function on systems that do
-have a native C<nl_langinfo>.
+C<langinfo.h> would try to import into the namespace for code that doesn't need
+it.)
 
 The original impetus for C<Perl_langinfo()> was so that code that needs to
 find out the current currency symbol, floating point radix character, or digit
@@ -2437,7 +2379,7 @@ S_my_nl_langinfo(const int item, bool toggle)
 
     /* We only need to toggle into the underlying LC_NUMERIC locale for these
      * two items, and only if not already there */
-    if (toggle && ((   item != PERL_RADIXCHAR && item != PERL_THOUSEP)
+    if (toggle && ((   item != RADIXCHAR && item != THOUSEP)
                     || PL_numeric_underlying))
     {
         toggle = FALSE;
@@ -2511,10 +2453,10 @@ S_my_nl_langinfo(const int item, bool toggle)
 #  endif
 
     if (strEQ(retval, "")) {
-        if (item == PERL_YESSTR) {
+        if (item == YESSTR) {
             return "yes";
         }
-        if (item == PERL_NOSTR) {
+        if (item == NOSTR) {
             return "no";
         }
     }
@@ -2551,22 +2493,81 @@ S_my_nl_langinfo(const int item, bool toggle)
         switch (item) {
             Size_t len;
 
-            /* These 2 are unimplemented */
-            case PERL_CODESET:
-            case PERL_ERA:      /* For use with strftime() %E modifier */
+            /* This is unimplemented */
+            case ERA:      /* For use with strftime() %E modifier */
 
             default:
                 return "";
 
             /* We use only an English set, since we don't know any more */
-            case PERL_YESEXPR:   return "^[+1yY]";
-            case PERL_YESSTR:    return "yes";
-            case PERL_NOEXPR:    return "^[-0nN]";
-            case PERL_NOSTR:     return "no";
+            case YESEXPR:   return "^[+1yY]";
+            case YESSTR:    return "yes";
+            case NOEXPR:    return "^[-0nN]";
+            case NOSTR:     return "no";
+
+            case CODESET:
+
+#  ifndef WIN32
+
+                /* On non-windows, this is unimplemented, in part because of
+                 * inconsistencies between vendors.  The Darwin native
+                 * nl_langinfo() implementation simply looks at everything past
+                 * any dot in the name, but that doesn't work for other
+                 * vendors.  Many Linux locales that don't have UTF-8 in their
+                 * names really are UTF-8, for example; z/OS locales that do
+                 * have UTF-8 in their names, aren't really UTF-8 */
+                return "";
+
+#  else
+
+                {   /* But on Windows, the name does seem to be consistent, so
+                       use that. */
+                    const char * p;
+                    const char * first;
+                    Size_t offset = 0;
+                    const char * name = my_setlocale(LC_CTYPE, NULL);
+
+                    if (isNAME_C_OR_POSIX(name)) {
+                        return "ANSI_X3.4-1968";
+                    }
+
+                    /* Find the dot in the locale name */
+                    first = (const char *) strchr(name, '.');
+                    if (! first) {
+                        first = name;
+                        goto has_nondigit;
+                    }
+
+                    /* Look at everything past the dot */
+                    first++;
+                    p = first;
+
+                    while (*p) {
+                        if (! isDIGIT(*p)) {
+                            goto has_nondigit;
+                        }
+
+                        p++;
+                    }
+
+                    /* Here everything past the dot is a digit.  Treat it as a
+                     * code page */
+                    save_to_buffer("CP", &PL_langinfo_buf,
+                                         &PL_langinfo_bufsize, 0);
+                    offset = STRLENs("CP");
 
+                  has_nondigit:
+
+                    retval = save_to_buffer(first, &PL_langinfo_buf,
+                                            &PL_langinfo_bufsize, offset);
+                }
+
+                break;
+
+#  endif
 #  ifdef HAS_LOCALECONV
 
-            case PERL_CRNCYSTR:
+            case CRNCYSTR:
 
                 /* We don't bother with localeconv_l() because any system that
                  * has it is likely to also have nl_langinfo() */
@@ -2602,8 +2603,8 @@ S_my_nl_langinfo(const int item, bool toggle)
                 LOCALE_UNLOCK;
                 break;
 
-            case PERL_RADIXCHAR:
-            case PERL_THOUSEP:
+            case RADIXCHAR:
+            case THOUSEP:
 
                 if (toggle) {
                     STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
@@ -2617,7 +2618,7 @@ S_my_nl_langinfo(const int item, bool toggle)
                     temp = "";
                 }
                 else {
-                    temp = (item == PERL_RADIXCHAR)
+                    temp = (item == RADIXCHAR)
                              ? lc->decimal_point
                              : lc->thousands_sep;
                     if (! temp) {
@@ -2645,30 +2646,26 @@ S_my_nl_langinfo(const int item, bool toggle)
              * for someone using them as formats (as opposed to trying to parse
              * them to figure out what the locale says).  The other format
              * items are actually tested to verify they work on the platform */
-            case PERL_D_FMT:         return "%x";
-            case PERL_T_FMT:         return "%X";
-            case PERL_D_T_FMT:       return "%c";
+            case D_FMT:         return "%x";
+            case T_FMT:         return "%X";
+            case D_T_FMT:       return "%c";
 
             /* These formats are only available in later strfmtime's */
-            case PERL_ERA_D_FMT: case PERL_ERA_T_FMT: case PERL_ERA_D_T_FMT:
-            case PERL_T_FMT_AMPM:
+            case ERA_D_FMT: case ERA_T_FMT: case ERA_D_T_FMT: case T_FMT_AMPM:
 
             /* The rest can be gotten from most versions of strftime(). */
-            case PERL_ABDAY_1: case PERL_ABDAY_2: case PERL_ABDAY_3:
-            case PERL_ABDAY_4: case PERL_ABDAY_5: case PERL_ABDAY_6:
-            case PERL_ABDAY_7:
-            case PERL_ALT_DIGITS:
-            case PERL_AM_STR: case PERL_PM_STR:
-            case PERL_ABMON_1: case PERL_ABMON_2: case PERL_ABMON_3:
-            case PERL_ABMON_4: case PERL_ABMON_5: case PERL_ABMON_6:
-            case PERL_ABMON_7: case PERL_ABMON_8: case PERL_ABMON_9:
-            case PERL_ABMON_10: case PERL_ABMON_11: case PERL_ABMON_12:
-            case PERL_DAY_1: case PERL_DAY_2: case PERL_DAY_3: case PERL_DAY_4:
-            case PERL_DAY_5: case PERL_DAY_6: case PERL_DAY_7:
-            case PERL_MON_1: case PERL_MON_2: case PERL_MON_3: case PERL_MON_4:
-            case PERL_MON_5: case PERL_MON_6: case PERL_MON_7: case PERL_MON_8:
-            case PERL_MON_9: case PERL_MON_10: case PERL_MON_11:
-            case PERL_MON_12:
+            case ABDAY_1: case ABDAY_2: case ABDAY_3:
+            case ABDAY_4: case ABDAY_5: case ABDAY_6: case ABDAY_7:
+            case ALT_DIGITS:
+            case AM_STR: case PM_STR:
+            case ABMON_1: case ABMON_2: case ABMON_3: case ABMON_4:
+            case ABMON_5: case ABMON_6: case ABMON_7: case ABMON_8:
+            case ABMON_9: case ABMON_10: case ABMON_11: case ABMON_12:
+            case DAY_1: case DAY_2: case DAY_3: case DAY_4:
+            case DAY_5: case DAY_6: case DAY_7:
+            case MON_1: case MON_2: case MON_3: case MON_4:
+            case MON_5: case MON_6: case MON_7: case MON_8:
+            case MON_9: case MON_10: case MON_11: case MON_12:
 
                 LOCALE_LOCK;
 
@@ -2687,82 +2684,82 @@ S_my_nl_langinfo(const int item, bool toggle)
                                        __FILE__, __LINE__, item);
                         NOT_REACHED; /* NOTREACHED */
 
-                    case PERL_PM_STR: tm.tm_hour = 18;
-                    case PERL_AM_STR:
+                    case PM_STR: tm.tm_hour = 18;
+                    case AM_STR:
                         format = "%p";
                         break;
 
-                    case PERL_ABDAY_7: tm.tm_wday++;
-                    case PERL_ABDAY_6: tm.tm_wday++;
-                    case PERL_ABDAY_5: tm.tm_wday++;
-                    case PERL_ABDAY_4: tm.tm_wday++;
-                    case PERL_ABDAY_3: tm.tm_wday++;
-                    case PERL_ABDAY_2: tm.tm_wday++;
-                    case PERL_ABDAY_1:
+                    case ABDAY_7: tm.tm_wday++;
+                    case ABDAY_6: tm.tm_wday++;
+                    case ABDAY_5: tm.tm_wday++;
+                    case ABDAY_4: tm.tm_wday++;
+                    case ABDAY_3: tm.tm_wday++;
+                    case ABDAY_2: tm.tm_wday++;
+                    case ABDAY_1:
                         format = "%a";
                         break;
 
-                    case PERL_DAY_7: tm.tm_wday++;
-                    case PERL_DAY_6: tm.tm_wday++;
-                    case PERL_DAY_5: tm.tm_wday++;
-                    case PERL_DAY_4: tm.tm_wday++;
-                    case PERL_DAY_3: tm.tm_wday++;
-                    case PERL_DAY_2: tm.tm_wday++;
-                    case PERL_DAY_1:
+                    case DAY_7: tm.tm_wday++;
+                    case DAY_6: tm.tm_wday++;
+                    case DAY_5: tm.tm_wday++;
+                    case DAY_4: tm.tm_wday++;
+                    case DAY_3: tm.tm_wday++;
+                    case DAY_2: tm.tm_wday++;
+                    case DAY_1:
                         format = "%A";
                         break;
 
-                    case PERL_ABMON_12: tm.tm_mon++;
-                    case PERL_ABMON_11: tm.tm_mon++;
-                    case PERL_ABMON_10: tm.tm_mon++;
-                    case PERL_ABMON_9: tm.tm_mon++;
-                    case PERL_ABMON_8: tm.tm_mon++;
-                    case PERL_ABMON_7: tm.tm_mon++;
-                    case PERL_ABMON_6: tm.tm_mon++;
-                    case PERL_ABMON_5: tm.tm_mon++;
-                    case PERL_ABMON_4: tm.tm_mon++;
-                    case PERL_ABMON_3: tm.tm_mon++;
-                    case PERL_ABMON_2: tm.tm_mon++;
-                    case PERL_ABMON_1:
+                    case ABMON_12: tm.tm_mon++;
+                    case ABMON_11: tm.tm_mon++;
+                    case ABMON_10: tm.tm_mon++;
+                    case ABMON_9: tm.tm_mon++;
+                    case ABMON_8: tm.tm_mon++;
+                    case ABMON_7: tm.tm_mon++;
+                    case ABMON_6: tm.tm_mon++;
+                    case ABMON_5: tm.tm_mon++;
+                    case ABMON_4: tm.tm_mon++;
+                    case ABMON_3: tm.tm_mon++;
+                    case ABMON_2: tm.tm_mon++;
+                    case ABMON_1:
                         format = "%b";
                         break;
 
-                    case PERL_MON_12: tm.tm_mon++;
-                    case PERL_MON_11: tm.tm_mon++;
-                    case PERL_MON_10: tm.tm_mon++;
-                    case PERL_MON_9: tm.tm_mon++;
-                    case PERL_MON_8: tm.tm_mon++;
-                    case PERL_MON_7: tm.tm_mon++;
-                    case PERL_MON_6: tm.tm_mon++;
-                    case PERL_MON_5: tm.tm_mon++;
-                    case PERL_MON_4: tm.tm_mon++;
-                    case PERL_MON_3: tm.tm_mon++;
-                    case PERL_MON_2: tm.tm_mon++;
-                    case PERL_MON_1:
+                    case MON_12: tm.tm_mon++;
+                    case MON_11: tm.tm_mon++;
+                    case MON_10: tm.tm_mon++;
+                    case MON_9: tm.tm_mon++;
+                    case MON_8: tm.tm_mon++;
+                    case MON_7: tm.tm_mon++;
+                    case MON_6: tm.tm_mon++;
+                    case MON_5: tm.tm_mon++;
+                    case MON_4: tm.tm_mon++;
+                    case MON_3: tm.tm_mon++;
+                    case MON_2: tm.tm_mon++;
+                    case MON_1:
                         format = "%B";
                         break;
 
-                    case PERL_T_FMT_AMPM:
+                    case T_FMT_AMPM:
                         format = "%r";
                         return_format = TRUE;
                         break;
 
-                    case PERL_ERA_D_FMT:
+                    case ERA_D_FMT:
                         format = "%Ex";
                         return_format = TRUE;
                         break;
 
-                    case PERL_ERA_T_FMT:
+                    case ERA_T_FMT:
                         format = "%EX";
                         return_format = TRUE;
                         break;
 
-                    case PERL_ERA_D_T_FMT:
+                    case ERA_D_T_FMT:
                         format = "%Ec";
                         return_format = TRUE;
                         break;
 
-                    case PERL_ALT_DIGITS:
+                    case ALT_DIGITS:
                         tm.tm_wday = 0;
                         format = "%Ow";        /* Find the alternate digit for 
0 */
                         break;
@@ -2830,7 +2827,7 @@ S_my_nl_langinfo(const int item, bool toggle)
                  * alternate format for wday 0.  If the value is the same as
                  * the normal 0, there isn't an alternate, so clear the buffer.
                  * */
-                if (   item == PERL_ALT_DIGITS
+                if (   item == ALT_DIGITS
                     && strEQ(PL_langinfo_buf, "0"))
                 {
                     *PL_langinfo_buf = '\0';
@@ -4339,7 +4336,7 @@ Perl__is_cur_LC_category_utf8(pTHX_ int category)
      * calculate it */
 
 #  if        defined(USE_LOCALE_CTYPE)                                  \
-     && (   (defined(HAS_NL_LANGINFO) && defined(CODESET))              \
+     && (    defined(HAS_NL_LANGINFO)                                   \
          || (defined(HAS_MBTOWC) || defined(HAS_MBRTOWC)))
 
     {
@@ -4367,7 +4364,7 @@ Perl__is_cur_LC_category_utf8(pTHX_ int category)
             }
 
 #    endif
-#    if defined(HAS_NL_LANGINFO) && defined(CODESET)
+#    if defined(HAS_NL_LANGINFO)
 
         { /* The task is easiest if the platform has this POSIX 2001 function.
              Except on some platforms it can wrongly return "", so have to have
@@ -4377,7 +4374,7 @@ Perl__is_cur_LC_category_utf8(pTHX_ int category)
              defective locale definition.  XXX We should probably check for
              these in the Latin1 range and warn (but on glibc, requires
              iswalnum() etc. due to their not handling 80-FF correctly */
-            const char *codeset = my_nl_langinfo(PERL_CODESET, FALSE);
+            const char *codeset = my_nl_langinfo(CODESET, FALSE);
                                           /* FALSE => already in dest locale */
 
             DEBUG_Lv(PerlIO_printf(Perl_debug_log,
@@ -4480,7 +4477,7 @@ Perl__is_cur_LC_category_utf8(pTHX_ int category)
                                                              
save_input_locale);
             bool only_ascii = FALSE;
             const U8 * currency_string
-                            = (const U8 *) my_nl_langinfo(PERL_CRNCYSTR, 
FALSE);
+                            = (const U8 *) my_nl_langinfo(CRNCYSTR, FALSE);
                                       /* 2nd param not relevant for this item 
*/
             const U8 * first_variant;
 
diff --git a/perl_langinfo.h b/perl_langinfo.h
index cd6eb07de5..ff96b384e1 100644
--- a/perl_langinfo.h
+++ b/perl_langinfo.h
@@ -13,295 +13,178 @@
 /* NOTE that this file is parsed by ext/XS-APItest/t/locale.t, so be careful
  * with changes */
 
-/* Define PERL_foo to 'foo' if it exists; a negative number otherwise.  The
- * negatives are to minimize the possibility of collisions on platforms that
- * define some but not all of these item names (though each name is required by
- * the 2008 POSIX specification) */
+/* If foo doesn't exist deine it to a negative number. */
 
-#ifdef CODESET
-#  define PERL_CODESET CODESET
-#else
-#  define PERL_CODESET -1
-#endif
-#ifdef D_T_FMT
-#  define PERL_D_T_FMT D_T_FMT
-#else
-#  define PERL_D_T_FMT -2
-#endif
-#ifdef D_FMT
-#  define PERL_D_FMT D_FMT
-#else
-#  define PERL_D_FMT -3
-#endif
-#ifdef T_FMT
-#  define PERL_T_FMT T_FMT
-#else
-#  define PERL_T_FMT -4
-#endif
-#ifdef T_FMT_AMPM
-#  define PERL_T_FMT_AMPM T_FMT_AMPM
-#else
-#  define PERL_T_FMT_AMPM -5
-#endif
-#ifdef AM_STR
-#  define PERL_AM_STR AM_STR
-#else
-#  define PERL_AM_STR -6
-#endif
-#ifdef PM_STR
-#  define PERL_PM_STR PM_STR
-#else
-#  define PERL_PM_STR -7
-#endif
-#ifdef DAY_1
-#  define PERL_DAY_1 DAY_1
-#else
-#  define PERL_DAY_1 -8
-#endif
-#ifdef DAY_2
-#  define PERL_DAY_2 DAY_2
-#else
-#  define PERL_DAY_2 -9
-#endif
-#ifdef DAY_3
-#  define PERL_DAY_3 DAY_3
-#else
-#  define PERL_DAY_3 -10
-#endif
-#ifdef DAY_4
-#  define PERL_DAY_4 DAY_4
-#else
-#  define PERL_DAY_4 -11
-#endif
-#ifdef DAY_5
-#  define PERL_DAY_5 DAY_5
-#else
-#  define PERL_DAY_5 -12
-#endif
-#ifdef DAY_6
-#  define PERL_DAY_6 DAY_6
-#else
-#  define PERL_DAY_6 -13
-#endif
-#ifdef DAY_7
-#  define PERL_DAY_7 DAY_7
-#else
-#  define PERL_DAY_7 -14
-#endif
-#ifdef ABDAY_1
-#  define PERL_ABDAY_1 ABDAY_1
-#else
-#  define PERL_ABDAY_1 -15
-#endif
-#ifdef ABDAY_2
-#  define PERL_ABDAY_2 ABDAY_2
-#else
-#  define PERL_ABDAY_2 -16
-#endif
-#ifdef ABDAY_3
-#  define PERL_ABDAY_3 ABDAY_3
-#else
-#  define PERL_ABDAY_3 -17
-#endif
-#ifdef ABDAY_4
-#  define PERL_ABDAY_4 ABDAY_4
-#else
-#  define PERL_ABDAY_4 -18
-#endif
-#ifdef ABDAY_5
-#  define PERL_ABDAY_5 ABDAY_5
-#else
-#  define PERL_ABDAY_5 -19
-#endif
-#ifdef ABDAY_6
-#  define PERL_ABDAY_6 ABDAY_6
-#else
-#  define PERL_ABDAY_6 -20
-#endif
-#ifdef ABDAY_7
-#  define PERL_ABDAY_7 ABDAY_7
-#else
-#  define PERL_ABDAY_7 -21
-#endif
-#ifdef MON_1
-#  define PERL_MON_1 MON_1
-#else
-#  define PERL_MON_1 -22
-#endif
-#ifdef MON_2
-#  define PERL_MON_2 MON_2
-#else
-#  define PERL_MON_2 -23
-#endif
-#ifdef MON_3
-#  define PERL_MON_3 MON_3
-#else
-#  define PERL_MON_3 -24
-#endif
-#ifdef MON_4
-#  define PERL_MON_4 MON_4
-#else
-#  define PERL_MON_4 -25
-#endif
-#ifdef MON_5
-#  define PERL_MON_5 MON_5
-#else
-#  define PERL_MON_5 -26
-#endif
-#ifdef MON_6
-#  define PERL_MON_6 MON_6
-#else
-#  define PERL_MON_6 -27
-#endif
-#ifdef MON_7
-#  define PERL_MON_7 MON_7
-#else
-#  define PERL_MON_7 -28
-#endif
-#ifdef MON_8
-#  define PERL_MON_8 MON_8
-#else
-#  define PERL_MON_8 -29
-#endif
-#ifdef MON_9
-#  define PERL_MON_9 MON_9
-#else
-#  define PERL_MON_9 -30
-#endif
-#ifdef MON_10
-#  define PERL_MON_10 MON_10
-#else
-#  define PERL_MON_10 -31
-#endif
-#ifdef MON_11
-#  define PERL_MON_11 MON_11
-#else
-#  define PERL_MON_11 -32
-#endif
-#ifdef MON_12
-#  define PERL_MON_12 MON_12
-#else
-#  define PERL_MON_12 -33
-#endif
-#ifdef ABMON_1
-#  define PERL_ABMON_1 ABMON_1
-#else
-#  define PERL_ABMON_1 -34
-#endif
-#ifdef ABMON_2
-#  define PERL_ABMON_2 ABMON_2
-#else
-#  define PERL_ABMON_2 -35
-#endif
-#ifdef ABMON_3
-#  define PERL_ABMON_3 ABMON_3
-#else
-#  define PERL_ABMON_3 -36
-#endif
-#ifdef ABMON_4
-#  define PERL_ABMON_4 ABMON_4
-#else
-#  define PERL_ABMON_4 -37
-#endif
-#ifdef ABMON_5
-#  define PERL_ABMON_5 ABMON_5
-#else
-#  define PERL_ABMON_5 -38
-#endif
-#ifdef ABMON_6
-#  define PERL_ABMON_6 ABMON_6
-#else
-#  define PERL_ABMON_6 -39
-#endif
-#ifdef ABMON_7
-#  define PERL_ABMON_7 ABMON_7
-#else
-#  define PERL_ABMON_7 -40
-#endif
-#ifdef ABMON_8
-#  define PERL_ABMON_8 ABMON_8
-#else
-#  define PERL_ABMON_8 -41
-#endif
-#ifdef ABMON_9
-#  define PERL_ABMON_9 ABMON_9
-#else
-#  define PERL_ABMON_9 -42
-#endif
-#ifdef ABMON_10
-#  define PERL_ABMON_10 ABMON_10
-#else
-#  define PERL_ABMON_10 -43
-#endif
-#ifdef ABMON_11
-#  define PERL_ABMON_11 ABMON_11
-#else
-#  define PERL_ABMON_11 -44
-#endif
-#ifdef ABMON_12
-#  define PERL_ABMON_12 ABMON_12
-#else
-#  define PERL_ABMON_12 -45
-#endif
-#ifdef ERA
-#  define PERL_ERA ERA
-#else
-#  define PERL_ERA -46
-#endif
-#ifdef ERA_D_FMT
-#  define PERL_ERA_D_FMT ERA_D_FMT
-#else
-#  define PERL_ERA_D_FMT -47
-#endif
-#ifdef ERA_D_T_FMT
-#  define PERL_ERA_D_T_FMT ERA_D_T_FMT
-#else
-#  define PERL_ERA_D_T_FMT -48
-#endif
-#ifdef ERA_T_FMT
-#  define PERL_ERA_T_FMT ERA_T_FMT
-#else
-#  define PERL_ERA_T_FMT -49
-#endif
-#ifdef ALT_DIGITS
-#  define PERL_ALT_DIGITS ALT_DIGITS
-#else
-#  define PERL_ALT_DIGITS -50
-#endif
-#ifdef RADIXCHAR
-#  define PERL_RADIXCHAR RADIXCHAR
-#else
-#  define PERL_RADIXCHAR -51
-#endif
-#ifdef THOUSEP
-#  define PERL_THOUSEP THOUSEP
-#else
-#  define PERL_THOUSEP -52
-#endif
-#ifdef YESEXPR
-#  define PERL_YESEXPR YESEXPR
-#else
-#  define PERL_YESEXPR -53
-#endif
-#ifdef YESSTR
-#  define PERL_YESSTR YESSTR
-#else
-#  define PERL_YESSTR -54
-#endif
-#ifdef NOEXPR
-#  define PERL_NOEXPR NOEXPR
-#else
-#  define PERL_NOEXPR -55
-#endif
-#ifdef NOSTR
-#  define PERL_NOSTR NOSTR
-#else
-#  define PERL_NOSTR -56
-#endif
-#ifdef CRNCYSTR
-#  define PERL_CRNCYSTR CRNCYSTR
-#else
-#  define PERL_CRNCYSTR -57
+#ifndef CODESET
+#  define CODESET -1
+#endif
+#ifndef D_T_FMT
+#  define D_T_FMT -2
+#endif
+#ifndef D_FMT
+#  define D_FMT -3
+#endif
+#ifndef T_FMT
+#  define T_FMT -4
+#endif
+#ifndef T_FMT_AMPM
+#  define T_FMT_AMPM -5
+#endif
+#ifndef AM_STR
+#  define AM_STR -6
+#endif
+#ifndef PM_STR
+#  define PM_STR -7
+#endif
+#ifndef DAY_1
+#  define DAY_1 -8
+#endif
+#ifndef DAY_2
+#  define DAY_2 -9
+#endif
+#ifndef DAY_3
+#  define DAY_3 -10
+#endif
+#ifndef DAY_4
+#  define DAY_4 -11
+#endif
+#ifndef DAY_5
+#  define DAY_5 -12
+#endif
+#ifndef DAY_6
+#  define DAY_6 -13
+#endif
+#ifndef DAY_7
+#  define DAY_7 -14
+#endif
+#ifndef ABDAY_1
+#  define ABDAY_1 -15
+#endif
+#ifndef ABDAY_2
+#  define ABDAY_2 -16
+#endif
+#ifndef ABDAY_3
+#  define ABDAY_3 -17
+#endif
+#ifndef ABDAY_4
+#  define ABDAY_4 -18
+#endif
+#ifndef ABDAY_5
+#  define ABDAY_5 -19
+#endif
+#ifndef ABDAY_6
+#  define ABDAY_6 -20
+#endif
+#ifndef ABDAY_7
+#  define ABDAY_7 -21
+#endif
+#ifndef MON_1
+#  define MON_1 -22
+#endif
+#ifndef MON_2
+#  define MON_2 -23
+#endif
+#ifndef MON_3
+#  define MON_3 -24
+#endif
+#ifndef MON_4
+#  define MON_4 -25
+#endif
+#ifndef MON_5
+#  define MON_5 -26
+#endif
+#ifndef MON_6
+#  define MON_6 -27
+#endif
+#ifndef MON_7
+#  define MON_7 -28
+#endif
+#ifndef MON_8
+#  define MON_8 -29
+#endif
+#ifndef MON_9
+#  define MON_9 -30
+#endif
+#ifndef MON_10
+#  define MON_10 -31
+#endif
+#ifndef MON_11
+#  define MON_11 -32
+#endif
+#ifndef MON_12
+#  define MON_12 -33
+#endif
+#ifndef ABMON_1
+#  define ABMON_1 -34
+#endif
+#ifndef ABMON_2
+#  define ABMON_2 -35
+#endif
+#ifndef ABMON_3
+#  define ABMON_3 -36
+#endif
+#ifndef ABMON_4
+#  define ABMON_4 -37
+#endif
+#ifndef ABMON_5
+#  define ABMON_5 -38
+#endif
+#ifndef ABMON_6
+#  define ABMON_6 -39
+#endif
+#ifndef ABMON_7
+#  define ABMON_7 -40
+#endif
+#ifndef ABMON_8
+#  define ABMON_8 -41
+#endif
+#ifndef ABMON_9
+#  define ABMON_9 -42
+#endif
+#ifndef ABMON_10
+#  define ABMON_10 -43
+#endif
+#ifndef ABMON_11
+#  define ABMON_11 -44
+#endif
+#ifndef ABMON_12
+#  define ABMON_12 -45
+#endif
+#ifndef ERA
+#  define ERA -46
+#endif
+#ifndef ERA_D_FMT
+#  define ERA_D_FMT -47
+#endif
+#ifndef ERA_D_T_FMT
+#  define ERA_D_T_FMT -48
+#endif
+#ifndef ERA_T_FMT
+#  define ERA_T_FMT -49
+#endif
+#ifndef ALT_DIGITS
+#  define ALT_DIGITS -50
+#endif
+#ifndef RADIXCHAR
+#  define RADIXCHAR -51
+#endif
+#ifndef THOUSEP
+#  define THOUSEP -52
+#endif
+#ifndef YESEXPR
+#  define YESEXPR -53
+#endif
+#ifndef YESSTR
+#  define YESSTR -54
+#endif
+#ifndef NOEXPR
+#  define NOEXPR -55
+#endif
+#ifndef NOSTR
+#  define NOSTR -56
+#endif
+#ifndef CRNCYSTR
+#  define CRNCYSTR -57
 #endif
 
 #endif
diff --git a/pod/perldelta.pod b/pod/perldelta.pod
index 85a086761b..9baa05a82f 100644
--- a/pod/perldelta.pod
+++ b/pod/perldelta.pod
@@ -135,6 +135,17 @@ Carp now avoids using C<overload::StrVal>, partly because 
older versions
 of L<overload> (included with perl 5.14 and earlier) load L<Scalar::Util>
 at run time, which will fail if Carp has been invoked after a syntax error.
 
+L<I18N::Langinfo> has been upgraded from version 0.15 to 0.16.
+
+This module is now available on all platforms, emulating the system
+L<nl_langinfo(3)> on systems that lack it.  Some caveats apply, as
+L<detailed in its documentation|I18N::Langinfo>, the most severe being
+that, except for MS Windows, the C<CODESET> item is not implemented on
+those systems, always returning C<"">.
+
+It now sets the UTF-8 flag in its returned scalar if the string contains
+legal non-ASCII UTF-8, and the locale is UTF-8 ([perl #127288].
+
 =back
 
 =head2 Removed Modules and Pragmata
@@ -342,7 +353,10 @@ XXX
 
 =item *
 
-XXX
+The item names passed to the function L<perlapi/Perl_langinfo>,
+introduced in 5.27.4, may no longer be prefixed with C<PERL_>.  For
+example, if you want the current floating point radix character, you
+must call it like C<Perl_langinfo(RADIXCHAR)>.
 
 =back
 
diff --git a/proto.h b/proto.h
index 2259c77e4c..e711e1094a 100644
--- a/proto.h
+++ b/proto.h
@@ -6221,7 +6221,7 @@ PERL_CALLCONV SV* Perl_sv_dup_inc(pTHX_ const SV *const 
sstr, CLONE_PARAMS *cons
        assert(param)
 
 #endif
-#if defined(USE_LOCALE)                    && (   defined(PERL_IN_LOCALE_C)    
        || defined(PERL_IN_MG_C)                || defined (PERL_EXT_POSIX))
+#if defined(USE_LOCALE)                    && (   defined(PERL_IN_LOCALE_C)    
        || defined(PERL_IN_MG_C)                || defined (PERL_EXT_POSIX)     
        || defined (PERL_EXT_LANGINFO))
 PERL_CALLCONV bool     Perl__is_cur_LC_category_utf8(pTHX_ int category);
 #endif
 #if defined(USE_LOCALE_COLLATE)
diff --git a/symbian/install.cfg b/symbian/install.cfg
index 28760b76c2..918d300826 100644
--- a/symbian/install.cfg
+++ b/symbian/install.cfg
@@ -99,7 +99,7 @@ ext   XSLoader
 # ext  Devel/DProf             nonconst
 # ext  Devel/PPPort            PORT
 # ext  Encode                  nonconst Encode/encode.h def_t.c encengine.c
-# ext  I18N/Langinfo           PORT
+ext    I18N/Langinfo           PORT
 # ext  IPC/SysV                PORT
 # ext  NDBM_File               PORT
 # ext  ODBM_File               PORT
diff --git a/win32/FindExt.pm b/win32/FindExt.pm
index 5f45a73484..4d4682171c 100644
--- a/win32/FindExt.pm
+++ b/win32/FindExt.pm
@@ -6,7 +6,7 @@ use strict;
 use warnings;
 
 my $no = join('|',qw(Amiga.* GDBM_File ODBM_File NDBM_File DB_File
-                     VMS.* Sys-Syslog IPC-SysV I18N-Langinfo));
+                     VMS.* Sys-Syslog IPC-SysV));
 $no = qr/^(?:$no)$/i;
 
 sub apply_config {
@@ -18,7 +18,6 @@ sub apply_config {
     # duplicates logic from Configure (mostly)
     push @no, "DB_File" unless $config->{i_db};
     push @no, "GDBM_File" unless $config->{i_gdbm};
-    push @no, "I18N-Langinfo" unless $config->{i_langinfo} && 
$config->{d_nl_langinfo};
     push @no, "IPC-SysV" unless $config->{d_msg} || $config->{d_sem} || 
$config->{d_shm};
     push @no, "NDBM_File" unless $config->{d_ndbm};
     push @no, "ODBM_File"

-- 
Perl5 Master Repository

Reply via email to