Imported Upstream version 5.33.5 upstream/5.33.5
authorDongHun Kwak <dh0128.kwak@samsung.com>
Fri, 21 Jan 2022 04:41:42 +0000 (13:41 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Fri, 21 Jan 2022 04:41:42 +0000 (13:41 +0900)
383 files changed:
.git_patch [new file with mode: 0644]
.gitattributes [new file with mode: 0644]
.github/ISSUE_TEMPLATE/01-perlbug-core.md [new file with mode: 0644]
.github/ISSUE_TEMPLATE/02-perlbug-docs.md [new file with mode: 0644]
.github/ISSUE_TEMPLATE/config.yml [new file with mode: 0644]
.github/ISSUE_TEMPLATE/feature_request.md [new file with mode: 0644]
.github/workflows/detect-conflicts.yml [new file with mode: 0644]
.github/workflows/irc-notifications.yaml [new file with mode: 0644]
.github/workflows/testsuite.yml [new file with mode: 0644]
.gitignore [new file with mode: 0644]
.mailmap [new file with mode: 0644]
AUTHORS
Configure
Cross/config.sh-arm-linux
Cross/config.sh-arm-linux-n770
INSTALL
MANIFEST
META.json
META.yml
Makefile.SH
NetWare/Makefile
NetWare/config.wc
NetWare/config_H.wc
Porting/Maintainers.pl
Porting/config.sh
Porting/config_H
Porting/epigraphs.pod
Porting/perldelta_template.pod
Porting/release_managers_guide.pod
Porting/release_schedule.pod
Porting/sync-with-cpan
Porting/todo.pod
README.haiku
README.macosx
README.os2
README.vms
autodoc.pl
av.c
config_h.SH
configure.com
cop.h
cpan/.gitignore [new file with mode: 0644]
cpan/Compress-Raw-Bzip2/.gitignore [new file with mode: 0644]
cpan/Compress-Raw-Zlib/.gitignore [new file with mode: 0644]
cpan/Config-Perl-V/V.pm
cpan/Config-Perl-V/t/35_plv52910g.t [new file with mode: 0644]
cpan/Config-Perl-V/t/36_plv5300.t [new file with mode: 0644]
cpan/Config-Perl-V/t/37_plv53111qm.t [new file with mode: 0644]
cpan/Config-Perl-V/t/38_plv5320tld.t [new file with mode: 0644]
cpan/DB_File/.gitignore [new file with mode: 0644]
cpan/Digest-MD5/.gitignore [new file with mode: 0644]
cpan/Digest-SHA/.gitignore [new file with mode: 0644]
cpan/Encode/.gitignore [new file with mode: 0644]
cpan/Encode/Encode.pm
cpan/Encode/Makefile.PL
cpan/Encode/bin/encguess
cpan/Encode/lib/Encode/GSM0338.pm
cpan/Encode/t/gsm0338.t
cpan/ExtUtils-Install/lib/ExtUtils/Install.pm
cpan/ExtUtils-Install/lib/ExtUtils/Installed.pm
cpan/ExtUtils-Install/lib/ExtUtils/Packlist.pm
cpan/ExtUtils-Install/t/Installed.t
cpan/IO-Compress/.gitignore [new file with mode: 0644]
cpan/IPC-SysV/.gitignore [new file with mode: 0644]
cpan/PerlIO-via-QuotedPrint/lib/PerlIO/via/QuotedPrint.pm
cpan/PerlIO-via-QuotedPrint/t/QuotedPrint.t
cpan/PerlIO-via-QuotedPrint/t/changes.t [new file with mode: 0644]
cpan/PerlIO-via-QuotedPrint/t/critic.t [new file with mode: 0644]
cpan/PerlIO-via-QuotedPrint/t/pod.t [new file with mode: 0644]
cpan/PerlIO-via-QuotedPrint/t/pod_coverage.t [new file with mode: 0644]
cpan/Pod-Checker/.gitignore [new file with mode: 0644]
cpan/Pod-Perldoc/.gitignore [new file with mode: 0644]
cpan/Pod-Usage/.gitignore [new file with mode: 0644]
cpan/Scalar-List-Utils/.gitignore [new file with mode: 0644]
cpan/Socket/.gitignore [new file with mode: 0644]
cpan/Sys-Syslog/.gitignore [new file with mode: 0644]
cpan/Test-Harness/lib/App/Prove.pm
cpan/Test-Harness/lib/App/Prove/State.pm
cpan/Test-Harness/lib/App/Prove/State/Result.pm
cpan/Test-Harness/lib/App/Prove/State/Result/Test.pm
cpan/Test-Harness/lib/TAP/Base.pm
cpan/Test-Harness/lib/TAP/Formatter/Base.pm
cpan/Test-Harness/lib/TAP/Formatter/Color.pm
cpan/Test-Harness/lib/TAP/Formatter/Console.pm
cpan/Test-Harness/lib/TAP/Formatter/Console/ParallelSession.pm
cpan/Test-Harness/lib/TAP/Formatter/Console/Session.pm
cpan/Test-Harness/lib/TAP/Formatter/File.pm
cpan/Test-Harness/lib/TAP/Formatter/File/Session.pm
cpan/Test-Harness/lib/TAP/Formatter/Session.pm
cpan/Test-Harness/lib/TAP/Harness.pm
cpan/Test-Harness/lib/TAP/Harness/Env.pm
cpan/Test-Harness/lib/TAP/Object.pm
cpan/Test-Harness/lib/TAP/Parser.pm
cpan/Test-Harness/lib/TAP/Parser/Aggregator.pm
cpan/Test-Harness/lib/TAP/Parser/Grammar.pm
cpan/Test-Harness/lib/TAP/Parser/Iterator.pm
cpan/Test-Harness/lib/TAP/Parser/Iterator/Array.pm
cpan/Test-Harness/lib/TAP/Parser/Iterator/Process.pm
cpan/Test-Harness/lib/TAP/Parser/Iterator/Stream.pm
cpan/Test-Harness/lib/TAP/Parser/IteratorFactory.pm
cpan/Test-Harness/lib/TAP/Parser/Multiplexer.pm
cpan/Test-Harness/lib/TAP/Parser/Result.pm
cpan/Test-Harness/lib/TAP/Parser/Result/Bailout.pm
cpan/Test-Harness/lib/TAP/Parser/Result/Comment.pm
cpan/Test-Harness/lib/TAP/Parser/Result/Plan.pm
cpan/Test-Harness/lib/TAP/Parser/Result/Pragma.pm
cpan/Test-Harness/lib/TAP/Parser/Result/Test.pm
cpan/Test-Harness/lib/TAP/Parser/Result/Unknown.pm
cpan/Test-Harness/lib/TAP/Parser/Result/Version.pm
cpan/Test-Harness/lib/TAP/Parser/Result/YAML.pm
cpan/Test-Harness/lib/TAP/Parser/ResultFactory.pm
cpan/Test-Harness/lib/TAP/Parser/Scheduler.pm
cpan/Test-Harness/lib/TAP/Parser/Scheduler/Job.pm
cpan/Test-Harness/lib/TAP/Parser/Scheduler/Spinner.pm
cpan/Test-Harness/lib/TAP/Parser/Source.pm
cpan/Test-Harness/lib/TAP/Parser/SourceHandler.pm
cpan/Test-Harness/lib/TAP/Parser/SourceHandler/Executable.pm
cpan/Test-Harness/lib/TAP/Parser/SourceHandler/File.pm
cpan/Test-Harness/lib/TAP/Parser/SourceHandler/Handle.pm
cpan/Test-Harness/lib/TAP/Parser/SourceHandler/Perl.pm
cpan/Test-Harness/lib/TAP/Parser/SourceHandler/RawTAP.pm
cpan/Test-Harness/lib/TAP/Parser/YAMLish/Reader.pm
cpan/Test-Harness/lib/TAP/Parser/YAMLish/Writer.pm
cpan/Test-Harness/lib/Test/Harness.pm
cpan/Test-Harness/t/source.t
cpan/Text-Balanced/lib/Text/Balanced.pm
cpan/Text-Balanced/t/01_compile.t
cpan/Text-Balanced/t/02_extbrk.t
cpan/Text-Balanced/t/03_extcbk.t
cpan/Text-Balanced/t/04_extdel.t
cpan/Text-Balanced/t/05_extmul.t
cpan/Text-Balanced/t/06_extqlk.t
cpan/Text-Balanced/t/07_exttag.t
cpan/Text-Balanced/t/08_extvar.t
cpan/Text-Balanced/t/09_gentag.t
cpan/Text-Balanced/t/94_changes.t [new file with mode: 0644]
cpan/Text-Balanced/t/95_critic.t [new file with mode: 0644]
cpan/Text-Balanced/t/96_pmv.t [new file with mode: 0644]
cpan/Text-Balanced/t/97_pod.t [new file with mode: 0644]
cpan/Text-Balanced/t/98_pod_coverage.t [new file with mode: 0644]
cpan/Unicode-Collate/.gitignore [new file with mode: 0644]
cpan/Win32/.gitignore [new file with mode: 0644]
cpan/Win32API-File/.gitignore [new file with mode: 0644]
cpan/libnet/.gitignore [new file with mode: 0644]
cpan/libnet/Makefile.PL
cpan/libnet/lib/Net/Cmd.pm
cpan/libnet/lib/Net/Config.pm
cpan/libnet/lib/Net/Domain.pm
cpan/libnet/lib/Net/FTP.pm
cpan/libnet/lib/Net/FTP/A.pm
cpan/libnet/lib/Net/FTP/E.pm
cpan/libnet/lib/Net/FTP/I.pm
cpan/libnet/lib/Net/FTP/L.pm
cpan/libnet/lib/Net/FTP/dataconn.pm
cpan/libnet/lib/Net/NNTP.pm
cpan/libnet/lib/Net/Netrc.pm
cpan/libnet/lib/Net/POP3.pm
cpan/libnet/lib/Net/SMTP.pm
cpan/libnet/lib/Net/Time.pm
cpan/libnet/lib/Net/libnetFAQ.pod
cpan/libnet/t/config.t
cpan/libnet/t/datasend.t
cpan/libnet/t/ftp.t
cpan/libnet/t/hostname.t
cpan/libnet/t/libnet_t.pl [deleted file]
cpan/libnet/t/netrc.t
cpan/libnet/t/nntp.t
cpan/libnet/t/nntp_ipv6.t
cpan/libnet/t/nntp_ssl.t
cpan/libnet/t/pop3_ipv6.t
cpan/libnet/t/pop3_ssl.t
cpan/libnet/t/require.t
cpan/libnet/t/smtp.t
cpan/libnet/t/smtp_ipv6.t
cpan/libnet/t/smtp_ssl.t
cpan/libnet/t/time.t
cpan/perlfaq/.gitignore [new file with mode: 0644]
cpan/podlators/.gitignore [new file with mode: 0644]
cygwin/cygwin.c
dist/.gitignore [new file with mode: 0644]
dist/Carp/.gitignore [new file with mode: 0644]
dist/Carp/lib/Carp.pm
dist/Carp/lib/Carp/Heavy.pm
dist/Devel-PPPort/.gitignore [new file with mode: 0644]
dist/ExtUtils-CBuilder/.gitignore [new file with mode: 0644]
dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS.pm
dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS/Constants.pm
dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS/CountLines.pm
dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS/Eval.pm
dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS/Utilities.pm
dist/ExtUtils-ParseXS/lib/perlxs.pod
dist/IO/.gitignore [new file with mode: 0644]
dist/Module-CoreList/.gitignore [new file with mode: 0644]
dist/Module-CoreList/Changes
dist/Module-CoreList/lib/Module/CoreList.pm
dist/Module-CoreList/lib/Module/CoreList/Utils.pm
dist/PathTools/.gitignore [new file with mode: 0644]
dist/PathTools/Cwd.pm
dist/PathTools/Cwd.xs
dist/PathTools/lib/File/Spec.pm
dist/PathTools/lib/File/Spec/AmigaOS.pm
dist/PathTools/lib/File/Spec/Cygwin.pm
dist/PathTools/lib/File/Spec/Epoc.pm
dist/PathTools/lib/File/Spec/Functions.pm
dist/PathTools/lib/File/Spec/Mac.pm
dist/PathTools/lib/File/Spec/OS2.pm
dist/PathTools/lib/File/Spec/Unix.pm
dist/PathTools/lib/File/Spec/VMS.pm
dist/PathTools/lib/File/Spec/Win32.pm
dist/PathTools/t/cwd.t
dist/Safe/.gitignore [new file with mode: 0644]
dist/Search-Dict/.gitignore [new file with mode: 0644]
dist/Storable/.gitignore [new file with mode: 0644]
dist/Storable/t/canonical.t
dist/Time-HiRes/.gitignore [new file with mode: 0644]
dist/Time-HiRes/HiRes.pm
dist/Time-HiRes/HiRes.xs
dist/Unicode-Normalize/.gitignore [new file with mode: 0644]
dist/Unicode-Normalize/Makefile.PL
dist/XSLoader/.gitignore [new file with mode: 0644]
dist/base/.gitignore [new file with mode: 0644]
dist/lib/.gitignore [new file with mode: 0644]
dist/threads/t/libc.t
doio.c
dosish.h
embed.fnc
embed.h
embedvar.h
ext/.gitignore [new file with mode: 0644]
ext/Amiga-ARexx/.gitignore [new file with mode: 0644]
ext/Amiga-Exec/.gitignore [new file with mode: 0644]
ext/B/.gitignore [new file with mode: 0644]
ext/DynaLoader/.gitignore [new file with mode: 0644]
ext/DynaLoader/DynaLoader_pm.PL
ext/DynaLoader/dlutils.c
ext/Errno/.gitignore [new file with mode: 0644]
ext/Fcntl/.gitignore [new file with mode: 0644]
ext/File-Find/lib/File/Find.pm
ext/File-Find/t/find.t
ext/File-Find/t/lib/Testing.pm
ext/File-Find/t/taint.t
ext/File-Glob/.gitignore [new file with mode: 0644]
ext/GDBM_File/.gitignore [new file with mode: 0644]
ext/Hash-Util/.gitignore [new file with mode: 0644]
ext/I18N-Langinfo/.gitignore [new file with mode: 0644]
ext/NDBM_File/.gitignore [new file with mode: 0644]
ext/ODBM_File/.gitignore [new file with mode: 0644]
ext/ODBM_File/ODBM_File.pm
ext/ODBM_File/ODBM_File.xs
ext/Opcode/Opcode.pm
ext/Opcode/Opcode.xs
ext/POSIX/.gitignore [new file with mode: 0644]
ext/POSIX/Makefile.PL
ext/POSIX/POSIX.xs
ext/POSIX/lib/POSIX.pm
ext/POSIX/t/iv_const.t [new file with mode: 0644]
ext/POSIX/t/posix.t
ext/POSIX/t/time.t
ext/POSIX/t/waitpid.t
ext/Pod-Functions/.gitignore [new file with mode: 0644]
ext/Pod-Html/.gitignore [new file with mode: 0644]
ext/SDBM_File/.gitignore [new file with mode: 0644]
ext/VMS-DCLsym/.gitignore [new file with mode: 0644]
ext/VMS-Stdio/.gitignore [new file with mode: 0644]
ext/Win32CORE/.gitignore [new file with mode: 0644]
ext/XS-APItest/.gitignore [new file with mode: 0644]
ext/XS-APItest/APItest.pm
ext/XS-APItest/APItest.xs
ext/XS-Typemap/.gitignore [new file with mode: 0644]
ext/re/.gitignore [new file with mode: 0644]
handy.h
hints/catamount.sh
hints/solaris_2.sh
hv.c
inline.h
intrpvar.h
iperlsys.h
lib/.gitignore [new file with mode: 0644]
lib/B/Op_private.pm
lib/File/Copy.pm
lib/File/Copy.t
lib/perl5db.pl
lib/perl5db.t
lib/warnings.pm
locale.c
makedef.pl
mathoms.c
metaconfig.h
mg.c
numeric.c
op.c
opcode.h
pad.c
patchlevel.h
perl.c
perl.h
perlvars.h
perly.act
perly.c
perly.h
perly.tab
perly.y
plan9/config_sh.sample
pod/.gitignore [new file with mode: 0644]
pod/perl.pod
pod/perl5260delta.pod
pod/perl5334delta.pod [new file with mode: 0644]
pod/perldata.pod
pod/perldelta.pod
pod/perldocstyle.pod [new file with mode: 0644]
pod/perlfunc.pod
pod/perlguts.pod
pod/perlhack.pod
pod/perlhist.pod
pod/perllocale.pod
pod/perlport.pod
pod/perlsub.pod
pod/perltie.pod
pod/perlvar.pod
pp.c
pp_ctl.c
pp_sys.c
proto.h
regcharclass.h
regcomp.c
regen/opcode.pl
regen/regcharclass.pl
regen/regcharclass_multi_char_folds.pl
regen/regcomp.pl
regen/unicode_constants.pl
regen/warnings.pl
regen_perly.pl
regexec.c
regexp.h
regnodes.h
scope.c
scope.h
sv.c
sv.h
t/base/num.t
t/comp/parser.t
t/harness
t/io/msg.t [new file with mode: 0644]
t/io/sem.t
t/io/shm.t
t/lib/croak/toke
t/lib/warnings/2use
t/op/magic.t
t/op/oct.t
t/op/stat.t
t/op/taint.t
t/porting/customized.dat
t/porting/known_pod_issues.dat
t/porting/podcheck.t
t/win32/stat.t [new file with mode: 0644]
t/win32/symlink.t [new file with mode: 0644]
thread.h
time64.c
time64_config.h
toke.c
uconfig.h
uconfig.sh
uconfig64.sh
unicode_constants.h
utf8.c
utf8.h
util.c
utils/.gitignore [new file with mode: 0644]
vms/descrip_mms.template
win32/.gitignore [new file with mode: 0644]
win32/GNUmakefile
win32/Makefile
win32/config.gc
win32/config.vc
win32/config_H.gc
win32/config_H.vc
win32/config_sh.PL
win32/makefile.mk
win32/perlhost.h
win32/pod.mak
win32/win32.c
win32/win32.h
win32/win32iop.h

diff --git a/.git_patch b/.git_patch
new file mode 100644 (file)
index 0000000..f90c1d5
--- /dev/null
@@ -0,0 +1 @@
+b0d2479a156520088b5c09de9b5322bb2381c19c|2020-12-20 11:19:16 +0100|tag: v5.33.5
diff --git a/.gitattributes b/.gitattributes
new file mode 100644 (file)
index 0000000..a5cc737
--- /dev/null
@@ -0,0 +1 @@
+.git_patch export-subst
diff --git a/.github/ISSUE_TEMPLATE/01-perlbug-core.md b/.github/ISSUE_TEMPLATE/01-perlbug-core.md
new file mode 100644 (file)
index 0000000..71a8c0e
--- /dev/null
@@ -0,0 +1,35 @@
+---
+name: Report a Perl 5 Bug
+about: Create a report to help us improve Perl 5
+title: ''
+labels: Needs Triage, bug, severity low
+assignees: ''
+
+---
+<!--
+Note: you can also replace the whole content with a file generated by the perlbug utility;
+perlbug reports by email are no longer supported.
+Be sure to enclose your perl configuration in a fenced code block to preserve formatting:
+https://help.github.com/en/github/writing-on-github/creating-and-highlighting-code-blocks
+-->
+
+<!--
+If your bug is about a Perl core module rather than a core language
+feature, please enter its name after.
+-->
+Module:
+
+**Description**
+<!-- A clear and concise description of what the bug is. -->
+
+**Steps to Reproduce**
+<!-- A one-liner or script to reproduce the issue. -->
+
+**Expected behavior**
+<!-- A clear and concise description of what you expected to happen. -->
+
+**Perl configuration**
+<!-- Please paste `perl -V` output just below. -->
+```
+# perl -V output goes here
+```
diff --git a/.github/ISSUE_TEMPLATE/02-perlbug-docs.md b/.github/ISSUE_TEMPLATE/02-perlbug-docs.md
new file mode 100644 (file)
index 0000000..6e6a302
--- /dev/null
@@ -0,0 +1,14 @@
+---
+name: Report a Perl 5 Documentation Issue
+about: Create a report to help us improve Perl 5
+title: '[doc] '
+labels: Needs Triage, bug, documentation, severity low
+assignees: ''
+
+---
+
+**Where**
+<!-- What module, script or perldoc URL needs to be fixed? -->
+
+**Description**
+<!--  Please describe the documentation issue here. -->
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644 (file)
index 0000000..7e350cd
--- /dev/null
@@ -0,0 +1,5 @@
+blank_issues_enabled: false
+contact_links:
+  - name: Report a CPAN Module Issue
+    url: https://metacpan.org
+    about: Please report issues with CPAN modules to their preferred bugtracker as indicated on their MetaCPAN page
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644 (file)
index 0000000..f9d3c09
--- /dev/null
@@ -0,0 +1,13 @@
+---
+name: Feature request
+about: Suggest an idea to help us improve Perl 5
+title: "[feature]"
+labels: Feature Request, Needs Triage
+assignees: ''
+
+---
+
+**Please do not report bugs as part of a feature request**
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
diff --git a/.github/workflows/detect-conflicts.yml b/.github/workflows/detect-conflicts.yml
new file mode 100644 (file)
index 0000000..ba81df0
--- /dev/null
@@ -0,0 +1,18 @@
+on:
+  push:
+    branches:
+      - blead
+jobs:
+  conflicts:
+    runs-on: ubuntu-latest
+    if: ( github.event.pull_request.head.repo.full_name == 'Perl/perl5' || github.repository == 'Perl/perl5' )
+    steps:
+      # improve the chance that the mergeable status is computed
+      #- uses: mschilde/auto-label-merge-conflicts@master
+      # use fork to use custom timeout need https://github.com/mschilde/auto-label-merge-conflicts/pull/43
+      - uses: atoomic/auto-label-merge-conflicts@custom
+        with:
+          CONFLICT_LABEL_NAME: "hasConflicts"
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          MAX_RETRIES: 600 # 600 * 10 sec => 100 minutes
+          WAIT_MS: 10000 # 10 sec
diff --git a/.github/workflows/irc-notifications.yaml b/.github/workflows/irc-notifications.yaml
new file mode 100644 (file)
index 0000000..7cb111e
--- /dev/null
@@ -0,0 +1,134 @@
+name: "Push Notification"
+on: [push, pull_request]
+# add create for tracking tags
+
+# IRC colors: https://modern.ircdocs.horse/formatting.html
+# yaml formating: https://www.yaml.info/learn/quote.html
+
+jobs:
+  notify-irc:
+    runs-on: ubuntu-latest
+    # only on main repo
+    if: ( github.event.pull_request.head.repo.full_name == 'Perl/perl5' || github.repository == 'Perl/perl5' )
+
+    env:
+      server: ssl.irc.perl.org
+      port: 7062
+      channel: "#p5p-commits"
+
+    steps:
+      - name: Dump GitHub context
+        env:
+          GITHUB_CONTEXT: ${{ toJson(github) }}
+        run: echo "$GITHUB_CONTEXT"
+
+      - name: setup branch env name
+        run: |
+          ref="${github_ref/refs\/heads\//}"
+          echo "ref=$ref" >> $GITHUB_ENV
+        env:
+          github_ref: ${{ github.event.ref }}
+
+      - name: Setup commit message SUMUP env
+        env:
+          TXT: ${{ join(github.event.commits.*.message, '\n') }}
+          C1: ${{ github.event.commits[0].message }}
+          C2: ${{ github.event.commits[1].message }}
+          C3: ${{ github.event.commits[2].message }}
+          C4: ${{ github.event.commits[3].message }}
+          C5: ${{ github.event.commits[4].message }}
+        run: |
+          # -------------------------------------
+          echo "# original commit message"
+          echo "TXT=$TXT"
+
+          # -------------------------------------
+          echo "# Last 5 commits message"
+          echo "C1=$C1"
+          echo "C2=$C2"
+          echo "C3=$C3"
+          echo "C4=$C4"
+          echo "C5=$C5"
+
+          # -------------------------------------
+          echo "# script parse.pl"
+          cat <<'EOS' > parse.pl
+          use v5.14; use strict; use warnings;
+          my $txt = join "\n", map { $ENV{"C$_"} // '' } 1..5;
+          $txt =~ s{\\n}{\n}g; $txt =~ s{\\t}{ }g; $txt =~ s{\t}{ }g;
+          my @l = split( "\n", $txt );
+          my $max = 5;
+          @l = ( @l[0..$max], "..." ) if @l > $max;
+          @l = grep { $_ !~ m{^EOF} } @l;
+          say( join( "\n", @l ) );
+          EOS
+
+          # -------------------------------------
+          echo "# testing script"
+          perl parse.pl
+
+          # -------------------------------------
+          echo "# setup SUMUP environment variable"
+          echo 'SUMUP<<EOF' >> $GITHUB_ENV
+          perl parse.pl     >> $GITHUB_ENV
+          echo 'EOF'        >> $GITHUB_ENV
+
+          # -------------------------------------
+          echo "# done"
+
+      - name: checking SUMUP variable
+        run: |
+          echo "SUMUP: $SUMUP"
+
+      - name: irc push
+        uses: rectalogic/notify-irc@v1
+        if: github.event_name == 'push' && github.ref != 'refs/heads/blead'
+        with:
+          server: ${{ env.server }}
+          port: ${{ env.port }}
+          channel: ${{ env.channel }}
+          nickname: Commit
+          message:
+            "\x037${{ github.actor }}\x0F pushed to branch \x033${{ env.ref }}\x0F\n\
+            ${{ env.SUMUP }}\n\
+            ${{ github.event.compare }}"
+
+      - name: irc push to blead
+        uses: rectalogic/notify-irc@v1
+        if: github.event_name == 'push' && github.ref == 'refs/heads/blead'
+        with:
+          server: ${{ env.server }}
+          port: ${{ env.port }}
+          channel: ${{ env.channel }}
+          nickname: inBlead
+          message:
+            "\x0313[blead]\x0F \x037${{ github.actor }}\x0F pushed to blead\n\
+            ${{ env.SUMUP }}\n\
+            ${{ github.event.compare }}"
+
+      - name: irc opened pull request
+        uses: rectalogic/notify-irc@v1
+        if: github.event_name == 'pull_request' && github.event.action == 'opened'
+        with:
+          server: ${{ env.server }}
+          port: ${{ env.port }}
+          channel: ${{ env.channel }}
+          nickname: Pull-Request
+          message:
+            "\x037${{ github.actor }}\x0F opened PR #${{ github.event.pull_request.number }}\n\
+            ${{ github.event.pull_request.title }}\n\
+            ${{ github.event.pull_request.body }}\n\
+            ${{ github.event.pull_request.html_url }}"
+
+      - name: irc synchronize pull request
+        uses: rectalogic/notify-irc@v1
+        if: github.event_name == 'pull_request' && github.event.action == 'synchronize'
+        with:
+          server: ${{ env.server }}
+          port: ${{ env.port }}
+          channel: ${{ env.channel }}
+          nickname: Pull-Request
+          message:
+            "\x037${{ github.actor }}\x0F updated PR #${{ github.event.pull_request.number }}\n\
+            ${{ github.event.pull_request.title }}\n\
+            ${{ github.event.pull_request.html_url }}"
diff --git a/.github/workflows/testsuite.yml b/.github/workflows/testsuite.yml
new file mode 100644 (file)
index 0000000..ad3b097
--- /dev/null
@@ -0,0 +1,419 @@
+name: testsuite
+
+on:
+  push:
+    branches:
+      - "**"
+    tags-ignore:
+      - "*"
+  pull_request:
+
+jobs:
+  #  ___           _         ___       __                    _   _
+  # / __|_ __  ___| |_____  |_ _|_ _  / _|___ _ _ _ __  __ _| |_(_)___ _ _  ___
+  # \__ \ '  \/ _ \ / / -_)  | || ' \|  _/ _ \ '_| '  \/ _` |  _| / _ \ ' \(_-<
+  # |___/_|_|_\___/_\_\___| |___|_||_|_| \___/_| |_|_|_\__,_|\__|_\___/_||_/__/
+
+  authors:
+    runs-on: ubuntu-latest
+    if: ( github.event.pull_request.head.repo.full_name == 'Perl/perl5' || github.repository == 'Perl/perl5' ) && github.base_ref != ''
+    continue-on-error: true
+
+    steps:
+      - name: Dump GitHub context
+        env:
+          GITHUB_CONTEXT: ${{ toJson(github) }}
+        run: echo "$GITHUB_CONTEXT"
+      - uses: actions/checkout@v2
+        with:
+          fetch-depth: 1000
+      - name: git setup
+        run: |
+          echo "Pull request authors"
+          echo "# git merge-base origin/${BASE_REF} HEAD"
+          git config diff.renameLimit 999999
+          git fetch --depth=1000 origin ${BASE_REF}
+        env:
+          BASE_REF: ${{ github.base_ref }}
+      - name: Involved authors
+        run: |
+          git log --pretty=format:"Author: %an <%ae>" origin/${BASE_REF}...${SHA}^2 | sort -u
+        env:
+          BASE_REF: ${{ github.base_ref }}
+          SHA: ${{ github.sha }}
+
+  #  ___            _ _           ___ _           _
+  # / __| __ _ _ _ (_) |_ _  _   / __| |_  ___ __| |__
+  # \__ \/ _` | ' \| |  _| || | | (__| ' \/ -_) _| / /
+  # |___/\__,_|_||_|_|\__|\_, |  \___|_||_\___\__|_\_\
+  #                       |__/
+  # ascii art small font from https://ascii.co.uk/text
+
+  sanity_check:
+    name: "Sanity: Linux -Dusethreads"
+    runs-on: ubuntu-latest
+    timeout-minutes: 120
+
+    env:
+      PERL_SKIP_TTY_TEST: 1
+      CONTINUOUS_INTEGRATION: 1
+      WORKSPACE: ${{ github.workspace }}
+
+    outputs:
+      run_all_jobs: ${{ steps.check_extended_testing.outputs.run_all_jobs }}
+
+    steps:
+      - name: Dump GitHub context
+        env:
+          GITHUB_CONTEXT: ${{ toJson(github) }}
+        run: echo "$GITHUB_CONTEXT"
+      - uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+      - name: git cfg + fetch tags
+        run: |
+          git config diff.renameLimit 999999
+          git fetch --depth=1 origin +refs/tags/*:refs/tags/*
+      - name: Configure
+        run: |
+          ./Configure -des -Dusedevel ${CONFIGURE_ARGS} -Dprefix="$HOME/perl-blead" -DDEBUGGING
+        env:
+          CONFIGURE_ARGS: "-Dusethreads"
+      - name: Build
+        run: |
+          make -j2
+      - name: Run Tests
+        run: |
+          TEST_JOBS=2 make -j2 test
+
+      # Set a variable for dependent jobs to signal if full testsuite is enabled
+      - name: "Check if EXTENDED_TESTING is set"
+        id: check_extended_testing
+        env:
+          EXTENDED_TESTING: ${{ secrets.EXTENDED_TESTING }}
+          CURRENT_REPOSITORY: ${{ github.repository }}
+        run: |
+          if [[ -z "${EXTENDED_TESTING}" && "${CURRENT_REPOSITORY}" != 'Perl/perl5' ]]; then
+            echo "Skipping extended test jobs."
+            echo "::set-output name=run_all_jobs::false"
+          else
+            echo "Running all test jobs"
+            echo "::set-output name=run_all_jobs::true"
+          fi
+
+  #  _ _
+  # | (_)_ _ _  ___ __
+  # | | | ' \ || \ \ /
+  # |_|_|_||_\_,_/_\_\
+
+  linux:
+    runs-on: ubuntu-latest
+    timeout-minutes: 120
+    needs: sanity_check
+    if: needs.sanity_check.outputs.run_all_jobs == 'true'
+
+    env:
+      PERL_SKIP_TTY_TEST: 1
+      CONTINUOUS_INTEGRATION: 1
+      WORKSPACE: ${{ github.workspace }}
+
+    strategy:
+      fail-fast: false
+      matrix:
+        # exercise a variety of build options
+        # threads often cause build issues
+        CONFIGURE_ARGS:
+          - "-Uusethreads"
+          #- "-Dusethreads" # already tested above by sanity_check
+          - "-Duseshrplib -Dusesitecustomize -Duselongdouble PERL_UNICODE='' LANG='en_US.UTF-8'"
+          - "-Duseshrplib -Dusequadmath -Dusecbacktrace -Dusethreads PERL_UNICODE='' LANG='de_DE.UTF-8'"
+          - "-Duserelocatableinc"
+          - "-Dcc='clang'"
+
+    steps:
+      - uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+      - name: git cfg + fetch tags
+        run: |
+          git config diff.renameLimit 999999
+          git fetch --depth=1 origin +refs/tags/*:refs/tags/*
+      - name: Configure
+        run: |
+          ./Configure -des -Dusedevel ${{ matrix.CONFIGURE_ARGS }} -Dprefix="$HOME/perl-blead" -DDEBUGGING
+      - name: Build
+        run: |
+          make -j2
+      - name: Run Tests
+        run: |
+          TEST_JOBS=2 make -j2 test
+
+  #===============================================
+
+  linux-i386:
+    name: "linux i386/ubuntu"
+    runs-on: ubuntu-latest
+    timeout-minutes: 120
+    needs: sanity_check
+    if: needs.sanity_check.outputs.run_all_jobs == 'true'
+
+    # https://hub.docker.com/r/i386/ubuntu/
+    container:
+      image: i386/ubuntu:latest
+      env:
+        PERL_SKIP_TTY_TEST: 1
+        CONTINUOUS_INTEGRATION: 1
+        WORKSPACE: ${{ github.workspace }}
+
+    strategy:
+      fail-fast: false
+      matrix:
+        CONFIGURE_ARGS:
+          - "-Dusedevel"
+
+    steps:
+      - name: Install System dependencies
+        run: |
+          apt-get update ||:
+          apt-get -y install build-essential git-core
+
+      # actions/checkout@v2 doesn't work in a container, so we use v1.
+      - uses: actions/checkout@v1
+      - name: fix git remote credential
+        run: git remote set-url origin "https://$GITHUB_ACTOR:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY"
+      - name: git cfg + fetch tags
+        run: |
+          git config diff.renameLimit 999999
+          git fetch --depth=1 origin +refs/tags/*:refs/tags/*
+      - name: Configure
+        run: |
+          ./Configure -des -Dusedevel ${{ matrix.CONFIGURE_ARGS }} -Dprefix="$HOME/perl-blead" -DDEBUGGING
+      - name: Build
+        run: |
+          make -j2
+      - name: Run Tests
+        run: |
+          TEST_JOBS=2 make -j2 test
+
+  #                 ___  ___
+  #  _ __  __ _ __ / _ \/ __|
+  # | '  \/ _` / _| (_) \__ \
+  # |_|_|_\__,_\__|\___/|___/
+
+  smoke-macos-catalina-xcode12:
+    name: "macOS (catalina) xcode 12"
+    runs-on: macos-10.15
+    timeout-minutes: 120
+    needs: sanity_check
+    if: needs.sanity_check.outputs.run_all_jobs == 'true'
+
+    env:
+      PERL_SKIP_TTY_TEST: 1
+      CONTINUOUS_INTEGRATION: 1
+
+    steps:
+      - uses: actions/checkout@v2
+        with:
+          fetch-depth: 10
+      - name: Configure
+        run: |
+          export SDK=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk
+          sh ./Configure -des -Dusedevel
+      - name: Build
+        run: |
+          make -j2
+      - name: Run Tests
+        run: |
+          make -j2 test
+
+  #         _         _
+  # __ __ _(_)_ _  __| |_____ __ _____
+  # \ V  V / | ' \/ _` / _ \ V  V (_-<
+  #  \_/\_/|_|_||_\__,_\___/\_/\_//__/
+
+  windows-msvc142:
+    name: "Windows msvc142"
+    runs-on: windows-latest
+    timeout-minutes: 120
+    needs: sanity_check
+    if: needs.sanity_check.outputs.run_all_jobs == 'true'
+
+    env:
+      PERL_SKIP_TTY_TEST: 1
+      CONTINUOUS_INTEGRATION: 1
+
+    steps:
+      - run: git config --global core.autocrlf false
+      - uses: actions/checkout@v2
+        with:
+          fetch-depth: 10
+      #- name: Install clcache
+      #  shell: cmd
+      #  run: |
+      #    curl -L https://github.com/frerich/clcache/releases/download/v4.2.0/clcache.4.2.0.nupkg --output clcache.4.2.0.nupkg
+      #    choco install clcache --source=.
+      #- name: find home directory
+      #  shell: cmd
+      #  run: |
+      #    set
+      #- name: C compiler cache
+      #  id: clcache
+      #  uses: actions/cache@v1
+      #  with:
+      #    path: $HOME\clcache
+      #    key: ${{ runner.os }}-x64
+      #- name: Set up Perl build environment
+      #  # pushd "C:\Program Files (x86)\Microsoft Visual Studio\Installer\"
+      #  # for /f "delims=" %%x in ('.\vswhere.exe -latest -property InstallationPath') do set VSPATH=%%x
+      #  # popd
+      #  # call "%VSPATH%\VC\Auxiliary\Build\vcvarsall.bat" x64
+      #  #run: |
+      - name: Build
+        shell: cmd
+        run: |
+          call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
+          cd win32
+          nmake CCTYPE=MSVC142
+      - name: Run Tests
+        shell: cmd
+        run: |
+          call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
+          cd win32
+          nmake CCTYPE=MSVC142 test
+
+  #===============================================
+
+  windows-msvc100:
+    name: "Windows msvc100"
+    runs-on: windows-latest
+    timeout-minutes: 120
+    needs: sanity_check
+    if: needs.sanity_check.outputs.run_all_jobs == 'true'
+
+    env:
+      PERL_SKIP_TTY_TEST: 1
+      CONTINUOUS_INTEGRATION: 1
+
+    steps:
+      - run: git config --global core.autocrlf false
+      - uses: actions/checkout@v2
+        with:
+          fetch-depth: 10
+      - uses: actions/cache@v2
+        with:
+          path: |
+            ${{ github.workspace }}\choco-cache
+          key: v2-msvc100
+      - name: Set up MSVC100
+        run: |
+          choco config set cacheLocation "${{ github.workspace }}\choco-cache"
+          choco install vcexpress2010
+      - name: Help
+        shell: cmd
+        run: |
+          call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" /help
+      - name: Build
+        shell: cmd
+        run: |
+          call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86
+          cd win32
+          nmake CCTYPE=MSVC100 WIN64=undef
+      - name: Run Tests
+        shell: cmd
+        run: |
+          call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86
+          cd win32
+          nmake CCTYPE=MSVC100 WIN64=undef test
+
+  #===============================================
+
+  mingw64:
+    name: "Windows mingw64"
+    runs-on: windows-latest
+    timeout-minutes: 120
+    needs: sanity_check
+    if: needs.sanity_check.outputs.run_all_jobs == 'true'
+
+    env:
+      PERL_SKIP_TTY_TEST: 1
+      CONTINUOUS_INTEGRATION: 1
+
+    steps:
+      - run: git config --global core.autocrlf false
+      - uses: actions/checkout@v2
+        with:
+          fetch-depth: 10
+      - name: Set up Perl build environment
+        run: |
+          # skip installing perl if it is already installed.
+          if (!(Test-Path "C:\strawberry\perl\bin")) {
+            choco install strawberryperl
+          }
+          echo @"
+          C:\strawberry\c\bin
+          C:\strawberry\perl\site\bin
+          C:\strawberry\perl\bin
+          "@ |
+            Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
+      - name: Host perl -V
+        run: perl -V
+      - name: gcc --version
+        run: gcc --version
+      - name: Build
+        shell: cmd
+        run: |
+          cd win32
+          gmake -f GNUMakefile -j2
+      - name: Run Tests
+        shell: cmd
+        run: |
+          cd win32
+          set HARNESS_OPTIONS=j2
+          set CCHOME=C:\strawberry\c
+          gmake -f GNUMakefile test
+
+  #===============================================
+
+  cygwin:
+    name: "cygwin"
+    runs-on: windows-latest
+    timeout-minutes: 120
+    needs: sanity_check
+    if: needs.sanity_check.outputs.run_all_jobs == 'true'
+
+    env:
+      PERL_SKIP_TTY_TEST: 1
+      CONTINUOUS_INTEGRATION: 1
+
+    steps:
+      # we use Cygwin git, so no need to configure git here.
+
+      - name: Set up Cygwin
+        shell: cmd
+        run: |
+          choco install cygwin --params="/InstallDir:%GITHUB_WORKSPACE%\cygwin"
+          choco install cyg-get
+          cyg-get cygwin-devel gcc-core gcc gcc-g++ make cygwin64-w32api-headers binutils libtool git ccache
+      - name: Check out using Cygwin git, to ensure correct file permissions
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        shell: cmd
+        run: |
+          path %GITHUB_WORKSPACE%\cygwin\bin;%GITHUB_WORKSPACE%\cygwin\usr\bin
+          sh -c "git config --global core.autocrlf false"
+          sh -c "mkdir -p ~; cd ~; git clone -qn \"https://$GITHUB_ACTOR:$GITHUB_TOKEN@github.com/$GITHUB_REPOSITORY\" work ; cd work ; if [ \"$GITHUB_EVENT_NAME\" = pull_request ] ; then git fetch origin \"$GITHUB_REF\" && git checkout FETCH_HEAD ; else  git checkout \"$GITHUB_SHA\" ; fi"
+      - name: Configure
+        shell: cmd
+        run: |
+          path %GITHUB_WORKSPACE%\cygwin\bin;%GITHUB_WORKSPACE%\cygwin\usr\bin
+          sh -c "cd ~/work; ./Configure -des -Dusedevel -Doptimize=-g -DDEBUGGING"
+      - name: Build
+        shell: cmd
+        run: |
+          path %GITHUB_WORKSPACE%\cygwin\bin;%GITHUB_WORKSPACE%\cygwin\usr\bin
+          sh -c "cd ~/work; make -j2"
+      - name: Run Tests
+        shell: cmd
+        run: |
+          path %GITHUB_WORKSPACE%\cygwin\bin;%GITHUB_WORKSPACE%\cygwin\usr\bin
+          sh -c "cd ~/work; make -j2 test"
diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..4fcfe62
--- /dev/null
@@ -0,0 +1,201 @@
+# ignore .patch from rsync, and any generated patch files from git-am
+/*.patch
+# ignore local .config files
+.config
+# these are generated by make_patchnum.sh from git or from a .patchfile
+.sha1
+git_version.h
+
+# ignore bug*.pl
+bug*.pl
+
+# Exists during ./Configure
+/UU
+/host
+
+# Tools for cross-compile remote testing:
+/Cross/from-*
+/Cross/mkdir
+/Cross/run-*
+/Cross/to-*
+
+# files produced by './configure.gnu' on a Linux machine
+/Makefile
+/Policy.sh
+/cflags
+/config.h
+/config.sh
+/makeaperl
+/makedepend
+/makedir
+/makefile
+/myconfig
+/opmini.c
+/perlmain.c
+/perlmini.c
+/pod/Makefile
+/preload
+/runtests
+/writemain
+/x2p/Makefile
+/x2p/cflags
+/x2p/makefile
+
+# generated for configuration overrides, eg Solaris
+/config.over
+/config.arch
+
+# alternative names on OS X
+/GNUmakefile
+/x2p/GNUmakefile
+
+# produced by dtrace -H when configured with usedtrace
+perldtrace.h
+
+# general build products
+*.o
+*.a
+*.so
+*.i
+*.old
+*.xsc
+
+# general build products (darwin)
+*.dylib
+*.DS_Store
+
+# general build products (Win32)
+*.def
+*.dll
+*.exe
+*.exp
+*.ico
+*.ilk
+*.lib
+*.obj
+*.pdb
+*.res
+*.RES
+
+# gcov build products. see L<perlhack/"GCC gcov Profiling">
+*.gcov
+*.gcda
+*.gcno
+
+dll.base
+/splittree.pl
+
+# generated by make on cygwin
+/cygwin.c
+
+# ?
+ext.libs
+
+# these are scattered everywhere, ignore them
+.exists
+MYMETA.*
+
+/miniperl
+/perl
+
+/extra.pods
+/generate_uudmap
+/uni.data
+/uudmap.h
+/bitcount.h
+/mg_data.h
+
+# Build products that we can't infer are generated by conventional extensions
+# (ie all the special cases that would take more code than just adding them
+# here):
+lib/CORE/
+lib/Config_git.pl
+lib/Config_heavy.pl
+lib/Config.pm
+lib/Config.pod
+lib/Cross.pm
+lib/ExtUtils/MANIFEST.SKIP
+lib/ExtUtils/xsubpp
+lib/auto/
+lib/perldoc.pod
+lib/buildcustomize.pl
+lib/unicore/CombiningClass.pl
+lib/unicore/Decomposition.pl
+lib/unicore/Name.pl
+lib/unicore/Name.pm
+lib/unicore/TestProp.pl
+lib/unicore/To/
+lib/unicore/UCD.pl
+lib/unicore/lib/
+lib/unicore/mktables.lst
+
+# generated by WinCE build
+xlib/
+
+# test byproducts
+t/rantests
+t/tmp*
+t/perl
+t/test_state
+*.output
+*.tmp
+*.bak
+t/*.ph
+t/lib/*.ph
+
+# t/op/require.t byproducts
+t/bleah.pm
+t/bleah.do
+t/bleah.flg
+t/urkkk.pm
+t/urkkk.pmc
+t/krunch.pm
+t/krunch.pmc
+t/whap.pm
+t/whap.pmc
+
+# make_ext.pl cleanup scripts
+realclean.sh
+veryclean.sh
+
+# metaconfig needs these three symlinks
+.package
+U
+MANIFEST.new
+
+# this is used to auto-sort the MANIFEST
+MANIFEST.srt
+
+# ignore editor droppings
+*.swp
+*~
+.#*
+
+# test.valgrind final outputs, excluding intermediate files (pls report)
+*.cachegrind
+*.perf-stat
+*.valgrind
+
+# dont show .gdb_history files
+.gdb_history
+
+# cscope -b
+cscope.out
+# cscope -q
+cscope.in.out
+cscope.po.out
+
+# generated by the top level install.html target. XXX Why does it need this?
+/vms/README_vms.pod
+
+# ctags
+tags
+TAGS
+# gtags
+GPATH
+GRPATH
+GRTAGS
+GTAGS
+
+# generated by Porting/sync-with-cpan
+/make.log
diff --git a/.mailmap b/.mailmap
new file mode 100644 (file)
index 0000000..e09fdab
--- /dev/null
+++ b/.mailmap
@@ -0,0 +1,71 @@
+# https://www.kernel.org/pub/software/scm/git/docs/git-shortlog.html#_mapping_authors
+Jarkko Hietaniemi <jhi@iki.fi> <jhi@alpha.hut.fi>
+Jarkko Hietaniemi <jhi@iki.fi> <Jarkko.Hietaniemi@cc.hut.fi>
+Jarkko Hietaniemi <jhi@iki.fi> <jhi@cc.hut.fi>
+Jarkko Hietaniemi <jhi@iki.fi> <jarkko.hietaniemi@booking.com>
+Jarkko Hietaniemi <jhi@iki.fi> <jhi@hut.fi>
+Karl Williamson <khw@cpan.org> <public@khwilliamson.com>
+Karl Williamson <khw@cpan.org> <khw@khw-desktop.(none)>
+Karl Williamson <khw@cpan.org> <khw@karl.(none)>
+Karl Williamson <khw@cpan.org> karl williamson (via RT) <perlbug-followup@perl.org>
+Father Chrysostomos <sprout@cpan.org> Father Chrysostomos <perlbug-followup@perl.org>
+Nicholas Clark <nick@ccl4.org> <Nicholas Clark (sans From field in mail header)>
+Nicholas Clark <nick@ccl4.org> <nicholas@dromedary.ams6.corp.booking.com>
+David Mitchell <davem@iabyn.com> <davem@fdisolutions.com>
+David Mitchell <davem@iabyn.com> <davem@iabyn.com>
+Rafael Garcia-Suarez <rgarciasuarez@gmail.com> Rafael Garcia-Suarez <rgs@consttype.org>
+Gurusamy Sarathy <gsar@cpan.org> <gsar@engin.umich.edu>
+Steve Hay <steve.m.hay@googlemail.com> <SteveHay@planit.com>
+Chris 'BinGOs' Williams <chris@bingosnet.co.uk> Chris BinGOs Williams <chris@bingosnet.co.uk>
+Chris 'BinGOs' Williams <chris@bingosnet.co.uk> Chris Williams <chris@bingosnet.co.uk>
+Tony Cook <tony@develop-help.com> <tony@openbsd32.tony.develop-help.com>
+Tony Cook <tony@develop-help.com> <tony@saturn.(none)>
+Craig A. Berry <craigberry@mac.com> <craig.a.berry@gmail.com>
+Craig A. Berry <craigberry@mac.com> <Craig A. Berry)>
+Nick Ing-Simmons <nik@tiuk.ti.com> <nick@ni-s.u-net.com>
+Nick Ing-Simmons <nik@tiuk.ti.com> <Nick.Ing-Simmons@tiuk.ti.com>
+Ricardo Signes <rjbs@cpan.org> <rjbs@cpan.org>
+Ricardo Signes <rjbs@cpan.org> <rjbs@semiotic.systems>
+Ricardo Signes <rjbs@cpan.org> <rjbs@users.noreply.github.com>
+Yves Orton <demerphq@gmail.com> <yves.orton@booking.com>
+Yves Orton <demerphq@gmail.com> yves orton <unknown>
+Yves Orton <demerphq@gmail.com> Orton, Yves <yves.orton@de.mci.com>
+Yves Orton <demerphq@gmail.com> yves orton <bugs-perl5@bugs6.perl.org>
+Yves Orton <demerphq@gmail.com> <demerphq@gmail.com>
+Yves Orton <demerphq@gmail.com> <demerphq@dromedary.booking.com>
+Yves Orton <demerphq@gmail.com> <demerphq@gemini.(none)>
+Yves Orton <demerphq@gmail.com> <demerphq@camel.booking.com>
+James E Keenan <jkeenan@cpan.org> James E. Keenan <jkeenan@cpan.org>
+James E Keenan <jkeenan@cpan.org> jkeenan
+James E Keenan <jkeenan@cpan.org> <jkeen@verizon.net>
+James E Keenan <jkeenan@cpan.org> James Keenan <jkeenan@dromedary-001.ams6.corp.booking.com>
+Jesse Vincent <jesse@bestpractical.com> Jesse Vincent <jesse@fsck.com>
+Chip Salzenberg <chip@atlantic.net> Chip Salzenberg <chip@perl.com>
+Chip Salzenberg <chip@atlantic.net> Chip Salzenberg <chip@pobox.com>
+Chip Salzenberg <chip@atlantic.net> Chip Salzenberg <salzench@nielsenmedia.com>
+Chip Salzenberg <chip@atlantic.net> Chip Salzenberg <salzench@dun.nielsen.com>
+Chip Salzenberg <chip@atlantic.net> Chip Salzenberg <chip@ci005.sv2.upperbeyond.com>
+Chip Salzenberg <chip@atlantic.net> Chip <chip@pobox.com>
+Hugo van der Sanden <hv@crypt.org> <hv@crypt.compulink.co.uk>
+Hugo van der Sanden <hv@crypt.org> <hv@iii.co.uk>
+Hugo van der Sanden <hv@crypt.org> <hv@crypt.org>
+Andy Dougherty <doughera@lafayette.edu> Andy Dougherty <doughera@lafcol.lafayette.edu>
+Andy Dougherty <doughera@lafayette.edu> Andy Dougherty <doughera@fractal.phys.lafayette.edu>
+Andy Dougherty <doughera@lafayette.edu> Andy Dougherty <doughera.lafayette.edu>
+Andy Dougherty <doughera@lafayette.edu> Andy Dougherty <doughera@newton.phys.lafayette.edu>
+Gisle Aas <gisle@aas.no> Gisle Aas <gisle@activestate.com>
+Gisle Aas <gisle@aas.no> Gisle Aas <aas@bergen.sn.no>
+Nicolas R <atoomic@cpan.org> ☢ ℕicolas ℝ <nicolas@atoomic.org>
+Nicolas R <atoomic@cpan.org> <nicolas@atoomic.org>
+Nicolas R <atoomic@cpan.org> <cpan@atoomic.org>
+Ævar Arnfjörð Bjarmason <avar@cpan.org> Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+Dominic Hargreaves <dom@earth.li> <dom@semmle.com>
+Dominic Dunlop <domo@computer.org> <domo@slipper.ip.lu>
+Dominic Dunlop <domo@computer.org> <domo@tcp.ip.lu>
+David Nicol <davidnicol@gmail.com> david nicol <whatever@davidnicol.com>
+Kurt D. Starsinic <kstar@wolfetech.com> <kstar@www.chapin.edu>
+Kurt D. Starsinic <kstar@wolfetech.com> Kurt Starsinic <kstar@cpan.org>
+Kurt D. Starsinic <kstar@wolfetech.com> Starsinic, Kurt <Kurt_Starsinic@ml.com>
+Audrey Tang <cpan@audreyt.org> Autrijus Tang <unknown>
+Audrey Tang <cpan@audreyt.org> autrijus@ossf.iis.sinica.edu.tw <autrijus@ossf.iis.sinica.edu.tw>
+Aaron Crane <arc@cpan.org> <perl@aaroncrane.co.uk>
diff --git a/AUTHORS b/AUTHORS
index 6ce4fe7..405c70f 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -175,6 +175,7 @@ Brad Lanam                     <bll@gentoo.com>
 Bradley Dean                   <bjdean@bjdean.id.au>
 Bram                           <perl-rt@wizbit.be>
 Brandon Black                  <blblack@gmail.com>
+Branislav Zahradník            <barney@cpan.org>
 Brendan Byrd                   <BBYRD@CPAN.org>
 Brendan O'Dea                  <bod@debian.org>
 Breno G. de Oliveira           <garu@cpan.org>
@@ -555,6 +556,7 @@ Jacinta Richardson             <jarich@perltraining.com.au>
 Jack Shirazi                   <JackS@GemStone.com>
 Jacques Germishuys             <jacquesg@striata.com>
 Jacqui Caren                   <Jacqui.Caren@ig.co.uk>
+Jae Bradley                    <jae.b.bradley@gmail.com>
 Jake Hamby                     <jehamby@lightside.com>
 Jakub Wilk                     <jwilk@jwilk.net>
 James                          <james@rf.net>
@@ -622,6 +624,7 @@ Jim Miner                      <jfm@winternet.com>
 Jim Richardson
 Jim Schneider                  <james.schneider@db.com>
 Jirka Hruška                   <jirka@fud.cz>
+jkahrman                       <jkahrman@users.noreply.github.com>
 Joachim Huober
 Joaquin Ferrero                <explorer@joaquinferrero.com>
 Jochen Wiedmann                <joe@ispsoft.de>
@@ -652,6 +655,7 @@ John Hawkinson                 <jhawk@mit.edu>
 John Heidemann                 <johnh@isi.edu>
 John Holdsworth                <coldwave@bigfoot.com>
 John Hughes                    <john@AtlanTech.COM>
+John Karr                      <brainbuz@brainbuz.org>
 John Kristian                  <jmk2001@engineer.com>
 John L. Allen                  <allen@grumman.com>
 John Lightsey                  <jd@cpanel.net>
@@ -1156,6 +1160,7 @@ Sebastien Barre                <Sebastien.Barre@utc.fr>
 Sergey Alekseev                <varnie29a@mail.ru>
 Sergey Aleynikov               <sergey.aleynikov@gmail.com>
 Sergiy Borodych                <bor@cpan.org>
+Sevan Janiyan                  <venture37@geeklan.co.uk>
 Shawn                          <svicalifornia@gmail.com>
 Shawn M Moore                  <sartak@gmail.com>
 Sherm Pendley                  <sherm@dot-app.org>
index 16d6370..90ea4bd 100755 (executable)
--- a/Configure
+++ b/Configure
@@ -514,6 +514,7 @@ d_gai_strerror=''
 d_Gconvert=''
 d_getaddrinfo=''
 d_getcwd=''
+d_getenv_preserves_other_thread=''
 d_getespwnam=''
 d_getfsstat=''
 d_getgrent=''
@@ -14206,6 +14207,86 @@ eval $inlibc
 set getcwd d_getcwd
 eval $inlibc
 
+: check for getenv behavior
+case "$d_getenv_preserves_other_thread" in
+'')
+$echo "Checking to see if getenv() preserves a different thread's results" >&4
+$cat >try.c <<EOCP
+#$i_stdlib I_STDLIB
+#ifdef I_STDLIB
+#  include <stdlib.h>
+#endif
+#include <stdio.h>
+#include <string.h>
+#$i_pthread I_PTHREAD
+#ifdef I_PTHREAD
+#  include <pthread.h>
+#endif
+
+void *
+thread_start(void * arg)
+{
+    (void *) getenv("HOME");
+}
+
+int main() {
+    char * main_buffer;
+    char save_main_buffer[1000];
+    pthread_t subthread;
+    pthread_attr_t attr;
+
+    main_buffer = getenv("PATH");
+
+    /* If too large for our generous allowance, return we couldn't figure it
+     * out. */
+    if (strlen(main_buffer) >= sizeof(save_main_buffer)) {
+        exit(2);
+    }
+
+    strcpy(save_main_buffer, main_buffer);
+
+    if (pthread_attr_init(&attr) != 0) {
+        exit(2);
+    }
+
+    if (pthread_create(&subthread, &attr, thread_start, NULL) != 0) {
+        exit(2);
+    }
+
+    if (pthread_join(subthread, NULL) != 0) {
+        exit(2);
+    }
+
+    exit(! strcmp(main_buffer, save_main_buffer) == 0);
+}
+EOCP
+val=
+set try
+if eval $compile_ok; then
+        $run ./try
+        rc=$?
+        case "$rc" in
+            0) echo "getenv() didn't destroy another thread's buffer" >&4
+              val=$define
+               ;;
+            1) echo "getenv() does destroy another thread's buffer" >&4
+              val=$undef
+               ;;
+            *) echo "Couldn't determine if getenv() destroys another thread's return value (code=$rc); assuming it does" >&4
+              val=$undef
+               ;;
+        esac
+else
+    echo "(I can't seem to compile the test program.)" >&4
+    echo "Assuming that your C library's getenv destroys another thread's return value." >&4
+    val=$undef
+fi
+set d_getenv_preserves_other_thread
+eval $setvar
+$rm_try
+;;
+esac
+
 : see if getespwnam exists
 set getespwnam d_getespwnam
 eval $inlibc
@@ -24251,6 +24332,7 @@ d_gdbm_ndbm_h_uses_prototypes='$d_gdbm_ndbm_h_uses_prototypes'
 d_gdbmndbm_h_uses_prototypes='$d_gdbmndbm_h_uses_prototypes'
 d_getaddrinfo='$d_getaddrinfo'
 d_getcwd='$d_getcwd'
+d_getenv_preserves_other_thread='$d_getenv_preserves_other_thread'
 d_getespwnam='$d_getespwnam'
 d_getfsstat='$d_getfsstat'
 d_getgrent='$d_getgrent'
index fc03860..170da9b 100644 (file)
@@ -31,12 +31,12 @@ afsroot='/afs'
 alignbytes='4'
 aphostname='/bin/hostname'
 api_revision='5'
-api_subversion='4'
+api_subversion='5'
 api_version='33'
-api_versionstring='5.33.4'
+api_versionstring='5.33.5'
 ar='ar'
-archlib='/usr/lib/perl5/5.33.4/armv4l-linux'
-archlibexp='/usr/lib/perl5/5.33.4/armv4l-linux'
+archlib='/usr/lib/perl5/5.33.5/armv4l-linux'
+archlibexp='/usr/lib/perl5/5.33.5/armv4l-linux'
 archname64=''
 archname='armv4l-linux'
 archobjs=''
@@ -55,7 +55,7 @@ castflags='0'
 cat='cat'
 cc='cc'
 cccdlflags='-fpic'
-ccdlflags='-rdynamic -Wl,-rpath,/usr/lib/perl5/5.33.4/armv4l-linux/CORE'
+ccdlflags='-rdynamic -Wl,-rpath,/usr/lib/perl5/5.33.5/armv4l-linux/CORE'
 ccflags='-fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
 ccflags_uselargefiles='-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
 ccname='arm-linux-gcc'
@@ -248,6 +248,7 @@ d_gdbm_ndbm_h_uses_prototypes='undef'
 d_gdbmndbm_h_uses_prototypes='undef'
 d_getaddrinfo='undef'
 d_getcwd='define'
+d_getenv_preserves_other_thread='define'
 d_getespwnam='undef'
 d_getfsstat='undef'
 d_getgrent='define'
@@ -824,7 +825,7 @@ inc_version_list=' '
 inc_version_list_init='0'
 incpath=''
 inews=''
-installarchlib='./install_me_here/usr/lib/perl5/5.33.4/armv4l-linux'
+installarchlib='./install_me_here/usr/lib/perl5/5.33.5/armv4l-linux'
 installbin='./install_me_here/usr/bin'
 installhtml1dir=''
 installhtml3dir=''
@@ -832,13 +833,13 @@ installman1dir='./install_me_here/usr/share/man/man1'
 installman3dir='./install_me_here/usr/share/man/man3'
 installprefix='./install_me_here/usr'
 installprefixexp='./install_me_here/usr'
-installprivlib='./install_me_here/usr/lib/perl5/5.33.4'
+installprivlib='./install_me_here/usr/lib/perl5/5.33.5'
 installscript='./install_me_here/usr/bin'
-installsitearch='./install_me_here/usr/lib/perl5/site_perl/5.33.4/armv4l-linux'
+installsitearch='./install_me_here/usr/lib/perl5/site_perl/5.33.5/armv4l-linux'
 installsitebin='./install_me_here/usr/bin'
 installsitehtml1dir=''
 installsitehtml3dir=''
-installsitelib='./install_me_here/usr/lib/perl5/site_perl/5.33.4'
+installsitelib='./install_me_here/usr/lib/perl5/site_perl/5.33.5'
 installsiteman1dir='./install_me_here/usr/share/man/man1'
 installsiteman3dir='./install_me_here/usr/share/man/man3'
 installsitescript='./install_me_here/usr/bin'
@@ -972,8 +973,8 @@ pmake=''
 pr=''
 prefix='/usr'
 prefixexp='/usr'
-privlib='/usr/lib/perl5/5.33.4'
-privlibexp='/usr/lib/perl5/5.33.4'
+privlib='/usr/lib/perl5/5.33.5'
+privlibexp='/usr/lib/perl5/5.33.5'
 procselfexe='"/proc/self/exe"'
 prototype='define'
 ptrsize='4'
@@ -1038,17 +1039,17 @@ sig_num='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 sig_num_init='0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 6, 17, 29, 31, 0'
 sig_size='68'
 signal_t='void'
-sitearch='/usr/lib/perl5/site_perl/5.33.4/armv4l-linux'
-sitearchexp='/usr/lib/perl5/site_perl/5.33.4/armv4l-linux'
+sitearch='/usr/lib/perl5/site_perl/5.33.5/armv4l-linux'
+sitearchexp='/usr/lib/perl5/site_perl/5.33.5/armv4l-linux'
 sitebin='/usr/bin'
 sitebinexp='/usr/bin'
 sitehtml1dir=''
 sitehtml1direxp=''
 sitehtml3dir=''
 sitehtml3direxp=''
-sitelib='/usr/lib/perl5/site_perl/5.33.4'
+sitelib='/usr/lib/perl5/site_perl/5.33.5'
 sitelib_stem='/usr/lib/perl5/site_perl'
-sitelibexp='/usr/lib/perl5/site_perl/5.33.4'
+sitelibexp='/usr/lib/perl5/site_perl/5.33.5'
 siteman1dir='/usr/share/man/man1'
 siteman1direxp='/usr/share/man/man1'
 siteman3dir='/usr/share/man/man3'
@@ -1087,7 +1088,7 @@ stdio_stream_array=''
 strerror_r_proto='0'
 strings='/usr/include/string.h'
 submit=''
-subversion='4'
+subversion='5'
 sysman='/usr/share/man/man1'
 tail=''
 tar=''
@@ -1178,8 +1179,8 @@ vendorprefix=''
 vendorprefixexp=''
 vendorscript=''
 vendorscriptexp=''
-version='5.33.4'
-version_patchlevel_string='version 33 subversion 4'
+version='5.33.5'
+version_patchlevel_string='version 33 subversion 5'
 versiononly='undef'
 vi=''
 xlibpth='/usr/lib/386 /lib/386'
@@ -1193,9 +1194,9 @@ config_args=''
 config_argc=0
 PERL_REVISION=5
 PERL_VERSION=33
-PERL_SUBVERSION=4
+PERL_SUBVERSION=5
 PERL_API_REVISION=5
 PERL_API_VERSION=33
-PERL_API_SUBVERSION=4
+PERL_API_SUBVERSION=5
 PERL_PATCHLEVEL=
 PERL_CONFIG_SH=true
index 5f18e7b..668d690 100644 (file)
@@ -31,12 +31,12 @@ afsroot='/afs'
 alignbytes='4'
 aphostname='/bin/hostname'
 api_revision='5'
-api_subversion='4'
+api_subversion='5'
 api_version='33'
-api_versionstring='5.33.4'
+api_versionstring='5.33.5'
 ar='ar'
-archlib='/usr/lib/perl5/5.33.4/armv4l-linux'
-archlibexp='/usr/lib/perl5/5.33.4/armv4l-linux'
+archlib='/usr/lib/perl5/5.33.5/armv4l-linux'
+archlibexp='/usr/lib/perl5/5.33.5/armv4l-linux'
 archname64=''
 archname='armv4l-linux'
 archobjs=''
@@ -54,7 +54,7 @@ castflags='0'
 cat='cat'
 cc='arm-none-linux-gnueabi-gcc'
 cccdlflags='-fpic'
-ccdlflags='-rdynamic -Wl,-rpath,/usr/lib/perl5/5.33.4/armv4l-linux/CORE'
+ccdlflags='-rdynamic -Wl,-rpath,/usr/lib/perl5/5.33.5/armv4l-linux/CORE'
 ccflags='-fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
 ccflags_uselargefiles='-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
 ccname='arm-linux-gcc'
@@ -247,6 +247,7 @@ d_gdbm_ndbm_h_uses_prototypes='undef'
 d_gdbmndbm_h_uses_prototypes='undef'
 d_getaddrinfo='undef'
 d_getcwd='define'
+d_getenv_preserves_other_thread='define'
 d_getespwnam='undef'
 d_getfsstat='undef'
 d_getgrent='define'
@@ -822,7 +823,7 @@ inc_version_list=' '
 inc_version_list_init='0'
 incpath=''
 inews=''
-installarchlib='./install_me_here/usr/lib/perl5/5.33.4/armv4l-linux'
+installarchlib='./install_me_here/usr/lib/perl5/5.33.5/armv4l-linux'
 installbin='./install_me_here/usr/bin'
 installhtml1dir=''
 installhtml3dir=''
@@ -830,13 +831,13 @@ installman1dir='./install_me_here/usr/share/man/man1'
 installman3dir='./install_me_here/usr/share/man/man3'
 installprefix='./install_me_here/usr'
 installprefixexp='./install_me_here/usr'
-installprivlib='./install_me_here/usr/lib/perl5/5.33.4'
+installprivlib='./install_me_here/usr/lib/perl5/5.33.5'
 installscript='./install_me_here/usr/bin'
-installsitearch='./install_me_here/usr/lib/perl5/site_perl/5.33.4/armv4l-linux'
+installsitearch='./install_me_here/usr/lib/perl5/site_perl/5.33.5/armv4l-linux'
 installsitebin='./install_me_here/usr/bin'
 installsitehtml1dir=''
 installsitehtml3dir=''
-installsitelib='./install_me_here/usr/lib/perl5/site_perl/5.33.4'
+installsitelib='./install_me_here/usr/lib/perl5/site_perl/5.33.5'
 installsiteman1dir='./install_me_here/usr/share/man/man1'
 installsiteman3dir='./install_me_here/usr/share/man/man3'
 installsitescript='./install_me_here/usr/bin'
@@ -970,8 +971,8 @@ pmake=''
 pr=''
 prefix='/usr'
 prefixexp='/usr'
-privlib='/usr/lib/perl5/5.33.4'
-privlibexp='/usr/lib/perl5/5.33.4'
+privlib='/usr/lib/perl5/5.33.5'
+privlibexp='/usr/lib/perl5/5.33.5'
 procselfexe='"/proc/self/exe"'
 prototype='define'
 ptrsize='4'
@@ -1036,17 +1037,17 @@ sig_num='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 sig_num_init='0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 6, 17, 29, 31, 0'
 sig_size='68'
 signal_t='void'
-sitearch='/usr/lib/perl5/site_perl/5.33.4/armv4l-linux'
-sitearchexp='/usr/lib/perl5/site_perl/5.33.4/armv4l-linux'
+sitearch='/usr/lib/perl5/site_perl/5.33.5/armv4l-linux'
+sitearchexp='/usr/lib/perl5/site_perl/5.33.5/armv4l-linux'
 sitebin='/usr/bin'
 sitebinexp='/usr/bin'
 sitehtml1dir=''
 sitehtml1direxp=''
 sitehtml3dir=''
 sitehtml3direxp=''
-sitelib='/usr/lib/perl5/site_perl/5.33.4'
+sitelib='/usr/lib/perl5/site_perl/5.33.5'
 sitelib_stem='/usr/lib/perl5/site_perl'
-sitelibexp='/usr/lib/perl5/site_perl/5.33.4'
+sitelibexp='/usr/lib/perl5/site_perl/5.33.5'
 siteman1dir='/usr/share/man/man1'
 siteman1direxp='/usr/share/man/man1'
 siteman3dir='/usr/share/man/man3'
@@ -1085,7 +1086,7 @@ stdio_stream_array=''
 strerror_r_proto='0'
 strings='/usr/include/string.h'
 submit=''
-subversion='4'
+subversion='5'
 sysman='/usr/share/man/man1'
 tail=''
 tar=''
@@ -1176,8 +1177,8 @@ vendorprefix=''
 vendorprefixexp=''
 vendorscript=''
 vendorscriptexp=''
-version='5.33.4'
-version_patchlevel_string='version 33 subversion 4'
+version='5.33.5'
+version_patchlevel_string='version 33 subversion 5'
 versiononly='undef'
 vi=''
 xlibpth='/usr/lib/386 /lib/386'
@@ -1191,9 +1192,9 @@ config_args=''
 config_argc=0
 PERL_REVISION=5
 PERL_VERSION=33
-PERL_SUBVERSION=4
+PERL_SUBVERSION=5
 PERL_API_REVISION=5
 PERL_API_VERSION=33
-PERL_API_SUBVERSION=4
+PERL_API_SUBVERSION=5
 PERL_PATCHLEVEL=
 PERL_CONFIG_SH=true
diff --git a/INSTALL b/INSTALL
index c16117f..ce38af0 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -371,7 +371,7 @@ although from time to time we change which functions we support,
 and which function is default (currently SBOX+STADTX on 64 bit builds
 and SBOX+ZAPHOD32 for 32 bit builds). You can choose a different
 algorithm by defining one of the following symbols during configure.
-Note that there security implications of which hash function you choose
+Note that there are security implications regarding which hash function you choose
 to use. The functions are listed roughly by how secure they are believed
 to be, with the one believed to be most secure at release time being PERL_HASH_FUNC_SIPHASH.
 
@@ -388,10 +388,10 @@ and which has rather expensive setup costs (relatively speaking), both in
 terms of performance and more importantly in terms of memory. SBOX32
 requires 1k of storage per character it can hash, and it must populate that
 storage with 256 32-bit random values as well. In practice the RNG we use
-for seeding the SBOX32 storage is very efficient and populating the table
+for seeding the SBOX32 storage is very efficient, and populating the table
 required for hashing even fairly long keys is negligible as we only do it
-during startup. By default we build with SBOX32 enabled, but you change that
-by setting
+during startup. By default we build with SBOX32 enabled, but you can change
+that by setting
 
    PERL_HASH_USE_SBOX32_ALSO
 
@@ -615,7 +615,7 @@ The directories set up by Configure fall into three broad categories.
 
 =item Directories for the perl distribution
 
-By default, Configure will use the following directories for 5.33.4.
+By default, Configure will use the following directories for 5.33.5.
 $version is the full perl version number, including subversion, e.g.
 5.12.3, and $archname is a string like sun4-sunos,
 determined by Configure.  The full definitions of all Configure
@@ -2438,7 +2438,7 @@ L<https://www.chiark.greenend.org.uk/~sgtatham/bugs.html>
 
 =head1 Coexistence with earlier versions of perl 5
 
-Perl 5.33.4 is not binary compatible with earlier versions of Perl.
+Perl 5.33.5 is not binary compatible with earlier versions of Perl.
 In other words, you will have to recompile your XS modules.
 
 In general, you can usually safely upgrade from one stable version of Perl
@@ -2513,9 +2513,9 @@ won't interfere with another version.  (The defaults guarantee this for
 libraries after 5.6.0, but not for executables. TODO?)  One convenient
 way to do this is by using a separate prefix for each version, such as
 
-       sh Configure -Dprefix=/opt/perl5.33.4
+       sh Configure -Dprefix=/opt/perl5.33.5
 
-and adding /opt/perl5.33.4/bin to the shell PATH variable.  Such users
+and adding /opt/perl5.33.5/bin to the shell PATH variable.  Such users
 may also wish to add a symbolic link /usr/local/bin/perl so that
 scripts can still start with #!/usr/local/bin/perl.
 
@@ -2528,13 +2528,13 @@ seriously consider using a separate directory, since development
 subversions may not have all the compatibility wrinkles ironed out
 yet.
 
-=head2 Upgrading from 5.33.3 or earlier
+=head2 Upgrading from 5.33.4 or earlier
 
-B<Perl 5.33.4 may not be binary compatible with Perl 5.33.3 or
+B<Perl 5.33.5 may not be binary compatible with Perl 5.33.4 or
 earlier Perl releases.>  Perl modules having binary parts
 (meaning that a C compiler is used) will have to be recompiled to be
-used with 5.33.4.  If you find you do need to rebuild an extension with
-5.33.4, you may safely do so without disturbing the older
+used with 5.33.5.  If you find you do need to rebuild an extension with
+5.33.5, you may safely do so without disturbing the older
 installations.  (See L<"Coexistence with earlier versions of perl 5">
 above.)
 
@@ -2567,15 +2567,15 @@ Firstly, the bare minimum to run this script
      print("$f\n");
   }
 
-in Linux with perl-5.33.4 is as follows (under $Config{prefix}):
+in Linux with perl-5.33.5 is as follows (under $Config{prefix}):
 
   ./bin/perl
-  ./lib/perl5/5.33.4/strict.pm
-  ./lib/perl5/5.33.4/warnings.pm
-  ./lib/perl5/5.33.4/i686-linux/File/Glob.pm
-  ./lib/perl5/5.33.4/feature.pm
-  ./lib/perl5/5.33.4/XSLoader.pm
-  ./lib/perl5/5.33.4/i686-linux/auto/File/Glob/Glob.so
+  ./lib/perl5/5.33.5/strict.pm
+  ./lib/perl5/5.33.5/warnings.pm
+  ./lib/perl5/5.33.5/i686-linux/File/Glob.pm
+  ./lib/perl5/5.33.5/feature.pm
+  ./lib/perl5/5.33.5/XSLoader.pm
+  ./lib/perl5/5.33.5/i686-linux/auto/File/Glob/Glob.so
 
 Secondly, for perl-5.10.1, the Debian perl-base package contains 591
 files, (of which 510 are for lib/unicore) totaling about 3.5MB in its
index 0e4790b..3330df8 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -248,6 +248,10 @@ cpan/Config-Perl-V/t/31_plv52511.t         Config::Perl::V
 cpan/Config-Perl-V/t/32_plv5261rc1.t           Config::Perl::V
 cpan/Config-Perl-V/t/33_plv52711r.t            Config::Perl::V
 cpan/Config-Perl-V/t/34_plv5280.t              Config::Perl::V
+cpan/Config-Perl-V/t/35_plv52910g.t            Config::Perl::V
+cpan/Config-Perl-V/t/36_plv5300.t              Config::Perl::V
+cpan/Config-Perl-V/t/37_plv53111qm.t           Config::Perl::V
+cpan/Config-Perl-V/t/38_plv5320tld.t           Config::Perl::V
 cpan/Config-Perl-V/V.pm                                Config::Perl::V
 cpan/CPAN/lib/App/Cpan.pm              helper package for CPAN.pm
 cpan/CPAN/lib/CPAN.pm                  Interface to Comprehensive Perl Archive Network
@@ -1275,7 +1279,6 @@ cpan/libnet/t/config.t            libnet
 cpan/libnet/t/datasend.t       libnet
 cpan/libnet/t/ftp.t            libnet
 cpan/libnet/t/hostname.t       libnet
-cpan/libnet/t/libnet_t.pl      libnet
 cpan/libnet/t/netrc.t          libnet
 cpan/libnet/t/nntp.t           libnet
 cpan/libnet/t/nntp_ipv6.t
@@ -1541,6 +1544,10 @@ cpan/perlfaq/lib/perlfaq8.pod    System Interaction
 cpan/perlfaq/lib/perlfaq9.pod  Networking
 cpan/perlfaq/lib/perlglossary.pod      Perl Glossary
 cpan/PerlIO-via-QuotedPrint/lib/PerlIO/via/QuotedPrint.pm      PerlIO::via::QuotedPrint
+cpan/PerlIO-via-QuotedPrint/t/changes.t
+cpan/PerlIO-via-QuotedPrint/t/critic.t
+cpan/PerlIO-via-QuotedPrint/t/pod.t
+cpan/PerlIO-via-QuotedPrint/t/pod_coverage.t
 cpan/PerlIO-via-QuotedPrint/t/QuotedPrint.t                    PerlIO::via::QuotedPrint
 cpan/Pod-Checker/lib/Pod/Checker.pm
 cpan/Pod-Checker/scripts/podchecker.PL
@@ -2582,6 +2589,11 @@ cpan/Text-Balanced/t/06_extqlk.t See if Text::Balanced works
 cpan/Text-Balanced/t/07_exttag.t       See if Text::Balanced works
 cpan/Text-Balanced/t/08_extvar.t       See if Text::Balanced works
 cpan/Text-Balanced/t/09_gentag.t       See if Text::Balanced works
+cpan/Text-Balanced/t/94_changes.t
+cpan/Text-Balanced/t/95_critic.t
+cpan/Text-Balanced/t/96_pmv.t
+cpan/Text-Balanced/t/97_pod.t
+cpan/Text-Balanced/t/98_pod_coverage.t
 cpan/Text-ParseWords/lib/Text/ParseWords.pm    Perl module to split words on arbitrary delimiter
 cpan/Text-ParseWords/t/ParseWords.t            See if Text::ParseWords works
 cpan/Text-ParseWords/t/taint.t                 See if Text::ParseWords works with tainting
@@ -4351,6 +4363,7 @@ ext/POSIX/Makefile.PL             POSIX extension makefile writer
 ext/POSIX/POSIX.xs             POSIX extension external subroutines
 ext/POSIX/t/export.t           Test @EXPORT and @EXPORT_OK
 ext/POSIX/t/iscrash            See if POSIX isxxx() crashes with threads on Win32
+ext/POSIX/t/iv_const.t         See if integer constants of POSIX are IV
 ext/POSIX/t/math.t             Basic math tests for POSIX
 ext/POSIX/t/mb.t               Multibyte function tests for POSIX
 ext/POSIX/t/posix.t            See if POSIX works
@@ -5214,6 +5227,7 @@ pod/perl5330delta.pod             Perl changes in version 5.33.0
 pod/perl5331delta.pod          Perl changes in version 5.33.1
 pod/perl5332delta.pod          Perl changes in version 5.33.2
 pod/perl5333delta.pod          Perl changes in version 5.33.3
+pod/perl5334delta.pod          Perl changes in version 5.33.4
 pod/perl561delta.pod           Perl changes in version 5.6.1
 pod/perl56delta.pod            Perl changes in version 5.6
 pod/perl581delta.pod           Perl changes in version 5.8.1
@@ -5243,6 +5257,7 @@ pod/perldebug.pod         Perl debugging
 pod/perldelta.pod              Perl changes since previous version
 pod/perldeprecation.pod                Perl deprecations
 pod/perldiag.pod               Perl diagnostic messages
+pod/perldocstyle.pod           Perl style guide for core docs
 pod/perldsc.pod                        Perl data structures intro
 pod/perldtrace.pod             Perl's support for DTrace
 pod/perlebcdic.pod             Considerations for running Perl on EBCDIC platforms
@@ -5557,6 +5572,7 @@ t/io/inplace.t                    See if inplace editing works
 t/io/iofile.t                  See if we can load IO::File on demand
 t/io/iprefix.t                 See if inplace editing works with prefixes
 t/io/layers.t                  See if PerlIO layers work
+t/io/msg.t                     See if SysV message queues work
 t/io/nargv.t                   See if nested ARGV stuff works
 t/io/open.t                    See if open works
 t/io/openpid.t                 See if open works for subprocesses
@@ -6162,6 +6178,8 @@ t/win32/fs.t                      Test Win32 link for compatibility
 t/win32/popen.t                        Test for stdout races in backticks, etc
 t/win32/runenv.t               Test if Win* perl honors its env variables
 t/win32/signal.t               Test Win32 signal emulation
+t/win32/stat.t                 Test Win32 stat emulation
+t/win32/symlink.t              Test Win32 symlink
 t/win32/system.t               See if system works in Win*
 t/win32/system_tests           Test runner for system.t
 taint.c                                Tainting code
index 9693694..77d5811 100644 (file)
--- a/META.json
+++ b/META.json
          "url" : "https://github.com/Perl/perl5"
       }
    },
-   "version" : "5.033004",
+   "version" : "5.033005",
    "x_serialization_backend" : "JSON::PP version 4.05"
 }
index 0f588ac..09696b2 100644 (file)
--- a/META.yml
+++ b/META.yml
@@ -117,5 +117,5 @@ resources:
   homepage: https://www.perl.org/
   license: https://dev.perl.org/licenses/
   repository: https://github.com/Perl/perl5
-version: '5.033004'
+version: '5.033005'
 x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
index 1c40b75..7356f0a 100755 (executable)
@@ -589,7 +589,7 @@ esac
 
 $spitshell >>$Makefile <<'!NO!SUBS!'
 
-perltoc_pod_prereqs = extra.pods pod/perl5334delta.pod pod/perlapi.pod pod/perlintern.pod pod/perlmodlib.pod pod/perluniprops.pod
+perltoc_pod_prereqs = extra.pods pod/perl5335delta.pod pod/perlapi.pod pod/perlintern.pod pod/perlmodlib.pod pod/perluniprops.pod
 generated_pods = pod/perltoc.pod $(perltoc_pod_prereqs)
 generated_headers = uudmap.h bitcount.h mg_data.h
 
@@ -1153,9 +1153,9 @@ pod/perlintern.pod: $(MINIPERL_EXE) autodoc.pl embed.fnc
 pod/perlmodlib.pod: $(MINIPERL_EXE) pod/perlmodlib.PL MANIFEST
        $(MINIPERL) pod/perlmodlib.PL -q
 
-pod/perl5334delta.pod: pod/perldelta.pod
-       $(RMS) pod/perl5334delta.pod
-       $(LNS) perldelta.pod pod/perl5334delta.pod
+pod/perl5335delta.pod: pod/perldelta.pod
+       $(RMS) pod/perl5335delta.pod
+       $(LNS) perldelta.pod pod/perl5335delta.pod
 
 extra.pods: $(MINIPERL_EXE)
        -@test ! -f extra.pods || rm -f `cat extra.pods`
index 9425c0a..c917ab7 100644 (file)
@@ -86,7 +86,7 @@ NLM_VERSION    = 3,20,0
 
 
 # Here comes the CW tools - TO BE FILLED TO BUILD WITH CW -
-MODULE_DESC     = "Perl 5.33.4 for NetWare"
+MODULE_DESC     = "Perl 5.33.5 for NetWare"
 CCTYPE          = CodeWarrior
 C_COMPILER             = mwccnlm -c
 CPP_COMPILER   = mwccnlm
@@ -462,7 +462,7 @@ INST_NW_TOP2 = $(INST_NW_DRV)\perl
 # versioned installation can be obtained by setting INST_TOP above to a
 # path that includes an arbitrary version string.
 #
-INST_VER       = \5.33.4
+INST_VER       = \5.33.5
 
 #
 # Comment this out if you DON'T want your perl installation to have
index 5f55e12..26c1755 100644 (file)
@@ -236,6 +236,7 @@ d_gdbm_ndbm_h_uses_prototypes='undef'
 d_gdbmndbm_h_uses_prototypes='undef'
 d_getaddrinfo='undef'
 d_getcwd='define'
+d_getenv_preserves_other_thread='define'
 d_getespwnam='undef'
 d_getfsstat='undef'
 d_getgrent='undef'
index 7d76806..19e6ce4 100644 (file)
  *     This symbol contains the ~name expanded version of ARCHLIB, to be used
  *     in programs that are not prepared to deal with ~ expansion at run-time.
  */
-#define ARCHLIB "c:\\perl\\5.33.4\\lib\\NetWare-x86-multi-thread"              /**/
+#define ARCHLIB "c:\\perl\\5.33.5\\lib\\NetWare-x86-multi-thread"              /**/
 /*#define ARCHLIB_EXP ""       /**/
 
 /* ARCHNAME:
  *     This symbol is the filename expanded version of the BIN symbol, for
  *     programs that do not want to deal with that at run-time.
  */
-#define BIN "c:\\perl\\5.33.4\\bin\\NetWare-x86-multi-thread"  /**/
-#define BIN_EXP "c:\\perl\\5.33.4\\bin\\NetWare-x86-multi-thread"      /**/
+#define BIN "c:\\perl\\5.33.5\\bin\\NetWare-x86-multi-thread"  /**/
+#define BIN_EXP "c:\\perl\\5.33.5\\bin\\NetWare-x86-multi-thread"      /**/
 
 /* BYTEORDER:
  *     This symbol holds the hexadecimal constant defined in byteorder,
  *     This symbol contains the ~name expanded version of SITEARCH, to be used
  *     in programs that are not prepared to deal with ~ expansion at run-time.
  */
-#define SITEARCH "c:\\perl\\site\\5.33.4\\lib\\NetWare-x86-multi-thread"               /**/
+#define SITEARCH "c:\\perl\\site\\5.33.5\\lib\\NetWare-x86-multi-thread"               /**/
 /*#define SITEARCH_EXP ""      /**/
 
 /* SITELIB:
  *     removed.  The elements in inc_version_list (inc_version_list.U) can
  *     be tacked onto this variable to generate a list of directories to search.
  */
-#define SITELIB "c:\\perl\\site\\5.33.4\\lib"          /**/
+#define SITELIB "c:\\perl\\site\\5.33.5\\lib"          /**/
 /*#define SITELIB_EXP ""       /**/
 #define SITELIB_STEM ""                /**/
 
index 652d198..42abcd5 100755 (executable)
@@ -224,12 +224,11 @@ use File::Glob qw(:case);
     },
 
     'Config::Perl::V' => {
-        'DISTRIBUTION' => 'HMBRAND/Config-Perl-V-0.31.tgz',
+        'DISTRIBUTION' => 'HMBRAND/Config-Perl-V-0.33.tgz',
         'FILES'        => q[cpan/Config-Perl-V],
         'EXCLUDED'     => [qw(
                examples/show-v.pl
                )],
-        'CUSTOMIZED'   => [ qw(V.pm) ],
     },
 
     'constant' => {
@@ -383,7 +382,7 @@ use File::Glob qw(:case);
     },
 
     'Encode' => {
-        'DISTRIBUTION' => 'DANKOGAI/Encode-3.07.tar.gz',
+        'DISTRIBUTION' => 'DANKOGAI/Encode-3.08.tar.gz',
         'FILES'        => q[cpan/Encode],
         'EXCLUDED'     => [
             qw( t/whatwg-aliases.json
@@ -453,7 +452,7 @@ use File::Glob qw(:case);
     },
 
     'ExtUtils::Install' => {
-        'DISTRIBUTION' => 'BINGOS/ExtUtils-Install-2.18.tar.gz',
+        'DISTRIBUTION' => 'BINGOS/ExtUtils-Install-2.20.tar.gz',
         'FILES'        => q[cpan/ExtUtils-Install],
         'EXCLUDED'     => [
             qw( t/lib/Test/Builder.pm
@@ -693,7 +692,7 @@ use File::Glob qw(:case);
     },
 
     'libnet' => {
-        'DISTRIBUTION' => 'SHAY/libnet-3.11.tar.gz',
+        'DISTRIBUTION' => 'SHAY/libnet-3.12.tar.gz',
         'FILES'        => q[cpan/libnet],
         'EXCLUDED'     => [
             qw( Configure
@@ -812,7 +811,7 @@ use File::Glob qw(:case);
     },
 
     'Module::CoreList' => {
-        'DISTRIBUTION' => 'BINGOS/Module-CoreList-5.20201020.tar.gz',
+        'DISTRIBUTION' => 'BINGOS/Module-CoreList-5.20201120.tar.gz',
         'FILES'        => q[dist/Module-CoreList],
     },
 
@@ -911,7 +910,7 @@ use File::Glob qw(:case);
     },
 
     'PerlIO::via::QuotedPrint' => {
-        'DISTRIBUTION' => 'SHAY/PerlIO-via-QuotedPrint-0.08.tar.gz',
+        'DISTRIBUTION' => 'SHAY/PerlIO-via-QuotedPrint-0.09.tar.gz',
         'FILES'        => q[cpan/PerlIO-via-QuotedPrint],
     },
 
@@ -1081,6 +1080,11 @@ use File::Glob qw(:case);
                 t/lib/if.pm
                 ),
         ],
+        'CUSTOMIZED'   => [
+             # https://github.com/Perl-Toolchain-Gang/Test-Harness/pull/103
+             # applied but not released
+             't/source.t'
+        ],
     },
 
     'Test::Simple' => {
@@ -1104,7 +1108,7 @@ use File::Glob qw(:case);
     },
 
     'Text::Balanced' => {
-        'DISTRIBUTION' => 'SHAY/Text-Balanced-2.03.tar.gz',
+        'DISTRIBUTION' => 'SHAY/Text-Balanced-2.04.tar.gz',
         'FILES'        => q[cpan/Text-Balanced],
         'EXCLUDED'     => [
             qw( t/97_meta.t
index a617f91..392decb 100644 (file)
@@ -46,12 +46,12 @@ afsroot='/afs'
 alignbytes='16'
 aphostname=''
 api_revision='5'
-api_subversion='4'
+api_subversion='5'
 api_version='33'
-api_versionstring='5.33.4'
+api_versionstring='5.33.5'
 ar='ar'
-archlib='/opt/perl/lib/5.33.4/x86_64-linux-thread-multi-ld'
-archlibexp='/opt/perl/lib/5.33.4/x86_64-linux-thread-multi-ld'
+archlib='/opt/perl/lib/5.33.5/x86_64-linux-thread-multi-ld'
+archlibexp='/opt/perl/lib/5.33.5/x86_64-linux-thread-multi-ld'
 archname64=''
 archname='x86_64-linux-thread-multi-ld'
 archobjs=''
@@ -264,6 +264,7 @@ d_gdbm_ndbm_h_uses_prototypes='undef'
 d_gdbmndbm_h_uses_prototypes='undef'
 d_getaddrinfo='define'
 d_getcwd='define'
+d_getenv_preserves_other_thread='define'
 d_getespwnam='undef'
 d_getfsstat='undef'
 d_getgrent='define'
@@ -853,7 +854,7 @@ incpath=''
 incpth='/usr/lib64/gcc/x86_64-suse-linux/10/include /usr/local/include /usr/lib64/gcc/x86_64-suse-linux/10/include-fixed /usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/include /usr/include'
 inews=''
 initialinstalllocation='/opt/perl/bin'
-installarchlib='/opt/perl/lib/5.33.4/x86_64-linux-thread-multi-ld'
+installarchlib='/opt/perl/lib/5.33.5/x86_64-linux-thread-multi-ld'
 installbin='/opt/perl/bin'
 installhtml1dir=''
 installhtml3dir=''
@@ -861,13 +862,13 @@ installman1dir='/opt/perl/man/man1'
 installman3dir='/opt/perl/man/man3'
 installprefix='/opt/perl'
 installprefixexp='/opt/perl'
-installprivlib='/opt/perl/lib/5.33.4'
+installprivlib='/opt/perl/lib/5.33.5'
 installscript='/opt/perl/bin'
-installsitearch='/opt/perl/lib/site_perl/5.33.4/x86_64-linux-thread-multi-ld'
+installsitearch='/opt/perl/lib/site_perl/5.33.5/x86_64-linux-thread-multi-ld'
 installsitebin='/opt/perl/bin'
 installsitehtml1dir=''
 installsitehtml3dir=''
-installsitelib='/opt/perl/lib/site_perl/5.33.4'
+installsitelib='/opt/perl/lib/site_perl/5.33.5'
 installsiteman1dir='/opt/perl/man/man1'
 installsiteman3dir='/opt/perl/man/man3'
 installsitescript='/opt/perl/bin'
@@ -992,7 +993,7 @@ perl_patchlevel=''
 perl_static_inline='static __inline__'
 perladmin='yourname@yourhost.yourplace.com'
 perllibs='-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc'
-perlpath='/opt/perl/bin/perl5.33.4'
+perlpath='/opt/perl/bin/perl5.33.5'
 pg='pg'
 phostname=''
 pidtype='pid_t'
@@ -1001,8 +1002,8 @@ pmake=''
 pr=''
 prefix='/opt/perl'
 prefixexp='/opt/perl'
-privlib='/opt/perl/lib/5.33.4'
-privlibexp='/opt/perl/lib/5.33.4'
+privlib='/opt/perl/lib/5.33.5'
+privlibexp='/opt/perl/lib/5.33.5'
 procselfexe='"/proc/self/exe"'
 ptrsize='8'
 quadkind='2'
@@ -1067,17 +1068,17 @@ sig_num='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 sig_num_init='0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 6, 17, 29, 0'
 sig_size='68'
 signal_t='void'
-sitearch='/opt/perl/lib/site_perl/5.33.4/x86_64-linux-thread-multi-ld'
-sitearchexp='/opt/perl/lib/site_perl/5.33.4/x86_64-linux-thread-multi-ld'
+sitearch='/opt/perl/lib/site_perl/5.33.5/x86_64-linux-thread-multi-ld'
+sitearchexp='/opt/perl/lib/site_perl/5.33.5/x86_64-linux-thread-multi-ld'
 sitebin='/opt/perl/bin'
 sitebinexp='/opt/perl/bin'
 sitehtml1dir=''
 sitehtml1direxp=''
 sitehtml3dir=''
 sitehtml3direxp=''
-sitelib='/opt/perl/lib/site_perl/5.33.4'
+sitelib='/opt/perl/lib/site_perl/5.33.5'
 sitelib_stem='/opt/perl/lib/site_perl'
-sitelibexp='/opt/perl/lib/site_perl/5.33.4'
+sitelibexp='/opt/perl/lib/site_perl/5.33.5'
 siteman1dir='/opt/perl/man/man1'
 siteman1direxp='/opt/perl/man/man1'
 siteman3dir='/opt/perl/man/man3'
@@ -1103,7 +1104,7 @@ src='.'
 ssizetype='ssize_t'
 st_ino_sign='1'
 st_ino_size='8'
-startperl='#!/opt/perl/bin/perl5.33.4'
+startperl='#!/opt/perl/bin/perl5.33.5'
 startsh='#!/bin/sh'
 static_ext=' '
 stdchar='char'
@@ -1115,7 +1116,7 @@ stdio_ptr='((fp)->_ptr)'
 stdio_stream_array=''
 strerror_r_proto='REENTRANT_PROTO_B_IBW'
 submit=''
-subversion='4'
+subversion='5'
 sysman='/usr/share/man/man1'
 sysroot=''
 tail=''
@@ -1214,8 +1215,8 @@ vendorprefix=''
 vendorprefixexp=''
 vendorscript=''
 vendorscriptexp=''
-version='5.33.4'
-version_patchlevel_string='version 33 subversion 4'
+version='5.33.5'
+version_patchlevel_string='version 33 subversion 5'
 versiononly='define'
 vi=''
 xlibpth='/usr/lib/386 /lib/386'
@@ -1225,10 +1226,10 @@ zcat=''
 zip='zip'
 PERL_REVISION=5
 PERL_VERSION=33
-PERL_SUBVERSION=4
+PERL_SUBVERSION=5
 PERL_API_REVISION=5
 PERL_API_VERSION=33
-PERL_API_SUBVERSION=4
+PERL_API_SUBVERSION=5
 PERL_PATCHLEVEL=''
 PERL_CONFIG_SH=true
 : Variables propagated from previous config.sh file.
index f54e173..096611f 100644 (file)
  *     This symbol contains the ~name expanded version of ARCHLIB, to be used
  *     in programs that are not prepared to deal with ~ expansion at run-time.
  */
-#define ARCHLIB "/opt/perl/lib/5.33.4/x86_64-linux"            /**/
-#define ARCHLIB_EXP "/opt/perl/lib/5.33.4/x86_64-linux"                /**/
+#define ARCHLIB "/opt/perl/lib/5.33.5/x86_64-linux"            /**/
+#define ARCHLIB_EXP "/opt/perl/lib/5.33.5/x86_64-linux"                /**/
 
 /* BIN:
  *     This symbol holds the path of the bin directory where the package will
  *     This symbol contains the ~name expanded version of PRIVLIB, to be used
  *     in programs that are not prepared to deal with ~ expansion at run-time.
  */
-#define PRIVLIB "/opt/perl/lib/5.33.4"         /**/
-#define PRIVLIB_EXP "/opt/perl/lib/5.33.4"             /**/
+#define PRIVLIB "/opt/perl/lib/5.33.5"         /**/
+#define PRIVLIB_EXP "/opt/perl/lib/5.33.5"             /**/
 
 /* SITEARCH:
  *     This symbol contains the name of the private library for this package.
  *     This symbol contains the ~name expanded version of SITEARCH, to be used
  *     in programs that are not prepared to deal with ~ expansion at run-time.
  */
-#define SITEARCH "/opt/perl/lib/site_perl/5.33.4/x86_64-linux"         /**/
-#define SITEARCH_EXP "/opt/perl/lib/site_perl/5.33.4/x86_64-linux"             /**/
+#define SITEARCH "/opt/perl/lib/site_perl/5.33.5/x86_64-linux"         /**/
+#define SITEARCH_EXP "/opt/perl/lib/site_perl/5.33.5/x86_64-linux"             /**/
 
 /* SITELIB:
  *     This symbol contains the name of the private library for this package.
  *     removed.  The elements in inc_version_list (inc_version_list.U) can
  *     be tacked onto this variable to generate a list of directories to search.
  */
-#define SITELIB "/opt/perl/lib/site_perl/5.33.4"               /**/
-#define SITELIB_EXP "/opt/perl/lib/site_perl/5.33.4"           /**/
+#define SITELIB "/opt/perl/lib/site_perl/5.33.5"               /**/
+#define SITELIB_EXP "/opt/perl/lib/site_perl/5.33.5"           /**/
 #define SITELIB_STEM "/opt/perl/lib/site_perl"         /**/
 
 /* PERL_VENDORARCH:
  *     script to make sure (one hopes) that it runs with perl and not
  *     some shell.
  */
-#define STARTPERL "#!/opt/perl/bin/perl5.33.4"         /**/
+#define STARTPERL "#!/opt/perl/bin/perl5.33.5"         /**/
 
 /* HAS_STDIO_STREAM_ARRAY:
  *     This symbol, if defined, tells that there is an array
index ed53a8a..b6bcf20 100644 (file)
@@ -17,6 +17,15 @@ Consult your favorite dictionary for details.
 
 =head1 EPIGRAPHS
 
+=head2 v5.33.4 - George Eliot, "Adam Bede"
+
+L<Announced on 2020-11-20 by Tom Hukins|https://www.nntp.perl.org/group/perl.perl5.porters/2020/11/msg258597.html>
+
+It was more than two o'clock in the afternoon when Adam came in sight of
+the grey town on the hill-side and looked searchingly towards the green
+valley below, for the first glimpse of the old thatched roof near the
+ugly red mill.
+
 =head2 v5.33.3 - Ludwig van Beethoven, "Heiligenstadt Testament"; translated and quoted in: Maynard Solomon, "Beethoven"
 
 L<Announced on 2020-10-20 by Steve Hay|https://www.nntp.perl.org/group/perl.perl5.porters/2020/10/msg258502.html>
index 9eb1053..a7b78d4 100644 (file)
@@ -403,7 +403,7 @@ died, add a short obituary here.
 
 XXX Generate this with:
 
-  perl Porting/acknowledgements.pl v5.33.4..HEAD
+  perl Porting/acknowledgements.pl v5.33.5..HEAD
 
 =head1 Reporting Bugs
 
index ecc6055..c9f729f 100644 (file)
@@ -141,23 +141,17 @@ Andreas' email address at:
 
     https://pause.perl.org/pause/query?ACTION=pause_04imprint
 
-=head3 GitHub issue management access
-
-Make sure you have permission to close tickets on L<https://github.com/Perl/perl5/issues>
-so you can respond to bug reports as necessary during your stint.  If you
-don't, make a GitHub account (if you don't have one) and contact the pumpking
-with your username to get ticket-closing permission.
-
-=head3 git checkout and commit bit
+=head3 GitHub access
 
 You will need a working C<git> installation, checkout of the perl
 git repository and perl commit bit.  For information about working
 with perl and git, see F<pod/perlgit.pod>.
 
 If you are not yet a perl committer, you won't be able to make a
-release.  Have a chat with whichever evil perl porter tried to talk
-you into the idea in the first place to figure out the best way to
-resolve the issue.
+release.  You will need to have a GitHub account (if you don't have one)
+and contact the pumpking with your username to get membership of the L<<
+Perl-Release-Managers|https://github.com/orgs/Perl/teams/perl-release-managers
+>> team.
 
 =head3 web-based file share
 
@@ -166,10 +160,6 @@ pre-release testing, and you may wish to upload to PAUSE via URL.
 Make sure you have a way of sharing files, such as a web server or
 file-sharing service.
 
-Porters have access to the "dromedary" server (users.perl5.git.perl.org),
-which has a F<public_html> directory to share files with.
-(L<http://users.perl5.git.perl.org/~username/perl-5.xx.y.tar.gz>)
-
 If you use Dropbox, you can append "raw=1" as a parameter to their usual
 sharing link to allow direct download (albeit with redirects).
 
@@ -374,6 +364,10 @@ the raw reports.
 Similarly, monitor the smoking of perl for compiler warnings, and try to
 fix.
 
+Additionally both L<Travis CI|https://travis-ci.org/Perl/perl5> and
+L<GitHub Actions|https://github.com/Perl/perl5/actions> smokers run
+automatically.
+
 =for checklist skip BLEAD-POINT
 
 =head3 monitor CPAN testers for failures
@@ -388,14 +382,6 @@ colon-delimited versions to use for comparison.  For example:
 
 L<http://analysis.cpantesters.org/beforemaintrelease?pair=5.20.2:5.22.0%20RC1>
 
-=head3 Monitor Continuous Integration smokers
-
-Currently both "Travis CI" and "GitHub Actions" smokers are setup.
-Their current status is available at:
-
-L<https://github.com/Perl/perl5/actions>
-L<https://travis-ci.org/Perl/perl5>
-
 =head3 update perldelta
 
 Get perldelta in a mostly finished state.
@@ -1176,11 +1162,6 @@ eliminate anxious gnashing of teeth while you wait to see if your
 15 megabyte HTTP upload successfully completes across your slow, twitchy
 cable modem.
 
-You can make use of your home directory on dromedary for
-this purpose: F<http://users.perl5.git.perl.org/~USERNAME> maps to
-F</home/USERNAME/public_html>, where F<USERNAME> is your login account
-on dromedary.
-
 I<Remember>: if your upload is partially successful, you
 may need to contact a PAUSE administrator or even bump the version of perl.
 
index de7bf85..9390a65 100644 (file)
@@ -43,12 +43,12 @@ you should reset the version numbers to the next blead series.
   2020-08-20  5.33.1 ✓       Karen Etheridge
   2020-09-20  5.33.2 ✓       Sawyer X
   2020-10-20  5.33.3 ✓       Steve Hay
-  2020-11-20  5.33.4         Tom Hukins
-  2020-12-20  5.33.5
-  2021-01-20  5.33.6
+  2020-11-20  5.33.4        Tom Hukins
+  2020-12-20  5.33.5         Max Maischein
+  2021-01-20  5.33.6         Richard Leach
   2021-02-20  5.33.7         Renee Backer
-  2021-03-20  5.33.8
-  2021-04-20  5.33.9
+  2021-03-20  5.33.8         Atoomic
+  2021-04-20  5.33.9         Todd Rinaldo
 
 =head1 VICTIMS
 
index b2cdd5f..660b3f3 100755 (executable)
@@ -9,7 +9,7 @@ Porting/sync-with-cpan - Synchronize with CPAN distributions
     sh ./Configure
     perl Porting/sync-with-cpan <module>
 
-where <module> is the name it appears in the C<%Modules> hash
+where C<module> is the name it appears in the C<%Modules> hash
 of F<Porting/Maintainers.pl>
 
 =head1 DESCRIPTION
index b67e419..72b5f0d 100644 (file)
@@ -486,7 +486,7 @@ Natively 64-bit systems need neither -Duse64bitint nor -Duse64bitall.
 On these systems, it might be the default compilation mode, and there
 is currently no guarantee that passing no use64bitall option to the
 Configure process will build a 32bit perl. Implementing -Duse32bit*
-options would be nice for perl 5.33.4.
+options would be nice for perl 5.33.5.
 
 =head2 Profile Perl - am I hot or not?
 
@@ -1189,7 +1189,7 @@ L<http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2013-01/msg00339.html>
 =head1 Big projects
 
 Tasks that will get your name mentioned in the description of the "Highlights
-of 5.33.4"
+of 5.33.5"
 
 =head2 make ithreads more robust
 
index 241cba8..415a4fd 100644 (file)
@@ -22,9 +22,9 @@ The build procedure is completely standard:
 Make perl executable and create a symlink for libperl:
 
   chmod a+x /boot/common/bin/perl
-  cd /boot/common/lib; ln -s perl5/5.33.4/BePC-haiku/CORE/libperl.so .
+  cd /boot/common/lib; ln -s perl5/5.33.5/BePC-haiku/CORE/libperl.so .
 
-Replace C<5.33.4> with your respective version of Perl.
+Replace C<5.33.5> with your respective version of Perl.
 
 =head1 KNOWN PROBLEMS
 
index bb66fe7..e57bb1b 100644 (file)
@@ -10,9 +10,9 @@ perlmacosx - Perl under Mac OS X
 
 This document briefly describes Perl under Mac OS X.
 
-  curl -O https://www.cpan.org/src/perl-5.33.4.tar.gz
-  tar -xzf perl-5.33.4.tar.gz
-  cd perl-5.33.4
+  curl -O https://www.cpan.org/src/perl-5.33.5.tar.gz
+  tar -xzf perl-5.33.5.tar.gz
+  cd perl-5.33.5
   ./Configure -des -Dprefix=/usr/local/
   make
   make test
@@ -20,7 +20,7 @@ This document briefly describes Perl under Mac OS X.
 
 =head1 DESCRIPTION
 
-The latest Perl release (5.33.4 as of this writing) builds without changes
+The latest Perl release (5.33.5 as of this writing) builds without changes
 under all versions of Mac OS X from 10.3 "Panther" onwards. 
 
 In order to build your own version of Perl you will need 'make',
index edaf049..3bcd3a1 100644 (file)
@@ -619,7 +619,7 @@ C<set PERLLIB_PREFIX> in F<Config.sys>, see L</"C<PERLLIB_PREFIX>">.
 
 =item Additional Perl modules
 
-  unzip perl_ste.zip -d f:/perllib/lib/site_perl/5.33.4/
+  unzip perl_ste.zip -d f:/perllib/lib/site_perl/5.33.5/
 
 Same remark as above applies.  Additionally, if this directory is not
 one of directories on @INC (and @INC is influenced by C<PERLLIB_PREFIX>), you
index 137e8ee..79191c2 100644 (file)
@@ -142,11 +142,11 @@ You may need to set up a foreign symbol for the unpacking utility of
 choice.  Once you have done so, use a command like the following to
 unpack the archive:
 
-    vmstar -xvf perl-5^.33^.4.tar
+    vmstar -xvf perl-5^.33^.5.tar
 
 Then set default to the top-level source directory like so:
 
-    set default [.perl-5^.33^.4]
+    set default [.perl-5^.33^.5]
 
 and proceed with configuration as described in the next section.
 
index 64491e7..a9f6f6b 100644 (file)
@@ -66,9 +66,9 @@ use Text::Tabs;
 use strict;
 use warnings;
 
-# 80 column terminal - 1 for pager adding a column; -7 for nroff
-# indent;
-my $max_width = 80 - 1 - 7;
+# 80 column terminal - 2 for pager adding 2 columns; -4 for indent for
+# non-heading lines;
+my $max_width = 80 - 2 - 4;
 
 if (@ARGV) {
     my $workdir = shift;
@@ -139,7 +139,6 @@ my $pack_scn = 'Pack and Unpack';
 my $pad_scn = 'Pad Data Structures';
 my $password_scn = 'Password and Group access';
 my $paths_scn = 'Paths to system commands';
-my $intrpvar_scn = 'Per-Interpreter Variables';
 my $prototypes_scn = 'Prototype information';
 my $regexp_scn = 'REGEXP Functions';
 my $signals_scn = 'Signals';
@@ -301,7 +300,6 @@ my %valid_sections = (
     $pad_scn => {},
     $password_scn => {},
     $paths_scn => {},
-    $intrpvar_scn => {},
     $prototypes_scn => {},
     $regexp_scn => {},
     $signals_scn => {},
diff --git a/av.c b/av.c
index ed67df1..67815fc 100644 (file)
--- a/av.c
+++ b/av.c
@@ -451,7 +451,7 @@ Perl_av_make(pTHX_ SSize_t size, SV **strp)
 /*
 =for apidoc av_clear
 
-Frees the all the elements of an array, leaving it empty.
+Frees all the elements of an array, leaving it empty.
 The XS equivalent of C<@array = ()>.  See also L</av_undef>.
 
 Note that it is possible that the actions of a destructor called directly
index fb3fba2..dceb480 100755 (executable)
@@ -3603,7 +3603,7 @@ sed <<!GROK!THIS! >$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un
  */
 #$default_inc_excludes_dot DEFAULT_INC_EXCLUDES_DOT    /**/
 
-/* USE_STRICT_BY_DEFAULT
+/* USE_STRICT_BY_DEFAULT:
  *     This symbol, if defined, enables additional defaults.
  *     At this time it only enables implicit strict by default.
  */
@@ -4575,6 +4575,19 @@ sed <<!GROK!THIS! >$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un
 #$d_endservent_r HAS_ENDSERVENT_R      /**/
 #define ENDSERVENT_R_PROTO $endservent_r_proto /**/
 
+/* GETENV_PRESERVES_OTHER_THREAD:
+ *     This symbol, if defined, indicates that the getenv system call doesn't
+ *     zap the static buffer of getenv() in a different thread.
+ *
+ *     The typical getenv() implementation will return a pointer to the proper
+ *     position in **environ.  But some may instead copy them to a static
+ *     buffer in getenv().  If there is a per-thread instance of that buffer,
+ *     or the return points to **environ, then a many-reader/1-writer mutex
+ *     will work; otherwise an exclusive locking mutex is required to prevent
+ *     races.
+ */
+#$d_getenv_preserves_other_thread GETENV_PRESERVES_OTHER_THREAD        /**/
+
 /* HAS_GETGRENT_R:
  *     This symbol, if defined, indicates that the getgrent_r routine
  *     is available to getgrent re-entrantly.
index e7ea8b9..77ce7ae 100644 (file)
@@ -5603,6 +5603,7 @@ $ THEN
 $   vms_cc_type="decc"
 $ ENDIF
 $ d_faststdio="define"
+$ d_getenv_preserves_other_thread="define"
 $ d_locconv="define"
 $ d_mblen="define"
 $ d_mbstowcs="define"
@@ -6398,6 +6399,7 @@ $ WC "d_nextafter='" + d_nextafter + "'"
 $ WC "d_nexttoward='" + d_nexttoward + "'"
 $ WC "d_nice='define'"
 $ WC "d_nl_langinfo='" + d_nl_langinfo + "'"
+$ WC "d_getenv_preserves_other_thread='" + d_getenv_preserves_other_thread + "'"
 $ WC "d_nv_preserves_uv='" + d_nv_preserves_uv + "'"
 $ WC "nv_overflows_integers_at='" + nv_overflows_integers_at + "'"
 $ WC "nv_preserves_uv_bits='" + nv_preserves_uv_bits + "'"
diff --git a/cop.h b/cop.h
index b61bb30..96b6739 100644 (file)
--- a/cop.h
+++ b/cop.h
@@ -299,7 +299,7 @@ be stored with referential integrity, but will be coerced to strings.
     Perl_refcounted_he_new_pvn(aTHX_ cophh, keypv, keylen, hash, value, flags)
 
 /*
-=for apidoc Amx|COPHH *|cophh_store_pvs|const COPHH *cophh|"key"|SV *value|U32 flags
+=for apidoc Amx|COPHH *|cophh_store_pvs|COPHH *cophh|"key"|SV *value|U32 flags
 
 Like L</cophh_store_pvn>, but takes a literal string instead
 of a string/length pair, and no precomputed hash.
@@ -311,7 +311,7 @@ of a string/length pair, and no precomputed hash.
     Perl_refcounted_he_new_pvn(aTHX_ cophh, STR_WITH_LEN(key), 0, value, flags)
 
 /*
-=for apidoc Amx|COPHH *|cophh_store_pv|const COPHH *cophh|const char *key|U32 hash|SV *value|U32 flags
+=for apidoc Amx|COPHH *|cophh_store_pv|COPHH *cophh|const char *key|U32 hash|SV *value|U32 flags
 
 Like L</cophh_store_pvn>, but takes a nul-terminated string instead of
 a string/length pair.
@@ -323,7 +323,7 @@ a string/length pair.
     Perl_refcounted_he_new_pv(aTHX_ cophh, key, hash, value, flags)
 
 /*
-=for apidoc Amx|COPHH *|cophh_store_sv|const COPHH *cophh|SV *key|U32 hash|SV *value|U32 flags
+=for apidoc Amx|COPHH *|cophh_store_sv|COPHH *cophh|SV *key|U32 hash|SV *value|U32 flags
 
 Like L</cophh_store_pvn>, but takes a Perl scalar instead of a
 string/length pair.
@@ -356,7 +356,7 @@ hash of the key string, or zero if it has not been precomputed.
        (SV *)NULL, flags)
 
 /*
-=for apidoc Amx|COPHH *|cophh_delete_pvs|const COPHH *cophh|"key"|U32 flags
+=for apidoc Amx|COPHH *|cophh_delete_pvs|COPHH *cophh|"key"|U32 flags
 
 Like L</cophh_delete_pvn>, but takes a literal string instead
 of a string/length pair, and no precomputed hash.
@@ -369,7 +369,7 @@ of a string/length pair, and no precomputed hash.
        (SV *)NULL, flags)
 
 /*
-=for apidoc Amx|COPHH *|cophh_delete_pv|const COPHH *cophh|const char *key|U32 hash|U32 flags
+=for apidoc Amx|COPHH *|cophh_delete_pv|COPHH *cophh|char *key|U32 hash|U32 flags
 
 Like L</cophh_delete_pvn>, but takes a nul-terminated string instead of
 a string/length pair.
@@ -381,7 +381,7 @@ a string/length pair.
     Perl_refcounted_he_new_pv(aTHX_ cophh, key, hash, (SV *)NULL, flags)
 
 /*
-=for apidoc Amx|COPHH *|cophh_delete_sv|const COPHH *cophh|SV *key|U32 hash|U32 flags
+=for apidoc Amx|COPHH *|cophh_delete_sv|COPHH *cophh|SV *key|U32 hash|U32 flags
 
 Like L</cophh_delete_pvn>, but takes a Perl scalar instead of a
 string/length pair.
@@ -423,6 +423,32 @@ struct cop {
     U32                cop_features;
 };
 
+/*
+=for apidoc Am|const char *|CopFILE|const COP * c
+Returns the name of the file associated with the C<COP> C<c>
+
+=for apidoc Am|STRLEN|CopLINE|const COP * c
+Returns the line number in the source code associated with the C<COP> C<c>
+
+=for apidoc Am|AV *|CopFILEAV|const COP * c
+Returns the AV associated with the C<COP> C<c>
+
+=for apidoc Am|SV *|CopFILESV|const COP * c
+Returns the SV associated with the C<COP> C<c>
+
+=for apidoc Am|void|CopFILE_set|COP * c|const char * pv
+Makes C<pv> the name of the file associated with the C<COP> C<c>
+
+=for apidoc Am|GV *|CopFILEGV|const COP * c
+Returns the GV associated with the C<COP> C<c>
+
+=for apidoc CopFILEGV_set
+Available only on unthreaded perls.  Makes C<pv> the name of the file
+associated with the C<COP> C<c>
+
+=cut
+*/
+
 #ifdef USE_ITHREADS
 #  define CopFILE(c)           ((c)->cop_file)
 #  define CopFILEGV(c)         (CopFILE(c) \
@@ -818,6 +844,9 @@ struct subst {
     void *     sbu_rxres;
     REGEXP *   sbu_rx;
 };
+
+#ifdef PERL_CORE
+
 #define sb_iters       cx_u.cx_subst.sbu_iters
 #define sb_maxiters    cx_u.cx_subst.sbu_maxiters
 #define sb_rflags      cx_u.cx_subst.sbu_rflags
@@ -831,7 +860,6 @@ struct subst {
 #define sb_rxres       cx_u.cx_subst.sbu_rxres
 #define sb_rx          cx_u.cx_subst.sbu_rx
 
-#ifdef PERL_CORE
 #  define CX_PUSHSUBST(cx) CXINC, cx = CX_CUR(),                       \
        cx->blk_oldsaveix = oldsave,                                    \
        cx->sb_iters            = iters,                                \
diff --git a/cpan/.gitignore b/cpan/.gitignore
new file mode 100644 (file)
index 0000000..378f55e
--- /dev/null
@@ -0,0 +1,10 @@
+# ignore generated .c files, and other module build traces
+*.c
+*.bs
+blib
+pm_to_blib
+Makefile
+Makefile.PL
+ppport.h
+Win32API-File/cFile_pc_to_blib
+AutoLoader/t/auto-*
diff --git a/cpan/Compress-Raw-Bzip2/.gitignore b/cpan/Compress-Raw-Bzip2/.gitignore
new file mode 100644 (file)
index 0000000..5f4846c
--- /dev/null
@@ -0,0 +1,6 @@
+/bzlib.h
+/bzlib_private.h
+/constants.h
+/constants.xs
+!/bzip2-src/*.c
+!/Makefile.PL
diff --git a/cpan/Compress-Raw-Zlib/.gitignore b/cpan/Compress-Raw-Zlib/.gitignore
new file mode 100644 (file)
index 0000000..0794817
--- /dev/null
@@ -0,0 +1,4 @@
+!/zlib-src/*.c
+!/Makefile.PL
+/constants.h
+/constants.xs
index dbb0f88..774446a 100644 (file)
@@ -6,12 +6,12 @@ use warnings;
 use Config;
 use Exporter;
 use vars qw($VERSION @ISA @EXPORT_OK %EXPORT_TAGS);
-$VERSION     = "0.32";
+$VERSION     = "0.33";
 @ISA         = qw( Exporter );
 @EXPORT_OK   = qw( plv2hash summary myconfig signature );
 %EXPORT_TAGS = (
-    all => [ @EXPORT_OK  ],
-    sig => [ "signature" ],
+    'all' => [ @EXPORT_OK  ],
+    'sig' => [ "signature" ],
     );
 
 #  Characteristics of this binary (from libperl):
@@ -24,7 +24,7 @@ $VERSION     = "0.32";
 #     perl -ne'(/^S_Internals_V/../^}/)&&s/^\s+"( .*)"/$1/ and print' perl.c
 #   perl.h line 4566 PL_bincompat_options
 #     perl -ne'(/^\w.*PL_bincompat/../^\w}/)&&s/^\s+"( .*)"/$1/ and print' perl.h
-my %BTD = map { $_ => 0 } qw(
+my %BTD = map {( $_ => 0 )} qw(
 
     DEBUGGING
     NO_HASH_SEED
@@ -183,52 +183,52 @@ my @config_vars = qw(
     );
 
 my %empty_build = (
-    osname  => "",
-    stamp   => 0,
-    options => { %BTD },
-    patches => [],
+    'osname'  => "",
+    'stamp'   => 0,
+    'options' => { %BTD },
+    'patches' => [],
     );
 
 sub _make_derived {
     my $conf = shift;
 
-    for ( [ lseektype          => "Off_t"      ],
-         [ myuname             => "uname"      ],
-         [ perl_patchlevel     => "patch"      ],
+    for ( [ 'lseektype'                => "Off_t"      ],
+         [ 'myuname'           => "uname"      ],
+         [ 'perl_patchlevel'   => "patch"      ],
          ) {
-       my ($official, $derived) = @$_;
-       $conf->{config}{$derived}  ||= $conf->{config}{$official};
-       $conf->{config}{$official} ||= $conf->{config}{$derived};
-       $conf->{derived}{$derived} = delete $conf->{config}{$derived};
+       my ($official, $derived) = @{$_};
+       $conf->{'config'}{$derived}  ||= $conf->{'config'}{$official};
+       $conf->{'config'}{$official} ||= $conf->{'config'}{$derived};
+       $conf->{'derived'}{$derived} = delete $conf->{'config'}{$derived};
        }
 
-    if (exists $conf->{config}{version_patchlevel_string} &&
-       !exists $conf->{config}{api_version}) {
-       my $vps = $conf->{config}{version_patchlevel_string};
+    if (exists $conf->{'config'}{'version_patchlevel_string'} &&
+       !exists $conf->{'config'}{'api_version'}) {
+       my $vps = $conf->{'config'}{'version_patchlevel_string'};
        $vps =~ s{\b revision   \s+ (\S+) }{}x and
-           $conf->{config}{revision}        ||= $1;
+           $conf->{'config'}{'revision'}        ||= $1;
 
        $vps =~ s{\b version    \s+ (\S+) }{}x and
-           $conf->{config}{api_version}     ||= $1;
+           $conf->{'config'}{'api_version'}     ||= $1;
        $vps =~ s{\b subversion \s+ (\S+) }{}x and
-           $conf->{config}{subversion}      ||= $1;
+           $conf->{'config'}{'subversion'}      ||= $1;
        $vps =~ s{\b patch      \s+ (\S+) }{}x and
-           $conf->{config}{perl_patchlevel} ||= $1;
+           $conf->{'config'}{'perl_patchlevel'} ||= $1;
        }
 
-    ($conf->{config}{version_patchlevel_string} ||= join " ",
-       map  { ($_, $conf->{config}{$_} ) }
-       grep {      $conf->{config}{$_}   }
+    ($conf->{'config'}{'version_patchlevel_string'} ||= join " ",
+       map  { ($_, $conf->{'config'}{$_} ) }
+       grep {      $conf->{'config'}{$_}   }
        qw( api_version subversion perl_patchlevel )) =~ s/\bperl_//; 
 
-    $conf->{config}{perl_patchlevel}  ||= "";  # 0 is not a valid patchlevel
+    $conf->{'config'}{'perl_patchlevel'}  ||= "";      # 0 is not a valid patchlevel
 
-    if ($conf->{config}{perl_patchlevel} =~ m{^git\w*-([^-]+)}i) {
-       $conf->{config}{git_branch}   ||= $1;
-       $conf->{config}{git_describe} ||= $conf->{config}{perl_patchlevel};
+    if ($conf->{'config'}{'perl_patchlevel'} =~ m{^git\w*-([^-]+)}i) {
+       $conf->{'config'}{'git_branch'}   ||= $1;
+       $conf->{'config'}{'git_describe'} ||= $conf->{'config'}{'perl_patchlevel'};
        }
 
-    $conf->{config}{$_} ||= "undef" for grep m/^(?:use|def)/ => @config_vars;
+    $conf->{'config'}{$_} ||= "undef" for grep m{^(?:use|def)} => @config_vars;
 
     $conf;
     } # _make_derived
@@ -238,20 +238,20 @@ sub plv2hash {
 
     my $pv = join "\n" => @_;
 
-    if ($pv =~ m/^Summary of my\s+(\S+)\s+\(\s*(.*?)\s*\)/m) {
-       $config{"package"} = $1;
+    if ($pv =~ m{^Summary of my\s+(\S+)\s+\(\s*(.*?)\s*\)}m) {
+       $config{'package'} = $1;
        my $rev = $2;
-       $rev =~ s/^ revision \s+ (\S+) \s*//x and $config{revision} = $1;
-       $rev and $config{version_patchlevel_string} = $rev;
-       my ($rel) = $config{"package"} =~ m{perl(\d)};
+       $rev =~ s/^ revision \s+ (\S+) \s*//x and $config{'revision'} = $1;
+       $rev and $config{'version_patchlevel_string'} = $rev;
+       my ($rel) = $config{'package'} =~ m{perl(\d)};
        my ($vers, $subvers) = $rev =~ m{version\s+(\d+)\s+subversion\s+(\d+)};
        defined $vers && defined $subvers && defined $rel and
-           $config{version} = "$rel.$vers.$subvers";
+           $config{'version'} = "$rel.$vers.$subvers";
        }
 
-    if ($pv =~ m/^\s+(Snapshot of:)\s+(\S+)/) {
-       $config{git_commit_id_title} = $1;
-       $config{git_commit_id}       = $2;
+    if ($pv =~ m{^\s+(Snapshot of:)\s+(\S+)}) {
+       $config{'git_commit_id_title'} = $1;
+       $config{'git_commit_id'}       = $2;
        }
 
     # these are always last on line and can have multiple quotation styles
@@ -275,11 +275,11 @@ sub plv2hash {
            }gx)) {             # between every kv pair
 
        while (my ($k, $v) = each %kv) {
-           $k =~ s/\s+$//;
-           $v =~ s/\s*\n\z//;
-           $v =~ s/,$//;
-           $v =~ m/^'(.*)'$/ and $v = $1;
-           $v =~ s/\s+$//;
+           $k =~ s{\s+$}       {};
+           $v =~ s{\s*\n\z}    {};
+           $v =~ s{,$}         {};
+           $v =~ m{^'(.*)'$} and $v = $1;
+           $v =~ s{\s+$}       {};
            $config{$k} = $v;
            }
        }
@@ -287,36 +287,36 @@ sub plv2hash {
     my $build = { %empty_build };
 
     $pv =~ m{^\s+Compiled at\s+(.*)}m
-       and $build->{stamp}   = $1;
+       and $build->{'stamp'}   = $1;
     $pv =~ m{^\s+Locally applied patches:(?:\s+|\n)(.*?)(?:[\s\n]+Buil[td] under)}ms
-       and $build->{patches} = [ split m/\n+\s*/, $1 ];
+       and $build->{'patches'} = [ split m{\n+\s*}, $1 ];
     $pv =~ m{^\s+Compile-time options:(?:\s+|\n)(.*?)(?:[\s\n]+(?:Locally applied|Buil[td] under))}ms
-       and map { $build->{options}{$_} = 1 } split m/\s+|\n/ => $1;
+       and map { $build->{'options'}{$_} = 1 } split m{\s+|\n} => $1;
 
-    $build->{osname} = $config{osname};
+    $build->{'osname'} = $config{'osname'};
     $pv =~ m{^\s+Built under\s+(.*)}m
-       and $build->{osname}  = $1;
-    $config{osname} ||= $build->{osname};
+       and $build->{'osname'}  = $1;
+    $config{'osname'} ||= $build->{'osname'};
 
     return _make_derived ({
-       build           => $build,
-       environment     => {},
-       config          => \%config,
-       derived         => {},
-       inc             => [],
+       'build'         => $build,
+       'environment'   => {},
+       'config'        => \%config,
+       'derived'       => {},
+       'inc'           => [],
        });
     } # plv2hash
 
 sub summary {
     my $conf = shift || myconfig ();
     ref $conf eq "HASH"
-    && exists $conf->{config}
-    && exists $conf->{build}
-    && ref $conf->{config} eq "HASH"
-    && ref $conf->{build}  eq "HASH" or return;
+    && exists $conf->{'config'}
+    && exists $conf->{'build'}
+    && ref $conf->{'config'} eq "HASH"
+    && ref $conf->{'build'}  eq "HASH" or return;
 
     my %info = map {
-       exists $conf->{config}{$_} ? ( $_ => $conf->{config}{$_} ) : () }
+       exists $conf->{'config'}{$_} ? ( $_ => $conf->{'config'}{$_} ) : () }
        qw( archname osname osvers revision patchlevel subversion version
            cc ccversion gccversion config_args inc_version_list
            d_longdbl d_longlong use64bitall use64bitint useithreads
@@ -324,7 +324,7 @@ sub summary {
            doublesize intsize ivsize nvsize longdblsize longlongsize lseeksize
            default_inc_excludes_dot
            );
-    $info{$_}++ for grep { $conf->{build}{options}{$_} } keys %{$conf->{build}{options}};
+    $info{$_}++ for grep { $conf->{'build'}{'options'}{$_} } keys %{$conf->{'build'}{'options'}};
 
     return \%info;
     } # summary
@@ -336,19 +336,19 @@ sub signature {
     eval { require Digest::MD5 };
     $@ and return $no_md5;
 
-    $conf->{cc} =~ s{.*\bccache\s+}{};
-    $conf->{cc} =~ s{.*[/\\]}{};
+    $conf->{'cc'} =~ s{.*\bccache\s+}{};
+    $conf->{'cc'} =~ s{.*[/\\]}{};
 
-    delete $conf->{config_args};
+    delete $conf->{'config_args'};
     return Digest::MD5::md5_hex (join "\xFF" => map {
        "$_=".(defined $conf->{$_} ? $conf->{$_} : "\xFE");
-       } sort keys %$conf);
+       } sort keys %{$conf});
     } # signature
 
 sub myconfig {
     my $args = shift;
-    my %args = ref $args eq "HASH"  ? %$args :
-               ref $args eq "ARRAY" ? @$args : ();
+    my %args = ref $args eq "HASH"  ? %{$args} :
+               ref $args eq "ARRAY" ? @{$args} : ();
 
     my $build = { %empty_build };
 
@@ -356,33 +356,34 @@ sub myconfig {
     my $stamp = eval { Config::compile_date () };
     if (defined $stamp) {
        $stamp =~ s/^Compiled at //;
-       $build->{osname}      = $^O;
-       $build->{stamp}       = $stamp;
-       $build->{patches}     =     [ Config::local_patches () ];
-       $build->{options}{$_} = 1 for Config::bincompat_options (),
-                                     Config::non_bincompat_options ();
+       $build->{'osname'}      = $^O;
+       $build->{'stamp'}       = $stamp;
+       $build->{'patches'}     =     [ Config::local_patches () ];
+       $build->{'options'}{$_} = 1 for Config::bincompat_options (),
+                                       Config::non_bincompat_options ();
        }
     else {
        #y $pv = qx[$^X -e"sub Config::myconfig{};" -V];
        my $cnf = plv2hash (qx[$^X -V]);
 
-       $build->{$_} = $cnf->{build}{$_} for qw( osname stamp patches options );
+       $build->{$_} = $cnf->{'build'}{$_} for qw( osname stamp patches options );
        }
 
     my @KEYS = keys %ENV;
     my %env  =
-       map {      $_ => $ENV{$_} } grep m/^PERL/      => @KEYS;
-    $args{env} and
-       map { $env{$_} = $ENV{$_} } grep m{$args{env}} => @KEYS;
+       map {( $_ => $ENV{$_} )}  grep m{^PERL}        => @KEYS;
+    if ($args{'env'}) {
+       $env{$_}  =  $ENV{$_} for grep m{$args{'env'}} => @KEYS;
+       }
 
     my %config = map { $_ => $Config{$_} } @config_vars;
 
     return _make_derived ({
-       build           => $build,
-       environment     => \%env,
-       config          => \%config,
-       derived         => {},
-       inc             => \@INC,
+       'build'         => $build,
+       'environment'   => \%env,
+       'config'        => \%config,
+       'derived'       => {},
+       'inc'           => \@INC,
        });
     } # myconfig
 
@@ -553,7 +554,7 @@ H.Merijn Brand <h.m.brand@xs4all.nl>
 
 =head1 COPYRIGHT AND LICENSE
 
-Copyright (C) 2009-2018 H.Merijn Brand
+Copyright (C) 2009-2020 H.Merijn Brand
 
 This library is free software; you can redistribute it and/or modify
 it under the same terms as Perl itself.
diff --git a/cpan/Config-Perl-V/t/35_plv52910g.t b/cpan/Config-Perl-V/t/35_plv52910g.t
new file mode 100644 (file)
index 0000000..6d822d1
--- /dev/null
@@ -0,0 +1,188 @@
+#!/pro/bin/perl
+
+use strict;
+use warnings;
+
+BEGIN {
+    use Test::More;
+    my $tests = 128;
+    unless ($ENV{PERL_CORE}) {
+       require Test::NoWarnings;
+       Test::NoWarnings->import ();
+       $tests++;
+       }
+
+    plan tests => $tests;
+    }
+
+use Config::Perl::V qw( summary );
+
+ok (my $conf = Config::Perl::V::plv2hash (<DATA>), "Read perl -v block");
+ok (exists $conf->{$_}, "Has $_ entry") for qw( build environment config inc );
+
+is ($conf->{build}{osname}, $conf->{config}{osname}, "osname");
+is ($conf->{build}{stamp}, "Apr 13 2019 00:06:38", "Build time");
+is ($conf->{config}{version}, "5.29.10", "reconstructed \$Config{version}");
+
+my $opt = Config::Perl::V::plv2hash ("")->{build}{options};
+foreach my $o (sort qw(
+       DEBUGGING HAS_TIMES MULTIPLICITY PERL_COPY_ON_WRITE PERL_DONT_CREATE_GVSV
+       PERL_IMPLICIT_CONTEXT PERLIO_LAYERS PERL_MALLOC_WRAP PERL_OP_PARENT
+       PERL_PRESERVE_IVUV PERL_TRACK_MEMPOOL PERL_USE_DEVEL USE_64_BIT_ALL
+       USE_64_BIT_INT USE_ITHREADS USE_LARGE_FILES USE_LOCALE USE_LOCALE_COLLATE
+       USE_LOCALE_CTYPE USE_LOCALE_NUMERIC USE_LOCALE_TIME USE_LONG_DOUBLE
+       USE_PERL_ATOF USE_PERLIO USE_REENTRANT_API USE_THREAD_SAFE_LOCALE
+       )) {
+    is ($conf->{build}{options}{$o}, 1, "Runtime option $o set");
+    delete $opt->{$o};
+    }
+foreach my $o (sort keys %$opt) {
+    is ($conf->{build}{options}{$o}, 0, "Runtime option $o unset");
+    }
+
+eval { require Digest::MD5; };
+my $md5 = $@ ? "0" x 32 : "8404b533829bd9752df7f662a710f993";
+ok (my $sig = Config::Perl::V::signature ($conf), "Get signature");
+is ($sig, $md5, "MD5");
+
+is_deeply ($conf->{build}{patches}, [
+    "SMOKEdfba4714a9dc4c35123b4df0a5e1721ccb081d97" ], "No local patches");
+
+my %check = (
+    alignbytes      => 16,
+    api_version     => 29,
+    bincompat5005   => "undef",
+    byteorder       => 12345678,
+    cc              => "g++",
+    cccdlflags      => "-fPIC",
+    ccdlflags       => "-Wl,-E",
+    config_args     => "-des -Dcc=g++ -Dusedevel -Duseithreads -Duse64bitall -Duselongdouble -DDEBUGGING",
+    gccversion      => "8.3.1 20190226 [gcc-8-branch revision 269204]",
+    gnulibc_version => "2.29",
+    ivsize          => 8,
+    ivtype          => "long",
+    ld              => "g++",
+    lddlflags       => "-shared -O2 -g -L/pro/local/lib -fstack-protector-strong",
+    ldflags         => "-L/pro/local/lib -fstack-protector-strong",
+    libc            => "libc-2.29.so",
+    lseektype       => "off_t",
+    osvers          => "5.0.7-1-default",
+    use64bitall     => "define",
+    use64bitint     => "define",
+    usemymalloc     => "n",
+    default_inc_excludes_dot
+                   => "define",
+    );
+is ($conf->{config}{$_}, $check{$_}, "reconstructed \$Config{$_}") for sort keys %check;
+
+ok (my $info = summary ($conf), "A summary");
+ok (exists $info->{$_}, "Summary has $_") for qw( cc config_args usemymalloc default_inc_excludes_dot );
+is ($info->{default_inc_excludes_dot}, "define", "This build has . NOT in INC");
+
+__END__
+Summary of my perl5 (revision 5 version 29 subversion 10) configuration:
+  Snapshot of: dfba4714a9dc4c35123b4df0a5e1721ccb081d97
+  Platform:
+    osname=linux
+    osvers=5.0.7-1-default
+    archname=x86_64-linux-thread-multi-ld
+    uname='linux lx09 5.0.7-1-default #1 smp sat apr 6 14:47:49 utc 2019 (8f18342) x86_64 x86_64 x86_64 gnulinux '
+    config_args='-des -Dcc=g++ -Dusedevel -Duseithreads -Duse64bitall -Duselongdouble -DDEBUGGING'
+    hint=recommended
+    useposix=true
+    d_sigaction=define
+    useithreads=define
+    usemultiplicity=define
+    use64bitint=define
+    use64bitall=define
+    uselongdouble=define
+    usemymalloc=n
+    default_inc_excludes_dot=define
+    bincompat5005=undef
+  Compiler:
+    cc='g++'
+    ccflags ='-D_REENTRANT -D_GNU_SOURCE -fPIC -DDEBUGGING -fwrapv -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector-strong -I/pro/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2'
+    optimize='-O2 -g'
+    cppflags='-D_REENTRANT -D_GNU_SOURCE -fPIC -DDEBUGGING -fwrapv -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector-strong -I/pro/local/include'
+    ccversion=''
+    gccversion='8.3.1 20190226 [gcc-8-branch revision 269204]'
+    gccosandvers=''
+    intsize=4
+    longsize=8
+    ptrsize=8
+    doublesize=8
+    byteorder=12345678
+    doublekind=3
+    d_longlong=define
+    longlongsize=8
+    d_longdbl=define
+    longdblsize=16
+    longdblkind=3
+    ivtype='long'
+    ivsize=8
+    nvtype='long double'
+    nvsize=16
+    Off_t='off_t'
+    lseeksize=8
+    alignbytes=16
+    prototype=define
+  Linker and Libraries:
+    ld='g++'
+    ldflags ='-L/pro/local/lib -fstack-protector-strong'
+    libpth=/usr/include/c++/8 /usr/include/c++/8/x86_64-suse-linux /usr/include/c++/8/backward /usr/local/lib /usr/lib64/gcc/x86_64-suse-linux/8/include-fixed /usr/lib64/gcc/x86_64-suse-linux/8/../../../../x86_64-suse-linux/lib /usr/lib /pro/local/lib /lib/../lib64 /usr/lib/../lib64 /lib /lib64 /usr/lib64 /usr/local/lib64
+    libs=-lpthread -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
+    perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
+    libc=libc-2.29.so
+    so=so
+    useshrplib=false
+    libperl=libperl.a
+    gnulibc_version='2.29'
+  Dynamic Linking:
+    dlsrc=dl_dlopen.xs
+    dlext=so
+    d_dlsymun=undef
+    ccdlflags='-Wl,-E'
+    cccdlflags='-fPIC'
+    lddlflags='-shared -O2 -g -L/pro/local/lib -fstack-protector-strong'
+
+
+Characteristics of this binary (from libperl):
+  Compile-time options:
+    DEBUGGING
+    HAS_TIMES
+    MULTIPLICITY
+    PERLIO_LAYERS
+    PERL_COPY_ON_WRITE
+    PERL_DONT_CREATE_GVSV
+    PERL_IMPLICIT_CONTEXT
+    PERL_MALLOC_WRAP
+    PERL_OP_PARENT
+    PERL_PRESERVE_IVUV
+    PERL_TRACK_MEMPOOL
+    PERL_USE_DEVEL
+    USE_64_BIT_ALL
+    USE_64_BIT_INT
+    USE_ITHREADS
+    USE_LARGE_FILES
+    USE_LOCALE
+    USE_LOCALE_COLLATE
+    USE_LOCALE_CTYPE
+    USE_LOCALE_NUMERIC
+    USE_LOCALE_TIME
+    USE_LONG_DOUBLE
+    USE_PERLIO
+    USE_PERL_ATOF
+    USE_REENTRANT_API
+    USE_THREAD_SAFE_LOCALE
+  Locally applied patches:
+    SMOKEdfba4714a9dc4c35123b4df0a5e1721ccb081d97
+  Built under linux
+  Compiled at Apr 13 2019 00:06:38
+  %ENV:
+    PERL6LIB="inst#/pro/3gl/CPAN/rakudo/install"
+  @INC:
+    lib
+    /opt/perl/lib/site_perl/5.29.10/x86_64-linux-thread-multi-ld
+    /opt/perl/lib/site_perl/5.29.10
+    /opt/perl/lib/5.29.10/x86_64-linux-thread-multi-ld
+    /opt/perl/lib/5.29.10
diff --git a/cpan/Config-Perl-V/t/36_plv5300.t b/cpan/Config-Perl-V/t/36_plv5300.t
new file mode 100644 (file)
index 0000000..6db7512
--- /dev/null
@@ -0,0 +1,182 @@
+#!/pro/bin/perl
+
+use strict;
+use warnings;
+
+BEGIN {
+    use Test::More;
+    my $tests = 128;
+    unless ($ENV{PERL_CORE}) {
+       require Test::NoWarnings;
+       Test::NoWarnings->import ();
+       $tests++;
+       }
+
+    plan tests => $tests;
+    }
+
+use Config::Perl::V qw( summary );
+
+ok (my $conf = Config::Perl::V::plv2hash (<DATA>), "Read perl -v block");
+ok (exists $conf->{$_}, "Has $_ entry") for qw( build environment config inc );
+
+is ($conf->{build}{osname}, $conf->{config}{osname}, "osname");
+is ($conf->{build}{stamp}, "May 23 2019 14:05:36", "Build time");
+is ($conf->{config}{version}, "5.30.0", "reconstructed \$Config{version}");
+
+my $opt = Config::Perl::V::plv2hash ("")->{build}{options};
+foreach my $o (sort qw(
+       HAS_TIMES MULTIPLICITY PERLIO_LAYERS PERL_COPY_ON_WRITE
+       PERL_DONT_CREATE_GVSV PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP
+       PERL_OP_PARENT PERL_PRESERVE_IVUV USE_THREAD_SAFE_LOCALE
+       USE_64_BIT_ALL USE_64_BIT_INT USE_ITHREADS USE_LARGE_FILES
+       USE_LOCALE USE_LOCALE_COLLATE USE_LOCALE_CTYPE USE_LOCALE_NUMERIC
+       USE_LOCALE_TIME USE_LONG_DOUBLE USE_PERLIO USE_PERL_ATOF
+       USE_REENTRANT_API
+       )) {
+    is ($conf->{build}{options}{$o}, 1, "Runtime option $o set");
+    delete $opt->{$o};
+    }
+foreach my $o (sort keys %$opt) {
+    is ($conf->{build}{options}{$o}, 0, "Runtime option $o unset");
+    }
+
+eval { require Digest::MD5; };
+my $md5 = $@ ? "0" x 32 : "b1138522685da4fff74f7b1118128d02";
+ok (my $sig = Config::Perl::V::signature ($conf), "Get signature");
+is ($sig, $md5, "MD5");
+
+is_deeply ($conf->{build}{patches}, [ ], "No patches");
+
+my %check = (
+    alignbytes      => 16,
+    api_version     => 30,
+    bincompat5005   => "undef",
+    byteorder       => 12345678,
+    cc              => "cc",
+    cccdlflags      => "-fPIC",
+    ccdlflags       => "-Wl,-E -Wl,-rpath,/pro/lib/perl5/5.30.0/x86_64-linux-thread-multi-ld/CORE",
+    config_args     => "-Dusethreads -Duseithreads -Duse64bitall -Duselongdouble -Duseshrplib -des",
+    gccversion      => "8.3.1 20190226 [gcc-8-branch revision 269204]",
+    gnulibc_version => "2.29",
+    ivsize          => 8,
+    ivtype          => "long",
+    ld              => "cc",
+    lddlflags       => "-shared -O2 -L/pro/local/lib -fstack-protector-strong",
+    ldflags         => "-L/pro/local/lib -fstack-protector-strong",
+    libc            => "libc-2.29.so",
+    lseektype       => "off_t",
+    osvers          => "5.1.3-1-default",
+    use64bitall     => "define",
+    use64bitint     => "define",
+    usemymalloc     => "n",
+    default_inc_excludes_dot
+                   => "define",
+    );
+is ($conf->{config}{$_}, $check{$_}, "reconstructed \$Config{$_}") for sort keys %check;
+
+ok (my $info = summary ($conf), "A summary");
+ok (exists $info->{$_}, "Summary has $_") for qw( cc config_args usemymalloc default_inc_excludes_dot );
+is ($info->{default_inc_excludes_dot}, "define", "This build has . NOT in INC");
+
+__END__
+Summary of my perl5 (revision 5 version 30 subversion 0) configuration:
+   
+  Platform:
+    osname=linux
+    osvers=5.1.3-1-default
+    archname=x86_64-linux-thread-multi-ld
+    uname='linux lx09 5.1.3-1-default #1 smp fri may 17 04:54:29 utc 2019 (07d2e25) x86_64 x86_64 x86_64 gnulinux '
+    config_args='-Dusethreads -Duseithreads -Duse64bitall -Duselongdouble -Duseshrplib -des'
+    hint=recommended
+    useposix=true
+    d_sigaction=define
+    useithreads=define
+    usemultiplicity=define
+    use64bitint=define
+    use64bitall=define
+    uselongdouble=define
+    usemymalloc=n
+    default_inc_excludes_dot=define
+    bincompat5005=undef
+  Compiler:
+    cc='cc'
+    ccflags ='-D_REENTRANT -D_GNU_SOURCE -fPIC -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/pro/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2'
+    optimize='-O2'
+    cppflags='-D_REENTRANT -D_GNU_SOURCE -fPIC -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/pro/local/include'
+    ccversion=''
+    gccversion='8.3.1 20190226 [gcc-8-branch revision 269204]'
+    gccosandvers=''
+    intsize=4
+    longsize=8
+    ptrsize=8
+    doublesize=8
+    byteorder=12345678
+    doublekind=3
+    d_longlong=define
+    longlongsize=8
+    d_longdbl=define
+    longdblsize=16
+    longdblkind=3
+    ivtype='long'
+    ivsize=8
+    nvtype='long double'
+    nvsize=16
+    Off_t='off_t'
+    lseeksize=8
+    alignbytes=16
+    prototype=define
+  Linker and Libraries:
+    ld='cc'
+    ldflags ='-L/pro/local/lib -fstack-protector-strong'
+    libpth=/usr/local/lib /usr/lib64/gcc/x86_64-suse-linux/8/include-fixed /usr/lib64/gcc/x86_64-suse-linux/8/../../../../x86_64-suse-linux/lib /usr/lib /pro/local/lib /lib/../lib64 /usr/lib/../lib64 /lib /lib64 /usr/lib64 /usr/local/lib64
+    libs=-lpthread -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
+    perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
+    libc=libc-2.29.so
+    so=so
+    useshrplib=true
+    libperl=libperl.so
+    gnulibc_version='2.29'
+  Dynamic Linking:
+    dlsrc=dl_dlopen.xs
+    dlext=so
+    d_dlsymun=undef
+    ccdlflags='-Wl,-E -Wl,-rpath,/pro/lib/perl5/5.30.0/x86_64-linux-thread-multi-ld/CORE'
+    cccdlflags='-fPIC'
+    lddlflags='-shared -O2 -L/pro/local/lib -fstack-protector-strong'
+
+
+Characteristics of this binary (from libperl): 
+  Compile-time options:
+    HAS_TIMES
+    MULTIPLICITY
+    PERLIO_LAYERS
+    PERL_COPY_ON_WRITE
+    PERL_DONT_CREATE_GVSV
+    PERL_IMPLICIT_CONTEXT
+    PERL_MALLOC_WRAP
+    PERL_OP_PARENT
+    PERL_PRESERVE_IVUV
+    USE_64_BIT_ALL
+    USE_64_BIT_INT
+    USE_ITHREADS
+    USE_LARGE_FILES
+    USE_LOCALE
+    USE_LOCALE_COLLATE
+    USE_LOCALE_CTYPE
+    USE_LOCALE_NUMERIC
+    USE_LOCALE_TIME
+    USE_LONG_DOUBLE
+    USE_PERLIO
+    USE_PERL_ATOF
+    USE_REENTRANT_API
+    USE_THREAD_SAFE_LOCALE
+  Built under linux
+  Compiled at May 23 2019 14:05:36
+  %ENV:
+    PERL6LIB="inst#/pro/3gl/CPAN/rakudo/install"
+  @INC:
+    /pro/lib/perl5/site_perl/5.30.0/x86_64-linux-thread-multi-ld
+    /pro/lib/perl5/site_perl/5.30.0
+    /pro/lib/perl5/5.30.0/x86_64-linux-thread-multi-ld
+    /pro/lib/perl5/5.30.0
diff --git a/cpan/Config-Perl-V/t/37_plv53111qm.t b/cpan/Config-Perl-V/t/37_plv53111qm.t
new file mode 100644 (file)
index 0000000..f566f76
--- /dev/null
@@ -0,0 +1,186 @@
+#!/pro/bin/perl
+
+use strict;
+use warnings;
+
+BEGIN {
+    use Test::More;
+    my $tests = 128;
+    unless ($ENV{PERL_CORE}) {
+       require Test::NoWarnings;
+       Test::NoWarnings->import ();
+       $tests++;
+       }
+
+    plan tests => $tests;
+    }
+
+use Config::Perl::V qw( summary );
+
+ok (my $conf = Config::Perl::V::plv2hash (<DATA>), "Read perl -v block");
+ok (exists $conf->{$_}, "Has $_ entry") for qw( build environment config inc );
+
+is ($conf->{build}{osname}, $conf->{config}{osname}, "osname");
+is ($conf->{build}{stamp}, "Apr  9 2020 17:12:07", "Build time");
+is ($conf->{config}{version}, "5.31.11", "reconstructed \$Config{version}");
+
+my $opt = Config::Perl::V::plv2hash ("")->{build}{options};
+foreach my $o (sort qw(
+       DEBUGGING HAS_TIMES MULTIPLICITY PERL_COPY_ON_WRITE
+       PERL_DONT_CREATE_GVSV PERL_IMPLICIT_CONTEXT PERLIO_LAYERS
+       PERL_MALLOC_WRAP PERL_OP_PARENT PERL_PRESERVE_IVUV PERL_TRACK_MEMPOOL
+       PERL_USE_DEVEL USE_64_BIT_ALL USE_64_BIT_INT USE_ITHREADS
+       USE_LARGE_FILES USE_LOCALE USE_LOCALE_COLLATE USE_LOCALE_CTYPE
+       USE_LOCALE_NUMERIC USE_LOCALE_TIME USE_PERL_ATOF USE_PERLIO
+       USE_QUADMATH USE_REENTRANT_API USE_THREAD_SAFE_LOCALE
+       )) {
+    is ($conf->{build}{options}{$o}, 1, "Runtime option $o set");
+    delete $opt->{$o};
+    }
+foreach my $o (sort keys %$opt) {
+    is ($conf->{build}{options}{$o}, 0, "Runtime option $o unset");
+    }
+
+eval { require Digest::MD5; };
+my $md5 = $@ ? "0" x 32 : "146e648c6239f623b8a8242fc8b5759f";
+ok (my $sig = Config::Perl::V::signature ($conf), "Get signature");
+is ($sig, $md5, "MD5");
+
+is_deeply ($conf->{build}{patches}, [ ], "No patches");
+
+my %check = (
+    alignbytes      => 16,
+    api_version     => 31,
+    bincompat5005   => "undef",
+    byteorder       => 12345678,
+    cc              => "cc",
+    cccdlflags      => "-fPIC",
+    ccdlflags       => "-Wl,-E",
+    config_args     => "-Dusedevel -Duse64bitall -Dusethreads -Duseithreads -Dusequadmath -des",
+    gccversion      => "10.0.1 20200302 (experimental) [revision 778a77357cad11e8dd4c810544330af0fbe843b1]",
+    gnulibc_version => "2.31",
+    ivsize          => 8,
+    ivtype          => "long",
+    ld              => "cc",
+    lddlflags       => "-shared -O2 -L/pro/local/lib -fstack-protector-strong",
+    ldflags         => "-L/pro/local/lib -fstack-protector-strong",
+    libc            => "libc-2.31.so",
+    lseektype       => "off_t",
+    osvers          => "5.6.2-1-default",
+    use64bitall     => "define",
+    use64bitint     => "define",
+    usemymalloc     => "n",
+    default_inc_excludes_dot
+                   => "define",
+    );
+is ($conf->{config}{$_}, $check{$_}, "reconstructed \$Config{$_}") for sort keys %check;
+
+ok (my $info = summary ($conf), "A summary");
+ok (exists $info->{$_}, "Summary has $_") for qw( cc config_args usemymalloc default_inc_excludes_dot );
+is ($info->{default_inc_excludes_dot}, "define", "This build has . NOT in INC");
+
+__END__
+Summary of my perl5 (revision 5 version 31 subversion 11) configuration:
+  Snapshot of: +0300
+  Platform:
+    osname=linux
+    osvers=5.6.2-1-default
+    archname=x86_64-linux-thread-multi-quadmath
+    uname='linux lx09 5.6.2-1-default #1 smp thu apr 2 06:31:32 utc 2020 (c8170d6) x86_64 x86_64 x86_64 gnulinux '
+    config_args='-Dusedevel -Duse64bitall -Dusethreads -Duseithreads -Dusequadmath -des'
+    hint=recommended
+    useposix=true
+    d_sigaction=define
+    useithreads=define
+    usemultiplicity=define
+    use64bitint=define
+    use64bitall=define
+    uselongdouble=undef
+    usemymalloc=n
+    default_inc_excludes_dot=define
+    bincompat5005=undef
+  Compiler:
+    cc='cc'
+    ccflags ='-D_REENTRANT -D_GNU_SOURCE -fPIC -DDEBUGGING -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/pro/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2'
+    optimize='-O2'
+    cppflags='-D_REENTRANT -D_GNU_SOURCE -fPIC -DDEBUGGING -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/pro/local/include'
+    ccversion=''
+    gccversion='10.0.1 20200302 (experimental) [revision 778a77357cad11e8dd4c810544330af0fbe843b1]'
+    gccosandvers=''
+    intsize=4
+    longsize=8
+    ptrsize=8
+    doublesize=8
+    byteorder=12345678
+    doublekind=3
+    d_longlong=define
+    longlongsize=8
+    d_longdbl=define
+    longdblsize=16
+    longdblkind=3
+    ivtype='long'
+    ivsize=8
+    nvtype='__float128'
+    nvsize=16
+    Off_t='off_t'
+    lseeksize=8
+    alignbytes=16
+    prototype=define
+  Linker and Libraries:
+    ld='cc'
+    ldflags ='-L/pro/local/lib -fstack-protector-strong'
+    libpth=/usr/local/lib /usr/lib64/gcc/x86_64-suse-linux/10/include-fixed /usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/lib /usr/lib /pro/local/lib /lib/../lib64 /usr/lib/../lib64 /lib /lib64 /usr/lib64 /usr/local/lib64
+    libs=-lpthread -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat -lquadmath
+    perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc -lquadmath
+    libc=libc-2.31.so
+    so=so
+    useshrplib=false
+    libperl=libperl.a
+    gnulibc_version='2.31'
+  Dynamic Linking:
+    dlsrc=dl_dlopen.xs
+    dlext=so
+    d_dlsymun=undef
+    ccdlflags='-Wl,-E'
+    cccdlflags='-fPIC'
+    lddlflags='-shared -O2 -L/pro/local/lib -fstack-protector-strong'
+
+
+Characteristics of this binary (from libperl):
+  Compile-time options:
+    DEBUGGING
+    HAS_TIMES
+    MULTIPLICITY
+    PERLIO_LAYERS
+    PERL_COPY_ON_WRITE
+    PERL_DONT_CREATE_GVSV
+    PERL_IMPLICIT_CONTEXT
+    PERL_MALLOC_WRAP
+    PERL_OP_PARENT
+    PERL_PRESERVE_IVUV
+    PERL_TRACK_MEMPOOL
+    PERL_USE_DEVEL
+    USE_64_BIT_ALL
+    USE_64_BIT_INT
+    USE_ITHREADS
+    USE_LARGE_FILES
+    USE_LOCALE
+    USE_LOCALE_COLLATE
+    USE_LOCALE_CTYPE
+    USE_LOCALE_NUMERIC
+    USE_LOCALE_TIME
+    USE_PERLIO
+    USE_PERL_ATOF
+    USE_QUADMATH
+    USE_REENTRANT_API
+    USE_THREAD_SAFE_LOCALE
+  Built under linux
+  Compiled at Apr  9 2020 17:12:07
+  %ENV:
+    PERL6LIB="inst#/pro/3gl/CPAN/rakudo/install"
+  @INC:
+    lib
+    /pro/lib/perl5/site_perl/5.31.11/x86_64-linux-thread-multi-quadmath
+    /pro/lib/perl5/site_perl/5.31.11
+    /pro/lib/perl5/5.31.11/x86_64-linux-thread-multi-quadmath
+    /pro/lib/perl5/5.31.11
diff --git a/cpan/Config-Perl-V/t/38_plv5320tld.t b/cpan/Config-Perl-V/t/38_plv5320tld.t
new file mode 100644 (file)
index 0000000..a8f0d73
--- /dev/null
@@ -0,0 +1,182 @@
+#!/pro/bin/perl
+
+use strict;
+use warnings;
+
+BEGIN {
+    use Test::More;
+    my $tests = 128;
+    unless ($ENV{PERL_CORE}) {
+       require Test::NoWarnings;
+       Test::NoWarnings->import ();
+       $tests++;
+       }
+
+    plan tests => $tests;
+    }
+
+use Config::Perl::V qw( summary );
+
+ok (my $conf = Config::Perl::V::plv2hash (<DATA>), "Read perl -v block");
+ok (exists $conf->{$_}, "Has $_ entry") for qw( build environment config inc );
+
+is ($conf->{build}{osname}, $conf->{config}{osname}, "osname");
+is ($conf->{build}{stamp}, "Jun 21 2020 10:17:00", "Build time");
+is ($conf->{config}{version}, "5.32.0", "reconstructed \$Config{version}");
+
+my $opt = Config::Perl::V::plv2hash ("")->{build}{options};
+foreach my $o (sort qw(
+       HAS_TIMES MULTIPLICITY PERLIO_LAYERS PERL_COPY_ON_WRITE
+       PERL_DONT_CREATE_GVSV PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP
+       PERL_OP_PARENT PERL_PRESERVE_IVUV USE_THREAD_SAFE_LOCALE
+       USE_64_BIT_ALL USE_64_BIT_INT USE_ITHREADS USE_LARGE_FILES
+       USE_LOCALE USE_LOCALE_COLLATE USE_LOCALE_CTYPE USE_LOCALE_NUMERIC
+       USE_LOCALE_TIME USE_LONG_DOUBLE USE_PERLIO USE_PERL_ATOF
+       USE_REENTRANT_API
+       )) {
+    is ($conf->{build}{options}{$o}, 1, "Runtime option $o set");
+    delete $opt->{$o};
+    }
+foreach my $o (sort keys %$opt) {
+    is ($conf->{build}{options}{$o}, 0, "Runtime option $o unset");
+    }
+
+eval { require Digest::MD5; };
+my $md5 = $@ ? "0" x 32 : "901df8463a7bda6075bd75539214e75e";
+ok (my $sig = Config::Perl::V::signature ($conf), "Get signature");
+is ($sig, $md5, "MD5");
+
+is_deeply ($conf->{build}{patches}, [ ], "No patches");
+
+my %check = (
+    alignbytes      => 16,
+    api_version     => 32,
+    bincompat5005   => "undef",
+    byteorder       => 12345678,
+    cc              => "cc",
+    cccdlflags      => "-fPIC",
+    ccdlflags       => "-Wl,-E -Wl,-rpath,/pro/lib/perl5/5.32.0/x86_64-linux-thread-multi-ld/CORE",
+    config_args     => "-Dusethreads -Duseithreads -Duse64bitall -Duselongdouble -Duseshrplib -des",
+    gccversion      => "10.1.1 20200507 [revision dd38686d9c810cecbaa80bb82ed91caaa58ad635]",
+    gnulibc_version => "2.31",
+    ivsize          => 8,
+    ivtype          => "long",
+    ld              => "cc",
+    lddlflags       => "-shared -O2 -L/pro/local/lib -fstack-protector-strong",
+    ldflags         => "-L/pro/local/lib -fstack-protector-strong",
+    libc            => "libc-2.31.so",
+    lseektype       => "off_t",
+    osvers          => "5.7.1-1-default",
+    use64bitall     => "define",
+    use64bitint     => "define",
+    usemymalloc     => "n",
+    default_inc_excludes_dot
+                   => "define",
+    );
+is ($conf->{config}{$_}, $check{$_}, "reconstructed \$Config{$_}") for sort keys %check;
+
+ok (my $info = summary ($conf), "A summary");
+ok (exists $info->{$_}, "Summary has $_") for qw( cc config_args usemymalloc default_inc_excludes_dot );
+is ($info->{default_inc_excludes_dot}, "define", "This build has . NOT in INC");
+
+__END__
+Summary of my perl5 (revision 5 version 32 subversion 0) configuration:
+   
+  Platform:
+    osname=linux
+    osvers=5.7.1-1-default
+    archname=x86_64-linux-thread-multi-ld
+    uname='linux lx09 5.7.1-1-default #1 smp wed jun 10 11:53:46 utc 2020 (6a549f6) x86_64 x86_64 x86_64 gnulinux '
+    config_args='-Dusethreads -Duseithreads -Duse64bitall -Duselongdouble -Duseshrplib -des'
+    hint=recommended
+    useposix=true
+    d_sigaction=define
+    useithreads=define
+    usemultiplicity=define
+    use64bitint=define
+    use64bitall=define
+    uselongdouble=define
+    usemymalloc=n
+    default_inc_excludes_dot=define
+    bincompat5005=undef
+  Compiler:
+    cc='cc'
+    ccflags ='-D_REENTRANT -D_GNU_SOURCE -fPIC -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/pro/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2'
+    optimize='-O2'
+    cppflags='-D_REENTRANT -D_GNU_SOURCE -fPIC -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/pro/local/include'
+    ccversion=''
+    gccversion='10.1.1 20200507 [revision dd38686d9c810cecbaa80bb82ed91caaa58ad635]'
+    gccosandvers=''
+    intsize=4
+    longsize=8
+    ptrsize=8
+    doublesize=8
+    byteorder=12345678
+    doublekind=3
+    d_longlong=define
+    longlongsize=8
+    d_longdbl=define
+    longdblsize=16
+    longdblkind=3
+    ivtype='long'
+    ivsize=8
+    nvtype='long double'
+    nvsize=16
+    Off_t='off_t'
+    lseeksize=8
+    alignbytes=16
+    prototype=define
+  Linker and Libraries:
+    ld='cc'
+    ldflags ='-L/pro/local/lib -fstack-protector-strong'
+    libpth=/usr/local/lib /usr/lib64/gcc/x86_64-suse-linux/10/include-fixed /usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/lib /usr/lib /pro/local/lib /lib/../lib64 /usr/lib/../lib64 /lib /lib64 /usr/lib64 /usr/local/lib64
+    libs=-lpthread -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
+    perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
+    libc=libc-2.31.so
+    so=so
+    useshrplib=true
+    libperl=libperl.so
+    gnulibc_version='2.31'
+  Dynamic Linking:
+    dlsrc=dl_dlopen.xs
+    dlext=so
+    d_dlsymun=undef
+    ccdlflags='-Wl,-E -Wl,-rpath,/pro/lib/perl5/5.32.0/x86_64-linux-thread-multi-ld/CORE'
+    cccdlflags='-fPIC'
+    lddlflags='-shared -O2 -L/pro/local/lib -fstack-protector-strong'
+
+
+Characteristics of this binary (from libperl): 
+  Compile-time options:
+    HAS_TIMES
+    MULTIPLICITY
+    PERLIO_LAYERS
+    PERL_COPY_ON_WRITE
+    PERL_DONT_CREATE_GVSV
+    PERL_IMPLICIT_CONTEXT
+    PERL_MALLOC_WRAP
+    PERL_OP_PARENT
+    PERL_PRESERVE_IVUV
+    USE_64_BIT_ALL
+    USE_64_BIT_INT
+    USE_ITHREADS
+    USE_LARGE_FILES
+    USE_LOCALE
+    USE_LOCALE_COLLATE
+    USE_LOCALE_CTYPE
+    USE_LOCALE_NUMERIC
+    USE_LOCALE_TIME
+    USE_LONG_DOUBLE
+    USE_PERLIO
+    USE_PERL_ATOF
+    USE_REENTRANT_API
+    USE_THREAD_SAFE_LOCALE
+  Built under linux
+  Compiled at Jun 21 2020 10:17:00
+  %ENV:
+    PERL6LIB="inst#/pro/3gl/CPAN/rakudo/install"
+  @INC:
+    /pro/lib/perl5/site_perl/5.32.0/x86_64-linux-thread-multi-ld
+    /pro/lib/perl5/site_perl/5.32.0
+    /pro/lib/perl5/5.32.0/x86_64-linux-thread-multi-ld
+    /pro/lib/perl5/5.32.0
diff --git a/cpan/DB_File/.gitignore b/cpan/DB_File/.gitignore
new file mode 100644 (file)
index 0000000..ef1c219
--- /dev/null
@@ -0,0 +1,5 @@
+!/version.c
+/constants.*
+*.bak
+!/Makefile.PL
+!/src/*.c
diff --git a/cpan/Digest-MD5/.gitignore b/cpan/Digest-MD5/.gitignore
new file mode 100644 (file)
index 0000000..e54624d
--- /dev/null
@@ -0,0 +1 @@
+!/Makefile.PL
diff --git a/cpan/Digest-SHA/.gitignore b/cpan/Digest-SHA/.gitignore
new file mode 100644 (file)
index 0000000..335fafb
--- /dev/null
@@ -0,0 +1,2 @@
+!/Makefile.PL
+!/src/*.c
diff --git a/cpan/Encode/.gitignore b/cpan/Encode/.gitignore
new file mode 100644 (file)
index 0000000..2e7d1d6
--- /dev/null
@@ -0,0 +1,13 @@
+!/encengine.c
+!Makefile.PL
+/Byte/Byte.xs
+/CN/CN.xs
+/EBCDIC/EBCDIC.xs
+/JP/JP.xs
+/KR/KR.xs
+/Symbol/Symbol.xs
+/TW/TW.xs
+*.exh
+*.h
+!/Encode/encode.h
+*.fnm
index 77ca93e..d3eb3c1 100644 (file)
@@ -1,5 +1,5 @@
 #
-# $Id: Encode.pm,v 3.07 2020/07/25 12:59:10 dankogai Exp $
+# $Id: Encode.pm,v 3.08 2020/12/02 01:27:44 dankogai Exp $
 #
 package Encode;
 use strict;
@@ -7,7 +7,7 @@ use warnings;
 use constant DEBUG => !!$ENV{PERL_ENCODE_DEBUG};
 our $VERSION;
 BEGIN {
-    $VERSION = sprintf "%d.%02d", q$Revision: 3.07 $ =~ /(\d+)/g;
+    $VERSION = sprintf "%d.%02d", q$Revision: 3.08 $ =~ /(\d+)/g;
     require XSLoader;
     XSLoader::load( __PACKAGE__, $VERSION );
 }
index 8c20d20..f9c7748 100644 (file)
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile.PL,v 2.22 2017/10/06 22:21:53 dankogai Exp $
+# $Id: Makefile.PL,v 2.23 2020/12/02 01:28:17 dankogai Exp dankogai $
 #
 use 5.007003;
 use strict;
@@ -70,7 +70,7 @@ WriteMakefile(
         Storable   => '0',      # bundled with Perl 5.7.3
     },
     TEST_REQUIRES => {
-        'Test::More' => '0.81_01',
+        'Test::More' => '0.92',
     },
     PMLIBDIRS   => \@pmlibdirs,
     INSTALLDIRS => ($] < 5.011 ? 'perl' : 'site'),
index 0f344ea..19a0673 100644 (file)
@@ -61,7 +61,7 @@ encguess - guess character encodings of files
 
 =head1 VERSION
 
-$Id: encguess,v 0.2 2016/08/04 03:15:58 dankogai Exp $
+$Id: encguess,v 0.3 2020/12/02 01:28:17 dankogai Exp dankogai $
 
 =head1 SYNOPSIS
 
@@ -78,7 +78,7 @@ show this message and exit.
 =item -s
 
 specify a list of "suspect encoding types" to test, 
-seperated by either C<:> or C<,>
+separated by either C<:> or C<,>
 
 =item -S
 
index 8b23a7b..644d445 100644 (file)
@@ -1,5 +1,5 @@
 #
-# $Id: GSM0338.pm,v 2.8 2020/07/25 12:59:29 dankogai Exp dankogai $
+# $Id: GSM0338.pm,v 2.9 2020/12/02 01:28:17 dankogai Exp dankogai $
 #
 package Encode::GSM0338;
 
@@ -8,16 +8,13 @@ use warnings;
 use Carp;
 
 use vars qw($VERSION);
-$VERSION = do { my @r = ( q$Revision: 2.8 $ =~ /\d+/g ); sprintf "%d." . "%02d" x $#r, @r };
+$VERSION = do { my @r = ( q$Revision: 2.9 $ =~ /\d+/g ); sprintf "%d." . "%02d" x $#r, @r };
 
 use Encode qw(:fallbacks);
 
 use parent qw(Encode::Encoding);
 __PACKAGE__->Define('gsm0338');
 
-sub needs_lines { 1 }
-sub perlio_ok   { 0 }
-
 use utf8;
 
 # Mapping table according to 3GPP TS 23.038 version 16.0.0 Release 16 and ETSI TS 123 038 V16.0.0 (2020-07)
@@ -182,6 +179,10 @@ sub decode ($$;$) {
             ? $chk->( unpack 'C*', $seq )
             : "\x{FFFD}";
         if ( not exists $GSM2UNI{$seq} and $chk and not ref $chk ) {
+            if ( substr($seq, 0, 1) eq $ESC and ($chk & Encode::STOP_AT_PARTIAL) ) {
+                $bytes .= $seq;
+                last;
+            }
             croak join( '', map { sprintf "\\x%02X", $_ } unpack 'C*', $seq ) . ' does not map to Unicode' if $chk & Encode::DIE_ON_ERR;
             carp join( '', map { sprintf "\\x%02X", $_ } unpack 'C*', $seq ) . ' does not map to Unicode' if $chk & Encode::WARN_ON_ERR;
             if ($chk & Encode::RETURN_ON_ERR) {
index 21a82fa..ab98583 100644 (file)
@@ -13,7 +13,7 @@ BEGIN {
 
 use strict;
 use utf8;
-use Test::More tests => 776;
+use Test::More tests => 777;
 use Encode;
 use Encode::GSM0338;
 
@@ -83,49 +83,9 @@ is encode("gsm0338", chr(0xC7)) => "\x09", 'RT75670: encode';
 is decode("gsm0338", encode('gsm0338', '..@@..')), '..@@..';
 is decode("gsm0338", encode('gsm0338', '..@€..')), '..@€..';
 
-__END__
-for my $c (map { chr } 0..127){
-    my $b = "\x1b$c";
-    my $u =  $Encode::GSM0338::GSM2UNI{$b};
-    next unless $u;
-    $u ||= "\xA0" . $Encode::GSM0338::GSM2UNI{$c};
-    is decode("gsm0338", $b), $u, sprintf("decode ESC+\\x%02X", ord($c) );
-}
-
-__END__
-# old test follows
-ub t { is(decode("gsm0338", my $t = $_[0]), $_[1]) }
-
-# t("\x00",     "\x00"); # ???
-
-# "Round-trip".
-t("\x41",     "\x41");
-
-t("\x01",     "\xA3");
-t("\x02",     "\x24");
-t("\x03",     "\xA5");
-t("\x09",     "\xE7");
-
-t("\x00\x00", "\x00\x00"); # Maybe?
-t("\x00\x1B", "\x40\xA0"); # Maybe?
-t("\x00\x41", "\x40\x41");
-
-# t("\x1B",     "\x1B"); # ???
-
-# Escape with no special second byte is just a NBSP.
-t("\x1B\x41", "\xA0\x41");
-
-t("\x1B\x00", "\xA0\x40"); # Maybe?
-
-# Special escape characters.
-t("\x1B\x0A", "\x0C");
-t("\x1B\x14", "\x5E");
-t("\x1B\x28", "\x7B");
-t("\x1B\x29", "\x7D");
-t("\x1B\x2F", "\x5C");
-t("\x1B\x3C", "\x5B");
-t("\x1B\x3D", "\x7E");
-t("\x1B\x3E", "\x5D");
-t("\x1B\x40", "\x7C");
-t("\x1B\x40", "\x7C");
-t("\x1B\x65", "\x{20AC}");
+# special GSM sequence, € is at 1024 byte buffer boundary
+my $gsm = "\x41" . "\x1B\x65" x 1024;
+open my $fh, '<:encoding(gsm0338)', \$gsm or die;
+my $uni = <$fh>;
+close $fh;
+is $uni, "A" . "€" x 1024, 'PerlIO encoding(gsm0338) read works';
index 2fb43bc..9608180 100644 (file)
@@ -32,11 +32,11 @@ ExtUtils::Install - install files from here to there
 
 =head1 VERSION
 
-2.18
+2.20
 
 =cut
 
-our $VERSION = '2.18';  # <-- do not forget to update the POD section just above this line!
+our $VERSION = '2.20';  # <-- do not forget to update the POD section just above this line!
 $VERSION = eval $VERSION;
 
 =pod
@@ -65,26 +65,22 @@ anything depending on this module cannot proceed until a reboot
 has occurred.
 
 If this value is defined but false then such an operation has
-ocurred, but should not impact later operations.
-
-=over
+occurred, but should not impact later operations.
 
 =begin _private
 
-=item _chmod($$;$)
+=head2 _chmod($$;$)
 
 Wrapper to chmod() for debugging and error trapping.
 
-=item _warnonce(@)
+=head2 _warnonce(@)
 
 Warns about something only once.
 
-=item _choke(@)
+=head2 _choke(@)
 
 Dies with a special message.
 
-=back
-
 =end _private
 
 =cut
@@ -137,8 +133,12 @@ sub _confess {
 }
 
 sub _compare {
-    require File::Compare;
-    File::Compare::compare(@_);
+    # avoid loading File::Compare in the common case
+    if (-f $_[1] && -s _ == -s $_[0]) {
+        require File::Compare;
+        return File::Compare::compare(@_);
+    }
+    return 1;
 }
 
 
@@ -157,9 +157,7 @@ sub _chmod($$;$) {
 
 =begin _private
 
-=over
-
-=item _move_file_at_boot( $file, $target, $moan  )
+=head2 _move_file_at_boot( $file, $target, $moan  )
 
 OS-Specific, Win32/Cygwin
 
@@ -231,8 +229,7 @@ If $moan is true then returns 0 on error and warns instead of dies.
 
 =begin _private
 
-
-=item _unlink_or_rename( $file, $tryhard, $installing )
+=head2 _unlink_or_rename( $file, $tryhard, $installing )
 
 OS-Specific, Win32/Cygwin
 
@@ -263,8 +260,6 @@ On failure throws a fatal error.
 
 =cut
 
-
-
 sub _unlink_or_rename { #XXX OS-SPECIFIC
     my ( $file, $tryhard, $installing )= @_;
 
@@ -310,25 +305,16 @@ sub _unlink_or_rename { #XXX OS-SPECIFIC
 
 }
 
-
-=pod
-
-=back
-
-=head2 Functions
+=head1 Functions
 
 =begin _private
 
-=over
-
-=item _get_install_skip
+=head2 _get_install_skip
 
 Handles loading the INSTALL.SKIP file. Returns an array of patterns to use.
 
 =cut
 
-
-
 sub _get_install_skip {
     my ( $skip, $verbose )= @_;
     if ($ENV{EU_INSTALL_IGNORE_SKIP}) {
@@ -378,9 +364,7 @@ sub _get_install_skip {
     return $skip
 }
 
-=pod
-
-=item _have_write_access
+=head2 _have_write_access
 
 Abstract a -w check that tries to use POSIX::access() if possible.
 
@@ -402,9 +386,7 @@ Abstract a -w check that tries to use POSIX::access() if possible.
     }
 }
 
-=pod
-
-=item _can_write_dir(C<$dir>)
+=head2 _can_write_dir(C<$dir>)
 
 Checks whether a given directory is writable, taking account
 the possibility that the directory might not exist and would have to
@@ -423,7 +405,6 @@ relative paths with C<..> in them. But for our purposes it should work ok
 
 =cut
 
-
 sub _can_write_dir {
     my $dir=shift;
     return
@@ -461,9 +442,7 @@ sub _can_write_dir {
     return 0;
 }
 
-=pod
-
-=item _mkpath($dir,$show,$mode,$verbose,$dry_run)
+=head2 _mkpath($dir,$show,$mode,$verbose,$dry_run)
 
 Wrapper around File::Path::mkpath() to handle errors.
 
@@ -486,10 +465,16 @@ sub _mkpath {
         printf "mkpath(%s,%d,%#o)\n", $dir, $show, $mode;
     }
     if (!$dry_run) {
-        if ( ! eval { File::Path::mkpath($dir,$show,$mode); 1 } ) {
-            _choke("Can't create '$dir'","$@");
+        my @created;
+        eval {
+            @created = File::Path::mkpath($dir,$show,$mode);
+            1;
+        } or _choke("Can't create '$dir'","$@");
+        # if we created any directories, we were able to write and don't need
+        # extra checks
+        if (@created) {
+            return;
         }
-
     }
     my ($can,$root,@make)=_can_write_dir($dir);
     if (!$can) {
@@ -509,9 +494,7 @@ sub _mkpath {
 
 }
 
-=pod
-
-=item _copy($from,$to,$verbose,$dry_run)
+=head2 _copy($from,$to,$verbose,$dry_run)
 
 Wrapper around File::Copy::copy to handle errors.
 
@@ -523,7 +506,6 @@ Dies if the copy fails.
 
 =cut
 
-
 sub _copy {
     my ( $from, $to, $verbose, $dry_run)=@_;
     if ($verbose && $verbose>1) {
@@ -537,7 +519,7 @@ sub _copy {
 
 =pod
 
-=item _chdir($from)
+=head2 _chdir($from)
 
 Wrapper around chdir to catch errors.
 
@@ -558,15 +540,9 @@ sub _chdir {
     return $ret;
 }
 
-=pod
-
-=back
-
 =end _private
 
-=over
-
-=item B<install>
+=head2 install
 
     # deprecated forms
     install(\%from_to);
@@ -774,15 +750,9 @@ sub install { #XXX OS-SPECIFIC
             }
             # we have to do this for back compat with old File::Finds
             # and because the target is relative
-            my $save_cwd = _chdir($cwd);
-            my $diff = 0;
-            # XXX: I wonder how useful this logic is actually -- demerphq
-            if ( $always_copy or !-f $targetfile or -s $targetfile != $size) {
-                $diff++;
-            } else {
-                # we might not need to copy this file
-                $diff = _compare($sourcefile, $targetfile);
-            }
+            my $save_cwd = File::Spec->catfile($cwd, $sourcedir);
+            _chdir($cwd);
+            my $diff = $always_copy || _compare($sourcefile, $targetfile);
             $check_dirs{$targetdir}++
                 unless -w $targetfile;
 
@@ -864,7 +834,7 @@ sub install { #XXX OS-SPECIFIC
 
 =begin _private
 
-=item _do_cleanup
+=head2 _do_cleanup
 
 Standardize finish event for after another instruction has occurred.
 Handles converting $MUST_REBOOT to a die for instance.
@@ -887,12 +857,12 @@ sub _do_cleanup {
 
 =begin _undocumented
 
-=item install_rooted_file( $file )
+=head2 install_rooted_file( $file )
 
 Returns $file, or catfile($INSTALL_ROOT,$file) if $INSTALL_ROOT
 is defined.
 
-=item install_rooted_dir( $dir )
+=head2 install_rooted_dir( $dir )
 
 Returns $dir, or catdir($INSTALL_ROOT,$dir) if $INSTALL_ROOT
 is defined.
@@ -901,7 +871,6 @@ is defined.
 
 =cut
 
-
 sub install_rooted_file {
     if (defined $INSTALL_ROOT) {
         File::Spec->catfile($INSTALL_ROOT, $_[0]);
@@ -921,7 +890,7 @@ sub install_rooted_dir {
 
 =begin _undocumented
 
-=item forceunlink( $file, $tryhard )
+=head2 forceunlink( $file, $tryhard )
 
 Tries to delete a file. If $tryhard is true then we will use whatever
 devious tricks we can to delete the file. Currently this only applies to
@@ -932,7 +901,6 @@ reboot. A wrapper for _unlink_or_rename().
 
 =cut
 
-
 sub forceunlink {
     my ( $file, $tryhard )= @_; #XXX OS-SPECIFIC
     _unlink_or_rename( $file, $tryhard, not("installing") );
@@ -940,7 +908,7 @@ sub forceunlink {
 
 =begin _undocumented
 
-=item directory_not_empty( $dir )
+=head2 directory_not_empty( $dir )
 
 Returns 1 if there is an .exists file somewhere in a directory tree.
 Returns 0 if there is not.
@@ -963,9 +931,9 @@ sub directory_not_empty ($) {
   return $files;
 }
 
-=pod
+=head2 install_default
 
-=item B<install_default> I<DISCOURAGED>
+I<DISCOURAGED>
 
     install_default();
     install_default($fullext);
@@ -1019,7 +987,7 @@ sub install_default {
 }
 
 
-=item B<uninstall>
+=head2 uninstall
 
     uninstall($packlist_file);
     uninstall($packlist_file, $verbose, $dont_execute);
@@ -1057,7 +1025,7 @@ sub uninstall {
 
 =begin _undocumented
 
-=item inc_uninstall($filepath,$libdir,$verbose,$dry_run,$ignore,$results)
+=head2 inc_uninstall($filepath,$libdir,$verbose,$dry_run,$ignore,$results)
 
 Remove shadowed files. If $ignore is true then it is assumed to hold
 a filename to ignore. This is used to prevent spurious warnings from
@@ -1103,13 +1071,8 @@ sub inc_uninstall {
         # The reason why we compare file's contents is, that we cannot
         # know, which is the file we just installed (AFS). So we leave
         # an identical file in place
-        my $diff = 0;
-        if ( -f $targetfile && -s _ == -s $filepath) {
-            # We have a good chance, we can skip this one
-            $diff = _compare($filepath,$targetfile);
-        } else {
-            $diff++;
-        }
+        my $diff = _compare($filepath,$targetfile);
+
         print "#$file and $targetfile differ\n" if $diff && $verbose > 1;
 
         if (!$diff or $targetfile eq $ignore) {
@@ -1150,7 +1113,7 @@ sub inc_uninstall {
 
 =begin _undocumented
 
-=item run_filter($cmd,$src,$dest)
+=head2 run_filter($cmd,$src,$dest)
 
 Filter $src using $cmd into $dest.
 
@@ -1172,9 +1135,7 @@ sub run_filter {
     close CMD or die "Filter command '$cmd' failed for $src";
 }
 
-=pod
-
-=item B<pm_to_blib>
+=head2 pm_to_blib
 
     pm_to_blib(\%from_to);
     pm_to_blib(\%from_to, $autosplit_dir);
@@ -1199,6 +1160,7 @@ environment variable will silence this output.
 sub pm_to_blib {
     my($fromto,$autodir,$pm_filter) = @_;
 
+    my %dirs;
     _mkpath($autodir,0,0755) if defined $autodir;
     while(my($from, $to) = each %$fromto) {
         if( -f $to && -s $from == -s $to && -M $to < -M $from ) {
@@ -1214,7 +1176,7 @@ sub pm_to_blib {
         my $need_filtering = defined $pm_filter && length $pm_filter &&
                              $from =~ /\.pm$/;
 
-        if (!$need_filtering && 0 == _compare($from,$to)) {
+        if (!$need_filtering && !_compare($from,$to)) {
             print "Skip $to (unchanged)\n" unless $INSTALL_QUIET;
             next;
         }
@@ -1222,7 +1184,10 @@ sub pm_to_blib {
             # we wont try hard here. its too likely to mess things up.
             forceunlink($to);
         } else {
-            _mkpath(dirname($to),0,0755);
+            my $dirname = dirname($to);
+            if (!$dirs{$dirname}++) {
+                _mkpath($dirname,0,0755);
+            }
         }
         if ($need_filtering) {
             run_filter($pm_filter, $from, $to);
@@ -1239,10 +1204,9 @@ sub pm_to_blib {
     }
 }
 
-
 =begin _private
 
-=item _autosplit
+=head2 _autosplit
 
 From 1.0307 back, AutoSplit will sometimes leave an open filehandle to
 the file being split.  This causes problems on systems with mandatory
@@ -1293,7 +1257,7 @@ sub DESTROY {
 
 =begin _private
 
-=item _invokant
+=head2 _invokant
 
 Does a heuristic on the stack to see who called us for more intelligent
 error messages. Currently assumes we will be called only by Module::Build
@@ -1320,10 +1284,6 @@ sub _invokant {
     return $builder;
 }
 
-=pod
-
-=back
-
 =head1 ENVIRONMENT
 
 =over 4
index f12ea23..0cfd96b 100644 (file)
@@ -15,7 +15,7 @@ my $DOSISH = ($^O =~ /^(MSWin\d\d|os2|dos|mint)$/);
 
 require VMS::Filespec if $Is_VMS;
 
-our $VERSION = '2.18';
+our $VERSION = '2.20';
 $VERSION = eval $VERSION;
 
 sub _is_prefix {
index f975b41..98d09e3 100644 (file)
@@ -4,7 +4,7 @@ use strict;
 use Carp qw();
 use Config;
 our $Relocations;
-our $VERSION = '2.18';
+our $VERSION = '2.20';
 $VERSION = eval $VERSION;
 
 # Used for generating filehandle globs.  IO::File might not be available!
index 5cf7b80..7d7bf24 100644 (file)
@@ -18,7 +18,7 @@ use File::Basename;
 use File::Spec;
 use File::Temp qw[tempdir];
 
-use Test::More tests => 74;
+use Test::More tests => 76;
 
 BEGIN { use_ok( 'ExtUtils::Installed' ) }
 
@@ -36,6 +36,10 @@ ok( $ei->_is_prefix('foo/bar', 'foo'),
         '_is_prefix() should match valid path prefix' );
 ok( !$ei->_is_prefix('\foo\bar', '\bar'),
         '... should not match wrong prefix' );
+ok( ! defined $ei->_is_prefix( undef, 'foo' ),
+    '_is_prefix() needs two defined arguments' );
+ok( ! defined $ei->_is_prefix( 'foo/bar', undef ),
+    '_is_prefix() needs two defined arguments' );
 
 # _is_type
 ok( $ei->_is_type(0, 'all'), '_is_type() should be true for type of "all"' );
diff --git a/cpan/IO-Compress/.gitignore b/cpan/IO-Compress/.gitignore
new file mode 100644 (file)
index 0000000..e54624d
--- /dev/null
@@ -0,0 +1 @@
+!/Makefile.PL
diff --git a/cpan/IPC-SysV/.gitignore b/cpan/IPC-SysV/.gitignore
new file mode 100644 (file)
index 0000000..6531b6b
--- /dev/null
@@ -0,0 +1,2 @@
+*.inc
+!/Makefile.PL
index 8135e17..d02ec68 100644 (file)
@@ -1,10 +1,19 @@
+# Copyright (C) 2002-2004, 2012 Elizabeth Mattijsen.  All rights reserved.
+# Copyright (C) 2015 Steve Hay.  All rights reserved.
+
+# This module is free software; you can redistribute it and/or modify it under
+# the same terms as Perl itself, i.e. under the terms of either the GNU General
+# Public License or the Artistic License, as specified in the F<LICENCE> file.
+
 package PerlIO::via::QuotedPrint;
 
-$VERSION= '0.08';
+use 5.008001;
 
 # be as strict as possible
 use strict;
 
+our $VERSION = '0.09';
+
 # modules that we need
 use MIME::QuotedPrint (); # no need to pollute this namespace
 
@@ -61,17 +70,13 @@ PerlIO::via::QuotedPrint - PerlIO layer for quoted-printable strings
 
 =head1 SYNOPSIS
 
- use PerlIO::via::QuotedPrint;
   use PerlIO::via::QuotedPrint;
 
- open( my $in, '<:via(QuotedPrint)', 'file.qp' )
-   or die "Can't open file.qp for reading: $!\n";
- open( my $out, '>:via(QuotedPrint)', 'file.qp' )
-   or die "Can't open file.qp for writing: $!\n";
-
-=head1 VERSION
+    open(my $in, '<:via(QuotedPrint)', 'file.qp') or
+        die "Can't open file.qp for reading: $!\n";
 
-This documentation describes version 0.08.
+    open(my $out, '>:via(QuotedPrint)', 'file.qp') or
+        die "Can't open file.qp for writing: $!\n";
 
 =head1 DESCRIPTION
 
@@ -79,24 +84,93 @@ This module implements a PerlIO layer that works on files encoded in the
 quoted-printable format.  It will decode from quoted-printable while reading
 from a handle, and it will encode as quoted-printable while writing to a handle.
 
-=head1 REQUIRED MODULES
+=head1 EXPORTS
+
+I<None>.
+
+=head1 KNOWN BUGS
+
+I<None>.
+
+=head1 FEEDBACK
 
- MIME::QuotedPrint (any)
+Patches, bug reports, suggestions or any other feedback is welcome.
+
+Patches can be sent as GitHub pull requests at
+L<https://github.com/steve-m-hay/PerlIO-via-QuotedPrint/pulls>.
+
+Bug reports and suggestions can be made on the CPAN Request Tracker at
+L<https://rt.cpan.org/Public/Bug/Report.html?Queue=PerlIO-via-QuotedPrint>.
+
+Currently active requests on the CPAN Request Tracker can be viewed at
+L<https://rt.cpan.org/Public/Dist/Display.html?Status=Active;Queue=PerlIO-via-QuotedPrint>.
+
+Please test this distribution.  See CPAN Testers Reports at
+L<https://www.cpantesters.org/> for details of how to get involved.
+
+Previous test results on CPAN Testers Reports can be viewed at
+L<https://www.cpantesters.org/distro/P/PerlIO-via-QuotedPrint.html>.
+
+Please rate this distribution on CPAN Ratings at
+L<https://cpanratings.perl.org/rate/?distribution=PerlIO-via-QuotedPrint>.
 
 =head1 SEE ALSO
 
-L<PerlIO::via>, L<MIME::QuotedPrint>, L<PerlIO::via::Base64>,
-L<PerlIO::via::MD5>, L<PerlIO::via::StripHTML>, L<PerlIO::via::Rotate>.
+L<PerlIO::via>,
+L<MIME::QuotedPrint>.
 
 =head1 ACKNOWLEDGEMENTS
 
-Based on example that was initially added to MIME::QuotedPrint.pm for the
-5.8.0 distribution of Perl.
+Based on an example in the standard library module MIME::QuotedPrint in Perl
+(version 5.8.0).
+
+=head1 AVAILABILITY
+
+The latest version of this module is available from CPAN (see
+L<perlmodlib/"CPAN"> for details) at
+
+L<https://metacpan.org/release/PerlIO-via-QuotedPrint> or
+
+L<https://www.cpan.org/authors/id/S/SH/SHAY/> or
+
+L<https://www.cpan.org/modules/by-module/PerlIO/>.
+
+The latest source code is available from GitHub at
+L<https://github.com/steve-m-hay/PerlIO-via-QuotedPrint>.
+
+=head1 INSTALLATION
+
+See the F<INSTALL> file.
+
+=head1 AUTHOR
+
+Elizabeth Mattijsen E<lt>L<liz@dijkmat.nl|mailto:liz@dijkmat.nl>E<gt>.
+
+Steve Hay E<lt>L<shay@cpan.org|mailto:shay@cpan.org>E<gt> is now maintaining
+PerlIO::via::QuotedPrint as of version 0.08.
 
 =head1 COPYRIGHT
 
-Copyright (c) 2002, 2003, 2004, 2012 Elizabeth Mattijsen.  All rights reserved.
-This library is free software; you can redistribute it and/or modify it under
-the same terms as Perl itself.
+Copyright (C) 2002-2004, 2012 Elizabeth Mattijsen.  All rights reserved.
+
+Copyright (C) 2015, 2020 Steve Hay.  All rights reserved.
+
+=head1 LICENCE
+
+This module is free software; you can redistribute it and/or modify it under
+the same terms as Perl itself, i.e. under the terms of either the GNU General
+Public License or the Artistic License, as specified in the F<LICENCE> file.
+
+=head1 VERSION
+
+Version 0.09
+
+=head1 DATE
+
+08 Dec 2020
+
+=head1 HISTORY
+
+See the F<Changes> file.
 
 =cut
index 33366bd..5270fb4 100644 (file)
@@ -1,4 +1,9 @@
-BEGIN {                                # Magic Perl CORE pragma
+use 5.008001;
+
+use strict;
+use warnings;
+
+BEGIN {                         # Magic Perl CORE pragma
     unless (find PerlIO::Layer 'perlio') {
         print "1..0 # Skip: PerlIO not used\n";
         exit 0;
@@ -8,8 +13,6 @@ BEGIN {                                # Magic Perl CORE pragma
     }
 }
 
-use strict;
-use warnings;
 use Test::More tests => 11;
 
 BEGIN { use_ok('PerlIO::via::QuotedPrint') }
@@ -34,16 +37,16 @@ ok(
  "opening '$file' for writing"
 );
 
-ok( (print $out $decoded),             'print to file' );
-ok( close( $out ),                     'closing encoding handle' );
+ok( (print $out $decoded),              'print to file' );
+ok( close( $out ),                      'closing encoding handle' );
 
 # Check encoding without layers
 
 {
 local $/ = undef;
-ok( open( my $test,$file ),            'opening without layer' );
-is( $encoded,readline( $test ),                'check encoded content' );
-ok( close( $test ),                    'close test handle' );
+ok( open( my $test, '<', $file ),       'opening without layer' );
+is( $encoded,readline( $test ),         'check encoded content' );
+ok( close( $test ),                     'close test handle' );
 }
 
 # Check decoding _with_ layers
@@ -52,10 +55,10 @@ ok(
  open( my $in,'<:via(QuotedPrint)', $file ),
  "opening '$file' for reading"
 );
-is( $decoded,join( '',<$in> ),         'check decoding' );
-ok( close( $in ),                      'close decoding handle' );
+is( $decoded,join( '',<$in> ),          'check decoding' );
+ok( close( $in ),                       'close decoding handle' );
 
 # Remove whatever we created now
 
-ok( unlink( $file ),                   "remove test file '$file'" );
+ok( unlink( $file ),                    "remove test file '$file'" );
 1 while unlink $file; # multiversioned filesystems
diff --git a/cpan/PerlIO-via-QuotedPrint/t/changes.t b/cpan/PerlIO-via-QuotedPrint/t/changes.t
new file mode 100644 (file)
index 0000000..bd743ad
--- /dev/null
@@ -0,0 +1,48 @@
+#!perl
+#===============================================================================
+#
+# t/changes.t
+#
+# DESCRIPTION
+#   Test script to check CPAN::Changes conformance.
+#
+# COPYRIGHT
+#   Copyright (C) 2015 Steve Hay.  All rights reserved.
+#
+# LICENCE
+#   This script is free software; you can redistribute it and/or modify it under
+#   the same terms as Perl itself, i.e. under the terms of either the GNU
+#   General Public License or the Artistic License, as specified in the LICENCE
+#   file.
+#
+#===============================================================================
+
+use 5.008001;
+
+use strict;
+use warnings;
+
+use Test::More;
+
+#===============================================================================
+# MAIN PROGRAM
+#===============================================================================
+
+MAIN: {
+    plan skip_all => 'Author testing only' unless $ENV{AUTHOR_TESTING};
+
+    my $ok = eval {
+        require Test::CPAN::Changes;
+        Test::CPAN::Changes->import();
+        1;
+    };
+
+    if (not $ok) {
+        plan skip_all => 'Test::CPAN::Changes required to test Changes';
+    }
+    else {
+        changes_ok();
+    }
+}
+
+#===============================================================================
diff --git a/cpan/PerlIO-via-QuotedPrint/t/critic.t b/cpan/PerlIO-via-QuotedPrint/t/critic.t
new file mode 100644 (file)
index 0000000..882853a
--- /dev/null
@@ -0,0 +1,48 @@
+#!perl
+#===============================================================================
+#
+# t/critic.t
+#
+# DESCRIPTION
+#   Test script to check Perl::Critic conformance.
+#
+# COPYRIGHT
+#   Copyright (C) 2015 Steve Hay.  All rights reserved.
+#
+# LICENCE
+#   This script is free software; you can redistribute it and/or modify it under
+#   the same terms as Perl itself, i.e. under the terms of either the GNU
+#   General Public License or the Artistic License, as specified in the LICENCE
+#   file.
+#
+#===============================================================================
+
+use 5.008001;
+
+use strict;
+use warnings;
+
+use Test::More;
+
+#===============================================================================
+# MAIN PROGRAM
+#===============================================================================
+
+MAIN: {
+    plan skip_all => 'Author testing only' unless $ENV{AUTHOR_TESTING};
+
+    my $ok = eval {
+        require Test::Perl::Critic;
+        Test::Perl::Critic->import(-profile => '');
+        1;
+    };
+
+    if (not $ok) {
+        plan skip_all => 'Test::Perl::Critic required to test with Perl::Critic';
+    }
+    else {
+        all_critic_ok('.');
+    }
+}
+
+#===============================================================================
diff --git a/cpan/PerlIO-via-QuotedPrint/t/pod.t b/cpan/PerlIO-via-QuotedPrint/t/pod.t
new file mode 100644 (file)
index 0000000..0e269bc
--- /dev/null
@@ -0,0 +1,51 @@
+#!perl
+#===============================================================================
+#
+# t/pod.t
+#
+# DESCRIPTION
+#   Test script to check POD.
+#
+# COPYRIGHT
+#   Copyright (C) 2015 Steve Hay.  All rights reserved.
+#
+# LICENCE
+#   This script is free software; you can redistribute it and/or modify it under
+#   the same terms as Perl itself, i.e. under the terms of either the GNU
+#   General Public License or the Artistic License, as specified in the LICENCE
+#   file.
+#
+#===============================================================================
+
+use 5.008001;
+
+use strict;
+use warnings;
+
+use Test::More;
+
+#===============================================================================
+# MAIN PROGRAM
+#===============================================================================
+
+MAIN: {
+    plan skip_all => 'Author testing only' unless $ENV{AUTHOR_TESTING};
+
+    my $ok = eval {
+        require Test::Pod;
+        Test::Pod->import();
+        1;
+    };
+
+    if (not $ok) {
+        plan skip_all => 'Test::Pod required to test POD';
+    }
+    elsif ($Test::Pod::VERSION < 1.00) {
+        plan skip_all => 'Test::Pod 1.00 or higher required to test POD';
+    }
+    else {
+        all_pod_files_ok();
+    }
+}
+
+#===============================================================================
diff --git a/cpan/PerlIO-via-QuotedPrint/t/pod_coverage.t b/cpan/PerlIO-via-QuotedPrint/t/pod_coverage.t
new file mode 100644 (file)
index 0000000..d733da9
--- /dev/null
@@ -0,0 +1,54 @@
+#!perl
+#===============================================================================
+#
+# t/pod_coverage.t
+#
+# DESCRIPTION
+#   Test script to check POD coverage.
+#
+# COPYRIGHT
+#   Copyright (C) 2015 Steve Hay.  All rights reserved.
+#
+# LICENCE
+#   This script is free software; you can redistribute it and/or modify it under
+#   the same terms as Perl itself, i.e. under the terms of either the GNU
+#   General Public License or the Artistic License, as specified in the LICENCE
+#   file.
+#
+#===============================================================================
+
+use 5.008001;
+
+use strict;
+use warnings;
+
+use Test::More;
+
+#===============================================================================
+# MAIN PROGRAM
+#===============================================================================
+
+MAIN: {
+    plan skip_all => 'Author testing only' unless $ENV{AUTHOR_TESTING};
+
+    my $ok = eval {
+        require Test::Pod::Coverage;
+        Test::Pod::Coverage->import();
+        1;
+    };
+
+    if (not $ok) {
+        plan skip_all => 'Test::Pod::Coverage required to test POD coverage';
+    }
+    elsif ($Test::Pod::Coverage::VERSION < 0.08) {
+        plan skip_all => 'Test::Pod::Coverage 0.08 or higher required to test POD coverage';
+    }
+    else {
+        plan tests => 1;
+        pod_coverage_ok('PerlIO::via::QuotedPrint', {
+            also_private => [qw(FILL PUSHED WRITE)]
+        });
+    }
+}
+
+#===============================================================================
diff --git a/cpan/Pod-Checker/.gitignore b/cpan/Pod-Checker/.gitignore
new file mode 100644 (file)
index 0000000..48f56f3
--- /dev/null
@@ -0,0 +1 @@
+/podchecker*
diff --git a/cpan/Pod-Perldoc/.gitignore b/cpan/Pod-Perldoc/.gitignore
new file mode 100644 (file)
index 0000000..e54624d
--- /dev/null
@@ -0,0 +1 @@
+!/Makefile.PL
diff --git a/cpan/Pod-Usage/.gitignore b/cpan/Pod-Usage/.gitignore
new file mode 100644 (file)
index 0000000..523ffa1
--- /dev/null
@@ -0,0 +1 @@
+/pod2usage*
diff --git a/cpan/Scalar-List-Utils/.gitignore b/cpan/Scalar-List-Utils/.gitignore
new file mode 100644 (file)
index 0000000..e54624d
--- /dev/null
@@ -0,0 +1 @@
+!/Makefile.PL
diff --git a/cpan/Socket/.gitignore b/cpan/Socket/.gitignore
new file mode 100644 (file)
index 0000000..6531b6b
--- /dev/null
@@ -0,0 +1,2 @@
+*.inc
+!/Makefile.PL
diff --git a/cpan/Sys-Syslog/.gitignore b/cpan/Sys-Syslog/.gitignore
new file mode 100644 (file)
index 0000000..b2bd5aa
--- /dev/null
@@ -0,0 +1,14 @@
+*.inc
+macros.all
+MYMETA.*
+Makefile
+Makefile.old
+Makefile.bak
+MANIFEST.bak
+Syslog.bs
+Syslog.c
+Syslog.o
+blib/
+pm_to_blib
+!/Makefile.PL
+!/fallback/*.inc
index 9298726..a33fe97 100644 (file)
@@ -18,11 +18,11 @@ App::Prove - Implements the C<prove> command.
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 DESCRIPTION
 
index 0b61a82..006d4f8 100644 (file)
@@ -25,11 +25,11 @@ App::Prove::State - State storage for the C<prove> command.
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 DESCRIPTION
 
index 8f89c77..fb5e2d5 100644 (file)
@@ -14,11 +14,11 @@ App::Prove::State::Result - Individual test suite results.
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 DESCRIPTION
 
index b795280..f4cddac 100644 (file)
@@ -9,11 +9,11 @@ App::Prove::State::Result::Test - Individual test results.
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 DESCRIPTION
 
index 78e07ab..289f093 100644 (file)
@@ -12,11 +12,11 @@ and L<TAP::Harness>
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 use constant GOT_TIME_HIRES => do {
     eval 'use Time::HiRes qw(time);';
index bf65e12..a9c0e3b 100644 (file)
@@ -58,11 +58,11 @@ TAP::Formatter::Base - Base class for harness output delegates
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 DESCRIPTION
 
index 7980790..0f08edf 100644 (file)
@@ -39,11 +39,11 @@ TAP::Formatter::Color - Run Perl test scripts with color
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 DESCRIPTION
 
index 1c82ef4..3217099 100644 (file)
@@ -11,11 +11,11 @@ TAP::Formatter::Console - Harness output delegate for default console output
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 DESCRIPTION
 
index 6826b4e..7f6767c 100644 (file)
@@ -41,11 +41,11 @@ TAP::Formatter::Console::ParallelSession - Harness output delegate for parallel
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 DESCRIPTION
 
index 492bdd7..8c2f957 100644 (file)
@@ -26,11 +26,11 @@ TAP::Formatter::Console::Session - Harness output delegate for default console o
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 DESCRIPTION
 
index ced7b3f..5a3a558 100644 (file)
@@ -13,11 +13,11 @@ TAP::Formatter::File - Harness output delegate for file output
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 DESCRIPTION
 
index 3403540..fb7b182 100644 (file)
@@ -10,11 +10,11 @@ TAP::Formatter::File::Session - Harness output delegate for file output
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 DESCRIPTION
 
index 2022220..a26048d 100644 (file)
@@ -23,11 +23,11 @@ TAP::Formatter::Session - Abstract base class for harness output delegate
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 METHODS
 
index a2f6daf..1b8ee87 100644 (file)
@@ -16,11 +16,11 @@ TAP::Harness - Run test scripts with statistics
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 $ENV{HARNESS_ACTIVE}  = 1;
 $ENV{HARNESS_VERSION} = $VERSION;
@@ -619,6 +619,10 @@ sub _aggregate_parallel {
 
             my ( $parser, $session ) = $self->make_parser($job);
             $mux->add( $parser, [ $session, $job ] );
+
+            # The job has started: begin the timers
+            $parser->start_time( $parser->get_time );
+            $parser->start_times( $parser->get_times );
         }
 
         if ( my ( $parser, $stash, $result ) = $mux->next ) {
index 077626d..78e75fb 100644 (file)
@@ -7,7 +7,7 @@ use constant IS_VMS => ( $^O eq 'VMS' );
 use TAP::Object;
 use Text::ParseWords qw/shellwords/;
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 # Get the parts of @INC which are changed from the stock list AND
 # preserve reordering of stock directories.
@@ -126,7 +126,7 @@ TAP::Harness::Env - Parsing harness related environmental variables where approp
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =head1 SYNOPSIS
 
index e9da17f..d3063c2 100644 (file)
@@ -9,11 +9,11 @@ TAP::Object - Base class that provides common functionality to all C<TAP::*> mod
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 SYNOPSIS
 
index 34f4110..e8d51b1 100644 (file)
@@ -27,11 +27,11 @@ TAP::Parser - Parse L<TAP|Test::Harness::TAP> output
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 my $DEFAULT_TAP_VERSION = 12;
 my $MAX_TAP_VERSION     = 13;
@@ -1384,8 +1384,8 @@ sub _iter {
     my $state       = 'INIT';
     my $state_table = $self->_make_state_table;
 
-    $self->start_time( $self->get_time );
-    $self->start_times( $self->get_times );
+    $self->start_time( $self->get_time ) unless $self->{start_time};
+    $self->start_times( $self->get_times ) unless $self->{start_times};
 
     # Make next_state closure
     my $next_state = sub {
index 65be445..1f4ff5d 100644 (file)
@@ -12,11 +12,11 @@ TAP::Parser::Aggregator - Aggregate TAP::Parser results
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 SYNOPSIS
 
index ff0f2aa..0cf4d5b 100644 (file)
@@ -14,11 +14,11 @@ TAP::Parser::Grammar - A grammar for the Test Anything Protocol.
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 SYNOPSIS
 
index fab48cb..b516929 100644 (file)
@@ -11,11 +11,11 @@ TAP::Parser::Iterator - Base class for TAP source iterators
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 SYNOPSIS
 
index 5a098cc..3ea348d 100644 (file)
@@ -11,11 +11,11 @@ TAP::Parser::Iterator::Array - Iterator for array-based TAP sources
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 SYNOPSIS
 
index a121485..8e95a44 100644 (file)
@@ -16,11 +16,11 @@ TAP::Parser::Iterator::Process - Iterator for process-based TAP sources
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 SYNOPSIS
 
index 2a21485..3054531 100644 (file)
@@ -11,11 +11,11 @@ TAP::Parser::Iterator::Stream - Iterator for filehandle-based TAP sources
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 SYNOPSIS
 
index cd67702..3529c2f 100644 (file)
@@ -16,11 +16,11 @@ TAP::Parser::IteratorFactory - Figures out which SourceHandler objects to use fo
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 SYNOPSIS
 
index 16af2d3..164e9af 100644 (file)
@@ -17,11 +17,11 @@ TAP::Parser::Multiplexer - Multiplex multiple TAP::Parsers
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 SYNOPSIS
 
index c892796..698402a 100644 (file)
@@ -24,11 +24,11 @@ TAP::Parser::Result - Base class for TAP::Parser output objects
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 SYNOPSIS
 
index facae6f..38ee458 100644 (file)
@@ -11,11 +11,11 @@ TAP::Parser::Result::Bailout - Bailout result token.
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 DESCRIPTION
 
index 0f99b57..a07308e 100644 (file)
@@ -11,11 +11,11 @@ TAP::Parser::Result::Comment - Comment result token.
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 DESCRIPTION
 
index 9db060e..1029694 100644 (file)
@@ -11,11 +11,11 @@ TAP::Parser::Result::Plan - Plan result token.
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 DESCRIPTION
 
index c7a26be..897e0da 100644 (file)
@@ -11,11 +11,11 @@ TAP::Parser::Result::Pragma - TAP pragma token.
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 DESCRIPTION
 
index b3bd224..e2c9781 100644 (file)
@@ -11,11 +11,11 @@ TAP::Parser::Result::Test - Test result token.
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 DESCRIPTION
 
index d735ed1..cc04c8a 100644 (file)
@@ -11,11 +11,11 @@ TAP::Parser::Result::Unknown - Unknown result token.
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 DESCRIPTION
 
index 5f4cb93..8a2bd7e 100644 (file)
@@ -11,11 +11,11 @@ TAP::Parser::Result::Version - TAP syntax version token.
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 DESCRIPTION
 
index a88b8da..17de945 100644 (file)
@@ -11,11 +11,11 @@ TAP::Parser::Result::YAML - YAML result token.
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 DESCRIPTION
 
index 27776ea..54d29a2 100644 (file)
@@ -29,11 +29,11 @@ TAP::Parser::ResultFactory - Factory for creating TAP::Parser output objects
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head2 DESCRIPTION
 
index e13d68e..7e3ddc2 100644 (file)
@@ -13,11 +13,11 @@ TAP::Parser::Scheduler - Schedule tests during parallel testing
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 SYNOPSIS
 
index b765ab2..bfcb0f7 100644 (file)
@@ -10,11 +10,11 @@ TAP::Parser::Scheduler::Job - A single testing job.
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 SYNOPSIS
 
index 47bc28f..29f5c0d 100644 (file)
@@ -10,11 +10,11 @@ TAP::Parser::Scheduler::Spinner - A no-op job.
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 SYNOPSIS
 
index 5bd85e3..74c22cc 100644 (file)
@@ -14,11 +14,11 @@ TAP::Parser::Source - a TAP source & meta data about it
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 SYNOPSIS
 
index 0156b99..f80c1ca 100644 (file)
@@ -12,11 +12,11 @@ TAP::Parser::SourceHandler - Base class for different TAP source handlers
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 SYNOPSIS
 
index 376e8d1..0ad412b 100644 (file)
@@ -16,11 +16,11 @@ TAP::Parser::SourceHandler::Executable - Stream output from an executable TAP so
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 SYNOPSIS
 
index 7e18437..48f9821 100644 (file)
@@ -16,11 +16,11 @@ TAP::Parser::SourceHandler::File - Stream TAP from a text file.
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 SYNOPSIS
 
index a0a0513..751e68a 100644 (file)
@@ -16,11 +16,11 @@ TAP::Parser::SourceHandler::Handle - Stream TAP from an IO::Handle or a GLOB.
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 SYNOPSIS
 
index c2ea252..26b408a 100644 (file)
@@ -21,11 +21,11 @@ TAP::Parser::SourceHandler::Perl - Stream TAP from a Perl executable
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 SYNOPSIS
 
index 2ef7711..9bf3b27 100644 (file)
@@ -16,11 +16,11 @@ TAP::Parser::SourceHandler::RawTAP - Stream output from raw TAP in a scalar/arra
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 =head1 SYNOPSIS
 
index 1a8185e..eafc37a 100644 (file)
@@ -5,7 +5,7 @@ use warnings;
 
 use base 'TAP::Object';
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 # TODO:
 #   Handle blessed object syntax
@@ -269,7 +269,7 @@ TAP::Parser::YAMLish::Reader - Read YAMLish data from iterator
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =head1 SYNOPSIS
 
index 904244a..9d6366c 100644 (file)
@@ -5,7 +5,7 @@ use warnings;
 
 use base 'TAP::Object';
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 my $ESCAPE_CHAR = qr{ [ \x00-\x1f \" ] }x;
 my $ESCAPE_KEY  = qr{ (?: ^\W ) | $ESCAPE_CHAR }x;
@@ -146,7 +146,7 @@ TAP::Parser::YAMLish::Writer - Write YAMLish data
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =head1 SYNOPSIS
 
index 6cce46e..7084d62 100644 (file)
@@ -31,11 +31,11 @@ Test::Harness - Run Perl standard test scripts with statistics
 
 =head1 VERSION
 
-Version 3.42
+Version 3.43
 
 =cut
 
-our $VERSION = '3.42';
+our $VERSION = '3.43';
 
 # Backwards compatibility for exportable variable names.
 *verbose  = *Verbose;
index 767892c..77cf442 100644 (file)
@@ -242,11 +242,12 @@ SKIP: {
     my $symlink = File::Spec->catfile( $dir, 'source_link.T' );
     my $source  = TAP::Parser::Source->new;
 
-    eval { symlink( File::Spec->rel2abs($test), $symlink ) };
+    my $did_symlink = eval { symlink( File::Spec->rel2abs($test), $symlink ) };
     if ( my $e = $@ ) {
         diag($@);
         die "aborting test";
     }
+    skip "symlink not successful: $!", 9 unless $did_symlink;
 
     $source->raw( \$symlink );
     my $meta = $source->assemble_meta;
index f1a5780..324a023 100644 (file)
@@ -1,35 +1,44 @@
+# Copyright (C) 1997-2001 Damian Conway.  All rights reserved.
+# Copyright (C) 2009 Adam Kennedy.
+# Copyright (C) 2015 Steve Hay.  All rights reserved.
+
+# This module is free software; you can redistribute it and/or modify it under
+# the same terms as Perl itself, i.e. under the terms of either the GNU General
+# Public License or the Artistic License, as specified in the F<LICENCE> file.
+
 package Text::Balanced;
 
 # EXTRACT VARIOUSLY DELIMITED TEXT SEQUENCES FROM STRINGS.
 # FOR FULL DOCUMENTATION SEE Balanced.pod
 
-use 5.005;
+use 5.008001;
 use strict;
 use Exporter ();
-use SelfLoader;
 
 use vars qw { $VERSION @ISA %EXPORT_TAGS };
 BEGIN {
-       $VERSION     = '2.03';
-       @ISA         = 'Exporter';
-       %EXPORT_TAGS = (
-               ALL => [ qw{
-                       &extract_delimited
-                       &extract_bracketed
-                       &extract_quotelike
-                       &extract_codeblock
-                       &extract_variable
-                       &extract_tagged
-                       &extract_multiple
-                       &gen_delimited_pat
-                       &gen_extract_tagged
-                       &delimited_pat
-               } ],
-       );
+    $VERSION     = '2.04';
+    @ISA         = 'Exporter';
+    %EXPORT_TAGS = (
+        ALL => [ qw{
+            &extract_delimited
+            &extract_bracketed
+            &extract_quotelike
+            &extract_codeblock
+            &extract_variable
+            &extract_tagged
+            &extract_multiple
+            &gen_delimited_pat
+            &gen_extract_tagged
+            &delimited_pat
+        } ],
+    );
 }
 
 Exporter::export_ok_tags('ALL');
 
+## no critic (Subroutines::ProhibitSubroutinePrototypes)
+
 # PROTOTYPES
 
 sub _match_bracketed($$$$$$);
@@ -40,80 +49,80 @@ sub _match_quotelike($$$$);
 # HANDLE RETURN VALUES IN VARIOUS CONTEXTS
 
 sub _failmsg {
-       my ($message, $pos) = @_;
-       $@ = bless {
-               error => $message,
-               pos   => $pos,
-       }, 'Text::Balanced::ErrorMsg';
+    my ($message, $pos) = @_;
+    $@ = bless {
+        error => $message,
+        pos   => $pos,
+    }, 'Text::Balanced::ErrorMsg';
 }
 
 sub _fail {
-       my ($wantarray, $textref, $message, $pos) = @_;
-       _failmsg $message, $pos if $message;
-       return (undef, $$textref, undef) if $wantarray;
-       return undef;
+    my ($wantarray, $textref, $message, $pos) = @_;
+    _failmsg $message, $pos if $message;
+    return (undef, $$textref, undef) if $wantarray;
+    return;
 }
 
 sub _succeed {
-       $@ = undef;
-       my ($wantarray,$textref) = splice @_, 0, 2;
-       my ($extrapos, $extralen) = @_ > 18
-               ? splice(@_, -2, 2)
-               : (0, 0);
-       my ($startlen, $oppos) = @_[5,6];
-       my $remainderpos = $_[2];
-       if ( $wantarray ) {
-               my @res;
-               while (my ($from, $len) = splice @_, 0, 2) {
-                       push @res, substr($$textref, $from, $len);
-               }
-               if ( $extralen ) { # CORRECT FILLET
-                       my $extra = substr($res[0], $extrapos-$oppos, $extralen, "\n");
-                       $res[1] = "$extra$res[1]";
-                       eval { substr($$textref,$remainderpos,0) = $extra;
-                              substr($$textref,$extrapos,$extralen,"\n")} ;
-                               #REARRANGE HERE DOC AND FILLET IF POSSIBLE
-                       pos($$textref) = $remainderpos-$extralen+1; # RESET \G
-               } else {
-                       pos($$textref) = $remainderpos;             # RESET \G
-               }
-               return @res;
-       } else {
-               my $match = substr($$textref,$_[0],$_[1]);
-               substr($match,$extrapos-$_[0]-$startlen,$extralen,"") if $extralen;
-               my $extra = $extralen
-                       ? substr($$textref, $extrapos, $extralen)."\n" : "";
-               eval {substr($$textref,$_[4],$_[1]+$_[5])=$extra} ;     #CHOP OUT PREFIX & MATCH, IF POSSIBLE
-               pos($$textref) = $_[4];                         # RESET \G
-               return $match;
-       }
+    $@ = undef;
+    my ($wantarray,$textref) = splice @_, 0, 2;
+    my ($extrapos, $extralen) = @_ > 18
+        ? splice(@_, -2, 2)
+        : (0, 0);
+    my ($startlen, $oppos) = @_[5,6];
+    my $remainderpos = $_[2];
+    if ( $wantarray ) {
+        my @res;
+        while (my ($from, $len) = splice @_, 0, 2) {
+            push @res, substr($$textref, $from, $len);
+        }
+        if ( $extralen ) { # CORRECT FILLET
+            my $extra = substr($res[0], $extrapos-$oppos, $extralen, "\n");
+            $res[1] = "$extra$res[1]";
+            eval { substr($$textref,$remainderpos,0) = $extra;
+                   substr($$textref,$extrapos,$extralen,"\n")} ;
+                    #REARRANGE HERE DOC AND FILLET IF POSSIBLE
+            pos($$textref) = $remainderpos-$extralen+1; # RESET \G
+        } else {
+            pos($$textref) = $remainderpos;             # RESET \G
+        }
+        return @res;
+    } else {
+        my $match = substr($$textref,$_[0],$_[1]);
+        substr($match,$extrapos-$_[0]-$startlen,$extralen,"") if $extralen;
+        my $extra = $extralen
+            ? substr($$textref, $extrapos, $extralen)."\n" : "";
+        eval {substr($$textref,$_[4],$_[1]+$_[5])=$extra} ;     #CHOP OUT PREFIX & MATCH, IF POSSIBLE
+        pos($$textref) = $_[4];                         # RESET \G
+        return $match;
+    }
 }
 
 # BUILD A PATTERN MATCHING A SIMPLE DELIMITED STRING
 
 sub gen_delimited_pat($;$)  # ($delimiters;$escapes)
 {
-       my ($dels, $escs) = @_;
-       return "" unless $dels =~ /\S/;
-       $escs = '\\' unless $escs;
-       $escs .= substr($escs,-1) x (length($dels)-length($escs));
-       my @pat = ();
-       my $i;
-       for ($i=0; $i<length $dels; $i++)
-       {
-               my $del = quotemeta substr($dels,$i,1);
-               my $esc = quotemeta substr($escs,$i,1);
-               if ($del eq $esc)
-               {
-                       push @pat, "$del(?:[^$del]*(?:(?:$del$del)[^$del]*)*)$del";
-               }
-               else
-               {
-                       push @pat, "$del(?:[^$esc$del]*(?:$esc.[^$esc$del]*)*)$del";
-               }
-       }
-       my $pat = join '|', @pat;
-       return "(?:$pat)";
+    my ($dels, $escs) = @_;
+    return "" unless $dels =~ /\S/;
+    $escs = '\\' unless $escs;
+    $escs .= substr($escs,-1) x (length($dels)-length($escs));
+    my @pat = ();
+    my $i;
+    for ($i=0; $i<length $dels; $i++)
+    {
+        my $del = quotemeta substr($dels,$i,1);
+        my $esc = quotemeta substr($escs,$i,1);
+        if ($del eq $esc)
+        {
+            push @pat, "$del(?:[^$del]*(?:(?:$del$del)[^$del]*)*)$del";
+        }
+        else
+        {
+            push @pat, "$del(?:[^$esc$del]*(?:$esc.[^$esc$del]*)*)$del";
+        }
+    }
+    my $pat = join '|', @pat;
+    return "(?:$pat)";
 }
 
 *delimited_pat = \&gen_delimited_pat;
@@ -122,315 +131,316 @@ sub gen_delimited_pat($;$)  # ($delimiters;$escapes)
 
 sub extract_delimited (;$$$$)
 {
-       my $textref = defined $_[0] ? \$_[0] : \$_;
-       my $wantarray = wantarray;
-       my $del  = defined $_[1] ? $_[1] : qq{\'\"\`};
-       my $pre  = defined $_[2] ? $_[2] : '\s*';
-       my $esc  = defined $_[3] ? $_[3] : qq{\\};
-       my $pat = gen_delimited_pat($del, $esc);
-       my $startpos = pos $$textref || 0;
-       return _fail($wantarray, $textref, "Not a delimited pattern", 0)
-               unless $$textref =~ m/\G($pre)($pat)/gc;
-       my $prelen = length($1);
-       my $matchpos = $startpos+$prelen;
-       my $endpos = pos $$textref;
-       return _succeed $wantarray, $textref,
-                       $matchpos, $endpos-$matchpos,           # MATCH
-                       $endpos,   length($$textref)-$endpos,   # REMAINDER
-                       $startpos, $prelen;                     # PREFIX
+    my $textref = defined $_[0] ? \$_[0] : \$_;
+    my $wantarray = wantarray;
+    my $del  = defined $_[1] ? $_[1] : qq{\'\"\`};
+    my $pre  = defined $_[2] ? $_[2] : '\s*';
+    my $esc  = defined $_[3] ? $_[3] : qq{\\};
+    my $pat = gen_delimited_pat($del, $esc);
+    my $startpos = pos $$textref || 0;
+    return _fail($wantarray, $textref, "Not a delimited pattern", 0)
+        unless $$textref =~ m/\G($pre)($pat)/gc;
+    my $prelen = length($1);
+    my $matchpos = $startpos+$prelen;
+    my $endpos = pos $$textref;
+    return _succeed $wantarray, $textref,
+                    $matchpos, $endpos-$matchpos,               # MATCH
+                    $endpos,   length($$textref)-$endpos,       # REMAINDER
+                    $startpos, $prelen;                         # PREFIX
 }
 
 sub extract_bracketed (;$$$)
 {
-       my $textref = defined $_[0] ? \$_[0] : \$_;
-       my $ldel = defined $_[1] ? $_[1] : '{([<';
-       my $pre  = defined $_[2] ? $_[2] : '\s*';
-       my $wantarray = wantarray;
-       my $qdel = "";
-       my $quotelike;
-       $ldel =~ s/'//g and $qdel .= q{'};
-       $ldel =~ s/"//g and $qdel .= q{"};
-       $ldel =~ s/`//g and $qdel .= q{`};
-       $ldel =~ s/q//g and $quotelike = 1;
-       $ldel =~ tr/[](){}<>\0-\377/[[(({{<</ds;
-       my $rdel = $ldel;
-       unless ($rdel =~ tr/[({</])}>/)
-        {
-               return _fail $wantarray, $textref,
-                            "Did not find a suitable bracket in delimiter: \"$_[1]\"",
-                            0;
-       }
-       my $posbug = pos;
-       $ldel = join('|', map { quotemeta $_ } split('', $ldel));
-       $rdel = join('|', map { quotemeta $_ } split('', $rdel));
-       pos = $posbug;
-
-       my $startpos = pos $$textref || 0;
-       my @match = _match_bracketed($textref,$pre, $ldel, $qdel, $quotelike, $rdel);
-
-       return _fail ($wantarray, $textref) unless @match;
-
-       return _succeed ( $wantarray, $textref,
-                         $match[2], $match[5]+2,       # MATCH
-                         @match[8,9],                  # REMAINDER
-                         @match[0,1],                  # PREFIX
-                       );
+    my $textref = defined $_[0] ? \$_[0] : \$_;
+    my $ldel = defined $_[1] ? $_[1] : '{([<';
+    my $pre  = defined $_[2] ? $_[2] : '\s*';
+    my $wantarray = wantarray;
+    my $qdel = "";
+    my $quotelike;
+    $ldel =~ s/'//g and $qdel .= q{'};
+    $ldel =~ s/"//g and $qdel .= q{"};
+    $ldel =~ s/`//g and $qdel .= q{`};
+    $ldel =~ s/q//g and $quotelike = 1;
+    $ldel =~ tr/[](){}<>\0-\377/[[(({{<</ds;
+    my $rdel = $ldel;
+    unless ($rdel =~ tr/[({</])}>/)
+    {
+        return _fail $wantarray, $textref,
+                     "Did not find a suitable bracket in delimiter: \"$_[1]\"",
+                     0;
+    }
+    my $posbug = pos;
+    $ldel = join('|', map { quotemeta $_ } split('', $ldel));
+    $rdel = join('|', map { quotemeta $_ } split('', $rdel));
+    pos = $posbug;
+
+    my $startpos = pos $$textref || 0;
+    my @match = _match_bracketed($textref,$pre, $ldel, $qdel, $quotelike, $rdel);
+
+    return _fail ($wantarray, $textref) unless @match;
+
+    return _succeed ( $wantarray, $textref,
+                      $match[2], $match[5]+2,           # MATCH
+                      @match[8,9],                      # REMAINDER
+                      @match[0,1],                      # PREFIX
+                    );
 }
 
-sub _match_bracketed($$$$$$)   # $textref, $pre, $ldel, $qdel, $quotelike, $rdel
+sub _match_bracketed($$$$$$)    # $textref, $pre, $ldel, $qdel, $quotelike, $rdel
 {
-       my ($textref, $pre, $ldel, $qdel, $quotelike, $rdel) = @_;
-       my ($startpos, $ldelpos, $endpos) = (pos $$textref = pos $$textref||0);
-       unless ($$textref =~ m/\G$pre/gc)
-       {
-               _failmsg "Did not find prefix: /$pre/", $startpos;
-               return;
-       }
-
-       $ldelpos = pos $$textref;
-
-       unless ($$textref =~ m/\G($ldel)/gc)
-       {
-               _failmsg "Did not find opening bracket after prefix: \"$pre\"",
-                        pos $$textref;
-               pos $$textref = $startpos;
-               return;
-       }
-
-       my @nesting = ( $1 );
-       my $textlen = length $$textref;
-       while (pos $$textref < $textlen)
-       {
-               next if $$textref =~ m/\G\\./gcs;
-
-               if ($$textref =~ m/\G($ldel)/gc)
-               {
-                       push @nesting, $1;
-               }
-               elsif ($$textref =~ m/\G($rdel)/gc)
-               {
-                       my ($found, $brackettype) = ($1, $1);
-                       if ($#nesting < 0)
-                       {
-                               _failmsg "Unmatched closing bracket: \"$found\"",
-                                        pos $$textref;
-                               pos $$textref = $startpos;
-                               return;
-                       }
-                       my $expected = pop(@nesting);
-                       $expected =~ tr/({[</)}]>/;
-                       if ($expected ne $brackettype)
-                       {
-                               _failmsg qq{Mismatched closing bracket: expected "$expected" but found "$found"},
-                                        pos $$textref;
-                               pos $$textref = $startpos;
-                               return;
-                       }
-                       last if $#nesting < 0;
-               }
-               elsif ($qdel && $$textref =~ m/\G([$qdel])/gc)
-               {
-                       $$textref =~ m/\G[^\\$1]*(?:\\.[^\\$1]*)*(\Q$1\E)/gsc and next;
-                       _failmsg "Unmatched embedded quote ($1)",
-                                pos $$textref;
-                       pos $$textref = $startpos;
-                       return;
-               }
-               elsif ($quotelike && _match_quotelike($textref,"",1,0))
-               {
-                       next;
-               }
-
-               else { $$textref =~ m/\G(?:[a-zA-Z0-9]+|.)/gcs }
-       }
-       if ($#nesting>=0)
-       {
-               _failmsg "Unmatched opening bracket(s): "
-                               . join("..",@nesting)."..",
-                        pos $$textref;
-               pos $$textref = $startpos;
-               return;
-       }
-
-       $endpos = pos $$textref;
-       
-       return (
-               $startpos,  $ldelpos-$startpos,         # PREFIX
-               $ldelpos,   1,                          # OPENING BRACKET
-               $ldelpos+1, $endpos-$ldelpos-2,         # CONTENTS
-               $endpos-1,  1,                          # CLOSING BRACKET
-               $endpos,    length($$textref)-$endpos,  # REMAINDER
-              );
+    my ($textref, $pre, $ldel, $qdel, $quotelike, $rdel) = @_;
+    my ($startpos, $ldelpos, $endpos) = (pos $$textref = pos $$textref||0);
+    unless ($$textref =~ m/\G$pre/gc)
+    {
+        _failmsg "Did not find prefix: /$pre/", $startpos;
+        return;
+    }
+
+    $ldelpos = pos $$textref;
+
+    unless ($$textref =~ m/\G($ldel)/gc)
+    {
+        _failmsg "Did not find opening bracket after prefix: \"$pre\"",
+                 pos $$textref;
+        pos $$textref = $startpos;
+        return;
+    }
+
+    my @nesting = ( $1 );
+    my $textlen = length $$textref;
+    while (pos $$textref < $textlen)
+    {
+        next if $$textref =~ m/\G\\./gcs;
+
+        if ($$textref =~ m/\G($ldel)/gc)
+        {
+            push @nesting, $1;
+        }
+        elsif ($$textref =~ m/\G($rdel)/gc)
+        {
+            my ($found, $brackettype) = ($1, $1);
+            if ($#nesting < 0)
+            {
+                _failmsg "Unmatched closing bracket: \"$found\"",
+                         pos $$textref;
+                pos $$textref = $startpos;
+                return;
+            }
+            my $expected = pop(@nesting);
+            $expected =~ tr/({[</)}]>/;
+            if ($expected ne $brackettype)
+            {
+                _failmsg qq{Mismatched closing bracket: expected "$expected" but found "$found"},
+                         pos $$textref;
+                pos $$textref = $startpos;
+                return;
+            }
+            last if $#nesting < 0;
+        }
+        elsif ($qdel && $$textref =~ m/\G([$qdel])/gc)
+        {
+            $$textref =~ m/\G[^\\$1]*(?:\\.[^\\$1]*)*(\Q$1\E)/gsc and next;
+            _failmsg "Unmatched embedded quote ($1)",
+                     pos $$textref;
+            pos $$textref = $startpos;
+            return;
+        }
+        elsif ($quotelike && _match_quotelike($textref,"",1,0))
+        {
+            next;
+        }
+
+        else { $$textref =~ m/\G(?:[a-zA-Z0-9]+|.)/gcs }
+    }
+    if ($#nesting>=0)
+    {
+        _failmsg "Unmatched opening bracket(s): "
+                     . join("..",@nesting)."..",
+                 pos $$textref;
+        pos $$textref = $startpos;
+        return;
+    }
+
+    $endpos = pos $$textref;
+
+    return (
+        $startpos,  $ldelpos-$startpos,         # PREFIX
+        $ldelpos,   1,                          # OPENING BRACKET
+        $ldelpos+1, $endpos-$ldelpos-2,         # CONTENTS
+        $endpos-1,  1,                          # CLOSING BRACKET
+        $endpos,    length($$textref)-$endpos,  # REMAINDER
+    );
 }
 
 sub _revbracket($)
 {
-       my $brack = reverse $_[0];
-       $brack =~ tr/[({</])}>/;
-       return $brack;
+    my $brack = reverse $_[0];
+    $brack =~ tr/[({</])}>/;
+    return $brack;
 }
 
 my $XMLNAME = q{[a-zA-Z_:][a-zA-Z0-9_:.-]*};
 
 sub extract_tagged (;$$$$$) # ($text, $opentag, $closetag, $pre, \%options)
 {
-       my $textref = defined $_[0] ? \$_[0] : \$_;
-       my $ldel    = $_[1];
-       my $rdel    = $_[2];
-       my $pre     = defined $_[3] ? $_[3] : '\s*';
-       my %options = defined $_[4] ? %{$_[4]} : ();
-       my $omode   = defined $options{fail} ? $options{fail} : '';
-       my $bad     = ref($options{reject}) eq 'ARRAY' ? join('|', @{$options{reject}})
-                   : defined($options{reject})        ? $options{reject}
-                   :                                    ''
-                   ;
-       my $ignore  = ref($options{ignore}) eq 'ARRAY' ? join('|', @{$options{ignore}})
-                   : defined($options{ignore})        ? $options{ignore}
-                   :                                    ''
-                   ;
-
-       if (!defined $ldel) { $ldel = '<\w+(?:' . gen_delimited_pat(q{'"}) . '|[^>])*>'; }
-       $@ = undef;
-
-       my @match = _match_tagged($textref, $pre, $ldel, $rdel, $omode, $bad, $ignore);
-
-       return _fail(wantarray, $textref) unless @match;
-       return _succeed wantarray, $textref,
-                       $match[2], $match[3]+$match[5]+$match[7],       # MATCH
-                       @match[8..9,0..1,2..7];                         # REM, PRE, BITS
+    my $textref = defined $_[0] ? \$_[0] : \$_;
+    my $ldel    = $_[1];
+    my $rdel    = $_[2];
+    my $pre     = defined $_[3] ? $_[3] : '\s*';
+    my %options = defined $_[4] ? %{$_[4]} : ();
+    my $omode   = defined $options{fail} ? $options{fail} : '';
+    my $bad     = ref($options{reject}) eq 'ARRAY' ? join('|', @{$options{reject}})
+                : defined($options{reject})        ? $options{reject}
+                :                                    ''
+                ;
+    my $ignore  = ref($options{ignore}) eq 'ARRAY' ? join('|', @{$options{ignore}})
+                : defined($options{ignore})        ? $options{ignore}
+                :                                    ''
+                ;
+
+    if (!defined $ldel) { $ldel = '<\w+(?:' . gen_delimited_pat(q{'"}) . '|[^>])*>'; }
+    $@ = undef;
+
+    my @match = _match_tagged($textref, $pre, $ldel, $rdel, $omode, $bad, $ignore);
+
+    return _fail(wantarray, $textref) unless @match;
+    return _succeed wantarray, $textref,
+            $match[2], $match[3]+$match[5]+$match[7],    # MATCH
+            @match[8..9,0..1,2..7];                      # REM, PRE, BITS
 }
 
-sub _match_tagged      # ($$$$$$$)
+sub _match_tagged       # ($$$$$$$)
 {
-       my ($textref, $pre, $ldel, $rdel, $omode, $bad, $ignore) = @_;
-       my $rdelspec;
-
-       my ($startpos, $opentagpos, $textpos, $parapos, $closetagpos, $endpos) = ( pos($$textref) = pos($$textref)||0 );
-
-       unless ($$textref =~ m/\G($pre)/gc)
-       {
-               _failmsg "Did not find prefix: /$pre/", pos $$textref;
-               goto failed;
-       }
-
-       $opentagpos = pos($$textref);
-
-       unless ($$textref =~ m/\G$ldel/gc)
-       {
-               _failmsg "Did not find opening tag: /$ldel/", pos $$textref;
-               goto failed;
-       }
-
-       $textpos = pos($$textref);
-
-       if (!defined $rdel)
-       {
-               $rdelspec = substr($$textref, $-[0], $+[0] - $-[0]);
-               unless ($rdelspec =~ s/\A([[(<{]+)($XMLNAME).*/ quotemeta "$1\/$2". _revbracket($1) /oes)
-               {
-                       _failmsg "Unable to construct closing tag to match: $rdel",
-                                pos $$textref;
-                       goto failed;
-               }
-       }
-       else
-       {
-               $rdelspec = eval "qq{$rdel}" || do {
-                       my $del;
-                       for (qw,~ ! ^ & * ) _ + - = } ] : " ; ' > . ? / | ',)
-                               { next if $rdel =~ /\Q$_/; $del = $_; last }
-                       unless ($del) {
-                               use Carp;
-                               croak "Can't interpolate right delimiter $rdel"
-                       }
-                       eval "qq$del$rdel$del";
-               };
-       }
-
-       while (pos($$textref) < length($$textref))
-       {
-               next if $$textref =~ m/\G\\./gc;
-
-               if ($$textref =~ m/\G(\n[ \t]*\n)/gc )
-               {
-                       $parapos = pos($$textref) - length($1)
-                               unless defined $parapos;
-               }
-               elsif ($$textref =~ m/\G($rdelspec)/gc )
-               {
-                       $closetagpos = pos($$textref)-length($1);
-                       goto matched;
-               }
-               elsif ($ignore && $$textref =~ m/\G(?:$ignore)/gc)
-               {
-                       next;
-               }
-               elsif ($bad && $$textref =~ m/\G($bad)/gcs)
-               {
-                       pos($$textref) -= length($1);   # CUT OFF WHATEVER CAUSED THE SHORTNESS
-                       goto short if ($omode eq 'PARA' || $omode eq 'MAX');
-                       _failmsg "Found invalid nested tag: $1", pos $$textref;
-                       goto failed;
-               }
-               elsif ($$textref =~ m/\G($ldel)/gc)
-               {
-                       my $tag = $1;
-                       pos($$textref) -= length($tag); # REWIND TO NESTED TAG
-                       unless (_match_tagged(@_))      # MATCH NESTED TAG
-                       {
-                               goto short if $omode eq 'PARA' || $omode eq 'MAX';
-                               _failmsg "Found unbalanced nested tag: $tag",
-                                        pos $$textref;
-                               goto failed;
-                       }
-               }
-               else { $$textref =~ m/./gcs }
-       }
+    my ($textref, $pre, $ldel, $rdel, $omode, $bad, $ignore) = @_;
+    my $rdelspec;
+
+    my ($startpos, $opentagpos, $textpos, $parapos, $closetagpos, $endpos) = ( pos($$textref) = pos($$textref)||0 );
+
+    unless ($$textref =~ m/\G($pre)/gc)
+    {
+        _failmsg "Did not find prefix: /$pre/", pos $$textref;
+        goto failed;
+    }
+
+    $opentagpos = pos($$textref);
+
+    unless ($$textref =~ m/\G$ldel/gc)
+    {
+        _failmsg "Did not find opening tag: /$ldel/", pos $$textref;
+        goto failed;
+    }
+
+    $textpos = pos($$textref);
+
+    if (!defined $rdel)
+    {
+        $rdelspec = substr($$textref, $-[0], $+[0] - $-[0]);
+        unless ($rdelspec =~ s/\A([[(<{]+)($XMLNAME).*/ quotemeta "$1\/$2". _revbracket($1) /oes)
+        {
+            _failmsg "Unable to construct closing tag to match: $rdel",
+                     pos $$textref;
+            goto failed;
+        }
+    }
+    else
+    {
+        ## no critic (BuiltinFunctions::ProhibitStringyEval)
+        $rdelspec = eval "qq{$rdel}" || do {
+            my $del;
+            for (qw,~ ! ^ & * ) _ + - = } ] : " ; ' > . ? / | ',)
+                { next if $rdel =~ /\Q$_/; $del = $_; last }
+            unless ($del) {
+                use Carp;
+                croak "Can't interpolate right delimiter $rdel"
+            }
+            eval "qq$del$rdel$del";
+        };
+    }
+
+    while (pos($$textref) < length($$textref))
+    {
+        next if $$textref =~ m/\G\\./gc;
+
+        if ($$textref =~ m/\G(\n[ \t]*\n)/gc )
+        {
+            $parapos = pos($$textref) - length($1)
+                unless defined $parapos;
+        }
+        elsif ($$textref =~ m/\G($rdelspec)/gc )
+        {
+            $closetagpos = pos($$textref)-length($1);
+            goto matched;
+        }
+        elsif ($ignore && $$textref =~ m/\G(?:$ignore)/gc)
+        {
+            next;
+        }
+        elsif ($bad && $$textref =~ m/\G($bad)/gcs)
+        {
+            pos($$textref) -= length($1);       # CUT OFF WHATEVER CAUSED THE SHORTNESS
+            goto short if ($omode eq 'PARA' || $omode eq 'MAX');
+            _failmsg "Found invalid nested tag: $1", pos $$textref;
+            goto failed;
+        }
+        elsif ($$textref =~ m/\G($ldel)/gc)
+        {
+            my $tag = $1;
+            pos($$textref) -= length($tag);     # REWIND TO NESTED TAG
+            unless (_match_tagged(@_))  # MATCH NESTED TAG
+            {
+                goto short if $omode eq 'PARA' || $omode eq 'MAX';
+                _failmsg "Found unbalanced nested tag: $tag",
+                         pos $$textref;
+                goto failed;
+            }
+        }
+        else { $$textref =~ m/./gcs }
+    }
 
 short:
-       $closetagpos = pos($$textref);
-       goto matched if $omode eq 'MAX';
-       goto failed unless $omode eq 'PARA';
-
-       if (defined $parapos) { pos($$textref) = $parapos }
-       else                  { $parapos = pos($$textref) }
-
-       return (
-               $startpos,    $opentagpos-$startpos,            # PREFIX
-               $opentagpos,  $textpos-$opentagpos,             # OPENING TAG
-               $textpos,     $parapos-$textpos,                # TEXT
-               $parapos,     0,                                # NO CLOSING TAG
-               $parapos,     length($$textref)-$parapos,       # REMAINDER
-              );
-       
+    $closetagpos = pos($$textref);
+    goto matched if $omode eq 'MAX';
+    goto failed unless $omode eq 'PARA';
+
+    if (defined $parapos) { pos($$textref) = $parapos }
+    else                  { $parapos = pos($$textref) }
+
+    return (
+        $startpos,    $opentagpos-$startpos,            # PREFIX
+        $opentagpos,  $textpos-$opentagpos,             # OPENING TAG
+        $textpos,     $parapos-$textpos,                # TEXT
+        $parapos,     0,                                # NO CLOSING TAG
+        $parapos,     length($$textref)-$parapos,       # REMAINDER
+    );
+
 matched:
-       $endpos = pos($$textref);
-       return (
-               $startpos,    $opentagpos-$startpos,            # PREFIX
-               $opentagpos,  $textpos-$opentagpos,             # OPENING TAG
-               $textpos,     $closetagpos-$textpos,            # TEXT
-               $closetagpos, $endpos-$closetagpos,             # CLOSING TAG
-               $endpos,      length($$textref)-$endpos,        # REMAINDER
-              );
+    $endpos = pos($$textref);
+    return (
+        $startpos,    $opentagpos-$startpos,            # PREFIX
+        $opentagpos,  $textpos-$opentagpos,             # OPENING TAG
+        $textpos,     $closetagpos-$textpos,            # TEXT
+        $closetagpos, $endpos-$closetagpos,             # CLOSING TAG
+        $endpos,      length($$textref)-$endpos,        # REMAINDER
+    );
 
 failed:
-       _failmsg "Did not find closing tag", pos $$textref unless $@;
-       pos($$textref) = $startpos;
-       return;
+    _failmsg "Did not find closing tag", pos $$textref unless $@;
+    pos($$textref) = $startpos;
+    return;
 }
 
 sub extract_variable (;$$)
 {
-       my $textref = defined $_[0] ? \$_[0] : \$_;
-       return ("","","") unless defined $$textref;
-       my $pre  = defined $_[1] ? $_[1] : '\s*';
+    my $textref = defined $_[0] ? \$_[0] : \$_;
+    return ("","","") unless defined $$textref;
+    my $pre  = defined $_[1] ? $_[1] : '\s*';
 
-       my @match = _match_variable($textref,$pre);
+    my @match = _match_variable($textref,$pre);
 
-       return _fail wantarray, $textref unless @match;
+    return _fail wantarray, $textref unless @match;
 
-       return _succeed wantarray, $textref,
-                       @match[2..3,4..5,0..1];         # MATCH, REMAINDER, PREFIX
+    return _succeed wantarray, $textref,
+                    @match[2..3,4..5,0..1];        # MATCH, REMAINDER, PREFIX
 }
 
 sub _match_variable($$)
@@ -438,582 +448,581 @@ sub _match_variable($$)
 #  $#
 #  $^
 #  $$
-       my ($textref, $pre) = @_;
-       my $startpos = pos($$textref) = pos($$textref)||0;
-       unless ($$textref =~ m/\G($pre)/gc)
-       {
-               _failmsg "Did not find prefix: /$pre/", pos $$textref;
-               return;
-       }
-       my $varpos = pos($$textref);
-        unless ($$textref =~ m{\G\$\s*(?!::)(\d+|[][&`'+*./|,";%=~:?!\@<>()-]|\^[a-z]?)}gci)
-       {
-           unless ($$textref =~ m/\G((\$#?|[*\@\%]|\\&)+)/gc)
-           {
-               _failmsg "Did not find leading dereferencer", pos $$textref;
-               pos $$textref = $startpos;
-               return;
-           }
-           my $deref = $1;
-
-           unless ($$textref =~ m/\G\s*(?:::|')?(?:[_a-z]\w*(?:::|'))*[_a-z]\w*/gci
-               or _match_codeblock($textref, "", '\{', '\}', '\{', '\}', 0)
-               or $deref eq '$#' or $deref eq '$$' )
-           {
-               _failmsg "Bad identifier after dereferencer", pos $$textref;
-               pos $$textref = $startpos;
-               return;
-           }
-       }
-
-       while (1)
-       {
-               next if $$textref =~ m/\G\s*(?:->)?\s*[{]\w+[}]/gc;
-               next if _match_codeblock($textref,
-                                        qr/\s*->\s*(?:[_a-zA-Z]\w+\s*)?/,
-                                        qr/[({[]/, qr/[)}\]]/,
-                                        qr/[({[]/, qr/[)}\]]/, 0);
-               next if _match_codeblock($textref,
-                                        qr/\s*/, qr/[{[]/, qr/[}\]]/,
-                                        qr/[{[]/, qr/[}\]]/, 0);
-               next if _match_variable($textref,'\s*->\s*');
-               next if $$textref =~ m/\G\s*->\s*\w+(?![{([])/gc;
-               last;
-       }
-       
-       my $endpos = pos($$textref);
-       return ($startpos, $varpos-$startpos,
-               $varpos,   $endpos-$varpos,
-               $endpos,   length($$textref)-$endpos
-               );
+    my ($textref, $pre) = @_;
+    my $startpos = pos($$textref) = pos($$textref)||0;
+    unless ($$textref =~ m/\G($pre)/gc)
+    {
+        _failmsg "Did not find prefix: /$pre/", pos $$textref;
+        return;
+    }
+    my $varpos = pos($$textref);
+    unless ($$textref =~ m{\G\$\s*(?!::)(\d+|[][&`'+*./|,";%=~:?!\@<>()-]|\^[a-z]?)}gci)
+    {
+        unless ($$textref =~ m/\G((\$#?|[*\@\%]|\\&)+)/gc)
+        {
+            _failmsg "Did not find leading dereferencer", pos $$textref;
+            pos $$textref = $startpos;
+            return;
+        }
+        my $deref = $1;
+
+        unless ($$textref =~ m/\G\s*(?:::|')?(?:[_a-z]\w*(?:::|'))*[_a-z]\w*/gci
+            or _match_codeblock($textref, "", '\{', '\}', '\{', '\}', 0)
+            or $deref eq '$#' or $deref eq '$$' )
+        {
+            _failmsg "Bad identifier after dereferencer", pos $$textref;
+            pos $$textref = $startpos;
+            return;
+        }
+    }
+
+    while (1)
+    {
+        next if $$textref =~ m/\G\s*(?:->)?\s*[{]\w+[}]/gc;
+        next if _match_codeblock($textref,
+                                 qr/\s*->\s*(?:[_a-zA-Z]\w+\s*)?/,
+                                 qr/[({[]/, qr/[)}\]]/,
+                                 qr/[({[]/, qr/[)}\]]/, 0);
+        next if _match_codeblock($textref,
+                                 qr/\s*/, qr/[{[]/, qr/[}\]]/,
+                                 qr/[{[]/, qr/[}\]]/, 0);
+        next if _match_variable($textref,'\s*->\s*');
+        next if $$textref =~ m/\G\s*->\s*\w+(?![{([])/gc;
+        last;
+    }
+
+    my $endpos = pos($$textref);
+    return ($startpos, $varpos-$startpos,
+            $varpos,   $endpos-$varpos,
+            $endpos,   length($$textref)-$endpos
+    );
 }
 
 sub extract_codeblock (;$$$$$)
 {
-       my $textref = defined $_[0] ? \$_[0] : \$_;
-       my $wantarray = wantarray;
-       my $ldel_inner = defined $_[1] ? $_[1] : '{';
-       my $pre        = defined $_[2] ? $_[2] : '\s*';
-       my $ldel_outer = defined $_[3] ? $_[3] : $ldel_inner;
-       my $rd         = $_[4];
-       my $rdel_inner = $ldel_inner;
-       my $rdel_outer = $ldel_outer;
-       my $posbug = pos;
-       for ($ldel_inner, $ldel_outer) { tr/[]()<>{}\0-\377/[[((<<{{/ds }
-       for ($rdel_inner, $rdel_outer) { tr/[]()<>{}\0-\377/]]))>>}}/ds }
-       for ($ldel_inner, $ldel_outer, $rdel_inner, $rdel_outer)
-       {
-               $_ = '('.join('|',map { quotemeta $_ } split('',$_)).')'
-       }
-       pos = $posbug;
-
-       my @match = _match_codeblock($textref, $pre,
-                                    $ldel_outer, $rdel_outer,
-                                    $ldel_inner, $rdel_inner,
-                                    $rd);
-       return _fail($wantarray, $textref) unless @match;
-       return _succeed($wantarray, $textref,
-                       @match[2..3,4..5,0..1]  # MATCH, REMAINDER, PREFIX
-                      );
+    my $textref = defined $_[0] ? \$_[0] : \$_;
+    my $wantarray = wantarray;
+    my $ldel_inner = defined $_[1] ? $_[1] : '{';
+    my $pre        = defined $_[2] ? $_[2] : '\s*';
+    my $ldel_outer = defined $_[3] ? $_[3] : $ldel_inner;
+    my $rd         = $_[4];
+    my $rdel_inner = $ldel_inner;
+    my $rdel_outer = $ldel_outer;
+    my $posbug = pos;
+    for ($ldel_inner, $ldel_outer) { tr/[]()<>{}\0-\377/[[((<<{{/ds }
+    for ($rdel_inner, $rdel_outer) { tr/[]()<>{}\0-\377/]]))>>}}/ds }
+    for ($ldel_inner, $ldel_outer, $rdel_inner, $rdel_outer)
+    {
+        $_ = '('.join('|',map { quotemeta $_ } split('',$_)).')'
+    }
+    pos = $posbug;
+
+    my @match = _match_codeblock($textref, $pre,
+                                 $ldel_outer, $rdel_outer,
+                                 $ldel_inner, $rdel_inner,
+                                 $rd);
+    return _fail($wantarray, $textref) unless @match;
+    return _succeed($wantarray, $textref,
+                    @match[2..3,4..5,0..1]    # MATCH, REMAINDER, PREFIX
+    );
 
 }
 
 sub _match_codeblock($$$$$$$)
 {
-       my ($textref, $pre, $ldel_outer, $rdel_outer, $ldel_inner, $rdel_inner, $rd) = @_;
-       my $startpos = pos($$textref) = pos($$textref) || 0;
-       unless ($$textref =~ m/\G($pre)/gc)
-       {
-               _failmsg qq{Did not match prefix /$pre/ at"} .
-                           substr($$textref,pos($$textref),20) .
-                           q{..."},
-                        pos $$textref;
-               return; 
-       }
-       my $codepos = pos($$textref);
-       unless ($$textref =~ m/\G($ldel_outer)/gc)      # OUTERMOST DELIMITER
-       {
-               _failmsg qq{Did not find expected opening bracket at "} .
-                            substr($$textref,pos($$textref),20) .
-                            q{..."},
-                        pos $$textref;
-               pos $$textref = $startpos;
-               return;
-       }
-       my $closing = $1;
-          $closing =~ tr/([<{/)]>}/;
-       my $matched;
-       my $patvalid = 1;
-       while (pos($$textref) < length($$textref))
-       {
-               $matched = '';
-               if ($rd && $$textref =~ m#\G(\Q(?)\E|\Q(s?)\E|\Q(s)\E)#gc)
-               {
-                       $patvalid = 0;
-                       next;
-               }
-
-               if ($$textref =~ m/\G\s*#.*/gc)
-               {
-                       next;
-               }
-
-               if ($$textref =~ m/\G\s*($rdel_outer)/gc)
-               {
-                       unless ($matched = ($closing && $1 eq $closing) )
-                       {
-                               next if $1 eq '>';      # MIGHT BE A "LESS THAN"
-                               _failmsg q{Mismatched closing bracket at "} .
-                                            substr($$textref,pos($$textref),20) .
-                                            qq{...". Expected '$closing'},
-                                        pos $$textref;
-                       }
-                       last;
-               }
-
-               if (_match_variable($textref,'\s*') ||
-                   _match_quotelike($textref,'\s*',$patvalid,$patvalid) )
-               {
-                       $patvalid = 0;
-                       next;
-               }
-
-
-               # NEED TO COVER MANY MORE CASES HERE!!!
-               if ($$textref =~ m#\G\s*(?!$ldel_inner)
-                                       ( [-+*x/%^&|.]=?
-                                       | [!=]~
-                                       | =(?!>)
-                                       | (\*\*|&&|\|\||<<|>>)=?
-                                       | split|grep|map|return
-                                       | [([]
-                                       )#gcx)
-               {
-                       $patvalid = 1;
-                       next;
-               }
-
-               if ( _match_codeblock($textref, '\s*', $ldel_inner, $rdel_inner, $ldel_inner, $rdel_inner, $rd) )
-               {
-                       $patvalid = 1;
-                       next;
-               }
-
-               if ($$textref =~ m/\G\s*$ldel_outer/gc)
-               {
-                       _failmsg q{Improperly nested codeblock at "} .
-                                    substr($$textref,pos($$textref),20) .
-                                    q{..."},
-                                pos $$textref;
-                       last;
-               }
-
-               $patvalid = 0;
-               $$textref =~ m/\G\s*(\w+|[-=>]>|.|\Z)/gc;
-       }
-       continue { $@ = undef }
-
-       unless ($matched)
-       {
-               _failmsg 'No match found for opening bracket', pos $$textref
-                       unless $@;
-               return;
-       }
-
-       my $endpos = pos($$textref);
-       return ( $startpos, $codepos-$startpos,
-                $codepos, $endpos-$codepos,
-                $endpos,  length($$textref)-$endpos,
-              );
+    my ($textref, $pre, $ldel_outer, $rdel_outer, $ldel_inner, $rdel_inner, $rd) = @_;
+    my $startpos = pos($$textref) = pos($$textref) || 0;
+    unless ($$textref =~ m/\G($pre)/gc)
+    {
+        _failmsg qq{Did not match prefix /$pre/ at"} .
+                     substr($$textref,pos($$textref),20) .
+                     q{..."},
+                 pos $$textref;
+        return;
+    }
+    my $codepos = pos($$textref);
+    unless ($$textref =~ m/\G($ldel_outer)/gc)  # OUTERMOST DELIMITER
+    {
+        _failmsg qq{Did not find expected opening bracket at "} .
+                     substr($$textref,pos($$textref),20) .
+                     q{..."},
+                 pos $$textref;
+        pos $$textref = $startpos;
+        return;
+    }
+    my $closing = $1;
+       $closing =~ tr/([<{/)]>}/;
+    my $matched;
+    my $patvalid = 1;
+    while (pos($$textref) < length($$textref))
+    {
+        $matched = '';
+        if ($rd && $$textref =~ m#\G(\Q(?)\E|\Q(s?)\E|\Q(s)\E)#gc)
+        {
+            $patvalid = 0;
+            next;
+        }
+
+        if ($$textref =~ m/\G\s*#.*/gc)
+        {
+            next;
+        }
+
+        if ($$textref =~ m/\G\s*($rdel_outer)/gc)
+        {
+            unless ($matched = ($closing && $1 eq $closing) )
+            {
+                next if $1 eq '>';      # MIGHT BE A "LESS THAN"
+                _failmsg q{Mismatched closing bracket at "} .
+                             substr($$textref,pos($$textref),20) .
+                             qq{...". Expected '$closing'},
+                         pos $$textref;
+            }
+            last;
+        }
+
+        if (_match_variable($textref,'\s*') ||
+            _match_quotelike($textref,'\s*',$patvalid,$patvalid) )
+        {
+            $patvalid = 0;
+            next;
+        }
+
+
+        # NEED TO COVER MANY MORE CASES HERE!!!
+        if ($$textref =~ m#\G\s*(?!$ldel_inner)
+                                ( [-+*x/%^&|.]=?
+                                | [!=]~
+                                | =(?!>)
+                                | (\*\*|&&|\|\||<<|>>)=?
+                                | split|grep|map|return
+                                | [([]
+                                )#gcx)
+        {
+            $patvalid = 1;
+            next;
+        }
+
+        if ( _match_codeblock($textref, '\s*', $ldel_inner, $rdel_inner, $ldel_inner, $rdel_inner, $rd) )
+        {
+            $patvalid = 1;
+            next;
+        }
+
+        if ($$textref =~ m/\G\s*$ldel_outer/gc)
+        {
+            _failmsg q{Improperly nested codeblock at "} .
+                         substr($$textref,pos($$textref),20) .
+                         q{..."},
+                     pos $$textref;
+            last;
+        }
+
+        $patvalid = 0;
+        $$textref =~ m/\G\s*(\w+|[-=>]>|.|\Z)/gc;
+    }
+    continue { $@ = undef }
+
+    unless ($matched)
+    {
+        _failmsg 'No match found for opening bracket', pos $$textref
+                unless $@;
+        return;
+    }
+
+    my $endpos = pos($$textref);
+    return ( $startpos, $codepos-$startpos,
+             $codepos, $endpos-$codepos,
+             $endpos,  length($$textref)-$endpos,
+    );
 }
 
 
 my %mods   = (
-               'none'  => '[cgimsox]*',
-               'm'     => '[cgimsox]*',
-               's'     => '[cegimsox]*',
-               'tr'    => '[cds]*',
-               'y'     => '[cds]*',
-               'qq'    => '',
-               'qx'    => '',
-               'qw'    => '',
-               'qr'    => '[imsx]*',
-               'q'     => '',
-            );
+    'none' => '[cgimsox]*',
+    'm'    => '[cgimsox]*',
+    's'    => '[cegimsox]*',
+    'tr'   => '[cds]*',
+    'y'    => '[cds]*',
+    'qq'   => '',
+    'qx'   => '',
+    'qw'   => '',
+    'qr'   => '[imsx]*',
+    'q'    => '',
+);
 
 sub extract_quotelike (;$$)
 {
-       my $textref = $_[0] ? \$_[0] : \$_;
-       my $wantarray = wantarray;
-       my $pre  = defined $_[1] ? $_[1] : '\s*';
-
-       my @match = _match_quotelike($textref,$pre,1,0);
-       return _fail($wantarray, $textref) unless @match;
-       return _succeed($wantarray, $textref,
-                       $match[2], $match[18]-$match[2],        # MATCH
-                       @match[18,19],                          # REMAINDER
-                       @match[0,1],                            # PREFIX
-                       @match[2..17],                          # THE BITS
-                       @match[20,21],                          # ANY FILLET?
-                      );
+    my $textref = $_[0] ? \$_[0] : \$_;
+    my $wantarray = wantarray;
+    my $pre  = defined $_[1] ? $_[1] : '\s*';
+
+    my @match = _match_quotelike($textref,$pre,1,0);
+    return _fail($wantarray, $textref) unless @match;
+    return _succeed($wantarray, $textref,
+                    $match[2], $match[18]-$match[2],    # MATCH
+                    @match[18,19],                      # REMAINDER
+                    @match[0,1],                        # PREFIX
+                    @match[2..17],                      # THE BITS
+                    @match[20,21],                      # ANY FILLET?
+    );
 };
 
-sub _match_quotelike($$$$)     # ($textref, $prepat, $allow_raw_match)
+sub _match_quotelike($$$$)      # ($textref, $prepat, $allow_raw_match)
 {
-       my ($textref, $pre, $rawmatch, $qmark) = @_;
-
-       my ($textlen,$startpos,
-           $oppos,
-           $preld1pos,$ld1pos,$str1pos,$rd1pos,
-           $preld2pos,$ld2pos,$str2pos,$rd2pos,
-           $modpos) = ( length($$textref), pos($$textref) = pos($$textref) || 0 );
-
-       unless ($$textref =~ m/\G($pre)/gc)
-       {
-               _failmsg qq{Did not find prefix /$pre/ at "} .
-                            substr($$textref, pos($$textref), 20) .
-                            q{..."},
-                        pos $$textref;
-               return; 
-       }
-       $oppos = pos($$textref);
-
-       my $initial = substr($$textref,$oppos,1);
-
-       if ($initial && $initial =~ m|^[\"\'\`]|
-                    || $rawmatch && $initial =~ m|^/|
-                    || $qmark && $initial =~ m|^\?|)
-       {
-               unless ($$textref =~ m/ \Q$initial\E [^\\$initial]* (\\.[^\\$initial]*)* \Q$initial\E /gcsx)
-               {
-                       _failmsg qq{Did not find closing delimiter to match '$initial' at "} .
-                                    substr($$textref, $oppos, 20) .
-                                    q{..."},
-                                pos $$textref;
-                       pos $$textref = $startpos;
-                       return;
-               }
-               $modpos= pos($$textref);
-               $rd1pos = $modpos-1;
-
-               if ($initial eq '/' || $initial eq '?') 
-               {
-                       $$textref =~ m/\G$mods{none}/gc
-               }
-
-               my $endpos = pos($$textref);
-               return (
-                       $startpos,      $oppos-$startpos,       # PREFIX
-                       $oppos,         0,                      # NO OPERATOR
-                       $oppos,         1,                      # LEFT DEL
-                       $oppos+1,       $rd1pos-$oppos-1,       # STR/PAT
-                       $rd1pos,        1,                      # RIGHT DEL
-                       $modpos,        0,                      # NO 2ND LDEL
-                       $modpos,        0,                      # NO 2ND STR
-                       $modpos,        0,                      # NO 2ND RDEL
-                       $modpos,        $endpos-$modpos,        # MODIFIERS
-                       $endpos,        $textlen-$endpos,       # REMAINDER
-                      );
-       }
-
-       unless ($$textref =~ m{\G(\b(?:m|s|qq|qx|qw|q|qr|tr|y)\b(?=\s*\S)|<<)}gc)
-       {
-               _failmsg q{No quotelike operator found after prefix at "} .
-                            substr($$textref, pos($$textref), 20) .
-                            q{..."},
-                        pos $$textref;
-               pos $$textref = $startpos;
-               return;
-       }
-
-       my $op = $1;
-       $preld1pos = pos($$textref);
-       if ($op eq '<<') {
-               $ld1pos = pos($$textref);
-               my $label;
-               if ($$textref =~ m{\G([A-Za-z_]\w*)}gc) {
-                       $label = $1;
-               }
-               elsif ($$textref =~ m{ \G ' ([^'\\]* (?:\\.[^'\\]*)*) '
-                                    | \G " ([^"\\]* (?:\\.[^"\\]*)*) "
-                                    | \G ` ([^`\\]* (?:\\.[^`\\]*)*) `
-                                    }gcsx) {
-                       $label = $+;
-               }
-               else {
-                       $label = "";
-               }
-               my $extrapos = pos($$textref);
-               $$textref =~ m{.*\n}gc;
-               $str1pos = pos($$textref)--;
-               unless ($$textref =~ m{.*?\n(?=\Q$label\E\n)}gc) {
-                       _failmsg qq{Missing here doc terminator ('$label') after "} .
-                                    substr($$textref, $startpos, 20) .
-                                    q{..."},
-                                pos $$textref;
-                       pos $$textref = $startpos;
-                       return;
-               }
-               $rd1pos = pos($$textref);
+    my ($textref, $pre, $rawmatch, $qmark) = @_;
+
+    my ($textlen,$startpos,
+        $oppos,
+        $preld1pos,$ld1pos,$str1pos,$rd1pos,
+        $preld2pos,$ld2pos,$str2pos,$rd2pos,
+        $modpos) = ( length($$textref), pos($$textref) = pos($$textref) || 0 );
+
+    unless ($$textref =~ m/\G($pre)/gc)
+    {
+        _failmsg qq{Did not find prefix /$pre/ at "} .
+                     substr($$textref, pos($$textref), 20) .
+                     q{..."},
+                 pos $$textref;
+        return;
+    }
+    $oppos = pos($$textref);
+
+    my $initial = substr($$textref,$oppos,1);
+
+    if ($initial && $initial =~ m|^[\"\'\`]|
+                 || $rawmatch && $initial =~ m|^/|
+                 || $qmark && $initial =~ m|^\?|)
+    {
+        unless ($$textref =~ m/ \Q$initial\E [^\\$initial]* (\\.[^\\$initial]*)* \Q$initial\E /gcsx)
+        {
+            _failmsg qq{Did not find closing delimiter to match '$initial' at "} .
+                         substr($$textref, $oppos, 20) .
+                         q{..."},
+                     pos $$textref;
+            pos $$textref = $startpos;
+            return;
+        }
+        $modpos= pos($$textref);
+        $rd1pos = $modpos-1;
+
+        if ($initial eq '/' || $initial eq '?')
+        {
+            $$textref =~ m/\G$mods{none}/gc
+        }
+
+        my $endpos = pos($$textref);
+        return (
+            $startpos,  $oppos-$startpos,       # PREFIX
+            $oppos,     0,                      # NO OPERATOR
+            $oppos,     1,                      # LEFT DEL
+            $oppos+1,   $rd1pos-$oppos-1,       # STR/PAT
+            $rd1pos,    1,                      # RIGHT DEL
+            $modpos,    0,                      # NO 2ND LDEL
+            $modpos,    0,                      # NO 2ND STR
+            $modpos,    0,                      # NO 2ND RDEL
+            $modpos,    $endpos-$modpos,        # MODIFIERS
+            $endpos,    $textlen-$endpos,       # REMAINDER
+        );
+    }
+
+    unless ($$textref =~ m{\G(\b(?:m|s|qq|qx|qw|q|qr|tr|y)\b(?=\s*\S)|<<)}gc)
+    {
+        _failmsg q{No quotelike operator found after prefix at "} .
+                     substr($$textref, pos($$textref), 20) .
+                     q{..."},
+                 pos $$textref;
+        pos $$textref = $startpos;
+        return;
+    }
+
+    my $op = $1;
+    $preld1pos = pos($$textref);
+    if ($op eq '<<') {
+        $ld1pos = pos($$textref);
+        my $label;
+        if ($$textref =~ m{\G([A-Za-z_]\w*)}gc) {
+            $label = $1;
+        }
+        elsif ($$textref =~ m{ \G ' ([^'\\]* (?:\\.[^'\\]*)*) '
+                             | \G " ([^"\\]* (?:\\.[^"\\]*)*) "
+                             | \G ` ([^`\\]* (?:\\.[^`\\]*)*) `
+                             }gcsx) {
+            $label = $+;
+        }
+        else {
+            $label = "";
+        }
+        my $extrapos = pos($$textref);
+        $$textref =~ m{.*\n}gc;
+        $str1pos = pos($$textref)--;
+        unless ($$textref =~ m{.*?\n(?=\Q$label\E\n)}gc) {
+            _failmsg qq{Missing here doc terminator ('$label') after "} .
+                         substr($$textref, $startpos, 20) .
+                         q{..."},
+                     pos $$textref;
+            pos $$textref = $startpos;
+            return;
+        }
+        $rd1pos = pos($$textref);
         $$textref =~ m{\Q$label\E\n}gc;
-               $ld2pos = pos($$textref);
-               return (
-                       $startpos,      $oppos-$startpos,       # PREFIX
-                       $oppos,         length($op),            # OPERATOR
-                       $ld1pos,        $extrapos-$ld1pos,      # LEFT DEL
-                       $str1pos,       $rd1pos-$str1pos,       # STR/PAT
-                       $rd1pos,        $ld2pos-$rd1pos,        # RIGHT DEL
-                       $ld2pos,        0,                      # NO 2ND LDEL
-                       $ld2pos,        0,                      # NO 2ND STR
-                       $ld2pos,        0,                      # NO 2ND RDEL
-                       $ld2pos,        0,                      # NO MODIFIERS
-                       $ld2pos,        $textlen-$ld2pos,       # REMAINDER
-                       $extrapos,      $str1pos-$extrapos,     # FILLETED BIT
-                      );
-       }
-
-       $$textref =~ m/\G\s*/gc;
-       $ld1pos = pos($$textref);
-       $str1pos = $ld1pos+1;
-
-       unless ($$textref =~ m/\G(\S)/gc)       # SHOULD USE LOOKAHEAD
-       {
-               _failmsg "No block delimiter found after quotelike $op",
-                        pos $$textref;
-               pos $$textref = $startpos;
-               return;
-       }
-       pos($$textref) = $ld1pos;       # HAVE TO DO THIS BECAUSE LOOKAHEAD BROKEN
-       my ($ldel1, $rdel1) = ("\Q$1","\Q$1");
-       if ($ldel1 =~ /[[(<{]/)
-       {
-               $rdel1 =~ tr/[({</])}>/;
-               defined(_match_bracketed($textref,"",$ldel1,"","",$rdel1))
-               || do { pos $$textref = $startpos; return };
+        $ld2pos = pos($$textref);
+        return (
+            $startpos,  $oppos-$startpos,       # PREFIX
+            $oppos,     length($op),            # OPERATOR
+            $ld1pos,    $extrapos-$ld1pos,      # LEFT DEL
+            $str1pos,   $rd1pos-$str1pos,       # STR/PAT
+            $rd1pos,    $ld2pos-$rd1pos,        # RIGHT DEL
+            $ld2pos,    0,                      # NO 2ND LDEL
+            $ld2pos,    0,                      # NO 2ND STR
+            $ld2pos,    0,                      # NO 2ND RDEL
+            $ld2pos,    0,                      # NO MODIFIERS
+            $ld2pos,    $textlen-$ld2pos,       # REMAINDER
+            $extrapos,  $str1pos-$extrapos,     # FILLETED BIT
+        );
+    }
+
+    $$textref =~ m/\G\s*/gc;
+    $ld1pos = pos($$textref);
+    $str1pos = $ld1pos+1;
+
+    unless ($$textref =~ m/\G(\S)/gc)   # SHOULD USE LOOKAHEAD
+    {
+        _failmsg "No block delimiter found after quotelike $op",
+                 pos $$textref;
+        pos $$textref = $startpos;
+        return;
+    }
+    pos($$textref) = $ld1pos;   # HAVE TO DO THIS BECAUSE LOOKAHEAD BROKEN
+    my ($ldel1, $rdel1) = ("\Q$1","\Q$1");
+    if ($ldel1 =~ /[[(<{]/)
+    {
+        $rdel1 =~ tr/[({</])}>/;
+        defined(_match_bracketed($textref,"",$ldel1,"","",$rdel1))
+            || do { pos $$textref = $startpos; return };
         $ld2pos = pos($$textref);
         $rd1pos = $ld2pos-1;
-       }
-       else
-       {
-               $$textref =~ /\G$ldel1[^\\$ldel1]*(\\.[^\\$ldel1]*)*$ldel1/gcs
-               || do { pos $$textref = $startpos; return };
+    }
+    else
+    {
+        $$textref =~ /\G$ldel1[^\\$ldel1]*(\\.[^\\$ldel1]*)*$ldel1/gcs
+            || do { pos $$textref = $startpos; return };
         $ld2pos = $rd1pos = pos($$textref)-1;
-       }
-
-       my $second_arg = $op =~ /s|tr|y/ ? 1 : 0;
-       if ($second_arg)
-       {
-               my ($ldel2, $rdel2);
-               if ($ldel1 =~ /[[(<{]/)
-               {
-                       unless ($$textref =~ /\G\s*(\S)/gc)     # SHOULD USE LOOKAHEAD
-                       {
-                               _failmsg "Missing second block for quotelike $op",
-                                        pos $$textref;
-                               pos $$textref = $startpos;
-                               return;
-                       }
-                       $ldel2 = $rdel2 = "\Q$1";
-                       $rdel2 =~ tr/[({</])}>/;
-               }
-               else
-               {
-                       $ldel2 = $rdel2 = $ldel1;
-               }
-               $str2pos = $ld2pos+1;
-
-               if ($ldel2 =~ /[[(<{]/)
-               {
-                       pos($$textref)--;       # OVERCOME BROKEN LOOKAHEAD 
-                       defined(_match_bracketed($textref,"",$ldel2,"","",$rdel2))
-                       || do { pos $$textref = $startpos; return };
-               }
-               else
-               {
-                       $$textref =~ /[^\\$ldel2]*(\\.[^\\$ldel2]*)*$ldel2/gcs
-                       || do { pos $$textref = $startpos; return };
-               }
-               $rd2pos = pos($$textref)-1;
-       }
-       else
-       {
-               $ld2pos = $str2pos = $rd2pos = $rd1pos;
-       }
-
-       $modpos = pos $$textref;
-
-       $$textref =~ m/\G($mods{$op})/gc;
-       my $endpos = pos $$textref;
-
-       return (
-               $startpos,      $oppos-$startpos,       # PREFIX
-               $oppos,         length($op),            # OPERATOR
-               $ld1pos,        1,                      # LEFT DEL
-               $str1pos,       $rd1pos-$str1pos,       # STR/PAT
-               $rd1pos,        1,                      # RIGHT DEL
-               $ld2pos,        $second_arg,            # 2ND LDEL (MAYBE)
-               $str2pos,       $rd2pos-$str2pos,       # 2ND STR (MAYBE)
-               $rd2pos,        $second_arg,            # 2ND RDEL (MAYBE)
-               $modpos,        $endpos-$modpos,        # MODIFIERS
-               $endpos,        $textlen-$endpos,       # REMAINDER
-              );
+    }
+
+    my $second_arg = $op =~ /s|tr|y/ ? 1 : 0;
+    if ($second_arg)
+    {
+        my ($ldel2, $rdel2);
+        if ($ldel1 =~ /[[(<{]/)
+        {
+            unless ($$textref =~ /\G\s*(\S)/gc) # SHOULD USE LOOKAHEAD
+            {
+                _failmsg "Missing second block for quotelike $op",
+                         pos $$textref;
+                pos $$textref = $startpos;
+                return;
+            }
+            $ldel2 = $rdel2 = "\Q$1";
+            $rdel2 =~ tr/[({</])}>/;
+        }
+        else
+        {
+            $ldel2 = $rdel2 = $ldel1;
+        }
+        $str2pos = $ld2pos+1;
+
+        if ($ldel2 =~ /[[(<{]/)
+        {
+            pos($$textref)--;   # OVERCOME BROKEN LOOKAHEAD
+            defined(_match_bracketed($textref,"",$ldel2,"","",$rdel2))
+                || do { pos $$textref = $startpos; return };
+        }
+        else
+        {
+            $$textref =~ /[^\\$ldel2]*(\\.[^\\$ldel2]*)*$ldel2/gcs
+                || do { pos $$textref = $startpos; return };
+        }
+        $rd2pos = pos($$textref)-1;
+    }
+    else
+    {
+        $ld2pos = $str2pos = $rd2pos = $rd1pos;
+    }
+
+    $modpos = pos $$textref;
+
+    $$textref =~ m/\G($mods{$op})/gc;
+    my $endpos = pos $$textref;
+
+    return (
+        $startpos,      $oppos-$startpos,       # PREFIX
+        $oppos,         length($op),            # OPERATOR
+        $ld1pos,        1,                      # LEFT DEL
+        $str1pos,       $rd1pos-$str1pos,       # STR/PAT
+        $rd1pos,        1,                      # RIGHT DEL
+        $ld2pos,        $second_arg,            # 2ND LDEL (MAYBE)
+        $str2pos,       $rd2pos-$str2pos,       # 2ND STR (MAYBE)
+        $rd2pos,        $second_arg,            # 2ND RDEL (MAYBE)
+        $modpos,        $endpos-$modpos,        # MODIFIERS
+        $endpos,        $textlen-$endpos,       # REMAINDER
+    );
 }
 
 my $def_func = [
-       sub { extract_variable($_[0], '') },
-       sub { extract_quotelike($_[0],'') },
-       sub { extract_codeblock($_[0],'{}','') },
+    sub { extract_variable($_[0], '') },
+    sub { extract_quotelike($_[0],'') },
+    sub { extract_codeblock($_[0],'{}','') },
 ];
 
-sub extract_multiple (;$$$$)   # ($text, $functions_ref, $max_fields, $ignoreunknown)
+sub extract_multiple (;$$$$)    # ($text, $functions_ref, $max_fields, $ignoreunknown)
 {
-       my $textref = defined($_[0]) ? \$_[0] : \$_;
-       my $posbug = pos;
-       my ($lastpos, $firstpos);
-       my @fields = ();
-
-       #for ($$textref)
-       {
-               my @func = defined $_[1] ? @{$_[1]} : @{$def_func};
-               my $max  = defined $_[2] && $_[2]>0 ? $_[2] : 1_000_000_000;
-               my $igunk = $_[3];
-
-               pos $$textref ||= 0;
-
-               unless (wantarray)
-               {
-                       use Carp;
-                       carp "extract_multiple reset maximal count to 1 in scalar context"
-                               if $^W && defined($_[2]) && $max > 1;
-                       $max = 1
-               }
-
-               my $unkpos;
-               my $func;
-               my $class;
-
-               my @class;
-               foreach $func ( @func )
-               {
-                       if (ref($func) eq 'HASH')
-                       {
-                               push @class, (keys %$func)[0];
-                               $func = (values %$func)[0];
-                       }
-                       else
-                       {
-                               push @class, undef;
-                       }
-               }
-
-               FIELD: while (pos($$textref) < length($$textref))
-               {
-                       my ($field, $rem);
-                       my @bits;
-                       foreach my $i ( 0..$#func )
-                       {
-                               my $pref;
-                               $func = $func[$i];
-                               $class = $class[$i];
-                               $lastpos = pos $$textref;
-                               if (ref($func) eq 'CODE')
-                                       { ($field,$rem,$pref) = @bits = $func->($$textref) }
-                               elsif (ref($func) eq 'Text::Balanced::Extractor')
-                                       { @bits = $field = $func->extract($$textref) }
-                               elsif( $$textref =~ m/\G$func/gc )
-                                       { @bits = $field = defined($1)
-                                ? $1
-                                : substr($$textref, $-[0], $+[0] - $-[0])
+    my $textref = defined($_[0]) ? \$_[0] : \$_;
+    my $posbug = pos;
+    my ($lastpos, $firstpos);
+    my @fields = ();
+
+    #for ($$textref)
+    {
+        my @func = defined $_[1] ? @{$_[1]} : @{$def_func};
+        my $max  = defined $_[2] && $_[2]>0 ? $_[2] : 1_000_000_000;
+        my $igunk = $_[3];
+
+        pos $$textref ||= 0;
+
+        unless (wantarray)
+        {
+            use Carp;
+            carp "extract_multiple reset maximal count to 1 in scalar context"
+                    if $^W && defined($_[2]) && $max > 1;
+            $max = 1
+        }
+
+        my $unkpos;
+        my $class;
+
+        my @class;
+        foreach my $func ( @func )
+        {
+            if (ref($func) eq 'HASH')
+            {
+                push @class, (keys %$func)[0];
+                $func = (values %$func)[0];
+            }
+            else
+            {
+                push @class, undef;
+            }
+        }
+
+        FIELD: while (pos($$textref) < length($$textref))
+        {
+            my ($field, $rem);
+            my @bits;
+            foreach my $i ( 0..$#func )
+            {
+                my $pref;
+                my $func = $func[$i];
+                $class = $class[$i];
+                $lastpos = pos $$textref;
+                if (ref($func) eq 'CODE')
+                    { ($field,$rem,$pref) = @bits = $func->($$textref) }
+                elsif (ref($func) eq 'Text::Balanced::Extractor')
+                    { @bits = $field = $func->extract($$textref) }
+                elsif( $$textref =~ m/\G$func/gc )
+                    { @bits = $field = defined($1)
+                        ? $1
+                        : substr($$textref, $-[0], $+[0] - $-[0])
+                    }
+                $pref ||= "";
+                if (defined($field) && length($field))
+                {
+                    if (!$igunk) {
+                        $unkpos = $lastpos
+                            if length($pref) && !defined($unkpos);
+                        if (defined $unkpos)
+                        {
+                            push @fields, substr($$textref, $unkpos, $lastpos-$unkpos).$pref;
+                            $firstpos = $unkpos unless defined $firstpos;
+                            undef $unkpos;
+                            last FIELD if @fields == $max;
+                        }
                     }
-                               $pref ||= "";
-                               if (defined($field) && length($field))
-                               {
-                                       if (!$igunk) {
-                                               $unkpos = $lastpos
-                                                       if length($pref) && !defined($unkpos);
-                                               if (defined $unkpos)
-                                               {
-                                                       push @fields, substr($$textref, $unkpos, $lastpos-$unkpos).$pref;
-                                                       $firstpos = $unkpos unless defined $firstpos;
-                                                       undef $unkpos;
-                                                       last FIELD if @fields == $max;
-                                               }
-                                       }
-                                       push @fields, $class
-                                               ? bless (\$field, $class)
-                                               : $field;
-                                       $firstpos = $lastpos unless defined $firstpos;
-                                       $lastpos = pos $$textref;
-                                       last FIELD if @fields == $max;
-                                       next FIELD;
-                               }
-                       }
-                       if ($$textref =~ /\G(.)/gcs)
-                       {
-                               $unkpos = pos($$textref)-1
-                                       unless $igunk || defined $unkpos;
-                       }
-               }
-               
-               if (defined $unkpos)
-               {
-                       push @fields, substr($$textref, $unkpos);
-                       $firstpos = $unkpos unless defined $firstpos;
-                       $lastpos = length $$textref;
-               }
-               last;
-       }
-
-       pos $$textref = $lastpos;
-       return @fields if wantarray;
-
-       $firstpos ||= 0;
-       eval { substr($$textref,$firstpos,$lastpos-$firstpos)="";
-              pos $$textref = $firstpos };
-       return $fields[0];
+                    push @fields, $class
+                            ? bless (\$field, $class)
+                            : $field;
+                    $firstpos = $lastpos unless defined $firstpos;
+                    $lastpos = pos $$textref;
+                    last FIELD if @fields == $max;
+                    next FIELD;
+                }
+            }
+            if ($$textref =~ /\G(.)/gcs)
+            {
+                $unkpos = pos($$textref)-1
+                    unless $igunk || defined $unkpos;
+            }
+        }
+
+        if (defined $unkpos)
+        {
+            push @fields, substr($$textref, $unkpos);
+            $firstpos = $unkpos unless defined $firstpos;
+            $lastpos = length $$textref;
+        }
+        last;
+    }
+
+    pos $$textref = $lastpos;
+    return @fields if wantarray;
+
+    $firstpos ||= 0;
+    eval { substr($$textref,$firstpos,$lastpos-$firstpos)="";
+           pos $$textref = $firstpos };
+    return $fields[0];
 }
 
 sub gen_extract_tagged # ($opentag, $closetag, $pre, \%options)
 {
-       my $ldel    = $_[0];
-       my $rdel    = $_[1];
-       my $pre     = defined $_[2] ? $_[2] : '\s*';
-       my %options = defined $_[3] ? %{$_[3]} : ();
-       my $omode   = defined $options{fail} ? $options{fail} : '';
-       my $bad     = ref($options{reject}) eq 'ARRAY' ? join('|', @{$options{reject}})
-                   : defined($options{reject})        ? $options{reject}
-                   :                                    ''
-                   ;
-       my $ignore  = ref($options{ignore}) eq 'ARRAY' ? join('|', @{$options{ignore}})
-                   : defined($options{ignore})        ? $options{ignore}
-                   :                                    ''
-                   ;
-
-       if (!defined $ldel) { $ldel = '<\w+(?:' . gen_delimited_pat(q{'"}) . '|[^>])*>'; }
-
-       my $posbug = pos;
-       for ($ldel, $pre, $bad, $ignore) { $_ = qr/$_/ if $_ }
-       pos = $posbug;
-
-       my $closure = sub
-       {
-               my $textref = defined $_[0] ? \$_[0] : \$_;
-               my @match = Text::Balanced::_match_tagged($textref, $pre, $ldel, $rdel, $omode, $bad, $ignore);
-
-               return _fail(wantarray, $textref) unless @match;
-               return _succeed wantarray, $textref,
-                               $match[2], $match[3]+$match[5]+$match[7],       # MATCH
-                               @match[8..9,0..1,2..7];                         # REM, PRE, BITS
-       };
-
-       bless $closure, 'Text::Balanced::Extractor';
+    my $ldel    = $_[0];
+    my $rdel    = $_[1];
+    my $pre     = defined $_[2] ? $_[2] : '\s*';
+    my %options = defined $_[3] ? %{$_[3]} : ();
+    my $omode   = defined $options{fail} ? $options{fail} : '';
+    my $bad     = ref($options{reject}) eq 'ARRAY' ? join('|', @{$options{reject}})
+                : defined($options{reject})        ? $options{reject}
+                :                                    ''
+                ;
+    my $ignore  = ref($options{ignore}) eq 'ARRAY' ? join('|', @{$options{ignore}})
+                : defined($options{ignore})        ? $options{ignore}
+                :                                    ''
+                ;
+
+    if (!defined $ldel) { $ldel = '<\w+(?:' . gen_delimited_pat(q{'"}) . '|[^>])*>'; }
+
+    my $posbug = pos;
+    for ($ldel, $pre, $bad, $ignore) { $_ = qr/$_/ if $_ }
+    pos = $posbug;
+
+    my $closure = sub
+    {
+        my $textref = defined $_[0] ? \$_[0] : \$_;
+        my @match = Text::Balanced::_match_tagged($textref, $pre, $ldel, $rdel, $omode, $bad, $ignore);
+
+        return _fail(wantarray, $textref) unless @match;
+        return _succeed wantarray, $textref,
+                        $match[2], $match[3]+$match[5]+$match[7],   # MATCH
+                        @match[8..9,0..1,2..7];                     # REM, PRE, BITS
+    };
+
+    bless $closure, 'Text::Balanced::Extractor';
 }
 
 package Text::Balanced::Extractor;
 
-sub extract($$)        # ($self, $text)
+sub extract($$) # ($self, $text)
 {
-       &{$_[0]}($_[1]);
+    &{$_[0]}($_[1]);
 }
 
 package Text::Balanced::ErrorMsg;
@@ -1032,83 +1041,76 @@ Text::Balanced - Extract delimited text sequences from strings.
 
 =head1 SYNOPSIS
 
- use Text::Balanced qw (
-                       extract_delimited
-                       extract_bracketed
-                       extract_quotelike
-                       extract_codeblock
-                       extract_variable
-                       extract_tagged
-                       extract_multiple
-                       gen_delimited_pat
-                       gen_extract_tagged
-                      );
   use Text::Balanced qw (
+        extract_delimited
+        extract_bracketed
+        extract_quotelike
+        extract_codeblock
+        extract_variable
+        extract_tagged
+        extract_multiple
+        gen_delimited_pat
+        gen_extract_tagged
+    );
 
- # Extract the initial substring of $text that is delimited by
- # two (unescaped) instances of the first character in $delim.
   # Extract the initial substring of $text that is delimited by
   # two (unescaped) instances of the first character in $delim.
 
-       ($extracted, $remainder) = extract_delimited($text,$delim);
+    ($extracted, $remainder) = extract_delimited($text,$delim);
 
+    # Extract the initial substring of $text that is bracketed
+    # with a delimiter(s) specified by $delim (where the string
+    # in $delim contains one or more of '(){}[]<>').
 
- # Extract the initial substring of $text that is bracketed
- # with a delimiter(s) specified by $delim (where the string
- # in $delim contains one or more of '(){}[]<>').
+    ($extracted, $remainder) = extract_bracketed($text,$delim);
 
-       ($extracted, $remainder) = extract_bracketed($text,$delim);
+    # Extract the initial substring of $text that is bounded by
+    # an XML tag.
 
+    ($extracted, $remainder) = extract_tagged($text);
 
- # Extract the initial substring of $text that is bounded by
- # an XML tag.
   # Extract the initial substring of $text that is bounded by
+    # a C<BEGIN>...C<END> pair. Don't allow nested C<BEGIN> tags
 
-       ($extracted, $remainder) = extract_tagged($text);
+    ($extracted, $remainder) =
+        extract_tagged($text,"BEGIN","END",undef,{bad=>["BEGIN"]});
 
+    # Extract the initial substring of $text that represents a
+    # Perl "quote or quote-like operation"
 
- # Extract the initial substring of $text that is bounded by
- # a C<BEGIN>...C<END> pair. Don't allow nested C<BEGIN> tags
+    ($extracted, $remainder) = extract_quotelike($text);
 
-       ($extracted, $remainder) =
-               extract_tagged($text,"BEGIN","END",undef,{bad=>["BEGIN"]});
+    # Extract the initial substring of $text that represents a block
+    # of Perl code, bracketed by any of character(s) specified by $delim
+    # (where the string $delim contains one or more of '(){}[]<>').
 
+    ($extracted, $remainder) = extract_codeblock($text,$delim);
 
- # Extract the initial substring of $text that represents a
- # Perl "quote or quote-like operation"
+    # Extract the initial substrings of $text that would be extracted by
+    # one or more sequential applications of the specified functions
+    # or regular expressions
 
-       ($extracted, $remainder) = extract_quotelike($text);
+    @extracted = extract_multiple($text,
+                                  [ \&extract_bracketed,
+                                    \&extract_quotelike,
+                                    \&some_other_extractor_sub,
+                                    qr/[xyz]*/,
+                                    'literal',
+                                  ]);
 
+    # Create a string representing an optimized pattern (a la Friedl)
+    # that matches a substring delimited by any of the specified characters
+    # (in this case: any type of quote or a slash)
 
- # Extract the initial substring of $text that represents a block
- # of Perl code, bracketed by any of character(s) specified by $delim
- # (where the string $delim contains one or more of '(){}[]<>').
+    $patstring = gen_delimited_pat(q{'"`/});
 
-       ($extracted, $remainder) = extract_codeblock($text,$delim);
+    # Generate a reference to an anonymous sub that is just like extract_tagged
+    # but pre-compiled and optimized for a specific pair of tags, and
+    # consequently much faster (i.e. 3 times faster). It uses qr// for better
+    # performance on repeated calls.
 
-
- # Extract the initial substrings of $text that would be extracted by
- # one or more sequential applications of the specified functions
- # or regular expressions
-
-       @extracted = extract_multiple($text,
-                                     [ \&extract_bracketed,
-                                       \&extract_quotelike,
-                                       \&some_other_extractor_sub,
-                                       qr/[xyz]*/,
-                                       'literal',
-                                     ]);
-
-# Create a string representing an optimized pattern (a la Friedl)
-# that matches a substring delimited by any of the specified characters
-# (in this case: any type of quote or a slash)
-
-       $patstring = gen_delimited_pat(q{'"`/});
-
-# Generate a reference to an anonymous sub that is just like extract_tagged
-# but pre-compiled and optimized for a specific pair of tags, and consequently
-# much faster (i.e. 3 times faster). It uses qr// for better performance on
-# repeated calls, so it only works under Perl 5.005 or later.
-
-       $extract_head = gen_extract_tagged('<HEAD>','</HEAD>');
-
-       ($extracted, $remainder) = $extract_head->($text);
+    $extract_head = gen_extract_tagged('<HEAD>','</HEAD>');
+    ($extracted, $remainder) = $extract_head->($text);
 
 =head1 DESCRIPTION
 
@@ -1128,7 +1130,7 @@ they extract an occurrence of the substring appearing
 immediately at the current matching position in the
 string (like a C<\G>-anchored regex would).
 
-=head2 General behaviour in list contexts
+=head2 General Behaviour in List Contexts
 
 In a list context, all the subroutines return a list, the first three
 elements of which are always:
@@ -1150,31 +1152,31 @@ extracted string). On failure, the entire string is returned.
 The skipped prefix (i.e. the characters before the extracted string).
 On failure, C<undef> is returned.
 
-=back 
+=back
 
 Note that in a list context, the contents of the original input text (the first
-argument) are not modified in any way. 
+argument) are not modified in any way.
 
 However, if the input text was passed in a variable, that variable's
 C<pos> value is updated to point at the first character after the
 extracted text. That means that in a list context the various
 subroutines can be used much like regular expressions. For example:
 
-       while ( $next = (extract_quotelike($text))[0] )
-       {
-               # process next quote-like (in $next)
-       }
+    while ( $next = (extract_quotelike($text))[0] )
+    {
+        # process next quote-like (in $next)
+    }
 
-=head2 General behaviour in scalar and void contexts
+=head2 General Behaviour in Scalar and Void Contexts
 
 In a scalar context, the extracted string is returned, having first been
 removed from the input text. Thus, the following code also processes
 each quote-like operation, but actually removes them from $text:
 
-       while ( $next = extract_quotelike($text) )
-       {
-               # process next quote-like (in $next)
-       }
+    while ( $next = extract_quotelike($text) )
+    {
+        # process next quote-like (in $next)
+    }
 
 Note that if the input text is a read-only string (i.e. a literal),
 no attempt is made to remove the extracted text.
@@ -1183,7 +1185,7 @@ In a void context the behaviour of the extraction subroutines is
 exactly the same as in a scalar context, except (of course) that the
 extracted substring is not returned.
 
-=head2 A note about prefixes
+=head2 A Note About Prefixes
 
 Prefix patterns are matched without any trailing modifiers (C</gimsox> etc.)
 This can bite you if you're expecting a prefix specification like
@@ -1194,19 +1196,23 @@ pattern will only succeed if the <H1> tag is on the current line, since
 To overcome this limitation, you need to turn on /s matching within
 the prefix pattern, using the C<(?s)> directive: '(?s).*?(?=<H1>)'
 
-=head2 C<extract_delimited>
+=head2 Functions
+
+=over 4
+
+=item C<extract_delimited>
 
 The C<extract_delimited> function formalizes the common idiom
 of extracting a single-character-delimited substring from the start of
 a string. For example, to extract a single-quote delimited string, the
 following code is typically used:
 
-       ($remainder = $text) =~ s/\A('(\\.|[^'])*')//s;
-       $extracted = $1;
+    ($remainder = $text) =~ s/\A('(\\.|[^'])*')//s;
+    $extracted = $1;
 
 but with C<extract_delimited> it can be simplified to:
 
-       ($extracted,$remainder) = extract_delimited($text, "'");
+    ($extracted,$remainder) = extract_delimited($text, "'");
 
 C<extract_delimited> takes up to four scalars (the input text, the
 delimiters, a prefix pattern to be skipped, and any escape characters)
@@ -1240,42 +1246,42 @@ removed from the beginning of the first argument.
 
 Examples:
 
-       # Remove a single-quoted substring from the very beginning of $text:
+    # Remove a single-quoted substring from the very beginning of $text:
 
-               $substring = extract_delimited($text, "'", '');
+        $substring = extract_delimited($text, "'", '');
 
-       # Remove a single-quoted Pascalish substring (i.e. one in which
-       # doubling the quote character escapes it) from the very
-       # beginning of $text:
+    # Remove a single-quoted Pascalish substring (i.e. one in which
+    # doubling the quote character escapes it) from the very
+    # beginning of $text:
 
-               $substring = extract_delimited($text, "'", '', "'");
+        $substring = extract_delimited($text, "'", '', "'");
 
-       # Extract a single- or double- quoted substring from the
-       # beginning of $text, optionally after some whitespace
-       # (note the list context to protect $text from modification):
+    # Extract a single- or double- quoted substring from the
+    # beginning of $text, optionally after some whitespace
+    # (note the list context to protect $text from modification):
 
-               ($substring) = extract_delimited $text, q{"'};
+        ($substring) = extract_delimited $text, q{"'};
 
-       # Delete the substring delimited by the first '/' in $text:
+    # Delete the substring delimited by the first '/' in $text:
 
-               $text = join '', (extract_delimited($text,'/','[^/]*')[2,1];
+        $text = join '', (extract_delimited($text,'/','[^/]*')[2,1];
 
 Note that this last example is I<not> the same as deleting the first
 quote-like pattern. For instance, if C<$text> contained the string:
 
-       "if ('./cmd' =~ m/$UNIXCMD/s) { $cmd = $1; }"
-       
+    "if ('./cmd' =~ m/$UNIXCMD/s) { $cmd = $1; }"
+
 then after the deletion it would contain:
 
-       "if ('.$UNIXCMD/s) { $cmd = $1; }"
+    "if ('.$UNIXCMD/s) { $cmd = $1; }"
 
 not:
 
-       "if ('./cmd' =~ ms) { $cmd = $1; }"
-       
+    "if ('./cmd' =~ ms) { $cmd = $1; }"
+
 See L<"extract_quotelike"> for a (partial) solution to this problem.
 
-=head2 C<extract_bracketed>
+=item C<extract_bracketed>
 
 Like C<"extract_delimited">, the C<extract_bracketed> function takes
 up to three optional scalar arguments: a string to extract from, a delimiter
@@ -1307,15 +1313,15 @@ balanced and correctly nested within the substring, and any other kind of
 
 For example, given the string:
 
-       $text = "{ an '[irregularly :-(] {} parenthesized >:-)' string }";
+    $text = "{ an '[irregularly :-(] {} parenthesized >:-)' string }";
 
 then a call to C<extract_bracketed> in a list context:
 
-       @result = extract_bracketed( $text, '{}' );
+    @result = extract_bracketed( $text, '{}' );
 
 would return:
 
-       ( "{ an '[irregularly :-(] {} parenthesized >:-)' string }" , "" , "" )
+    ( "{ an '[irregularly :-(] {} parenthesized >:-)' string }" , "" , "" )
 
 since both sets of C<'{..}'> brackets are properly nested and evenly balanced.
 (In a scalar context just the first element of the array would be returned. In
@@ -1323,18 +1329,18 @@ a void context, C<$text> would be replaced by an empty string.)
 
 Likewise the call in:
 
-       @result = extract_bracketed( $text, '{[' );
+    @result = extract_bracketed( $text, '{[' );
 
 would return the same result, since all sets of both types of specified
 delimiter brackets are correctly nested and balanced.
 
 However, the call in:
 
-       @result = extract_bracketed( $text, '{([<' );
+    @result = extract_bracketed( $text, '{([<' );
 
 would fail, returning:
 
-       ( undef , "{ an '[irregularly :-(] {} parenthesized >:-)' string }"  );
+    ( undef , "{ an '[irregularly :-(] {} parenthesized >:-)' string }"  );
 
 because the embedded pairs of C<'(..)'>s and C<'[..]'>s are "cross-nested" and
 the embedded C<'E<gt>'> is unbalanced. (In a scalar context, this call would
@@ -1348,37 +1354,37 @@ However, if a particular species of quote character is included in the
 delimiter specification, then that type of quote will be correctly handled.
 for example, if C<$text> is:
 
-       $text = '<A HREF=">>>>">link</A>';
+    $text = '<A HREF=">>>>">link</A>';
 
 then
 
-       @result = extract_bracketed( $text, '<">' );
+    @result = extract_bracketed( $text, '<">' );
 
 returns:
 
-       ( '<A HREF=">>>>">', 'link</A>', "" )
+    ( '<A HREF=">>>>">', 'link</A>', "" )
 
 as expected. Without the specification of C<"> as an embedded quoter:
 
-       @result = extract_bracketed( $text, '<>' );
+    @result = extract_bracketed( $text, '<>' );
 
 the result would be:
 
-       ( '<A HREF=">', '>>>">link</A>', "" )
+    ( '<A HREF=">', '>>>">link</A>', "" )
 
 In addition to the quote delimiters C<'>, C<">, and C<`>, full Perl quote-like
 quoting (i.e. q{string}, qq{string}, etc) can be specified by including the
 letter 'q' as a delimiter. Hence:
 
-       @result = extract_bracketed( $text, '<q>' );
+    @result = extract_bracketed( $text, '<q>' );
 
 would correctly match something like this:
 
-       $text = '<leftop: conj /and/ conj>';
+    $text = '<leftop: conj /and/ conj>';
 
 See also: C<"extract_quotelike"> and C<"extract_codeblock">.
 
-=head2 C<extract_variable>
+=item C<extract_variable>
 
 C<extract_variable> extracts any valid Perl variable or
 variable-involved expression, including scalars, arrays, hashes, array
@@ -1429,11 +1435,10 @@ failure. In addition, the original input text has the returned substring
 In a void context, the input text just has the matched substring (and
 any specified prefix) removed.
 
-
-=head2 C<extract_tagged>
+=item C<extract_tagged>
 
 C<extract_tagged> extracts and segments text between (balanced)
-specified tags. 
+specified tags.
 
 The subroutine takes up to five optional arguments:
 
@@ -1451,12 +1456,12 @@ that matches any standard XML tag is used.
 
 =item 3.
 
-A string specifying a pattern to be matched at the closing tag. 
+A string specifying a pattern to be matched at the closing tag.
 If the pattern string is omitted (or C<undef>) then the closing
 tag is constructed by inserting a C</> after any leading bracket
 characters in the actual opening tag that was matched (I<not> the pattern
 that matched the tag). For example, if the opening tag pattern
-is specified as C<'{{\w+}}'> and actually matched the opening tag 
+is specified as C<'{{\w+}}'> and actually matched the opening tag
 C<"{{DATA}}">, then the constructed closing tag would be C<"{{/DATA}}">.
 
 =item 4.
@@ -1487,7 +1492,7 @@ an HTML link (which should not contain nested links) use:
 =item C<ignore =E<gt> $listref>
 
 The list reference contains one or more strings specifying patterns
-that are I<not> be be treated as nested tags within the tagged text
+that are I<not> to be treated as nested tags within the tagged text
 (even if they would match the start tag pattern).
 
 For example, to extract an arbitrary XML tag, but ignore "empty" elements:
@@ -1508,7 +1513,7 @@ C<extract_tagged> returns the complete text up to the point of failure.
 If the string is "PARA", C<extract_tagged> returns only the first paragraph
 after the tag (up to the first line that is either empty or contains
 only whitespace characters).
-If the string is "", the the default behaviour (i.e. failure) is reinstated.
+If the string is "", the default behaviour (i.e. failure) is reinstated.
 
 For example, suppose the start tag "/para" introduces a paragraph, which then
 continues until the next "/endpara" tag or until another "/para" tag is
@@ -1575,9 +1580,7 @@ text has the returned substring (and any prefix) removed from it.
 In a void context, the input text just has the matched substring (and
 any specified prefix) removed.
 
-=head2 C<gen_extract_tagged>
-
-(Note: This subroutine is only available under Perl5.005)
+=item C<gen_extract_tagged>
 
 C<gen_extract_tagged> generates a new anonymous subroutine which
 extracts text between (balanced) specified tags. In other words,
@@ -1589,7 +1592,7 @@ C<gen_extract_tagged>, is that those generated subroutines:
 
 =over 4
 
-=item * 
+=item *
 
 do not have to reparse tag specification or parsing options every time
 they are called (whereas C<extract_tagged> has to effectively rebuild
@@ -1598,7 +1601,7 @@ its tag parser on every call);
 =item *
 
 make use of the new qr// construct to pre-compile the regexes they use
-(whereas C<extract_tagged> uses standard string variable interpolation 
+(whereas C<extract_tagged> uses standard string variable interpolation
 to create tag-matching patterns).
 
 =back
@@ -1618,16 +1621,14 @@ equivalent to:
                 return $extractor->($text);
         }
 
-(although C<extract_tagged> is not currently implemented that way, in order
-to preserve pre-5.005 compatibility).
+(although C<extract_tagged> is not currently implemented that way).
 
-Using C<gen_extract_tagged> to create extraction functions for specific tags 
+Using C<gen_extract_tagged> to create extraction functions for specific tags
 is a good idea if those functions are going to be called more than once, since
 their performance is typically twice as good as the more general-purpose
 C<extract_tagged>.
 
-
-=head2 C<extract_quotelike>
+=item C<extract_quotelike>
 
 C<extract_quotelike> attempts to recognize, extract, and segment any
 one of the various Perl quotes and quotelike operators (see
@@ -1636,7 +1637,7 @@ delimiters (for the quotelike operators), and trailing modifiers are
 all caught. For example, in:
 
         extract_quotelike 'q # an octothorpe: \# (not the end of the q!) #'
-        
+
         extract_quotelike '  "You said, \"Use sed\"."  '
 
         extract_quotelike ' s{([A-Z]{1,8}\.[A-Z]{3})} /\L$1\E/; '
@@ -1664,7 +1665,7 @@ will be extracted as if it were:
 This behaviour is identical to that of the actual compiler.
 
 C<extract_quotelike> takes two arguments: the text to be processed and
-a prefix to be matched at the very beginning of the text. If no prefix 
+a prefix to be matched at the very beginning of the text. If no prefix
 is specified, optional whitespace is the default. If no text is given,
 C<$_> is used.
 
@@ -1710,7 +1711,7 @@ the left delimiter of the second block of the operation
 
 =item [8]
 
-the text of the second block of the operation 
+the text of the second block of the operation
 (that is, the replacement of a substitution or the translation list
 of a translation),
 
@@ -1757,7 +1758,7 @@ Examples:
                         print "$op is not a pattern matching operation\n";
                 }
 
-=head2 C<extract_quotelike> and "here documents"
+=item C<extract_quotelike>
 
 C<extract_quotelike> can successfully extract "here documents" from an input
 string, but with an important caveat in list contexts.
@@ -1842,7 +1843,7 @@ you can pass the input variable as an interpolated literal:
 
         $quotelike = extract_quotelike("$var");
 
-=head2 C<extract_codeblock>
+=item C<extract_codeblock>
 
 C<extract_codeblock> attempts to recognize and extract a balanced
 bracket delimited substring that may contain unbalanced brackets
@@ -1861,7 +1862,7 @@ Omitting the third argument (prefix argument) implies optional whitespace at the
 Omitting the fourth argument (outermost delimiter brackets) indicates that the
 value of the second argument is to be used for the outermost delimiters.
 
-Once the prefix an dthe outermost opening delimiter bracket have been
+Once the prefix anthe outermost opening delimiter bracket have been
 recognized, code blocks are extracted by stepping through the input text and
 trying the following alternatives in sequence:
 
@@ -1933,9 +1934,9 @@ S<C<extract_codeblock($text, '{}', undef, 'E<lt>E<gt>')>>
 the '>' character is only treated as a delimited at the outermost
 level of the code block, so the directive is parsed correctly.
 
-=head2 C<extract_multiple>
+=item C<extract_multiple>
 
-The C<extract_multiple> subroutine takes a string to be processed and a 
+The C<extract_multiple> subroutine takes a string to be processed and a
 list of extractors (subroutines or regular expressions) to apply to that string.
 
 In an array context C<extract_multiple> returns an array of substrings
@@ -1947,7 +1948,7 @@ extracted substring removed from it. In all contexts
 C<extract_multiple> starts at the current C<pos> of the string, and
 sets that C<pos> appropriately after it matches.
 
-Hence, the aim of of a call to C<extract_multiple> in a list context
+Hence, the aim of a call to C<extract_multiple> in a list context
 is to split the processed string into as many non-overlapping fields as
 possible, by repeatedly applying each of the specified extractors
 to the remainder of the string. Thus C<extract_multiple> is
@@ -1982,11 +1983,11 @@ An number specifying the maximum number of fields to return. If this
 argument is omitted (or C<undef>), split continues as long as possible.
 
 If the third argument is I<N>, then extraction continues until I<N> fields
-have been successfully extracted, or until the string has been completely 
+have been successfully extracted, or until the string has been completely
 processed.
 
-Note that in scalar and void contexts the value of this argument is 
-automatically reset to 1 (under C<-w>, a warning is issued if the argument 
+Note that in scalar and void contexts the value of this argument is
+automatically reset to 1 (under C<-w>, a warning is issued if the argument
 has to be reset).
 
 =item 4.
@@ -2026,7 +2027,7 @@ return value of the extractor will be blessed.
 If an extractor returns a defined value, that value is immediately
 treated as the next extracted field and pushed onto the list of fields.
 If the extractor was specified in a hash reference, the field is also
-blessed into the appropriate class, 
+blessed into the appropriate class,
 
 If the extractor fails to match (in the case of a regex extractor), or returns an empty list or an undefined value (in the case of a subroutine extractor), it is
 assumed to have failed to extract.
@@ -2080,7 +2081,7 @@ If you wanted the commas preserved as separate fields (i.e. like split
 does if your split pattern has capturing parentheses), you would
 just make the last parameter undefined (or remove it).
 
-=head2 C<gen_delimited_pat>
+=item C<gen_delimited_pat>
 
 The C<gen_delimited_pat> subroutine takes a single (string) argument and
    > builds a Friedl-style optimized regex that matches a string delimited
@@ -2119,11 +2120,12 @@ If more delimiters than escape chars are specified, the last escape char
 is used for the remaining delimiters.
 If no escape char is specified for a given specified delimiter, '\' is used.
 
-=head2 C<delimited_pat>
+=item C<delimited_pat>
 
 Note that C<gen_delimited_pat> was previously called C<delimited_pat>.
 That name may still be used, but is now deprecated.
-        
+
+=back
 
 =head1 DIAGNOSTICS
 
@@ -2170,7 +2172,7 @@ a closing bracket where none was expected.
 
 =item  C<Unmatched opening bracket(s): "%s">
 
-C<extract_bracketed>, C<extract_quotelike> or C<extract_codeblock> ran 
+C<extract_bracketed>, C<extract_quotelike> or C<extract_codeblock> ran
 out of characters in the text before closing one or more levels of nested
 brackets.
 
@@ -2257,25 +2259,125 @@ to match the original opening tag (and the failure mode was not
 
 =back
 
-=head1 AUTHOR
+=head1 EXPORTS
 
-Damian Conway (damian@conway.org)
+The following symbols are, or can be, exported by this module:
 
-=head1 BUGS AND IRRITATIONS
+=over 4
+
+=item Default Exports
+
+I<None>.
+
+=item Optional Exports
+
+C<extract_delimited>,
+C<extract_bracketed>,
+C<extract_quotelike>,
+C<extract_codeblock>,
+C<extract_variable>,
+C<extract_tagged>,
+C<extract_multiple>,
+C<gen_delimited_pat>,
+C<gen_extract_tagged>,
+C<delimited_pat>.
+
+=item Export Tags
+
+=over 4
+
+=item C<:ALL>
+
+C<extract_delimited>,
+C<extract_bracketed>,
+C<extract_quotelike>,
+C<extract_codeblock>,
+C<extract_variable>,
+C<extract_tagged>,
+C<extract_multiple>,
+C<gen_delimited_pat>,
+C<gen_extract_tagged>,
+C<delimited_pat>.
+
+=back
+
+=back
+
+=head1 KNOWN BUGS
+
+See L<https://rt.cpan.org/Dist/Display.html?Status=Active&Queue=Text-Balanced>.
+
+=head1 FEEDBACK
+
+Patches, bug reports, suggestions or any other feedback is welcome.
+
+Patches can be sent as GitHub pull requests at
+L<https://github.com/steve-m-hay/Text-Balanced/pulls>.
+
+Bug reports and suggestions can be made on the CPAN Request Tracker at
+L<https://rt.cpan.org/Public/Bug/Report.html?Queue=Text-Balanced>.
+
+Currently active requests on the CPAN Request Tracker can be viewed at
+L<https://rt.cpan.org/Public/Dist/Display.html?Status=Active;Queue=Text-Balanced>.
 
-There are undoubtedly serious bugs lurking somewhere in this code, if
-only because parts of it give the impression of understanding a great deal
-more about Perl than they really do. 
+Please test this distribution.  See CPAN Testers Reports at
+L<https://www.cpantesters.org/> for details of how to get involved.
 
-Bug reports and other feedback are most welcome.
+Previous test results on CPAN Testers Reports can be viewed at
+L<https://www.cpantesters.org/distro/T/Text-Balanced.html>.
+
+Please rate this distribution on CPAN Ratings at
+L<https://cpanratings.perl.org/rate/?distribution=Text-Balanced>.
+
+=head1 AVAILABILITY
+
+The latest version of this module is available from CPAN (see
+L<perlmodlib/"CPAN"> for details) at
+
+L<https://metacpan.org/release/Text-Balanced> or
+
+L<https://www.cpan.org/authors/id/S/SH/SHAY/> or
+
+L<https://www.cpan.org/modules/by-module/Text/>.
+
+The latest source code is available from GitHub at
+L<https://github.com/steve-m-hay/Text-Balanced>.
+
+=head1 INSTALLATION
+
+See the F<INSTALL> file.
+
+=head1 AUTHOR
+
+Damian Conway E<lt>L<damian@conway.org|mailto:damian@conway.org>E<gt>.
+
+Steve Hay E<lt>L<shay@cpan.org|mailto:shay@cpan.org>E<gt> is now maintaining
+Text::Balanced as of version 2.03.
 
 =head1 COPYRIGHT
 
-Copyright 1997 - 2001 Damian Conway. All Rights Reserved.
+Copyright (C) 1997-2001 Damian Conway.  All rights reserved.
+
+Copyright (C) 2009 Adam Kennedy.
+
+Copyright (C) 2015, 2020 Steve Hay.  All rights reserved.
+
+=head1 LICENCE
+
+This module is free software; you can redistribute it and/or modify it under the
+same terms as Perl itself, i.e. under the terms of either the GNU General Public
+License or the Artistic License, as specified in the F<LICENCE> file.
+
+=head1 VERSION
+
+Version 2.04
+
+=head1 DATE
+
+11 Dec 2020
 
-Some (minor) parts copyright 2009 Adam Kennedy.
+=head1 HISTORY
 
-This module is free software. It may be used, redistributed
-and/or modified under the same terms as Perl itself.
+See the F<Changes> file.
 
 =cut
index 77c1099..a6e9191 100644 (file)
@@ -1,10 +1,9 @@
 #!/usr/bin/perl
 
+use 5.008001;
+
 use strict;
-BEGIN {
-       $|  = 1;
-       $^W = 1;
-}
+use warnings;
 
 use Test::More tests => 1;
 
index a36025d..5da792f 100644 (file)
@@ -1,52 +1,60 @@
 # Before `make install' is performed this script should be runnable with
 # `make test'. After `make install' it should work as `perl test.pl'
 
+use 5.008001;
+
+use strict;
+use warnings;
+
 ######################### We start with some black magic to print on failure.
 
 # Change 1..1 below to 1..last_test_to_print .
 # (It may become useful if the test is moved to ./t subdirectory.)
 
+my $loaded = 0;
 BEGIN { $| = 1; print "1..19\n"; }
 END {print "not ok 1\n" unless $loaded;}
 use Text::Balanced qw ( extract_bracketed );
 $loaded = 1;
 print "ok 1\n";
-$count=2;
+my $count=2;
 use vars qw( $DEBUG );
 sub debug { print "\t>>>",@_ if $DEBUG }
 
 ######################### End of black magic.
 
+## no critic (BuiltinFunctions::ProhibitStringyEval)
 
-$cmd = "print";
-$neg = 0;
+my $cmd = "print";
+my $neg = 0;
+my $str;
 while (defined($str = <DATA>))
 {
-       chomp $str;
-       if ($str =~ s/\A# USING://) { $neg = 0; $cmd = $str; next; }
-       elsif ($str =~ /\A# TH[EI]SE? SHOULD FAIL/) { $neg = 1; next; }
-       elsif (!$str || $str =~ /\A#/) { $neg = 0; next }
-       $str =~ s/\\n/\n/g;
-       debug "\tUsing: $cmd\n";
-       debug "\t   on: [$str]\n";
-
-       $var = eval "() = $cmd";
-       debug "\t list got: [$var]\n";
-       debug "\t list left: [$str]\n";
-       print "not " if (substr($str,pos($str),1) eq ';')==$neg;
-       print "ok ", $count++;
-       print " ($@)" if $@ && $DEBUG;
-       print "\n";
-
-       pos $str = 0;
-       $var = eval $cmd;
-       $var = "<undef>" unless defined $var;
-       debug "\t scalar got: [$var]\n";
-       debug "\t scalar left: [$str]\n";
-       print "not " if ($str =~ '\A;')==$neg;
-       print "ok ", $count++;
-       print " ($@)" if $@ && $DEBUG;
-       print "\n";
+    chomp $str;
+    if ($str =~ s/\A# USING://) { $neg = 0; $cmd = $str; next; }
+    elsif ($str =~ /\A# TH[EI]SE? SHOULD FAIL/) { $neg = 1; next; }
+    elsif (!$str || $str =~ /\A#/) { $neg = 0; next }
+    $str =~ s/\\n/\n/g;
+    debug "\tUsing: $cmd\n";
+    debug "\t   on: [$str]\n";
+
+    my $var = eval "() = $cmd";
+    debug "\t list got: [$var]\n";
+    debug "\t list left: [$str]\n";
+    print "not " if (substr($str,pos($str),1) eq ';')==$neg;
+    print "ok ", $count++;
+    print " ($@)" if $@ && $DEBUG;
+    print "\n";
+
+    pos $str = 0;
+    $var = eval $cmd;
+    $var = "<undef>" unless defined $var;
+    debug "\t scalar got: [$var]\n";
+    debug "\t scalar left: [$str]\n";
+    print "not " if ($str =~ '\A;')==$neg;
+    print "ok ", $count++;
+    print " ($@)" if $@ && $DEBUG;
+    print "\n";
 }
 
 __DATA__
index 83081ae..398d277 100644 (file)
@@ -1,53 +1,61 @@
 # Before `make install' is performed this script should be runnable with
 # `make test'. After `make install' it should work as `perl test.pl'
 
+use 5.008001;
+
+use strict;
+use warnings;
+
 ######################### We start with some black magic to print on failure.
 
 # Change 1..1 below to 1..last_test_to_print .
 # (It may become useful if the test is moved to ./t subdirectory.)
 
+my $loaded = 0;
 BEGIN { $| = 1; print "1..41\n"; }
 END {print "not ok 1\n" unless $loaded;}
 use Text::Balanced qw ( extract_codeblock );
 $loaded = 1;
 print "ok 1\n";
-$count=2;
+my $count=2;
 use vars qw( $DEBUG );
 sub debug { print "\t>>>",@_ if $DEBUG }
 
 ######################### End of black magic.
 
+## no critic (BuiltinFunctions::ProhibitStringyEval)
 
-$cmd = "print";
-$neg = 0;
+my $cmd = "print";
+my $neg = 0;
+my $str;
 while (defined($str = <DATA>))
 {
-       chomp $str;
-       if ($str =~ s/\A# USING://) { $neg = 0; $cmd = $str; next; }
-       elsif ($str =~ /\A# TH[EI]SE? SHOULD FAIL/) { $neg = 1; next; }
-       elsif (!$str || $str =~ /\A#/) { $neg = 0; next }
-       $str =~ s/\\n/\n/g;
-       debug "\tUsing: $cmd\n";
-       debug "\t   on: [$str]\n";
-
-       my @res;
-       $var = eval "\@res = $cmd";
-       debug "\t   Failed: $@ at " . $@+0 .")" if $@;
-       debug "\t list got: [" . join("|", map {defined $_ ? $_ : '<undef>'} @res) . "]\n";
-       debug "\t list left: [$str]\n";
-       print "not " if (substr($str,pos($str)||0,1) eq ';')==$neg;
-       print "ok ", $count++;
-       print "\n";
-
-       pos $str = 0;
-       $var = eval $cmd;
-       $var = "<undef>" unless defined $var;
-       debug "\t scalar got: [$var]\n";
-       debug "\t scalar left: [$str]\n";
-       print "not " if ($str =~ '\A;')==$neg;
-       print "ok ", $count++;
-       print " ($@)" if $@ && $DEBUG;
-       print "\n";
+    chomp $str;
+    if ($str =~ s/\A# USING://) { $neg = 0; $cmd = $str; next; }
+    elsif ($str =~ /\A# TH[EI]SE? SHOULD FAIL/) { $neg = 1; next; }
+    elsif (!$str || $str =~ /\A#/) { $neg = 0; next }
+    $str =~ s/\\n/\n/g;
+    debug "\tUsing: $cmd\n";
+    debug "\t   on: [$str]\n";
+
+    my @res;
+    my $var = eval "\@res = $cmd";
+    debug "\t   Failed: $@ at " . $@+0 .")" if $@;
+    debug "\t list got: [" . join("|", map {defined $_ ? $_ : '<undef>'} @res) . "]\n";
+    debug "\t list left: [$str]\n";
+    print "not " if (substr($str,pos($str)||0,1) eq ';')==$neg;
+    print "ok ", $count++;
+    print "\n";
+
+    pos $str = 0;
+    $var = eval $cmd;
+    $var = "<undef>" unless defined $var;
+    debug "\t scalar got: [$var]\n";
+    debug "\t scalar left: [$str]\n";
+    print "not " if ($str =~ '\A;')==$neg;
+    print "ok ", $count++;
+    print " ($@)" if $@ && $DEBUG;
+    print "\n";
 }
 
 __DATA__
index c5ca88e..b2f94cf 100644 (file)
@@ -1,52 +1,60 @@
 # Before `make install' is performed this script should be runnable with
 # `make test'. After `make install' it should work as `perl test.pl'
 
+use 5.008001;
+
+use strict;
+use warnings;
+
 ######################### We start with some black magic to print on failure.
 
 # Change 1..1 below to 1..last_test_to_print .
 # (It may become useful if the test is moved to ./t subdirectory.)
 
+my $loaded = 0;
 BEGIN { $| = 1; print "1..45\n"; }
 END {print "not ok 1\n" unless $loaded;}
 use Text::Balanced qw ( extract_delimited );
 $loaded = 1;
 print "ok 1\n";
-$count=2;
+my $count=2;
 use vars qw( $DEBUG );
 sub debug { print "\t>>>",@_ if $DEBUG }
 
 ######################### End of black magic.
 
+## no critic (BuiltinFunctions::ProhibitStringyEval)
 
-$cmd = "print";
-$neg = 0;
+my $cmd = "print";
+my $neg = 0;
+my $str;
 while (defined($str = <DATA>))
 {
-       chomp $str;
-       if ($str =~ s/\A# USING://) { $neg = 0; $cmd = $str; next; }
-       elsif ($str =~ /\A# TH[EI]SE? SHOULD FAIL/) { $neg = 1; next; }
-       elsif (!$str || $str =~ /\A#/) { $neg = 0; next }
-       $str =~ s/\\n/\n/g;
-       debug "\tUsing: $cmd\n";
-       debug "\t   on: [$str]\n";
+    chomp $str;
+    if ($str =~ s/\A# USING://) { $neg = 0; $cmd = $str; next; }
+    elsif ($str =~ /\A# TH[EI]SE? SHOULD FAIL/) { $neg = 1; next; }
+    elsif (!$str || $str =~ /\A#/) { $neg = 0; next }
+    $str =~ s/\\n/\n/g;
+    debug "\tUsing: $cmd\n";
+    debug "\t   on: [$str]\n";
 
-       $var = eval "() = $cmd";
-       debug "\t list got: [$var]\n";
-       debug "\t list left: [$str]\n";
-       print "not " if (substr($str,pos($str)||0,1) eq ';')==$neg;
-       print "ok ", $count++;
-       print " ($@)" if $@ && $DEBUG;
-       print "\n";
+    my $var = eval "() = $cmd";
+    debug "\t list got: [$var]\n";
+    debug "\t list left: [$str]\n";
+    print "not " if (substr($str,pos($str)||0,1) eq ';')==$neg;
+    print "ok ", $count++;
+    print " ($@)" if $@ && $DEBUG;
+    print "\n";
 
-       pos $str = 0;
-       $var = eval $cmd;
-       $var = "<undef>" unless defined $var;
-       debug "\t scalar got: [$var]\n";
-       debug "\t scalar left: [$str]\n";
-       print "not " if ($str =~ '\A;')==$neg;
-       print "ok ", $count++;
-       print " ($@)" if $@ && $DEBUG;
-       print "\n";
+    pos $str = 0;
+    $var = eval $cmd;
+    $var = "<undef>" unless defined $var;
+    debug "\t scalar got: [$var]\n";
+    debug "\t scalar left: [$str]\n";
+    print "not " if ($str =~ '\A;')==$neg;
+    print "ok ", $count++;
+    print " ($@)" if $@ && $DEBUG;
+    print "\n";
 }
 
 __DATA__
index 2ac1b19..9a9711b 100644 (file)
@@ -1,17 +1,23 @@
 # Before `make install' is performed this script should be runnable with
 # `make test'. After `make install' it should work as `perl test.pl'
 
+use 5.008001;
+
+use strict;
+use warnings;
+
 ######################### We start with some black magic to print on failure.
 
 # Change 1..1 below to 1..last_test_to_print .
 # (It may become useful if the test is moved to ./t subdirectory.)
 
+my $loaded = 0;
 BEGIN { $| = 1; print "1..86\n"; }
 END {print "not ok 1\n" unless $loaded;}
 use Text::Balanced qw ( :ALL );
 $loaded = 1;
 print "ok 1\n";
-$count=2;
+my $count=2;
 use vars qw( $DEBUG );
 sub debug { print "\t>>>",@_ if $DEBUG }
 
@@ -19,62 +25,62 @@ sub debug { print "\t>>>",@_ if $DEBUG }
 
 sub expect
 {
-       local $^W;
-       my ($l1, $l2) = @_;
-
-       if (@$l1 != @$l2)
-       {
-               print "\@l1: ", join(", ", @$l1), "\n";
-               print "\@l2: ", join(", ", @$l2), "\n";
-               print "not ";
-       }
-       else
-       {
-               for (my $i = 0; $i < @$l1; $i++)
-               {
-                       if ($l1->[$i] ne $l2->[$i])
-                       {
-                               print "field $i: '$l1->[$i]' ne '$l2->[$i]'\n";
-                               print "not ";
-                               last;
-                       }
-               }
-       }
-
-       print "ok $count\n";
-       $count++;
+    local $^W;
+    my ($l1, $l2) = @_;
+
+    if (@$l1 != @$l2)
+    {
+        print "\@l1: ", join(", ", @$l1), "\n";
+        print "\@l2: ", join(", ", @$l2), "\n";
+        print "not ";
+    }
+    else
+    {
+        for (my $i = 0; $i < @$l1; $i++)
+        {
+            if ($l1->[$i] ne $l2->[$i])
+            {
+                print "field $i: '$l1->[$i]' ne '$l2->[$i]'\n";
+                print "not ";
+                last;
+            }
+        }
+    }
+
+    print "ok $count\n";
+    $count++;
 }
 
 sub divide
 {
-       my ($text, @index) = @_;
-       my @bits = ();
-       unshift @index, 0;
-       push @index, length($text);
-       for ( my $i= 0; $i < $#index; $i++)
-       {
-               push @bits, substr($text, $index[$i], $index[$i+1]-$index[$i]);
-       }
-       pop @bits;
-       return @bits;
+    my ($text, @index) = @_;
+    my @bits = ();
+    unshift @index, 0;
+    push @index, length($text);
+    for ( my $i= 0; $i < $#index; $i++)
+    {
+        push @bits, substr($text, $index[$i], $index[$i+1]-$index[$i]);
+    }
+    pop @bits;
+    return @bits;
 
 }
 
 
-$stdtext1 = q{$var = do {"val" && $val;};};
+my $stdtext1 = q{$var = do {"val" && $val;};};
 
 # TESTS 2-4
-$text = $stdtext1;
-expect [ extract_multiple($text,undef,1) ],
-       [ divide $stdtext1 => 4 ];
+my $text = $stdtext1;
+expect [ extract_multiple($text,undef,1) ],
+       [ divide $stdtext1 => 4 ];
 
 expect [ pos $text], [ 4 ];
 expect [ $text ], [ $stdtext1 ];
 
 # TESTS 5-7
 $text = $stdtext1;
-expect [ scalar extract_multiple($text,undef,1) ],
-       [ divide $stdtext1 => 4 ];
+expect [ scalar extract_multiple($text,undef,1) ],
+       [ divide $stdtext1 => 4 ];
 
 expect [ pos $text], [ 0 ];
 expect [ $text ], [ substr($stdtext1,4) ];
@@ -82,16 +88,16 @@ expect [ $text ], [ substr($stdtext1,4) ];
 
 # TESTS 8-10
 $text = $stdtext1;
-expect [ extract_multiple($text,undef,2) ],
-       [ divide($stdtext1 => 4, 10) ];
+expect [ extract_multiple($text,undef,2) ],
+       [ divide($stdtext1 => 4, 10) ];
 
 expect [ pos $text], [ 10 ];
 expect [ $text ], [ $stdtext1 ];
 
 # TESTS 11-13
 $text = $stdtext1;
-expect [ eval{local$^W;scalar extract_multiple($text,undef,2)} ],
-       [ substr($stdtext1,0,4) ];
+expect [ eval{local$^W;scalar extract_multiple($text,undef,2)} ],
+       [ substr($stdtext1,0,4) ];
 
 expect [ pos $text], [ 0 ];
 expect [ $text ], [ substr($stdtext1,4) ];
@@ -99,16 +105,16 @@ expect [ $text ], [ substr($stdtext1,4) ];
 
 # TESTS 14-16
 $text = $stdtext1;
-expect [ extract_multiple($text,undef,3) ],
-       [ divide($stdtext1 => 4, 10, 26) ];
+expect [ extract_multiple($text,undef,3) ],
+       [ divide($stdtext1 => 4, 10, 26) ];
 
 expect [ pos $text], [ 26 ];
 expect [ $text ], [ $stdtext1 ];
 
 # TESTS 17-19
 $text = $stdtext1;
-expect [ eval{local$^W;scalar extract_multiple($text,undef,3)} ],
-       [ substr($stdtext1,0,4) ];
+expect [ eval{local$^W;scalar extract_multiple($text,undef,3)} ],
+       [ substr($stdtext1,0,4) ];
 
 expect [ pos $text], [ 0 ];
 expect [ $text ], [ substr($stdtext1,4) ];
@@ -116,16 +122,16 @@ expect [ $text ], [ substr($stdtext1,4) ];
 
 # TESTS 20-22
 $text = $stdtext1;
-expect [ extract_multiple($text,undef,4) ],
-       [ divide($stdtext1 => 4, 10, 26, 27) ];
+expect [ extract_multiple($text,undef,4) ],
+       [ divide($stdtext1 => 4, 10, 26, 27) ];
 
 expect [ pos $text], [ 27 ];
 expect [ $text ], [ $stdtext1 ];
 
 # TESTS 23-25
 $text = $stdtext1;
-expect [ eval{local$^W;scalar extract_multiple($text,undef,4)} ],
-       [ substr($stdtext1,0,4) ];
+expect [ eval{local$^W;scalar extract_multiple($text,undef,4)} ],
+       [ substr($stdtext1,0,4) ];
 
 expect [ pos $text], [ 0 ];
 expect [ $text ], [ substr($stdtext1,4) ];
@@ -133,8 +139,8 @@ expect [ $text ], [ substr($stdtext1,4) ];
 
 # TESTS 26-28
 $text = $stdtext1;
-expect [ extract_multiple($text,undef,5) ],
-       [ divide($stdtext1 => 4, 10, 26, 27) ];
+expect [ extract_multiple($text,undef,5) ],
+       [ divide($stdtext1 => 4, 10, 26, 27) ];
 
 expect [ pos $text], [ 27 ];
 expect [ $text ], [ $stdtext1 ];
@@ -142,8 +148,8 @@ expect [ $text ], [ $stdtext1 ];
 
 # TESTS 29-31
 $text = $stdtext1;
-expect [ eval{local$^W;scalar extract_multiple($text,undef,5)} ],
-       [ substr($stdtext1,0,4) ];
+expect [ eval{local$^W;scalar extract_multiple($text,undef,5)} ],
+       [ substr($stdtext1,0,4) ];
 
 expect [ pos $text], [ 0 ];
 expect [ $text ], [ substr($stdtext1,4) ];
@@ -151,19 +157,19 @@ expect [ $text ], [ substr($stdtext1,4) ];
 
 
 # TESTS 32-34
-$stdtext2 = q{$var = "val" && (1,2,3);};
+my $stdtext2 = q{$var = "val" && (1,2,3);};
 
 $text = $stdtext2;
-expect [ extract_multiple($text) ],
-       [ divide($stdtext2 => 4, 7, 12, 24) ];
+expect [ extract_multiple($text) ],
+       [ divide($stdtext2 => 4, 7, 12, 24) ];
 
 expect [ pos $text], [ 24 ];
 expect [ $text ], [ $stdtext2 ];
 
 # TESTS 35-37
 $text = $stdtext2;
-expect [ scalar extract_multiple($text) ],
-       [ substr($stdtext2,0,4) ];
+expect [ scalar extract_multiple($text) ],
+       [ substr($stdtext2,0,4) ];
 
 expect [ pos $text], [ 0 ];
 expect [ $text ], [ substr($stdtext2,4) ];
@@ -171,16 +177,16 @@ expect [ $text ], [ substr($stdtext2,4) ];
 
 # TESTS 38-40
 $text = $stdtext2;
-expect [ extract_multiple($text,[\&extract_bracketed]) ],
-       [ substr($stdtext2,0,16), substr($stdtext2,16,7), substr($stdtext2,23) ];
+expect [ extract_multiple($text,[\&extract_bracketed]) ],
+       [ substr($stdtext2,0,16), substr($stdtext2,16,7), substr($stdtext2,23) ];
 
 expect [ pos $text], [ 24 ];
 expect [ $text ], [ $stdtext2 ];
 
 # TESTS 41-43
 $text = $stdtext2;
-expect [ scalar extract_multiple($text,[\&extract_bracketed]) ],
-       [ substr($stdtext2,0,16) ];
+expect [ scalar extract_multiple($text,[\&extract_bracketed]) ],
+       [ substr($stdtext2,0,16) ];
 
 expect [ pos $text], [ 0 ];
 expect [ $text ], [ substr($stdtext2,15) ];
@@ -188,16 +194,16 @@ expect [ $text ], [ substr($stdtext2,15) ];
 
 # TESTS 44-46
 $text = $stdtext2;
-expect [ extract_multiple($text,[\&extract_variable]) ],
-       [ substr($stdtext2,0,4), substr($stdtext2,4) ];
+expect [ extract_multiple($text,[\&extract_variable]) ],
+       [ substr($stdtext2,0,4), substr($stdtext2,4) ];
 
 expect [ pos $text], [ length($text) ];
 expect [ $text ], [ $stdtext2 ];
 
 # TESTS 47-49
 $text = $stdtext2;
-expect [ scalar extract_multiple($text,[\&extract_variable]) ],
-       [ substr($stdtext2,0,4) ];
+expect [ scalar extract_multiple($text,[\&extract_variable]) ],
+       [ substr($stdtext2,0,4) ];
 
 expect [ pos $text], [ 0 ];
 expect [ $text ], [ substr($stdtext2,4) ];
@@ -205,16 +211,16 @@ expect [ $text ], [ substr($stdtext2,4) ];
 
 # TESTS 50-52
 $text = $stdtext2;
-expect [ extract_multiple($text,[\&extract_quotelike]) ],
-       [ substr($stdtext2,0,7), substr($stdtext2,7,5), substr($stdtext2,12) ];
+expect [ extract_multiple($text,[\&extract_quotelike]) ],
+       [ substr($stdtext2,0,7), substr($stdtext2,7,5), substr($stdtext2,12) ];
 
 expect [ pos $text], [ length($text) ];
 expect [ $text ], [ $stdtext2 ];
 
 # TESTS 53-55
 $text = $stdtext2;
-expect [ scalar extract_multiple($text,[\&extract_quotelike]) ],
-       [ substr($stdtext2,0,7) ];
+expect [ scalar extract_multiple($text,[\&extract_quotelike]) ],
+       [ substr($stdtext2,0,7) ];
 
 expect [ pos $text], [ 0 ];
 expect [ $text ], [ substr($stdtext2,6) ];
@@ -222,16 +228,16 @@ expect [ $text ], [ substr($stdtext2,6) ];
 
 # TESTS 56-58
 $text = $stdtext2;
-expect [ extract_multiple($text,[\&extract_quotelike],2,1) ],
-       [ substr($stdtext2,7,5) ];
+expect [ extract_multiple($text,[\&extract_quotelike],2,1) ],
+       [ substr($stdtext2,7,5) ];
 
 expect [ pos $text], [ 23 ];
 expect [ $text ], [ $stdtext2 ];
 
 # TESTS 59-61
 $text = $stdtext2;
-expect [ eval{local$^W;scalar extract_multiple($text,[\&extract_quotelike],2,1)} ],
-       [ substr($stdtext2,7,5) ];
+expect [ eval{local$^W;scalar extract_multiple($text,[\&extract_quotelike],2,1)} ],
+       [ substr($stdtext2,7,5) ];
 
 expect [ pos $text], [ 6 ];
 expect [ $text ], [ substr($stdtext2,0,6). substr($stdtext2,12) ];
@@ -239,16 +245,16 @@ expect [ $text ], [ substr($stdtext2,0,6). substr($stdtext2,12) ];
 
 # TESTS 62-64
 $text = $stdtext2;
-expect [ extract_multiple($text,[\&extract_quotelike],1,1) ],
-       [ substr($stdtext2,7,5) ];
+expect [ extract_multiple($text,[\&extract_quotelike],1,1) ],
+       [ substr($stdtext2,7,5) ];
 
 expect [ pos $text], [ 12 ];
 expect [ $text ], [ $stdtext2 ];
 
 # TESTS 65-67
 $text = $stdtext2;
-expect [ scalar extract_multiple($text,[\&extract_quotelike],1,1) ],
-       [ substr($stdtext2,7,5) ];
+expect [ scalar extract_multiple($text,[\&extract_quotelike],1,1) ],
+       [ substr($stdtext2,7,5) ];
 
 expect [ pos $text], [ 6 ];
 expect [ $text ], [ substr($stdtext2,0,6). substr($stdtext2,12) ];
@@ -257,8 +263,8 @@ expect [ $text ], [ substr($stdtext2,0,6). substr($stdtext2,12) ];
 my $stdtext3 = "a,b,c";
 
 $_ = $stdtext3;
-expect [ extract_multiple(undef, [ sub { /\G[a-z]/gc && $& } ]) ],
-       [ divide($stdtext3 => 1,2,3,4,5) ];
+expect [ extract_multiple(undef, [ sub { /\G[a-z]/gc && $& } ]) ],
+       [ divide($stdtext3 => 1,2,3,4,5) ];
 
 expect [ pos ], [ 5 ];
 expect [ $_ ], [ $stdtext3 ];
@@ -266,8 +272,8 @@ expect [ $_ ], [ $stdtext3 ];
 # TESTS 71-73
 
 $_ = $stdtext3;
-expect [ scalar extract_multiple(undef, [ sub { /\G[a-z]/gc && $& } ]) ],
-       [ divide($stdtext3 => 1) ];
+expect [ scalar extract_multiple(undef, [ sub { /\G[a-z]/gc && $& } ]) ],
+       [ divide($stdtext3 => 1) ];
 
 expect [ pos ], [ 0 ];
 expect [ $_ ], [ substr($stdtext3,1) ];
@@ -276,8 +282,8 @@ expect [ $_ ], [ substr($stdtext3,1) ];
 # TESTS 74-76
 
 $_ = $stdtext3;
-expect [ extract_multiple(undef, [ qr/\G[a-z]/ ]) ],
-       [ divide($stdtext3 => 1,2,3,4,5) ];
+expect [ extract_multiple(undef, [ qr/\G[a-z]/ ]) ],
+       [ divide($stdtext3 => 1,2,3,4,5) ];
 
 expect [ pos ], [ 5 ];
 expect [ $_ ], [ $stdtext3 ];
@@ -285,8 +291,8 @@ expect [ $_ ], [ $stdtext3 ];
 # TESTS 77-79
 
 $_ = $stdtext3;
-expect [ scalar extract_multiple(undef, [ qr/\G[a-z]/ ]) ],
-       [ divide($stdtext3 => 1) ];
+expect [ scalar extract_multiple(undef, [ qr/\G[a-z]/ ]) ],
+       [ divide($stdtext3 => 1) ];
 
 expect [ pos ], [ 0 ];
 expect [ $_ ], [ substr($stdtext3,1) ];
@@ -295,8 +301,8 @@ expect [ $_ ], [ substr($stdtext3,1) ];
 # TESTS 80-82
 
 $_ = $stdtext3;
-expect [ extract_multiple(undef, [ q/([a-z]),?/ ]) ],
-       [ qw(a b c) ];
+expect [ extract_multiple(undef, [ q/([a-z]),?/ ]) ],
+       [ qw(a b c) ];
 
 expect [ pos ], [ 5 ];
 expect [ $_ ], [ $stdtext3 ];
@@ -304,8 +310,8 @@ expect [ $_ ], [ $stdtext3 ];
 # TESTS 83-85
 
 $_ = $stdtext3;
-expect [ scalar extract_multiple(undef, [ q/([a-z]),?/ ]) ],
-       [ divide($stdtext3 => 1) ];
+expect [ scalar extract_multiple(undef, [ q/([a-z]),?/ ]) ],
+       [ divide($stdtext3 => 1) ];
 
 expect [ pos ], [ 0 ];
 expect [ $_ ], [ substr($stdtext3,2) ];
@@ -315,5 +321,5 @@ expect [ $_ ], [ substr($stdtext3,2) ];
 
 # Fails in Text-Balanced-1.95 with result ['1 ', '""', '1234']
 $_ = q{ ""1234};
-expect [ extract_multiple(undef, [\&extract_quotelike]) ],
-       [ ' ', '""', '1234' ];
+expect [ extract_multiple(undef, [\&extract_quotelike]) ],
+       [ ' ', '""', '1234' ];
index 6badc0e..e32ca7d 100644 (file)
@@ -2,17 +2,23 @@
 # Before `make install' is performed this script should be runnable with
 # `make test'. After `make install' it should work as `perl test.pl'
 
+use 5.008001;
+
+use strict;
+use warnings;
+
 ######################### We start with some black magic to print on failure.
 
 # Change 1..1 below to 1..last_test_to_print .
 # (It may become useful if the test is moved to ./t subdirectory.)
 
+my $loaded = 0;
 BEGIN { $| = 1; print "1..95\n"; }
 END {print "not ok 1\n" unless $loaded;}
 use Text::Balanced qw ( extract_quotelike );
 $loaded = 1;
 print "ok 1\n";
-$count=2;
+my $count=2;
 use vars qw( $DEBUG );
 #$DEBUG=1;
 sub debug { print "\t>>>",@_ if $ENV{DEBUG} }
@@ -20,48 +26,50 @@ sub esc   { my $x = shift||'<undef>'; $x =~ s/\n/\\n/gs; $x }
 
 ######################### End of black magic.
 
+## no critic (BuiltinFunctions::ProhibitStringyEval)
 
-$cmd = "print";
-$neg = 0;
+my $cmd = "print";
+my $neg = 0;
+my $str;
 while (defined($str = <DATA>))
 {
-       chomp $str;
-       if ($str =~ s/\A# USING://)                 { $neg = 0; $cmd = $str; next; }
-       elsif ($str =~ /\A# TH[EI]SE? SHOULD FAIL/) { $neg = 1; next; }
-       elsif (!$str || $str =~ /\A#/)              { $neg = 0; next }
-       my $setup_cmd = ($str =~ s/\A\{(.*)\}//) ? $1 : '';
-       my $tests = 'sl';
-       $str =~ s/\\n/\n/g;
-       my $orig = $str;
-
-       eval $setup_cmd if $setup_cmd ne ''; 
-       if($tests =~ /l/) {
-               debug "\tUsing: $cmd\n";
-               debug "\t   on: [" . esc($setup_cmd) . "][" . esc($str) . "]\n";
-               my @res;
-               eval qq{\@res = $cmd; };
-               debug "\t  got:\n" . join "", map { "\t\t\t$_: [" . esc($res[$_]) . "]\n"} (0..$#res);
-               debug "\t left: [" . esc($str) . "]\n";
-               debug "\t  pos: [" . esc(substr($str,pos($str))) . "...]\n";
-               print "not " if (substr($str,pos($str),1) eq ';')==$neg;
-               print "ok ", $count++;
-               print "\n";
-       }
-
-       eval $setup_cmd if $setup_cmd ne '';
-       if($tests =~ /s/) {
-               $str = $orig;
-               debug "\tUsing: scalar $cmd\n";
-               debug "\t   on: [" . esc($str) . "]\n";
-               $var = eval $cmd;
-               print " ($@)" if $@ && $DEBUG;
-               $var = "<undef>" unless defined $var;
-               debug "\t scalar got: [" . esc($var) . "]\n";
-               debug "\t scalar left: [" . esc($str) . "]\n";
-               print "not " if ($str =~ '\A;')==$neg;
-               print "ok ", $count++;
-               print "\n";
-       }
+    chomp $str;
+    if ($str =~ s/\A# USING://)                 { $neg = 0; $cmd = $str; next; }
+    elsif ($str =~ /\A# TH[EI]SE? SHOULD FAIL/) { $neg = 1; next; }
+    elsif (!$str || $str =~ /\A#/)              { $neg = 0; next }
+    my $setup_cmd = ($str =~ s/\A\{(.*)\}//) ? $1 : '';
+    my $tests = 'sl';
+    $str =~ s/\\n/\n/g;
+    my $orig = $str;
+
+    eval $setup_cmd if $setup_cmd ne '';
+    if($tests =~ /l/) {
+        debug "\tUsing: $cmd\n";
+        debug "\t   on: [" . esc($setup_cmd) . "][" . esc($str) . "]\n";
+        my @res;
+        eval qq{\@res = $cmd; };
+        debug "\t  got:\n" . join "", map { "\t\t\t$_: [" . esc($res[$_]) . "]\n"} (0..$#res);
+        debug "\t left: [" . esc($str) . "]\n";
+        debug "\t  pos: [" . esc(substr($str,pos($str))) . "...]\n";
+        print "not " if (substr($str,pos($str),1) eq ';')==$neg;
+        print "ok ", $count++;
+        print "\n";
+    }
+
+    eval $setup_cmd if $setup_cmd ne '';
+    if($tests =~ /s/) {
+        $str = $orig;
+        debug "\tUsing: scalar $cmd\n";
+        debug "\t   on: [" . esc($str) . "]\n";
+        my $var = eval $cmd;
+        print " ($@)" if $@ && $DEBUG;
+        $var = "<undef>" unless defined $var;
+        debug "\t scalar got: [" . esc($var) . "]\n";
+        debug "\t scalar left: [" . esc($str) . "]\n";
+        print "not " if ($str =~ '\A;')==$neg;
+        print "ok ", $count++;
+        print "\n";
+    }
 }
 
 # fails in Text::Balanced 1.95
@@ -71,7 +79,7 @@ print "not " if $z[0] eq '';
 print "ok ", $count++;
 print "\n";
 
+
 __DATA__
 
 # USING: extract_quotelike($str);
@@ -92,9 +100,9 @@ __DATA__
 <<""; done()\nline1\nline2\n\n and next
 <<; done()\nline1\nline2\n\n and next
 # fails in Text::Balanced 1.95
-<<EOHERE;\nEOHERE\n; 
+<<EOHERE;\nEOHERE\n;
 # fails in Text::Balanced 1.95
-<<"*";\n\n*\n; 
+<<"*";\n\n*\n;
 
 "this is a nested $var[$x] {";
 /a/gci;
@@ -128,8 +136,8 @@ y/x/y/;
 { $tests = 'l'; pos($str)=6 }012345<<E;\n\nE\n
 
 # THESE SHOULD FAIL
-s<$self->{pat}>{$self->{sub}};         # CAN'T HANDLE '>' in '->'
-s-$self->{pap}-$self->{sub}-;          # CAN'T HANDLE '-' in '->'
-<<EOHERE; done();\nline1\nline2\nEOHERE;\n; next;          # RDEL HAS NO ';'
-<<'EOHERE'; done();\nline1\nline2\nEOHERE;\n; next;        # RDEF HAS NO ';'
+s<$self->{pat}>{$self->{sub}}; # CAN'T HANDLE '>' in '->'
+s-$self->{pap}-$self->{sub}-;  # CAN'T HANDLE '-' in '->'
+<<EOHERE; done();\nline1\nline2\nEOHERE;\n; next;   # RDEL HAS NO ';'
+<<'EOHERE'; done();\nline1\nline2\nEOHERE;\n; next; # RDEF HAS NO ';'
      <<    EOTHERE; done();\nline1\nline2\n    EOTHERE\n; next;  # RDEL IS "" (!)
index 16a48b2..fd7eff4 100644 (file)
 # Before `make install' is performed this script should be runnable with
 # `make test'. After `make install' it should work as `perl test.pl'
 
+use 5.008001;
+
+use strict;
+use warnings;
+
 ######################### We start with some black magic to print on failure.
 
 # Change 1..1 below to 1..last_test_to_print .
 # (It may become useful if the test is moved to ./t subdirectory.)
 
+my $loaded = 0;
 BEGIN { $| = 1; print "1..53\n"; }
 END {print "not ok 1\n" unless $loaded;}
 use Text::Balanced qw ( extract_tagged gen_extract_tagged );
 $loaded = 1;
 print "ok 1\n";
-$count=2;
+my $count=2;
 use vars qw( $DEBUG );
 sub debug { print "\t>>>",@_ if $DEBUG }
 
 ######################### End of black magic.
 
+## no critic (BuiltinFunctions::ProhibitStringyEval)
 
-$cmd = "print";
-$neg = 0;
+my $cmd = "print";
+my $neg = 0;
+my $str;
 while (defined($str = <DATA>))
 {
-       chomp $str;
-       if ($str =~ s/\A# USING://) { $neg = 0; $cmd = $str; next; }
-       elsif ($str =~ /\A# TH[EI]SE? SHOULD FAIL/) { $neg = 1; next; }
-       elsif (!$str || $str =~ /\A#/) { $neg = 0; next }
-       $str =~ s/\\n/\n/g;
-       debug "\tUsing: $cmd\n";
-       debug "\t   on: [$str]\n";
-
-       my @res;
-       $var = eval "\@res = $cmd";
-       debug "\t list got: [" . join("|",map {defined $_ ? $_ : '<undef>'} @res) . "]\n";
-       debug "\t list left: [$str]\n";
-       print "not " if (substr($str,pos($str)||0,1) eq ';')==$neg;
-       print "ok ", $count++;
-       print " ($@)" if $@ && $DEBUG;
-       print "\n";
-
-       pos $str = 0;
-       $var = eval $cmd;
-       $var = "<undef>" unless defined $var;
-       debug "\t scalar got: [$var]\n";
-       debug "\t scalar left: [$str]\n";
-       print "not " if ($str =~ '\A;')==$neg;
-       print "ok ", $count++;
-       print " ($@)" if $@ && $DEBUG;
-       print "\n";
+    chomp $str;
+    if ($str =~ s/\A# USING://) { $neg = 0; $cmd = $str; next; }
+    elsif ($str =~ /\A# TH[EI]SE? SHOULD FAIL/) { $neg = 1; next; }
+    elsif (!$str || $str =~ /\A#/) { $neg = 0; next }
+    $str =~ s/\\n/\n/g;
+    debug "\tUsing: $cmd\n";
+    debug "\t   on: [$str]\n";
+
+    my @res;
+    my $var = eval "\@res = $cmd";
+    debug "\t list got: [" . join("|",map {defined $_ ? $_ : '<undef>'} @res) . "]\n";
+    debug "\t list left: [$str]\n";
+    print "not " if (substr($str,pos($str)||0,1) eq ';')==$neg;
+    print "ok ", $count++;
+    print " ($@)" if $@ && $DEBUG;
+    print "\n";
+
+    pos $str = 0;
+    $var = eval $cmd;
+    $var = "<undef>" unless defined $var;
+    debug "\t scalar got: [$var]\n";
+    debug "\t scalar left: [$str]\n";
+    print "not " if ($str =~ '\A;')==$neg;
+    print "ok ", $count++;
+    print " ($@)" if $@ && $DEBUG;
+    print "\n";
 }
 
 __DATA__
 # USING: gen_extract_tagged("BEGIN([A-Z]+)",'END$1',"(?s).*?(?=BEGIN)")->($str);
-       ignore\n this and then BEGINHERE at the ENDHERE;
-       ignore\n this and then BEGINTHIS at the ENDTHIS;
+    ignore\n this and then BEGINHERE at the ENDHERE;
+    ignore\n this and then BEGINTHIS at the ENDTHIS;
 
 # USING: extract_tagged($str,"BEGIN([A-Z]+)",'END$1',"(?s).*?(?=BEGIN)");
-       ignore\n this and then BEGINHERE at the ENDHERE;
-       ignore\n this and then BEGINTHIS at the ENDTHIS;
+    ignore\n this and then BEGINHERE at the ENDHERE;
+    ignore\n this and then BEGINTHIS at the ENDTHIS;
 
 # USING: extract_tagged($str,"BEGIN([A-Z]+)",'END$1',"(?s).*?(?=BEGIN)");
-       ignore\n this and then BEGINHERE at the ENDHERE;
-       ignore\n this and then BEGINTHIS at the ENDTHIS;
+    ignore\n this and then BEGINHERE at the ENDHERE;
+    ignore\n this and then BEGINTHIS at the ENDTHIS;
 
 # THIS SHOULD FAIL
-       ignore\n this and then BEGINTHIS at the ENDTHAT;
+    ignore\n this and then BEGINTHIS at the ENDTHAT;
 
 # USING: extract_tagged($str,"BEGIN","END","(?s).*?(?=BEGIN)");
-       ignore\n this and then BEGIN at the END;
+    ignore\n this and then BEGIN at the END;
 
 # USING: extract_tagged($str);
-       <A-1 HREF="#section2">some text</A-1>;
+    <A-1 HREF="#section2">some text</A-1>;
 
 # USING: extract_tagged($str,qr/<[A-Z]+>/,undef, undef, {ignore=>["<BR>"]});
-       <A>aaa<B>bbb<BR>ccc</B>ddd</A>;
+    <A>aaa<B>bbb<BR>ccc</B>ddd</A>;
 
 # USING: extract_tagged($str,"BEGIN","END");
-       BEGIN at the BEGIN keyword and END at the END;
-       BEGIN at the beginning and end at the END;
+    BEGIN at the BEGIN keyword and END at the END;
+    BEGIN at the beginning and end at the END;
 
 # USING: extract_tagged($str,undef,undef,undef,{ignore=>["<[^>]*/>"]});
-       <A>aaa<B>bbb<BR/>ccc</B>ddd</A>;
+    <A>aaa<B>bbb<BR/>ccc</B>ddd</A>;
 
 # USING: extract_tagged($str,";","-",undef,{reject=>[";"],fail=>"MAX"});
-       ; at the ;-) keyword
+    ; at the ;-) keyword
 
 # USING: extract_tagged($str,"<[A-Z]+>",undef, undef, {ignore=>["<BR>"]});
-       <A>aaa<B>bbb<BR>ccc</B>ddd</A>;
+    <A>aaa<B>bbb<BR>ccc</B>ddd</A>;
 
 # THESE SHOULD FAIL
-       BEGIN at the beginning and end at the end;
-       BEGIN at the BEGIN keyword and END at the end;
+    BEGIN at the beginning and end at the end;
+    BEGIN at the BEGIN keyword and END at the end;
 
 # TEST EXTRACTION OF TAGGED STRINGS
 # USING: extract_tagged($str,"BEGIN","END",undef,{reject=>["BEGIN","END"]});
 # THESE SHOULD FAIL
-       BEGIN at the BEGIN keyword and END at the end;
+    BEGIN at the BEGIN keyword and END at the end;
 
 # USING: extract_tagged($str,";","-",undef,{reject=>[";"],fail=>"PARA"});
-       ; at the ;-) keyword
+    ; at the ;-) keyword
 
 
 # USING: extract_tagged($str);
-       <A>some text</A>;
-       <B>some text<A>other text</A></B>;
-       <A>some text<A>other text</A></A>;
-       <A HREF="#section2">some text</A>;
+    <A>some text</A>;
+    <B>some text<A>other text</A></B>;
+    <A>some text<A>other text</A></A>;
+    <A HREF="#section2">some text</A>;
 
 # THESE SHOULD FAIL
-       <A>some text
-       <A>some text<A>other text</A>;
-       <B>some text<A>other text</B>;
+    <A>some text
+    <A>some text<A>other text</A>;
+    <B>some text<A>other text</B>;
index a33ac91..f527b84 100644 (file)
@@ -1,53 +1,61 @@
 # Before `make install' is performed this script should be runnable with
 # `make test'. After `make install' it should work as `perl test.pl'
 
+use 5.008001;
+
+use strict;
+use warnings;
+
 ######################### We start with some black magic to print on failure.
 
 # Change 1..1 below to 1..last_test_to_print .
 # (It may become useful if the test is moved to ./t subdirectory.)
 
+my $loaded = 0;
 BEGIN { $| = 1; print "1..183\n"; }
 END {print "not ok 1\n" unless $loaded;}
 use Text::Balanced qw ( extract_variable );
 $loaded = 1;
 print "ok 1\n";
-$count=2;
+my $count=2;
 use vars qw( $DEBUG );
 sub debug { print "\t>>>",@_ if $DEBUG }
 
 ######################### End of black magic.
 
+## no critic (BuiltinFunctions::ProhibitStringyEval)
 
-$cmd = "print";
-$neg = 0;
+my $cmd = "print";
+my $neg = 0;
+my $str;
 while (defined($str = <DATA>))
 {
-       chomp $str;
-       if ($str =~ s/\A# USING://) { $neg = 0; $cmd = $str; next; }
-       elsif ($str =~ /\A# TH[EI]SE? SHOULD FAIL/) { $neg = 1; next; }
-       elsif (!$str || $str =~ /\A#/) { $neg = 0; next }
-       $str =~ s/\\n/\n/g;
-       debug "\tUsing: $cmd\n";
-       debug "\t   on: [$str]\n";
+    chomp $str;
+    if ($str =~ s/\A# USING://) { $neg = 0; $cmd = $str; next; }
+    elsif ($str =~ /\A# TH[EI]SE? SHOULD FAIL/) { $neg = 1; next; }
+    elsif (!$str || $str =~ /\A#/) { $neg = 0; next }
+    $str =~ s/\\n/\n/g;
+    debug "\tUsing: $cmd\n";
+    debug "\t   on: [$str]\n";
 
-       my @res;
-       $var = eval "\@res = $cmd";
-       debug "\t list got: [" . join("|",map {defined $_ ? $_ : '<undef>'} @res) . "]\n";
-       debug "\t list left: [$str]\n";
-       print "not " if (substr($str,pos($str)||0,1) eq ';')==$neg;
-       print "ok ", $count++;
-       print " ($@)" if $@ && $DEBUG;
-       print "\n";
+    my @res;
+    my $var = eval "\@res = $cmd";
+    debug "\t list got: [" . join("|",map {defined $_ ? $_ : '<undef>'} @res) . "]\n";
+    debug "\t list left: [$str]\n";
+    print "not " if (substr($str,pos($str)||0,1) eq ';')==$neg;
+    print "ok ", $count++;
+    print " ($@)" if $@ && $DEBUG;
+    print "\n";
 
-       pos $str = 0;
-       $var = eval $cmd;
-       $var = "<undef>" unless defined $var;
-       debug "\t scalar got: [$var]\n";
-       debug "\t scalar left: [$str]\n";
-       print "not " if ($str =~ '\A;')==$neg;
-       print "ok ", $count++;
-       print " ($@)" if $@ && $DEBUG;
-       print "\n";
+    pos $str = 0;
+    $var = eval $cmd;
+    $var = "<undef>" unless defined $var;
+    debug "\t scalar got: [$var]\n";
+    debug "\t scalar left: [$str]\n";
+    print "not " if ($str =~ '\A;')==$neg;
+    print "ok ", $count++;
+    print " ($@)" if $@ && $DEBUG;
+    print "\n";
 }
 
 __DATA__
index 0dd55a5..1a82ae1 100644 (file)
 # Before `make install' is performed this script should be runnable with
 # `make test'. After `make install' it should work as `perl test.pl'
 
+use 5.008001;
+
+use strict;
+use warnings;
+
 ######################### We start with some black magic to print on failure.
 
 # Change 1..1 below to 1..last_test_to_print .
 # (It may become useful if the test is moved to ./t subdirectory.)
 
+my $loaded = 0;
 BEGIN { $| = 1; print "1..37\n"; }
 END {print "not ok 1\n" unless $loaded;}
 use Text::Balanced qw ( gen_extract_tagged );
 $loaded = 1;
 print "ok 1\n";
-$count=2;
+my $count=2;
 use vars qw( $DEBUG );
 sub debug { print "\t>>>",@_ if $DEBUG }
 
 ######################### End of black magic.
 
+## no critic (BuiltinFunctions::ProhibitStringyEval)
 
-$cmd = "print";
-$neg = 0;
+my $cmd = "print";
+my $neg = 0;
+my $str;
 while (defined($str = <DATA>))
 {
-       chomp $str;
-       $str =~ s/\\n/\n/g;
-       if ($str =~ s/\A# USING://)
-       {
-               $neg = 0;
-               eval{local$^W;*f = eval $str || die};
-               next;
-       }
-       elsif ($str =~ /\A# TH[EI]SE? SHOULD FAIL/) { $neg = 1; next; }
-       elsif (!$str || $str =~ /\A#/) { $neg = 0; next }
-       $str =~ s/\\n/\n/g;
-       debug "\tUsing: $cmd\n";
-       debug "\t   on: [$str]\n";
-
-       my @res;
-       $var = eval { @res = f($str) };
-       debug "\t list got: [" . join("|",map {defined $_ ? $_ : '<undef>'} @res) . "]\n";
-       debug "\t list left: [$str]\n";
-       print "not " if (substr($str,pos($str)||0,1) eq ';')==$neg;
-       print "ok ", $count++;
-       print " ($@)" if $@ && $DEBUG;
-       print "\n";
-
-       pos $str = 0;
-       $var = eval { scalar f($str) };
-       $var = "<undef>" unless defined $var;
-       debug "\t scalar got: [$var]\n";
-       debug "\t scalar left: [$str]\n";
-       print "not " if ($str =~ '\A;')==$neg;
-       print "ok ", $count++;
-       print " ($@)" if $@ && $DEBUG;
-       print "\n";
+    chomp $str;
+    $str =~ s/\\n/\n/g;
+    if ($str =~ s/\A# USING://)
+    {
+        $neg = 0;
+        eval {
+                # Capture "Subroutine main::f redefined" warning
+                my @warnings;
+                local $SIG{__WARN__} = sub { push @warnings, shift; };
+                *f = eval $str || die;
+        };
+        next;
+    }
+    elsif ($str =~ /\A# TH[EI]SE? SHOULD FAIL/) { $neg = 1; next; }
+    elsif (!$str || $str =~ /\A#/) { $neg = 0; next }
+    $str =~ s/\\n/\n/g;
+    debug "\tUsing: $cmd\n";
+    debug "\t   on: [$str]\n";
+
+    my @res;
+    my $var = eval { @res = f($str) };
+    debug "\t list got: [" . join("|",map {defined $_ ? $_ : '<undef>'} @res) . "]\n";
+    debug "\t list left: [$str]\n";
+    print "not " if (substr($str,pos($str)||0,1) eq ';')==$neg;
+    print "ok ", $count++;
+    print " ($@)" if $@ && $DEBUG;
+    print "\n";
+
+    pos $str = 0;
+    $var = eval { scalar f($str) };
+    $var = "<undef>" unless defined $var;
+    debug "\t scalar got: [$var]\n";
+    debug "\t scalar left: [$str]\n";
+    print "not " if ($str =~ '\A;')==$neg;
+    print "ok ", $count++;
+    print " ($@)" if $@ && $DEBUG;
+    print "\n";
 }
 
 __DATA__
 
 # USING: gen_extract_tagged('{','}');
-       { a test };
+    { a test };
 
 # USING: gen_extract_tagged(qr/<[A-Z]+>/,undef, undef, {ignore=>["<BR>"]});
-       <A>aaa<B>bbb<BR>ccc</B>ddd</A>;
+    <A>aaa<B>bbb<BR>ccc</B>ddd</A>;
 
 # USING: gen_extract_tagged("BEGIN","END");
-       BEGIN at the BEGIN keyword and END at the END;
-       BEGIN at the beginning and end at the END;
+    BEGIN at the BEGIN keyword and END at the END;
+    BEGIN at the beginning and end at the END;
 
 # USING: gen_extract_tagged(undef,undef,undef,{ignore=>["<[^>]*/>"]});
-       <A>aaa<B>bbb<BR/>ccc</B>ddd</A>;
+    <A>aaa<B>bbb<BR/>ccc</B>ddd</A>;
 
 # USING: gen_extract_tagged(";","-",undef,{reject=>[";"],fail=>"MAX"});
-       ; at the ;-) keyword
+    ; at the ;-) keyword
 
 # USING: gen_extract_tagged("<[A-Z]+>",undef, undef, {ignore=>["<BR>"]});
-       <A>aaa<B>bbb<BR>ccc</B>ddd</A>;
+    <A>aaa<B>bbb<BR>ccc</B>ddd</A>;
 
 # THESE SHOULD FAIL
-       BEGIN at the beginning and end at the end;
-       BEGIN at the BEGIN keyword and END at the end;
+    BEGIN at the beginning and end at the end;
+    BEGIN at the BEGIN keyword and END at the end;
 
 # TEST EXTRACTION OF TAGGED STRINGS
 # USING: gen_extract_tagged("BEGIN","END",undef,{reject=>["BEGIN","END"]});
 # THESE SHOULD FAIL
-       BEGIN at the BEGIN keyword and END at the end;
+    BEGIN at the BEGIN keyword and END at the end;
 
 # USING: gen_extract_tagged(";","-",undef,{reject=>[";"],fail=>"PARA"});
-       ; at the ;-) keyword
+    ; at the ;-) keyword
 
 
 # USING: gen_extract_tagged();
-       <A>some text</A>;
-       <B>some text<A>other text</A></B>;
-       <A>some text<A>other text</A></A>;
-       <A HREF="#section2">some text</A>;
+    <A>some text</A>;
+    <B>some text<A>other text</A></B>;
+    <A>some text<A>other text</A></A>;
+    <A HREF="#section2">some text</A>;
 
 # THESE SHOULD FAIL
-       <A>some text
-       <A>some text<A>other text</A>;
-       <B>some text<A>other text</B>;
+    <A>some text
+    <A>some text<A>other text</A>;
+    <B>some text<A>other text</B>;
diff --git a/cpan/Text-Balanced/t/94_changes.t b/cpan/Text-Balanced/t/94_changes.t
new file mode 100644 (file)
index 0000000..400ec89
--- /dev/null
@@ -0,0 +1,48 @@
+#!perl
+#===============================================================================
+#
+# t/94_changes.t
+#
+# DESCRIPTION
+#   Test script to check CPAN::Changes conformance.
+#
+# COPYRIGHT
+#   Copyright (C) 2015 Steve Hay.  All rights reserved.
+#
+# LICENCE
+#   This script is free software; you can redistribute it and/or modify it under
+#   the same terms as Perl itself, i.e. under the terms of either the GNU
+#   General Public License or the Artistic License, as specified in the LICENCE
+#   file.
+#
+#===============================================================================
+
+use 5.008001;
+
+use strict;
+use warnings;
+
+use Test::More;
+
+#===============================================================================
+# MAIN PROGRAM
+#===============================================================================
+
+MAIN: {
+    plan skip_all => 'Author testing only' unless $ENV{AUTHOR_TESTING};
+
+    my $ok = eval {
+        require Test::CPAN::Changes;
+        Test::CPAN::Changes->import();
+        1;
+    };
+
+    if (not $ok) {
+        plan skip_all => 'Test::CPAN::Changes required to test Changes';
+    }
+    else {
+        changes_ok();
+    }
+}
+
+#===============================================================================
diff --git a/cpan/Text-Balanced/t/95_critic.t b/cpan/Text-Balanced/t/95_critic.t
new file mode 100644 (file)
index 0000000..1e57542
--- /dev/null
@@ -0,0 +1,48 @@
+#!perl
+#===============================================================================
+#
+# t/95_critic.t
+#
+# DESCRIPTION
+#   Test script to check Perl::Critic conformance.
+#
+# COPYRIGHT
+#   Copyright (C) 2015 Steve Hay.  All rights reserved.
+#
+# LICENCE
+#   This script is free software; you can redistribute it and/or modify it under
+#   the same terms as Perl itself, i.e. under the terms of either the GNU
+#   General Public License or the Artistic License, as specified in the LICENCE
+#   file.
+#
+#===============================================================================
+
+use 5.008001;
+
+use strict;
+use warnings;
+
+use Test::More;
+
+#===============================================================================
+# MAIN PROGRAM
+#===============================================================================
+
+MAIN: {
+    plan skip_all => 'Author testing only' unless $ENV{AUTHOR_TESTING};
+
+    my $ok = eval {
+        require Test::Perl::Critic;
+        Test::Perl::Critic->import(-profile => '');
+        1;
+    };
+
+    if (not $ok) {
+        plan skip_all => 'Test::Perl::Critic required to test with Perl::Critic';
+    }
+    else {
+        all_critic_ok('.');
+    }
+}
+
+#===============================================================================
diff --git a/cpan/Text-Balanced/t/96_pmv.t b/cpan/Text-Balanced/t/96_pmv.t
new file mode 100644 (file)
index 0000000..e1197da
--- /dev/null
@@ -0,0 +1,32 @@
+#!/usr/bin/perl
+
+# Test that our declared minimum Perl version matches our syntax
+
+use 5.008001;
+
+use strict;
+use warnings;
+
+use Test::More;
+
+my @MODULES = (
+    'Perl::MinimumVersion 1.20',
+    'Test::MinimumVersion 0.101082',
+);
+
+# Don't run tests for installs
+use Test::More;
+unless ( $ENV{AUTHOR_TESTING} ) {
+    plan( skip_all => "Author testing only" );
+}
+
+# Load the testing modules
+foreach my $MODULE ( @MODULES ) {
+    ## no critic (BuiltinFunctions::ProhibitStringyEval)
+    eval "use $MODULE";
+    if ( $@ ) {
+        plan( skip_all => "$MODULE not available for testing" );
+    }
+}
+
+all_minimum_version_from_mymetayml_ok();
diff --git a/cpan/Text-Balanced/t/97_pod.t b/cpan/Text-Balanced/t/97_pod.t
new file mode 100644 (file)
index 0000000..d0f4cae
--- /dev/null
@@ -0,0 +1,32 @@
+#!/usr/bin/perl
+
+# Test that the syntax of our POD documentation is valid
+
+use 5.008001;
+
+use strict;
+use warnings;
+
+use Test::More;
+
+my @MODULES = (
+    'Pod::Simple 3.07',
+    'Test::Pod 1.26',
+);
+
+# Don't run tests for installs
+use Test::More;
+unless ( $ENV{AUTHOR_TESTING} ) {
+    plan( skip_all => "Author testing only" );
+}
+
+# Load the testing modules
+foreach my $MODULE ( @MODULES ) {
+    ## no critic (BuiltinFunctions::ProhibitStringyEval)
+    eval "use $MODULE";
+    if ( $@ ) {
+        plan( skip_all => "$MODULE not available for testing" );
+    }
+}
+
+all_pod_files_ok();
diff --git a/cpan/Text-Balanced/t/98_pod_coverage.t b/cpan/Text-Balanced/t/98_pod_coverage.t
new file mode 100644 (file)
index 0000000..cce4f94
--- /dev/null
@@ -0,0 +1,51 @@
+#!perl
+#===============================================================================
+#
+# t/99_pod_coverage.t
+#
+# DESCRIPTION
+#   Test script to check POD coverage.
+#
+# COPYRIGHT
+#   Copyright (C) 2015 Steve Hay.  All rights reserved.
+#
+# LICENCE
+#   This script is free software; you can redistribute it and/or modify it under
+#   the same terms as Perl itself, i.e. under the terms of either the GNU
+#   General Public License or the Artistic License, as specified in the LICENCE
+#   file.
+#
+#===============================================================================
+
+use 5.008001;
+
+use strict;
+use warnings;
+
+use Test::More;
+
+#===============================================================================
+# MAIN PROGRAM
+#===============================================================================
+
+MAIN: {
+    plan skip_all => 'Author testing only' unless $ENV{AUTHOR_TESTING};
+
+    my $ok = eval {
+        require Test::Pod::Coverage;
+        Test::Pod::Coverage->import();
+        1;
+    };
+
+    if (not $ok) {
+        plan skip_all => 'Test::Pod::Coverage required to test POD coverage';
+    }
+    elsif ($Test::Pod::Coverage::VERSION < 0.08) {
+        plan skip_all => 'Test::Pod::Coverage 0.08 or higher required to test POD coverage';
+    }
+    else {
+        all_pod_coverage_ok();
+    }
+}
+
+#===============================================================================
diff --git a/cpan/Unicode-Collate/.gitignore b/cpan/Unicode-Collate/.gitignore
new file mode 100644 (file)
index 0000000..47489b4
--- /dev/null
@@ -0,0 +1,2 @@
+*.h
+!/Makefile.PL
diff --git a/cpan/Win32/.gitignore b/cpan/Win32/.gitignore
new file mode 100644 (file)
index 0000000..e54624d
--- /dev/null
@@ -0,0 +1 @@
+!/Makefile.PL
diff --git a/cpan/Win32API-File/.gitignore b/cpan/Win32API-File/.gitignore
new file mode 100644 (file)
index 0000000..e54624d
--- /dev/null
@@ -0,0 +1 @@
+!/Makefile.PL
diff --git a/cpan/libnet/.gitignore b/cpan/libnet/.gitignore
new file mode 100644 (file)
index 0000000..e54624d
--- /dev/null
@@ -0,0 +1 @@
+!/Makefile.PL
index 73be0a1..4777390 100644 (file)
@@ -7,7 +7,7 @@
 #   Makefile creation script.
 #
 # COPYRIGHT
-#   Copyright (C) 2014, 2015 Steve Hay.  All rights reserved.
+#   Copyright (C) 2014-2015, 2020 Steve Hay.  All rights reserved.
 #
 # LICENCE
 #   This script is free software; you can redistribute it and/or modify it under
@@ -66,7 +66,7 @@ MAIN: {
         ABSTRACT => 'Collection of network protocol modules',
         AUTHOR   => 'Graham Barr <gbarr@pobox.com>, Steve Hay <shay@cpan.org>',
         LICENSE  => 'perl_5',
-        VERSION  => '3.11',
+        VERSION  => '3.12',
 
         META_MERGE => {
             'meta-spec' => {
@@ -76,7 +76,7 @@ MAIN: {
             resources => {
                 repository => {
                     type => 'git',
-                    url  => 'https://github.com/steve-m-hay/perl-libnet.git'
+                    web  => 'https://github.com/steve-m-hay/perl-libnet'
                 }
             },
 
index b695f64..650f23b 100644 (file)
@@ -1,7 +1,7 @@
 # Net::Cmd.pm
 #
 # Copyright (C) 1995-2006 Graham Barr.  All rights reserved.
-# Copyright (C) 2013-2016 Steve Hay.  All rights reserved.
+# Copyright (C) 2013-2016, 2020 Steve Hay.  All rights reserved.
 # This module is free software; you can redistribute it and/or modify it under
 # the same terms as Perl itself, i.e. under the terms of either the GNU General
 # Public License or the Artistic License, as specified in the F<LICENCE> file.
@@ -26,7 +26,7 @@ BEGIN {
   }
 }
 
-our $VERSION = "3.11";
+our $VERSION = "3.12";
 our @ISA     = qw(Exporter);
 our @EXPORT  = qw(CMD_INFO CMD_OK CMD_MORE CMD_REJECT CMD_ERROR CMD_PENDING);
 
@@ -100,7 +100,7 @@ sub _print_isa {
 
 
 sub debug {
-  @_ == 1 or @_ == 2 or croak 'usage: $obj->debug([LEVEL])';
+  @_ == 1 or @_ == 2 or croak 'usage: $obj->debug([$level])';
 
   my ($cmd, $level) = @_;
   my $pkg    = ref($cmd) || $cmd;
@@ -175,7 +175,7 @@ sub status {
 
 
 sub set_status {
-  @_ == 3 or croak 'usage: $obj->set_status(CODE, MESSAGE)';
+  @_ == 3 or croak 'usage: $obj->set_status($code, $resp)';
 
   my $cmd = shift;
   my ($code, $resp) = @_;
@@ -335,15 +335,19 @@ sub getline {
   my $rin = "";
   vec($rin, $fd, 1) = 1;
 
+  my $timeout = $cmd->timeout || undef;
+  my $initial = time;
+  my $pending = $timeout;
+
   my $buf;
 
   until (scalar(@{${*$cmd}{'net_cmd_lines'}})) {
-    my $timeout = $cmd->timeout || undef;
     my $rout;
 
-    my $select_ret = select($rout = $rin, undef, undef, $timeout);
-    if ($select_ret > 0) {
-      unless (sysread($cmd, $buf = "", 1024)) {
+    my $select_ret = select($rout = $rin, undef, undef, $pending);
+    if (defined $select_ret and $select_ret > 0) {
+      my $r = sysread($cmd, $buf = "", 1024);
+      if (! defined($r) ) {
         my $err = $!;
         $cmd->close;
         $cmd->_set_status_closed($err);
@@ -359,6 +363,20 @@ sub getline {
       push(@{${*$cmd}{'net_cmd_lines'}}, map {"$_\n"} @buf);
 
     }
+    elsif (defined $select_ret && $select_ret == -1) {
+      if ( $! == EINTR ) {
+        if ( defined($timeout) ) {
+          redo if ($pending = $timeout - ( time - $initial ) ) > 0;
+          $cmd->_set_status_timeout;
+          return;
+        }
+        redo;
+      }
+      my $err = $!;
+      $cmd->close;
+      $cmd->_set_status_closed($err);
+      return;
+    }
     else {
       $cmd->_set_status_timeout;
       return;
@@ -661,59 +679,59 @@ C<IO::Socket::IP>, C<IO::Socket::INET6> or C<IO::Socket::SSL>) then you must
 provide the following methods by other means yourself: C<close()> and
 C<timeout()>.
 
-=head1 USER METHODS
+=head2 Public Methods
 
 These methods provide a user interface to the C<Net::Cmd> object.
 
 =over 4
 
-=item debug ( VALUE )
+=item C<debug($level)>
 
-Set the level of debug information for this object. If C<VALUE> is not given
+Set the level of debug information for this object. If C<$level> is not given
 then the current state is returned. Otherwise the state is changed to 
-C<VALUE> and the previous state returned. 
+C<$level> and the previous state returned. 
 
 Different packages
 may implement different levels of debug but a non-zero value results in 
 copies of all commands and responses also being sent to STDERR.
 
-If C<VALUE> is C<undef> then the debug level will be set to the default
+If C<$level> is C<undef> then the debug level will be set to the default
 debug level for the class.
 
 This method can also be called as a I<static> method to set/get the default
 debug level for a given class.
 
-=item message ()
+=item C<message()>
 
 Returns the text message returned from the last command. In a scalar
 context it returns a single string, in a list context it will return
 each line as a separate element. (See L<PSEUDO RESPONSES> below.)
 
-=item code ()
+=item C<code()>
 
 Returns the 3-digit code from the last command. If a command is pending
 then the value 0 is returned. (See L<PSEUDO RESPONSES> below.)
 
-=item ok ()
+=item C<ok()>
 
 Returns non-zero if the last code value was greater than zero and
 less than 400. This holds true for most command servers. Servers
 where this does not hold may override this method.
 
-=item status ()
+=item C<status()>
 
 Returns the most significant digit of the current status code. If a command
 is pending then C<CMD_PENDING> is returned.
 
-=item datasend ( DATA )
+=item C<datasend($data)>
 
 Send data to the remote server, converting LF to CRLF. Any line starting
 with a '.' will be prefixed with another '.'.
-C<DATA> may be an array or a reference to an array.
-The C<DATA> passed in must be encoded by the caller to octets of whatever
+C<$data> may be an array or a reference to an array.
+The C<$data> passed in must be encoded by the caller to octets of whatever
 encoding is required, e.g. by using the Encode module's C<encode()> function.
 
-=item dataend ()
+=item C<dataend()>
 
 End the sending of data to the remote server. This is done by ensuring that
 the data already sent ends with CRLF then sending '.CRLF' to end the
@@ -722,28 +740,28 @@ returns true if C<response> returns CMD_OK.
 
 =back
 
-=head1 CLASS METHODS
+=head2 Protected Methods
 
 These methods are not intended to be called by the user, but used or 
 over-ridden by a sub-class of C<Net::Cmd>
 
 =over 4
 
-=item debug_print ( DIR, TEXT )
+=item C<debug_print($dir, $text)>
 
-Print debugging information. C<DIR> denotes the direction I<true> being
+Print debugging information. C<$dir> denotes the direction I<true> being
 data being sent to the server. Calls C<debug_text> before printing to
 STDERR.
 
-=item debug_text ( DIR, TEXT )
+=item C<debug_text($dir, $text)>
 
-This method is called to print debugging information. TEXT is
+This method is called to print debugging information. C<$text> is
 the text being sent. The method should return the text to be printed.
 
 This is primarily meant for the use of modules such as FTP where passwords
 are sent, but we do not want to display them in the debugging information.
 
-=item command ( CMD [, ARGS, ... ])
+=item C<command($cmd[, $args, ... ])>
 
 Send a command to the command server. All arguments are first joined with
 a space character and CRLF is appended, this string is then sent to the
@@ -751,24 +769,24 @@ command server.
 
 Returns undef upon failure.
 
-=item unsupported ()
+=item C<unsupported()>
 
 Sets the status code to 580 and the response text to 'Unsupported command'.
 Returns zero.
 
-=item response ()
+=item C<response()>
 
 Obtain a response from the server. Upon success the most significant digit
 of the status code is returned. Upon failure, timeout etc., I<CMD_ERROR> is
 returned.
 
-=item parse_response ( TEXT )
+=item C<parse_response($text)>
 
 This method is called by C<response> as a method with one argument. It should
 return an array of 2 values, the 3-digit status code and a flag which is true
 when this is part of a multi-line response and this line is not the last.
 
-=item getline ()
+=item C<getline()>
 
 Retrieve one line, delimited by CRLF, from the remote server. Returns I<undef>
 upon failure.
@@ -776,26 +794,26 @@ upon failure.
 B<NOTE>: If you do use this method for any reason, please remember to add
 some C<debug_print> calls into your method.
 
-=item ungetline ( TEXT )
+=item C<ungetline($text)>
 
 Unget a line of text from the server.
 
-=item rawdatasend ( DATA )
+=item C<rawdatasend($data)>
 
-Send data to the remote server without performing any conversions. C<DATA>
+Send data to the remote server without performing any conversions. C<$data>
 is a scalar.
-As with C<datasend()>, the C<DATA> passed in must be encoded by the caller
+As with C<datasend()>, the C<$data> passed in must be encoded by the caller
 to octets of whatever encoding is required, e.g. by using the Encode module's
 C<encode()> function.
 
-=item read_until_dot ()
+=item C<read_until_dot()>
 
 Read data from the remote server until a line consisting of a single '.'.
 Any lines starting with '..' will have one of the '.'s removed.
 
 Returns a reference to a list containing the lines, or I<undef> upon failure.
 
-=item tied_fh ()
+=item C<tied_fh()>
 
 Returns a filehandle tied to the Net::Cmd object.  After issuing a
 command, you may read from this filehandle using read() or <>.  The
@@ -807,7 +825,7 @@ See the Net::POP3 and Net::SMTP modules for examples of this.
 
 =back
 
-=head1 PSEUDO RESPONSES
+=head2 Pseudo Responses
 
 Normally the values returned by C<message()> and C<code()> are
 obtained from the remote server, but in a few circumstances, as
@@ -847,22 +865,47 @@ or otherwise trap this error.
 
 =head1 EXPORTS
 
-C<Net::Cmd> exports six subroutines, five of these, C<CMD_INFO>, C<CMD_OK>,
-C<CMD_MORE>, C<CMD_REJECT> and C<CMD_ERROR>, correspond to possible results
-of C<response> and C<status>. The sixth is C<CMD_PENDING>.
+The following symbols are, or can be, exported by this module:
+
+=over 4
+
+=item Default Exports
+
+C<CMD_INFO>,
+C<CMD_OK>,
+C<CMD_MORE>,
+C<CMD_REJECT>,
+C<CMD_ERROR>,
+C<CMD_PENDING>.
+
+(These correspond to possible results of C<response()> and C<status()>.)
+
+=item Optional Exports
+
+I<None>.
+
+=item Export Tags
+
+I<None>.
+
+=back
+
+=head1 KNOWN BUGS
+
+See L<https://rt.cpan.org/Dist/Display.html?Status=Active&Queue=libnet>.
 
 =head1 AUTHOR
 
-Graham Barr E<lt>F<gbarr@pobox.com>E<gt>.
+Graham Barr E<lt>L<gbarr@pobox.com|mailto:gbarr@pobox.com>E<gt>.
 
-Steve Hay E<lt>F<shay@cpan.org>E<gt> is now maintaining libnet as of version
-1.22_02.
+Steve Hay E<lt>L<shay@cpan.org|mailto:shay@cpan.org>E<gt> is now maintaining
+libnet as of version 1.22_02.
 
 =head1 COPYRIGHT
 
 Copyright (C) 1995-2006 Graham Barr.  All rights reserved.
 
-Copyright (C) 2013-2016 Steve Hay.  All rights reserved.
+Copyright (C) 2013-2016, 2020 Steve Hay.  All rights reserved.
 
 =head1 LICENCE
 
@@ -870,4 +913,16 @@ This module is free software; you can redistribute it and/or modify it under the
 same terms as Perl itself, i.e. under the terms of either the GNU General Public
 License or the Artistic License, as specified in the F<LICENCE> file.
 
+=head1 VERSION
+
+Version 3.12
+
+=head1 DATE
+
+09 Dec 2020
+
+=head1 HISTORY
+
+See the F<Changes> file.
+
 =cut
index 4f822a4..365cb49 100644 (file)
@@ -1,7 +1,7 @@
 # Net::Config.pm
 #
 # Copyright (C) 2000 Graham Barr.  All rights reserved.
-# Copyright (C) 2013-2014, 2016 Steve Hay.  All rights reserved.
+# Copyright (C) 2013-2014, 2016, 2020 Steve Hay.  All rights reserved.
 # This module is free software; you can redistribute it and/or modify it under
 # the same terms as Perl itself, i.e. under the terms of either the GNU General
 # Public License or the Artistic License, as specified in the F<LICENCE> file.
@@ -18,7 +18,7 @@ use Socket qw(inet_aton inet_ntoa);
 
 our @EXPORT  = qw(%NetConfig);
 our @ISA     = qw(Net::LocalCfg Exporter);
-our $VERSION = "3.11";
+our $VERSION = "3.12";
 
 our($CONFIGURE, $LIBNET_CFG);
 
@@ -159,7 +159,7 @@ For example
     }
     __END__
 
-=head1 METHODS
+=head2 Class Methods
 
 C<Net::Config> defines the following methods. They are methods as they are
 invoked as class methods. This is because C<Net::Config> inherits from
@@ -167,7 +167,7 @@ C<Net::LocalCfg> so you can override these methods if you want.
 
 =over 4
 
-=item requires_firewall ( HOST )
+=item C<requires_firewall($host)>
 
 Attempts to determine if a given host is outside your firewall. Possible
 return values are.
@@ -181,7 +181,7 @@ the configuration data.
 
 =back
 
-=head1 NetConfig VALUES
+=head2 NetConfig Values
 
 =over 4
 
@@ -323,18 +323,42 @@ If true then C<Configure> will check each hostname given that it exists
 
 =back
 
+=head1 EXPORTS
+
+The following symbols are, or can be, exported by this module:
+
+=over 4
+
+=item Default Exports
+
+C<%NetConfig>.
+
+=item Optional Exports
+
+I<None>.
+
+=item Export Tags
+
+I<None>.
+
+=back
+
+=head1 KNOWN BUGS
+
+I<None>.
+
 =head1 AUTHOR
 
-Graham Barr E<lt>F<gbarr@pobox.com>E<gt>.
+Graham Barr E<lt>L<gbarr@pobox.com|mailto:gbarr@pobox.com>E<gt>.
 
-Steve Hay E<lt>F<shay@cpan.org>E<gt> is now maintaining libnet as of version
-1.22_02.
+Steve Hay E<lt>L<shay@cpan.org|mailto:shay@cpan.org>E<gt> is now maintaining
+libnet as of version 1.22_02.
 
 =head1 COPYRIGHT
 
-Copyright (C) 1998-2011 Graham Barr.  All rights reserved.
+Copyright (C) 2000 Graham Barr.  All rights reserved.
 
-Copyright (C) 2013-2014, 2016 Steve Hay.  All rights reserved.
+Copyright (C) 2013-2014, 2016, 2020 Steve Hay.  All rights reserved.
 
 =head1 LICENCE
 
@@ -342,4 +366,16 @@ This module is free software; you can redistribute it and/or modify it under the
 same terms as Perl itself, i.e. under the terms of either the GNU General Public
 License or the Artistic License, as specified in the F<LICENCE> file.
 
+=head1 VERSION
+
+Version 3.12
+
+=head1 DATE
+
+09 Dec 2020
+
+=head1 HISTORY
+
+See the F<Changes> file.
+
 =cut
index 556cc15..f4c93ea 100644 (file)
@@ -1,7 +1,7 @@
 # Net::Domain.pm
 #
 # Copyright (C) 1995-1998 Graham Barr.  All rights reserved.
-# Copyright (C) 2013-2014 Steve Hay.  All rights reserved.
+# Copyright (C) 2013-2014, 2020 Steve Hay.  All rights reserved.
 # This module is free software; you can redistribute it and/or modify it under
 # the same terms as Perl itself, i.e. under the terms of either the GNU General
 # Public License or the Artistic License, as specified in the F<LICENCE> file.
@@ -19,7 +19,7 @@ use Net::Config;
 
 our @ISA       = qw(Exporter);
 our @EXPORT_OK = qw(hostname hostdomain hostfqdn domainname);
-our $VERSION = "3.11";
+our $VERSION = "3.12";
 
 my ($host, $domain, $fqdn) = (undef, undef, undef);
 
@@ -321,40 +321,71 @@ of the current host. From this determine the host-name and the host-domain.
 
 Each of the functions will return I<undef> if the FQDN cannot be determined.
 
+=head2 Functions
+
 =over 4
 
-=item hostfqdn ()
+=item C<hostfqdn()>
 
 Identify and return the FQDN of the current host.
 
-=item domainname ()
+=item C<domainname()>
 
-An alias for hostfqdn ().
+An alias for hostfqdn().
 
-=item hostname ()
+=item C<hostname()>
 
 Returns the smallest part of the FQDN which can be used to identify the host.
 
-=item hostdomain ()
+=item C<hostdomain()>
 
 Returns the remainder of the FQDN after the I<hostname> has been removed.
 
 =back
 
+=head1 EXPORTS
+
+The following symbols are, or can be, exported by this module:
+
+=over 4
+
+=item Default Exports
+
+I<None>.
+
+=item Optional Exports
+
+C<hostname>,
+C<hostdomain>,
+C<hostfqdn>,
+C<domainname>.
+
+=item Export Tags
+
+I<None>.
+
+=back
+
+
+=head1 KNOWN BUGS
+
+See L<https://rt.cpan.org/Dist/Display.html?Status=Active&Queue=libnet>.
+
 =head1 AUTHOR
 
-Graham Barr E<lt>F<gbarr@pobox.com>E<gt>.
+Graham Barr E<lt>L<gbarr@pobox.com|mailto:gbarr@pobox.com>E<gt>.
 
-Adapted from Sys::Hostname by David Sundstrom E<lt>F<sunds@asictest.sc.ti.com>E<gt>.
+Adapted from Sys::Hostname by David Sundstrom
+E<lt>L<sunds@asictest.sc.ti.com|mailto:sunds@asictest.sc.ti.com>E<gt>.
 
-Steve Hay E<lt>F<shay@cpan.org>E<gt> is now maintaining libnet as of version
-1.22_02.
+Steve Hay E<lt>L<shay@cpan.org|mailto:shay@cpan.org>E<gt> is now maintaining
+libnet as of version 1.22_02.
 
 =head1 COPYRIGHT
 
 Copyright (C) 1995-1998 Graham Barr.  All rights reserved.
 
-Copyright (C) 2013-2014 Steve Hay.  All rights reserved.
+Copyright (C) 2013-2014, 2020 Steve Hay.  All rights reserved.
 
 =head1 LICENCE
 
@@ -362,4 +393,16 @@ This module is free software; you can redistribute it and/or modify it under the
 same terms as Perl itself, i.e. under the terms of either the GNU General Public
 License or the Artistic License, as specified in the F<LICENCE> file.
 
+=head1 VERSION
+
+Version 3.12
+
+=head1 DATE
+
+09 Dec 2020
+
+=head1 HISTORY
+
+See the F<Changes> file.
+
 =cut
index 14153be..b195c9c 100644 (file)
@@ -1,7 +1,7 @@
 # Net::FTP.pm
 #
 # Copyright (C) 1995-2004 Graham Barr.  All rights reserved.
-# Copyright (C) 2013-2017 Steve Hay.  All rights reserved.
+# Copyright (C) 2013-2017, 2020 Steve Hay.  All rights reserved.
 # This module is free software; you can redistribute it and/or modify it under
 # the same terms as Perl itself, i.e. under the terms of either the GNU General
 # Public License or the Artistic License, as specified in the F<LICENCE> file.
@@ -23,7 +23,7 @@ use Net::Config;
 use Socket;
 use Time::Local;
 
-our $VERSION = '3.11';
+our $VERSION = '3.12';
 
 our $IOCLASS;
 my $family_key;
@@ -110,10 +110,13 @@ sub new {
       # use SNI if supported by IO::Socket::SSL
       $pkg->can_client_sni ? (SSL_hostname => $hostname):(),
       # reuse SSL session of control connection in data connections
-      SSL_session_cache => Net::FTP::_SSL_SingleSessionCache->new,
+      SSL_session_cache_size => 10,
+      SSL_session_key => $hostname,
     );
     # user defined SSL arg
     $tlsargs{$_} = $arg{$_} for(grep { m{^SSL_} } keys %arg);
+    $tlsargs{SSL_reuse_ctx} = IO::Socket::SSL::SSL_Context->new(%tlsargs)
+      or return;
 
   } elsif ($arg{SSL}) {
     croak("IO::Socket::SSL >= 2.007 needed for SSL support");
@@ -262,7 +265,7 @@ sub mdtm {
 
   $ftp->_MDTM($file)
     && $ftp->message =~ /((\d\d)(\d\d\d?))(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/
-    ? timegm($8, $7, $6, $5, $4 - 1, $2 eq '19' ? $3 : ($1 - 1900))
+    ? timegm($8, $7, $6, $5, $4 - 1, $2 eq '19' ? ($3 + 1900) : $1)
     : undef;
 }
 
@@ -426,7 +429,7 @@ sub login {
 
 
 sub account {
-  @_ == 2 or croak 'usage: $ftp->account( ACCT )';
+  @_ == 2 or croak 'usage: $ftp->account($acct)';
   my $ftp  = shift;
   my $acct = shift;
   $ftp->_ACCT($acct) == CMD_OK;
@@ -452,7 +455,7 @@ sub _auth_id {
 
 
 sub authorize {
-  @_ >= 1 || @_ <= 3 or croak 'usage: $ftp->authorize( [AUTH [, RESP]])';
+  @_ >= 1 || @_ <= 3 or croak 'usage: $ftp->authorize([$auth[, $resp]])';
 
   my ($ftp, $auth, $resp) = &_auth_id;
 
@@ -466,12 +469,12 @@ sub authorize {
 
 
 sub rename {
-  @_ == 3 or croak 'usage: $ftp->rename(FROM, TO)';
+  @_ == 3 or croak 'usage: $ftp->rename($oldname, $newname)';
 
-  my ($ftp, $from, $to) = @_;
+  my ($ftp, $oldname, $newname) = @_;
 
-  $ftp->_RNFR($from)
-    && $ftp->_RNTO($to);
+  $ftp->_RNFR($oldname)
+    && $ftp->_RNTO($newname);
 }
 
 
@@ -619,7 +622,7 @@ sub get {
 
 
 sub cwd {
-  @_ == 1 || @_ == 2 or croak 'usage: $ftp->cwd( [ DIR ] )';
+  @_ == 1 || @_ == 2 or croak 'usage: $ftp->cwd([$dir])';
 
   my ($ftp, $dir) = @_;
 
@@ -656,7 +659,7 @@ sub pwd {
 # Initial version contributed by Dinkum Software
 #
 sub rmdir {
-  @_ == 2 || @_ == 3 or croak('usage: $ftp->rmdir( DIR [, RECURSE ] )');
+  @_ == 2 || @_ == 3 or croak('usage: $ftp->rmdir($dir[, $recurse])');
 
   # Pick off the args
   my ($ftp, $dir, $recurse) = @_;
@@ -702,7 +705,7 @@ sub rmdir {
 
 
 sub restart {
-  @_ == 2 || croak 'usage: $ftp->restart( BYTE_OFFSET )';
+  @_ == 2 || croak 'usage: $ftp->restart($where)';
 
   my ($ftp, $where) = @_;
 
@@ -713,7 +716,7 @@ sub restart {
 
 
 sub mkdir {
-  @_ == 2 || @_ == 3 or croak 'usage: $ftp->mkdir( DIR [, RECURSE ] )';
+  @_ == 2 || @_ == 3 or croak 'usage: $ftp->mkdir($dir[, $recurse])';
 
   my ($ftp, $dir, $recurse) = @_;
 
@@ -758,7 +761,7 @@ sub mkdir {
 
 
 sub delete {
-  @_ == 2 || croak 'usage: $ftp->delete( FILENAME )';
+  @_ == 2 || croak 'usage: $ftp->delete($filename)';
 
   $_[0]->_DELE($_[1]);
 }
@@ -881,12 +884,12 @@ sub _store_cmd {
 
 
 sub port {
-    @_ == 1 || @_ == 2 or croak 'usage: $self->port([PORT])';
+    @_ == 1 || @_ == 2 or croak 'usage: $self->port([$port])';
     return _eprt('PORT',@_);
 }
 
 sub eprt {
-  @_ == 1 || @_ == 2 or croak 'usage: $self->eprt([PORT])';
+  @_ == 1 || @_ == 2 or croak 'usage: $self->eprt([$port])';
   return _eprt('EPRT',@_);
 }
 
@@ -959,7 +962,7 @@ sub unique_name {
 
 
 sub supported {
-  @_ == 2 or croak 'usage: $ftp->supported( CMD )';
+  @_ == 2 or croak 'usage: $ftp->supported($cmd)';
   my $ftp  = shift;
   my $cmd  = uc shift;
   my $hash = ${*$ftp}{'net_ftp_supported'} ||= {};
@@ -1282,36 +1285,36 @@ sub pasv_xfer {
 
 
 sub pasv_wait {
-  @_ == 2 or croak 'usage: $ftp->pasv_wait(NON_PASV_FTP)';
+  @_ == 2 or croak 'usage: $ftp->pasv_wait($non_pasv_server)';
 
-  my ($ftp, $non_pasv) = @_;
+  my ($ftp, $non_pasv_server) = @_;
   my ($file, $rin, $rout);
 
   vec($rin = '', fileno($ftp), 1) = 1;
   select($rout = $rin, undef, undef, undef);
 
   my $dres = $ftp->response();
-  my $sres = $non_pasv->response();
+  my $sres = $non_pasv_server->response();
 
   return
     unless $dres == CMD_OK && $sres == CMD_OK;
 
   return
-    unless $ftp->ok() && $non_pasv->ok();
+    unless $ftp->ok() && $non_pasv_server->ok();
 
   return $1
     if $ftp->message =~ /unique file name:\s*(\S*)\s*\)/;
 
   return $1
-    if $non_pasv->message =~ /unique file name:\s*(\S*)\s*\)/;
+    if $non_pasv_server->message =~ /unique file name:\s*(\S*)\s*\)/;
 
   return 1;
 }
 
 
 sub feature {
-  @_ == 2 or croak 'usage: $ftp->feature( NAME )';
-  my ($ftp, $feat) = @_;
+  @_ == 2 or croak 'usage: $ftp->feature($name)';
+  my ($ftp, $name) = @_;
 
   my $feature = ${*$ftp}{net_ftp_feature} ||= do {
     my @feat;
@@ -1329,7 +1332,7 @@ sub feature {
     \@feat;
   };
 
-  return grep { /^\Q$feat\E\b/i } @$feature;
+  return grep { /^\Q$name\E\b/i } @$feature;
 }
 
 
@@ -1397,25 +1400,6 @@ sub _SYST { shift->unsupported(@_) }
 sub _STRU { shift->unsupported(@_) }
 sub _REIN { shift->unsupported(@_) }
 
-{
-  # Session Cache with single entry
-  # used to make sure that we reuse same session for control and data channels
-  package Net::FTP::_SSL_SingleSessionCache;
-  sub new { my $x; return bless \$x,shift }
-  sub add_session {
-    my ($cache,$key,$session) = @_;
-    Net::SSLeay::SESSION_free($$cache) if $$cache;
-    $$cache = $session;
-  }
-  sub get_session {
-    my $cache = shift;
-    return $$cache
-  }
-  sub DESTROY {
-    my $cache = shift;
-    Net::SSLeay::SESSION_free($$cache) if $$cache;
-  }
-}
 
 1;
 
@@ -1456,7 +1440,7 @@ and explicit FTPS as defined in RFC4217.
 The Net::FTP class is a subclass of Net::Cmd and (depending on avaibility) of
 IO::Socket::IP, IO::Socket::INET6 or IO::Socket::INET.
 
-=head1 OVERVIEW
+=head2 Overview
 
 FTP stands for File Transfer Protocol.  It is a way of transferring
 files between networked machines.  The protocol defines a client
@@ -1487,19 +1471,19 @@ this if you really know what you're doing).  This class does not support
 the EBCDIC or byte formats, and will default to binary instead if they
 are attempted.
 
-=head1 CONSTRUCTOR
+=head2 Class Methods
 
 =over 4
 
-=item new ([ HOST ] [, OPTIONS ])
+=item C<new([$host][, %options])>
 
-This is the constructor for a new Net::FTP object. C<HOST> is the
+This is the constructor for a new Net::FTP object. C<$host> is the
 name of the remote host to which an FTP connection is required.
 
-C<HOST> is optional. If C<HOST> is not given then it may instead be
+C<$host> is optional. If C<$host> is not given then it may instead be
 passed as the C<Host> option described below. 
 
-C<OPTIONS> are passed in a hash like fashion, using key and value pairs.
+C<%options> are passed in a hash like fashion, using key and value pairs.
 Possible options are:
 
 B<Host> - FTP host to connect to. It may be a single scalar, as defined for
@@ -1570,7 +1554,7 @@ be in $@
 
 =back
 
-=head1 METHODS
+=head2 Object Methods
 
 Unless otherwise stated all methods return either a I<true> or I<false>
 value, with I<true> meaning that the operation was a success. When a method
@@ -1583,7 +1567,7 @@ documented here.
 
 =over 4
 
-=item login ([LOGIN [,PASSWORD [, ACCOUNT] ] ])
+=item C<login([$login[, $password[, $account]]])>
 
 Log into the remote FTP server with the given login information. If
 no arguments are given then the C<Net::FTP> uses the C<Net::Netrc>
@@ -1595,114 +1579,114 @@ will be used for password.
 If the connection is via a firewall then the C<authorize> method will
 be called with no arguments.
 
-=item starttls ()
+=item C<starttls()>
 
 Upgrade existing plain connection to SSL.
 The SSL arguments have to be given in C<new> already because they are needed for
 data connections too.
 
-=item stoptls ()
+=item C<stoptls()>
 
 Downgrade existing SSL connection back to plain.
 This is needed to work with some FTP helpers at firewalls, which need to see the
 PORT and PASV commands and responses to dynamically open the necessary ports.
 In this case C<starttls> is usually only done to protect the authorization.
 
-=item prot ( LEVEL )
+=item C<prot($level)>
 
 Set what type of data channel protection the client and server will be using.
-Only C<LEVEL>s "C" (clear) and "P" (private) are supported.
+Only C<$level>s "C" (clear) and "P" (private) are supported.
 
-=item host ()
+=item C<host()>
 
 Returns the value used by the constructor, and passed to the IO::Socket super
 class to connect to the host.
 
-=item account( ACCT )
+=item C<account($acct)>
 
 Set a string identifying the user's account.
 
-=item authorize ( [AUTH [, RESP]])
+=item C<authorize([$auth[, $resp]])>
 
 This is a protocol used by some firewall ftp proxies. It is used
 to authorise the user to send data out.  If both arguments are not specified
 then C<authorize> uses C<Net::Netrc> to do a lookup.
 
-=item site (ARGS)
+=item C<site($args)>
 
 Send a SITE command to the remote server and wait for a response.
 
 Returns most significant digit of the response code.
 
-=item ascii ()
+=item C<ascii()>
 
 Transfer file in ASCII. CRLF translation will be done if required
 
-=item binary ()
+=item C<binary()>
 
 Transfer file in binary mode. No transformation will be done.
 
 B<Hint>: If both server and client machines use the same line ending for
 text files, then it will be faster to transfer all files in binary mode.
 
-=item type ( [ TYPE ] )
+=item C<type([$type])>
 
 Set or get if files will be transferred in ASCII or binary mode.
 
-=item rename ( OLDNAME, NEWNAME )
+=item C<rename($oldname, $newname)>
 
-Rename a file on the remote FTP server from C<OLDNAME> to C<NEWNAME>. This
+Rename a file on the remote FTP server from C<$oldname> to C<$newname>. This
 is done by sending the RNFR and RNTO commands.
 
-=item delete ( FILENAME )
+=item C<delete($filename)>
 
-Send a request to the server to delete C<FILENAME>.
+Send a request to the server to delete C<$filename>.
 
-=item cwd ( [ DIR ] )
+=item C<cwd([$dir])>
 
 Attempt to change directory to the directory given in C<$dir>.  If
 C<$dir> is C<"..">, the FTP C<CDUP> command is used to attempt to
 move up one directory. If no directory is given then an attempt is made
 to change the directory to the root directory.
 
-=item cdup ()
+=item C<cdup()>
 
 Change directory to the parent of the current directory.
 
-=item passive ( [ PASSIVE ] )
+=item C<passive([$passive])>
 
 Set or get if data connections will be initiated in passive mode.
 
-=item pwd ()
+=item C<pwd()>
 
 Returns the full pathname of the current directory.
 
-=item restart ( WHERE )
+=item C<restart($where)>
 
 Set the byte offset at which to begin the next data transfer. Net::FTP simply
 records this value and uses it when during the next data transfer. For this
 reason this method will not return an error, but setting it may cause
 a subsequent data transfer to fail.
 
-=item rmdir ( DIR [, RECURSE ])
+=item C<rmdir($dir[, $recurse])>
 
-Remove the directory with the name C<DIR>. If C<RECURSE> is I<true> then
+Remove the directory with the name C<$dir>. If C<$recurse> is I<true> then
 C<rmdir> will attempt to delete everything inside the directory.
 
-=item mkdir ( DIR [, RECURSE ])
+=item C<mkdir($dir[, $recurse])>
 
-Create a new directory with the name C<DIR>. If C<RECURSE> is I<true> then
+Create a new directory with the name C<$dir>. If C<$recurse> is I<true> then
 C<mkdir> will attempt to create all the directories in the given path.
 
 Returns the full pathname to the new directory.
 
-=item alloc ( SIZE [, RECORD_SIZE] )
+=item C<alloc($size[, $record_size])>
 
 The alloc command allows you to give the ftp server a hint about the size
 of the file about to be transferred using the ALLO ftp command. Some storage
 systems use this to make intelligent decisions about how to store the file.
-The C<SIZE> argument represents the size of the file in bytes. The
-C<RECORD_SIZE> argument indicates a maximum record or page size for files
+The C<$size> argument represents the size of the file in bytes. The
+C<$record_size> argument indicates a maximum record or page size for files
 sent with a record or page structure.
 
 The size of the file will be determined, and sent to the server
@@ -1710,70 +1694,70 @@ automatically for normal files so that this method need only be called if
 you are transferring data from a socket, named pipe, or other stream not
 associated with a normal file.
 
-=item ls ( [ DIR ] )
+=item C<ls([$dir])>
 
-Get a directory listing of C<DIR>, or the current directory.
+Get a directory listing of C<$dir>, or the current directory.
 
 In an array context, returns a list of lines returned from the server. In
 a scalar context, returns a reference to a list.
 
-=item dir ( [ DIR ] )
+=item C<dir([$dir])>
 
-Get a directory listing of C<DIR>, or the current directory in long format.
+Get a directory listing of C<$dir>, or the current directory in long format.
 
 In an array context, returns a list of lines returned from the server. In
 a scalar context, returns a reference to a list.
 
-=item get ( REMOTE_FILE [, LOCAL_FILE [, WHERE]] )
+=item C<get($remote_file[, $local_file[, $where]])>
 
-Get C<REMOTE_FILE> from the server and store locally. C<LOCAL_FILE> may be
+Get C<$remote_file> from the server and store locally. C<$local_file> may be
 a filename or a filehandle. If not specified, the file will be stored in
 the current directory with the same leafname as the remote file.
 
-If C<WHERE> is given then the first C<WHERE> bytes of the file will
+If C<$where> is given then the first C<$where> bytes of the file will
 not be transferred, and the remaining bytes will be appended to
 the local file if it already exists.
 
-Returns C<LOCAL_FILE>, or the generated local file name if C<LOCAL_FILE>
+Returns C<$local_file>, or the generated local file name if C<$local_file>
 is not given. If an error was encountered undef is returned.
 
-=item put ( LOCAL_FILE [, REMOTE_FILE ] )
+=item C<put($local_file[, $remote_file])>
 
-Put a file on the remote server. C<LOCAL_FILE> may be a name or a filehandle.
-If C<LOCAL_FILE> is a filehandle then C<REMOTE_FILE> must be specified. If
-C<REMOTE_FILE> is not specified then the file will be stored in the current
-directory with the same leafname as C<LOCAL_FILE>.
+Put a file on the remote server. C<$local_file> may be a name or a filehandle.
+If C<$local_file> is a filehandle then C<$remote_file> must be specified. If
+C<$remote_file> is not specified then the file will be stored in the current
+directory with the same leafname as C<$local_file>.
 
-Returns C<REMOTE_FILE>, or the generated remote filename if C<REMOTE_FILE>
+Returns C<$remote_file>, or the generated remote filename if C<$remote_file>
 is not given.
 
 B<NOTE>: If for some reason the transfer does not complete and an error is
 returned then the contents that had been transferred will not be remove
 automatically.
 
-=item put_unique ( LOCAL_FILE [, REMOTE_FILE ] )
+=item C<put_unique($local_file[, $remote_file])>
 
 Same as put but uses the C<STOU> command.
 
 Returns the name of the file on the server.
 
-=item append ( LOCAL_FILE [, REMOTE_FILE ] )
+=item C<append($local_file[, $remote_file])>
 
 Same as put but appends to the file on the remote server.
 
-Returns C<REMOTE_FILE>, or the generated remote filename if C<REMOTE_FILE>
+Returns C<$remote_file>, or the generated remote filename if C<$remote_file>
 is not given.
 
-=item unique_name ()
+=item C<unique_name()>
 
 Returns the name of the last file stored on the server using the
 C<STOU> command.
 
-=item mdtm ( FILE )
+=item C<mdtm($file)>
 
 Returns the I<modification time> of the given file
 
-=item size ( FILE )
+=item C<size($file)>
 
 Returns the size in bytes for the given file as stored on the remote server.
 
@@ -1783,11 +1767,11 @@ and the remote server and local machine have different ideas about
 "End Of Line" then the size of file on the local machine after transfer
 may be different.
 
-=item supported ( CMD )
+=item C<supported($cmd)>
 
 Returns TRUE if the remote server supports the given command.
 
-=item hash ( [FILEHANDLE_GLOB_REF],[ BYTES_PER_HASH_MARK] )
+=item C<hash([$filehandle_glob_ref[, $bytes_per_hash_mark]])>
 
 Called without parameters, or with the first argument false, hash marks
 are suppressed.  If the first argument is true but not a reference to a 
@@ -1796,7 +1780,7 @@ of bytes per hash mark printed, and defaults to 1024.  In all cases the
 return value is a reference to an array of two:  the filehandle glob reference
 and the bytes per hash mark.
 
-=item feature ( NAME )
+=item C<feature($name)>
 
 Determine if the server supports the specified feature. The return
 value is a list of lines the server responded with to describe the
@@ -1822,33 +1806,33 @@ reference to a C<Net::FTP::dataconn> based object.
 
 =over 4
 
-=item nlst ( [ DIR ] )
+=item C<nlst([$dir])>
 
 Send an C<NLST> command to the server, with an optional parameter.
 
-=item list ( [ DIR ] )
+=item C<list([$dir])>
 
 Same as C<nlst> but using the C<LIST> command
 
-=item retr ( FILE )
+=item C<retr($file)>
 
-Begin the retrieval of a file called C<FILE> from the remote server.
+Begin the retrieval of a file called C<$file> from the remote server.
 
-=item stor ( FILE )
+=item C<stor($file)>
 
-Tell the server that you wish to store a file. C<FILE> is the
+Tell the server that you wish to store a file. C<$file> is the
 name of the new file that should be created.
 
-=item stou ( FILE )
+=item C<stou($file)>
 
 Same as C<stor> but using the C<STOU> command. The name of the unique
 file which was created on the server will be available via the C<unique_name>
 method after the data connection has been closed.
 
-=item appe ( FILE )
+=item C<appe($file)>
 
 Tell the server that we want to append some data to the end of a file
-called C<FILE>. If this file does not exist then create it.
+called C<$file>. If this file does not exist then create it.
 
 =back
 
@@ -1862,17 +1846,17 @@ C<put_unique> and those that do not require data connections.
 
 =over 4
 
-=item port ( [ PORT ] )
+=item C<port([$port])>
 
-=item eprt ( [ PORT ] )
+=item C<eprt([$port])>
 
-Send a C<PORT> (IPv4) or C<EPRT> (IPv6) command to the server. If C<PORT> is
+Send a C<PORT> (IPv4) or C<EPRT> (IPv6) command to the server. If C<$port> is
 specified then it is sent to the server. If not, then a listen socket is created
 and the correct information sent to the server.
 
-=item pasv ()
+=item C<pasv()>
 
-=item epsv ()
+=item C<epsv()>
 
 Tell the server to go into passive mode (C<pasv> for IPv4, C<epsv> for IPv6).
 Returns the text that represents the port on which the server is listening, this
@@ -1886,38 +1870,38 @@ servers, providing that these two servers can connect directly to each other.
 
 =over 4
 
-=item pasv_xfer ( SRC_FILE, DEST_SERVER [, DEST_FILE ] )
+=item C<pasv_xfer($src_file, $dest_server[, $dest_file ])>
 
 This method will do a file transfer between two remote ftp servers. If
-C<DEST_FILE> is omitted then the leaf name of C<SRC_FILE> will be used.
+C<$dest_file> is omitted then the leaf name of C<$src_file> will be used.
 
-=item pasv_xfer_unique ( SRC_FILE, DEST_SERVER [, DEST_FILE ] )
+=item C<pasv_xfer_unique($src_file, $dest_server[, $dest_file ])>
 
 Like C<pasv_xfer> but the file is stored on the remote server using
 the STOU command.
 
-=item pasv_wait ( NON_PASV_SERVER )
+=item C<pasv_wait($non_pasv_server)>
 
 This method can be used to wait for a transfer to complete between a passive
 server and a non-passive server. The method should be called on the passive
 server with the C<Net::FTP> object for the non-passive server passed as an
 argument.
 
-=item abort ()
+=item C<abort()>
 
 Abort the current data transfer.
 
-=item quit ()
+=item C<quit()>
 
 Send the QUIT command to the remote FTP server and close the socket connection.
 
 =back
 
-=head2 Methods for the adventurous
+=head2 Methods for the Adventurous
 
 =over 4
 
-=item quot (CMD [,ARGS])
+=item C<quot($cmd[, $args])>
 
 Send a command, that Net::FTP does not directly support, to the remote
 server and wait for a response.
@@ -1927,62 +1911,83 @@ Returns most significant digit of the response code.
 B<WARNING> This call should only be used on commands that do not require
 data connections. Misuse of this method can hang the connection.
 
-=item can_inet6 ()
+=item C<can_inet6()>
 
 Returns whether we can use IPv6.
 
-=item can_ssl ()
+=item C<can_ssl()>
 
 Returns whether we can use SSL.
 
 =back
 
-=head1 THE dataconn CLASS
+=head2 The dataconn Class
 
 Some of the methods defined in C<Net::FTP> return an object which will
 be derived from the C<Net::FTP::dataconn> class. See L<Net::FTP::dataconn> for
 more details.
 
-=head1 UNIMPLEMENTED
+=head2 Unimplemented
 
 The following RFC959 commands have not been implemented:
 
 =over 4
 
-=item B<SMNT>
+=item C<SMNT>
 
 Mount a different file system structure without changing login or
 accounting information.
 
-=item B<HELP>
+=item C<HELP>
 
 Ask the server for "helpful information" (that's what the RFC says) on
 the commands it accepts.
 
-=item B<MODE>
+=item C<MODE>
 
 Specifies transfer mode (stream, block or compressed) for file to be
 transferred.
 
-=item B<SYST>
+=item C<SYST>
 
 Request remote server system identification.
 
-=item B<STAT>
+=item C<STAT>
 
 Request remote server status.
 
-=item B<STRU>
+=item C<STRU>
 
 Specifies file structure for file to be transferred.
 
-=item B<REIN>
+=item C<REIN>
 
 Reinitialize the connection, flushing all I/O and account information.
 
 =back
 
-=head1 REPORTING BUGS
+=head1 EXAMPLES
+
+For an example of the use of Net::FTP see
+
+=over 4
+
+=item L<https://www.csh.rit.edu/~adam/Progs/>
+
+C<autoftp> is a program that can retrieve, send, or list files via
+the FTP protocol in a non-interactive manner.
+
+=back
+
+=head1 EXPORTS
+
+I<None>.
+
+=head1 KNOWN BUGS
+
+See L<https://rt.cpan.org/Dist/Display.html?Status=Active&Queue=libnet>.
+
+=head2 Reporting Bugs
 
 When reporting bugs/problems please include as much information as possible.
 It may be difficult for me to reproduce the problem as almost every setup
@@ -1994,51 +1999,42 @@ passed to the constructor, and the output sent with the bug report. If you
 cannot include a small script then please include a Debug trace from a
 run of your program which does yield the problem.
 
-=head1 AUTHOR
-
-Graham Barr E<lt>F<gbarr@pobox.com>E<gt>.
-
-Steve Hay E<lt>F<shay@cpan.org>E<gt> is now maintaining libnet as of version
-1.22_02.
-
 =head1 SEE ALSO
 
 L<Net::Netrc>,
 L<Net::Cmd>,
-L<IO::Socket::SSL>
+L<IO::Socket::SSL>;
 
-ftp(1), ftpd(8), RFC 959, RFC 2428, RFC 4217
-http://www.ietf.org/rfc/rfc959.txt
-http://www.ietf.org/rfc/rfc2428.txt
-http://www.ietf.org/rfc/rfc4217.txt
+L<ftp(1)>,
+L<ftpd(8)>;
 
-=head1 USE EXAMPLES
+L<https://www.ietf.org/rfc/rfc959.txt>,
+L<https://www.ietf.org/rfc/rfc2428.txt>,
+L<https://www.ietf.org/rfc/rfc4217.txt>.
 
-For an example of the use of Net::FTP see
+=head1 ACKNOWLEDGEMENTS
 
-=over 4
+Henry Gabryjelski E<lt>L<henryg@WPI.EDU|mailto:henryg@WPI.EDU>E<gt> - for the
+suggestion of creating directories recursively.
 
-=item http://www.csh.rit.edu/~adam/Progs/
+Nathan Torkington E<lt>L<gnat@frii.com|mailto:gnat@frii.com>E<gt> - for some
+input on the documentation.
 
-C<autoftp> is a program that can retrieve, send, or list files via
-the FTP protocol in a non-interactive manner.
+Roderick Schertler E<lt>L<roderick@gate.net|mailto:roderick@gate.net>E<gt> - for
+various inputs
 
-=back
-
-=head1 CREDITS
-
-Henry Gabryjelski <henryg@WPI.EDU> - for the suggestion of creating directories
-recursively.
+=head1 AUTHOR
 
-Nathan Torkington <gnat@frii.com> - for some input on the documentation.
+Graham Barr E<lt>L<gbarr@pobox.com|mailto:gbarr@pobox.com>E<gt>.
 
-Roderick Schertler <roderick@gate.net> - for various inputs
+Steve Hay E<lt>L<shay@cpan.org|mailto:shay@cpan.org>E<gt> is now maintaining
+libnet as of version 1.22_02.
 
 =head1 COPYRIGHT
 
 Copyright (C) 1995-2004 Graham Barr.  All rights reserved.
 
-Copyright (C) 2013-2017 Steve Hay.  All rights reserved.
+Copyright (C) 2013-2017, 2020 Steve Hay.  All rights reserved.
 
 =head1 LICENCE
 
@@ -2046,4 +2042,16 @@ This module is free software; you can redistribute it and/or modify it under the
 same terms as Perl itself, i.e. under the terms of either the GNU General Public
 License or the Artistic License, as specified in the F<LICENCE> file.
 
+=head1 VERSION
+
+Version 3.12
+
+=head1 DATE
+
+09 Dec 2020
+
+=head1 HISTORY
+
+See the F<Changes> file.
+
 =cut
index 0ea1ba2..f22c974 100644 (file)
@@ -13,7 +13,7 @@ use Carp;
 use Net::FTP::dataconn;
 
 our @ISA     = qw(Net::FTP::dataconn);
-our $VERSION = "3.11";
+our $VERSION = "3.12";
 
 our $buf;
 
index 30b371a..df281c0 100644 (file)
@@ -8,6 +8,6 @@ use warnings;
 use Net::FTP::I;
 
 our @ISA = qw(Net::FTP::I);
-our $VERSION = "3.11";
+our $VERSION = "3.12";
 
 1;
index ec46ab0..8f85e0e 100644 (file)
@@ -13,7 +13,7 @@ use Carp;
 use Net::FTP::dataconn;
 
 our @ISA     = qw(Net::FTP::dataconn);
-our $VERSION = "3.11";
+our $VERSION = "3.12";
 
 our $buf;
 
index d9a8857..9eda610 100644 (file)
@@ -8,6 +8,6 @@ use warnings;
 use Net::FTP::I;
 
 our @ISA = qw(Net::FTP::I);
-our $VERSION = "3.11";
+our $VERSION = "3.12";
 
 1;
index 337b0e9..51e9c2f 100644 (file)
@@ -13,7 +13,7 @@ use Carp;
 use Errno;
 use Net::Cmd;
 
-our $VERSION = '3.11';
+our $VERSION = '3.12';
 
 $Net::FTP::IOCLASS or die "please load Net::FTP before Net::FTP::dataconn";
 our @ISA = $Net::FTP::IOCLASS;
@@ -137,6 +137,22 @@ __END__
 
 Net::FTP::dataconn - FTP Client data connection class
 
+=head1 SYNOPSIS
+
+    # Perform IO operations on an FTP client data connection object:
+
+    $num_bytes_read = $obj->read($buffer, $size);
+    $num_bytes_read = $obj->read($buffer, $size, $timeout);
+
+    $num_bytes_written = $obj->write($buffer, $size);
+    $num_bytes_written = $obj->write($buffer, $size, $timeout);
+
+    $num_bytes_read_so_far = $obj->bytes_read();
+
+    $obj->abort();
+
+    $closed_successfully = $obj->close();
+
 =head1 DESCRIPTION
 
 Some of the methods defined in C<Net::FTP> return an object which will
@@ -147,31 +163,31 @@ be performed using these.
 
 =over 4
 
-=item read ( BUFFER, SIZE [, TIMEOUT ] )
+=item C<read($buffer, $size[, $timeout])>
 
-Read C<SIZE> bytes of data from the server and place it into C<BUFFER>, also
-performing any <CRLF> translation necessary. C<TIMEOUT> is optional, if not
+Read C<$size> bytes of data from the server and place it into C<$buffer>, also
+performing any <CRLF> translation necessary. C<$timeout> is optional, if not
 given, the timeout value from the command connection will be used.
 
 Returns the number of bytes read before any <CRLF> translation.
 
-=item write ( BUFFER, SIZE [, TIMEOUT ] )
+=item C<write($buffer, $size[, $timeout])>
 
-Write C<SIZE> bytes of data from C<BUFFER> to the server, also
-performing any <CRLF> translation necessary. C<TIMEOUT> is optional, if not
+Write C<$size> bytes of data from C<$buffer> to the server, also
+performing any <CRLF> translation necessary. C<$timeout> is optional, if not
 given, the timeout value from the command connection will be used.
 
 Returns the number of bytes written before any <CRLF> translation.
 
-=item bytes_read ()
+=item C<bytes_read()>
 
 Returns the number of bytes read so far.
 
-=item abort ()
+=item C<abort()>
 
 Abort the current data transfer.
 
-=item close ()
+=item C<close()>
 
 Close the data connection and get a response from the FTP server. Returns
 I<true> if the connection was closed successfully and the first digit of
@@ -179,4 +195,43 @@ the response from the server was a '2'.
 
 =back
 
+=head1 EXPORTS
+
+I<None>.
+
+=head1 KNOWN BUGS
+
+I<None>.
+
+=head1 AUTHOR
+
+Graham Barr E<lt>L<gbarr@pobox.com|mailto:gbarr@pobox.com>E<gt>.
+
+Steve Hay E<lt>L<shay@cpan.org|mailto:shay@cpan.org>E<gt> is now maintaining
+libnet as of version 1.22_02.
+
+=head1 COPYRIGHT
+
+Copyright (C) 1997-2010 Graham Barr.  All rights reserved.
+
+Copyright (C) 2013-2014, 2020 Steve Hay.  All rights reserved.
+
+=head1 LICENCE
+
+This module is free software; you can redistribute it and/or modify it under the
+same terms as Perl itself, i.e. under the terms of either the GNU General Public
+License or the Artistic License, as specified in the F<LICENCE> file.
+
+=head1 VERSION
+
+Version 3.12
+
+=head1 DATE
+
+09 Dec 2020
+
+=head1 HISTORY
+
+See the F<Changes> file.
+
 =cut
index 0c22930..9289b59 100644 (file)
@@ -1,7 +1,7 @@
 # Net::NNTP.pm
 #
 # Copyright (C) 1995-1997 Graham Barr.  All rights reserved.
-# Copyright (C) 2013-2016 Steve Hay.  All rights reserved.
+# Copyright (C) 2013-2016, 2020 Steve Hay.  All rights reserved.
 # This module is free software; you can redistribute it and/or modify it under
 # the same terms as Perl itself, i.e. under the terms of either the GNU General
 # Public License or the Artistic License, as specified in the F<LICENCE> file.
@@ -19,7 +19,7 @@ use Net::Cmd;
 use Net::Config;
 use Time::Local;
 
-our $VERSION = "3.11";
+our $VERSION = "3.12";
 
 # Code for detecting if we can use SSL
 my $ssl_class = eval {
@@ -96,7 +96,6 @@ sub new {
     if ($arg{SSL}) {
       Net::NNTP::_SSL->start_SSL($obj,%arg) or next;
     }
-    last:
   }
 
   return
@@ -176,7 +175,7 @@ sub starttls {
 
 
 sub article {
-  @_ >= 1 && @_ <= 3 or croak 'usage: $nntp->article( [ MSGID ], [ FH ] )';
+  @_ >= 1 && @_ <= 3 or croak 'usage: $nntp->article([{$msgid|$msgnum}[, $fh]])';
   my $nntp = shift;
   my @fh;
 
@@ -189,7 +188,7 @@ sub article {
 
 
 sub articlefh {
-  @_ >= 1 && @_ <= 2 or croak 'usage: $nntp->articlefh( [ MSGID ] )';
+  @_ >= 1 && @_ <= 2 or croak 'usage: $nntp->articlefh([{$msgid|$msgnum}])';
   my $nntp = shift;
 
   return unless $nntp->_ARTICLE(@_);
@@ -198,7 +197,7 @@ sub articlefh {
 
 
 sub authinfo {
-  @_ == 3 or croak 'usage: $nntp->authinfo( USER, PASS )';
+  @_ == 3 or croak 'usage: $nntp->authinfo($user, $pass)';
   my ($nntp, $user, $pass) = @_;
 
   $nntp->_AUTHINFO("USER",      $user) == CMD_MORE
@@ -207,7 +206,7 @@ sub authinfo {
 
 
 sub authinfo_simple {
-  @_ == 3 or croak 'usage: $nntp->authinfo( USER, PASS )';
+  @_ == 3 or croak 'usage: $nntp->authinfo_simple($user, $pass)';
   my ($nntp, $user, $pass) = @_;
 
   $nntp->_AUTHINFO('SIMPLE') == CMD_MORE
@@ -216,7 +215,7 @@ sub authinfo_simple {
 
 
 sub body {
-  @_ >= 1 && @_ <= 3 or croak 'usage: $nntp->body( [ MSGID ], [ FH ] )';
+  @_ >= 1 && @_ <= 3 or croak 'usage: $nntp->body([{$msgid|$msgnum}[, $fh]])';
   my $nntp = shift;
   my @fh;
 
@@ -229,7 +228,7 @@ sub body {
 
 
 sub bodyfh {
-  @_ >= 1 && @_ <= 2 or croak 'usage: $nntp->bodyfh( [ MSGID ] )';
+  @_ >= 1 && @_ <= 2 or croak 'usage: $nntp->bodyfh([{$msgid|$msgnum}])';
   my $nntp = shift;
   return unless $nntp->_BODY(@_);
   return $nntp->tied_fh;
@@ -237,7 +236,7 @@ sub bodyfh {
 
 
 sub head {
-  @_ >= 1 && @_ <= 3 or croak 'usage: $nntp->head( [ MSGID ], [ FH ] )';
+  @_ >= 1 && @_ <= 3 or croak 'usage: $nntp->head([{$msgid|$msgnum}[, $fh]])';
   my $nntp = shift;
   my @fh;
 
@@ -250,7 +249,7 @@ sub head {
 
 
 sub headfh {
-  @_ >= 1 && @_ <= 2 or croak 'usage: $nntp->headfh( [ MSGID ] )';
+  @_ >= 1 && @_ <= 2 or croak 'usage: $nntp->headfh([{$msgid|$msgnum}])';
   my $nntp = shift;
   return unless $nntp->_HEAD(@_);
   return $nntp->tied_fh;
@@ -258,7 +257,7 @@ sub headfh {
 
 
 sub nntpstat {
-  @_ == 1 || @_ == 2 or croak 'usage: $nntp->nntpstat( [ MSGID ] )';
+  @_ == 1 || @_ == 2 or croak 'usage: $nntp->nntpstat([{$msgid|$msgnum}])';
   my $nntp = shift;
 
   $nntp->_STAT(@_) && $nntp->message =~ /(<[^>]+>)/o
@@ -268,7 +267,7 @@ sub nntpstat {
 
 
 sub group {
-  @_ == 1 || @_ == 2 or croak 'usage: $nntp->group( [ GROUP ] )';
+  @_ == 1 || @_ == 2 or croak 'usage: $nntp->group([$group])';
   my $nntp = shift;
   my $grp  = ${*$nntp}{'net_nntp_group'};
 
@@ -308,11 +307,11 @@ sub help {
 
 
 sub ihave {
-  @_ >= 2 or croak 'usage: $nntp->ihave( MESSAGE-ID [, MESSAGE ])';
-  my $nntp = shift;
-  my $mid  = shift;
+  @_ >= 2 or croak 'usage: $nntp->ihave($msgid[, $message])';
+  my $nntp  = shift;
+  my $msgid = shift;
 
-  $nntp->_IHAVE($mid) && $nntp->datasend(@_)
+  $nntp->_IHAVE($msgid) && $nntp->datasend(@_)
     ? @_ == 0 || $nntp->dataend
     : undef;
 }
@@ -339,15 +338,15 @@ sub list {
 
 
 sub newgroups {
-  @_ >= 2 or croak 'usage: $nntp->newgroups( SINCE [, DISTRIBUTIONS ])';
+  @_ >= 2 or croak 'usage: $nntp->newgroups($since[, $distributions])';
   my $nntp = shift;
-  my $time = _timestr(shift);
-  my $dist = shift || "";
+  my $since = _timestr(shift);
+  my $distributions = shift || "";
 
-  $dist = join(",", @{$dist})
-    if ref($dist);
+  $distributions = join(",", @{$distributions})
+    if ref($distributions);
 
-  $nntp->_NEWGROUPS($time, $dist)
+  $nntp->_NEWGROUPS($since, $distributions)
     ? $nntp->_grouplist
     : undef;
 }
@@ -355,20 +354,20 @@ sub newgroups {
 
 sub newnews {
   @_ >= 2 && @_ <= 4
-    or croak 'usage: $nntp->newnews( SINCE [, GROUPS [, DISTRIBUTIONS ]])';
+    or croak 'usage: $nntp->newnews($since[, $groups[, $distributions]])';
   my $nntp = shift;
-  my $time = _timestr(shift);
-  my $grp  = @_ ? shift: $nntp->group;
-  my $dist = shift || "";
+  my $since = _timestr(shift);
+  my $groups = @_ ? shift : $nntp->group;
+  my $distributions = shift || "";
 
-  $grp ||= "*";
-  $grp = join(",", @{$grp})
-    if ref($grp);
+  $groups ||= "*";
+  $groups = join(",", @{$groups})
+    if ref($groups);
 
-  $dist = join(",", @{$dist})
-    if ref($dist);
+  $distributions = join(",", @{$distributions})
+    if ref($distributions);
 
-  $nntp->_NEWNEWS($grp, $time, $dist)
+  $nntp->_NEWNEWS($groups, $since, $distributions)
     ? $nntp->_articlelist
     : undef;
 }
@@ -385,7 +384,7 @@ sub next {
 
 
 sub post {
-  @_ >= 1 or croak 'usage: $nntp->post( [ MESSAGE ] )';
+  @_ >= 1 or croak 'usage: $nntp->post([$message])';
   my $nntp = shift;
 
   $nntp->_POST() && $nntp->datasend(@_)
@@ -423,7 +422,7 @@ sub slave {
 
 
 sub active {
-  @_ == 1 || @_ == 2 or croak 'usage: $nntp->active( [ PATTERN ] )';
+  @_ == 1 || @_ == 2 or croak 'usage: $nntp->active([$pattern])';
   my $nntp = shift;
 
   $nntp->_LIST('ACTIVE', @_)
@@ -453,7 +452,7 @@ sub distributions {
 
 
 sub distribution_patterns {
-  @_ == 1 or croak 'usage: $nntp->distributions()';
+  @_ == 1 or croak 'usage: $nntp->distribution_patterns()';
   my $nntp = shift;
 
   my $arr;
@@ -468,7 +467,7 @@ sub distribution_patterns {
 
 
 sub newsgroups {
-  @_ == 1 || @_ == 2 or croak 'usage: $nntp->newsgroups( [ PATTERN ] )';
+  @_ == 1 || @_ == 2 or croak 'usage: $nntp->newsgroups([$pattern])';
   my $nntp = shift;
 
   $nntp->_LIST('NEWSGROUPS', @_)
@@ -498,7 +497,7 @@ sub subscriptions {
 
 
 sub listgroup {
-  @_ == 1 || @_ == 2 or croak 'usage: $nntp->listgroup( [ GROUP ] )';
+  @_ == 1 || @_ == 2 or croak 'usage: $nntp->listgroup([$group])';
   my $nntp = shift;
 
   $nntp->_LISTGROUP(@_)
@@ -516,7 +515,7 @@ sub reader {
 
 
 sub xgtitle {
-  @_ == 1 || @_ == 2 or croak 'usage: $nntp->xgtitle( [ PATTERN ] )';
+  @_ == 1 || @_ == 2 or croak 'usage: $nntp->xgtitle([$pattern])';
   my $nntp = shift;
 
   $nntp->_XGTITLE(@_)
@@ -526,19 +525,19 @@ sub xgtitle {
 
 
 sub xhdr {
-  @_ >= 2 && @_ <= 4 or croak 'usage: $nntp->xhdr( HEADER, [ MESSAGE-SPEC ] )';
+  @_ >= 2 && @_ <= 4 or croak 'usage: $nntp->xhdr($header[, $message_spec])';
   my $nntp = shift;
-  my $hdr  = shift;
-  my $arg  = _msg_arg(@_);
+  my $header = shift;
+  my $arg = _msg_arg(@_);
 
-  $nntp->_XHDR($hdr, $arg)
+  $nntp->_XHDR($header, $arg)
     ? $nntp->_description
     : undef;
 }
 
 
 sub xover {
-  @_ == 2 || @_ == 3 or croak 'usage: $nntp->xover( MESSAGE-SPEC )';
+  @_ == 2 || @_ == 3 or croak 'usage: $nntp->xover($message_spec)';
   my $nntp = shift;
   my $arg  = _msg_arg(@_);
 
@@ -549,27 +548,27 @@ sub xover {
 
 
 sub xpat {
-  @_ == 4 || @_ == 5 or croak '$nntp->xpat( HEADER, PATTERN, MESSAGE-SPEC )';
+  @_ == 4 || @_ == 5 or croak 'usage: $nntp->xpat($header, $pattern, $message_spec )';
   my $nntp = shift;
-  my $hdr  = shift;
-  my $pat  = shift;
-  my $arg  = _msg_arg(@_);
+  my $header = shift;
+  my $pattern = shift;
+  my $arg = _msg_arg(@_);
 
-  $pat = join(" ", @$pat)
-    if ref($pat);
+  $pattern = join(" ", @$pattern)
+    if ref($pattern);
 
-  $nntp->_XPAT($hdr, $arg, $pat)
+  $nntp->_XPAT($header, $arg, $pattern)
     ? $nntp->_description
     : undef;
 }
 
 
 sub xpath {
-  @_ == 2 or croak 'usage: $nntp->xpath( MESSAGE-ID )';
-  my ($nntp, $mid) = @_;
+  @_ == 2 or croak 'usage: $nntp->xpath($message_id)';
+  my ($nntp, $message_id) = @_;
 
   return
-    unless $nntp->_XPATH($mid);
+    unless $nntp->_XPATH($message_id);
 
   my $m;
   ($m = $nntp->message) =~ s/^\d+\s+//o;
@@ -580,7 +579,7 @@ sub xpath {
 
 
 sub xrover {
-  @_ == 2 || @_ == 3 or croak 'usage: $nntp->xrover( MESSAGE-SPEC )';
+  @_ == 2 || @_ == 3 or croak 'usage: $nntp->xrover($message_spec)';
   my $nntp = shift;
   my $arg  = _msg_arg(@_);
 
@@ -596,7 +595,7 @@ sub date {
 
   $nntp->_DATE
     && $nntp->message =~ /(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/
-    ? timegm($6, $5, $4, $3, $2 - 1, $1 - 1900)
+    ? timegm($6, $5, $4, $3, $2 - 1, $1)
     : undef;
 }
 
@@ -807,20 +806,20 @@ explicit TLS encryption, i.e. NNTPS or NNTP+STARTTLS.
 The Net::NNTP class is a subclass of Net::Cmd and (depending on avaibility) of
 IO::Socket::IP, IO::Socket::INET6 or IO::Socket::INET.
 
-=head1 CONSTRUCTOR
+=head2 Class Methods
 
 =over 4
 
-=item new ( [ HOST ] [, OPTIONS ])
+=item C<new([$host][, %options])>
 
-This is the constructor for a new Net::NNTP object. C<HOST> is the
+This is the constructor for a new Net::NNTP object. C<$host> is the
 name of the remote host to which a NNTP connection is required. If not
 given then it may be passed as the C<Host> option described below. If no host is passed
 then two environment variables are checked, first C<NNTPSERVER> then
 C<NEWSHOST>, then C<Net::Config> is checked, and if a host is not found
 then C<news> is used.
 
-C<OPTIONS> are passed in a hash like fashion, using key and value pairs.
+C<%options> are passed in a hash like fashion, using key and value pairs.
 Possible options are:
 
 B<Host> - NNTP host to connect to. It may be a single scalar, as defined for
@@ -857,7 +856,7 @@ class. Alternatively B<Family> can be used.
 
 =back
 
-=head1 METHODS
+=head2 Object Methods
 
 Unless otherwise stated all methods return either a I<true> or I<false>
 value, with I<true> meaning that the operation was a success. When a method
@@ -870,58 +869,58 @@ documented here.
 
 =over 4
 
-=item host ()
+=item C<host()>
 
 Returns the value used by the constructor, and passed to IO::Socket::INET,
 to connect to the host.
 
-=item starttls ()
+=item C<starttls()>
 
 Upgrade existing plain connection to SSL.
 Any arguments necessary for SSL must be given in C<new> already.
 
-=item article ( [ MSGID|MSGNUM ], [FH] )
+=item C<article([{$msgid|$msgnum}[, $fh]])>
 
 Retrieve the header, a blank line, then the body (text) of the
 specified article. 
 
-If C<FH> is specified then it is expected to be a valid filehandle
+If C<$fh> is specified then it is expected to be a valid filehandle
 and the result will be printed to it, on success a true value will be
-returned. If C<FH> is not specified then the return value, on success,
+returned. If C<$fh> is not specified then the return value, on success,
 will be a reference to an array containing the article requested, each
 entry in the array will contain one line of the article.
 
 If no arguments are passed then the current article in the currently
 selected newsgroup is fetched.
 
-C<MSGNUM> is a numeric id of an article in the current newsgroup, and
-will change the current article pointer.  C<MSGID> is the message id of
+C<$msgnum> is a numeric id of an article in the current newsgroup, and
+will change the current article pointer.  C<$msgid> is the message id of
 an article as shown in that article's header.  It is anticipated that the
-client will obtain the C<MSGID> from a list provided by the C<newnews>
+client will obtain the C<$msgid> from a list provided by the C<newnews>
 command, from references contained within another article, or from the
 message-id provided in the response to some other commands.
 
 If there is an error then C<undef> will be returned.
 
-=item body ( [ MSGID|MSGNUM ], [FH] )
+=item C<body([{$msgid|$msgnum}[, [$fh]])>
 
 Like C<article> but only fetches the body of the article.
 
-=item head ( [ MSGID|MSGNUM ], [FH] )
+=item C<head([{$msgid|$msgnum}[, [$fh]])>
 
 Like C<article> but only fetches the headers for the article.
 
-=item articlefh ( [ MSGID|MSGNUM ] )
+=item C<articlefh([{$msgid|$msgnum}])>
 
-=item bodyfh ( [ MSGID|MSGNUM ] )
+=item C<bodyfh([{$msgid|$msgnum}])>
 
-=item headfh ( [ MSGID|MSGNUM ] )
+=item C<headfh([{$msgid|$msgnum}])>
 
 These are similar to article(), body() and head(), but rather than
 returning the requested data directly, they return a tied filehandle
 from which to read the article.
 
-=item nntpstat ( [ MSGID|MSGNUM ] )
+=item C<nntpstat([{$msgid|$msgnum}])>
 
 The C<nntpstat> command is similar to the C<article> command except that no
 text is returned.  When selecting by message number within a group,
@@ -934,9 +933,9 @@ selection by message-id does B<not> alter the "current article pointer".
 
 Returns the message-id of the "current article".
 
-=item group ( [ GROUP ] )
+=item C<group([$group])>
 
-Set and/or get the current group. If C<GROUP> is not given then information
+Set and/or get the current group. If C<$group> is not given then information
 is returned on the current group.
 
 In a scalar context it returns the group name.
@@ -945,45 +944,45 @@ In an array context the return value is a list containing, the number
 of articles in the group, the number of the first article, the number
 of the last article and the group name.
 
-=item help ( )
+=item C<help()>
 
 Request help text (a short summary of commands that are understood by this
 implementation) from the server. Returns the text or undef upon failure.
 
-=item ihave ( MSGID [, MESSAGE ])
+=item C<ihave($msgid[, $message])>
 
 The C<ihave> command informs the server that the client has an article
-whose id is C<MSGID>.  If the server desires a copy of that
-article and C<MESSAGE> has been given then it will be sent.
+whose id is C<$msgid>.  If the server desires a copy of that
+article and C<$message> has been given then it will be sent.
 
-Returns I<true> if the server desires the article and C<MESSAGE> was
+Returns I<true> if the server desires the article and C<$message> was
 successfully sent, if specified.
 
-If C<MESSAGE> is not specified then the message must be sent using the
+If C<$message> is not specified then the message must be sent using the
 C<datasend> and C<dataend> methods from L<Net::Cmd>
 
-C<MESSAGE> can be either an array of lines or a reference to an array
+C<$message> can be either an array of lines or a reference to an array
 and must be encoded by the caller to octets of whatever encoding is required,
 e.g. by using the Encode module's C<encode()> function.
 
-=item last ()
+=item C<last()>
 
 Set the "current article pointer" to the previous article in the current
 newsgroup.
 
 Returns the message-id of the article.
 
-=item date ()
+=item C<date()>
 
 Returns the date on the remote server. This date will be in a UNIX time
 format (seconds since 1970)
 
-=item postok ()
+=item C<postok()>
 
 C<postok> will return I<true> if the servers initial response indicated
 that it will allow posting.
 
-=item authinfo ( USER, PASS )
+=item C<authinfo($user, $pass)>
 
 Authenticates to the server (using the original AUTHINFO USER / AUTHINFO PASS
 form, defined in RFC2980) using the supplied username and password.  Please
@@ -991,61 +990,61 @@ note that the password is sent in clear text to the server.  This command
 should not be used with valuable passwords unless the connection to the server
 is somehow protected.
 
-=item authinfo_simple ( USER, PASS )
+=item C<authinfo_simple($user, $pass)>
 
 Authenticates to the server (using the proposed NNTP V2 AUTHINFO SIMPLE form,
 defined and deprecated in RFC2980) using the supplied username and password.
 As with L</authinfo> the password is sent in clear text.
 
-=item list ()
+=item C<list()>
 
 Obtain information about all the active newsgroups. The results is a reference
 to a hash where the key is a group name and each value is a reference to an
 array. The elements in this array are:- the last article number in the group,
 the first article number in the group and any information flags about the group.
 
-=item newgroups ( SINCE [, DISTRIBUTIONS ])
+=item C<newgroups($since[, $distributions])>
 
-C<SINCE> is a time value and C<DISTRIBUTIONS> is either a distribution
+C<$since> is a time value and C<$distributions> is either a distribution
 pattern or a reference to a list of distribution patterns.
 The result is the same as C<list>, but the
-groups return will be limited to those created after C<SINCE> and, if
-specified, in one of the distribution areas in C<DISTRIBUTIONS>. 
+groups return will be limited to those created after C<$since> and, if
+specified, in one of the distribution areas in C<$distributions>. 
 
-=item newnews ( SINCE [, GROUPS [, DISTRIBUTIONS ]])
+=item C<newnews($since[, $groups[, $distributions]])>
 
-C<SINCE> is a time value. C<GROUPS> is either a group pattern or a reference
-to a list of group patterns. C<DISTRIBUTIONS> is either a distribution
+C<$since> is a time value. C<$groups> is either a group pattern or a reference
+to a list of group patterns. C<$distributions> is either a distribution
 pattern or a reference to a list of distribution patterns.
 
 Returns a reference to a list which contains the message-ids of all news posted
-after C<SINCE>, that are in a groups which matched C<GROUPS> and a
-distribution which matches C<DISTRIBUTIONS>.
+after C<$since>, that are in a groups which matched C<$groups> and a
+distribution which matches C<$distributions>.
 
-=item next ()
+=item C<next()>
 
 Set the "current article pointer" to the next article in the current
 newsgroup.
 
 Returns the message-id of the article.
 
-=item post ( [ MESSAGE ] )
+=item C<post([$message])>
 
-Post a new article to the news server. If C<MESSAGE> is specified and posting
+Post a new article to the news server. If C<$message> is specified and posting
 is allowed then the message will be sent.
 
-If C<MESSAGE> is not specified then the message must be sent using the
+If C<$message> is not specified then the message must be sent using the
 C<datasend> and C<dataend> methods from L<Net::Cmd>
 
-C<MESSAGE> can be either an array of lines or a reference to an array
+C<$message> can be either an array of lines or a reference to an array
 and must be encoded by the caller to octets of whatever encoding is required,
 e.g. by using the Encode module's C<encode()> function.
 
-The message, either sent via C<datasend> or as the C<MESSAGE>
+The message, either sent via C<datasend> or as the C<$message>
 parameter, must be in the format as described by RFC822 and must
 contain From:, Newsgroups: and Subject: headers.
 
-=item postfh ()
+=item C<postfh()>
 
 Post a new article to the news server using a tied filehandle.  If
 posting is allowed, this method will return a tied filehandle that you
@@ -1054,85 +1053,85 @@ explicitly close() the filehandle when you are finished posting the
 article, and the return value from the close() call will indicate
 whether the message was successfully posted.
 
-=item slave ()
+=item C<slave()>
 
 Tell the remote server that I am not a user client, but probably another
 news server.
 
-=item quit ()
+=item C<quit()>
 
 Quit the remote server and close the socket connection.
 
-=item can_inet6 ()
+=item C<can_inet6()>
 
 Returns whether we can use IPv6.
 
-=item can_ssl ()
+=item C<can_ssl()>
 
 Returns whether we can use SSL.
 
 =back
 
-=head2 Extension methods
+=head2 Extension Methods
 
 These methods use commands that are not part of the RFC977 documentation. Some
 servers may not support all of them.
 
 =over 4
 
-=item newsgroups ( [ PATTERN ] )
+=item C<newsgroups([$pattern])>
 
 Returns a reference to a hash where the keys are all the group names which
-match C<PATTERN>, or all of the groups if no pattern is specified, and
+match C<$pattern>, or all of the groups if no pattern is specified, and
 each value contains the description text for the group.
 
-=item distributions ()
+=item C<distributions()>
 
 Returns a reference to a hash where the keys are all the possible
 distribution names and the values are the distribution descriptions.
 
-=item distribution_patterns ()
+=item C<distribution_patterns()>
 
 Returns a reference to an array where each element, itself an array
 reference, consists of the three fields of a line of the distrib.pats list
 maintained by some NNTP servers, namely: a weight, a wildmat and a value
 which the client may use to construct a Distribution header.
 
-=item subscriptions ()
+=item C<subscriptions()>
 
 Returns a reference to a list which contains a list of groups which
 are recommended for a new user to subscribe to.
 
-=item overview_fmt ()
+=item C<overview_fmt()>
 
 Returns a reference to an array which contain the names of the fields returned
 by C<xover>.
 
-=item active_times ()
+=item C<active_times()>
 
 Returns a reference to a hash where the keys are the group names and each
 value is a reference to an array containing the time the groups was created
 and an identifier, possibly an Email address, of the creator.
 
-=item active ( [ PATTERN ] )
+=item C<active([$pattern])>
 
 Similar to C<list> but only active groups that match the pattern are returned.
-C<PATTERN> can be a group pattern.
+C<$pattern> can be a group pattern.
 
-=item xgtitle ( PATTERN )
+=item C<xgtitle($pattern)>
 
 Returns a reference to a hash where the keys are all the group names which
-match C<PATTERN> and each value is the description text for the group.
+match C<$pattern> and each value is the description text for the group.
 
-=item xhdr ( HEADER, MESSAGE-SPEC )
+=item C<xhdr($header, $message_spec)>
 
-Obtain the header field C<HEADER> for all the messages specified. 
+Obtain the header field C<$header> for all the messages specified. 
 
 The return value will be a reference
 to a hash where the keys are the message numbers and each value contains
 the text of the requested header for that message.
 
-=item xover ( MESSAGE-SPEC )
+=item C<xover($message_spec)>
 
 The return value will be a reference
 to a hash where the keys are the message numbers and each value contains
@@ -1141,17 +1140,17 @@ message.
 
 The names of the fields can be obtained by calling C<overview_fmt>.
 
-=item xpath ( MESSAGE-ID )
+=item C<xpath($message_id)>
 
 Returns the path name to the file on the server which contains the specified
 message.
 
-=item xpat ( HEADER, PATTERN, MESSAGE-SPEC)
+=item C<xpat($header, $pattern, $message_spec)>
 
 The result is the same as C<xhdr> except the is will be restricted to
-headers where the text of the header matches C<PATTERN>
+headers where the text of the header matches C<$pattern>
 
-=item xrover ()
+=item C<xrover($message_spec)>
 
 The XROVER command returns reference information for the article(s)
 specified.
@@ -1159,12 +1158,12 @@ specified.
 Returns a reference to a HASH where the keys are the message numbers and the
 values are the References: lines from the articles
 
-=item listgroup ( [ GROUP ] )
+=item C<listgroup([$group])>
 
-Returns a reference to a list of all the active messages in C<GROUP>, or
-the current group if C<GROUP> is not specified.
+Returns a reference to a list of all the active messages in C<$group>, or
+the current group if C<$group> is not specified.
 
-=item reader ()
+=item C<reader()>
 
 Tell the server that you are a reader and not another server.
 
@@ -1179,7 +1178,7 @@ the response is harmless.
 
 =back
 
-=head1 UNSUPPORTED
+=head2 Unsupported
 
 The following NNTP command are unsupported by the package, and there are
 no plans to do so.
@@ -1189,16 +1188,16 @@ no plans to do so.
     XSEARCH
     XINDEX
 
-=head1 DEFINITIONS
+=head2 Definitions
 
 =over 4
 
-=item MESSAGE-SPEC
+=item $message_spec
 
-C<MESSAGE-SPEC> is either a single message-id, a single message number, or
+C<$message_spec> is either a single message-id, a single message number, or
 a reference to a list of two message numbers.
 
-If C<MESSAGE-SPEC> is a reference to a list of two message numbers and the
+If C<$message_spec> is a reference to a list of two message numbers and the
 second number in a range is less than or equal to the first then the range
 represents all messages in the group after the first message number.
 
@@ -1206,7 +1205,7 @@ B<NOTE> For compatibility reasons only with earlier versions of Net::NNTP
 a message spec can be passed as a list of two numbers, this is deprecated
 and a reference to the list should now be passed
 
-=item PATTERN
+=item $pattern
 
 The C<NNTP> protocol uses the C<WILDMAT> format for patterns.
 The WILDMAT format was first developed by Rich Salz based on
@@ -1275,23 +1274,31 @@ with a and ends with d.
 
 =back
 
+=head1 EXPORTS
+
+I<None>.
+
+=head1 KNOWN BUGS
+
+See L<https://rt.cpan.org/Dist/Display.html?Status=Active&Queue=libnet>.
+
 =head1 SEE ALSO
 
 L<Net::Cmd>,
-L<IO::Socket::SSL>
+L<IO::Socket::SSL>.
 
 =head1 AUTHOR
 
-Graham Barr E<lt>F<gbarr@pobox.com>E<gt>.
+Graham Barr E<lt>L<gbarr@pobox.com|mailto:gbarr@pobox.com>E<gt>.
 
-Steve Hay E<lt>F<shay@cpan.org>E<gt> is now maintaining libnet as of version
-1.22_02.
+Steve Hay E<lt>L<shay@cpan.org|mailto:shay@cpan.org>E<gt> is now maintaining
+libnet as of version 1.22_02.
 
 =head1 COPYRIGHT
 
 Copyright (C) 1995-1997 Graham Barr.  All rights reserved.
 
-Copyright (C) 2013-2016 Steve Hay.  All rights reserved.
+Copyright (C) 2013-2016, 2020 Steve Hay.  All rights reserved.
 
 =head1 LICENCE
 
@@ -1299,4 +1306,16 @@ This module is free software; you can redistribute it and/or modify it under the
 same terms as Perl itself, i.e. under the terms of either the GNU General Public
 License or the Artistic License, as specified in the F<LICENCE> file.
 
+=head1 VERSION
+
+Version 3.12
+
+=head1 DATE
+
+09 Dec 2020
+
+=head1 HISTORY
+
+See the F<Changes> file.
+
 =cut
index 46fba27..b66eb82 100644 (file)
@@ -1,7 +1,7 @@
 # Net::Netrc.pm
 #
 # Copyright (C) 1995-1998 Graham Barr.  All rights reserved.
-# Copyright (C) 2013-2014 Steve Hay.  All rights reserved.
+# Copyright (C) 2013-2014, 2020 Steve Hay.  All rights reserved.
 # This module is free software; you can redistribute it and/or modify it under
 # the same terms as Perl itself, i.e. under the terms of either the GNU General
 # Public License or the Artistic License, as specified in the F<LICENCE> file.
@@ -16,7 +16,7 @@ use warnings;
 use Carp;
 use FileHandle;
 
-our $VERSION = "3.11";
+our $VERSION = "3.12";
 
 our $TESTING;
 
@@ -224,7 +224,7 @@ second the ownership permissions should be such that only the owner has
 read and write access. If these conditions are not met then a warning is
 output and the .netrc file is not read.
 
-=head1 THE .netrc FILE
+=head2 The F<.netrc> File
 
 The .netrc file contains login and initialization information used by the
 auto-login process.  It resides in the user's home directory.  The following
@@ -276,7 +276,7 @@ with I<ftp>.
 
 =back
 
-=head1 CONSTRUCTOR
+=head2 Class Methods
 
 The constructor for a C<Net::Netrc> object is not called new as it does not
 really create a new object. But instead is called C<lookup> as this is
@@ -284,11 +284,11 @@ essentially what it does.
 
 =over 4
 
-=item lookup ( MACHINE [, LOGIN ])
+=item C<lookup($machine[, $login])>
 
-Lookup and return a reference to the entry for C<MACHINE>. If C<LOGIN> is given
-then the entry returned will have the given login. If C<LOGIN> is not given then
-the first entry in the .netrc file for C<MACHINE> will be returned.
+Lookup and return a reference to the entry for C<$machine>. If C<$login> is given
+then the entry returned will have the given login. If C<$login> is not given then
+the first entry in the .netrc file for C<$machine> will be returned.
 
 If a matching entry cannot be found, and a default entry exists, then a
 reference to the default entry is returned.
@@ -298,45 +298,52 @@ no .netrc file is found, then C<undef> is returned.
 
 =back
 
-=head1 METHODS
+=head2 Object Methods
 
 =over 4
 
-=item login ()
+=item C<login()>
 
 Return the login id for the netrc entry
 
-=item password ()
+=item C<password()>
 
 Return the password for the netrc entry
 
-=item account ()
+=item C<account()>
 
 Return the account information for the netrc entry
 
-=item lpa ()
+=item C<lpa()>
 
 Return a list of login, password and account information for the netrc entry
 
 =back
 
-=head1 AUTHOR
+=head1 EXPORTS
+
+I<None>.
 
-Graham Barr E<lt>F<gbarr@pobox.com>E<gt>.
+=head1 KNOWN BUGS
 
-Steve Hay E<lt>F<shay@cpan.org>E<gt> is now maintaining libnet as of version
-1.22_02.
+See L<https://rt.cpan.org/Dist/Display.html?Status=Active&Queue=libnet>.
 
 =head1 SEE ALSO
 
-L<Net::Netrc>,
-L<Net::Cmd>
+L<Net::Cmd>.
+
+=head1 AUTHOR
+
+Graham Barr E<lt>L<gbarr@pobox.com|mailto:gbarr@pobox.com>E<gt>.
+
+Steve Hay E<lt>L<shay@cpan.org|mailto:shay@cpan.org>E<gt> is now maintaining
+libnet as of version 1.22_02.
 
 =head1 COPYRIGHT
 
 Copyright (C) 1995-1998 Graham Barr.  All rights reserved.
 
-Copyright (C) 2013-2014 Steve Hay.  All rights reserved.
+Copyright (C) 2013-2014, 2020 Steve Hay.  All rights reserved.
 
 =head1 LICENCE
 
@@ -344,4 +351,16 @@ This module is free software; you can redistribute it and/or modify it under the
 same terms as Perl itself, i.e. under the terms of either the GNU General Public
 License or the Artistic License, as specified in the F<LICENCE> file.
 
+=head1 VERSION
+
+Version 3.12
+
+=head1 DATE
+
+09 Dec 2020
+
+=head1 HISTORY
+
+See the F<Changes> file.
+
 =cut
index 0811025..fb442ad 100644 (file)
@@ -1,7 +1,7 @@
 # Net::POP3.pm
 #
 # Copyright (C) 1995-2004 Graham Barr.  All rights reserved.
-# Copyright (C) 2013-2016 Steve Hay.  All rights reserved.
+# Copyright (C) 2013-2016, 2020 Steve Hay.  All rights reserved.
 # This module is free software; you can redistribute it and/or modify it under
 # the same terms as Perl itself, i.e. under the terms of either the GNU General
 # Public License or the Artistic License, as specified in the F<LICENCE> file.
@@ -18,7 +18,7 @@ use IO::Socket;
 use Net::Cmd;
 use Net::Config;
 
-our $VERSION = "3.11";
+our $VERSION = "3.12";
 
 # Code for detecting if we can use SSL
 my $ssl_class = eval {
@@ -124,7 +124,7 @@ sub debug_text { $_[2] =~ /^(pass|rpop)/i ? "$1 ....\n" : $_[2]; }
 
 
 sub login {
-  @_ >= 1 && @_ <= 3 or croak 'usage: $pop3->login( USER, PASS )';
+  @_ >= 1 && @_ <= 3 or croak 'usage: $pop3->login([$user[, $pass]])';
   my ($me, $user, $pass) = @_;
 
   if (@_ <= 2) {
@@ -147,7 +147,7 @@ sub starttls {
 }
 
 sub apop {
-  @_ >= 1 && @_ <= 3 or croak 'usage: $pop3->apop( USER, PASS )';
+  @_ >= 1 && @_ <= 3 or croak 'usage: $pop3->apop([$user[, $pass]])';
   my ($me, $user, $pass) = @_;
   my $banner;
   my $md;
@@ -180,13 +180,13 @@ sub apop {
 
 
 sub user {
-  @_ == 2 or croak 'usage: $pop3->user( USER )';
+  @_ == 2 or croak 'usage: $pop3->user($user)';
   $_[0]->_USER($_[1]) ? 1 : undef;
 }
 
 
 sub pass {
-  @_ == 2 or croak 'usage: $pop3->pass( PASS )';
+  @_ == 2 or croak 'usage: $pop3->pass($pass)';
 
   my ($me, $pass) = @_;
 
@@ -225,7 +225,7 @@ sub last {
 
 
 sub top {
-  @_ == 2 || @_ == 3 or croak 'usage: $pop3->top( MSGNUM [, NUMLINES ])';
+  @_ == 2 || @_ == 3 or croak 'usage: $pop3->top($msgnum[, $numlines])';
   my $me = shift;
 
   return
@@ -247,7 +247,7 @@ sub popstat {
 
 
 sub list {
-  @_ == 1 || @_ == 2 or croak 'usage: $pop3->list( [ MSGNUM ] )';
+  @_ == 1 || @_ == 2 or croak 'usage: $pop3->list([$msgnum])';
   my $me = shift;
 
   return
@@ -268,7 +268,7 @@ sub list {
 
 
 sub get {
-  @_ == 2 or @_ == 3 or croak 'usage: $pop3->get( MSGNUM [, FH ])';
+  @_ == 2 or @_ == 3 or croak 'usage: $pop3->get($msgnum[, $fh])';
   my $me = shift;
 
   return
@@ -279,7 +279,7 @@ sub get {
 
 
 sub getfh {
-  @_ == 2 or croak 'usage: $pop3->getfh( MSGNUM )';
+  @_ == 2 or croak 'usage: $pop3->getfh($msgnum)';
   my $me = shift;
 
   return unless $me->_RETR(shift);
@@ -288,7 +288,7 @@ sub getfh {
 
 
 sub delete {
-  @_ == 2 or croak 'usage: $pop3->delete( MSGNUM )';
+  @_ == 2 or croak 'usage: $pop3->delete($msgnum)';
   my $me = shift;
   return 0 unless $me->_DELE(@_);
   ${*$me}{'net_pop3_deleted'} = 1;
@@ -296,7 +296,7 @@ sub delete {
 
 
 sub uidl {
-  @_ == 1 || @_ == 2 or croak 'usage: $pop3->uidl( [ MSGNUM ] )';
+  @_ == 1 || @_ == 2 or croak 'usage: $pop3->uidl([$msgnum])';
   my $me = shift;
   my $uidl;
 
@@ -319,7 +319,7 @@ sub uidl {
 
 
 sub ping {
-  @_ == 2 or croak 'usage: $pop3->ping( USER )';
+  @_ == 2 or croak 'usage: $pop3->ping($user)';
   my $me = shift;
 
   return () unless $me->_PING(@_) && $me->message =~ /(\d+)\D+(\d+)/;
@@ -635,21 +635,20 @@ on the object.
 The Net::POP3 class is a subclass of Net::Cmd and (depending on avaibility) of
 IO::Socket::IP, IO::Socket::INET6 or IO::Socket::INET.
 
-
-=head1 CONSTRUCTOR
+=head2 Class Methods
 
 =over 4
 
-=item new ( [ HOST ] [, OPTIONS ] )
+=item C<new([$host][, %options])>
 
-This is the constructor for a new Net::POP3 object. C<HOST> is the
+This is the constructor for a new Net::POP3 object. C<$host> is the
 name of the remote host to which an POP3 connection is required.
 
-C<HOST> is optional. If C<HOST> is not given then it may instead be
+C<$host> is optional. If C<$host> is not given then it may instead be
 passed as the C<Host> option described below. If neither is given then
 the C<POP3_Hosts> specified in C<Net::Config> will be used.
 
-C<OPTIONS> are passed in a hash like fashion, using key and value pairs.
+C<%options> are passed in a hash like fashion, using key and value pairs.
 Possible options are:
 
 B<Host> - POP3 host to connect to. It may be a single scalar, as defined for
@@ -681,7 +680,7 @@ B<Debug> - Enable debugging information
 
 =back
 
-=head1 METHODS
+=head2 Object Methods
 
 Unless otherwise stated all methods return either a I<true> or I<false>
 value, with I<true> meaning that the operation was a success. When a method
@@ -694,26 +693,26 @@ documented here.
 
 =over 4
 
-=item host ()
+=item C<host()>
 
 Returns the value used by the constructor, and passed to IO::Socket::INET,
 to connect to the host.
 
-=item auth ( USERNAME, PASSWORD )
+=item C<auth($username, $password)>
 
 Attempt SASL authentication.
 
-=item user ( USER )
+=item C<user($user)>
 
 Send the USER command.
 
-=item pass ( PASS )
+=item C<pass($pass)>
 
 Send the PASS command. Returns the number of messages in the mailbox.
 
-=item login ( [ USER [, PASS ]] )
+=item C<login([$user[, $pass]])>
 
-Send both the USER and PASS commands. If C<PASS> is not given the
+Send both the USER and PASS commands. If C<$pass> is not given the
 C<Net::POP3> uses C<Net::Netrc> to lookup the password using the host
 and username. If the username is not specified then the current user name
 will be used.
@@ -724,25 +723,25 @@ will give a true value in a boolean context, but zero in a numeric context.
 
 If there was an error authenticating the user then I<undef> will be returned.
 
-=item starttls ( SSLARGS )
+=item C<starttls(%sslargs)>
 
 Upgrade existing plain connection to SSL.
 You can use SSL arguments as documented in L<IO::Socket::SSL>, but it will
 usually use the right arguments already.
 
-=item apop ( [ USER [, PASS ]] )
+=item C<apop([$user[, $pass]])>
 
-Authenticate with the server identifying as C<USER> with password C<PASS>.
+Authenticate with the server identifying as C<$user> with password C<$pass>.
 Similar to L</login>, but the password is not sent in clear text.
 
 To use this method you must have the Digest::MD5 or the MD5 module installed,
 otherwise this method will return I<undef>.
 
-=item banner ()
+=item C<banner()>
 
 Return the sever's connection banner
 
-=item capa ()
+=item C<capa()>
 
 Return a reference to a hash of the capabilities of the server.  APOP
 is added as a pseudo capability.  Note that I've been unable to
@@ -750,109 +749,117 @@ find a list of the standard capability values, and some appear to
 be multi-word and some are not.  We make an attempt at intelligently
 parsing them, but it may not be correct.
 
-=item  capabilities ()
+=item C<capabilities()>
 
 Just like capa, but only uses a cache from the last time we asked
 the server, so as to avoid asking more than once.
 
-=item top ( MSGNUM [, NUMLINES ] )
+=item C<top($msgnum[, $numlines])>
 
-Get the header and the first C<NUMLINES> of the body for the message
-C<MSGNUM>. Returns a reference to an array which contains the lines of text
+Get the header and the first C<$numlines> of the body for the message
+C<$msgnum>. Returns a reference to an array which contains the lines of text
 read from the server.
 
-=item list ( [ MSGNUM ] )
+=item C<list([$msgnum])>
 
 If called with an argument the C<list> returns the size of the message
 in octets.
 
 If called without arguments a reference to a hash is returned. The
-keys will be the C<MSGNUM>'s of all undeleted messages and the values will
+keys will be the C<$msgnum>'s of all undeleted messages and the values will
 be their size in octets.
 
-=item get ( MSGNUM [, FH ] )
+=item C<get($msgnum[, $fh])>
 
-Get the message C<MSGNUM> from the remote mailbox. If C<FH> is not given
+Get the message C<$msgnum> from the remote mailbox. If C<$fh> is not given
 then get returns a reference to an array which contains the lines of
-text read from the server. If C<FH> is given then the lines returned
-from the server are printed to the filehandle C<FH>.
+text read from the server. If C<$fh> is given then the lines returned
+from the server are printed to the filehandle C<$fh>.
 
-=item getfh ( MSGNUM )
+=item C<getfh($msgnum)>
 
 As per get(), but returns a tied filehandle.  Reading from this
 filehandle returns the requested message.  The filehandle will return
 EOF at the end of the message and should not be reused.
 
-=item last ()
+=item C<last()>
 
-Returns the highest C<MSGNUM> of all the messages accessed.
+Returns the highest C<$msgnum> of all the messages accessed.
 
-=item popstat ()
+=item C<popstat()>
 
 Returns a list of two elements. These are the number of undeleted
 elements and the size of the mbox in octets.
 
-=item ping ( USER )
+=item C<ping($user)>
 
 Returns a list of two elements. These are the number of new messages
-and the total number of messages for C<USER>.
+and the total number of messages for C<$user>.
 
-=item uidl ( [ MSGNUM ] )
+=item C<uidl([$msgnum])>
 
-Returns a unique identifier for C<MSGNUM> if given. If C<MSGNUM> is not
+Returns a unique identifier for C<$msgnum> if given. If C<$msgnum> is not
 given C<uidl> returns a reference to a hash where the keys are the
 message numbers and the values are the unique identifiers.
 
-=item delete ( MSGNUM )
+=item C<delete($msgnum)>
 
-Mark message C<MSGNUM> to be deleted from the remote mailbox. All messages
+Mark message C<$msgnum> to be deleted from the remote mailbox. All messages
 that are marked to be deleted will be removed from the remote mailbox
 when the server connection closed.
 
-=item reset ()
+=item C<reset()>
 
 Reset the status of the remote POP3 server. This includes resetting the
 status of all messages to not be deleted.
 
-=item quit ()
+=item C<quit()>
 
 Quit and close the connection to the remote POP3 server. Any messages marked
 as deleted will be deleted from the remote mailbox.
 
-=item can_inet6 ()
+=item C<can_inet6()>
 
 Returns whether we can use IPv6.
 
-=item can_ssl ()
+=item C<can_ssl()>
 
 Returns whether we can use SSL.
 
 =back
 
-=head1 NOTES
+=head2 Notes
 
 If a C<Net::POP3> object goes out of scope before C<quit> method is called
 then the C<reset> method will called before the connection is closed. This
 means that any messages marked to be deleted will not be.
 
+=head1 EXPORTS
+
+I<None>.
+
+=head1 KNOWN BUGS
+
+See L<https://rt.cpan.org/Dist/Display.html?Status=Active&Queue=libnet>.
+
 =head1 SEE ALSO
 
 L<Net::Netrc>,
 L<Net::Cmd>,
-L<IO::Socket::SSL>
+L<IO::Socket::SSL>.
 
 =head1 AUTHOR
 
-Graham Barr E<lt>F<gbarr@pobox.com>E<gt>.
+Graham Barr E<lt>L<gbarr@pobox.com|mailto:gbarr@pobox.com>E<gt>.
 
-Steve Hay E<lt>F<shay@cpan.org>E<gt> is now maintaining libnet as of version
-1.22_02.
+Steve Hay E<lt>L<shay@cpan.org|mailto:shay@cpan.org>E<gt> is now maintaining
+libnet as of version 1.22_02.
 
 =head1 COPYRIGHT
 
 Copyright (C) 1995-2004 Graham Barr.  All rights reserved.
 
-Copyright (C) 2013-2016 Steve Hay.  All rights reserved.
+Copyright (C) 2013-2016, 2020 Steve Hay.  All rights reserved.
 
 =head1 LICENCE
 
@@ -860,4 +867,16 @@ This module is free software; you can redistribute it and/or modify it under the
 same terms as Perl itself, i.e. under the terms of either the GNU General Public
 License or the Artistic License, as specified in the F<LICENCE> file.
 
+=head1 VERSION
+
+Version 3.12
+
+=head1 DATE
+
+09 Dec 2020
+
+=head1 HISTORY
+
+See the F<Changes> file.
+
 =cut
index 5eaf422..fd81d0b 100644 (file)
@@ -1,7 +1,7 @@
 # Net::SMTP.pm
 #
 # Copyright (C) 1995-2004 Graham Barr.  All rights reserved.
-# Copyright (C) 2013-2016 Steve Hay.  All rights reserved.
+# Copyright (C) 2013-2016, 2020 Steve Hay.  All rights reserved.
 # This module is free software; you can redistribute it and/or modify it under
 # the same terms as Perl itself, i.e. under the terms of either the GNU General
 # Public License or the Artistic License, as specified in the F<LICENCE> file.
@@ -19,7 +19,7 @@ use Net::Cmd;
 use Net::Config;
 use Socket;
 
-our $VERSION = "3.11";
+our $VERSION = "3.12";
 
 # Code for detecting if we can use SSL
 my $ssl_class = eval {
@@ -663,57 +663,23 @@ explicit TLS encryption, i.e. SMTPS or SMTP+STARTTLS.
 The Net::SMTP class is a subclass of Net::Cmd and (depending on avaibility) of
 IO::Socket::IP, IO::Socket::INET6 or IO::Socket::INET.
 
-=head1 EXAMPLES
-
-This example prints the mail domain name of the SMTP server known as mailhost:
-
-    #!/usr/local/bin/perl -w
-
-    use Net::SMTP;
-
-    $smtp = Net::SMTP->new('mailhost');
-    print $smtp->domain,"\n";
-    $smtp->quit;
-
-This example sends a small message to the postmaster at the SMTP server
-known as mailhost:
-
-    #!/usr/local/bin/perl -w
-
-    use Net::SMTP;
-
-    my $smtp = Net::SMTP->new('mailhost');
-
-    $smtp->mail($ENV{USER});
-    if ($smtp->to('postmaster')) {
-     $smtp->data();
-     $smtp->datasend("To: postmaster\n");
-     $smtp->datasend("\n");
-     $smtp->datasend("A simple test message\n");
-     $smtp->dataend();
-    } else {
-     print "Error: ", $smtp->message();
-    }
-
-    $smtp->quit;
-
-=head1 CONSTRUCTOR
+=head2 Class Methods
 
 =over 4
 
-=item new ( [ HOST ] [, OPTIONS ] )
+=item C<new([$host][, %options])>
 
-This is the constructor for a new Net::SMTP object. C<HOST> is the
+This is the constructor for a new Net::SMTP object. C<$host> is the
 name of the remote host to which an SMTP connection is required.
 
 On failure C<undef> will be returned and C<$@> will contain the reason
 for the failure.
 
-C<HOST> is optional. If C<HOST> is not given then it may instead be
+C<$host> is optional. If C<$host> is not given then it may instead be
 passed as the C<Host> option described below. If neither is given then
 the C<SMTP_Hosts> specified in C<Net::Config> will be used.
 
-C<OPTIONS> are passed in a hash like fashion, using key and value pairs.
+C<%options> are passed in a hash like fashion, using key and value pairs.
 Possible options are:
 
 B<Hello> - SMTP requires that you identify yourself. This option
@@ -748,16 +714,14 @@ class. Alternatively B<Family> can be used.
 B<Timeout> - Maximum time, in seconds, to wait for a response from the
 SMTP server (default: 120)
 
-B<ExactAddresses> - If true the all ADDRESS arguments must be as
+B<ExactAddresses> - If true then all C<$address> arguments must be as
 defined by C<addr-spec> in RFC2822. If not given, or false, then
 Net::SMTP will attempt to extract the address from the value passed.
 
 B<Debug> - Enable debugging information
 
-
 Example:
 
-
     $smtp = Net::SMTP->new('mailhost',
                            Hello => 'my.mail.domain',
                            Timeout => 30,
@@ -788,7 +752,7 @@ Example:
 
 =back
 
-=head1 METHODS
+=head1 Object Methods
 
 Unless otherwise stated all methods return either a I<true> or I<false>
 value, with I<true> meaning that the operation was a success. When a method
@@ -801,60 +765,60 @@ documented here.
 
 =over 4
 
-=item banner ()
+=item C<banner()>
 
 Returns the banner message which the server replied with when the
 initial connection was made.
 
-=item domain ()
+=item C<domain()>
 
 Returns the domain that the remote SMTP server identified itself as during
 connection.
 
-=item hello ( DOMAIN )
+=item C<hello($domain)>
 
 Tell the remote server the mail domain which you are in using the EHLO
 command (or HELO if EHLO fails).  Since this method is invoked
 automatically when the Net::SMTP object is constructed the user should
 normally not have to call it manually.
 
-=item host ()
+=item C<host()>
 
 Returns the value used by the constructor, and passed to IO::Socket::INET,
 to connect to the host.
 
-=item etrn ( DOMAIN )
+=item C<etrn($domain)>
 
-Request a queue run for the DOMAIN given.
+Request a queue run for the C<$domain> given.
 
-=item starttls ( SSLARGS )
+=item C<starttls(%sslargs)>
 
 Upgrade existing plain connection to SSL.
 You can use SSL arguments as documented in L<IO::Socket::SSL>, but it will
 usually use the right arguments already.
 
-=item auth ( USERNAME, PASSWORD )
+=item C<auth($username, $password)>
 
-=item auth ( SASL )
+=item C<auth($sasl)>
 
 Attempt SASL authentication. Requires Authen::SASL module. The first form
 constructs a new Authen::SASL object using the given username and password;
 the second form uses the given Authen::SASL object.
 
-=item mail ( ADDRESS [, OPTIONS] )
+=item C<mail($address[, %options])>
 
-=item send ( ADDRESS )
+=item C<send($address)>
 
-=item send_or_mail ( ADDRESS )
+=item C<send_or_mail($address)>
 
-=item send_and_mail ( ADDRESS )
+=item C<send_and_mail($address)>
 
-Send the appropriate command to the server MAIL, SEND, SOML or SAML. C<ADDRESS>
+Send the appropriate command to the server MAIL, SEND, SOML or SAML. C<$address>
 is the address of the sender. This initiates the sending of a message. The
 method C<recipient> should be called for each address that the message is to
 be sent to.
 
-The C<mail> method can some additional ESMTP OPTIONS which is passed
+The C<mail> method can take some additional ESMTP C<%options> which is passed
 in hash like fashion, using key and value pairs.  Possible options are:
 
  Size        => <bytes>
@@ -872,13 +836,13 @@ Status Notification).
 The submitter address in C<AUTH> option is expected to be in a format as
 required by RFC 2554, in an RFC2821-quoted form and xtext-encoded, or <> .
 
-=item reset ()
+=item C<reset()>
 
 Reset the status of the server. This may be called after a message has been 
 initiated, but before any data has been sent, to cancel the sending of the
 message.
 
-=item recipient ( ADDRESS [, ADDRESS, [...]] [, OPTIONS ] )
+=item C<recipient($address[, $address[, ...]][, %options])>
 
 Notify the server that the current message should be sent to all of the
 addresses given. Each address is sent as a separate command to the server.
@@ -886,7 +850,7 @@ Should the sending of any address result in a failure then the process is
 aborted and a I<false> value is returned. It is up to the user to call
 C<reset> if they so desire.
 
-The C<recipient> method can also pass additional case-sensitive OPTIONS as an
+The C<recipient> method can also pass additional case-sensitive C<%options> as an
 anonymous hash using key and value pairs.  Possible options are:
 
   Notify  => ['NEVER'] or ['SUCCESS','FAILURE','DELAY']  (see below)
@@ -919,8 +883,9 @@ that a DSN not be returned to the sender under any conditions."
   $smtp->recipient(@recipients, { Notify => ['NEVER'], SkipBad => 1 });  # Good
 
 You may use any combination of these three values 'SUCCESS','FAILURE','DELAY' in
-the anonymous array reference as defined by RFC3461 (see http://www.ietf.org/rfc/rfc3461.txt
-for more information.  Note: quotations in this topic from same.).
+the anonymous array reference as defined by RFC3461 (see
+L<https://www.ietf.org/rfc/rfc3461.txt> for more information.  Note: quotations
+in this topic from same.).
 
 A Notify parameter of 'SUCCESS' or 'FAILURE' "requests that a DSN be issued on
 successful delivery or delivery failure, respectively."
@@ -943,67 +908,67 @@ sent to.  The machine that generates a DSN will use this address to inform
 the sender, because he can't know if recipients get rewritten by mail servers.
 It is expected to be in a format as required by RFC3461, xtext-encoded.
 
-=item to ( ADDRESS [, ADDRESS [...]] )
+=item C<to($address[, $address[, ...]])>
 
-=item cc ( ADDRESS [, ADDRESS [...]] )
+=item C<cc($address[, $address[, ...]])>
 
-=item bcc ( ADDRESS [, ADDRESS [...]] )
+=item C<bcc($address[, $address[, ...]])>
 
 Synonyms for C<recipient>.
 
-=item data ( [ DATA ] )
+=item C<data([$data])>
 
 Initiate the sending of the data from the current message. 
 
-C<DATA> may be a reference to a list or a list and must be encoded by the
+C<$data> may be a reference to a list or a list and must be encoded by the
 caller to octets of whatever encoding is required, e.g. by using the Encode
 module's C<encode()> function.
 
-If specified the contents of C<DATA> and a termination string C<".\r\n"> is
+If specified the contents of C<$data> and a termination string C<".\r\n"> is
 sent to the server. The result will be true if the data was accepted.
 
-If C<DATA> is not specified then the result will indicate that the server
+If C<$data> is not specified then the result will indicate that the server
 wishes the data to be sent. The data must then be sent using the C<datasend>
 and C<dataend> methods described in L<Net::Cmd>.
 
-=item bdat ( DATA )
+=item C<bdat($data)>
 
-=item bdatlast ( DATA )
+=item C<bdatlast($data)>
 
-Use the alternate DATA command "BDAT" of the data chunking service extension
+Use the alternate C<$data> command "BDAT" of the data chunking service extension
 defined in RFC1830 for efficiently sending large MIME messages.
 
-=item expand ( ADDRESS )
+=item C<expand($address)>
 
 Request the server to expand the given address Returns an array
 which contains the text read from the server.
 
-=item verify ( ADDRESS )
+=item C<verify($address)>
 
-Verify that C<ADDRESS> is a legitimate mailing address.
+Verify that C<$address> is a legitimate mailing address.
 
 Most sites usually disable this feature in their SMTP service configuration.
 Use "Debug => 1" option under new() to see if disabled.
 
-=item help ( [ $subject ] )
+=item C<help([$subject])>
 
 Request help text from the server. Returns the text or undef upon failure
 
-=item quit ()
+=item C<quit()>
 
 Send the QUIT command to the remote SMTP server and close the socket connection.
 
-=item can_inet6 ()
+=item C<can_inet6()>
 
 Returns whether we can use IPv6.
 
-=item can_ssl ()
+=item C<can_ssl()>
 
 Returns whether we can use SSL.
 
 =back
 
-=head1 ADDRESSES
+=head2 Addresses
 
 Net::SMTP attempts to DWIM with addresses that are passed. For
 example an application might extract The From: line from an email
@@ -1019,23 +984,65 @@ accept the address surrounded by angle brackets.
  "funny user"@domain    RIGHT, recommended
  <"funny user"@domain>  OK
 
+=head1 EXAMPLES
+
+This example prints the mail domain name of the SMTP server known as mailhost:
+
+    #!/usr/local/bin/perl -w
+
+    use Net::SMTP;
+
+    $smtp = Net::SMTP->new('mailhost');
+    print $smtp->domain,"\n";
+    $smtp->quit;
+
+This example sends a small message to the postmaster at the SMTP server
+known as mailhost:
+
+    #!/usr/local/bin/perl -w
+
+    use Net::SMTP;
+
+    my $smtp = Net::SMTP->new('mailhost');
+
+    $smtp->mail($ENV{USER});
+    if ($smtp->to('postmaster')) {
+     $smtp->data();
+     $smtp->datasend("To: postmaster\n");
+     $smtp->datasend("\n");
+     $smtp->datasend("A simple test message\n");
+     $smtp->dataend();
+    } else {
+     print "Error: ", $smtp->message();
+    }
+
+    $smtp->quit;
+
+=head1 EXPORTS
+
+I<None>.
+
+=head1 KNOWN BUGS
+
+See L<https://rt.cpan.org/Dist/Display.html?Status=Active&Queue=libnet>.
+
 =head1 SEE ALSO
 
 L<Net::Cmd>,
-L<IO::Socket::SSL>
+L<IO::Socket::SSL>.
 
 =head1 AUTHOR
 
-Graham Barr E<lt>F<gbarr@pobox.com>E<gt>.
+Graham Barr E<lt>L<gbarr@pobox.com|mailto:gbarr@pobox.com>E<gt>.
 
-Steve Hay E<lt>F<shay@cpan.org>E<gt> is now maintaining libnet as of version
-1.22_02.
+Steve Hay E<lt>L<shay@cpan.org|mailto:shay@cpan.org>E<gt> is now maintaining
+libnet as of version 1.22_02.
 
 =head1 COPYRIGHT
 
 Copyright (C) 1995-2004 Graham Barr.  All rights reserved.
 
-Copyright (C) 2013-2016 Steve Hay.  All rights reserved.
+Copyright (C) 2013-2016, 2020 Steve Hay.  All rights reserved.
 
 =head1 LICENCE
 
@@ -1043,4 +1050,16 @@ This module is free software; you can redistribute it and/or modify it under the
 same terms as Perl itself, i.e. under the terms of either the GNU General Public
 License or the Artistic License, as specified in the F<LICENCE> file.
 
+=head1 VERSION
+
+Version 3.12
+
+=head1 DATE
+
+09 Dec 2020
+
+=head1 HISTORY
+
+See the F<Changes> file.
+
 =cut
index d049408..4ce1daf 100644 (file)
@@ -1,7 +1,7 @@
 # Net::Time.pm
 #
 # Copyright (C) 1995-2004 Graham Barr.  All rights reserved.
-# Copyright (C) 2014 Steve Hay.  All rights reserved.
+# Copyright (C) 2014, 2020 Steve Hay.  All rights reserved.
 # This module is free software; you can redistribute it and/or modify it under
 # the same terms as Perl itself, i.e. under the terms of either the GNU General
 # Public License or the Artistic License, as specified in the F<LICENCE> file.
@@ -22,7 +22,7 @@ use Net::Config;
 our @ISA       = qw(Exporter);
 our @EXPORT_OK = qw(inet_time inet_daytime);
 
-our $VERSION = "3.11";
+our $VERSION = "3.12";
 
 our $TIMEOUT = 120;
 
@@ -123,37 +123,64 @@ Net::Time - time and daytime network client interface
 
 C<Net::Time> provides subroutines that obtain the time on a remote machine.
 
+=head2 Functions
+
 =over 4
 
-=item inet_time ( [HOST [, PROTOCOL [, TIMEOUT]]])
+=item C<inet_time([$host[, $protocol[, $timeout]]])>
 
-Obtain the time on C<HOST>, or some default host if C<HOST> is not given
+Obtain the time on C<$host>, or some default host if C<$host> is not given
 or not defined, using the protocol as defined in RFC868. The optional
-argument C<PROTOCOL> should define the protocol to use, either C<tcp> or
+argument C<$protocol> should define the protocol to use, either C<tcp> or
 C<udp>. The result will be a time value in the same units as returned
 by time() or I<undef> upon failure.
 
-=item inet_daytime ( [HOST [, PROTOCOL [, TIMEOUT]]])
+=item C<inet_daytime([$host[, $protocol[, $timeout]]])>
 
-Obtain the time on C<HOST>, or some default host if C<HOST> is not given
+Obtain the time on C<$host>, or some default host if C<$host> is not given
 or not defined, using the protocol as defined in RFC867. The optional
-argument C<PROTOCOL> should define the protocol to use, either C<tcp> or
+argument C<$protocol> should define the protocol to use, either C<tcp> or
 C<udp>. The result will be an ASCII string or I<undef> upon failure.
 
 =back
 
+=head1 EXPORTS
+
+The following symbols are, or can be, exported by this module:
+
+=over 4
+
+=item Default Exports
+
+I<None>.
+
+=item Optional Exports
+
+C<inet_time>,
+C<inet_daytime>.
+
+=item Export Tags
+
+I<None>.
+
+=back
+
+=head1 KNOWN BUGS
+
+I<None>.
+
 =head1 AUTHOR
 
-Graham Barr E<lt>F<gbarr@pobox.com>E<gt>.
+Graham Barr E<lt>L<gbarr@pobox.com|mailto:gbarr@pobox.com>E<gt>.
 
-Steve Hay E<lt>F<shay@cpan.org>E<gt> is now maintaining libnet as of version
-1.22_02.
+Steve Hay E<lt>L<shay@cpan.org|mailto:shay@cpan.org>E<gt> is now maintaining
+libnet as of version 1.22_02.
 
 =head1 COPYRIGHT
 
 Copyright (C) 1995-2004 Graham Barr.  All rights reserved.
 
-Copyright (C) 2014 Steve Hay.  All rights reserved.
+Copyright (C) 2014, 2020 Steve Hay.  All rights reserved.
 
 =head1 LICENCE
 
@@ -161,4 +188,16 @@ This module is free software; you can redistribute it and/or modify it under the
 same terms as Perl itself, i.e. under the terms of either the GNU General Public
 License or the Artistic License, as specified in the F<LICENCE> file.
 
+=head1 VERSION
+
+Version 3.12
+
+=head1 DATE
+
+09 Dec 2020
+
+=head1 HISTORY
+
+See the F<Changes> file.
+
 =cut
index bcc5347..4a3b183 100644 (file)
@@ -9,23 +9,25 @@ libnetFAQ - libnet Frequently Asked Questions
 This document is distributed with the libnet distribution, and is also
 available on the libnet web page at
 
-    http://search.cpan.org/dist/libnet/
+L<https://metacpan.org/release/libnet>
 
 =head2 How to contribute to this document
 
 You may report corrections, additions, and suggestions on the
 CPAN Request Tracker at
 
-    http://rt.cpan.org/Public/Bug/Report.html?Queue=libnet
+L<https://rt.cpan.org/Public/Bug/Report.html?Queue=libnet>
 
 =head1 Author and Copyright Information
 
 Copyright (C) 1997-1998 Graham Barr.  All rights reserved.
-This document is free; you can redistribute it and/or modify it
-under the terms of the Artistic License.
+This document is free; you can redistribute it and/or modify it under
+the same terms as Perl itself, i.e. under the terms of either the GNU
+General Public License or the Artistic License, as specified in the
+F<LICENCE> file.
 
-Steve Hay E<lt>F<shay@cpan.org>E<gt> is now maintaining libnet as of version
-1.22_02.
+Steve Hay E<lt>L<shay@cpan.org|mailto:shay@cpan.org>E<gt> is now maintaining
+libnet as of version 1.22_02.
 
 =head2 Disclaimer
 
@@ -70,7 +72,7 @@ on any machine that perl runs on.
 The latest libnet release is always on CPAN, you will find it
 in 
 
- http://search.cpan.org/dist/libnet/
+L<https://metacpan.org/release/libnet>
 
 =head1 Using Net::FTP
 
index 3c29a03..897ca21 100644 (file)
@@ -5,15 +5,21 @@ use 5.008001;
 use strict;
 use warnings;
 
+use Test::More;
+
 BEGIN {
     if (!eval { require Socket }) {
-        print "1..0 # no Socket\n"; exit 0;
+        plan skip_all => "no Socket";
+    }
+    elsif (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
+        plan skip_all => "EBCDIC but no Convert::EBCDIC";
+    }
+    else {
+        plan tests => 10;
     }
+
     undef *{Socket::inet_aton};
     undef *{Socket::inet_ntoa};
-    if (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
-        print "1..0 # EBCDIC but no Convert::EBCDIC\n"; exit 0;
-    }
     $INC{'Socket.pm'} = 1;
 }
 
@@ -45,13 +51,8 @@ sub inet_ntoa {
         return $names{$_[0]};
 }
 
-package main;
-
 
-(my $libnet_t = __FILE__) =~ s/config.t/libnet_t.pl/;
-require $libnet_t;
-
-print "1..10\n";
+package main;
 
 use Net::Config;
 ok( exists $INC{'Net/Config.pm'}, 'Net::Config should have been used' );
index 0aea9d4..7902c17 100644 (file)
@@ -5,12 +5,17 @@ use 5.008001;
 use strict;
 use warnings;
 
+use Test::More;
+
 BEGIN {
     if (!eval { require Socket }) {
-        print "1..0 # no Socket\n"; exit 0;
+        plan skip_all => "no Socket";
+    }
+    elsif (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
+        plan skip_all => "EBCDIC but no Convert::EBCDIC";
     }
-    if (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
-        print "1..0 # EBCDIC but no Convert::EBCDIC\n"; exit 0;
+    else {
+        plan tests => 54;
     }
 }
 
@@ -41,11 +46,6 @@ BEGIN {
   }
 }
 
-(my $libnet_t = __FILE__) =~ s/datasend.t/libnet_t.pl/;
-require $libnet_t or die;
-
-print "1..54\n";
-
 sub check {
   my $expect = pop;
   my $cmd = Foo->new;
index 16cb868..69af504 100644 (file)
@@ -7,7 +7,7 @@ use warnings;
 
 BEGIN {
     if (!eval { require Socket }) {
-        print "1..0 # Skip: no Socket module\n"; exit 0;
+        print "1..0 # Skip: no Socket\n"; exit 0;
     }
     if (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
         print "1..0 # Skip: EBCDIC but no Convert::EBCDIC\n"; exit 0;
index 55031bf..5e20b81 100644 (file)
@@ -7,10 +7,10 @@ use warnings;
 
 BEGIN {
     if (!eval { require Socket }) {
-        print "1..0 # no Socket\n"; exit 0;
+        print "1..0 # Skip: no Socket\n"; exit 0;
     }
     if (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
-        print "1..0 # EBCDIC but no Convert::EBCDIC\n"; exit 0;
+        print "1..0 # Skip: EBCDIC but no Convert::EBCDIC\n"; exit 0;
     }
 }
 
@@ -18,7 +18,7 @@ use Net::Domain qw(hostname domainname hostdomain hostfqdn);
 use Net::Config;
 
 unless($NetConfig{test_hosts}) {
-    print "1..0\n";
+    print "1..0 # Skip: test_hosts not enabled in config\n";
     exit 0;
 }
 
diff --git a/cpan/libnet/t/libnet_t.pl b/cpan/libnet/t/libnet_t.pl
deleted file mode 100644 (file)
index cc512ca..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-use 5.008001;
-
-use strict;
-use warnings;
-
-my $number = 0;
-sub ok {
-        my ($condition, $name) = @_;
-
-        my $message = $condition ? "ok " : "not ok ";
-        $message .= ++$number;
-        $message .= " # $name" if defined $name;
-        print $message, "\n";
-        return $condition;
-}
-
-sub is {
-        my ($got, $expected, $name) = @_;
-
-        for ($got, $expected) {
-                $_ = 'undef' unless defined $_;
-        }
-
-        unless (ok($got eq $expected, $name)) {
-                warn "Got: '$got'\nExpected: '$expected'\n" . join(' ', caller) . "\n";
-        }
-}
-
-sub skip {
-        my ($reason, $num) = @_;
-        $reason ||= '';
-        $number ||= 1;
-
-        for (1 .. $num) {
-                $number++;
-                print "ok $number # skip $reason\n";
-        }
-}
-
-1;
-
index e270b36..ba0183c 100644 (file)
@@ -5,17 +5,21 @@ use 5.008001;
 use strict;
 use warnings;
 
+use Test::More;
+
 BEGIN {
     if (!eval { require Socket }) {
-        print "1..0 # no Socket\n"; exit 0;
+        plan skip_all => "no Socket";
+    }
+    elsif (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
+        plan skip_all => "EBCDIC but no Convert::EBCDIC";
     }
-    if (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
-        print "1..0 # EBCDIC but no Convert::EBCDIC\n"; exit 0;
+    else {
+        plan tests => 20;
     }
 }
 
 use Cwd;
-print "1..20\n";
 
 # for testing _readrc
 $ENV{HOME} = Cwd::cwd();
@@ -36,9 +40,6 @@ my @stat;
 # for testing _readrc
 $INC{'FileHandle.pm'} = 1;
 
-(my $libnet_t = __FILE__) =~ s/\w+.t$/libnet_t.pl/;
-require $libnet_t;
-
 # now that the tricks are out of the way...
 eval { require Net::Netrc; };
 ok( !$@, 'should be able to require() Net::Netrc safely' );
index 559f398..b346caa 100644 (file)
@@ -7,10 +7,10 @@ use warnings;
 
 BEGIN {
     if (!eval { require Socket }) {
-        print "1..0 # no Socket\n"; exit 0;
+        print "1..0 # Skip: no Socket\n"; exit 0;
     }
     if (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
-        print "1..0 # EBCDIC but no Convert::EBCDIC\n"; exit 0;
+        print "1..0 # Skip: EBCDIC but no Convert::EBCDIC\n"; exit 0;
     }
 }
 
@@ -18,8 +18,13 @@ use Net::Config;
 use Net::NNTP;
 use Net::Cmd qw(CMD_REJECT);
 
-unless(@{$NetConfig{nntp_hosts}} && $NetConfig{test_hosts}) {
-    print "1..0\n";
+unless(@{$NetConfig{nntp_hosts}}) {
+    print "1..0 # Skip: no nntp_hosts defined in config\n";
+    exit;
+}
+
+unless($NetConfig{test_hosts}) {
+    print "1..0 # Skip: test_hosts not enabled in config\n";
     exit;
 }
 
index 768489a..af1ba16 100644 (file)
@@ -5,10 +5,20 @@ use 5.008001;
 use strict;
 use warnings;
 
+use Test::More;
+
+BEGIN {
+    if (!eval { require Socket }) {
+        plan skip_all => "no Socket";
+    }
+    elsif (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
+        plan skip_all => "EBCDIC but no Convert::EBCDIC";
+    }
+}
+
 use Config;
 use File::Temp 'tempfile';
 use Net::NNTP;
-use Test::More;
 
 my $debug = 0; # Net::NNTP->new( Debug => .. )
 
index e6a4fe5..5120e92 100644 (file)
@@ -5,10 +5,20 @@ use 5.008001;
 use strict;
 use warnings;
 
+use Test::More;
+
+BEGIN {
+    if (!eval { require Socket }) {
+        plan skip_all => "no Socket";
+    }
+    elsif (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
+        plan skip_all => "EBCDIC but no Convert::EBCDIC";
+    }
+}
+
 use Config;
 use File::Temp 'tempfile';
 use Net::NNTP;
-use Test::More;
 
 my $debug = 0; # Net::NNTP Debug => ..
 
index db31128..e684122 100644 (file)
@@ -5,10 +5,20 @@ use 5.008001;
 use strict;
 use warnings;
 
+use Test::More;
+
+BEGIN {
+    if (!eval { require Socket }) {
+        plan skip_all => "no Socket";
+    }
+    elsif (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
+        plan skip_all => "EBCDIC but no Convert::EBCDIC";
+    }
+}
+
 use Config;
 use File::Temp 'tempfile';
 use Net::POP3;
-use Test::More;
 
 my $debug = 0; # Net::POP3->new( Debug => .. )
 
index 356de40..12d31ec 100644 (file)
@@ -5,10 +5,20 @@ use 5.008001;
 use strict;
 use warnings;
 
+use Test::More;
+
+BEGIN {
+    if (!eval { require Socket }) {
+        plan skip_all => "no Socket";
+    }
+    elsif (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
+        plan skip_all => "EBCDIC but no Convert::EBCDIC";
+    }
+}
+
 use Config;
 use File::Temp 'tempfile';
 use Net::POP3;
-use Test::More;
 
 my $debug = 0; # Net::POP3 Debug => ..
 
index 70ec1f6..cc14b4b 100644 (file)
@@ -7,10 +7,10 @@ use warnings;
 
 BEGIN {
     if (!eval { require Socket }) {
-        print "1..0 # no Socket\n"; exit 0;
+        print "1..0 # Skip: no Socket\n"; exit 0;
     }
     if (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
-        print "1..0 # EBCDIC but no Convert::EBCDIC\n"; exit 0;
+        print "1..0 # Skip: EBCDIC but no Convert::EBCDIC\n"; exit 0;
     }
 }
 
index 9d6f65a..e2cd6eb 100644 (file)
@@ -7,18 +7,23 @@ use warnings;
 
 BEGIN {
     if (!eval { require Socket }) {
-        print "1..0 # no Socket\n"; exit 0;
+        print "1..0 # Skip: no Socket\n"; exit 0;
     }
-    if (ord('A') == 193 && eval { require Convert::EBCDIC }) {
-        print "1..0 # EBCDIC but no Convert::EBCDIC\n"; exit 0;
+    if (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
+        print "1..0 # Skip: EBCDIC but no Convert::EBCDIC\n"; exit 0;
     }
 }
 
 use Net::Config;
 use Net::SMTP;
 
-unless(@{$NetConfig{smtp_hosts}} && $NetConfig{test_hosts}) {
-    print "1..0\n";
+unless(@{$NetConfig{smtp_hosts}}) {
+    print "1..0 # Skip: no smtp_hosts defined in config\n";
+    exit 0;
+}
+
+unless($NetConfig{test_hosts}) {
+    print "1..0 # Skip: test_hosts not enabled in config\n";
     exit 0;
 }
 
index f430721..d0bdb90 100644 (file)
@@ -5,10 +5,20 @@ use 5.008001;
 use strict;
 use warnings;
 
+use Test::More;
+
+BEGIN {
+    if (!eval { require Socket }) {
+        plan skip_all => "no Socket";
+    }
+    elsif (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
+        plan skip_all => "EBCDIC but no Convert::EBCDIC";
+    }
+}
+
 use Config;
 use File::Temp 'tempfile';
 use Net::SMTP;
-use Test::More;
 
 my $debug = 0; # Net::SMTP->new( Debug => .. )
 
index 7290176..314dcb7 100644 (file)
@@ -5,10 +5,20 @@ use 5.008001;
 use strict;
 use warnings;
 
+use Test::More;
+
+BEGIN {
+    if (!eval { require Socket }) {
+        plan skip_all => "no Socket";
+    }
+    elsif (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
+        plan skip_all => "EBCDIC but no Convert::EBCDIC";
+    }
+}
+
 use Config;
 use File::Temp 'tempfile';
 use Net::SMTP;
-use Test::More;
 
 my $debug = 0; # Net::SMTP Debug => ..
 
index 6dcba3a..1b02d60 100644 (file)
@@ -5,22 +5,24 @@ use 5.008001;
 use strict;
 use warnings;
 
+use Test::More;
+
 BEGIN {
     if (!eval { require Socket }) {
-        print "1..0 # no Socket\n"; exit 0;
+        plan skip_all => "no Socket";
+    }
+    elsif (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
+        plan skip_all => "EBCDIC but no Convert::EBCDIC";
     }
-    if (ord('A') == 193 && !eval { require Convert::EBCDIC }) {
-        print "1..0 # EBCDIC but no Convert::EBCDIC\n"; exit 0;
+    else {
+        plan tests => 12;
     }
+
     $INC{'IO/Socket.pm'} = 1;
     $INC{'IO/Select.pm'} = 1;
     $INC{'IO/Socket/INET.pm'} = 1;
 }
 
-(my $libnet_t = __FILE__) =~ s/time.t/libnet_t.pl/;
-require $libnet_t;
-
-print "1..12\n";
 # cannot use(), otherwise it will use IO::Socket and IO::Select
 eval{ require Net::Time; };
 ok( !$@, 'should be able to require() Net::Time safely' );
diff --git a/cpan/perlfaq/.gitignore b/cpan/perlfaq/.gitignore
new file mode 100644 (file)
index 0000000..e988940
--- /dev/null
@@ -0,0 +1,10 @@
+/Changes
+/LICENSE
+/MANIFEST
+/META.json
+/META.yml
+/README
+/dist.ini
+/inc/
+/t/00-compile.t
+/xt/
diff --git a/cpan/podlators/.gitignore b/cpan/podlators/.gitignore
new file mode 100644 (file)
index 0000000..8539efd
--- /dev/null
@@ -0,0 +1,21 @@
+/Build
+/Build.bat
+/MANIFEST.bak
+/Makefile
+/Makefile.old
+/META.json
+/META.yml
+/MYMETA.json
+/MYMETA.yml
+/_build/
+/blib/
+/cover_db/
+/nytprof.out
+/nytprof/
+/pm_to_blib
+/podlators-*/
+/podlators-*.tar.gz
+/podlators-*.tar.gz.asc
+/scripts/pod2man
+/scripts/pod2text
+!/Makefile.PL
index 3bb5818..bbb3e1a 100644 (file)
@@ -167,7 +167,7 @@ wide_to_utf8(const wchar_t *wbuf)
     /* Here and elsewhere in this file, we have a critical section to prevent
      * another thread from changing the locale out from under us.  XXX But why
      * not just use uvchr_to_utf8? */
-    LOCALE_LOCK;
+    SETLOCALE_LOCK;
 
     oldlocale = setlocale(LC_CTYPE, NULL);
     setlocale(LC_CTYPE, "utf-8");
@@ -180,7 +180,7 @@ wide_to_utf8(const wchar_t *wbuf)
     if (oldlocale) setlocale(LC_CTYPE, oldlocale);
     else setlocale(LC_CTYPE, "C");
 
-    LOCALE_UNLOCK;
+    SETLOCALE_UNLOCK;
 
     return buf;
 }
@@ -193,7 +193,7 @@ utf8_to_wide(const char *buf)
     char *oldlocale;
     int wlen = sizeof(wchar_t)*strlen(buf);
 
-    LOCALE_LOCK;
+    SETLOCALE_LOCK;
 
     oldlocale = setlocale(LC_CTYPE, NULL);
 
@@ -205,7 +205,7 @@ utf8_to_wide(const char *buf)
     if (oldlocale) setlocale(LC_CTYPE, oldlocale);
     else setlocale(LC_CTYPE, "C");
 
-    LOCALE_UNLOCK;
+    SETLOCALE_UNLOCK;
 
     return wbuf;
 }
@@ -307,7 +307,7 @@ XS(XS_Cygwin_win_to_posix_path)
            mbstate_t mbs;
             char *oldlocale;
 
-            LOCALE_LOCK;
+            SETLOCALE_LOCK;
 
             oldlocale = setlocale(LC_CTYPE, NULL);
             setlocale(LC_CTYPE, "utf-8");
@@ -318,7 +318,7 @@ XS(XS_Cygwin_win_to_posix_path)
             if (oldlocale) setlocale(LC_CTYPE, oldlocale);
             else setlocale(LC_CTYPE, "C");
 
-            LOCALE_UNLOCK;
+            SETLOCALE_UNLOCK;
        } else { /* use bytes; assume already ucs-2 encoded bytestream */
            err = cygwin_conv_path(what, src_path, wbuf, wlen);
        }
@@ -398,7 +398,7 @@ XS(XS_Cygwin_posix_to_win_path)
        wchar_t *wbuf = (wchar_t *) safemalloc(wlen);
        char *oldlocale;
 
-        LOCALE_LOCK;
+        SETLOCALE_LOCK;
 
        oldlocale = setlocale(LC_CTYPE, NULL);
        setlocale(LC_CTYPE, "utf-8");
@@ -424,7 +424,7 @@ XS(XS_Cygwin_posix_to_win_path)
        if (oldlocale) setlocale(LC_CTYPE, oldlocale);
        else setlocale(LC_CTYPE, "C");
 
-        LOCALE_UNLOCK;
+        SETLOCALE_UNLOCK;
     } else {
        int what = absolute_flag ? CCP_POSIX_TO_WIN_A : CCP_POSIX_TO_WIN_A | CCP_RELATIVE;
        win_path = (char *) safemalloc(len + 260 + 1001);
diff --git a/dist/.gitignore b/dist/.gitignore
new file mode 100644 (file)
index 0000000..d8a22d5
--- /dev/null
@@ -0,0 +1,10 @@
+# ignore generated .c files, and other module build traces
+*.c
+*.bs
+blib
+pm_to_blib
+Makefile
+Makefile.PL
+ppport.h
+Time-HiRes/*.inc
+Time-HiRes/xdefine
diff --git a/dist/Carp/.gitignore b/dist/Carp/.gitignore
new file mode 100644 (file)
index 0000000..e54624d
--- /dev/null
@@ -0,0 +1 @@
+!/Makefile.PL
index 109b7fe..941f59d 100644 (file)
@@ -211,7 +211,7 @@ BEGIN {
 }
 
 
-our $VERSION = '1.50';
+our $VERSION = '1.51';
 $VERSION =~ tr/_//d;
 
 our $MaxEvalLen = 0;
@@ -284,7 +284,7 @@ sub shortmess {
     my $cgc = _cgc();
 
     # Icky backwards compatibility wrapper. :-(
-    local @CARP_NOT = $cgc ? $cgc->() : caller();
+    local @CARP_NOT = scalar( $cgc ? $cgc->() : caller() );
     shortmess_heavy(@_);
 }
 
index a9b803c..028d2a2 100644 (file)
@@ -2,7 +2,7 @@ package Carp::Heavy;
 
 use Carp ();
 
-our $VERSION = '1.50';
+our $VERSION = '1.51';
 $VERSION =~ tr/_//d;
 
 # Carp::Heavy was merged into Carp in version 1.12.  Any mismatched versions
diff --git a/dist/Devel-PPPort/.gitignore b/dist/Devel-PPPort/.gitignore
new file mode 100644 (file)
index 0000000..857c79f
--- /dev/null
@@ -0,0 +1,24 @@
+/blib/
+/Makefile
+/Makefile.old
+/MANIFEST
+/MANIFEST.bak
+/META.json
+/META.yml
+/MYMETA.*
+pm_to_blib
+/PPPort.pm
+/RealPPPort.*
+/ppport.h
+/*.o
+.DS_Store
+PPPort.bs
+/README
+/README.md
+/.travis.yml
+/Devel-PPPort-*.tar.gz
+/Devel-PPPort-*/
+/t/*.t
+!/Makefile.PL
+!/module2.c
+!/module3.c
diff --git a/dist/ExtUtils-CBuilder/.gitignore b/dist/ExtUtils-CBuilder/.gitignore
new file mode 100644 (file)
index 0000000..e54624d
--- /dev/null
@@ -0,0 +1 @@
+!/Makefile.PL
index 18ed08f..39f9df9 100644 (file)
@@ -11,7 +11,7 @@ use Symbol;
 
 our $VERSION;
 BEGIN {
-  $VERSION = '3.41';
+  $VERSION = '3.42';
   require ExtUtils::ParseXS::Constants; ExtUtils::ParseXS::Constants->VERSION($VERSION);
   require ExtUtils::ParseXS::CountLines; ExtUtils::ParseXS::CountLines->VERSION($VERSION);
   require ExtUtils::ParseXS::Utilities; ExtUtils::ParseXS::Utilities->VERSION($VERSION);
@@ -42,6 +42,7 @@ use ExtUtils::ParseXS::Utilities qw(
 our @EXPORT_OK = qw(
   process_file
   report_error_count
+  errors
 );
 
 ##############################
@@ -1012,6 +1013,7 @@ sub report_error_count {
     return $Singleton->{errors}||0;
   }
 }
+*errors = \&report_error_count;
 
 # Input:  ($self, $_, @{ $self->{line} }) == unparsed input.
 # Output: ($_, @{ $self->{line} }) == (rest of line, following lines).
index a972b63..869836c 100644 (file)
@@ -3,7 +3,7 @@ use strict;
 use warnings;
 use Symbol;
 
-our $VERSION = '3.41';
+our $VERSION = '3.42';
 
 =head1 NAME
 
index bb6450e..57aa90d 100644 (file)
@@ -1,7 +1,7 @@
 package ExtUtils::ParseXS::CountLines;
 use strict;
 
-our $VERSION = '3.41';
+our $VERSION = '3.42';
 
 our $SECTION_END_MARKER;
 
index 97aea54..45c4ba1 100644 (file)
@@ -2,7 +2,7 @@ package ExtUtils::ParseXS::Eval;
 use strict;
 use warnings;
 
-our $VERSION = '3.41';
+our $VERSION = '3.42';
 
 =head1 NAME
 
index 37b89de..faf53cb 100644 (file)
@@ -5,7 +5,7 @@ use Exporter;
 use File::Spec;
 use ExtUtils::ParseXS::Constants ();
 
-our $VERSION = '3.41';
+our $VERSION = '3.42';
 
 our (@ISA, @EXPORT_OK);
 @ISA = qw(Exporter);
index 6a48d7e..2dfbf7d 100644 (file)
@@ -2103,6 +2103,7 @@ File C<RPC.xs>: Interface to some ONC+ RPC bind library functions.
      #include "perl.h"
      #include "XSUB.h"
 
+     /* On some systems this should be <tirpc/rpc.h> */
      #include <rpc/rpc.h>
 
      typedef struct netconfig Netconfig;
@@ -2163,6 +2164,8 @@ File C<rpctest.pl>: Perl test program for the RPC extension.
      print "time = $a\n";
      print "netconf = $netconf\n";
 
+In Makefile.PL add -ltirpc and -I/usr/include/tirpc.
+
 =head1 CAVEATS
 
 XS code has full access to system calls including C library functions.
diff --git a/dist/IO/.gitignore b/dist/IO/.gitignore
new file mode 100644 (file)
index 0000000..7703c92
--- /dev/null
@@ -0,0 +1,2 @@
+!/poll.c
+!/Makefile.PL
diff --git a/dist/Module-CoreList/.gitignore b/dist/Module-CoreList/.gitignore
new file mode 100644 (file)
index 0000000..e54624d
--- /dev/null
@@ -0,0 +1 @@
+!/Makefile.PL
index bca8d50..768e99e 100644 (file)
@@ -1,3 +1,6 @@
+5.20201220
+  - Updated for v5.33.5
+
 5.20201120
   - Updated for v5.33.4
 
index b20670d..a938a03 100644 (file)
@@ -4,7 +4,7 @@ use strict;
 our ( %released, %version, %families, %upstream, %bug_tracker, %deprecated, %delta );
 
 use version;
-our $VERSION = '5.20201120';
+our $VERSION = '5.20201220';
 
 sub PKG_PATTERN () { q#\A[a-zA-Z_][0-9a-zA-Z_]*(?:(::|')[0-9a-zA-Z_]+)*\z# }
 sub _looks_like_invocant ($) { local $@; !!eval { $_[0]->isa(__PACKAGE__) } }
@@ -371,6 +371,7 @@ sub changes_between {
     5.033002 => '2020-09-20',
     5.033003 => '2020-10-20',
     5.033004 => '2020-11-20',
+    5.033005 => '2020-12-20',
   );
 
 for my $version ( sort { $a <=> $b } keys %released ) {
@@ -18086,6 +18087,114 @@ for my $version ( sort { $a <=> $b } keys %released ) {
         removed => {
         }
     },
+    5.033005 => {
+        delta_from => 5.033004,
+        changed => {
+            'App::Prove'            => '3.43',
+            'App::Prove::State'     => '3.43',
+            'App::Prove::State::Result'=> '3.43',
+            'App::Prove::State::Result::Test'=> '3.43',
+            'B::Op_private'         => '5.033005',
+            'Carp'                  => '1.51',
+            'Carp::Heavy'           => '1.51',
+            'Config'                => '5.033005',
+            'Config::Perl::V'       => '0.33',
+            'Cwd'                   => '3.80',
+            'DynaLoader'            => '1.49',
+            'Encode'                => '3.08',
+            'Encode::GSM0338'       => '2.09',
+            'ExtUtils::Install'     => '2.20',
+            'ExtUtils::Installed'   => '2.20',
+            'ExtUtils::Packlist'    => '2.20',
+            'ExtUtils::ParseXS'     => '3.42',
+            'ExtUtils::ParseXS::Constants'=> '3.42',
+            'ExtUtils::ParseXS::CountLines'=> '3.42',
+            'ExtUtils::ParseXS::Eval'=> '3.42',
+            'ExtUtils::ParseXS::Utilities'=> '3.42',
+            'File::Copy'            => '2.35',
+            'File::Find'            => '1.38',
+            'File::Spec'            => '3.80',
+            'File::Spec::AmigaOS'   => '3.80',
+            'File::Spec::Cygwin'    => '3.80',
+            'File::Spec::Epoc'      => '3.80',
+            'File::Spec::Functions' => '3.80',
+            'File::Spec::Mac'       => '3.80',
+            'File::Spec::OS2'       => '3.80',
+            'File::Spec::Unix'      => '3.80',
+            'File::Spec::VMS'       => '3.80',
+            'File::Spec::Win32'     => '3.80',
+            'Module::CoreList'      => '5.20201220',
+            'Module::CoreList::Utils'=> '5.20201220',
+            'Net::Cmd'              => '3.12',
+            'Net::Config'           => '3.12',
+            'Net::Domain'           => '3.12',
+            'Net::FTP'              => '3.12',
+            'Net::FTP::A'           => '3.12',
+            'Net::FTP::E'           => '3.12',
+            'Net::FTP::I'           => '3.12',
+            'Net::FTP::L'           => '3.12',
+            'Net::FTP::dataconn'    => '3.12',
+            'Net::NNTP'             => '3.12',
+            'Net::Netrc'            => '3.12',
+            'Net::POP3'             => '3.12',
+            'Net::SMTP'             => '3.12',
+            'Net::Time'             => '3.12',
+            'ODBM_File'             => '1.17',
+            'Opcode'                => '1.49',
+            'POSIX'                 => '1.96',
+            'PerlIO::via::QuotedPrint'=> '0.09',
+            'TAP::Base'             => '3.43',
+            'TAP::Formatter::Base'  => '3.43',
+            'TAP::Formatter::Color' => '3.43',
+            'TAP::Formatter::Console'=> '3.43',
+            'TAP::Formatter::Console::ParallelSession'=> '3.43',
+            'TAP::Formatter::Console::Session'=> '3.43',
+            'TAP::Formatter::File'  => '3.43',
+            'TAP::Formatter::File::Session'=> '3.43',
+            'TAP::Formatter::Session'=> '3.43',
+            'TAP::Harness'          => '3.43',
+            'TAP::Harness::Env'     => '3.43',
+            'TAP::Object'           => '3.43',
+            'TAP::Parser'           => '3.43',
+            'TAP::Parser::Aggregator'=> '3.43',
+            'TAP::Parser::Grammar'  => '3.43',
+            'TAP::Parser::Iterator' => '3.43',
+            'TAP::Parser::Iterator::Array'=> '3.43',
+            'TAP::Parser::Iterator::Process'=> '3.43',
+            'TAP::Parser::Iterator::Stream'=> '3.43',
+            'TAP::Parser::IteratorFactory'=> '3.43',
+            'TAP::Parser::Multiplexer'=> '3.43',
+            'TAP::Parser::Result'   => '3.43',
+            'TAP::Parser::Result::Bailout'=> '3.43',
+            'TAP::Parser::Result::Comment'=> '3.43',
+            'TAP::Parser::Result::Plan'=> '3.43',
+            'TAP::Parser::Result::Pragma'=> '3.43',
+            'TAP::Parser::Result::Test'=> '3.43',
+            'TAP::Parser::Result::Unknown'=> '3.43',
+            'TAP::Parser::Result::Version'=> '3.43',
+            'TAP::Parser::Result::YAML'=> '3.43',
+            'TAP::Parser::ResultFactory'=> '3.43',
+            'TAP::Parser::Scheduler'=> '3.43',
+            'TAP::Parser::Scheduler::Job'=> '3.43',
+            'TAP::Parser::Scheduler::Spinner'=> '3.43',
+            'TAP::Parser::Source'   => '3.43',
+            'TAP::Parser::SourceHandler'=> '3.43',
+            'TAP::Parser::SourceHandler::Executable'=> '3.43',
+            'TAP::Parser::SourceHandler::File'=> '3.43',
+            'TAP::Parser::SourceHandler::Handle'=> '3.43',
+            'TAP::Parser::SourceHandler::Perl'=> '3.43',
+            'TAP::Parser::SourceHandler::RawTAP'=> '3.43',
+            'TAP::Parser::YAMLish::Reader'=> '3.43',
+            'TAP::Parser::YAMLish::Writer'=> '3.43',
+            'Test::Harness'         => '3.43',
+            'Text::Balanced'        => '2.04',
+            'Time::HiRes'           => '1.9766',
+            'XS::APItest'           => '1.14',
+            'warnings'              => '1.49',
+        },
+        removed => {
+        }
+    },
 );
 
 sub is_core
@@ -19242,6 +19351,13 @@ sub is_core
         removed => {
         }
     },
+    5.033005 => {
+        delta_from => 5.033004,
+        changed => {
+        },
+        removed => {
+        }
+    },
 );
 
 %deprecated = _undelta(\%deprecated);
@@ -19734,7 +19850,7 @@ sub is_core
     'Compress::Raw::Bzip2'  => 'https://github.com/pmqs/Compress-Raw-Bzip2/issues',
     'Compress::Raw::Zlib'   => 'https://github.com/pmqs/Compress-Raw-Zlib/issues',
     'Compress::Zlib'        => 'https://github.com/pmqs/IO-Compress/issues',
-    'Config::Perl::V'       => undef,
+    'Config::Perl::V'       => 'https://github.com/Tux/Config-Perl-V/issues',
     'DB_File'               => 'https://github.com/pmqs/DB_File/issues',
     'Digest'                => 'https://github.com/Dual-Life/digest/issues',
     'Digest::MD5'           => 'https://github.com/Dual-Life/digest-md5/issues',
index 1406f1b..036fe87 100644 (file)
@@ -4,7 +4,7 @@ use strict;
 use warnings;
 use Module::CoreList;
 
-our $VERSION = '5.20201120';
+our $VERSION = '5.20201220';
 our %utilities;
 
 sub utilities {
@@ -1657,6 +1657,13 @@ my %delta = (
         removed => {
         }
     },
+    5.033005 => {
+        delta_from => 5.033004,
+        changed => {
+        },
+        removed => {
+        }
+    },
 );
 
 %utilities = Module::CoreList::_undelta(\%delta);
diff --git a/dist/PathTools/.gitignore b/dist/PathTools/.gitignore
new file mode 100644 (file)
index 0000000..3c1f39c
--- /dev/null
@@ -0,0 +1,3 @@
+/Cwd.c
+/Cwd.bs
+!/Makefile.PL
index ce0f25f..6a1d2f1 100644 (file)
@@ -3,7 +3,7 @@ use strict;
 use Exporter;
 
 
-our $VERSION = '3.79';
+our $VERSION = '3.80';
 my $xs_version = $VERSION;
 $VERSION =~ tr/_//d;
 
index e7ecb3c..223e1a6 100644 (file)
@@ -84,6 +84,9 @@ bsd_realpath(const char *path, char resolved[MAXPATHLEN])
        unsigned symlinks;
        int serrno;
        char remaining[MAXPATHLEN], next_token[MAXPATHLEN];
+#ifdef PERL_IMPLICIT_SYS
+        dTHX;
+#endif
 
        serrno = errno;
        symlinks = 0;
@@ -175,8 +178,8 @@ bsd_realpath(const char *path, char resolved[MAXPATHLEN])
             }
 #if defined(HAS_LSTAT) && defined(HAS_READLINK) && defined(HAS_SYMLINK)
             {
-                struct stat sb;
-                if (lstat(resolved, &sb) != 0) {
+                Stat_t sb;
+                if (PerlLIO_lstat(resolved, &sb) != 0) {
                     if (errno == ENOENT && p == NULL) {
                         errno = serrno;
                         return (resolved);
@@ -191,7 +194,7 @@ bsd_realpath(const char *path, char resolved[MAXPATHLEN])
                         errno = ELOOP;
                         return (NULL);
                     }
-                    slen = readlink(resolved, symlink, sizeof(symlink) - 1);
+                    slen = PerlLIO_readlink(resolved, symlink, sizeof(symlink) - 1);
                     if (slen < 0)
                         return (NULL);
                     symlink[slen] = '\0';
index 732746d..30d883b 100644 (file)
@@ -2,7 +2,7 @@ package File::Spec;
 
 use strict;
 
-our $VERSION = '3.79';
+our $VERSION = '3.80';
 $VERSION =~ tr/_//d;
 
 my %module = (
index 0d3c9a5..fd9da81 100644 (file)
@@ -3,7 +3,7 @@ package File::Spec::AmigaOS;
 use strict;
 require File::Spec::Unix;
 
-our $VERSION = '3.79';
+our $VERSION = '3.80';
 $VERSION =~ tr/_//d;
 
 our @ISA = qw(File::Spec::Unix);
index 591af63..953c233 100644 (file)
@@ -3,7 +3,7 @@ package File::Spec::Cygwin;
 use strict;
 require File::Spec::Unix;
 
-our $VERSION = '3.79';
+our $VERSION = '3.80';
 $VERSION =~ tr/_//d;
 
 our @ISA = qw(File::Spec::Unix);
index 4b8a17f..fcb9e89 100644 (file)
@@ -2,7 +2,7 @@ package File::Spec::Epoc;
 
 use strict;
 
-our $VERSION = '3.79';
+our $VERSION = '3.80';
 $VERSION =~ tr/_//d;
 
 require File::Spec::Unix;
index fda2e95..e14ad2f 100644 (file)
@@ -3,7 +3,7 @@ package File::Spec::Functions;
 use File::Spec;
 use strict;
 
-our $VERSION = '3.79';
+our $VERSION = '3.80';
 $VERSION =~ tr/_//d;
 
 require Exporter;
index 504d0ce..8026edc 100644 (file)
@@ -4,7 +4,7 @@ use strict;
 use Cwd ();
 require File::Spec::Unix;
 
-our $VERSION = '3.79';
+our $VERSION = '3.80';
 $VERSION =~ tr/_//d;
 
 our @ISA = qw(File::Spec::Unix);
index fd7bc7f..3c35ba9 100644 (file)
@@ -4,7 +4,7 @@ use strict;
 use Cwd ();
 require File::Spec::Unix;
 
-our $VERSION = '3.79';
+our $VERSION = '3.80';
 $VERSION =~ tr/_//d;
 
 our @ISA = qw(File::Spec::Unix);
index 2221587..c06d18f 100644 (file)
@@ -3,7 +3,7 @@ package File::Spec::Unix;
 use strict;
 use Cwd ();
 
-our $VERSION = '3.79';
+our $VERSION = '3.80';
 $VERSION =~ tr/_//d;
 
 =head1 NAME
index 174dd22..9b78c8b 100644 (file)
@@ -4,7 +4,7 @@ use strict;
 use Cwd ();
 require File::Spec::Unix;
 
-our $VERSION = '3.79';
+our $VERSION = '3.80';
 $VERSION =~ tr/_//d;
 
 our @ISA = qw(File::Spec::Unix);
index a3b89c3..1537442 100644 (file)
@@ -5,7 +5,7 @@ use strict;
 use Cwd ();
 require File::Spec::Unix;
 
-our $VERSION = '3.79';
+our $VERSION = '3.80';
 $VERSION =~ tr/_//d;
 
 our @ISA = qw(File::Spec::Unix);
index c056938..d155e33 100644 (file)
@@ -187,6 +187,10 @@ rmtree($test_dirs[0], 0, 0);
 SKIP: {
     skip "no symlinks on this platform", 2+$EXTRA_ABSPATH_TESTS unless $Config{d_symlink} && $^O !~ m!^(qnx|nto)!;
 
+    # on Win32 GetCurrentDirectory() includes the symlink if
+    # you chdir() to a path including the symlink.
+    skip "Win32 symlinks are unusual", 2+$EXTRA_ABSPATH_TESTS if $^O eq "MSWin32";
+
     my $file = "linktest";
     mkpath([$Test_Dir], 0, 0777);
     symlink $Test_Dir, $file;
diff --git a/dist/Safe/.gitignore b/dist/Safe/.gitignore
new file mode 100644 (file)
index 0000000..e54624d
--- /dev/null
@@ -0,0 +1 @@
+!/Makefile.PL
diff --git a/dist/Search-Dict/.gitignore b/dist/Search-Dict/.gitignore
new file mode 100644 (file)
index 0000000..e54624d
--- /dev/null
@@ -0,0 +1 @@
+!/Makefile.PL
diff --git a/dist/Storable/.gitignore b/dist/Storable/.gitignore
new file mode 100644 (file)
index 0000000..e54624d
--- /dev/null
@@ -0,0 +1 @@
+!/Makefile.PL
index f7791ce..3b930aa 100644 (file)
@@ -34,7 +34,7 @@ $maxarraysize = 100;
 
 eval { require Digest::MD5; };
 $gotmd5 = !$@;
-diag "Will use Digest::MD5" if $gotmd5;
+note "Will use Digest::MD5" if $gotmd5;
 
 # Use Data::Dumper if debugging and it is available to create an ASCII dump
 
diff --git a/dist/Time-HiRes/.gitignore b/dist/Time-HiRes/.gitignore
new file mode 100644 (file)
index 0000000..e54624d
--- /dev/null
@@ -0,0 +1 @@
+!/Makefile.PL
index 1183dc9..a7600b2 100644 (file)
@@ -50,7 +50,7 @@ our @EXPORT_OK = qw (usleep sleep ualarm alarm gettimeofday time tv_interval
                  stat lstat utime
                 );
 
-our $VERSION = '1.9765';
+our $VERSION = '1.9766';
 our $XS_VERSION = $VERSION;
 $VERSION = eval $VERSION;
 
index ca81e5a..ec43295 100644 (file)
@@ -86,13 +86,6 @@ extern "C" {
 #  undef ITIMER_REALPROF
 #endif
 
-#ifndef ENV_LOCALE_LOCK
-#  define ENV_LOCALE_LOCK
-#endif
-#ifndef ENV_LOCALE_UNLOCK
-#  define ENV_LOCALE_UNLOCK
-#endif
-
 #ifndef TIME_HIRES_CLOCKID_T
 typedef int clockid_t;
 #endif
diff --git a/dist/Unicode-Normalize/.gitignore b/dist/Unicode-Normalize/.gitignore
new file mode 100644 (file)
index 0000000..47489b4
--- /dev/null
@@ -0,0 +1,2 @@
+*.h
+!/Makefile.PL
index 5c40ff1..a848b0d 100644 (file)
@@ -8,7 +8,7 @@ my $clean = {};
 my $mm_ver = ExtUtils::MakeMaker->VERSION;
 
 if (-f "Normalize.xs") {
-    print STDERR "Making header files for XS...\n";
+    print "Making header files for XS...\n";
 
     do './mkheader' or die $@ || "mkheader: $!";
 
diff --git a/dist/XSLoader/.gitignore b/dist/XSLoader/.gitignore
new file mode 100644 (file)
index 0000000..447ed53
--- /dev/null
@@ -0,0 +1,2 @@
+/XSLoader.pm
+!/Makefile.PL
diff --git a/dist/base/.gitignore b/dist/base/.gitignore
new file mode 100644 (file)
index 0000000..e54624d
--- /dev/null
@@ -0,0 +1 @@
+!/Makefile.PL
diff --git a/dist/lib/.gitignore b/dist/lib/.gitignore
new file mode 100644 (file)
index 0000000..c5c4f72
--- /dev/null
@@ -0,0 +1,2 @@
+/lib.pm
+!/Makefile.PL
index 4f6f6ed..6595894 100644 (file)
@@ -9,6 +9,12 @@ BEGIN {
         skip_all(q/Perl not compiled with 'useithreads'/);
     }
 
+    my $time_out_factor = $ENV{PERL_TEST_TIME_OUT_FACTOR} || 1;
+    $time_out_factor = 1 if $time_out_factor < 1;
+
+    # Guard against bugs that result in deadlock
+    watchdog(1 * 60 * $time_out_factor);
+
     plan(11);
 }
 
diff --git a/doio.c b/doio.c
index 2bffeea..439f2d0 100644 (file)
--- a/doio.c
+++ b/doio.c
@@ -2999,13 +2999,17 @@ Perl_do_ipcctl(pTHX_ I32 optype, SV **mark, SV **sp)
     {
        if (getinfo)
        {
-           SvPV_force_nolen(astr);
+            /* we're not using the value here, so don't SvPVanything */
+            SvUPGRADE(astr, SVt_PV);
+            SvGETMAGIC(astr);
+            if (SvTHINKFIRST(astr))
+                sv_force_normal_flags(astr, 0);
            a = SvGROW(astr, infosize+1);
        }
        else
        {
            STRLEN len;
-           a = SvPV(astr, len);
+           a = SvPVbyte(astr, len);
            if (len != infosize)
                Perl_croak(aTHX_ "Bad arg length for %s, is %lu, should be %ld",
                      PL_op_desc[optype],
@@ -3015,8 +3019,18 @@ Perl_do_ipcctl(pTHX_ I32 optype, SV **mark, SV **sp)
     }
     else
     {
-       const IV i = SvIV(astr);
-       a = INT2PTR(char *,i);          /* ouch */
+        /* We historically treat this as a pointer if we don't otherwise recognize
+           the op, but for many ops the value is simply ignored anyway, so
+           don't warn on undef.
+        */
+        SvGETMAGIC(astr);
+        if (SvOK(astr)) {
+            const IV i = SvIV_nomg(astr);
+            a = INT2PTR(char *,i);             /* ouch */
+        }
+        else {
+            a = NULL;
+        }
     }
     SETERRNO(0,0);
     switch (optype)
@@ -3058,6 +3072,7 @@ Perl_do_ipcctl(pTHX_ I32 optype, SV **mark, SV **sp)
     if (getinfo && ret >= 0) {
        SvCUR_set(astr, infosize);
        *SvEND(astr) = '\0';
+        SvPOK_only(astr);
        SvSETMAGIC(astr);
     }
     return ret;
@@ -3071,7 +3086,7 @@ Perl_do_msgsnd(pTHX_ SV **mark, SV **sp)
     const I32 id = SvIVx(*++mark);
     SV * const mstr = *++mark;
     const I32 flags = SvIVx(*++mark);
-    const char * const mbuf = SvPV_const(mstr, len);
+    const char * const mbuf = SvPVbyte(mstr, len);
     const I32 msize = len - sizeof(long);
 
     PERL_ARGS_ASSERT_DO_MSGSND;
@@ -3126,6 +3141,7 @@ Perl_do_msgrcv(pTHX_ SV **mark, SV **sp)
     }
     if (ret >= 0) {
        SvCUR_set(mstr, sizeof(long)+ret);
+        SvPOK_only(mstr);
        *SvEND(mstr) = '\0';
        /* who knows who has been playing with this message? */
        SvTAINTED_on(mstr);
@@ -3147,7 +3163,7 @@ Perl_do_semop(pTHX_ SV **mark, SV **sp)
     STRLEN opsize;
     const I32 id = SvIVx(*++mark);
     SV * const opstr = *++mark;
-    const char * const opbuf = SvPV_const(opstr, opsize);
+    const char * const opbuf = SvPVbyte(opstr, opsize);
 
     PERL_ARGS_ASSERT_DO_SEMOP;
     PERL_UNUSED_ARG(sp);
@@ -3235,7 +3251,7 @@ Perl_do_shmio(pTHX_ I32 optype, SV **mark, SV **sp)
     else {
        STRLEN len;
 
-       const char *mbuf = SvPV_const(mstr, len);
+       const char *mbuf = SvPVbyte(mstr, len);
        const I32 n = ((I32)len > msize) ? msize : (I32)len;
        Copy(mbuf, shm + mpos, n, char);
        if (n < msize)
index 5b27160..3580693 100644 (file)
--- a/dosish.h
+++ b/dosish.h
  *     to include <sys/stat.h> and <sys/types.h> to get any typedef'ed
  *     information.
  */
-#if defined(WIN64) || defined(USE_LARGE_FILES)
-#  define Stat_t struct _stati64
+#if defined(WIN32)
+#  define Stat_t struct w32_stat
 #else
-#  define Stat_t struct stat
+#  define Stat_t struct _stati64
 #endif
 
 /* USE_STAT_RDEV:
index 97d85a8..c66a280 100644 (file)
--- a/embed.fnc
+++ b/embed.fnc
@@ -1401,7 +1401,7 @@ Ap        |I32    |my_fflush_all
 ATp    |Pid_t  |my_fork
 ATp    |void   |atfork_lock
 ATp    |void   |atfork_unlock
-ApMb   |I32    |my_lstat
+m      |I32    |my_lstat
 pX     |I32    |my_lstat_flags |NULLOK const U32 flags
 #if ! defined(HAS_MEMRCHR) && (defined(PERL_CORE) || defined(PERL_EXT))
 EeiT   |void * |my_memrchr     |NN const char * s|const char c|const STRLEN len
@@ -1412,7 +1412,7 @@ Ap        |PerlIO*|my_popen       |NN const char* cmd|NN const char* mode
 #endif
 Ap     |PerlIO*|my_popen_list  |NN const char* mode|int n|NN SV ** args
 Apd    |void   |my_setenv      |NULLOK const char* nam|NULLOK const char* val
-ApMb   |I32    |my_stat
+m      |I32    |my_stat
 pX     |I32    |my_stat_flags  |NULLOK const U32 flags
 Adfp   |char * |my_strftime    |NN const char *fmt|int sec|int min|int hour|int mday|int mon|int year|int wday|int yday|int isdst
 : Used in pp_ctl.c
@@ -1579,7 +1579,7 @@ ApdO      |I32    |call_argv      |NN const char* sub_name|I32 flags|NN char** argv
 ApdO   |I32    |call_method    |NN const char* methname|I32 flags
 ApdO   |I32    |call_pv        |NN const char* sub_name|I32 flags
 ApdO   |I32    |call_sv        |NN SV* sv|volatile I32 flags
-Ap     |void   |despatch_signals
+Cp     |void   |despatch_signals
 Ap     |OP *   |doref          |NN OP *o|I32 type|bool set_op_ref
 ApdO   |SV*    |eval_pv        |NN const char* p|I32 croak_on_error
 ApdO   |I32    |eval_sv        |NN SV* sv|I32 flags
@@ -2700,7 +2700,7 @@ Ap        |void   |do_pmop_dump   |I32 level|NN PerlIO *file|NULLOK const PMOP *pm
 Ap     |void   |do_sv_dump     |I32 level|NN PerlIO *file|NULLOK SV *sv|I32 nest \
                                |I32 maxnest|bool dumpops|STRLEN pvlim
 Ap     |void   |magic_dump     |NULLOK const MAGIC *mg
-Ap     |void   |reginitcolors
+Cp     |void   |reginitcolors
 CpdRMb |char*  |sv_2pv_nolen   |NN SV* sv
 CpdRMb |char*  |sv_2pvutf8_nolen|NN SV* sv
 CpdRMb |char*  |sv_2pvbyte_nolen|NN SV* sv
@@ -2727,6 +2727,10 @@ AiMdp    |void   |SvREFCNT_dec   |NULLOK SV *sv
 AiMdp  |void   |SvREFCNT_dec_NN|NN SV *sv
 AiTp   |void   |SvAMAGIC_on    |NN SV *sv
 AiTp   |void   |SvAMAGIC_off   |NN SV *sv
+Aipd   |bool   |SvTRUE         |NULLOK SV *sv
+Aipd   |bool   |SvTRUE_nomg    |NULLOK SV *sv
+Aipd   |bool   |SvTRUE_NN      |NN SV *sv
+Cip    |bool   |SvTRUE_common  |NN SV *sv|const bool sv_2bool_is_fallback
 : This is indirectly referenced by globals.c. This is somewhat annoying.
 p      |int    |magic_killbackrefs|NN SV *sv|NN MAGIC *mg
 Ap     |OP*    |newANONATTRSUB |I32 floor|NULLOK OP *proto|NULLOK OP *attrs|NULLOK OP *block
@@ -3418,7 +3422,7 @@ Apd       |CV*    |cv_clone       |NN CV* proto
 p      |CV*    |cv_clone_into  |NN CV* proto|NN CV *target
 pd     |void   |pad_fixup_inner_anons|NN PADLIST *padlist|NN CV *old_cv|NN CV *new_cv
 pdX    |void   |pad_push       |NN PADLIST *padlist|int depth
-ApbdRM |HV*    |pad_compname_type|const PADOFFSET po
+ApbdDR |HV*    |pad_compname_type|const PADOFFSET po
 AxpdRT |PADNAME *|padnamelist_fetch|NN PADNAMELIST *pnl|SSize_t key
 Xop    |void   |padnamelist_free|NN PADNAMELIST *pnl
 Axpd   |PADNAME **|padnamelist_store|NN PADNAMELIST *pnl|SSize_t key \
@@ -3660,4 +3664,8 @@ XEop      |void   |dtrace_probe_phase|enum perl_phase phase
 
 XEop   |STRLEN*|dup_warnings   |NULLOK STRLEN* warnings
 
+#ifndef USE_ITHREADS
+Amd    |void   |CopFILEGV_set  |NN COP * c|NN GV * gv
+#endif
+
 : ex: set ts=8 sts=4 sw=4 noet:
diff --git a/embed.h b/embed.h
index 6348d64..fd5f3b4 100644 (file)
--- a/embed.h
+++ b/embed.h
 #define Gv_AMupdate(a,b)       Perl_Gv_AMupdate(aTHX_ a,b)
 #define SvAMAGIC_off           Perl_SvAMAGIC_off
 #define SvAMAGIC_on            Perl_SvAMAGIC_on
+#define SvTRUE(a)              Perl_SvTRUE(aTHX_ a)
+#define SvTRUE_NN(a)           Perl_SvTRUE_NN(aTHX_ a)
+#define SvTRUE_common(a,b)     Perl_SvTRUE_common(aTHX_ a,b)
+#define SvTRUE_nomg(a)         Perl_SvTRUE_nomg(aTHX_ a)
 #define _force_out_malformed_utf8_message(a,b,c,d)     Perl__force_out_malformed_utf8_message(aTHX_ a,b,c,d)
 #define _is_uni_FOO(a,b)       Perl__is_uni_FOO(aTHX_ a,b)
 #define _is_uni_perl_idcont(a) Perl__is_uni_perl_idcont(aTHX_ a)
 #define pad_add_name_pvn(a,b,c,d,e)    Perl_pad_add_name_pvn(aTHX_ a,b,c,d,e)
 #define pad_add_name_sv(a,b,c,d)       Perl_pad_add_name_sv(aTHX_ a,b,c,d)
 #define pad_alloc(a,b)         Perl_pad_alloc(aTHX_ a,b)
+#ifndef NO_MATHOMS
+#define pad_compname_type(a)   Perl_pad_compname_type(aTHX_ a)
+#endif
 #define pad_findmy_pv(a,b)     Perl_pad_findmy_pv(aTHX_ a,b)
 #define pad_findmy_pvn(a,b,c)  Perl_pad_findmy_pvn(aTHX_ a,b,c)
 #define pad_findmy_sv(a,b)     Perl_pad_findmy_sv(aTHX_ a,b)
index 4427e07..67ccd6b 100644 (file)
 #define PL_maxsysfd            (vTHX->Imaxsysfd)
 #define PL_mbrlen_ps           (vTHX->Imbrlen_ps)
 #define PL_mbrtowc_ps          (vTHX->Imbrtowc_ps)
+#define PL_mem_log             (vTHX->Imem_log)
 #define PL_memory_debug_header (vTHX->Imemory_debug_header)
 #define PL_mess_sv             (vTHX->Imess_sv)
 #define PL_min_intro_pending   (vTHX->Imin_intro_pending)
diff --git a/ext/.gitignore b/ext/.gitignore
new file mode 100644 (file)
index 0000000..48ab117
--- /dev/null
@@ -0,0 +1,8 @@
+# ignore generated .c files, and other module build traces
+*.c
+*.bs
+blib
+pm_to_blib
+Makefile
+Makefile.PL
+ppport.h
diff --git a/ext/Amiga-ARexx/.gitignore b/ext/Amiga-ARexx/.gitignore
new file mode 100644 (file)
index 0000000..e54624d
--- /dev/null
@@ -0,0 +1 @@
+!/Makefile.PL
diff --git a/ext/Amiga-Exec/.gitignore b/ext/Amiga-Exec/.gitignore
new file mode 100644 (file)
index 0000000..e54624d
--- /dev/null
@@ -0,0 +1 @@
+!/Makefile.PL
diff --git a/ext/B/.gitignore b/ext/B/.gitignore
new file mode 100644 (file)
index 0000000..7fb2000
--- /dev/null
@@ -0,0 +1,4 @@
+defsubs.h
+const-c.inc
+const-xs.inc
+!/Makefile.PL
diff --git a/ext/DynaLoader/.gitignore b/ext/DynaLoader/.gitignore
new file mode 100644 (file)
index 0000000..2af9bc6
--- /dev/null
@@ -0,0 +1,4 @@
+!/dlutils.c
+/DynaLoader.pm
+/DynaLoader.xs
+!/Makefile.PL
index 86a1128..f68d59a 100644 (file)
@@ -88,7 +88,7 @@ package DynaLoader;
 # Tim.Bunce@ig.co.uk, August 1994
 
 BEGIN {
-    $VERSION = '1.48';
+    $VERSION = '1.49';
 }
 
 EOT
index 8584f89..1a27fbd 100644 (file)
@@ -115,7 +115,7 @@ dl_generic_private_init(pTHX)       /* called by dl_*.xs dl_private_init() */
 #endif
 
 #if defined(PERL_IN_DL_HPUX_XS) || defined(PERL_IN_DL_DLOPEN_XS)
-    if ( (perl_dl_nonlazy = getenv("PERL_DL_NONLAZY")) != NULL
+    if ( (perl_dl_nonlazy = PerlEnv_getenv("PERL_DL_NONLAZY")) != NULL
        && grok_atoUV(perl_dl_nonlazy, &uv, NULL)
        && uv <= INT_MAX
     ) {
diff --git a/ext/Errno/.gitignore b/ext/Errno/.gitignore
new file mode 100644 (file)
index 0000000..5b0c2ef
--- /dev/null
@@ -0,0 +1,3 @@
+/Errno.pm
+/arch.txt
+!/Makefile.PL
diff --git a/ext/Fcntl/.gitignore b/ext/Fcntl/.gitignore
new file mode 100644 (file)
index 0000000..6531b6b
--- /dev/null
@@ -0,0 +1,2 @@
+*.inc
+!/Makefile.PL
index 4c67e88..01dbc8b 100644 (file)
@@ -3,7 +3,7 @@ use 5.006;
 use strict;
 use warnings;
 use warnings::register;
-our $VERSION = '1.37';
+our $VERSION = '1.38';
 require Exporter;
 require Cwd;
 
@@ -161,9 +161,8 @@ sub _find_opt {
     $pre_process       = $wanted->{preprocess};
     $post_process      = $wanted->{postprocess};
     $no_chdir          = $wanted->{no_chdir};
-    $full_check        = $Is_Win32 ? 0 : $wanted->{follow};
-    $follow            = $Is_Win32 ? 0 :
-                             $full_check || $wanted->{follow_fast};
+    $full_check        = $wanted->{follow};
+    $follow            = $full_check || $wanted->{follow_fast};
     $follow_skip       = $wanted->{follow_skip};
     $untaint           = $wanted->{untaint};
     $untaint_pat       = $wanted->{untaint_pattern};
index 40d14db..add20c2 100644 (file)
@@ -24,13 +24,8 @@ BEGIN {
 }
 
 my $symlink_exists = eval { symlink("",""); 1 };
-my $test_count = 111;
-$test_count += 127 if $symlink_exists;
-$test_count += 26 if $^O eq 'MSWin32';
-$test_count += 2 if $^O eq 'MSWin32' and $symlink_exists;
 
 use Test::More;
-plan tests => $test_count;
 use lib qw( ./t/lib );
 use Testing qw(
     create_file_ok
@@ -39,6 +34,7 @@ use Testing qw(
     dir_path
     file_path
 );
+use Errno ();
 
 my %Expect_File = (); # what we expect for $_
 my %Expect_Name = (); # what we expect for $File::Find::name/fullname
@@ -252,7 +248,17 @@ create_file_ok( file_path('fb', $testing_basenames[0]) );
 mkdir_ok( dir_path('fb', 'fba'), 0770  );
 create_file_ok( file_path('fb', 'fba', $testing_basenames[1]) );
 if ($symlink_exists) {
-    symlink_ok('../fb','fa/fsl');
+    if (symlink('../fb','fa/fsl')) {
+        pass("able to symlink from ../fb to fa/fsl");
+    }
+    else {
+        if ($^O eq "MSWin32" && ($! == &Errno::ENOSYS || $! == &Errno::EPERM)) {
+            $symlink_exists = 0;
+        }
+        else {
+            fail("able to symlink from ../fb to fa/fsl");
+        }
+    }
 }
 create_file_ok( file_path('fa', $testing_basenames[2]) );
 
@@ -885,6 +891,7 @@ if ($^O eq 'MSWin32') {
                    dir_path('fb') => 1,
                    dir_path('fba') => 1);
 
+    $FastFileTests_OK = 0;
     File::Find::find( {wanted => \&wanted_File_Dir}, topdir('fa'));
     is( scalar(keys %Expect_File), 0, "Got no files, as expected" );
 
@@ -1104,3 +1111,5 @@ if ($^O eq 'MSWin32') {
     like($@, qr/invalid top directory/,
         "find() correctly died due to undefined top directory");
 }
+
+done_testing();
index c638ce0..056e06c 100644 (file)
@@ -28,7 +28,7 @@ sub mkdir_ok($$;$) {
     my ($dir, $mask) = @_[0..1];
     my $msg = $_[2] || "able to mkdir: $dir";
     ok( mkdir($dir, $mask), $msg )
-        or die("Unable to mkdir: $dir");
+        or die("Unable to mkdir $!: $dir");
 }
 
 sub symlink_ok($$;$) {
index f56d186..aed431a 100644 (file)
@@ -1,5 +1,24 @@
 #!./perl -T
 use strict;
+
+BEGIN {
+    require File::Spec;
+    if ($ENV{PERL_CORE}) {
+        # May be doing dynamic loading while @INC is all relative
+        @INC = map { $_ = File::Spec->rel2abs($_); /(.*)/; $1 } @INC;
+    }
+
+    if ($^O eq 'MSWin32' || $^O eq 'cygwin' || $^O eq 'VMS') {
+        # This is a hack - at present File::Find does not produce native names
+        # on Win32 or VMS, so force File::Spec to use Unix names.
+        # must be set *before* importing File::Find
+        require File::Spec::Unix;
+        @File::Spec::ISA = 'File::Spec::Unix';
+    }
+    require File::Find;
+    import File::Find;
+}
+
 use Test::More;
 BEGIN {
     plan(
@@ -16,6 +35,7 @@ use Testing qw(
     dir_path
     file_path
 );
+use Errno ();
 
 my %Expect_File = (); # what we expect for $_
 my %Expect_Name = (); # what we expect for $File::Find::name/fullname
@@ -169,8 +189,21 @@ create_file_ok( file_path('fb_taint', 'fb_ord') );
 mkdir_ok( dir_path('fb_taint', 'fba'), 0770  );
 create_file_ok( file_path('fb_taint', 'fba', 'fba_ord') );
 SKIP: {
-       skip "Creating symlink", 1, unless $symlink_exists;
-       ok( symlink('../fb_taint','fa_taint/fsl'), 'Created symbolic link' );
+    skip "Creating symlink", 1, unless $symlink_exists;
+    if (symlink('../fb_taint','fa_taint/fsl')) {
+        pass('Created symbolic link' );
+    }
+    else {
+        my $error = 0 + $!;
+        if ($^O eq "MSWin32" &&
+            ($error == &Errno::ENOSYS || $error == &Errno::EPERM)) {
+            $symlink_exists = 0;
+            skip "symbolic links not available", 1;
+        }
+        else {
+            fail('Created symbolic link');
+        }
+    }
 }
 create_file_ok( file_path('fa_taint', 'fa_ord') );
 
@@ -201,7 +234,8 @@ delete @Expect_Dir{ dir_path('fb_taint'), dir_path('fba') } unless $symlink_exis
 File::Find::find( {wanted => \&wanted_File_Dir_prune, untaint => 1,
                   untaint_pattern => qr|^(.+)$|}, topdir('fa_taint') );
 
-is(scalar keys %Expect_File, 0, 'Found all expected files');
+is(scalar keys %Expect_File, 0, 'Found all expected files')
+    or diag "Not found " . join(" ", sort keys %Expect_File);
 
 # don't untaint at all, should die
 %Expect_File = ();
diff --git a/ext/File-Glob/.gitignore b/ext/File-Glob/.gitignore
new file mode 100644 (file)
index 0000000..d71ca7d
--- /dev/null
@@ -0,0 +1,3 @@
+*.inc
+!/Makefile.PL
+!/bsd_glob.c
diff --git a/ext/GDBM_File/.gitignore b/ext/GDBM_File/.gitignore
new file mode 100644 (file)
index 0000000..67de96f
--- /dev/null
@@ -0,0 +1,2 @@
+const-*.inc
+!/Makefile.PL
diff --git a/ext/Hash-Util/.gitignore b/ext/Hash-Util/.gitignore
new file mode 100644 (file)
index 0000000..e54624d
--- /dev/null
@@ -0,0 +1 @@
+!/Makefile.PL
diff --git a/ext/I18N-Langinfo/.gitignore b/ext/I18N-Langinfo/.gitignore
new file mode 100644 (file)
index 0000000..6531b6b
--- /dev/null
@@ -0,0 +1,2 @@
+*.inc
+!/Makefile.PL
diff --git a/ext/NDBM_File/.gitignore b/ext/NDBM_File/.gitignore
new file mode 100644 (file)
index 0000000..e54624d
--- /dev/null
@@ -0,0 +1 @@
+!/Makefile.PL
diff --git a/ext/ODBM_File/.gitignore b/ext/ODBM_File/.gitignore
new file mode 100644 (file)
index 0000000..e54624d
--- /dev/null
@@ -0,0 +1 @@
+!/Makefile.PL
index 7bdbecc..1b49440 100644 (file)
@@ -7,7 +7,7 @@ require Tie::Hash;
 require XSLoader;
 
 our @ISA = qw(Tie::Hash);
-our $VERSION = "1.16";
+our $VERSION = "1.17";
 
 XSLoader::load();
 
index 9b70811..38e6dbf 100644 (file)
@@ -181,6 +181,14 @@ int
 odbm_DELETE(db, key)
        ODBM_File       db
        datum_key       key
+       CODE:
+            /* don't warn about 'delete' being a C++ keyword */
+            GCC_DIAG_IGNORE_STMT(-Wc++-compat);
+           RETVAL = odbm_DELETE(db, key);
+            GCC_DIAG_RESTORE_STMT;
+       OUTPUT:
+         RETVAL
+
 
 datum_key
 odbm_FIRSTKEY(db)
index 9351c3b..fd3fbee 100644 (file)
@@ -6,7 +6,7 @@ use strict;
 
 our($VERSION, @ISA, @EXPORT_OK);
 
-$VERSION = "1.48";
+$VERSION = "1.49";
 
 use Carp;
 use Exporter ();
index 121b14f..3fb1116 100644 (file)
@@ -237,7 +237,8 @@ opmask_addlocal(pTHX_ SV *opset, char *op_mask_buf) /* Localise PL_op_mask then
      * is disallowed by Borland
      */
     if (opcode_debug >= 2)
-       SAVEDESTRUCTOR((void(*)(void*))Perl_warn,"PL_op_mask restored");
+       SAVEDESTRUCTOR((void(*)(void*))Perl_warn_nocontext,
+            "PL_op_mask restored");
     PL_op_mask = &op_mask_buf[0];
     if (orig_op_mask)
        Copy(orig_op_mask, PL_op_mask, PL_maxo, char);
diff --git a/ext/POSIX/.gitignore b/ext/POSIX/.gitignore
new file mode 100644 (file)
index 0000000..6531b6b
--- /dev/null
@@ -0,0 +1,2 @@
+*.inc
+!/Makefile.PL
index 5d5c009..a124003 100644 (file)
@@ -116,15 +116,18 @@ push @names, {name=>$_, type=>"NV", not_constant=>1}
   foreach (qw(DBL_MAX FLT_MAX LDBL_MAX LDBL_MIN LDBL_EPSILON
               DBL_EPSILON DBL_MIN FLT_EPSILON FLT_MIN));
 
-push @names, {name=>$_, type=>"NV"}
+push @names, {name=>$_, type=>"IV"}
   foreach (qw(DBL_DIG DBL_MANT_DIG DBL_MAX_10_EXP DBL_MAX_EXP DBL_MIN_10_EXP
              DBL_MIN_EXP FLT_DIG FLT_MANT_DIG FLT_MAX_10_EXP FLT_MAX_EXP
              FLT_MIN_10_EXP FLT_MIN_EXP FLT_RADIX LDBL_DIG LDBL_MANT_DIG
              LDBL_MAX_10_EXP LDBL_MAX_EXP LDBL_MIN_10_EXP LDBL_MIN_EXP));
 
-push @names, {name=>$_, type=>"NV"}
+push @names, {name=>$_, type=>"IV"}
   foreach (qw(FP_ILOGB0 FP_ILOGBNAN FP_INFINITE FP_NAN FP_NORMAL
-              FP_SUBNORMAL FP_ZERO M_1_PI M_2_PI M_2_SQRTPI M_E M_LN10 M_LN2
+              FP_SUBNORMAL FP_ZERO));
+
+push @names, {name=>$_, type=>"NV"}
+  foreach (qw(M_1_PI M_2_PI M_2_SQRTPI M_E M_LN10 M_LN2
               M_LOG10E M_LOG2E M_PI M_PI_2 M_PI_4 M_SQRT1_2 M_SQRT2));
 
 push @names, {name=>$_, type=>"IV"}
index ad5ca6c..6bd30e8 100644 (file)
@@ -1333,7 +1333,7 @@ static NV_PAYLOAD_TYPE S_getpayload(NV nv)
 #ifdef NV_PAYLOAD_DEBUG
     Perl_warn(aTHX_ "a[%d] = %" UVxf "\n", i, a[i]);
 #endif
-    payload *= UV_MAX;
+    payload *= (NV) UV_MAX;
     payload += a[i];
   }
 #ifdef NV_PAYLOAD_DEBUG
@@ -1559,13 +1559,13 @@ END_EXTERN_C
 #endif
 
 #if ! defined(HAS_MBLEN) && ! defined(HAS_MBRLEN)
-#define mblen(a,b) not_here("mblen")
+#  define mblen(a,b) not_here("mblen")
 #endif
 #if ! defined(HAS_MBTOWC) && ! defined(HAS_MBRTOWC)
-#define mbtowc(pwc, s, n) not_here("mbtowc")
+#  define mbtowc(pwc, s, n) not_here("mbtowc")
 #endif
-#ifndef HAS_WCTOMB
-#define wctomb(s, wchar) not_here("wctomb")
+#if ! defined(HAS_WCTOMB) && ! defined(HAS_WCRTOMB)
+#  define wctomb(s, wchar) not_here("wctomb")
 #endif
 #if !defined(HAS_MBLEN) && !defined(HAS_MBSTOWCS) && !defined(HAS_MBTOWC) && !defined(HAS_WCSTOMBS) && !defined(HAS_WCTOMB)
 /* If we don't have these functions, then we wouldn't have gotten a typedef
@@ -1578,7 +1578,7 @@ END_EXTERN_C
 #endif
 #endif
 
-#ifndef HAS_LOCALECONV
+#if ! defined(HAS_LOCALECONV) && ! defined(HAS_LOCALECONV_L)
 #   define localeconv() not_here("localeconv")
 #else
 struct lconv_offset {
@@ -2185,8 +2185,8 @@ localeconv()
 
         lcbuf = localeconv_l(cur);
 #  else
-        LOCALE_LOCK_V;  /* Prevent interference with other threads using
-                           localeconv() */
+        LOCALECONV_LOCK;    /* Prevent interference with other threads using
+                               localeconv() */
 #    ifdef TS_W32_BROKEN_LOCALECONV
         /* This is a workaround for a Windows bug prior to VS 15, in which
          * localeconv only looks at the global locale.  We toggle to the global
@@ -2271,7 +2271,7 @@ localeconv()
         Safefree(save_global);
         Safefree(save_thread);
 #    endif
-        LOCALE_UNLOCK_V;
+        LOCALECONV_UNLOCK;
 #  endif
         RESTORE_LC_NUMERIC();
 #endif  /* HAS_LOCALECONV */
@@ -3376,9 +3376,9 @@ mblen(s, n = ~0)
             memzero(&PL_mbrlen_ps, sizeof(PL_mbrlen_ps));
             RETVAL = 0;
 #else
-            LOCALE_LOCK;
+            MBLEN_LOCK;
             RETVAL = mblen(NULL, 0);
-            LOCALE_UNLOCK;
+            MBLEN_UNLOCK;
 #endif
         }
         else {  /* Not resetting state */
@@ -3398,9 +3398,9 @@ mblen(s, n = ~0)
 #else
                 /* Locking prevents races, but locales can be switched out
                  * without locking, so this isn't a cure all */
-                LOCALE_LOCK;
+                MBLEN_LOCK;
                 RETVAL = mblen(string, len);
-                LOCALE_UNLOCK;
+                MBLEN_UNLOCK;
 #endif
             }
         }
@@ -3427,9 +3427,9 @@ mbtowc(pwc, s, n = ~0)
             memzero(&PL_mbrtowc_ps, sizeof(PL_mbrtowc_ps));
             RETVAL = 0;
 #else
-            LOCALE_LOCK;
+            MBTOWC_LOCK;
             RETVAL = mbtowc(NULL, NULL, 0);
-            LOCALE_UNLOCK;
+            MBTOWC_UNLOCK;
 #endif
         }
         else {  /* Not resetting state */
@@ -3448,9 +3448,9 @@ mbtowc(pwc, s, n = ~0)
 #else
                 /* Locking prevents races, but locales can be switched out
                  * without locking, so this isn't a cure all */
-                LOCALE_LOCK;
+                MBTOWC_LOCK;
                 RETVAL = mbtowc(&wc, string, len);
-                LOCALE_UNLOCK;
+                MBTOWC_UNLOCK;
 #endif
                 if (RETVAL >= 0) {
                     sv_setiv_mg(pwc, wc);
@@ -3482,9 +3482,9 @@ wctomb(s, wchar)
              * But probably memzero would too */
             RETVAL = wcrtomb(NULL, L'\0', &PL_wcrtomb_ps);
 #else
-            LOCALE_LOCK;
+            WCTOMB_LOCK;
             RETVAL = wctomb(NULL, L'\0');
-            LOCALE_UNLOCK;
+            WCTOMB_UNLOCK;
 #endif
         }
         else {  /* Not resetting state */
@@ -3494,9 +3494,9 @@ wctomb(s, wchar)
 #else
             /* Locking prevents races, but locales can be switched out without
              * locking, so this isn't a cure all */
-            LOCALE_LOCK;
+            WCTOMB_LOCK;
             RETVAL = wctomb(buffer, wchar);
-            LOCALE_UNLOCK;
+            WCTOMB_UNLOCK;
 #endif
             if (RETVAL >= 0) {
                 sv_setpvn_mg(s, buffer, RETVAL);
index 51a51a2..c374af6 100644 (file)
@@ -4,7 +4,7 @@ use warnings;
 
 our ($AUTOLOAD, %SIGRT);
 
-our $VERSION = '1.95';
+our $VERSION = '1.96';
 
 require XSLoader;
 
diff --git a/ext/POSIX/t/iv_const.t b/ext/POSIX/t/iv_const.t
new file mode 100644 (file)
index 0000000..38d1b36
--- /dev/null
@@ -0,0 +1,69 @@
+#! perl -w
+
+# Test integer constants (DBL_DIG, DBL_MAX_EXP, FP_*, ...) are IV, not NV.
+
+use strict;
+use Test::More;
+use Devel::Peek;
+use POSIX;
+use Config;
+
+# Capture output from Devel::Peek::Dump() into Perl string
+sub capture_dump
+{
+    open my $olderr, '>&', *STDERR
+        or die "Can't save STDERR: $!";
+    my $str;
+    my $result = eval {
+        local $SIG{__DIE__};
+        close STDERR;
+        open STDERR, '>', \$str
+            or die "Can't redirect STDERR: $!";
+        Dump($_[0]);
+        1;
+    };
+    my $reason = $@;
+    open STDERR, '>&', $olderr
+        or die "Can't restore STDERR: $!";
+    $result or die $reason;
+    $str;
+}
+
+# Avoid die() in a test harness.
+sub capture_dump_in_test
+{
+    my $str;
+    eval { $str = capture_dump($_[0]); 1 } or BAIL_OUT $@;
+    $str;
+}
+
+sub is_iv ($$)
+{
+    # We would write "ok(SvIOK($_[0]), ...)",
+    # but unfortunately SvIOK is not available in Perl.
+
+    my $dump = capture_dump_in_test($_[0]);
+    #note($dump);
+    ok($dump =~ /^\h*FLAGS = .*\bIOK\b/m && $dump =~ /^\h*IV =/m, $_[1]);
+}
+
+my @tests = qw(EXIT_SUCCESS);
+
+push @tests, qw(FLT_RADIX FP_NORMAL FP_ZERO FP_SUBNORMAL FP_INFINITE FP_NAN);
+
+if ($Config{uselongdouble} ? $Config{d_ilogbl} : $Config{d_ilogb}) {
+    push @tests, qw(FP_ILOGB0);
+    push @tests, qw(FP_ILOGBNAN) if $Config{d_double_has_nan};
+}
+
+foreach my $flt ('FLT', 'DBL', ($Config{d_longdbl} ? ('LDBL') : ())) {
+    push @tests, "${flt}_$_"
+        foreach qw(DIG MANT_DIG MAX_10_EXP MAX_EXP MIN_10_EXP MIN_EXP);
+}
+
+push @tests, qw(FE_TONEAREST FE_TOWARDZERO FE_UPWARD FE_DOWNWARD)
+    if $Config{d_fegetround};
+
+is_iv(eval "POSIX::$_", "$_ is an integer") foreach @tests;
+
+done_testing();
index 5024937..60ef36d 100644 (file)
@@ -351,7 +351,12 @@ is ($result, undef, "fgets should fail");
 like ($@, qr/^Unimplemented: POSIX::fgets\(\): Use method IO::Handle::gets\(\) instead/,
       "check its redef message");
 
-eval { use strict; POSIX->import("S_ISBLK"); my $x = S_ISBLK };
+eval {
+    use strict;
+    no warnings 'uninitialized'; # S_ISBLK normally has an arg
+    POSIX->import("S_ISBLK");
+    my $x = S_ISBLK
+};
 unlike( $@, qr/Can't use string .* as a symbol ref/, "Can import autoloaded constants" );
 
 SKIP: {
index b19ed70..5e71d27 100644 (file)
@@ -86,7 +86,7 @@ if (locales_enabled('LC_TIME')) {
     setlocale(LC_TIME, $orig_time_loc) || die "Cannot setlocale(LC_TIME) back to orig: $!";
 }
 if (locales_enabled('LC_CTYPE')) {
-    setlocale(LC_TIME, $orig_ctype_loc) || die "Cannot setlocale(LC_CTYPE) back to orig: $!";
+    setlocale(LC_CTYPE, $orig_ctype_loc) || die "Cannot setlocale(LC_CTYPE) back to orig: $!";
 }
 
 # clock() seems to have different definitions of what it does between POSIX
index 7e821fd..d47382b 100644 (file)
@@ -61,7 +61,7 @@ if ($child_pid) {
                $state = NEG1_REQUIRED;
                is(WIFEXITED(${^CHILD_ERROR_NATIVE}), 1, 'child exited cleanly');
                is(WEXITSTATUS(${^CHILD_ERROR_NATIVE}), 0,
-                  'child exited with 0 (the retun value of its sleep(3) call)');
+                  'child exited with 0 (the return value of its sleep(3) call)');
 
            }
        }
diff --git a/ext/Pod-Functions/.gitignore b/ext/Pod-Functions/.gitignore
new file mode 100644 (file)
index 0000000..d751436
--- /dev/null
@@ -0,0 +1,2 @@
+/Functions.pm
+!/Makefile.PL
diff --git a/ext/Pod-Html/.gitignore b/ext/Pod-Html/.gitignore
new file mode 100644 (file)
index 0000000..0a64446
--- /dev/null
@@ -0,0 +1 @@
+/pod2html
diff --git a/ext/SDBM_File/.gitignore b/ext/SDBM_File/.gitignore
new file mode 100644 (file)
index 0000000..18641ce
--- /dev/null
@@ -0,0 +1,3 @@
+!*.c
+SDBM_File.c
+!/Makefile.PL
diff --git a/ext/VMS-DCLsym/.gitignore b/ext/VMS-DCLsym/.gitignore
new file mode 100644 (file)
index 0000000..e54624d
--- /dev/null
@@ -0,0 +1 @@
+!/Makefile.PL
diff --git a/ext/VMS-Stdio/.gitignore b/ext/VMS-Stdio/.gitignore
new file mode 100644 (file)
index 0000000..e54624d
--- /dev/null
@@ -0,0 +1 @@
+!/Makefile.PL
diff --git a/ext/Win32CORE/.gitignore b/ext/Win32CORE/.gitignore
new file mode 100644 (file)
index 0000000..7148fe9
--- /dev/null
@@ -0,0 +1,2 @@
+!/Win32CORE.c
+!/Makefile.PL
diff --git a/ext/XS-APItest/.gitignore b/ext/XS-APItest/.gitignore
new file mode 100644 (file)
index 0000000..9bc400b
--- /dev/null
@@ -0,0 +1,6 @@
+const-*.inc
+/APItest.bso
+!/Makefile.PL
+!/core.c
+!/exception.c
+!/notcore.c
index fc47450..eda042e 100644 (file)
@@ -5,7 +5,7 @@ use strict;
 use warnings;
 use Carp;
 
-our $VERSION = '1.13';
+our $VERSION = '1.14';
 
 require XSLoader;
 
index 549bf54..acfbe22 100644 (file)
@@ -6936,6 +6936,31 @@ Comctl32Version()
 #endif
 
 
+MODULE = XS::APItest                PACKAGE = XS::APItest::RWMacro
+
+#if defined(USE_ITHREADS)
+
+void
+compile_macros()
+    PREINIT:
+        perl_RnW1_mutex_t m;
+       perl_RnW1_mutex_t *pm = &m;
+    CODE:
+        PERL_RW_MUTEX_INIT(&m);
+        PERL_WRITE_LOCK(&m);
+        PERL_WRITE_UNLOCK(&m);
+        PERL_READ_LOCK(&m);
+        PERL_READ_UNLOCK(&m);
+        PERL_RW_MUTEX_DESTROY(&m);
+        PERL_RW_MUTEX_INIT(pm);
+        PERL_WRITE_LOCK(pm);
+        PERL_WRITE_UNLOCK(pm);
+        PERL_READ_LOCK(pm);
+        PERL_READ_UNLOCK(pm);
+        PERL_RW_MUTEX_DESTROY(pm);
+
+#endif
+
 MODULE = XS::APItest                PACKAGE = XS::APItest::HvMacro
 
 
diff --git a/ext/XS-Typemap/.gitignore b/ext/XS-Typemap/.gitignore
new file mode 100644 (file)
index 0000000..3fb2f0e
--- /dev/null
@@ -0,0 +1,2 @@
+!/Makefile.PL
+!/stdio.c
diff --git a/ext/re/.gitignore b/ext/re/.gitignore
new file mode 100644 (file)
index 0000000..f63246b
--- /dev/null
@@ -0,0 +1,2 @@
+!/Makefile.PL
+/invlist_inline.h
diff --git a/handy.h b/handy.h
index 7feedcb..f0a2a3c 100644 (file)
--- a/handy.h
+++ b/handy.h
@@ -355,7 +355,7 @@ assert(), we would get a comma with nothing before it when not DEBUGGING.
 
 =cut
 
-We also use empty definition under Coverity since the __ASSERT__
+We also use empty definition under Coverity since the __ASSERT_
 checks often check for things that Really Cannot Happen, and Coverity
 detects that and gets all excited. */
 
@@ -631,22 +631,24 @@ wrapper for C<strncmp>).
 =for apidoc Am|bool|memEQ|char* s1|char* s2|STRLEN len
 Test two buffers (which may contain embedded C<NUL> characters, to see if they
 are equal.  The C<len> parameter indicates the number of bytes to compare.
-Returns zero if equal, or non-zero if non-equal.
+Returns true or false.  It is undefined behavior if either of the buffers
+doesn't contain at least C<len> bytes.
 
 =for apidoc Am|bool|memEQs|char* s1|STRLEN l1|"s2"
 Like L</memEQ>, but the second string is a literal enclosed in double quotes,
 C<l1> gives the number of bytes in C<s1>.
-Returns zero if equal, or non-zero if non-equal.
+Returns true or false.
 
 =for apidoc Am|bool|memNE|char* s1|char* s2|STRLEN len
 Test two buffers (which may contain embedded C<NUL> characters, to see if they
 are not equal.  The C<len> parameter indicates the number of bytes to compare.
-Returns zero if non-equal, or non-zero if equal.
+Returns true or false.  It is undefined behavior if either of the buffers
+doesn't contain at least C<len> bytes.
 
 =for apidoc Am|bool|memNEs|char* s1|STRLEN l1|"s2"
 Like L</memNE>, but the second string is a literal enclosed in double quotes,
 C<l1> gives the number of bytes in C<s1>.
-Returns zero if non-equal, or zero if non-equal.
+Returns true or false.
 
 =for apidoc Am|bool|memCHRs|"list"|char c
 Returns the position of the first occurence of the byte C<c> in the literal
@@ -1407,18 +1409,33 @@ or casts
  * needed.  (The NV casts stop any warnings about comparison always being true
  * if called with an unsigned.  The cast preserves the sign, which is all we
  * care about.) */
-#define withinCOUNT(c, l, n) (__ASSERT_((NV) (l) >= 0)                         \
-                              __ASSERT_((NV) (n) >= 0)                         \
-   (((WIDEST_UTYPE) (((c)) - ((l) | 0))) <= (((WIDEST_UTYPE) ((n) | 0)))))
+#define withinCOUNT(c, l, n)  (__ASSERT_((NV) (l) >= 0)                 \
+                               __ASSERT_((NV) (n) >= 0)                 \
+                               withinCOUNT_KNOWN_VALID_((c), (l), (n)))
+
+/* For internal use only, this can be used in places where it is known that the
+ * parameters to withinCOUNT() are valid, to avoid the asserts.  For example,
+ * inRANGE() below, calls this several times, but does all the necessary
+ * asserts itself, once.  The reason that this is necessary is that the
+ * duplicate asserts were exceeding the internal limits of some compilers */
+#define withinCOUNT_KNOWN_VALID_(c, l, n)                                   \
+    (((WIDEST_UTYPE) (((c)) - ((l) | 0))) <= (((WIDEST_UTYPE) ((n) | 0))))
 
 /* Returns true if c is in the range l..u, where 'l' is non-negative
  * Written this way so that after optimization, only one conditional test is
  * needed. */
-#define inRANGE(c, l, u) (__ASSERT_((u) >= (l))                                \
-   (  (sizeof(c) == sizeof(U8))  ? withinCOUNT(((U8)  (c)), (l), ((u) - (l)))  \
-    : (sizeof(c) == sizeof(U32)) ? withinCOUNT(((U32) (c)), (l), ((u) - (l)))  \
-    : (__ASSERT_(sizeof(c) == sizeof(WIDEST_UTYPE))                            \
-                          withinCOUNT(((WIDEST_UTYPE) (c)), (l), ((u) - (l))))))
+#define inRANGE(c, l, u) (__ASSERT_((NV) (l) >= 0) __ASSERT_((u) >= (l))    \
+   (  (sizeof(c) == sizeof(U8))  ? inRANGE_helper_(U8, (c), (l), ((u)))     \
+    : (sizeof(c) == sizeof(U16)) ? inRANGE_helper_(U16,(c), (l), ((u)))     \
+    : (sizeof(c) == sizeof(U32)) ? inRANGE_helper_(U32,(c), (l), ((u)))     \
+             : (__ASSERT_(sizeof(c) == sizeof(WIDEST_UTYPE))                \
+                          inRANGE_helper_(WIDEST_UTYPE,(c), (l), ((u))))))
+
+/* For internal use, this is used by machine-generated code which generates
+ * known valid calls, with a known sizeof().  This avoids the extra code and
+ * asserts that were exceeding internal limits of some compilers. */
+#define inRANGE_helper_(cast, c, l, u)                                      \
+                    withinCOUNT_KNOWN_VALID_(((cast) (c)), (l), ((u) - (l)))
 
 #ifdef EBCDIC
 #   ifndef _ALL_SOURCE
@@ -1616,16 +1633,21 @@ END_EXTERN_C
 #   endif
 
     /* Participates in a single-character fold with a character above 255 */
-#   define _HAS_NONLATIN1_SIMPLE_FOLD_CLOSURE_ONLY_FOR_USE_BY_REGCOMP_DOT_C_AND_REGEXEC_DOT_C(c) ((! cBOOL(FITS_IN_8_BITS(c))) || (PL_charclass[(U8) (c)] & _CC_mask(_CC_NONLATIN1_SIMPLE_FOLD)))
+#   if defined(PERL_IN_REGCOMP_C) || defined(PERL_IN_REGEXEC_C)
+#     define HAS_NONLATIN1_SIMPLE_FOLD_CLOSURE(c)                          \
+        ((   ! cBOOL(FITS_IN_8_BITS(c)))                                    \
+          || (PL_charclass[(U8) (c)] & _CC_mask(_CC_NONLATIN1_SIMPLE_FOLD)))
+
+#   define IS_NON_FINAL_FOLD(c)   _generic_isCC(c, _CC_NON_FINAL_FOLD)
+#   define IS_IN_SOME_FOLD_L1(c)  _generic_isCC(c, _CC_IS_IN_SOME_FOLD)
+#  endif
 
     /* Like the above, but also can be part of a multi-char fold */
-#   define _HAS_NONLATIN1_FOLD_CLOSURE_ONLY_FOR_USE_BY_REGCOMP_DOT_C_AND_REGEXEC_DOT_C(c) ((! cBOOL(FITS_IN_8_BITS(c))) || (PL_charclass[(U8) (c)] & _CC_mask(_CC_NONLATIN1_FOLD)))
+#   define HAS_NONLATIN1_FOLD_CLOSURE(c)                                    \
+      (   (! cBOOL(FITS_IN_8_BITS(c)))                                      \
+       || (PL_charclass[(U8) (c)] & _CC_mask(_CC_NONLATIN1_FOLD)))
 
 #   define _isQUOTEMETA(c) _generic_isCC(c, _CC_QUOTEMETA)
-#   define _IS_NON_FINAL_FOLD_ONLY_FOR_USE_BY_REGCOMP_DOT_C(c) \
-                                           _generic_isCC(c, _CC_NON_FINAL_FOLD)
-#   define _IS_IN_SOME_FOLD_ONLY_FOR_USE_BY_REGCOMP_DOT_C(c) \
-                                           _generic_isCC(c, _CC_IS_IN_SOME_FOLD)
 
 /* is c a control character for which we have a mnemonic? */
 #  if defined(PERL_CORE) || defined(PERL_EXT)
index d09e448..16b901a 100644 (file)
 # mkdir -p /opt/perl-catamount
 # mkdir -p /opt/perl-catamount/include
 # mkdir -p /opt/perl-catamount/lib
-# mkdir -p /opt/perl-catamount/lib/perl5/5.33.4
+# mkdir -p /opt/perl-catamount/lib/perl5/5.33.5
 # mkdir -p /opt/perl-catamount/bin
 # cp *.h /opt/perl-catamount/include
 # cp libperl.a /opt/perl-catamount/lib
-# cp -pr lib/* /opt/perl-catamount/lib/perl5/5.33.4
+# cp -pr lib/* /opt/perl-catamount/lib/perl5/5.33.5
 # cp miniperl perl run.sh cc.sh /opt/perl-catamount/lib
 #
 # With the headers and the libperl.a you can embed Perl to your Catamount
index c613406..e50d9d8 100644 (file)
@@ -90,7 +90,8 @@ END
 `
 
 case "$cc" in
-'')    for i in `ls -r /opt/*studio*/bin/cc` /opt/SUNWspro/bin/cc
+'')    for i in `ls -r /opt/*studio*/bin/cc` /opt/SUNWspro/bin/cc \
+               `which gcc`
        do
               if test -f "$i"; then
                       cc=$i
diff --git a/hv.c b/hv.c
index 43b9330..8f7dbdc 100644 (file)
--- a/hv.c
+++ b/hv.c
@@ -1776,7 +1776,7 @@ Perl_hv_delayfree_ent(pTHX_ HV *hv, HE *entry)
 /*
 =for apidoc hv_clear
 
-Frees the all the elements of a hash, leaving it empty.
+Frees all the elements of a hash, leaving it empty.
 The XS equivalent of C<%hash = ()>.  See also L</hv_undef>.
 
 See L</av_clear> for a note about the hash possibly being invalid on
@@ -3681,8 +3681,6 @@ no action occurs in this case.
 
 void
 Perl_refcounted_he_free(pTHX_ struct refcounted_he *he) {
-#ifdef USE_ITHREADS
-#endif
     PERL_UNUSED_CONTEXT;
 
     while (he) {
@@ -3719,8 +3717,6 @@ to this function: no action occurs and a null pointer is returned.
 struct refcounted_he *
 Perl_refcounted_he_inc(pTHX_ struct refcounted_he *he)
 {
-#ifdef USE_ITHREADS
-#endif
     PERL_UNUSED_CONTEXT;
     if (he) {
        HINTS_REFCNT_LOCK;
index 5ada155..bed8afa 100644 (file)
--- a/inline.h
+++ b/inline.h
@@ -212,13 +212,62 @@ Perl_ReANY(const REGEXP * const re)
 /* ------------------------------- sv.h ------------------------------- */
 
 PERL_STATIC_INLINE bool
-Perl_SvTRUE(pTHX_ SV *sv) {
+Perl_SvTRUE(pTHX_ SV *sv)
+{
+    PERL_ARGS_ASSERT_SVTRUE;
+
+    if (UNLIKELY(sv == NULL))
+        return FALSE;
+    SvGETMAGIC(sv);
+    return SvTRUE_nomg_NN(sv);
+}
+
+PERL_STATIC_INLINE bool
+Perl_SvTRUE_nomg(pTHX_ SV *sv)
+{
+    PERL_ARGS_ASSERT_SVTRUE_NOMG;
+
     if (UNLIKELY(sv == NULL))
         return FALSE;
+    return SvTRUE_nomg_NN(sv);
+}
+
+PERL_STATIC_INLINE bool
+Perl_SvTRUE_NN(pTHX_ SV *sv)
+{
+    PERL_ARGS_ASSERT_SVTRUE_NN;
+
     SvGETMAGIC(sv);
     return SvTRUE_nomg_NN(sv);
 }
 
+PERL_STATIC_INLINE bool
+Perl_SvTRUE_common(pTHX_ SV * sv, const bool sv_2bool_is_fallback)
+{
+    PERL_ARGS_ASSERT_SVTRUE_COMMON;
+
+    if (UNLIKELY(SvIMMORTAL_INTERP(sv)))
+        return SvIMMORTAL_TRUE(sv);
+
+    if (! SvOK(sv))
+        return FALSE;
+
+    if (SvPOK(sv))
+        return SvPVXtrue(sv);
+
+    if (SvIOK(sv))
+        return SvIVX(sv) != 0; /* casts to bool */
+
+    if (SvROK(sv) && !(SvOBJECT(SvRV(sv)) && HvAMAGIC(SvSTASH(SvRV(sv)))))
+        return TRUE;
+
+    if (sv_2bool_is_fallback)
+        return sv_2bool_nomg(sv);
+
+    return isGV_with_GP(sv);
+}
+
+
 PERL_STATIC_INLINE SV *
 Perl_SvREFCNT_inc(SV *sv)
 {
@@ -1980,7 +2029,7 @@ S_lossless_NV_to_IV(const NV nv, IV *ivp)
 
     /* Written this way so that with an always-false NaN comparison we
      * return false */
-    if (!(LIKELY(nv >= IV_MIN) && LIKELY(nv <= IV_MAX))) {
+    if (!(LIKELY(nv >= (NV) IV_MIN) && LIKELY(nv < IV_MAX_P1))) {
         return FALSE;
     }
 
@@ -2569,23 +2618,31 @@ Perl_mortal_getenv(const char * str)
 {
     /* This implements a (mostly) thread-safe, sequential-call-safe getenv().
      *
-     * It's (mostly) thread-safe because it uses a mutex to prevent
-     * simultaneous access from other threads that use the same mutex, and
-     * makes a copy of the result before releasing that mutex.  All of the Perl
-     * core uses that mutex, but, like all mutexes, everything has to cooperate
-     * for it to completely work.  It is possible for code from, say XS, to not
-     * use this mutex, defeating the safety.
+     * It's (mostly) thread-safe because it uses a mutex to prevent other
+     * threads (that look at this mutex) from destroying the result before this
+     * routine has a chance to copy the result to a place that won't be
+     * destroyed before the caller gets a chance to handle it.  That place is a
+     * mortal SV.  khw chose this over SAVEFREEPV because he is under the
+     * impression that the SV will hang around longer under more circumstances
      *
-     * On some platforms, getenv() is not sequential-call-safe, because
-     * subsequent calls destroy the static storage inside the C library
-     * returned by an earlier call.  The result must be copied or completely
-     * acted upon before a subsequent getenv call.  Those calls could come from
-     * another thread.  Again, making a copy while controlling the mutex
-     * prevents these problems..
+     * The reason it isn't completely thread-safe is that other code could
+     * simply not pay attention to the mutex.  All of the Perl core uses the
+     * mutex, but it is possible for code from, say XS, to not use this mutex,
+     * defeating the safety.
      *
-     * To prevent leaks, the copy is made by creating a new SV containing it,
-     * mortalizing the SV, and returning the SV's string (the copy).  Thus this
-     * is a drop-in replacement for getenv().
+     * getenv() returns, in some implementations, a pointer to a spot in the
+     * **environ array, which could be invalidated at any time by this or
+     * another thread changing the environment.  Other implementations copy the
+     * **environ value to a static buffer, returning a pointer to that.  That
+     * buffer might or might not be invalidated by a getenv() call in another
+     * thread.  If it does get zapped, we need an exclusive lock.  Otherwise,
+     * many getenv() calls can safely be running simultaneously, so a
+     * many-reader (but no simultaneous writers) lock is ok.  There is a
+     * Configure probe to see if another thread destroys the buffer, and the
+     * mutex is defined accordingly.
+     *
+     * But in all cases, using the mutex prevents these problems, as long as
+     * all code uses the same mutex..
      *
      * A complication is that this can be called during phases where the
      * mortalization process isn't available.  These are in interpreter
@@ -2605,15 +2662,152 @@ Perl_mortal_getenv(const char * str)
         return getenv(str);
     }
 
-    ENV_LOCK;
+#ifdef PERL_MEM_LOG
+
+    /* A major complication arises under PERL_MEM_LOG.  When that is active,
+     * every memory allocation may result in logging, depending on the value of
+     * ENV{PERL_MEM_LOG} at the moment.  That means, as we create the SV for
+     * saving ENV{foo}'s value (but before saving it), the logging code will
+     * call us recursively to find out what ENV{PERL_MEM_LOG} is.  Without some
+     * care that could lead to: 1) infinite recursion; or 2) deadlock (trying to
+     * lock a boolean mutex recursively); 3) destroying the getenv() static
+     * buffer; or 4) destroying the temporary created by this for the copy
+     * causes a log entry to be made which could cause a new temporary to be
+     * created, which will need to be destroyed at some point, leading to an
+     * infinite loop.
+     *
+     * The solution adopted here (after some gnashing of teeth) is to detect
+     * the recursive calls and calls from the logger, and treat them specially.
+     * Let's say we want to do getenv("foo").  We first find
+     * getenv(PERL_MEM_LOG) and save it to a fixed-length per-interpreter
+     * variable, so no temporary is required.  Then we do getenv(foo}, and in
+     * the process of creating a temporary to save it, this function will be
+     * called recursively to do a getenv(PERL_MEM_LOG).  On the recursed call,
+     * we detect that it is such a call and return our saved value instead of
+     * locking and doing a new getenv().  This solves all of problems 1), 2),
+     * and 3).  Because all the getenv()s are done while the mutex is locked,
+     * the state cannot have changed.  To solve 4), we don't create a temporary
+     * when this is called from the logging code.  That code disposes of the
+     * return value while the mutex is still locked.
+     *
+     * The value of getenv(PERL_MEM_LOG) can be anything, but only initial
+     * digits and 3 particular letters are significant; the rest are ignored by
+     * the memory logging code.  Thus the per-interpreter variable only needs
+     * to be large enough to save the significant information, the size of
+     * which is known at compile time.  The first byte is extra, reserved for
+     * flags for our use.  To protect against overflowing, only the reserved
+     * byte, as many digits as don't overflow, and the three letters are
+     * stored.
+     *
+     * The reserved byte has two bits:
+     *      0x1 if set indicates that if we get here, it is a recursive call of
+     *          getenv()
+     *      0x2 if set indicates that the call is from the logging code.
+     *
+     * If the flag indicates this is a recursive call, just return the stored
+     * value of PL_mem_log;  An empty value gets turned into NULL. */
+    if (strEQ(str, "PERL_MEM_LOG") && PL_mem_log[0] & 0x1) {
+        if (PL_mem_log[1] == '\0') {
+            return NULL;
+        } else {
+            return PL_mem_log + 1;
+        }
+    }
+
+#endif
+
+    GETENV_LOCK;
+
+#ifdef PERL_MEM_LOG
+
+    /* Here we are in a critical section.  As explained above, we do our own
+     * getenv(PERL_MEM_LOG), saving the result safely. */
+    ret = getenv("PERL_MEM_LOG");
+    if (ret == NULL) {  /* No logging active */
 
+        /* Return that immediately if called from the logging code */
+        if (PL_mem_log[0] & 0x2) {
+            GETENV_UNLOCK;
+            return NULL;
+        }
+
+        PL_mem_log[1] = '\0';
+    }
+    else {
+        char *mem_log_meat = PL_mem_log + 1;    /* first byte reserved */
+
+        /* There is nothing to prevent the value of PERL_MEM_LOG from being an
+         * extremely long string.  But we want only a few characters from it.
+         * PL_mem_log has been made large enough to hold just the ones we need.
+         * First the file descriptor. */
+        if (isDIGIT(*ret)) {
+            const char * s = ret;
+            if (UNLIKELY(*s == '0')) {
+
+                /* Reduce multiple leading zeros to a single one.  This is to
+                 * allow the caller to change what to do with leading zeros. */
+                *mem_log_meat++ = '0';
+                s++;
+                while (*s == '0') {
+                    s++;
+                }
+            }
+
+            /* If the input overflows, copy just enough for the result to also
+             * overflow, plus 1 to make sure */
+            while (isDIGIT(*s) && s < ret + TYPE_DIGITS(UV) + 1) {
+                *mem_log_meat++ = *s++;
+            }
+        }
+
+        /* Then each of the three significant characters */
+        if (strchr(ret, 'm')) {
+            *mem_log_meat++ = 'm';
+        }
+        if (strchr(ret, 's')) {
+            *mem_log_meat++ = 's';
+        }
+        if (strchr(ret, 't')) {
+            *mem_log_meat++ = 't';
+        }
+        *mem_log_meat = '\0';
+
+        assert(mem_log_meat < PL_mem_log + sizeof(PL_mem_log));
+    }
+
+    /* If we are being called from the logger, it only needs the significant
+     * portion of PERL_MEM_LOG, and doesn't need a safe copy */
+    if (PL_mem_log[0] & 0x2) {
+        assert(strEQ(str, "PERL_MEM_LOG"));
+        GETENV_UNLOCK;
+        return PL_mem_log + 1;
+    }
+
+    /* Here is a generic getenv().  This could be a getenv("PERL_MEM_LOG") that
+     * is coming from other than the logging code, so it should be treated the
+     * same as any other getenv(), returning the full value, not just the
+     * significant part, and having its value saved.  Set the flag that
+     * indicates any call to this routine will be a recursion from here */
+    PL_mem_log[0] = 0x1;
+
+#endif
+
+    /* Now get the value of the real desired variable, and save a copy */
     ret = getenv(str);
 
     if (ret != NULL) {
         ret = SvPVX(sv_2mortal(newSVpv(ret, 0)));
     }
 
-    ENV_UNLOCK;
+    GETENV_UNLOCK;
+
+#ifdef PERL_MEM_LOG
+
+    /* Clear the buffer */
+    Zero(PL_mem_log, sizeof(PL_mem_log), char);
+
+#endif
+
     return ret;
 }
 
index 1ea21ca..f16d6dd 100644 (file)
 
 #include "handy.h"
 
-/*
-=for apidoc_section Per-Interpreter Variables
-*/
-
 /* These variables are per-interpreter in threaded/multiplicity builds,
  * global otherwise.
 
@@ -94,12 +90,17 @@ PERLVARI(I, tainted,        bool, FALSE)    /* using variables controlled by $< */
 PERLVAR(I, delaymagic, U16)            /* ($<,$>) = ... */
 
 /*
+=for apidoc_section $warning
 =for apidoc mn|U8|PL_dowarn
 
 The C variable that roughly corresponds to Perl's C<$^W> warning variable.
 However, C<$^W> is treated as a boolean, whereas C<PL_dowarn> is a
 collection of flag bits.
 
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+
 =cut
 */
 
@@ -118,6 +119,10 @@ PERLVARI(I, utf8cache, I8, PERL___I)       /* Is the utf8 caching code enabled? */
 
 The GV representing C<*_>.  Useful for access to C<$_>.
 
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+
 =cut
 */
 
@@ -130,6 +135,10 @@ PERLVAR(I, defgv,  GV *)           /* the *_ glob */
 
 The stash for the package code will be compiled into.
 
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+
 =cut
 */
 
@@ -143,6 +152,10 @@ PERLVAR(I, curstash,       HV *)           /* symbol table for current package */
 The currently active COP (control op) roughly representing the current
 statement in the source.
 
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+
 =cut
 */
 
@@ -171,16 +184,18 @@ PERLVAR(I, regmatch_state, regmatch_state *)
 PERLVAR(I, comppad,    PAD *)          /* storage for lexically scoped temporaries */
 
 /*
+=for apidoc_section $SV
 =for apidoc Amn|SV|PL_sv_undef
-This is the C<undef> SV.  Always refer to this as C<&PL_sv_undef>.
+This is the C<undef> SV.  It is readonly.  Always refer to this as
+C<&PL_sv_undef>.
 
 =for apidoc Amn|SV|PL_sv_no
-This is the C<false> SV.  See C<L</PL_sv_yes>>.  Always refer to this as
-C<&PL_sv_no>.
+This is the C<false> SV.  It is readonly.  See C<L</PL_sv_yes>>.  Always refer
+to this as C<&PL_sv_no>.
 
 =for apidoc Amn|SV|PL_sv_yes
-This is the C<true> SV.  See C<L</PL_sv_no>>.  Always refer to this as
-C<&PL_sv_yes>.
+This is the C<true> SV.  It is readonly.  See C<L</PL_sv_no>>.  Always refer to
+this as C<&PL_sv_yes>.
 
 =for apidoc Amn|SV|PL_sv_zero
 This readonly SV has a zero numeric value and a C<"0"> string value. It's
@@ -242,18 +257,31 @@ PERLVAR(I, statgv,        GV *)
 PERLVARI(I, statname,  SV *,   NULL)
 
 /*
+=for apidoc_section $io
 =for apidoc mn|SV*|PL_rs
 
 The input record separator - C<$/> in Perl space.
 
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+
 =for apidoc mn|GV*|PL_last_in_gv
 
 The GV which was last used for a filehandle input operation.  (C<< <FH> >>)
 
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+
 =for apidoc mn|GV*|PL_ofsgv
 
 The glob containing the output field separator - C<*,> in Perl space.
 
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+
 =cut
 */
 
@@ -293,6 +321,7 @@ PERLVARI(I, dumpindent,     U16,    4)      /* number of blanks per dump
                                           indentation level */
 
 /*
+=for apidoc_section $embedding
 =for apidoc Amn|U8|PL_exit_flags
 
 Contains flags controlling perl's behaviour on exit():
@@ -325,6 +354,10 @@ Set by the L<perlfunc/exit> operator.
 =for apidoc Amnh||PERL_EXIT_DESTRUCT_END
 =for apidoc Amnh||PERL_EXIT_WARN
 
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+
 =cut
 */
 
@@ -346,6 +379,7 @@ PERLVARA(I, locale_utf8ness, 256, char)
 PERLVARA(I, colors,6,  char *)         /* values from PERL_RE_COLORS env var */
 
 /*
+=for apidoc_section $optree_construction
 =for apidoc Amn|peep_t|PL_peepp
 
 Pointer to the per-subroutine peephole optimiser.  This is a function
@@ -363,6 +397,10 @@ If the new code wishes to operate on ops throughout the subroutine's
 structure, rather than just at the top level, it is likely to be more
 convenient to wrap the L</PL_rpeepp> hook.
 
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+
 =cut
 */
 
@@ -387,6 +425,10 @@ If the new code wishes to operate only on ops at a subroutine's top level,
 rather than throughout the structure, it is likely to be more convenient
 to wrap the L</PL_peepp> hook.
 
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+
 =cut
 */
 
@@ -401,6 +443,10 @@ It is also assured to first fire for the parent OP and then for its kids.
 
 When you replace this variable, it is considered a good practice to store the possibly previously installed hook and that you recall it inside your own.
 
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+
 =cut
 */
 
@@ -475,12 +521,17 @@ PERLVAR(I, DBgv,  GV *)           /*  *DB::DB     */
 PERLVAR(I, DBline,     GV *)           /*  *DB::line   */
 
 /*
+=for apidoc_section $debugging
 =for apidoc mn|GV *|PL_DBsub
 When Perl is run in debugging mode, with the B<-d> switch, this GV contains
 the SV which holds the name of the sub being debugged.  This is the C
 variable which corresponds to Perl's $DB::sub variable.  See
 C<L</PL_DBsingle>>.
 
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+
 =for apidoc mn|SV *|PL_DBsingle
 When Perl is run in debugging mode, with the B<-d> switch, this SV is a
 boolean which indicates whether subs are being single-stepped.
@@ -488,11 +539,19 @@ Single-stepping is automatically turned on after every step.  This is the C
 variable which corresponds to Perl's $DB::single variable.  See
 C<L</PL_DBsub>>.
 
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+
 =for apidoc mn|SV *|PL_DBtrace
 Trace variable used when Perl is run in debugging mode, with the B<-d>
 switch.  This is the C variable which corresponds to Perl's $DB::trace
 variable.  See C<L</PL_DBsingle>>.
 
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+
 =cut
 */
 
@@ -561,6 +620,7 @@ PERLVARI(I, exitlist,       PerlExitListEntry *, NULL)
                                        /* list of exit functions */
 
 /*
+=for apidoc_section $HV
 =for apidoc Amn|HV*|PL_modglobal
 
 C<PL_modglobal> is a general purpose, interpreter global HV for use by
@@ -569,6 +629,10 @@ In a pinch, it can also be used as a symbol table for extensions
 to share data among each other.  It is a good idea to use keys
 prefixed by the package name of the extension that owns the data.
 
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+
 =cut
 */
 
@@ -695,6 +759,7 @@ PERLVAR(I, unsafe,  bool)
 PERLVAR(I, colorset,   bool)           /* PERL_RE_COLORS env var is in use */
 
 /*
+=for apidoc_section $embedding
 =for apidoc Amn|signed char|PL_perl_destruct_level
 
 This value may be set when embedding for full cleanup.
@@ -714,6 +779,10 @@ Possible values:
 If C<$ENV{PERL_DESTRUCT_LEVEL}> is set to an integer greater than the
 value of C<PL_perl_destruct_level> its value is used instead.
 
+On threaded perls, each thread has an independent copy of this variable;
+each initialized at creation time with the current value of the creating
+thread's copy.
+
 =cut
 */
 /* mod_perl is special, and also assigns a meaning -1 */
@@ -951,6 +1020,12 @@ PERLVAR(I, mbrtowc_ps, mbstate_t)
 #ifdef HAS_WCRTOMB
 PERLVAR(I, wcrtomb_ps, mbstate_t)
 #endif
+#ifdef PERL_MEM_LOG
+/* Enough space for the reserved byte, 1 for a potential leading 0, then enough
+ * for the longest representable integer plus an extra, the 3 flag characters,
+ * and NUL */
+PERLVARA(I, mem_log, 1 + 1 + TYPE_DIGITS(UV) + 1 + 3 + 1, char);
+#endif
 
 /* If you are adding a U8 or U16, check to see if there are 'Space' comments
  * above on where there are gaps which currently will be structure padding.  */
index c176ad5..2809114 100644 (file)
@@ -654,6 +654,10 @@ typedef int                (*LPLIOUnlink)(struct IPerlLIO*, const char*);
 typedef int            (*LPLIOUtime)(struct IPerlLIO*, const char*, struct utimbuf*);
 typedef int            (*LPLIOWrite)(struct IPerlLIO*, int, const void*,
                            unsigned int);
+typedef int            (*LPLIOSymLink)(struct IPerlLIO*, const char*,
+                                    const char *);
+typedef int            (*LPLIOReadLink)(struct IPerlLIO*, const char*,
+                                         char *, size_t);
 
 struct IPerlLIO
 {
@@ -683,6 +687,8 @@ struct IPerlLIO
     LPLIOUnlink                pUnlink;
     LPLIOUtime         pUtime;
     LPLIOWrite         pWrite;
+    LPLIOSymLink        pSymLink;
+    LPLIOReadLink       pReadLink;
 };
 
 struct IPerlLIOInfo
@@ -715,6 +721,10 @@ struct IPerlLIOInfo
        (*PL_LIO->pIsatty)(PL_LIO, (fd))
 #define PerlLIO_link(oldname, newname)                                 \
        (*PL_LIO->pLink)(PL_LIO, (oldname), (newname))
+#define PerlLIO_symlink(oldname, newname)                              \
+        (*PL_LIO->pSymLink)(PL_LIO, (oldname), (newname))
+#define PerlLIO_readlink(path, buf, bufsiz)                            \
+        (*PL_LIO->pReadLink)(PL_LIO, (path), (buf), (bufsiz))
 #define PerlLIO_lseek(fd, offset, mode)                                        \
        (*PL_LIO->pLseek)(PL_LIO, (fd), (offset), (mode))
 #define PerlLIO_lstat(name, buf)                                       \
@@ -764,6 +774,8 @@ struct IPerlLIOInfo
 #define PerlLIO_ioctl(fd, u, buf)      ioctl((fd), (u), (buf))
 #define PerlLIO_isatty(fd)             isatty((fd))
 #define PerlLIO_link(oldname, newname) link((oldname), (newname))
+#define PerlLIO_symlink(oldname, newname)      symlink((oldname), (newname))
+#define PerlLIO_readlink(path, buf, bufsiz)    readlink((path), (buf), (bufsiz))
 #define PerlLIO_lseek(fd, offset, mode)        lseek((fd), (offset), (mode))
 #define PerlLIO_stat(name, buf)                Stat((name), (buf))
 #ifdef HAS_LSTAT
diff --git a/lib/.gitignore b/lib/.gitignore
new file mode 100644 (file)
index 0000000..4973b08
--- /dev/null
@@ -0,0 +1,229 @@
+# -*- buffer-read-only: t -*-
+# !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!!
+# This file is built by regen/lib_cleanup.pl from MANIFEST and parsing files
+# in cpan/ dist/ and ext/.
+# Any changes made here will be lost!
+
+# If this generated file has problems, it may be simpler to add more special
+# cases to the top level .gitignore than to code one-off logic into the
+# generation script regen/lib_cleanup.pl
+
+/Amiga/
+/App/
+/Archive/
+/Attribute/
+/AutoLoader.pm
+/AutoSplit.pm
+/B.pm
+/B/Concise.pm
+/B/Showlex.pm
+/B/Terse.pm
+/B/Xref.pm
+/CPAN.pm
+/CPAN/
+/Carp.pm
+/Carp/
+/Compress/
+/Config/Perl/
+/Cwd.pm
+/DB_File.pm
+/Data/
+/Devel/
+/Digest.pm
+/Digest/
+/Dumpvalue.pm
+/DynaLoader.pm
+/Encode.pm
+/Encode/
+/Env.pm
+/Errno.pm
+/Exporter.pm
+/Exporter/
+/ExtUtils/CBuilder.pm
+/ExtUtils/CBuilder/
+/ExtUtils/Command.pm
+/ExtUtils/Command/
+/ExtUtils/Constant.pm
+/ExtUtils/Constant/
+/ExtUtils/Install.pm
+/ExtUtils/Installed.pm
+/ExtUtils/Liblist.pm
+/ExtUtils/Liblist/
+/ExtUtils/MM.pm
+/ExtUtils/MM_AIX.pm
+/ExtUtils/MM_Any.pm
+/ExtUtils/MM_BeOS.pm
+/ExtUtils/MM_Cygwin.pm
+/ExtUtils/MM_DOS.pm
+/ExtUtils/MM_Darwin.pm
+/ExtUtils/MM_MacOS.pm
+/ExtUtils/MM_NW5.pm
+/ExtUtils/MM_OS2.pm
+/ExtUtils/MM_OS390.pm
+/ExtUtils/MM_QNX.pm
+/ExtUtils/MM_UWIN.pm
+/ExtUtils/MM_Unix.pm
+/ExtUtils/MM_VMS.pm
+/ExtUtils/MM_VOS.pm
+/ExtUtils/MM_Win32.pm
+/ExtUtils/MM_Win95.pm
+/ExtUtils/MY.pm
+/ExtUtils/MakeMaker.pm
+/ExtUtils/MakeMaker/
+/ExtUtils/Manifest.pm
+/ExtUtils/Miniperl.pm
+/ExtUtils/Mkbootstrap.pm
+/ExtUtils/Mksymlists.pm
+/ExtUtils/PL2Bat.pm
+/ExtUtils/Packlist.pm
+/ExtUtils/ParseXS.pm
+/ExtUtils/ParseXS.pod
+/ExtUtils/ParseXS/
+/ExtUtils/Typemaps.pm
+/ExtUtils/Typemaps/
+/ExtUtils/testlib.pm
+/Fatal.pm
+/Fcntl.pm
+/File/DosGlob.pm
+/File/Fetch.pm
+/File/Find.pm
+/File/Glob.pm
+/File/GlobMapper.pm
+/File/Path.pm
+/File/Spec.pm
+/File/Spec/
+/File/Temp.pm
+/FileCache.pm
+/Filter/
+/FindBin.pm
+/GDBM_File.pm
+/Getopt/Long.pm
+/HTTP/
+/Hash/
+/I18N/
+/IO.pm
+/IO/
+/IPC/
+/JSON/
+/List/
+/Locale/
+/MIME/
+/Math/
+/Memoize.pm
+/Memoize/
+/Module/
+/NDBM_File.pm
+/NEXT.pm
+/Net/Cmd.pm
+/Net/Config.pm
+/Net/Domain.pm
+/Net/FTP.pm
+/Net/FTP/
+/Net/NNTP.pm
+/Net/Netrc.pm
+/Net/POP3.pm
+/Net/Ping.pm
+/Net/SMTP.pm
+/Net/Time.pm
+/Net/libnetFAQ.pod
+/O.pm
+/ODBM_File.pm
+/Opcode.pm
+/POSIX.pm
+/POSIX.pod
+/Params/
+/Parse/
+/Perl/
+/PerlIO/
+/Pod/Checker.pm
+/Pod/Escapes.pm
+/Pod/Functions.pm
+/Pod/Html.pm
+/Pod/Man.pm
+/Pod/ParseLink.pm
+/Pod/Perldoc.pm
+/Pod/Perldoc/
+/Pod/Simple.pm
+/Pod/Simple.pod
+/Pod/Simple/
+/Pod/Text.pm
+/Pod/Text/
+/Pod/Usage.pm
+/Pod/perldoc.pod
+/SDBM_File.pm
+/Safe.pm
+/Scalar/
+/Search/
+/SelfLoader.pm
+/Socket.pm
+/Storable.pm
+/Sub/
+/Sys/
+/TAP/
+/Term/
+/Test.pm
+/Test/
+/Test2.pm
+/Test2/
+/Text/
+/Thread/
+/Tie/File.pm
+/Tie/Hash/
+/Tie/Memoize.pm
+/Tie/RefHash.pm
+/Time/HiRes.pm
+/Time/Local.pm
+/Time/Piece.pm
+/Time/Seconds.pm
+/Unicode/Collate.pm
+/Unicode/Collate/
+/Unicode/Normalize.pm
+/VMS/
+/Win32.pm
+/Win32API/
+/Win32CORE.pm
+/XS/
+/XSLoader.pm
+/attributes.pm
+/autodie.pm
+/autodie/
+/autouse.pm
+/base.pm
+/bigint.pm
+/bignum.pm
+/bigrat.pm
+/constant.pm
+/encoding.pm
+/encoding/
+/experimental.pm
+/fields.pm
+/if.pm
+/inc/
+/lib.pm
+/mro.pm
+/ok.pm
+/ops.pm
+/parent.pm
+/perlfaq.pm
+/perlfaq.pod
+/perlfaq1.pod
+/perlfaq2.pod
+/perlfaq3.pod
+/perlfaq4.pod
+/perlfaq5.pod
+/perlfaq6.pod
+/perlfaq7.pod
+/perlfaq8.pod
+/perlfaq9.pod
+/perlglossary.pod
+/perlxs.pod
+/perlxstut.pod
+/perlxstypemap.pod
+/re.pm
+/threads.pm
+/threads/
+/version.pm
+/version.pod
+/version/
+
+# ex: set ro:
index d89e3da..2961bd9 100644 (file)
@@ -118,7 +118,7 @@ package B::Op_private;
 our %bits;
 
 
-our $VERSION = "5.033004";
+our $VERSION = "5.033005";
 
 $bits{$_}{3} = 'OPpENTERSUB_AMPER' for qw(entersub rv2cv);
 $bits{$_}{6} = 'OPpENTERSUB_DB' for qw(entersub rv2cv);
index 63609cc..ac98cc2 100644 (file)
@@ -24,7 +24,7 @@ sub syscopy;
 sub cp;
 sub mv;
 
-$VERSION = '2.34';
+$VERSION = '2.35';
 
 require Exporter;
 @ISA = qw(Exporter);
@@ -100,7 +100,7 @@ sub copy {
     }
 
     if ((($Config{d_symlink} && $Config{d_readlink}) || $Config{d_link}) &&
-       !($^O eq 'MSWin32' || $^O eq 'os2')) {
+       !($^O eq 'os2')) {
        my @fs = stat($from);
        if (@fs) {
            my @ts = stat($to);
index 57d9478..f21c871 100644 (file)
@@ -164,7 +164,10 @@ for my $cross_partition_test (0..1) {
     open(F, ">", "file-$$") or die $!;
     print F "dummy content\n";
     close F;
-    symlink("file-$$", "symlink-$$") or die $!;
+    if (!symlink("file-$$", "symlink-$$")) {
+        unlink "file-$$";
+        skip "Can't create symlink", 3;
+    }
 
     my $warnings = '';
     local $SIG{__WARN__} = sub { $warnings .= join '', @_ };
index 69890ef..3ab6e57 100644 (file)
@@ -531,7 +531,7 @@ BEGIN {
 use vars qw($VERSION $header);
 
 # bump to X.XX in blead, only use X.XX_XX in maint
-$VERSION = '1.59';
+$VERSION = '1.60';
 
 $header = "perl5db.pl version $VERSION";
 
@@ -1878,7 +1878,7 @@ sub _DB__trim_command_and_return_first_component {
     # A single-character debugger command can be immediately followed by its
     # argument if they aren't both alphanumeric; otherwise require space
     # between commands and arguments:
-    my ($verb, $args) = $cmd =~ m{\A(.\b|\S*)\s*(.*)}s;
+    my ($verb, $args) = $cmd =~ m{\A([^\.-]\b|\S*)\s*(.*)}s;
 
     $obj->cmd_verb($verb);
     $obj->cmd_args($args);
index d68eeb7..f6740f5 100644 (file)
@@ -2144,7 +2144,11 @@ DebugWrap->new({
             [
                 '= quit q',
                 '= foobar l',
+                '= .hello print "hellox\n"',
+                '= -goodbye print "goodbyex\n"',
                 'foobar',
+                '.hello',
+                '-goodbye',
                 'quit',
             ],
             prog => '../lib/perl5db/t/test-l-statement-1',
@@ -2160,7 +2164,9 @@ DebugWrap->new({
             5:\s+print\ "2\\n";\n
         /msx,
         'Test the = (command alias) command.',
-    );
+       );
+    $wrapper->output_like(qr/hellox.*goodbyex/xs,
+                          "check . and - can start alias name");
 }
 
 # Test the m statement.
index 595792c..6f3420b 100644 (file)
@@ -5,7 +5,7 @@
 
 package warnings;
 
-our $VERSION = "1.48";
+our $VERSION = "1.49";
 
 # Verify that we're called correctly so that warnings will work.
 # Can't use Carp, since Carp uses us!
@@ -335,16 +335,24 @@ sub bits
 
 sub import
 {
-    shift;
-
-    my $mask = ${^WARNING_BITS} // ($^W ? $Bits{all} : $DEFAULT) ;
+    my $invocant = shift;
 
     # append 'all' when implied (empty import list or after a lone
     # "FATAL" or "NONFATAL")
     push @_, 'all'
-       if !@_ || (@_==1 && ($_[0] eq 'FATAL' || $_[0] eq 'NONFATAL'));
-
-    ${^WARNING_BITS} = _bits($mask, @_);
+        if !@_ || (@_==1 && ($_[0] eq 'FATAL' || $_[0] eq 'NONFATAL'));
+
+    my @fatal = ();
+    foreach my $warning (@_) {
+        if($warning =~ /^(NON)?FATAL$/) {
+            @fatal = ($warning);
+        } elsif(substr($warning, 0, 1) ne '-') {
+            my $mask = ${^WARNING_BITS} // ($^W ? $Bits{all} : $DEFAULT) ;
+            ${^WARNING_BITS} = _bits($mask, @fatal, $warning);
+        } else {
+            $invocant->unimport(substr($warning, 1));
+        }
+    }
 }
 
 sub unimport
@@ -571,7 +579,10 @@ warnings - Perl pragma to control optional warnings
     no warnings;
 
     use warnings "all";
-    no warnings "all";
+    no warnings "uninitialized";
+
+    # or equivalent to those last two ...
+    use warnings qw(all -uninitialized);
 
     use warnings::register;
     if (warnings::enabled()) {
@@ -658,6 +669,41 @@ be reported for the C<$x> variable.
 Note that neither the B<-w> flag or the C<$^W> can be used to
 disable/enable default warnings.  They are still mandatory in this case.
 
+=head2 "Negative warnings"
+
+As a convenience, you can (as of Perl 5.34) pass arguments to the
+C<import()> method both positively and negatively. Negative warnings
+are those with a C<-> sign prepended to their names; positive warnings
+are anything else. This lets you turn on some warnings and turn off
+others in one command. So, assuming that you've already turned on a
+bunch of warnings but want to tweak them a bit in some block, you can
+do this:
+
+    {
+        use warnings qw(uninitialized -redefine);
+        ...
+    }
+
+which is equivalent to:
+
+    {
+        use warnings qw(uninitialized);
+        no warnings qw(redefine);
+        ...
+    }
+
+The argument list is processed in the order you specify. So, for example, if you
+don't want to be warned about use of experimental features, except for C<somefeature>
+that you really dislike, you can say this:
+
+    use warnings qw(all -experimental experimental::somefeature);
+
+which is equivalent to:
+
+    use warnings 'all';
+    no warnings  'experimental';
+    use warnings 'experimental::somefeature';
+
 =head2 What's wrong with B<-w> and C<$^W>
 
 Although very useful, the big problem with using B<-w> on the command
index 4654a5b..ed3cb66 100644 (file)
--- a/locale.c
+++ b/locale.c
@@ -636,11 +636,12 @@ S_emulate_setlocale(const int category,
         /* If this assert fails, adjust the size of curlocales in intrpvar.h */
         STATIC_ASSERT_STMT(C_ARRAY_LENGTH(PL_curlocales) > LC_ALL_INDEX);
 
-#    if   defined(_NL_LOCALE_NAME)                      \
-     &&   defined(DEBUGGING)                            \
+#    if   defined(_NL_LOCALE_NAME)                                          \
+     &&   defined(DEBUGGING)                                                \
+          /* On systems that accept any locale name, the real underlying    \
+           * locale is often returned by this internal function, so we      \
+           * can't use it */                                                \
      && ! defined(SETLOCALE_ACCEPTS_ANY_LOCALE_NAME)
-          /* On systems that accept any locale name, the real underlying locale
-           * is often returned by this internal function, so we can't use it */
         {
             /* Internal glibc for querylocale(), but doesn't handle
              * empty-string ("") locale properly; who knows what other
@@ -1226,10 +1227,10 @@ S_emulate_setlocale(const int category,
  * correct locale for that thread.  Any operation that was locale-sensitive
  * would have to be changed so that it would look like this:
  *
- *      LOCALE_LOCK;
+ *      SETLOCALE_LOCK;
  *      setlocale to the correct locale for this operation
  *      do operation
- *      LOCALE_UNLOCK
+ *      SETLOCALE_UNLOCK
  *
  * This leaves the global locale in the most recently used operation's, but it
  * was locked long enough to get the result.  If that result is static, it
@@ -1322,7 +1323,7 @@ S_locking_setlocale(pTHX_
 
     /* It might be that this is called from an already-locked section of code.
      * We would have to detect and skip the LOCK/UNLOCK if so */
-    LOCALE_LOCK;
+    SETLOCALE_LOCK;
 
     curlocales[index] = savepv(my_setlocale(category, new_locale));
 
@@ -1344,7 +1345,7 @@ S_locking_setlocale(pTHX_
 
 #endif
 
-    LOCALE_UNLOCK;
+    SETLOCALE_UNLOCK;
 
     return curlocales[index];
 }
@@ -2619,8 +2620,7 @@ S_my_nl_langinfo(const int item, bool toggle)
 
 #if defined(HAS_NL_LANGINFO) /* nl_langinfo() is available.  */
 #  if   ! defined(HAS_THREAD_SAFE_NL_LANGINFO_L)      \
-     || ! defined(HAS_POSIX_2008_LOCALE)              \
-     || ! defined(DUPLOCALE)
+     || ! defined(HAS_POSIX_2008_LOCALE)
 
     /* Here, use plain nl_langinfo(), switching to the underlying LC_NUMERIC
      * for those items dependent on it.  This must be copied to a buffer before
@@ -2634,18 +2634,16 @@ S_my_nl_langinfo(const int item, bool toggle)
             STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
         }
 
-        LOCALE_LOCK;    /* Prevent interference from another thread executing
-                           this code section (the only call to nl_langinfo in
-                           the core) */
-
+        /* Prevent interference from another thread executing this code
+         * section. */
+        NL_LANGINFO_LOCK;
 
         /* Copy to a per-thread buffer, which is also one that won't be
          * destroyed by a subsequent setlocale(), such as the
          * RESTORE_LC_NUMERIC may do just below. */
         retval = save_to_buffer(nl_langinfo(item),
                                 &PL_langinfo_buf, &PL_langinfo_bufsize, 0);
-
-        LOCALE_UNLOCK;
+        NL_LANGINFO_UNLOCK;
 
         if (toggle) {
             RESTORE_LC_NUMERIC();
@@ -2819,8 +2817,8 @@ S_my_nl_langinfo(const int item, bool toggle)
                 /* We don't bother with localeconv_l() because any system that
                  * has it is likely to also have nl_langinfo() */
 
-                LOCALE_LOCK_V;    /* Prevent interference with other threads
-                                     using localeconv() */
+                LOCALECONV_LOCK;    /* Prevent interference with other threads
+                                       using localeconv() */
 
 #    ifdef TS_W32_BROKEN_LOCALECONV
 
@@ -2847,7 +2845,7 @@ S_my_nl_langinfo(const int item, bool toggle)
                     || ! lc->currency_symbol
                     || strEQ("", lc->currency_symbol))
                 {
-                    LOCALE_UNLOCK_V;
+                    LOCALECONV_UNLOCK;
                     return "";
                 }
 
@@ -2877,7 +2875,7 @@ S_my_nl_langinfo(const int item, bool toggle)
 
 #    endif
 
-                LOCALE_UNLOCK_V;
+                LOCALECONV_UNLOCK;
                 break;
 
 #    ifdef TS_W32_BROKEN_LOCALECONV
@@ -2950,8 +2948,8 @@ S_my_nl_langinfo(const int item, bool toggle)
                     STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
                 }
 
-                LOCALE_LOCK_V;    /* Prevent interference with other threads
-                                     using localeconv() */
+                LOCALECONV_LOCK;    /* Prevent interference with other threads
+                                       using localeconv() */
 
 #    ifdef TS_W32_BROKEN_LOCALECONV
 
@@ -3003,7 +3001,7 @@ S_my_nl_langinfo(const int item, bool toggle)
 
 #    endif
 
-                LOCALE_UNLOCK_V;
+                LOCALECONV_UNLOCK;
 
                 if (toggle) {
                     RESTORE_LC_NUMERIC();
@@ -3041,8 +3039,6 @@ S_my_nl_langinfo(const int item, bool toggle)
             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;
-
                 init_tm(&tm);   /* Precaution against core dumps */
                 tm.tm_sec = 30;
                 tm.tm_min = 30;
@@ -3052,7 +3048,6 @@ S_my_nl_langinfo(const int item, bool toggle)
                 tm.tm_mon = 0;
                 switch (item) {
                     default:
-                        LOCALE_UNLOCK;
                         Perl_croak(aTHX_
                                     "panic: %s: %d: switch case: %d problem",
                                        __FILE__, __LINE__, item);
@@ -3228,8 +3223,6 @@ S_my_nl_langinfo(const int item, bool toggle)
                  * wday was chosen because its range is all a single digit.
                  * Things like tm_sec have two digits as the minimum: '00' */
 
-                LOCALE_UNLOCK;
-
                 retval = PL_langinfo_buf;
 
                 /* If to return the format, not the value, overwrite the buffer
@@ -4844,12 +4837,12 @@ Perl__is_cur_LC_category_utf8(pTHX_ int category)
 
 #      else
 
-            LOCALE_LOCK;
+            MBTOWC_LOCK;
             PERL_UNUSED_RESULT(mbtowc(&wc, NULL, 0));/* Reset any shift state */
             SETERRNO(0, 0);
             len = mbtowc(&wc, STR_WITH_LEN(REPLACEMENT_CHARACTER_UTF8));
             SAVE_ERRNO;
-            LOCALE_UNLOCK;
+            MBTOWC_UNLOCK;
 
 #      endif
 
@@ -5302,8 +5295,7 @@ Perl_my_strerror(pTHX_ const int errnum)
     }
 
 #  elif   defined(USE_POSIX_2008_LOCALE)                      \
-     &&   defined(HAS_STRERROR_L)                             \
-     &&   defined(HAS_DUPLOCALE)
+     &&   defined(HAS_STRERROR_L)
 
     /* This function is also trivial if we don't have to worry about thread
      * safety and have strerror_l(), as it handles the switch of locales so we
@@ -5358,13 +5350,14 @@ Perl_my_strerror(pTHX_ const int errnum)
      * same code at the same time.  (On thread-safe perls, the LOCK is a
      * no-op.)  Since this is the only place in core that changes LC_MESSAGES
      * (unless the user has called setlocale(), this works to prevent races. */
-    LOCALE_LOCK;
+    SETLOCALE_LOCK;
 
     DEBUG_Lv(PerlIO_printf(Perl_debug_log,
                             "my_strerror called with errnum %d\n", errnum));
     if (! within_locale_scope) {
         save_locale = do_setlocale_c(LC_MESSAGES, NULL);
         if (! save_locale) {
+            SETLOCALE_UNLOCK;
             Perl_croak(aTHX_
                  "panic: %s: %d: Could not find current LC_MESSAGES locale,"
                  " errno=%d\n", __FILE__, __LINE__, errno);
@@ -5378,7 +5371,19 @@ Perl_my_strerror(pTHX_ const int errnum)
                 /* The setlocale() just below likely will zap 'save_locale', so
                  * create a copy.  */
                 save_locale = savepv(save_locale);
-                do_setlocale_c(LC_MESSAGES, "C");
+                if (! do_setlocale_c(LC_MESSAGES, "C")) {
+
+                    /* If, for some reason, the locale change failed, we
+                     * soldier on as best as possible under the circumstances,
+                     * using the current locale, and clear save_locale, so we
+                     * don't try to change back.  On z/0S, all setlocale()
+                     * calls fail after you've created a thread.  This is their
+                     * way of making sure the entire process is always a single
+                     * locale.  This means that 'use locale' is always in place
+                     * for messages under these circumstances. */
+                    Safefree(save_locale);
+                    save_locale = NULL;
+                }
             }
         }
     }   /* end of ! within_locale_scope */
@@ -5394,15 +5399,16 @@ Perl_my_strerror(pTHX_ const int errnum)
     if (! within_locale_scope) {
         if (save_locale && ! locale_is_C) {
             if (! do_setlocale_c(LC_MESSAGES, save_locale)) {
+                SETLOCALE_UNLOCK;
                 Perl_croak(aTHX_
-                     "panic: %s: %d: setlocale restore failed, errno=%d\n",
-                             __FILE__, __LINE__, errno);
+                     "panic: %s: %d: setlocale restore to '%s' failed, errno=%d\n",
+                             __FILE__, __LINE__, save_locale, errno);
             }
             Safefree(save_locale);
         }
     }
 
-    LOCALE_UNLOCK;
+    SETLOCALE_UNLOCK;
 
 #  endif /* End of doesn't have strerror_l */
 #  ifdef DEBUGGING
index 9af199d..16dd951 100644 (file)
@@ -455,9 +455,6 @@ unless ($define{'PERL_IMPLICIT_CONTEXT'}) {
 if ($define{USE_THREAD_SAFE_LOCALE}) {
     ++$skip{PL_lc_numeric_mutex};
     ++$skip{PL_lc_numeric_mutex_depth};
-    if (! $define{TS_W32_BROKEN_LOCALECONV}) {
-        ++$skip{PL_locale_mutex};
-    }
 }
 
 unless ($define{'USE_DTRACE'}) {
@@ -489,6 +486,10 @@ unless ($define{'PERL_TRACK_MEMPOOL'}) {
     ++$skip{PL_memory_debug_header};
 }
 
+unless ($define{'PERL_MEM_LOG'}) {
+    ++$skip{PL_mem_log};
+}
+
 unless ($define{'MULTIPLICITY'}) {
     ++$skip{$_} foreach qw(
                    PL_interp_size
index a07b260..fb21563 100644 (file)
--- a/mathoms.c
+++ b/mathoms.c
@@ -1261,6 +1261,8 @@ Looks up the type of the lexical variable at position C<po> in the
 currently-compiling pad.  If the variable is typed, the stash of the
 class to which it is typed is returned.  If not, C<NULL> is returned.
 
+Use L<perlintern/C<PAD_COMPNAME_TYPE>> instead.
+
 =cut
 */
 
index baba5ea..ae0093a 100644 (file)
@@ -14,4 +14,6 @@
  * they should be removed from here.
  *
  * HAS_WCRTOMB
+ * GETENV_PRESERVES_OTHER_THREAD
+ *
  */
diff --git a/mg.c b/mg.c
index 8b90aa4..fcbefff 100644 (file)
--- a/mg.c
+++ b/mg.c
@@ -1128,11 +1128,6 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg)
                          *PL_compiling.cop_warnings);
            }
        }
-#ifdef WIN32
-       else if (strEQ(remaining, "IN32_SLOPPY_STAT")) {
-           sv_setiv(sv, w32_sloppystat);
-       }
-#endif
        break;
     case '+':
        if (PL_curpm && (rx = PM_GETRE(PL_curpm))) {
@@ -2769,8 +2764,6 @@ static void
 S_set_dollarzero(pTHX_ SV *sv)
     PERL_TSA_REQUIRES(PL_dollarzero_mutex)
 {
-#ifdef USE_ITHREADS
-#endif
     const char *s;
     STRLEN len;
 #ifdef HAS_SETPROCTITLE
@@ -2847,8 +2840,6 @@ S_set_dollarzero(pTHX_ SV *sv)
 int
 Perl_magic_set(pTHX_ SV *sv, MAGIC *mg)
 {
-#ifdef USE_ITHREADS
-#endif
     I32 paren;
     const REGEXP * rx;
     I32 i;
@@ -3044,11 +3035,6 @@ Perl_magic_set(pTHX_ SV *sv, MAGIC *mg)
                }
            }
        }
-#ifdef WIN32
-       else if (strEQ(mg->mg_ptr+1, "IN32_SLOPPY_STAT")) {
-           w32_sloppystat = SvTRUE(sv);
-       }
-#endif
        break;
     case '.':
        if (PL_localizing) {
index 52c4547..349048c 100644 (file)
--- a/numeric.c
+++ b/numeric.c
@@ -994,7 +994,7 @@ C<valuep> is non-C<NULL>, but no actual assignment (or SEGV) will occur.
 C<IS_NUMBER_NOT_INT> will be set with C<IS_NUMBER_IN_UV> if trailing decimals were
 seen (in which case C<*valuep> gives the true value truncated to an integer), and
 C<IS_NUMBER_NEG> if the number is negative (in which case C<*valuep> holds the
-absolute value).  C<IS_NUMBER_IN_UV> is not set if e notation was used or the
+absolute value).  C<IS_NUMBER_IN_UV> is not set if C<e> notation was used or the
 number is larger than a UV.
 
 C<flags> allows only C<PERL_SCAN_TRAILING>, which allows for trailing
diff --git a/op.c b/op.c
index 421387e..822ea18 100644 (file)
--- a/op.c
+++ b/op.c
@@ -1406,8 +1406,6 @@ void
 Perl_op_refcnt_lock(pTHX)
   PERL_TSA_ACQUIRE(PL_op_mutex)
 {
-#ifdef USE_ITHREADS
-#endif
     PERL_UNUSED_CONTEXT;
     OP_REFCNT_LOCK;
 }
@@ -1416,8 +1414,6 @@ void
 Perl_op_refcnt_unlock(pTHX)
   PERL_TSA_RELEASE(PL_op_mutex)
 {
-#ifdef USE_ITHREADS
-#endif
     PERL_UNUSED_CONTEXT;
     OP_REFCNT_UNLOCK;
 }
index c754a64..7c708e4 100644 (file)
--- a/opcode.h
+++ b/opcode.h
@@ -13,6 +13,8 @@
  * Any changes made here will be lost!
  */
 
+#if defined(PERL_CORE) || defined(PERL_EXT)
+
 #define Perl_pp_scalar Perl_pp_null
 #define Perl_pp_padany Perl_unimplemented_op
 #define Perl_pp_regcmaybe Perl_pp_null
 #define Perl_pp_sgrent Perl_pp_ehostent
 #define Perl_pp_egrent Perl_pp_ehostent
 #define Perl_pp_custom Perl_unimplemented_op
+
+#endif /* End of if defined(PERL_CORE) || defined(PERL_EXT) */
+
 START_EXTERN_C
 
 #ifndef DOINIT
diff --git a/pad.c b/pad.c
index 9283e43..2af0e19 100644 (file)
--- a/pad.c
+++ b/pad.c
@@ -2186,8 +2186,6 @@ S_cv_clone_pad(pTHX_ CV *proto, CV *cv, CV *outside, HV *cloned,
 static CV *
 S_cv_clone(pTHX_ CV *proto, CV *cv, CV *outside, HV *cloned)
 {
-#ifdef USE_ITHREADS
-#endif
     const bool newcv = !cv;
 
     assert(!CvUNIQUE(proto));
index 69b9ef5..b2c0442 100644 (file)
@@ -39,7 +39,7 @@ Instead use one of the version comparison macros.  See C<L</PERL_VERSION_EQ>>.
 
 #define PERL_REVISION  5               /* age */
 #define PERL_VERSION   33              /* epoch */
-#define PERL_SUBVERSION        4               /* generation */
+#define PERL_SUBVERSION        5               /* generation */
 
 /* The following numbers describe the earliest compatible version of
    Perl ("compatibility" here being defined as sufficient binary/API
@@ -60,7 +60,7 @@ Instead use one of the version comparison macros.  See C<L</PERL_VERSION_EQ>>.
 */
 #define PERL_API_REVISION      5
 #define PERL_API_VERSION       33
-#define PERL_API_SUBVERSION    4
+#define PERL_API_SUBVERSION    5
 /*
    XXX Note:  The selection of non-default Configure options, such
    as -Duselonglong may invalidate these settings.  Currently, Configure
diff --git a/perl.c b/perl.c
index 488cebc..6c3ed0d 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -2831,17 +2831,24 @@ Perl_get_hv(pTHX_ const char *name, I32 flags)
 /*
 =for apidoc_section $CV
 
-=for apidoc get_cvn_flags
+=for apidoc get_cv
+=for apidoc_item |CV *|get_cvs|"string"|I32 flags
+=for apidoc_item get_cvn_flags
 
-Returns the CV of the specified Perl subroutine.  C<flags> are passed to
+These return the CV of the specified Perl subroutine.  C<flags> are passed to
 C<gv_fetchpvn_flags>.  If C<GV_ADD> is set and the Perl subroutine does not
 exist then it will be declared (which has the same effect as saying
-C<sub name;>).  If C<GV_ADD> is not set and the subroutine does not exist
+C<sub name;>).  If C<GV_ADD> is not set and the subroutine does not exist,
 then NULL is returned.
 
-=for apidoc get_cv
+The forms differ only in how the subroutine is specified..  With C<get_cvs>,
+the name is a literal C string, enclosed in double quotes.  With C<get_cv>, the
+name is given by the C<name> parameter, which must be a NUL-terminated C
+string.  With C<get_cvn_flags>, the name is also given by the C<name>
+parameter, but it is a Perl string (possibly containing embedded NUL bytes),
+and its length in bytes is contained in the C<len> parameter.
 
-Uses C<strlen> to get the length of C<name>, then calls C<get_cvn_flags>.
+=for apidoc Amnh||GV_ADD
 
 =cut
 */
@@ -3308,34 +3315,34 @@ S_usage(pTHX)           /* XXX move this out into a module ? */
     /* Grouped as 6 lines per C string literal, to keep under the ANSI C 89
        minimum of 509 character string literals.  */
     static const char * const usage_msg[] = {
-"  -0[octal]         specify record separator (\\0, if no argument)\n"
-"  -a                autosplit mode with -n or -p (splits $_ into @F)\n"
-"  -C[number/list]   enables the listed Unicode features\n"
-"  -c                check syntax only (runs BEGIN and CHECK blocks)\n"
-"  -d[:debugger]     run program under debugger\n"
-"  -D[number/list]   set debugging flags (argument is a bit mask or alphabets)\n",
-"  -e program        one line of program (several -e's allowed, omit programfile)\n"
-"  -E program        like -e, but enables all optional features\n"
-"  -f                don't do $sitelib/sitecustomize.pl at startup\n"
-"  -F/pattern/       split() pattern for -a switch (//'s are optional)\n"
-"  -i[extension]     edit <> files in place (makes backup if extension supplied)\n"
-"  -Idirectory       specify @INC/#include directory (several -I's allowed)\n",
-"  -l[octal]         enable line ending processing, specifies line terminator\n"
-"  -[mM][-]module    execute \"use/no module...\" before executing program\n"
-"  -n                assume \"while (<>) { ... }\" loop around program\n"
-"  -p                assume loop like -n but print line also, like sed\n"
-"  -s                enable rudimentary parsing for switches after programfile\n"
-"  -S                look for programfile using PATH environment variable\n",
-"  -t                enable tainting warnings\n"
-"  -T                enable tainting checks\n"
-"  -u                dump core after parsing program\n"
-"  -U                allow unsafe operations\n"
-"  -v                print version, patchlevel and license\n"
-"  -V[:variable]     print configuration summary (or a single Config.pm variable)\n",
-"  -w                enable many useful warnings\n"
-"  -W                enable all warnings\n"
-"  -x[directory]     ignore text before #!perl line (optionally cd to directory)\n"
-"  -X                disable all warnings\n"
+"  -0[octal/hexadecimal] specify record separator (\\0, if no argument)\n"
+"  -a                    autosplit mode with -n or -p (splits $_ into @F)\n"
+"  -C[number/list]       enables the listed Unicode features\n"
+"  -c                    check syntax only (runs BEGIN and CHECK blocks)\n"
+"  -d[t][:MOD]           run program under debugger or module Devel::MOD\n"
+"  -D[number/letters]    set debugging flags (argument is a bit mask or alphabets)\n",
+"  -e commandline        one line of program (several -e's allowed, omit programfile)\n"
+"  -E commandline        like -e, but enables all optional features\n"
+"  -f                    don't do $sitelib/sitecustomize.pl at startup\n"
+"  -F/pattern/           split() pattern for -a switch (//'s are optional)\n"
+"  -i[extension]         edit <> files in place (makes backup if extension supplied)\n"
+"  -Idirectory           specify @INC/#include directory (several -I's allowed)\n",
+"  -l[octnum]            enable line ending processing, specifies line terminator\n"
+"  -[mM][-]module        execute \"use/no module...\" before executing program\n"
+"  -n                    assume \"while (<>) { ... }\" loop around program\n"
+"  -p                    assume loop like -n but print line also, like sed\n"
+"  -s                    enable rudimentary parsing for switches after programfile\n"
+"  -S                    look for programfile using PATH environment variable\n",
+"  -t                    enable tainting warnings\n"
+"  -T                    enable tainting checks\n"
+"  -u                    dump core after parsing program\n"
+"  -U                    allow unsafe operations\n"
+"  -v                    print version, patchlevel and license\n"
+"  -V[:configvar]        print configuration summary (or a single Config.pm variable)\n",
+"  -w                    enable many useful warnings\n"
+"  -W                    enable all warnings\n"
+"  -x[directory]         ignore text before #!perl line (optionally cd to directory)\n"
+"  -X                    disable all warnings\n"
 "  \n"
 "Run 'perldoc perl' for more help with Perl.\n\n",
 NULL
@@ -4536,8 +4543,6 @@ Perl_init_argv_symbols(pTHX_ int argc, char **argv)
 STATIC void
 S_init_postdump_symbols(pTHX_ int argc, char **argv, char **env)
 {
-#ifdef USE_ITHREADS
-#endif
     GV* tmpgv;
 
     PERL_ARGS_ASSERT_INIT_POSTDUMP_SYMBOLS;
diff --git a/perl.h b/perl.h
index e8ecb1b..cbb6905 100644 (file)
--- a/perl.h
+++ b/perl.h
 /* this is used for functions which take a depth trailing
  * argument under debugging */
 #ifdef DEBUGGING
-#define _pDEPTH ,U32 depth
-#define _aDEPTH ,depth
+#  define _pDEPTH ,U32 depth
+#  define _aDEPTH ,depth
 #else
-#define _pDEPTH
-#define _aDEPTH
+#  define _pDEPTH
+#  define _aDEPTH
 #endif
 
 /* NOTE 1: that with gcc -std=c89 the __STDC_VERSION__ is *not* defined
@@ -135,6 +135,17 @@ Otherwise ends a section of code already begun by a C<L</START_EXTERN_C>>.
 #  endif
 #endif
 
+/*
+=for apidoc_section $concurrency
+=for apidoc AmU|void|dTHXa|PerlInterpreter * a
+On threaded perls, set C<pTHX> to C<a>; on unthreaded perls, do nothing
+
+=for apidoc AmU|void|dTHXoa|PerlInterpreter * a
+Now a synonym for C<L</dTHXa>>.
+
+=cut
+*/
+
 #ifdef PERL_IMPLICIT_CONTEXT
 #  ifndef MULTIPLICITY
 #    define MULTIPLICITY
@@ -186,15 +197,15 @@ Now a no-op.
 
 =cut
  */
-#define CPERLscope(x) x
-#define CPERLarg void
-#define CPERLarg_
-#define _CPERLarg
-#define PERL_OBJECT_THIS
-#define _PERL_OBJECT_THIS
-#define PERL_OBJECT_THIS_
-#define CALL_FPTR(fptr) (*fptr)
-#define MEMBER_TO_FPTR(name) name
+#  define CPERLscope(x) x
+#  define CPERLarg void
+#  define CPERLarg_
+#  define _CPERLarg
+#  define PERL_OBJECT_THIS
+#  define _PERL_OBJECT_THIS
+#  define PERL_OBJECT_THIS_
+#  define CALL_FPTR(fptr) (*fptr)
+#  define MEMBER_TO_FPTR(name) name
 #endif /* !PERL_CORE */
 
 #define CALLRUNOPS  PL_runops
@@ -260,10 +271,10 @@ Now a no-op.
     RX_ENGINE(rx)->qr_package(aTHX_ (rx))
 
 #if defined(USE_ITHREADS)
-#define CALLREGDUPE(prog,param) \
+#  define CALLREGDUPE(prog,param) \
     Perl_re_dup(aTHX_ (prog),(param))
 
-#define CALLREGDUPE_PVT(prog,param) \
+#  define CALLREGDUPE_PVT(prog,param) \
     (prog ? RX_ENGINE(prog)->dupe(aTHX_ (prog),(param)) \
           : (REGEXP *)NULL)
 #endif
@@ -288,42 +299,42 @@ Now a no-op.
  */
 
 #ifndef PERL_MICRO
-#if defined __GNUC__ && !defined(__INTEL_COMPILER)
-#  if __GNUC__ == 3 && __GNUC_MINOR__ >= 1 || __GNUC__ > 3 /* 3.1 -> */
-#    define HASATTRIBUTE_DEPRECATED
-#  endif
-#  if __GNUC__ >= 3 /* 3.0 -> */ /* XXX Verify this version */
-#    define HASATTRIBUTE_FORMAT
-#    if defined __MINGW32__
-#      define PRINTF_FORMAT_NULL_OK
+#  if defined __GNUC__ && !defined(__INTEL_COMPILER)
+#    if __GNUC__ == 3 && __GNUC_MINOR__ >= 1 || __GNUC__ > 3 /* 3.1 -> */
+#      define HASATTRIBUTE_DEPRECATED
+#    endif
+#    if __GNUC__ >= 3 /* 3.0 -> */ /* XXX Verify this version */
+#      define HASATTRIBUTE_FORMAT
+#      if defined __MINGW32__
+#        define PRINTF_FORMAT_NULL_OK
+#      endif
+#    endif
+#    if __GNUC__ >= 3 /* 3.0 -> */
+#      define HASATTRIBUTE_MALLOC
+#    endif
+#    if __GNUC__ == 3 && __GNUC_MINOR__ >= 3 || __GNUC__ > 3 /* 3.3 -> */
+#      define HASATTRIBUTE_NONNULL
+#    endif
+#    if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 || __GNUC__ > 2 /* 2.5 -> */
+#      define HASATTRIBUTE_NORETURN
+#    endif
+#    if __GNUC__ >= 3 /* gcc 3.0 -> */
+#      define HASATTRIBUTE_PURE
+#    endif
+#    if __GNUC__ == 3 && __GNUC_MINOR__ >= 4 || __GNUC__ > 3 /* 3.4 -> */
+#      define HASATTRIBUTE_UNUSED
+#    endif
+#    if __GNUC__ == 3 && __GNUC_MINOR__ == 3 && !defined(__cplusplus)
+#      define HASATTRIBUTE_UNUSED /* gcc-3.3, but not g++-3.3. */
+#    endif
+#    if __GNUC__ == 3 && __GNUC_MINOR__ >= 4 || __GNUC__ > 3 /* 3.4 -> */
+#      define HASATTRIBUTE_WARN_UNUSED_RESULT
+#    endif
+     /* always_inline is buggy in gcc <= 4.6 and causes compilation errors */
+#    if __GNUC__ == 4 && __GNUC_MINOR__ >= 7 || __GNUC__ > 4 /* 4.7 -> */
+#      define HASATTRIBUTE_ALWAYS_INLINE
 #    endif
 #  endif
-#  if __GNUC__ >= 3 /* 3.0 -> */
-#    define HASATTRIBUTE_MALLOC
-#  endif
-#  if __GNUC__ == 3 && __GNUC_MINOR__ >= 3 || __GNUC__ > 3 /* 3.3 -> */
-#    define HASATTRIBUTE_NONNULL
-#  endif
-#  if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 || __GNUC__ > 2 /* 2.5 -> */
-#    define HASATTRIBUTE_NORETURN
-#  endif
-#  if __GNUC__ >= 3 /* gcc 3.0 -> */
-#    define HASATTRIBUTE_PURE
-#  endif
-#  if __GNUC__ == 3 && __GNUC_MINOR__ >= 4 || __GNUC__ > 3 /* 3.4 -> */
-#    define HASATTRIBUTE_UNUSED
-#  endif
-#  if __GNUC__ == 3 && __GNUC_MINOR__ == 3 && !defined(__cplusplus)
-#    define HASATTRIBUTE_UNUSED /* gcc-3.3, but not g++-3.3. */
-#  endif
-#  if __GNUC__ == 3 && __GNUC_MINOR__ >= 4 || __GNUC__ > 3 /* 3.4 -> */
-#    define HASATTRIBUTE_WARN_UNUSED_RESULT
-#  endif
-/* always_inline is buggy in gcc <= 4.6 and causes compilation errors */
-#  if __GNUC__ == 4 && __GNUC_MINOR__ >= 7 || __GNUC__ > 4 /* 4.7 -> */
-#    define HASATTRIBUTE_ALWAYS_INLINE
-#  endif
-#endif
 #endif /* #ifndef PERL_MICRO */
 
 #ifdef HASATTRIBUTE_DEPRECATED
@@ -518,9 +529,9 @@ __typeof__ and nothing else.
 #  endif
 #endif
 
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) && _MSC_VER < 1400
 /* XXX older MSVC versions have a smallish macro buffer */
-#define PERL_SMALL_MACRO_BUFFER
+#  define PERL_SMALL_MACRO_BUFFER
 #endif
 
 /* on gcc (and clang), specify that a warning should be temporarily
@@ -632,6 +643,10 @@ code.
 =for apidoc AmnU||dVAR
 This is now a synonym for dNOOP: declare nothing
 
+=for apidoc_section $XS
+=for apidoc Amns||dMY_CXT_SV
+Now a placeholder that declares nothing
+
 =cut
 */
 
@@ -642,6 +657,7 @@ This is now a synonym for dNOOP: declare nothing
 
     /* these are only defined for compatibility; should not be used internally.
      * */
+#  define dMY_CXT_SV    dNOOP
 #  ifndef pTHXo
 #    define pTHXo              pTHX
 #    define pTHXo_     pTHX_
@@ -2112,6 +2128,14 @@ typedef UVTYPE UV;
 #  define PTR2ul(p)    INT2PTR(unsigned long,p)        
 #endif
 
+/*
+=for apidoc_section Casting
+=for apidoc Cyh|type|NUM2PTR|type|int value
+You probably want to be using L<C</INT2PTR>> instead.
+
+=cut
+*/
+
 #define NUM2PTR(any,d) (any)(PTRV)(d)
 #define PTR2IV(p)      INT2PTR(IV,p)
 #define PTR2UV(p)      INT2PTR(UV,p)
@@ -3052,37 +3076,6 @@ typedef struct padname PADNAME;
 #  define USE_ENVIRON_ARRAY
 #endif
 
-#ifdef USE_ITHREADS
-   /* On some platforms it would be safe to use a read/write mutex with many
-    * readers possible at the same time.  On other platforms, notably IBM ones,
-    * subsequent getenv calls destroy earlier ones.  Those platforms would not
-    * be able to handle simultaneous getenv calls */
-#  define ENV_LOCK            MUTEX_LOCK(&PL_env_mutex)
-#  define ENV_UNLOCK          MUTEX_UNLOCK(&PL_env_mutex)
-#  define ENV_INIT            MUTEX_INIT(&PL_env_mutex);
-#  define ENV_TERM            MUTEX_DESTROY(&PL_env_mutex);
-#else
-#  define ENV_LOCK       NOOP;
-#  define ENV_UNLOCK     NOOP;
-#  define ENV_INIT       NOOP;
-#  define ENV_TERM       NOOP;
-#endif
-
-/* Some critical sections need to lock both the locale and the environment.
- * XXX khw intends to change this to lock both mutexes, but that brings up
- * issues of potential deadlock, so should be done at the beginning of a
- * development cycle.  So for now, it just locks the environment.  Note that
- * many modern platforms are locale-thread-safe anyway, so locking the locale
- * mutex is a no-op anyway */
-#define ENV_LOCALE_LOCK     ENV_LOCK
-#define ENV_LOCALE_UNLOCK   ENV_UNLOCK
-
-/* And some critical sections care only that no one else is writing either the
- * locale nor the environment.  XXX Again this is for the future.  This can be
- * simulated with using COND_WAIT in thread.h */
-#define ENV_LOCALE_READ_LOCK     ENV_LOCALE_LOCK
-#define ENV_LOCALE_READ_UNLOCK   ENV_LOCALE_UNLOCK
-
 #if defined(HAS_SIGACTION) && defined(SA_SIGINFO)
     /* having sigaction(2) means that the OS supports both 1-arg and 3-arg
      * signal handlers. But the perl core itself only fully supports 1-arg
@@ -3347,6 +3340,15 @@ typedef pthread_mutex_t PERL_TSA_CAPABILITY("mutex") perl_mutex;
 typedef pthread_cond_t perl_cond;
 typedef pthread_key_t  perl_key;
 #  endif
+
+/* Many readers; single writer */
+typedef struct {
+    perl_mutex lock;
+    perl_cond  wakeup;
+    Size_t     readers_count;
+} perl_RnW1_mutex_t;
+
+
 #endif /* USE_ITHREADS */
 
 #ifdef PERL_TSA_ACTIVE
@@ -3751,7 +3753,13 @@ EXTERN_C int perl_tsa_mutex_unlock(perl_mutex* mutex)
 #define PNfARG(pn) (int)1, (UV)PadnameLEN(pn), (void *)PadnamePV(pn)
 
 #ifdef PERL_CORE
-/* not used; but needed for backward compatibility with XS code? - RMB */
+/* not used; but needed for backward compatibility with XS code? - RMB
+=for apidoc AmnD|const char *|UVf
+
+Obsolete form of C<UVuf>, which you should convert to instead use
+
+=cut
+*/
 #  undef UVf
 #elif !defined(UVf)
 #  define UVf UVuf
@@ -6230,22 +6238,6 @@ EXTCONST U8 PL_c9_utf8_dfa_tab[];
 #  endif
 #endif    /* end of isn't EBCDIC */
 
-#ifndef PERL_NO_INLINE_FUNCTIONS
-/* Static inline funcs that depend on includes and declarations above.
-   Some of these reference functions in the perl object files, and some
-   compilers aren't smart enough to eliminate unused static inline
-   functions, so including this file in source code can cause link errors
-   even if the source code uses none of the functions. Hence including these
-   can be suppressed by setting PERL_NO_INLINE_FUNCTIONS. Doing this will
-   (obviously) result in unworkable XS code, but allows simple probing code
-   to continue to work, because it permits tests to include the perl headers
-   for definitions without creating a link dependency on the perl library
-   (which may not exist yet).
-*/
-
-#  include "inline.h"
-#endif
-
 #include "overload.h"
 
 END_EXTERN_C
@@ -6491,89 +6483,135 @@ the plain locale pragma without a parameter (S<C<use locale>>) is in effect.
 #endif
 
 
-/* Locale/thread synchronization macros.  These aren't needed if using
- * thread-safe locale operations, except if something is broken */
-#if    defined(USE_LOCALE)                                                  \
- &&    defined(USE_ITHREADS)                                                \
- && (! defined(USE_THREAD_SAFE_LOCALE) || defined(TS_W32_BROKEN_LOCALECONV))
+/* Locale/thread synchronization macros. */
+#if ! (   defined(USE_LOCALE)                                               \
+       &&    defined(USE_ITHREADS)                                          \
+       && (  ! defined(USE_THREAD_SAFE_LOCALE)                              \
+           || (   defined(HAS_LOCALECONV)                                   \
+               && (  ! defined(HAS_LOCALECONV_L)                            \
+                   ||  defined(TS_W32_BROKEN_LOCALECONV)))                  \
+           || (   defined(HAS_NL_LANGINFO)                                  \
+               && ! defined(HAS_THREAD_SAFE_NL_LANGINFO_L))                 \
+           || (defined(HAS_MBLEN)  && ! defined(HAS_MBRLEN))                \
+           || (defined(HAS_MBTOWC) && ! defined(HAS_MBRTOWC))               \
+           || (defined(HAS_WCTOMB) && ! defined(HAS_WCRTOMB))))
 
-/* We have a locale object holding the 'C' locale for Posix 2008 */
-#  ifndef USE_POSIX_2008_LOCALE
-#    define _LOCALE_TERM_POSIX_2008  NOOP
-#  else
-#    define _LOCALE_TERM_POSIX_2008                                         \
-                    STMT_START {                                            \
-                        if (PL_C_locale_obj) {                              \
-                            /* Make sure we aren't using the locale         \
-                             * space we are about to free */                \
-                            uselocale(LC_GLOBAL_LOCALE);                    \
-                            freelocale(PL_C_locale_obj);                    \
-                            PL_C_locale_obj = (locale_t) NULL;              \
-                        }                                                   \
-                    } STMT_END
-#  endif
+/* The whole expression just above was complemented, so here we have no need
+ * for thread synchronization, most likely it would be that this isn't a
+ * threaded build. */
+#  define LOCALE_INIT
+#  define LOCALE_TERM
+#  define LC_NUMERIC_LOCK(cond)     NOOP
+#  define LC_NUMERIC_UNLOCK         NOOP
+#  define LOCALECONV_LOCK           NOOP
+#  define LOCALECONV_UNLOCK         NOOP
+#  define LOCALE_READ_LOCK          NOOP
+#  define LOCALE_READ_UNLOCK        NOOP
+#  define MBLEN_LOCK                NOOP
+#  define MBLEN_UNLOCK              NOOP
+#  define MBTOWC_LOCK               NOOP
+#  define MBTOWC_UNLOCK             NOOP
+#  define NL_LANGINFO_LOCK          NOOP
+#  define NL_LANGINFO_UNLOCK        NOOP
+#  define SETLOCALE_LOCK            NOOP
+#  define SETLOCALE_UNLOCK          NOOP
+#  define WCTOMB_LOCK               NOOP
+#  define WCTOMB_UNLOCK             NOOP
+#else
 
-/* This is used as a generic lock for locale operations.  For example this is
- * used when calling nl_langinfo() so that another thread won't zap the
- * contents of its buffer before it gets saved; and it's called when changing
- * the locale of LC_MESSAGES.  On some systems the latter can cause the
- * nl_langinfo buffer to be zapped under a race condition.
- *
- * If combined with LC_NUMERIC_LOCK, calls to this and its corresponding unlock
- * should be contained entirely within the locked portion of LC_NUMERIC.  This
- * mutex should be used only in very short sections of code, while
- * LC_NUMERIC_LOCK may span more operations.  By always following this
- * convention, deadlock should be impossible.  But if necessary, the two
- * mutexes could be combined.
- *
- * Actually, the two macros just below with the '_V' suffixes are used in just
- * a few places where there is a broken localeconv(), but otherwise things are
- * thread safe, and hence don't need locking.  Just below LOCALE_LOCK and
- * LOCALE_UNLOCK are defined in terms of these for use everywhere else */
-#  define LOCALE_LOCK_V                                                     \
+   /* Here, we will need critical sections in locale handling, because one or
+    * more of the above conditions are true.  This could be because the
+    * platform doesn't have thread-safe locales, or that at least one of the
+    * locale-dependent functions in the core isn't thread-safe.  The latter
+    * case is generally because they return a pointer to a static buffer, which
+    * may be per-process instead of per-thread.  There are supposedly
+    * re-entrant, safe versions for all of them Perl currently uses (which the
+    * #if above checks for), but most platforms don't have all the needed ones
+    * available, and the Posix standard doesn't require nl_langinfo_l() to be
+    * fully thread-safe, so a Configure probe was written.  localeconv_l() is
+    * uncommon, and judging by bug reports on the web, some earlier library
+    * localeconv_l versions were broken, so perhaps a probe is in order for
+    * that, but it would be a pain to write.
+    *
+    * On non-thread-safe systems, some of the above functions are vulnerable to
+    * races should another thread get control and change the locale in the
+    * middle of their execution.
+    *
+    * We currently use a single mutex for all these cases.  This solves both
+    * the problem of another thread changing the locale, and the buffer being
+    * overwritten (the code copies the results to a safe place before releasing
+    * the mutex).  Ideally, for locale thread-safe platforms where the only
+    * issue is another thread clobbering the function's static buffer, there
+    * would be a separate mutex for each such buffer.  Otherwise, things get
+    * locked that don't need to.  But, it is not expected that any of these
+    * will be called frequently, and the locked interval should be short, and
+    * modern platforms will have reentrant versions (which don't lock) for
+    * almost all of them, so khw thinks a single mutex should suffice. */
+#  define LOCALE_LOCK_                                                      \
         STMT_START {                                                        \
             DEBUG_Lv(PerlIO_printf(Perl_debug_log,                          \
                     "%s: %d: locking locale\n", __FILE__, __LINE__));       \
             MUTEX_LOCK(&PL_locale_mutex);                                   \
         } STMT_END
-#  define LOCALE_UNLOCK_V                                                   \
+#  define LOCALE_UNLOCK_                                                    \
         STMT_START {                                                        \
             DEBUG_Lv(PerlIO_printf(Perl_debug_log,                          \
                    "%s: %d: unlocking locale\n", __FILE__, __LINE__));      \
             MUTEX_UNLOCK(&PL_locale_mutex);                                 \
         } STMT_END
 
-/* On windows, we just need the mutex for LOCALE_LOCK */
-#  ifdef TS_W32_BROKEN_LOCALECONV
-#    define LOCALE_LOCK     NOOP
-#    define LOCALE_UNLOCK   NOOP
-#    define LOCALE_INIT     MUTEX_INIT(&PL_locale_mutex);
-#    define LOCALE_TERM     MUTEX_DESTROY(&PL_locale_mutex)
-#    define LC_NUMERIC_LOCK(cond)
-#    define LC_NUMERIC_UNLOCK
+   /* We do define a different macro for each case; then if we want to have
+    * separate mutexes for some of them, the only changes needed are here.
+    * Define just the necessary macros.  The compiler should then croak if the
+    * #ifdef's in the code are incorrect */
+#  if defined(HAS_LOCALECONV) && (  ! defined(HAS_POSIX_2008_LOCALE)        \
+                                 || ! defined(HAS_LOCALECONV_L)             \
+                                 ||   defined(TS_W32_BROKEN_LOCALECONV))
+#    define LOCALECONV_LOCK   LOCALE_LOCK_
+#    define LOCALECONV_UNLOCK LOCALE_UNLOCK_
+#  endif
+#  if defined(HAS_NL_LANGINFO) && (   ! defined(HAS_THREAD_SAFE_NL_LANGINFO_L) \
+                                   || ! defined(HAS_POSIX_2008_LOCALE))
+#    define NL_LANGINFO_LOCK   LOCALE_LOCK_
+#    define NL_LANGINFO_UNLOCK LOCALE_UNLOCK_
+#  endif
+#  if defined(HAS_MBLEN) && ! defined(HAS_MBRLEN)
+#    define MBLEN_LOCK   LOCALE_LOCK_
+#    define MBLEN_UNLOCK LOCALE_UNLOCK_
+#  endif
+#  if defined(HAS_MBTOWC) && ! defined(HAS_MBRTOWC)
+#    define MBTOWC_LOCK   LOCALE_LOCK_
+#    define MBTOWC_UNLOCK LOCALE_UNLOCK_
+#  endif
+#  if defined(HAS_WCTOMB) && ! defined(HAS_WCRTOMB)
+#    define WCTOMB_LOCK   LOCALE_LOCK_
+#    define WCTOMB_UNLOCK LOCALE_UNLOCK_
+#  endif
+#  if defined(USE_THREAD_SAFE_LOCALE)
+     /* On locale thread-safe systems, we don't need these workarounds */
+#    define LOCALE_TERM_LC_NUMERIC_   NOOP
+#    define LOCALE_INIT_LC_NUMERIC_   NOOP
+#    define LC_NUMERIC_LOCK(cond)   NOOP
+#    define LC_NUMERIC_UNLOCK       NOOP
+#    define LOCALE_INIT_LC_NUMERIC_ NOOP
+#    define LOCALE_TERM_LC_NUMERIC_ NOOP
+
+     /* There may be instance core where we this is invoked yet should do
+      * nothing.  Rather than have #ifdef's around them, define it here */
+#    define SETLOCALE_LOCK    NOOP
+#    define SETLOCALE_UNLOCK  NOOP
 #  else
-#    define LOCALE_LOCK     LOCALE_LOCK_V
-#    define LOCALE_UNLOCK   LOCALE_UNLOCK_V
-
-     /* We also need to lock LC_NUMERIC for non-windows (hence Posix 2008)
-      * systems */
-#    define LOCALE_INIT          STMT_START {                               \
-                                    MUTEX_INIT(&PL_locale_mutex);           \
-                                    MUTEX_INIT(&PL_lc_numeric_mutex);       \
-                                } STMT_END
-
-#    define LOCALE_TERM         STMT_START {                                \
-                                    MUTEX_DESTROY(&PL_locale_mutex);        \
-                                    MUTEX_DESTROY(&PL_lc_numeric_mutex);    \
-                                    _LOCALE_TERM_POSIX_2008;                \
-                                } STMT_END
-
-    /* This mutex is used to create critical sections where we want the
-     * LC_NUMERIC locale to be locked into either the C (standard) locale, or
-     * the underlying locale, so that other threads interrupting this one don't
-     * change it to the wrong state before we've had a chance to complete our
-     * operation.  It can stay locked over an entire printf operation, for
-     * example.  And so is made distinct from the LOCALE_LOCK mutex.
+#    define SETLOCALE_LOCK   LOCALE_LOCK_
+#    define SETLOCALE_UNLOCK LOCALE_UNLOCK_
+
+    /* On platforms without per-thread locales, when another thread can switch
+     * our locale, we need another mutex to create critical sections where we
+     * want the LC_NUMERIC locale to be locked into either the C (standard)
+     * locale, or the underlying locale, so that other threads interrupting
+     * this one don't change it to the wrong state before we've had a chance to
+     * complete our operation.  It can stay locked over an entire printf
+     * operation, for example.  And so is made distinct from the LOCALE_LOCK
+     * mutex.
      *
      * This simulates kind of a general semaphore.  The current thread will
      * lock the mutex if the per-thread variable is zero, and then increments
@@ -6587,7 +6625,13 @@ the plain locale pragma without a parameter (S<C<use locale>>) is in effect.
      *
      * Clang improperly gives warnings for this, if not silenced:
      * https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#conditional-locks
-     * */
+     *
+     * If LC_NUMERIC_LOCK is combined with one of the LOCKs above, calls to
+     * that and its corresponding unlock should be contained entirely within
+     * the locked portion of LC_NUMERIC.  Those mutexes should be used only in
+     * very short sections of code, while LC_NUMERIC_LOCK may span more
+     * operations.  By always following this convention, deadlock should be
+     * impossible.  But if necessary, the two mutexes could be combined. */
 #    define LC_NUMERIC_LOCK(cond_to_panic_if_already_locked)                \
         CLANG_DIAG_IGNORE(-Wthread-safety)                                 \
         STMT_START {                                                        \
@@ -6629,16 +6673,36 @@ the plain locale pragma without a parameter (S<C<use locale>>) is in effect.
         } STMT_END                                                          \
         CLANG_DIAG_RESTORE
 
-#  endif    /* End of needs locking LC_NUMERIC */
-#else   /* Below is no locale sync needed */
-#  define LOCALE_INIT
-#  define LOCALE_LOCK
-#  define LOCALE_LOCK_V
-#  define LOCALE_UNLOCK
-#  define LOCALE_UNLOCK_V
-#  define LC_NUMERIC_LOCK(cond)
-#  define LC_NUMERIC_UNLOCK
-#  define LOCALE_TERM
+#    define LOCALE_INIT_LC_NUMERIC_   MUTEX_INIT(&PL_lc_numeric_mutex)
+#    define LOCALE_TERM_LC_NUMERIC_   MUTEX_DESTROY(&PL_lc_numeric_mutex)
+#  endif
+
+#  ifdef USE_POSIX_2008_LOCALE
+     /* We have a locale object holding the 'C' locale for Posix 2008 */
+#    define LOCALE_TERM_POSIX_2008_                                         \
+                    STMT_START {                                            \
+                        if (PL_C_locale_obj) {                              \
+                            /* Make sure we aren't using the locale         \
+                             * space we are about to free */                \
+                            uselocale(LC_GLOBAL_LOCALE);                    \
+                            freelocale(PL_C_locale_obj);                    \
+                            PL_C_locale_obj = (locale_t) NULL;              \
+                        }                                                   \
+                    } STMT_END
+#  else
+#    define LOCALE_TERM_POSIX_2008_  NOOP
+#  endif
+
+#  define LOCALE_INIT           STMT_START {                                \
+                                    MUTEX_INIT(&PL_locale_mutex);           \
+                                    LOCALE_INIT_LC_NUMERIC_;                \
+                                } STMT_END
+
+#  define LOCALE_TERM           STMT_START {                                \
+                                    MUTEX_DESTROY(&PL_locale_mutex);        \
+                                    LOCALE_TERM_LC_NUMERIC_;                \
+                                    LOCALE_TERM_POSIX_2008_;                \
+                                } STMT_END
 #endif
 
 #ifdef USE_LOCALE_NUMERIC
@@ -6938,6 +7002,75 @@ cannot have changed since the precalculation.
 
 #endif /* !USE_LOCALE_NUMERIC */
 
+#ifdef USE_ITHREADS
+#  define ENV_LOCK            PERL_WRITE_LOCK(&PL_env_mutex)
+#  define ENV_UNLOCK          PERL_WRITE_UNLOCK(&PL_env_mutex)
+#  define ENV_READ_LOCK       PERL_READ_LOCK(&PL_env_mutex)
+#  define ENV_READ_UNLOCK     PERL_READ_UNLOCK(&PL_env_mutex)
+#  define ENV_INIT            PERL_RW_MUTEX_INIT(&PL_env_mutex)
+#  define ENV_TERM            PERL_RW_MUTEX_DESTROY(&PL_env_mutex)
+
+   /* On platforms where the static buffer contained in getenv() is per-thread
+    * rather than process-wide, another thread executing a getenv() at the same
+    * time won't destroy ours before we have copied the result safely away and
+    * unlocked the mutex.  On such platforms (which is most), we can have many
+    * readers of the environment at the same time. */
+#  ifdef GETENV_PRESERVES_OTHER_THREAD
+#    define GETENV_LOCK    ENV_READ_LOCK
+#    define GETENV_UNLOCK  ENV_READ_UNLOCK
+#  else
+     /* If, on the other hand, another thread could zap our getenv() return, we
+      * need to keep them from executing until we are done */
+#    define GETENV_LOCK    ENV_LOCK
+#    define GETENV_UNLOCK  ENV_UNLOCK
+#  endif
+#else
+#  define ENV_LOCK        NOOP
+#  define ENV_UNLOCK      NOOP
+#  define ENV_READ_LOCK   NOOP
+#  define ENV_READ_UNLOCK NOOP
+#  define ENV_INIT        NOOP
+#  define ENV_TERM        NOOP
+#  define GETENV_LOCK     NOOP
+#  define GETENV_UNLOCK   NOOP
+#endif
+
+#ifndef PERL_NO_INLINE_FUNCTIONS
+/* Static inline funcs that depend on includes and declarations above.
+   Some of these reference functions in the perl object files, and some
+   compilers aren't smart enough to eliminate unused static inline
+   functions, so including this file in source code can cause link errors
+   even if the source code uses none of the functions. Hence including these
+   can be suppressed by setting PERL_NO_INLINE_FUNCTIONS. Doing this will
+   (obviously) result in unworkable XS code, but allows simple probing code
+   to continue to work, because it permits tests to include the perl headers
+   for definitions without creating a link dependency on the perl library
+   (which may not exist yet).
+*/
+
+START_EXTERN_C
+
+#  include "inline.h"
+
+END_EXTERN_C
+
+#endif
+
+/* Some critical sections need to lock both the locale and the environment.
+ * XXX khw intends to change this to lock both mutexes, but that brings up
+ * issues of potential deadlock, so should be done at the beginning of a
+ * development cycle.  So for now, it just locks the environment.  Note that
+ * many modern platforms are locale-thread-safe anyway, so locking the locale
+ * mutex is a no-op anyway */
+#define ENV_LOCALE_LOCK     ENV_LOCK
+#define ENV_LOCALE_UNLOCK   ENV_UNLOCK
+
+/* And some critical sections care only that no one else is writing either the
+ * locale nor the environment.  XXX Again this is for the future.  This can be
+ * simulated with using COND_WAIT in thread.h */
+#define ENV_LOCALE_READ_LOCK     ENV_LOCALE_LOCK
+#define ENV_LOCALE_READ_UNLOCK   ENV_LOCALE_UNLOCK
+
 #define Atof                           my_atof
 
 /*
@@ -7180,9 +7313,7 @@ C<strtoul>.
 #  define _aMY_CXT     ,aMY_CXT
 
 #else /* PERL_IMPLICIT_CONTEXT */
-
 #  define START_MY_CXT         static my_cxt_t my_cxt;
-#  define dMY_CXT_SV           dNOOP
 #  define dMY_CXT              dNOOP
 #  define dMY_CXT_INTERP(my_perl) dNOOP
 #  define MY_CXT_INIT          NOOP
index 760cb5c..3bfd46f 100644 (file)
@@ -104,10 +104,8 @@ PERLVARI(G, mmap_page_size, IV, 0)
 
 #if defined(USE_ITHREADS)
 PERLVAR(G, hints_mutex, perl_mutex)    /* Mutex for refcounted he refcounting */
-PERLVAR(G, env_mutex, perl_mutex)      /* Mutex for accessing ENV */
-#  if ! defined(USE_THREAD_SAFE_LOCALE) || defined(TS_W32_BROKEN_LOCALECONV)
-PERLVAR(G, locale_mutex, perl_mutex)   /* Mutex for setlocale() changing */
-#  endif
+PERLVAR(G, env_mutex, perl_RnW1_mutex_t)      /* Mutex for accessing ENV */
+PERLVAR(G, locale_mutex, perl_mutex)   /* Mutex related to locale handling */
 #  ifndef USE_THREAD_SAFE_LOCALE
 PERLVAR(G, lc_numeric_mutex, perl_mutex)   /* Mutex for switching LC_NUMERIC */
 #  endif
@@ -307,6 +305,3 @@ PERLVARI(G, strategy_socket,     int, 0)    /* doio.c */
 PERLVARI(G, strategy_accept,     int, 0)       /* doio.c */
 PERLVARI(G, strategy_pipe,       int, 0)       /* doio.c */
 PERLVARI(G, strategy_socketpair, int, 0)       /* doio.c */
-
-#ifdef PERL_IMPLICIT_CONTEXT
-#endif
index bc684e7..1004d34 100644 (file)
--- a/perly.act
+++ b/perly.act
@@ -5,8 +5,8 @@
  */
 
 case 2:
-#line 121 "perly.y"
-    {
+#line 122 "perly.y"
+                        {
                          parser->expect = XSTATE;
                           (yyval.ival) = 0;
                        }
@@ -14,8 +14,8 @@ case 2:
     break;
 
   case 3:
-#line 126 "perly.y"
-    {
+#line 127 "perly.y"
+                        {
                          newPROG(block_end((ps[-1].val.ival),(ps[0].val.opval)));
                          PL_compiling.cop_seq = 0;
                          (yyval.ival) = 0;
@@ -24,8 +24,8 @@ case 2:
     break;
 
   case 4:
-#line 132 "perly.y"
-    {
+#line 133 "perly.y"
+                        {
                          parser->expect = XTERM;
                           (yyval.ival) = 0;
                        }
@@ -33,8 +33,8 @@ case 2:
     break;
 
   case 5:
-#line 137 "perly.y"
-    {
+#line 138 "perly.y"
+                        {
                          PL_eval_root = (ps[0].val.opval);
                          (yyval.ival) = 0;
                        }
@@ -42,8 +42,8 @@ case 2:
     break;
 
   case 6:
-#line 142 "perly.y"
-    {
+#line 143 "perly.y"
+                        {
                          parser->expect = XBLOCK;
                           (yyval.ival) = 0;
                        }
@@ -51,8 +51,8 @@ case 2:
     break;
 
   case 7:
-#line 147 "perly.y"
-    {
+#line 148 "perly.y"
+                        {
                          PL_pad_reset_pending = TRUE;
                          PL_eval_root = (ps[0].val.opval);
                          (yyval.ival) = 0;
@@ -63,8 +63,8 @@ case 2:
     break;
 
   case 8:
-#line 155 "perly.y"
-    {
+#line 156 "perly.y"
+                        {
                          parser->expect = XSTATE;
                           (yyval.ival) = 0;
                        }
@@ -72,8 +72,8 @@ case 2:
     break;
 
   case 9:
-#line 160 "perly.y"
-    {
+#line 161 "perly.y"
+                        {
                          PL_pad_reset_pending = TRUE;
                          PL_eval_root = (ps[0].val.opval);
                          (yyval.ival) = 0;
@@ -84,8 +84,8 @@ case 2:
     break;
 
   case 10:
-#line 168 "perly.y"
-    {
+#line 169 "perly.y"
+                        {
                          parser->expect = XSTATE;
                           (yyval.ival) = 0;
                        }
@@ -93,8 +93,8 @@ case 2:
     break;
 
   case 11:
-#line 173 "perly.y"
-    {
+#line 174 "perly.y"
+                        {
                          PL_pad_reset_pending = TRUE;
                          PL_eval_root = (ps[0].val.opval);
                          (yyval.ival) = 0;
@@ -105,8 +105,8 @@ case 2:
     break;
 
   case 12:
-#line 181 "perly.y"
-    {
+#line 182 "perly.y"
+                        {
                          parser->expect = XSTATE;
                           (yyval.ival) = 0;
                        }
@@ -114,8 +114,8 @@ case 2:
     break;
 
   case 13:
-#line 186 "perly.y"
-    {
+#line 187 "perly.y"
+                        {
                          PL_eval_root = (ps[0].val.opval);
                          (yyval.ival) = 0;
                        }
@@ -123,8 +123,8 @@ case 2:
     break;
 
   case 14:
-#line 191 "perly.y"
-    {
+#line 192 "perly.y"
+                        {
                          parser->expect = XSTATE;
                          (yyval.ival) = 0;
                        }
@@ -132,8 +132,8 @@ case 2:
     break;
 
   case 15:
-#line 196 "perly.y"
-    {
+#line 197 "perly.y"
+                        {
                          PL_eval_root = (ps[0].val.opval);
                          (yyval.ival) = 0;
                        }
@@ -141,8 +141,8 @@ case 2:
     break;
 
   case 16:
-#line 204 "perly.y"
-    { if (parser->copline > (line_t)(ps[-3].val.ival))
+#line 205 "perly.y"
+                        { if (parser->copline > (line_t)(ps[-3].val.ival))
                              parser->copline = (line_t)(ps[-3].val.ival);
                          (yyval.opval) = block_end((ps[-2].val.ival), (ps[-1].val.opval));
                        }
@@ -150,8 +150,8 @@ case 2:
     break;
 
   case 17:
-#line 212 "perly.y"
-    { if (parser->copline > (line_t)(ps[-6].val.ival))
+#line 213 "perly.y"
+                        { if (parser->copline > (line_t)(ps[-6].val.ival))
                              parser->copline = (line_t)(ps[-6].val.ival);
                          (yyval.opval) = block_end((ps[-5].val.ival), (ps[-2].val.opval));
                        }
@@ -159,15 +159,15 @@ case 2:
     break;
 
   case 18:
-#line 219 "perly.y"
-    { (yyval.ival) = block_start(TRUE);
+#line 220 "perly.y"
+                        { (yyval.ival) = block_start(TRUE);
                          parser->parsed_sub = 0; }
 
     break;
 
   case 19:
-#line 224 "perly.y"
-    { if (parser->copline > (line_t)(ps[-3].val.ival))
+#line 225 "perly.y"
+                        { if (parser->copline > (line_t)(ps[-3].val.ival))
                              parser->copline = (line_t)(ps[-3].val.ival);
                          (yyval.opval) = block_end((ps[-2].val.ival), (ps[-1].val.opval));
                        }
@@ -175,21 +175,21 @@ case 2:
     break;
 
   case 20:
-#line 231 "perly.y"
-    { (yyval.ival) = block_start(FALSE);
+#line 232 "perly.y"
+                        { (yyval.ival) = block_start(FALSE);
                          parser->parsed_sub = 0; }
 
     break;
 
   case 21:
-#line 237 "perly.y"
-    { (yyval.opval) = NULL; }
+#line 238 "perly.y"
+                        { (yyval.opval) = NULL; }
 
     break;
 
   case 22:
-#line 239 "perly.y"
-    {   (yyval.opval) = op_append_list(OP_LINESEQ, (ps[-1].val.opval), (ps[0].val.opval));
+#line 240 "perly.y"
+                        {   (yyval.opval) = op_append_list(OP_LINESEQ, (ps[-1].val.opval), (ps[0].val.opval));
                            PL_pad_reset_pending = TRUE;
                            if ((ps[-1].val.opval) && (ps[0].val.opval))
                                PL_hints |= HINT_BLOCK_SCOPE;
@@ -198,14 +198,14 @@ case 2:
     break;
 
   case 23:
-#line 248 "perly.y"
-    { (yyval.opval) = NULL; }
+#line 249 "perly.y"
+                        { (yyval.opval) = NULL; }
 
     break;
 
   case 24:
-#line 250 "perly.y"
-    {   (yyval.opval) = op_append_list(OP_LINESEQ, (ps[-1].val.opval), (ps[0].val.opval));
+#line 251 "perly.y"
+                        {   (yyval.opval) = op_append_list(OP_LINESEQ, (ps[-1].val.opval), (ps[0].val.opval));
                            PL_pad_reset_pending = TRUE;
                            if ((ps[-1].val.opval) && (ps[0].val.opval))
                                PL_hints |= HINT_BLOCK_SCOPE;
@@ -214,22 +214,22 @@ case 2:
     break;
 
   case 25:
-#line 259 "perly.y"
-    {
+#line 260 "perly.y"
+                        {
                          (yyval.opval) = (ps[0].val.opval) ? newSTATEOP(0, NULL, (ps[0].val.opval)) : NULL;
                        }
 
     break;
 
   case 26:
-#line 263 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 264 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 27:
-#line 267 "perly.y"
-    {
+#line 268 "perly.y"
+                        {
                           SV *label = cSVOPx_sv((ps[-1].val.opval));
                          (yyval.opval) = newSTATEOP(SvFLAGS(label) & SVf_UTF8,
                                             savepv(SvPVX_const(label)), (ps[0].val.opval));
@@ -239,8 +239,8 @@ case 2:
     break;
 
   case 28:
-#line 274 "perly.y"
-    {
+#line 275 "perly.y"
+                        {
                           SV *label = cSVOPx_sv((ps[-1].val.opval));
                          (yyval.opval) = newSTATEOP(SvFLAGS(label) & SVf_UTF8,
                                             savepv(SvPVX_const(label)), (ps[0].val.opval));
@@ -250,14 +250,14 @@ case 2:
     break;
 
   case 29:
-#line 284 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 285 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 30:
-#line 286 "perly.y"
-    {
+#line 287 "perly.y"
+                        {
                          CV *fmtcv = PL_compcv;
                          newFORM((ps[-2].val.ival), (ps[-1].val.opval), (ps[0].val.opval));
                          (yyval.opval) = NULL;
@@ -270,8 +270,8 @@ case 2:
     break;
 
   case 31:
-#line 298 "perly.y"
-    {
+#line 299 "perly.y"
+                        {
                           init_named_cv(PL_compcv, (ps[-1].val.opval));
                          parser->in_my = 0;
                          parser->in_my_stash = NULL;
@@ -280,8 +280,8 @@ case 2:
     break;
 
   case 32:
-#line 304 "perly.y"
-    {
+#line 305 "perly.y"
+                        {
                          SvREFCNT_inc_simple_void(PL_compcv);
                          (ps[-5].val.opval)->op_type == OP_CONST
                              ? newATTRSUB((ps[-4].val.ival), (ps[-5].val.opval), (ps[-2].val.opval), (ps[-1].val.opval), (ps[0].val.opval))
@@ -295,8 +295,8 @@ case 2:
     break;
 
   case 33:
-#line 319 "perly.y"
-    {
+#line 320 "perly.y"
+                        {
                           init_named_cv(PL_compcv, (ps[-1].val.opval));
                          parser->in_my = 0;
                          parser->in_my_stash = NULL;
@@ -305,8 +305,8 @@ case 2:
     break;
 
   case 34:
-#line 325 "perly.y"
-    {
+#line 326 "perly.y"
+                        {
                          SvREFCNT_inc_simple_void(PL_compcv);
                          (ps[-4].val.opval)->op_type == OP_CONST
                              ? newATTRSUB((ps[-3].val.ival), (ps[-4].val.opval), NULL, (ps[-1].val.opval), (ps[0].val.opval))
@@ -320,8 +320,8 @@ case 2:
     break;
 
   case 35:
-#line 336 "perly.y"
-    {
+#line 337 "perly.y"
+                        {
                          package((ps[-1].val.opval));
                          if ((ps[-2].val.opval))
                              package_version((ps[-2].val.opval));
@@ -331,14 +331,14 @@ case 2:
     break;
 
   case 36:
-#line 343 "perly.y"
-    { CvSPECIAL_on(PL_compcv); /* It's a BEGIN {} */ }
+#line 344 "perly.y"
+                        { CvSPECIAL_on(PL_compcv); /* It's a BEGIN {} */ }
 
     break;
 
   case 37:
-#line 345 "perly.y"
-    {
+#line 346 "perly.y"
+                        {
                          SvREFCNT_inc_simple_void(PL_compcv);
                          utilize((ps[-6].val.ival), (ps[-5].val.ival), (ps[-3].val.opval), (ps[-2].val.opval), (ps[-1].val.opval));
                          parser->parsed_sub = 1;
@@ -348,8 +348,8 @@ case 2:
     break;
 
   case 38:
-#line 352 "perly.y"
-    {
+#line 353 "perly.y"
+                        {
                          (yyval.opval) = block_end((ps[-4].val.ival),
                              newCONDOP(0, (ps[-3].val.opval), op_scope((ps[-1].val.opval)), (ps[0].val.opval)));
                          parser->copline = (line_t)(ps[-6].val.ival);
@@ -358,8 +358,8 @@ case 2:
     break;
 
   case 39:
-#line 358 "perly.y"
-    {
+#line 359 "perly.y"
+                        {
                          (yyval.opval) = block_end((ps[-4].val.ival),
                               newCONDOP(0, (ps[-3].val.opval), (ps[0].val.opval), op_scope((ps[-1].val.opval))));
                          parser->copline = (line_t)(ps[-6].val.ival);
@@ -368,8 +368,8 @@ case 2:
     break;
 
   case 40:
-#line 364 "perly.y"
-    {
+#line 365 "perly.y"
+                        {
                          (yyval.opval) = block_end((ps[-3].val.ival), newGIVENOP((ps[-2].val.opval), op_scope((ps[0].val.opval)), 0));
                          parser->copline = (line_t)(ps[-5].val.ival);
                        }
@@ -377,20 +377,20 @@ case 2:
     break;
 
   case 41:
-#line 369 "perly.y"
-    { (yyval.opval) = block_end((ps[-3].val.ival), newWHENOP((ps[-2].val.opval), op_scope((ps[0].val.opval)))); }
+#line 370 "perly.y"
+                        { (yyval.opval) = block_end((ps[-3].val.ival), newWHENOP((ps[-2].val.opval), op_scope((ps[0].val.opval)))); }
 
     break;
 
   case 42:
-#line 371 "perly.y"
-    { (yyval.opval) = newWHENOP(0, op_scope((ps[0].val.opval))); }
+#line 372 "perly.y"
+                        { (yyval.opval) = newWHENOP(0, op_scope((ps[0].val.opval))); }
 
     break;
 
   case 43:
-#line 373 "perly.y"
-    {
+#line 374 "perly.y"
+                        {
                          (yyval.opval) = block_end((ps[-5].val.ival),
                                  newWHILEOP(0, 1, NULL,
                                      (ps[-4].val.opval), (ps[-1].val.opval), (ps[0].val.opval), (ps[-2].val.ival)));
@@ -400,8 +400,8 @@ case 2:
     break;
 
   case 44:
-#line 380 "perly.y"
-    {
+#line 381 "perly.y"
+                        {
                          (yyval.opval) = block_end((ps[-5].val.ival),
                                  newWHILEOP(0, 1, NULL,
                                      (ps[-4].val.opval), (ps[-1].val.opval), (ps[0].val.opval), (ps[-2].val.ival)));
@@ -411,20 +411,20 @@ case 2:
     break;
 
   case 45:
-#line 387 "perly.y"
-    { parser->expect = XTERM; }
+#line 388 "perly.y"
+                        { parser->expect = XTERM; }
 
     break;
 
   case 46:
-#line 389 "perly.y"
-    { parser->expect = XTERM; }
+#line 390 "perly.y"
+                        { parser->expect = XTERM; }
 
     break;
 
   case 47:
-#line 392 "perly.y"
-    {
+#line 393 "perly.y"
+                        {
                          OP *initop = (ps[-9].val.opval);
                          OP *forop = newWHILEOP(0, 1, NULL,
                                      scalar((ps[-6].val.opval)), (ps[0].val.opval), (ps[-2].val.opval), (ps[-3].val.ival));
@@ -442,8 +442,8 @@ case 2:
     break;
 
   case 48:
-#line 407 "perly.y"
-    {
+#line 408 "perly.y"
+                        {
                          (yyval.opval) = block_end((ps[-6].val.ival), newFOROP(0, (ps[-5].val.opval), (ps[-3].val.opval), (ps[-1].val.opval), (ps[0].val.opval)));
                          parser->copline = (line_t)(ps[-8].val.ival);
                        }
@@ -451,8 +451,8 @@ case 2:
     break;
 
   case 49:
-#line 412 "perly.y"
-    {
+#line 413 "perly.y"
+                        {
                          (yyval.opval) = block_end((ps[-4].val.ival), newFOROP(0,
                                      op_lvalue((ps[-6].val.opval), OP_ENTERLOOP), (ps[-3].val.opval), (ps[-1].val.opval), (ps[0].val.opval)));
                          parser->copline = (line_t)(ps[-7].val.ival);
@@ -461,14 +461,14 @@ case 2:
     break;
 
   case 50:
-#line 418 "perly.y"
-    { parser->in_my = 0; (yyval.opval) = my((ps[0].val.opval)); }
+#line 419 "perly.y"
+                        { parser->in_my = 0; (yyval.opval) = my((ps[0].val.opval)); }
 
     break;
 
   case 51:
-#line 420 "perly.y"
-    {
+#line 421 "perly.y"
+                        {
                          (yyval.opval) = block_end(
                                (ps[-7].val.ival),
                                newFOROP(0,
@@ -484,8 +484,8 @@ case 2:
     break;
 
   case 52:
-#line 433 "perly.y"
-    {
+#line 434 "perly.y"
+                        {
                          (yyval.opval) = block_end((ps[-4].val.ival), newFOROP(
                                0, op_lvalue(newUNOP(OP_REFGEN, 0,
                                                     (ps[-6].val.opval)),
@@ -496,8 +496,8 @@ case 2:
     break;
 
   case 53:
-#line 441 "perly.y"
-    {
+#line 442 "perly.y"
+                        {
                          (yyval.opval) = block_end((ps[-4].val.ival),
                                  newFOROP(0, NULL, (ps[-3].val.opval), (ps[-1].val.opval), (ps[0].val.opval)));
                          parser->copline = (line_t)(ps[-6].val.ival);
@@ -506,8 +506,8 @@ case 2:
     break;
 
   case 54:
-#line 447 "perly.y"
-    {
+#line 448 "perly.y"
+                        {
                          /* a block is a loop that happens once */
                          (yyval.opval) = newWHILEOP(0, 1, NULL,
                                  NULL, (ps[-1].val.opval), (ps[0].val.opval), 0);
@@ -516,8 +516,8 @@ case 2:
     break;
 
   case 55:
-#line 453 "perly.y"
-    {
+#line 454 "perly.y"
+                        {
                          package((ps[-2].val.opval));
                          if ((ps[-3].val.opval)) {
                              package_version((ps[-3].val.opval));
@@ -527,8 +527,8 @@ case 2:
     break;
 
   case 56:
-#line 460 "perly.y"
-    {
+#line 461 "perly.y"
+                        {
                          /* a block is a loop that happens once */
                          (yyval.opval) = newWHILEOP(0, 1, NULL,
                                  NULL, block_end((ps[-3].val.ival), (ps[-1].val.opval)), NULL, 0);
@@ -539,16 +539,16 @@ case 2:
     break;
 
   case 57:
-#line 468 "perly.y"
-    {
+#line 469 "perly.y"
+                        {
                          (yyval.opval) = (ps[-1].val.opval);
                        }
 
     break;
 
   case 58:
-#line 472 "perly.y"
-    {
+#line 473 "perly.y"
+                        {
                          (yyval.opval) = newLISTOP(OP_DIE, 0, newOP(OP_PUSHMARK, 0),
                                newSVOP(OP_CONST, 0, newSVpvs("Unimplemented")));
                        }
@@ -556,8 +556,8 @@ case 2:
     break;
 
   case 59:
-#line 477 "perly.y"
-    {
+#line 478 "perly.y"
+                        {
                          (yyval.opval) = NULL;
                          parser->copline = NOLINE;
                        }
@@ -565,8 +565,8 @@ case 2:
     break;
 
   case 60:
-#line 485 "perly.y"
-    { OP *list;
+#line 486 "perly.y"
+                        { OP *list;
                          if ((ps[0].val.opval)) {
                              OP *term = (ps[0].val.opval);
                              list = op_append_elem(OP_LIST, (ps[-1].val.opval), term);
@@ -584,84 +584,84 @@ case 2:
     break;
 
   case 61:
-#line 502 "perly.y"
-    { (yyval.opval) = NULL; }
+#line 503 "perly.y"
+                        { (yyval.opval) = NULL; }
 
     break;
 
   case 62:
-#line 504 "perly.y"
-    { (yyval.opval) = op_unscope((ps[-1].val.opval)); }
-
-    break;
-
-  case 63:
-#line 509 "perly.y"
-    { (yyval.opval) = NULL; }
+#line 505 "perly.y"
+                        { (yyval.opval) = op_unscope((ps[-1].val.opval)); }
 
     break;
 
   case 64:
-#line 511 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 513 "perly.y"
+                        { (yyval.opval) = NULL; }
 
     break;
 
   case 65:
-#line 513 "perly.y"
-    { (yyval.opval) = newLOGOP(OP_AND, 0, (ps[0].val.opval), (ps[-2].val.opval)); }
+#line 515 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 66:
-#line 515 "perly.y"
-    { (yyval.opval) = newLOGOP(OP_OR, 0, (ps[0].val.opval), (ps[-2].val.opval)); }
+#line 517 "perly.y"
+                        { (yyval.opval) = newLOGOP(OP_AND, 0, (ps[0].val.opval), (ps[-2].val.opval)); }
 
     break;
 
   case 67:
-#line 517 "perly.y"
-    { (yyval.opval) = newLOOPOP(OPf_PARENS, 1, scalar((ps[0].val.opval)), (ps[-2].val.opval)); }
+#line 519 "perly.y"
+                        { (yyval.opval) = newLOGOP(OP_OR, 0, (ps[0].val.opval), (ps[-2].val.opval)); }
 
     break;
 
   case 68:
-#line 519 "perly.y"
-    { (yyval.opval) = newLOOPOP(OPf_PARENS, 1, (ps[0].val.opval), (ps[-2].val.opval)); }
+#line 521 "perly.y"
+                        { (yyval.opval) = newLOOPOP(OPf_PARENS, 1, scalar((ps[0].val.opval)), (ps[-2].val.opval)); }
 
     break;
 
   case 69:
-#line 521 "perly.y"
-    { (yyval.opval) = newFOROP(0, NULL, (ps[0].val.opval), (ps[-2].val.opval), NULL);
-                         parser->copline = (line_t)(ps[-1].val.ival); }
+#line 523 "perly.y"
+                        { (yyval.opval) = newLOOPOP(OPf_PARENS, 1, (ps[0].val.opval), (ps[-2].val.opval)); }
 
     break;
 
   case 70:
-#line 524 "perly.y"
-    { (yyval.opval) = newWHENOP((ps[0].val.opval), op_scope((ps[-2].val.opval))); }
+#line 525 "perly.y"
+                        { (yyval.opval) = newFOROP(0, NULL, (ps[0].val.opval), (ps[-2].val.opval), NULL);
+                         parser->copline = (line_t)(ps[-1].val.ival); }
 
     break;
 
   case 71:
-#line 529 "perly.y"
-    { (yyval.opval) = NULL; }
+#line 528 "perly.y"
+                        { (yyval.opval) = newWHENOP((ps[0].val.opval), op_scope((ps[-2].val.opval))); }
 
     break;
 
   case 72:
-#line 531 "perly.y"
-    {
+#line 533 "perly.y"
+                        { (yyval.opval) = NULL; }
+
+    break;
+
+  case 73:
+#line 535 "perly.y"
+                        {
                          ((ps[0].val.opval))->op_flags |= OPf_PARENS;
                          (yyval.opval) = op_scope((ps[0].val.opval));
                        }
 
     break;
 
-  case 73:
-#line 536 "perly.y"
-    { parser->copline = (line_t)(ps[-5].val.ival);
+  case 74:
+#line 540 "perly.y"
+                        { parser->copline = (line_t)(ps[-5].val.ival);
                            (yyval.opval) = newCONDOP(0,
                                newSTATEOP(OPf_SPECIAL,NULL,(ps[-3].val.opval)),
                                op_scope((ps[-1].val.opval)), (ps[0].val.opval));
@@ -670,154 +670,154 @@ case 2:
 
     break;
 
-  case 74:
-#line 546 "perly.y"
-    { (yyval.opval) = NULL; }
+  case 75:
+#line 550 "perly.y"
+                        { (yyval.opval) = NULL; }
 
     break;
 
-  case 75:
-#line 548 "perly.y"
-    { (yyval.opval) = op_scope((ps[0].val.opval)); }
+  case 76:
+#line 552 "perly.y"
+                        { (yyval.opval) = op_scope((ps[0].val.opval)); }
 
     break;
 
-  case 76:
-#line 553 "perly.y"
-    { (yyval.ival) = (PL_min_intro_pending &&
+  case 77:
+#line 557 "perly.y"
+                        { (yyval.ival) = (PL_min_intro_pending &&
                            PL_max_intro_pending >=  PL_min_intro_pending);
                          intro_my(); }
 
     break;
 
-  case 77:
-#line 559 "perly.y"
-    { (yyval.opval) = NULL; }
+  case 78:
+#line 563 "perly.y"
+                        { (yyval.opval) = NULL; }
 
     break;
 
-  case 79:
-#line 565 "perly.y"
-    { YYSTYPE tmplval;
+  case 80:
+#line 569 "perly.y"
+                        { YYSTYPE tmplval;
                          (void)scan_num("1", &tmplval);
                          (yyval.opval) = tmplval.opval; }
 
     break;
 
-  case 81:
-#line 573 "perly.y"
-    { (yyval.opval) = invert(scalar((ps[0].val.opval))); }
-
-    break;
-
   case 82:
-#line 578 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); intro_my(); }
+#line 577 "perly.y"
+                        { (yyval.opval) = invert(scalar((ps[0].val.opval))); }
 
     break;
 
   case 83:
 #line 582 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); intro_my(); }
+                        { (yyval.opval) = (ps[0].val.opval); intro_my(); }
 
     break;
 
   case 84:
-#line 585 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 586 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); intro_my(); }
 
     break;
 
   case 85:
-#line 586 "perly.y"
-    { (yyval.opval) = NULL; }
+#line 589 "perly.y"
+                                { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 86:
 #line 590 "perly.y"
-    { (yyval.ival) = start_subparse(FALSE, 0);
-                           SAVEFREESV(PL_compcv); }
+                                { (yyval.opval) = NULL; }
 
     break;
 
   case 87:
-#line 596 "perly.y"
-    { (yyval.ival) = start_subparse(FALSE, CVf_ANON);
+#line 594 "perly.y"
+                        { (yyval.ival) = start_subparse(FALSE, 0);
                            SAVEFREESV(PL_compcv); }
 
     break;
 
   case 88:
-#line 601 "perly.y"
-    { (yyval.ival) = start_subparse(TRUE, 0);
+#line 600 "perly.y"
+                        { (yyval.ival) = start_subparse(FALSE, CVf_ANON);
                            SAVEFREESV(PL_compcv); }
 
     break;
 
-  case 91:
-#line 612 "perly.y"
-    { (yyval.opval) = NULL; }
+  case 89:
+#line 605 "perly.y"
+                        { (yyval.ival) = start_subparse(TRUE, 0);
+                           SAVEFREESV(PL_compcv); }
 
     break;
 
-  case 93:
-#line 618 "perly.y"
-    { (yyval.opval) = NULL; }
+  case 92:
+#line 616 "perly.y"
+                        { (yyval.opval) = NULL; }
 
     break;
 
   case 94:
-#line 620 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 622 "perly.y"
+                        { (yyval.opval) = NULL; }
 
     break;
 
   case 95:
-#line 622 "perly.y"
-    { (yyval.opval) = NULL; }
+#line 624 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 96:
-#line 627 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 626 "perly.y"
+                        { (yyval.opval) = NULL; }
 
     break;
 
   case 97:
-#line 629 "perly.y"
-    { (yyval.opval) = NULL; }
+#line 631 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 98:
-#line 640 "perly.y"
-    { parser->in_my = 0; (yyval.opval) = NULL; }
+#line 633 "perly.y"
+                        { (yyval.opval) = NULL; }
 
     break;
 
   case 99:
-#line 642 "perly.y"
-    { parser->in_my = 0; (yyval.opval) = (ps[0].val.opval); }
+#line 644 "perly.y"
+                        { parser->in_my = 0; (yyval.opval) = NULL; }
 
     break;
 
   case 100:
-#line 647 "perly.y"
-    { (yyval.ival) = '@'; }
+#line 646 "perly.y"
+                        { parser->in_my = 0; (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 101:
-#line 649 "perly.y"
-    { (yyval.ival) = '%'; }
+#line 651 "perly.y"
+                        { (yyval.ival) = '@'; }
 
     break;
 
   case 102:
 #line 653 "perly.y"
-    {
+                        { (yyval.ival) = '%'; }
+
+    break;
+
+  case 103:
+#line 657 "perly.y"
+                        {
                             I32 sigil   = (ps[-2].val.ival);
                             OP *var     = (ps[-1].val.opval);
                             OP *defexpr = (ps[0].val.opval);
@@ -835,27 +835,27 @@ case 2:
 
     break;
 
-  case 103:
-#line 672 "perly.y"
-    { (yyval.opval) = NULL; }
-
-    break;
-
   case 104:
-#line 674 "perly.y"
-    { (yyval.opval) = newOP(OP_NULL, 0); }
+#line 676 "perly.y"
+                        { (yyval.opval) = NULL; }
 
     break;
 
   case 105:
-#line 676 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 678 "perly.y"
+                        { (yyval.opval) = newOP(OP_NULL, 0); }
 
     break;
 
   case 106:
-#line 682 "perly.y"
-    {
+#line 680 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
+
+    break;
+
+  case 107:
+#line 686 "perly.y"
+                        {
                             OP *var     = (ps[-1].val.opval);
                             OP *defexpr = (ps[0].val.opval);
 
@@ -918,71 +918,71 @@ case 2:
 
     break;
 
-  case 107:
-#line 747 "perly.y"
-    { parser->in_my = KEY_sigvar; (yyval.opval) = (ps[0].val.opval); }
-
-    break;
-
   case 108:
-#line 749 "perly.y"
-    { parser->in_my = KEY_sigvar; (yyval.opval) = (ps[0].val.opval); }
+#line 751 "perly.y"
+                        { parser->in_my = KEY_sigvar; (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 109:
-#line 755 "perly.y"
-    { (yyval.opval) = (ps[-1].val.opval); }
+#line 753 "perly.y"
+                        { parser->in_my = KEY_sigvar; (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 110:
-#line 757 "perly.y"
-    {
-                         (yyval.opval) = op_append_list(OP_LINESEQ, (ps[-2].val.opval), (ps[0].val.opval));
-                       }
+#line 759 "perly.y"
+                        { (yyval.opval) = (ps[-1].val.opval); }
 
     break;
 
   case 111:
 #line 761 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+                        {
+                         (yyval.opval) = op_append_list(OP_LINESEQ, (ps[-2].val.opval), (ps[0].val.opval));
+                       }
 
     break;
 
   case 112:
-#line 766 "perly.y"
-    { (yyval.opval) = NULL; }
+#line 765 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 113:
-#line 768 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 770 "perly.y"
+                        { (yyval.opval) = NULL; }
 
     break;
 
   case 114:
 #line 772 "perly.y"
-    { (yyval.opval) = NULL; }
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 115:
-#line 774 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 776 "perly.y"
+                        { (yyval.opval) = NULL; }
 
     break;
 
   case 116:
 #line 778 "perly.y"
-    { (yyval.opval) = (ps[-1].val.opval); }
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 117:
-#line 781 "perly.y"
-    {
+#line 782 "perly.y"
+                        { (yyval.opval) = (ps[-1].val.opval); }
+
+    break;
+
+  case 118:
+#line 785 "perly.y"
+                        {
                             ENTER;
                             SAVEIV(parser->sig_elems);
                             SAVEIV(parser->sig_optelems);
@@ -995,9 +995,9 @@ case 2:
 
     break;
 
-  case 118:
-#line 792 "perly.y"
-    {
+  case 119:
+#line 796 "perly.y"
+                        {
                             OP            *sigops = (ps[0].val.opval);
                             struct op_argcheck_aux *aux;
                             OP            *check;
@@ -1054,21 +1054,21 @@ case 2:
 
     break;
 
-  case 119:
-#line 849 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+  case 120:
+#line 853 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
-  case 120:
-#line 850 "perly.y"
-    { (yyval.opval) = NULL; }
+  case 121:
+#line 854 "perly.y"
+                        { (yyval.opval) = NULL; }
 
     break;
 
-  case 121:
-#line 856 "perly.y"
-    {
+  case 122:
+#line 860 "perly.y"
+                        {
                          if (parser->copline > (line_t)(ps[-2].val.ival))
                              parser->copline = (line_t)(ps[-2].val.ival);
                          (yyval.opval) = block_end((ps[-3].val.ival), (ps[-1].val.opval));
@@ -1076,21 +1076,21 @@ case 2:
 
     break;
 
-  case 122:
-#line 866 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
-
-    break;
-
   case 123:
-#line 867 "perly.y"
-    { (yyval.opval) = NULL; }
+#line 870 "perly.y"
+                           { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 124:
 #line 871 "perly.y"
-    {
+                           { (yyval.opval) = NULL; }
+
+    break;
+
+  case 125:
+#line 875 "perly.y"
+                        {
                          if (parser->copline > (line_t)(ps[-2].val.ival))
                              parser->copline = (line_t)(ps[-2].val.ival);
                          (yyval.opval) = block_end((ps[-4].val.ival),
@@ -1099,58 +1099,58 @@ case 2:
 
     break;
 
-  case 125:
-#line 882 "perly.y"
-    { (yyval.opval) = newLOGOP(OP_AND, 0, (ps[-2].val.opval), (ps[0].val.opval)); }
-
-    break;
-
   case 126:
-#line 884 "perly.y"
-    { (yyval.opval) = newLOGOP((ps[-1].val.ival), 0, (ps[-2].val.opval), (ps[0].val.opval)); }
+#line 886 "perly.y"
+                        { (yyval.opval) = newLOGOP(OP_AND, 0, (ps[-2].val.opval), (ps[0].val.opval)); }
 
     break;
 
   case 127:
-#line 886 "perly.y"
-    { (yyval.opval) = newLOGOP(OP_DOR, 0, (ps[-2].val.opval), (ps[0].val.opval)); }
+#line 888 "perly.y"
+                        { (yyval.opval) = newLOGOP((ps[-1].val.ival), 0, (ps[-2].val.opval), (ps[0].val.opval)); }
 
     break;
 
-  case 129:
-#line 892 "perly.y"
-    { (yyval.opval) = (ps[-1].val.opval); }
+  case 128:
+#line 890 "perly.y"
+                        { (yyval.opval) = newLOGOP(OP_DOR, 0, (ps[-2].val.opval), (ps[0].val.opval)); }
 
     break;
 
   case 130:
-#line 894 "perly.y"
-    {
+#line 896 "perly.y"
+                        { (yyval.opval) = (ps[-1].val.opval); }
+
+    break;
+
+  case 131:
+#line 898 "perly.y"
+                        {
                          OP* term = (ps[0].val.opval);
                          (yyval.opval) = op_append_elem(OP_LIST, (ps[-2].val.opval), term);
                        }
 
     break;
 
-  case 132:
-#line 903 "perly.y"
-    { (yyval.opval) = op_convert_list((ps[-2].val.ival), OPf_STACKED,
+  case 133:
+#line 907 "perly.y"
+                        { (yyval.opval) = op_convert_list((ps[-2].val.ival), OPf_STACKED,
                                op_prepend_elem(OP_LIST, newGVREF((ps[-2].val.ival),(ps[-1].val.opval)), (ps[0].val.opval)) );
                        }
 
     break;
 
-  case 133:
-#line 907 "perly.y"
-    { (yyval.opval) = op_convert_list((ps[-4].val.ival), OPf_STACKED,
+  case 134:
+#line 911 "perly.y"
+                        { (yyval.opval) = op_convert_list((ps[-4].val.ival), OPf_STACKED,
                                op_prepend_elem(OP_LIST, newGVREF((ps[-4].val.ival),(ps[-2].val.opval)), (ps[-1].val.opval)) );
                        }
 
     break;
 
-  case 134:
-#line 911 "perly.y"
-    { (yyval.opval) = op_convert_list(OP_ENTERSUB, OPf_STACKED,
+  case 135:
+#line 915 "perly.y"
+                        { (yyval.opval) = op_convert_list(OP_ENTERSUB, OPf_STACKED,
                                op_append_elem(OP_LIST,
                                    op_prepend_elem(OP_LIST, scalar((ps[-5].val.opval)), (ps[-1].val.opval)),
                                    newMETHOP(OP_METHOD, 0, (ps[-3].val.opval))));
@@ -1158,18 +1158,18 @@ case 2:
 
     break;
 
-  case 135:
-#line 917 "perly.y"
-    { (yyval.opval) = op_convert_list(OP_ENTERSUB, OPf_STACKED,
+  case 136:
+#line 921 "perly.y"
+                        { (yyval.opval) = op_convert_list(OP_ENTERSUB, OPf_STACKED,
                                op_append_elem(OP_LIST, scalar((ps[-2].val.opval)),
                                    newMETHOP(OP_METHOD, 0, (ps[0].val.opval))));
                        }
 
     break;
 
-  case 136:
-#line 922 "perly.y"
-    { (yyval.opval) = op_convert_list(OP_ENTERSUB, OPf_STACKED,
+  case 137:
+#line 926 "perly.y"
+                        { (yyval.opval) = op_convert_list(OP_ENTERSUB, OPf_STACKED,
                                op_append_elem(OP_LIST,
                                    op_prepend_elem(OP_LIST, (ps[-1].val.opval), (ps[0].val.opval)),
                                    newMETHOP(OP_METHOD, 0, (ps[-2].val.opval))));
@@ -1177,9 +1177,9 @@ case 2:
 
     break;
 
-  case 137:
-#line 928 "perly.y"
-    { (yyval.opval) = op_convert_list(OP_ENTERSUB, OPf_STACKED,
+  case 138:
+#line 932 "perly.y"
+                        { (yyval.opval) = op_convert_list(OP_ENTERSUB, OPf_STACKED,
                                op_append_elem(OP_LIST,
                                    op_prepend_elem(OP_LIST, (ps[-3].val.opval), (ps[-1].val.opval)),
                                    newMETHOP(OP_METHOD, 0, (ps[-4].val.opval))));
@@ -1187,97 +1187,97 @@ case 2:
 
     break;
 
-  case 138:
-#line 934 "perly.y"
-    { (yyval.opval) = op_convert_list((ps[-1].val.ival), 0, (ps[0].val.opval)); }
-
-    break;
-
   case 139:
-#line 936 "perly.y"
-    { (yyval.opval) = op_convert_list((ps[-3].val.ival), 0, (ps[-1].val.opval)); }
+#line 938 "perly.y"
+                        { (yyval.opval) = op_convert_list((ps[-1].val.ival), 0, (ps[0].val.opval)); }
 
     break;
 
   case 140:
-#line 938 "perly.y"
-    { (yyval.opval) = op_convert_list((ps[-3].val.ival), 0, (ps[-1].val.opval)); }
+#line 940 "perly.y"
+                        { (yyval.opval) = op_convert_list((ps[-3].val.ival), 0, (ps[-1].val.opval)); }
 
     break;
 
   case 141:
-#line 940 "perly.y"
-    { SvREFCNT_inc_simple_void(PL_compcv);
-                         (yyval.opval) = newANONATTRSUB((ps[-1].val.ival), 0, NULL, (ps[0].val.opval)); }
+#line 942 "perly.y"
+                        { (yyval.opval) = op_convert_list((ps[-3].val.ival), 0, (ps[-1].val.opval)); }
 
     break;
 
   case 142:
-#line 943 "perly.y"
-    { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
+#line 944 "perly.y"
+                        { SvREFCNT_inc_simple_void(PL_compcv);
+                         (yyval.opval) = newANONATTRSUB((ps[-1].val.ival), 0, NULL, (ps[0].val.opval)); }
+
+    break;
+
+  case 143:
+#line 947 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
                                 op_append_elem(OP_LIST,
                                   op_prepend_elem(OP_LIST, (ps[-1].val.opval), (ps[0].val.opval)), (ps[-4].val.opval)));
                        }
 
     break;
 
-  case 145:
-#line 958 "perly.y"
-    { (yyval.opval) = newBINOP(OP_GELEM, 0, (ps[-4].val.opval), scalar((ps[-2].val.opval))); }
+  case 146:
+#line 962 "perly.y"
+                        { (yyval.opval) = newBINOP(OP_GELEM, 0, (ps[-4].val.opval), scalar((ps[-2].val.opval))); }
 
     break;
 
-  case 146:
-#line 960 "perly.y"
-    { (yyval.opval) = newBINOP(OP_AELEM, 0, oopsAV((ps[-3].val.opval)), scalar((ps[-1].val.opval)));
+  case 147:
+#line 964 "perly.y"
+                        { (yyval.opval) = newBINOP(OP_AELEM, 0, oopsAV((ps[-3].val.opval)), scalar((ps[-1].val.opval)));
                        }
 
     break;
 
-  case 147:
-#line 963 "perly.y"
-    { (yyval.opval) = newBINOP(OP_AELEM, 0,
+  case 148:
+#line 967 "perly.y"
+                        { (yyval.opval) = newBINOP(OP_AELEM, 0,
                                        ref(newAVREF((ps[-4].val.opval)),OP_RV2AV),
                                        scalar((ps[-1].val.opval)));
                        }
 
     break;
 
-  case 148:
-#line 968 "perly.y"
-    { (yyval.opval) = newBINOP(OP_AELEM, 0,
+  case 149:
+#line 972 "perly.y"
+                        { (yyval.opval) = newBINOP(OP_AELEM, 0,
                                        ref(newAVREF((ps[-3].val.opval)),OP_RV2AV),
                                        scalar((ps[-1].val.opval)));
                        }
 
     break;
 
-  case 149:
-#line 973 "perly.y"
-    { (yyval.opval) = newBINOP(OP_HELEM, 0, oopsHV((ps[-4].val.opval)), jmaybe((ps[-2].val.opval)));
+  case 150:
+#line 977 "perly.y"
+                        { (yyval.opval) = newBINOP(OP_HELEM, 0, oopsHV((ps[-4].val.opval)), jmaybe((ps[-2].val.opval)));
                        }
 
     break;
 
-  case 150:
-#line 976 "perly.y"
-    { (yyval.opval) = newBINOP(OP_HELEM, 0,
+  case 151:
+#line 980 "perly.y"
+                        { (yyval.opval) = newBINOP(OP_HELEM, 0,
                                        ref(newHVREF((ps[-5].val.opval)),OP_RV2HV),
                                        jmaybe((ps[-2].val.opval))); }
 
     break;
 
-  case 151:
-#line 980 "perly.y"
-    { (yyval.opval) = newBINOP(OP_HELEM, 0,
+  case 152:
+#line 984 "perly.y"
+                        { (yyval.opval) = newBINOP(OP_HELEM, 0,
                                        ref(newHVREF((ps[-4].val.opval)),OP_RV2HV),
                                        jmaybe((ps[-2].val.opval))); }
 
     break;
 
-  case 152:
-#line 984 "perly.y"
-    { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
+  case 153:
+#line 988 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
                                   newCVREF(0, scalar((ps[-3].val.opval))));
                          if (parser->expect == XBLOCK)
                              parser->expect = XOPERATOR;
@@ -1285,9 +1285,9 @@ case 2:
 
     break;
 
-  case 153:
-#line 990 "perly.y"
-    { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
+  case 154:
+#line 994 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
                                   op_append_elem(OP_LIST, (ps[-1].val.opval),
                                       newCVREF(0, scalar((ps[-4].val.opval)))));
                          if (parser->expect == XBLOCK)
@@ -1296,9 +1296,9 @@ case 2:
 
     break;
 
-  case 154:
-#line 998 "perly.y"
-    { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
+  case 155:
+#line 1002 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
                                   op_append_elem(OP_LIST, (ps[-1].val.opval),
                                               newCVREF(0, scalar((ps[-3].val.opval)))));
                          if (parser->expect == XBLOCK)
@@ -1307,9 +1307,9 @@ case 2:
 
     break;
 
-  case 155:
-#line 1005 "perly.y"
-    { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
+  case 156:
+#line 1009 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
                                   newCVREF(0, scalar((ps[-2].val.opval))));
                          if (parser->expect == XBLOCK)
                              parser->expect = XOPERATOR;
@@ -1317,224 +1317,224 @@ case 2:
 
     break;
 
-  case 156:
-#line 1011 "perly.y"
-    { (yyval.opval) = newSLICEOP(0, (ps[-1].val.opval), (ps[-4].val.opval)); }
-
-    break;
-
   case 157:
-#line 1013 "perly.y"
-    { (yyval.opval) = newSLICEOP(0, (ps[-1].val.opval), (ps[-3].val.opval)); }
+#line 1015 "perly.y"
+                        { (yyval.opval) = newSLICEOP(0, (ps[-1].val.opval), (ps[-4].val.opval)); }
 
     break;
 
   case 158:
-#line 1015 "perly.y"
-    { (yyval.opval) = newSLICEOP(0, (ps[-1].val.opval), NULL); }
+#line 1017 "perly.y"
+                        { (yyval.opval) = newSLICEOP(0, (ps[-1].val.opval), (ps[-3].val.opval)); }
 
     break;
 
   case 159:
-#line 1020 "perly.y"
-    { (yyval.opval) = newASSIGNOP(OPf_STACKED, (ps[-2].val.opval), (ps[-1].val.ival), (ps[0].val.opval)); }
+#line 1019 "perly.y"
+                        { (yyval.opval) = newSLICEOP(0, (ps[-1].val.opval), NULL); }
 
     break;
 
   case 160:
-#line 1022 "perly.y"
-    { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }
+#line 1024 "perly.y"
+                        { (yyval.opval) = newASSIGNOP(OPf_STACKED, (ps[-2].val.opval), (ps[-1].val.ival), (ps[0].val.opval)); }
 
     break;
 
   case 161:
-#line 1024 "perly.y"
-    {   if ((ps[-1].val.ival) != OP_REPEAT)
-                               scalar((ps[-2].val.opval));
-                           (yyval.opval) = newBINOP((ps[-1].val.ival), 0, (ps[-2].val.opval), scalar((ps[0].val.opval)));
-                       }
+#line 1026 "perly.y"
+                        { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }
 
     break;
 
   case 162:
-#line 1029 "perly.y"
-    { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }
+#line 1028 "perly.y"
+                        {   if ((ps[-1].val.ival) != OP_REPEAT)
+                               scalar((ps[-2].val.opval));
+                           (yyval.opval) = newBINOP((ps[-1].val.ival), 0, (ps[-2].val.opval), scalar((ps[0].val.opval)));
+                       }
 
     break;
 
   case 163:
-#line 1031 "perly.y"
-    { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }
+#line 1033 "perly.y"
+                        { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }
 
     break;
 
   case 164:
-#line 1033 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 1035 "perly.y"
+                        { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }
 
     break;
 
   case 165:
-#line 1035 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 1037 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 166:
-#line 1037 "perly.y"
-    { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }
+#line 1039 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 167:
-#line 1039 "perly.y"
-    { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }
+#line 1041 "perly.y"
+                        { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }
 
     break;
 
   case 168:
-#line 1041 "perly.y"
-    { (yyval.opval) = newRANGE((ps[-1].val.ival), scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }
+#line 1043 "perly.y"
+                        { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }
 
     break;
 
   case 169:
-#line 1043 "perly.y"
-    { (yyval.opval) = newLOGOP(OP_AND, 0, (ps[-2].val.opval), (ps[0].val.opval)); }
+#line 1045 "perly.y"
+                        { (yyval.opval) = newRANGE((ps[-1].val.ival), scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }
 
     break;
 
   case 170:
-#line 1045 "perly.y"
-    { (yyval.opval) = newLOGOP(OP_OR, 0, (ps[-2].val.opval), (ps[0].val.opval)); }
+#line 1047 "perly.y"
+                        { (yyval.opval) = newLOGOP(OP_AND, 0, (ps[-2].val.opval), (ps[0].val.opval)); }
 
     break;
 
   case 171:
-#line 1047 "perly.y"
-    { (yyval.opval) = newLOGOP(OP_DOR, 0, (ps[-2].val.opval), (ps[0].val.opval)); }
+#line 1049 "perly.y"
+                        { (yyval.opval) = newLOGOP(OP_OR, 0, (ps[-2].val.opval), (ps[0].val.opval)); }
 
     break;
 
   case 172:
-#line 1049 "perly.y"
-    { (yyval.opval) = bind_match((ps[-1].val.ival), (ps[-2].val.opval), (ps[0].val.opval)); }
+#line 1051 "perly.y"
+                        { (yyval.opval) = newLOGOP(OP_DOR, 0, (ps[-2].val.opval), (ps[0].val.opval)); }
 
     break;
 
   case 173:
 #line 1053 "perly.y"
-    { (yyval.opval) = cmpchain_finish((ps[0].val.opval)); }
+                        { (yyval.opval) = bind_match((ps[-1].val.ival), (ps[-2].val.opval), (ps[0].val.opval)); }
 
     break;
 
   case 174:
-#line 1055 "perly.y"
-    { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }
+#line 1057 "perly.y"
+                        { (yyval.opval) = cmpchain_finish((ps[0].val.opval)); }
 
     break;
 
   case 175:
-#line 1057 "perly.y"
-    { yyerror("syntax error"); YYERROR; }
+#line 1059 "perly.y"
+                        { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }
 
     break;
 
   case 176:
-#line 1059 "perly.y"
-    { yyerror("syntax error"); YYERROR; }
+#line 1061 "perly.y"
+                        { yyerror("syntax error"); YYERROR; }
 
     break;
 
   case 177:
 #line 1063 "perly.y"
-    { (yyval.opval) = cmpchain_start((ps[-1].val.ival), (ps[-2].val.opval), (ps[0].val.opval)); }
+                        { yyerror("syntax error"); YYERROR; }
 
     break;
 
   case 178:
-#line 1065 "perly.y"
-    { (yyval.opval) = cmpchain_extend((ps[-1].val.ival), (ps[-2].val.opval), (ps[0].val.opval)); }
+#line 1067 "perly.y"
+                        { (yyval.opval) = cmpchain_start((ps[-1].val.ival), (ps[-2].val.opval), (ps[0].val.opval)); }
 
     break;
 
   case 179:
 #line 1069 "perly.y"
-    { (yyval.opval) = cmpchain_finish((ps[0].val.opval)); }
+                        { (yyval.opval) = cmpchain_extend((ps[-1].val.ival), (ps[-2].val.opval), (ps[0].val.opval)); }
 
     break;
 
   case 180:
-#line 1071 "perly.y"
-    { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }
+#line 1073 "perly.y"
+                        { (yyval.opval) = cmpchain_finish((ps[0].val.opval)); }
 
     break;
 
   case 181:
-#line 1073 "perly.y"
-    { yyerror("syntax error"); YYERROR; }
+#line 1075 "perly.y"
+                        { (yyval.opval) = newBINOP((ps[-1].val.ival), 0, scalar((ps[-2].val.opval)), scalar((ps[0].val.opval))); }
 
     break;
 
   case 182:
-#line 1075 "perly.y"
-    { yyerror("syntax error"); YYERROR; }
+#line 1077 "perly.y"
+                        { yyerror("syntax error"); YYERROR; }
 
     break;
 
   case 183:
 #line 1079 "perly.y"
-    { (yyval.opval) = cmpchain_start((ps[-1].val.ival), (ps[-2].val.opval), (ps[0].val.opval)); }
+                        { yyerror("syntax error"); YYERROR; }
 
     break;
 
   case 184:
-#line 1081 "perly.y"
-    { (yyval.opval) = cmpchain_extend((ps[-1].val.ival), (ps[-2].val.opval), (ps[0].val.opval)); }
+#line 1083 "perly.y"
+                        { (yyval.opval) = cmpchain_start((ps[-1].val.ival), (ps[-2].val.opval), (ps[0].val.opval)); }
 
     break;
 
   case 185:
-#line 1086 "perly.y"
-    { (yyval.opval) = newUNOP(OP_NEGATE, 0, scalar((ps[0].val.opval))); }
+#line 1085 "perly.y"
+                        { (yyval.opval) = cmpchain_extend((ps[-1].val.ival), (ps[-2].val.opval), (ps[0].val.opval)); }
 
     break;
 
   case 186:
-#line 1088 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 1090 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_NEGATE, 0, scalar((ps[0].val.opval))); }
 
     break;
 
   case 187:
-#line 1091 "perly.y"
-    { (yyval.opval) = newUNOP(OP_NOT, 0, scalar((ps[0].val.opval))); }
+#line 1092 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 188:
-#line 1093 "perly.y"
-    { (yyval.opval) = newUNOP((ps[-1].val.ival), 0, scalar((ps[0].val.opval))); }
+#line 1095 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_NOT, 0, scalar((ps[0].val.opval))); }
 
     break;
 
   case 189:
-#line 1095 "perly.y"
-    { (yyval.opval) = newUNOP(OP_POSTINC, 0,
-                                       op_lvalue(scalar((ps[-1].val.opval)), OP_POSTINC)); }
+#line 1097 "perly.y"
+                        { (yyval.opval) = newUNOP((ps[-1].val.ival), 0, scalar((ps[0].val.opval))); }
 
     break;
 
   case 190:
-#line 1098 "perly.y"
-    { (yyval.opval) = newUNOP(OP_POSTDEC, 0,
-                                       op_lvalue(scalar((ps[-1].val.opval)), OP_POSTDEC));}
+#line 1099 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_POSTINC, 0,
+                                       op_lvalue(scalar((ps[-1].val.opval)), OP_POSTINC)); }
 
     break;
 
   case 191:
-#line 1101 "perly.y"
-    { (yyval.opval) = op_convert_list(OP_JOIN, 0,
+#line 1102 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_POSTDEC, 0,
+                                       op_lvalue(scalar((ps[-1].val.opval)), OP_POSTDEC));}
+
+    break;
+
+  case 192:
+#line 1105 "perly.y"
+                        { (yyval.opval) = op_convert_list(OP_JOIN, 0,
                                       op_append_elem(
                                        OP_LIST,
                                        newSVREF(scalar(
@@ -1547,157 +1547,157 @@ case 2:
 
     break;
 
-  case 192:
-#line 1112 "perly.y"
-    { (yyval.opval) = newUNOP(OP_PREINC, 0,
-                                       op_lvalue(scalar((ps[0].val.opval)), OP_PREINC)); }
-
-    break;
-
   case 193:
-#line 1115 "perly.y"
-    { (yyval.opval) = newUNOP(OP_PREDEC, 0,
-                                       op_lvalue(scalar((ps[0].val.opval)), OP_PREDEC)); }
+#line 1116 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_PREINC, 0,
+                                       op_lvalue(scalar((ps[0].val.opval)), OP_PREINC)); }
 
     break;
 
   case 194:
-#line 1122 "perly.y"
-    { (yyval.opval) = newANONLIST((ps[-1].val.opval)); }
+#line 1119 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_PREDEC, 0,
+                                       op_lvalue(scalar((ps[0].val.opval)), OP_PREDEC)); }
 
     break;
 
   case 195:
-#line 1124 "perly.y"
-    { (yyval.opval) = newANONLIST(NULL);}
+#line 1126 "perly.y"
+                        { (yyval.opval) = newANONLIST((ps[-1].val.opval)); }
 
     break;
 
   case 196:
-#line 1126 "perly.y"
-    { (yyval.opval) = newANONHASH((ps[-2].val.opval)); }
+#line 1128 "perly.y"
+                        { (yyval.opval) = newANONLIST(NULL);}
 
     break;
 
   case 197:
-#line 1128 "perly.y"
-    { (yyval.opval) = newANONHASH(NULL); }
+#line 1130 "perly.y"
+                        { (yyval.opval) = newANONHASH((ps[-2].val.opval)); }
 
     break;
 
   case 198:
-#line 1130 "perly.y"
-    { SvREFCNT_inc_simple_void(PL_compcv);
-                         (yyval.opval) = newANONATTRSUB((ps[-3].val.ival), (ps[-2].val.opval), (ps[-1].val.opval), (ps[0].val.opval)); }
+#line 1132 "perly.y"
+                        { (yyval.opval) = newANONHASH(NULL); }
 
     break;
 
   case 199:
-#line 1133 "perly.y"
-    { SvREFCNT_inc_simple_void(PL_compcv);
-                         (yyval.opval) = newANONATTRSUB((ps[-2].val.ival), NULL, (ps[-1].val.opval), (ps[0].val.opval)); }
+#line 1134 "perly.y"
+                        { SvREFCNT_inc_simple_void(PL_compcv);
+                         (yyval.opval) = newANONATTRSUB((ps[-3].val.ival), (ps[-2].val.opval), (ps[-1].val.opval), (ps[0].val.opval)); }
 
     break;
 
   case 200:
-#line 1139 "perly.y"
-    { (yyval.opval) = dofile((ps[0].val.opval), (ps[-1].val.ival));}
+#line 1137 "perly.y"
+                        { SvREFCNT_inc_simple_void(PL_compcv);
+                         (yyval.opval) = newANONATTRSUB((ps[-2].val.ival), NULL, (ps[-1].val.opval), (ps[0].val.opval)); }
 
     break;
 
   case 201:
-#line 1141 "perly.y"
-    { (yyval.opval) = newUNOP(OP_NULL, OPf_SPECIAL, op_scope((ps[0].val.opval)));}
+#line 1143 "perly.y"
+                        { (yyval.opval) = dofile((ps[0].val.opval), (ps[-1].val.ival));}
 
     break;
 
-  case 206:
-#line 1149 "perly.y"
-    { (yyval.opval) = newCONDOP(0, (ps[-4].val.opval), (ps[-2].val.opval), (ps[0].val.opval)); }
+  case 202:
+#line 1145 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_NULL, OPf_SPECIAL, op_scope((ps[0].val.opval)));}
 
     break;
 
   case 207:
-#line 1151 "perly.y"
-    { (yyval.opval) = newUNOP(OP_REFGEN, 0, (ps[0].val.opval)); }
+#line 1153 "perly.y"
+                        { (yyval.opval) = newCONDOP(0, (ps[-4].val.opval), (ps[-2].val.opval), (ps[0].val.opval)); }
 
     break;
 
   case 208:
-#line 1153 "perly.y"
-    { (yyval.opval) = newUNOP(OP_REFGEN, 0, localize((ps[0].val.opval),1)); }
+#line 1155 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_REFGEN, 0, (ps[0].val.opval)); }
 
     break;
 
   case 209:
-#line 1155 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 1157 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_REFGEN, 0, localize((ps[0].val.opval),1)); }
 
     break;
 
   case 210:
-#line 1157 "perly.y"
-    { (yyval.opval) = localize((ps[0].val.opval),0); }
+#line 1159 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 211:
-#line 1159 "perly.y"
-    { (yyval.opval) = sawparens((ps[-1].val.opval)); }
+#line 1161 "perly.y"
+                        { (yyval.opval) = localize((ps[0].val.opval),0); }
 
     break;
 
   case 212:
-#line 1161 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 1163 "perly.y"
+                        { (yyval.opval) = sawparens((ps[-1].val.opval)); }
 
     break;
 
   case 213:
-#line 1163 "perly.y"
-    { (yyval.opval) = sawparens(newNULLLIST()); }
+#line 1165 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 214:
-#line 1165 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 1167 "perly.y"
+                        { (yyval.opval) = sawparens(newNULLLIST()); }
 
     break;
 
   case 215:
-#line 1167 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 1169 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 216:
-#line 1169 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 1171 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 217:
-#line 1171 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 1173 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 218:
-#line 1173 "perly.y"
-    { (yyval.opval) = newUNOP(OP_AV2ARYLEN, 0, ref((ps[0].val.opval), OP_AV2ARYLEN));}
+#line 1175 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 219:
-#line 1175 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 1177 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_AV2ARYLEN, 0, ref((ps[0].val.opval), OP_AV2ARYLEN));}
 
     break;
 
   case 220:
-#line 1177 "perly.y"
-    { (yyval.opval) = op_prepend_elem(OP_ASLICE,
+#line 1179 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
+
+    break;
+
+  case 221:
+#line 1181 "perly.y"
+                        { (yyval.opval) = op_prepend_elem(OP_ASLICE,
                                newOP(OP_PUSHMARK, 0),
                                    newLISTOP(OP_ASLICE, 0,
                                        list((ps[-1].val.opval)),
@@ -1709,9 +1709,9 @@ case 2:
 
     break;
 
-  case 221:
-#line 1187 "perly.y"
-    { (yyval.opval) = op_prepend_elem(OP_KVASLICE,
+  case 222:
+#line 1191 "perly.y"
+                        { (yyval.opval) = op_prepend_elem(OP_KVASLICE,
                                newOP(OP_PUSHMARK, 0),
                                    newLISTOP(OP_KVASLICE, 0,
                                        list((ps[-1].val.opval)),
@@ -1723,9 +1723,9 @@ case 2:
 
     break;
 
-  case 222:
-#line 1197 "perly.y"
-    { (yyval.opval) = op_prepend_elem(OP_HSLICE,
+  case 223:
+#line 1201 "perly.y"
+                        { (yyval.opval) = op_prepend_elem(OP_HSLICE,
                                newOP(OP_PUSHMARK, 0),
                                    newLISTOP(OP_HSLICE, 0,
                                        list((ps[-2].val.opval)),
@@ -1737,9 +1737,9 @@ case 2:
 
     break;
 
-  case 223:
-#line 1207 "perly.y"
-    { (yyval.opval) = op_prepend_elem(OP_KVHSLICE,
+  case 224:
+#line 1211 "perly.y"
+                        { (yyval.opval) = op_prepend_elem(OP_KVHSLICE,
                                newOP(OP_PUSHMARK, 0),
                                    newLISTOP(OP_KVHSLICE, 0,
                                        list((ps[-2].val.opval)),
@@ -1751,182 +1751,182 @@ case 2:
 
     break;
 
-  case 224:
-#line 1217 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
-
-    break;
-
   case 225:
-#line 1219 "perly.y"
-    { (yyval.opval) = newUNOP(OP_ENTERSUB, 0, scalar((ps[0].val.opval))); }
+#line 1221 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 226:
-#line 1221 "perly.y"
-    { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar((ps[-2].val.opval)));
-                       }
+#line 1223 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_ENTERSUB, 0, scalar((ps[0].val.opval))); }
 
     break;
 
   case 227:
-#line 1224 "perly.y"
-    {
-                         (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
-                               op_append_elem(OP_LIST, (ps[-1].val.opval), scalar((ps[-3].val.opval))));
+#line 1225 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar((ps[-2].val.opval)));
                        }
 
     break;
 
   case 228:
-#line 1229 "perly.y"
-    { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
-                           op_append_elem(OP_LIST, (ps[0].val.opval), scalar((ps[-1].val.opval))));
+#line 1228 "perly.y"
+                        {
+                         (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
+                               op_append_elem(OP_LIST, (ps[-1].val.opval), scalar((ps[-3].val.opval))));
                        }
 
     break;
 
   case 229:
 #line 1233 "perly.y"
-    { (yyval.opval) = newSVREF((ps[-3].val.opval)); }
+                        { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
+                           op_append_elem(OP_LIST, (ps[0].val.opval), scalar((ps[-1].val.opval))));
+                       }
 
     break;
 
   case 230:
-#line 1235 "perly.y"
-    { (yyval.opval) = newAVREF((ps[-3].val.opval)); }
+#line 1237 "perly.y"
+                        { (yyval.opval) = newSVREF((ps[-3].val.opval)); }
 
     break;
 
   case 231:
-#line 1237 "perly.y"
-    { (yyval.opval) = newHVREF((ps[-3].val.opval)); }
+#line 1239 "perly.y"
+                        { (yyval.opval) = newAVREF((ps[-3].val.opval)); }
 
     break;
 
   case 232:
-#line 1239 "perly.y"
-    { (yyval.opval) = newUNOP(OP_ENTERSUB, 0,
-                                      scalar(newCVREF((ps[-1].val.ival),(ps[-3].val.opval)))); }
+#line 1241 "perly.y"
+                        { (yyval.opval) = newHVREF((ps[-3].val.opval)); }
 
     break;
 
   case 233:
-#line 1242 "perly.y"
-    { (yyval.opval) = newGVREF(0,(ps[-3].val.opval)); }
+#line 1243 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_ENTERSUB, 0,
+                                      scalar(newCVREF((ps[-1].val.ival),(ps[-3].val.opval)))); }
 
     break;
 
   case 234:
-#line 1244 "perly.y"
-    { (yyval.opval) = newOP((ps[0].val.ival), OPf_SPECIAL);
-                           PL_hints |= HINT_BLOCK_SCOPE; }
+#line 1246 "perly.y"
+                        { (yyval.opval) = newGVREF(0,(ps[-3].val.opval)); }
 
     break;
 
   case 235:
-#line 1247 "perly.y"
-    { (yyval.opval) = newLOOPEX((ps[-1].val.ival),(ps[0].val.opval)); }
+#line 1248 "perly.y"
+                        { (yyval.opval) = newOP((ps[0].val.ival), OPf_SPECIAL);
+                           PL_hints |= HINT_BLOCK_SCOPE; }
 
     break;
 
   case 236:
-#line 1249 "perly.y"
-    { (yyval.opval) = newUNOP(OP_NOT, 0, scalar((ps[0].val.opval))); }
+#line 1251 "perly.y"
+                        { (yyval.opval) = newLOOPEX((ps[-1].val.ival),(ps[0].val.opval)); }
 
     break;
 
   case 237:
-#line 1251 "perly.y"
-    { (yyval.opval) = newOP((ps[0].val.ival), 0); }
+#line 1253 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_NOT, 0, scalar((ps[0].val.opval))); }
 
     break;
 
   case 238:
-#line 1253 "perly.y"
-    { (yyval.opval) = newUNOP((ps[-1].val.ival), 0, (ps[0].val.opval)); }
+#line 1255 "perly.y"
+                        { (yyval.opval) = newOP((ps[0].val.ival), 0); }
 
     break;
 
   case 239:
-#line 1255 "perly.y"
-    { (yyval.opval) = newUNOP((ps[-1].val.ival), 0, (ps[0].val.opval)); }
+#line 1257 "perly.y"
+                        { (yyval.opval) = newUNOP((ps[-1].val.ival), 0, (ps[0].val.opval)); }
 
     break;
 
   case 240:
-#line 1257 "perly.y"
-    { (yyval.opval) = newOP(OP_REQUIRE, (ps[0].val.ival) ? OPf_SPECIAL : 0); }
+#line 1259 "perly.y"
+                        { (yyval.opval) = newUNOP((ps[-1].val.ival), 0, (ps[0].val.opval)); }
 
     break;
 
   case 241:
-#line 1259 "perly.y"
-    { (yyval.opval) = newUNOP(OP_REQUIRE, (ps[-1].val.ival) ? OPf_SPECIAL : 0, (ps[0].val.opval)); }
+#line 1261 "perly.y"
+                        { (yyval.opval) = newOP(OP_REQUIRE, (ps[0].val.ival) ? OPf_SPECIAL : 0); }
 
     break;
 
   case 242:
-#line 1261 "perly.y"
-    { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar((ps[0].val.opval))); }
+#line 1263 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_REQUIRE, (ps[-1].val.ival) ? OPf_SPECIAL : 0, (ps[0].val.opval)); }
 
     break;
 
   case 243:
-#line 1263 "perly.y"
-    { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
-                           op_append_elem(OP_LIST, (ps[0].val.opval), scalar((ps[-1].val.opval)))); }
+#line 1265 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar((ps[0].val.opval))); }
 
     break;
 
   case 244:
-#line 1266 "perly.y"
-    { (yyval.opval) = newOP((ps[0].val.ival), 0); }
+#line 1267 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED,
+                           op_append_elem(OP_LIST, (ps[0].val.opval), scalar((ps[-1].val.opval)))); }
 
     break;
 
   case 245:
-#line 1268 "perly.y"
-    { (yyval.opval) = newOP((ps[-2].val.ival), 0);}
+#line 1270 "perly.y"
+                        { (yyval.opval) = newOP((ps[0].val.ival), 0); }
 
     break;
 
   case 246:
-#line 1270 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 1272 "perly.y"
+                        { (yyval.opval) = newOP((ps[-2].val.ival), 0);}
 
     break;
 
   case 247:
-#line 1272 "perly.y"
-    { (yyval.opval) = (ps[-2].val.opval); }
+#line 1274 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 248:
-#line 1274 "perly.y"
-    { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar((ps[0].val.opval))); }
+#line 1276 "perly.y"
+                        { (yyval.opval) = (ps[-2].val.opval); }
 
     break;
 
   case 249:
-#line 1276 "perly.y"
-    { (yyval.opval) = ((ps[-2].val.ival) == OP_NOT)
-                          ? newUNOP((ps[-2].val.ival), 0, newSVOP(OP_CONST, 0, newSViv(0)))
-                          : newOP((ps[-2].val.ival), OPf_SPECIAL); }
+#line 1278 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar((ps[0].val.opval))); }
 
     break;
 
   case 250:
 #line 1280 "perly.y"
-    { (yyval.opval) = newUNOP((ps[-3].val.ival), 0, (ps[-1].val.opval)); }
+                        { (yyval.opval) = ((ps[-2].val.ival) == OP_NOT)
+                          ? newUNOP((ps[-2].val.ival), 0, newSVOP(OP_CONST, 0, newSViv(0)))
+                          : newOP((ps[-2].val.ival), OPf_SPECIAL); }
 
     break;
 
   case 251:
-#line 1282 "perly.y"
-    {
+#line 1284 "perly.y"
+                        { (yyval.opval) = newUNOP((ps[-3].val.ival), 0, (ps[-1].val.opval)); }
+
+    break;
+
+  case 252:
+#line 1286 "perly.y"
+                        {
                            if (   (ps[0].val.opval)->op_type != OP_TRANS
                                && (ps[0].val.opval)->op_type != OP_TRANSR
                                && (((PMOP*)(ps[0].val.opval))->op_pmflags & PMf_HAS_CV))
@@ -1939,196 +1939,197 @@ case 2:
 
     break;
 
-  case 252:
-#line 1293 "perly.y"
-    { (yyval.opval) = pmruntime((ps[-5].val.opval), (ps[-2].val.opval), (ps[-1].val.opval), 1, (ps[-4].val.ival)); }
-
-    break;
-
-  case 256:
-#line 1301 "perly.y"
-    { (yyval.opval) = my_attrs((ps[-1].val.opval),(ps[0].val.opval)); }
+  case 253:
+#line 1297 "perly.y"
+                        { (yyval.opval) = pmruntime((ps[-5].val.opval), (ps[-2].val.opval), (ps[-1].val.opval), 1, (ps[-4].val.ival)); }
 
     break;
 
   case 257:
-#line 1303 "perly.y"
-    { (yyval.opval) = localize((ps[0].val.opval),1); }
+#line 1305 "perly.y"
+                        { (yyval.opval) = my_attrs((ps[-1].val.opval),(ps[0].val.opval)); }
 
     break;
 
   case 258:
-#line 1305 "perly.y"
-    { (yyval.opval) = newUNOP(OP_REFGEN, 0, my_attrs((ps[-1].val.opval),(ps[0].val.opval))); }
+#line 1307 "perly.y"
+                        { (yyval.opval) = localize((ps[0].val.opval),1); }
 
     break;
 
   case 259:
-#line 1310 "perly.y"
-    { (yyval.opval) = sawparens((ps[-1].val.opval)); }
+#line 1309 "perly.y"
+                        { (yyval.opval) = newUNOP(OP_REFGEN, 0, my_attrs((ps[-1].val.opval),(ps[0].val.opval))); }
 
     break;
 
   case 260:
-#line 1312 "perly.y"
-    { (yyval.opval) = sawparens(newNULLLIST()); }
+#line 1314 "perly.y"
+                        { (yyval.opval) = sawparens((ps[-1].val.opval)); }
 
     break;
 
   case 261:
-#line 1315 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 1316 "perly.y"
+                        { (yyval.opval) = sawparens(newNULLLIST()); }
 
     break;
 
   case 262:
-#line 1317 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 1319 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 263:
-#line 1319 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 1321 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 264:
-#line 1324 "perly.y"
-    { (yyval.opval) = NULL; }
+#line 1323 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 265:
-#line 1326 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 1328 "perly.y"
+                        { (yyval.opval) = NULL; }
 
     break;
 
   case 266:
 #line 1330 "perly.y"
-    { (yyval.opval) = NULL; }
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 267:
-#line 1332 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 1334 "perly.y"
+                        { (yyval.opval) = NULL; }
 
     break;
 
   case 268:
 #line 1336 "perly.y"
-    { (yyval.opval) = NULL; }
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
   case 269:
-#line 1338 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 1340 "perly.y"
+                        { (yyval.opval) = NULL; }
 
     break;
 
   case 270:
-#line 1344 "perly.y"
-    { parser->in_my = 0; (yyval.opval) = my((ps[0].val.opval)); }
+#line 1342 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
 
     break;
 
-  case 278:
-#line 1361 "perly.y"
-    { (yyval.opval) = newCVREF((ps[-1].val.ival),(ps[0].val.opval)); }
+  case 271:
+#line 1348 "perly.y"
+                        { parser->in_my = 0; (yyval.opval) = my((ps[0].val.opval)); }
 
     break;
 
   case 279:
 #line 1365 "perly.y"
-    { (yyval.opval) = newSVREF((ps[0].val.opval)); }
+                        { (yyval.opval) = newCVREF((ps[-1].val.ival),(ps[0].val.opval)); }
 
     break;
 
   case 280:
 #line 1369 "perly.y"
-    { (yyval.opval) = newAVREF((ps[0].val.opval));
-                         if ((yyval.opval)) (yyval.opval)->op_private |= (ps[-1].val.ival);
-                       }
+                        { (yyval.opval) = newSVREF((ps[0].val.opval)); }
 
     break;
 
   case 281:
-#line 1375 "perly.y"
-    { (yyval.opval) = newHVREF((ps[0].val.opval));
+#line 1373 "perly.y"
+                        { (yyval.opval) = newAVREF((ps[0].val.opval));
                          if ((yyval.opval)) (yyval.opval)->op_private |= (ps[-1].val.ival);
                        }
 
     break;
 
   case 282:
-#line 1381 "perly.y"
-    { (yyval.opval) = newAVREF((ps[0].val.opval)); }
+#line 1379 "perly.y"
+                        { (yyval.opval) = newHVREF((ps[0].val.opval));
+                         if ((yyval.opval)) (yyval.opval)->op_private |= (ps[-1].val.ival);
+                       }
 
     break;
 
   case 283:
-#line 1383 "perly.y"
-    { (yyval.opval) = newAVREF((ps[-3].val.opval)); }
+#line 1385 "perly.y"
+                        { (yyval.opval) = newAVREF((ps[0].val.opval)); }
 
     break;
 
   case 284:
 #line 1387 "perly.y"
-    { (yyval.opval) = newGVREF(0,(ps[0].val.opval)); }
+                        { (yyval.opval) = newAVREF((ps[-3].val.opval)); }
 
     break;
 
-  case 286:
-#line 1392 "perly.y"
-    { (yyval.opval) = newAVREF((ps[-2].val.opval)); }
+  case 285:
+#line 1391 "perly.y"
+                        { (yyval.opval) = newGVREF(0,(ps[0].val.opval)); }
 
     break;
 
-  case 288:
-#line 1397 "perly.y"
-    { (yyval.opval) = newHVREF((ps[-2].val.opval)); }
+  case 287:
+#line 1396 "perly.y"
+                        { (yyval.opval) = newAVREF((ps[-2].val.opval)); }
 
     break;
 
-  case 290:
-#line 1402 "perly.y"
-    { (yyval.opval) = newGVREF(0,(ps[-2].val.opval)); }
+  case 289:
+#line 1401 "perly.y"
+                        { (yyval.opval) = newHVREF((ps[-2].val.opval)); }
 
     break;
 
   case 291:
-#line 1407 "perly.y"
-    { (yyval.opval) = scalar((ps[0].val.opval)); }
+#line 1406 "perly.y"
+                        { (yyval.opval) = newGVREF(0,(ps[-2].val.opval)); }
 
     break;
 
   case 292:
-#line 1409 "perly.y"
-    { (yyval.opval) = scalar((ps[0].val.opval)); }
+#line 1411 "perly.y"
+                        { (yyval.opval) = scalar((ps[0].val.opval)); }
 
     break;
 
   case 293:
-#line 1411 "perly.y"
-    { (yyval.opval) = op_scope((ps[0].val.opval)); }
+#line 1413 "perly.y"
+                        { (yyval.opval) = scalar((ps[0].val.opval)); }
 
     break;
 
   case 294:
-#line 1414 "perly.y"
-    { (yyval.opval) = (ps[0].val.opval); }
+#line 1415 "perly.y"
+                        { (yyval.opval) = op_scope((ps[0].val.opval)); }
 
     break;
 
+  case 295:
+#line 1418 "perly.y"
+                        { (yyval.opval) = (ps[0].val.opval); }
+
+    break;
+
+
 
 
       default: break;
     
 
 /* Generated from:
- * f83d884147747f2d8f5a62eebc4ccd07d71b6b34e5ba1a8d7559526ad864dc97 perly.y
- * 01ce33b49f9f04b8d3112b7f042cde113a7d29763a846e870f9766072a5bc614 regen_perly.pl
+ * cb0b53384d9fa75068c8e30d8fe9016dec2e65e0a5c16ce6479563d6b41626d6 perly.y
+ * acf1cbfd2545faeaaa58b1cf0cf9d7f98b5be0752eb7a54528ef904a9e2e1ca7 regen_perly.pl
  * ex: set ro: */
diff --git a/perly.c b/perly.c
index 0913719..ad79c49 100644 (file)
--- a/perly.c
+++ b/perly.c
@@ -297,7 +297,7 @@ Perl_yyparse (pTHX_ int gramtype)
 
     /* initialise state for this parse */
     parser->yychar = gramtype;
-    yytoken = YYTRANSLATE(NATIVE_TO_UNI(parser->yychar));
+    yytoken = YYTRANSLATE((int)NATIVE_TO_UNI(parser->yychar));
 
     parser->yyerrstatus = 0;
     parser->yylen = 0;
@@ -369,11 +369,11 @@ Perl_yyparse (pTHX_ int gramtype)
                  * characters in that range, but all tokens it returns are
                  * either 0, or above 255.  There could be a problem if NULs
                  * weren't 0, or were ever returned as raw chars by yylex() */
-                yytoken = YYTRANSLATE(NATIVE_TO_UNI(parser->yychar));
+                yytoken = YYTRANSLATE((int)NATIVE_TO_UNI(parser->yychar));
             }
 
             /* make sure no-one's changed yychar since the last call to yylex */
-            assert(yytoken == YYTRANSLATE(NATIVE_TO_UNI(parser->yychar)));
+            assert(yytoken == YYTRANSLATE((int)NATIVE_TO_UNI(parser->yychar)));
             YYDSYMPRINTF("lookahead token is", yytoken, &parser->yylval);
 
 
diff --git a/perly.h b/perly.h
index 0cbbf3b..1bc9d63 100644 (file)
--- a/perly.h
+++ b/perly.h
@@ -4,14 +4,14 @@
    Any changes made here will be lost!
  */
 
-#define PERL_BISON_VERSION  30003
+#define PERL_BISON_VERSION  30005
 
 #ifdef PERL_CORE
-/* A Bison parser, made by GNU Bison 3.3.2.  */
+/* A Bison parser, made by GNU Bison 3.5.1.  */
 
 /* Bison interface for Yacc-like parsers in C
 
-   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
    Inc.
 
    This program is free software: you can redistribute it and/or modify
@@ -172,7 +172,6 @@ S_is_opval_token(int type) {
 #endif /* PERL_IN_TOKE_C */
 #endif /* PERL_CORE */
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-
 union YYSTYPE
 {
 
@@ -182,8 +181,8 @@ union YYSTYPE
     OP *opval;
     GV *gvval;
 
-};
 
+};
 typedef union YYSTYPE YYSTYPE;
 # define YYSTYPE_IS_TRIVIAL 1
 # define YYSTYPE_IS_DECLARED 1
@@ -195,6 +194,6 @@ int yyparse (void);
 
 
 /* Generated from:
- * f83d884147747f2d8f5a62eebc4ccd07d71b6b34e5ba1a8d7559526ad864dc97 perly.y
- * 01ce33b49f9f04b8d3112b7f042cde113a7d29763a846e870f9766072a5bc614 regen_perly.pl
+ * cb0b53384d9fa75068c8e30d8fe9016dec2e65e0a5c16ce6479563d6b41626d6 perly.y
+ * acf1cbfd2545faeaaa58b1cf0cf9d7f98b5be0752eb7a54528ef904a9e2e1ca7 regen_perly.pl
  * ex: set ro: */
index 0154f44..42ac1f6 100644 (file)
--- a/perly.tab
+++ b/perly.tab
@@ -6,28 +6,29 @@
 
 #define YYFINAL  16
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   3348
+#define YYLAST   3303
 
 /* YYNTOKENS -- Number of terminals.  */
 #define YYNTOKENS  112
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  96
+#define YYNNTS  97
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  294
+#define YYNRULES  295
 /* YYNSTATES -- Number of states.  */
-#define YYNSTATES  572
+#define YYNSTATES  573
 
 #define YYUNDEFTOK  2
 #define YYMAXUTOK   344
 
+
 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
    as returned by yylex, with out-of-bounds checking.  */
 #define YYTRANSLATE(YYX)                                                \
-  ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+  (0 <= (YYX) && (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
 
 /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
    as returned by yylex.  */
-static const yytype_uint8 yytranslate[] =
+static const yytype_int8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -68,38 +69,38 @@ static const yytype_uint8 yytranslate[] =
 
 #if YYDEBUG
   /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
-static const yytype_uint16 yyrline[] =
+static const yytype_int16 yyrline[] =
 {
-       0,   121,   121,   120,   132,   131,   142,   141,   155,   154,
-     168,   167,   181,   180,   191,   190,   203,   211,   219,   223,
-     231,   237,   238,   248,   249,   258,   262,   266,   273,   283,
-     285,   298,   295,   319,   314,   335,   343,   342,   351,   357,
-     363,   368,   370,   372,   379,   387,   389,   386,   406,   411,
-     418,   417,   432,   440,   446,   453,   452,   467,   471,   476,
-     484,   502,   503,   508,   510,   512,   514,   516,   518,   520,
-     523,   529,   530,   535,   546,   547,   553,   559,   560,   565,
-     568,   572,   577,   581,   585,   586,   590,   596,   601,   606,
-     607,   612,   613,   618,   619,   621,   626,   628,   640,   641,
-     646,   648,   652,   672,   673,   675,   681,   746,   748,   754,
-     756,   760,   766,   767,   772,   773,   777,   781,   781,   849,
-     850,   855,   866,   867,   870,   881,   883,   885,   887,   891,
-     893,   898,   902,   906,   910,   916,   921,   927,   933,   935,
-     937,   940,   939,   950,   951,   955,   959,   962,   967,   972,
-     975,   979,   983,   989,   997,  1004,  1010,  1012,  1014,  1019,
-    1021,  1023,  1028,  1030,  1032,  1034,  1036,  1038,  1040,  1042,
-    1044,  1046,  1048,  1052,  1054,  1056,  1058,  1062,  1064,  1068,
-    1070,  1072,  1074,  1078,  1080,  1085,  1087,  1090,  1092,  1094,
-    1097,  1100,  1111,  1114,  1121,  1123,  1125,  1127,  1129,  1132,
-    1138,  1140,  1144,  1145,  1146,  1147,  1148,  1150,  1152,  1154,
-    1156,  1158,  1160,  1162,  1164,  1166,  1168,  1170,  1172,  1174,
-    1176,  1186,  1196,  1206,  1216,  1218,  1220,  1223,  1228,  1232,
-    1234,  1236,  1238,  1241,  1243,  1246,  1248,  1250,  1252,  1254,
-    1256,  1258,  1260,  1262,  1265,  1267,  1269,  1271,  1273,  1275,
-    1279,  1282,  1281,  1294,  1295,  1296,  1300,  1302,  1304,  1309,
-    1311,  1314,  1316,  1318,  1323,  1325,  1330,  1331,  1336,  1337,
-    1343,  1347,  1348,  1349,  1352,  1353,  1356,  1357,  1360,  1364,
-    1368,  1374,  1380,  1382,  1386,  1390,  1391,  1395,  1396,  1400,
-    1401,  1406,  1408,  1410,  1413
+       0,   122,   122,   121,   133,   132,   143,   142,   156,   155,
+     169,   168,   182,   181,   192,   191,   204,   212,   220,   224,
+     232,   238,   239,   249,   250,   259,   263,   267,   274,   284,
+     286,   299,   296,   320,   315,   336,   344,   343,   352,   358,
+     364,   369,   371,   373,   380,   388,   390,   387,   407,   412,
+     419,   418,   433,   441,   447,   454,   453,   468,   472,   477,
+     485,   503,   504,   508,   512,   514,   516,   518,   520,   522,
+     524,   527,   533,   534,   539,   550,   551,   557,   563,   564,
+     569,   572,   576,   581,   585,   589,   590,   594,   600,   605,
+     610,   611,   616,   617,   622,   623,   625,   630,   632,   644,
+     645,   650,   652,   656,   676,   677,   679,   685,   750,   752,
+     758,   760,   764,   770,   771,   776,   777,   781,   785,   785,
+     853,   854,   859,   870,   871,   874,   885,   887,   889,   891,
+     895,   897,   902,   906,   910,   914,   920,   925,   931,   937,
+     939,   941,   944,   943,   954,   955,   959,   963,   966,   971,
+     976,   979,   983,   987,   993,  1001,  1008,  1014,  1016,  1018,
+    1023,  1025,  1027,  1032,  1034,  1036,  1038,  1040,  1042,  1044,
+    1046,  1048,  1050,  1052,  1056,  1058,  1060,  1062,  1066,  1068,
+    1072,  1074,  1076,  1078,  1082,  1084,  1089,  1091,  1094,  1096,
+    1098,  1101,  1104,  1115,  1118,  1125,  1127,  1129,  1131,  1133,
+    1136,  1142,  1144,  1148,  1149,  1150,  1151,  1152,  1154,  1156,
+    1158,  1160,  1162,  1164,  1166,  1168,  1170,  1172,  1174,  1176,
+    1178,  1180,  1190,  1200,  1210,  1220,  1222,  1224,  1227,  1232,
+    1236,  1238,  1240,  1242,  1245,  1247,  1250,  1252,  1254,  1256,
+    1258,  1260,  1262,  1264,  1266,  1269,  1271,  1273,  1275,  1277,
+    1279,  1283,  1286,  1285,  1298,  1299,  1300,  1304,  1306,  1308,
+    1313,  1315,  1318,  1320,  1322,  1327,  1329,  1334,  1335,  1340,
+    1341,  1347,  1351,  1352,  1353,  1356,  1357,  1360,  1361,  1364,
+    1368,  1372,  1378,  1384,  1386,  1390,  1394,  1395,  1399,  1400,
+    1404,  1405,  1410,  1412,  1414,  1417
 };
 #endif
 
@@ -127,10 +128,10 @@ static const char *const yytname[] =
   "grammar", "@1", "@2", "@3", "@4", "@5", "@6", "@7", "block",
   "formblock", "remember", "mblock", "mremember", "stmtseq", "formstmtseq",
   "fullstmt", "labfullstmt", "barestmt", "$@8", "$@9", "$@10", "$@11",
-  "$@12", "@13", "$@14", "formline", "formarg", "sideff", "else", "cont",
-  "mintro", "nexpr", "texpr", "iexpr", "mexpr", "mnexpr", "formname",
-  "startsub", "startanonsub", "startformsub", "subname", "proto",
-  "subattrlist", "myattrlist", "sigvarname", "sigslurpsigil",
+  "$@12", "@13", "$@14", "formline", "formarg", "condition", "sideff",
+  "else", "cont", "mintro", "nexpr", "texpr", "iexpr", "mexpr", "mnexpr",
+  "formname", "startsub", "startanonsub", "startformsub", "subname",
+  "proto", "subattrlist", "myattrlist", "sigvarname", "sigslurpsigil",
   "sigslurpelem", "sigdefault", "sigscalarelem", "sigelem", "siglist",
   "siglistornull", "optsubsignature", "subsignature", "subsigguts", "$@15",
   "optsubbody", "subbody", "optsigsubbody", "sigsubbody", "expr",
@@ -146,7 +147,7 @@ static const char *const yytname[] =
 # ifdef YYPRINT
 /* YYTOKNUM[NUM] -- (External) token number corresponding to the
    (internal) symbol number NUM (which must be that of a token).  */
-static const yytype_uint16 yytoknum[] =
+static const yytype_int16 yytoknum[] =
 {
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
      123,   125,    91,    93,    45,    43,    64,    37,    38,    61,
@@ -163,173 +164,173 @@ static const yytype_uint16 yytoknum[] =
 };
 # endif
 
-#define YYPACT_NINF -485
+#define YYPACT_NINF (-456)
 
-#define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-485)))
+#define yypact_value_is_default(Yyn) \
+  ((Yyn) == YYPACT_NINF)
 
-#define YYTABLE_NINF -290
+#define YYTABLE_NINF (-291)
 
-#define yytable_value_is_error(Yytable_value) \
-  (!!((Yytable_value) == (-290)))
+#define yytable_value_is_error(Yyn) \
+  ((Yyn) == YYTABLE_NINF)
 
   /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
      STATE-NUM.  */
 static const yytype_int16 yypact[] =
 {
-     739,  -485,  -485,  -485,  -485,  -485,  -485,  -485,    28,  -485,
-    2976,    32,  1582,  1481,  -485,  -485,  -485,  -485,  2085,  2976,
-    2976,     6,     6,     6,  -485,     6,     6,  -485,  -485,    50,
-     -31,  -485,  2976,  -485,  -485,  -485,  -485,  2976,   -13,    20,
-     -33,  1986,  1885,     6,  1986,  2184,     4,  2976,    83,  2976,
-    2976,  2976,  2976,  2976,  2976,  2976,  2283,     6,     6,    41,
-      -7,  -485,    14,  -485,   -34,    -1,   -20,    22,  -485,  -485,
-    -485,  3151,  -485,  -485,    29,    56,    95,   102,  -485,   153,
-     247,   254,   157,  -485,  -485,  -485,  -485,  -485,     4,     4,
-     132,  -485,    79,   100,   119,   130,   174,   146,   154,    32,
-     152,  -485,   217,  -485,   160,  1984,  1481,  -485,  -485,  -485,
-     672,  -485,    30,   774,  -485,   111,   142,   142,  -485,  -485,
-    -485,  -485,  -485,  -485,  -485,  2976,   172,   207,  2976,   176,
-     430,    32,   261,   216,  3151,   202,  2382,  2976,  1885,  -485,
-     430,   572,    -7,  -485,   476,  2976,  -485,  -485,   430,   299,
-     197,  -485,  -485,  2976,   430,  3075,  2481,   242,  -485,  -485,
-    -485,   430,    -7,   142,   142,   142,    57,    57,   306,   267,
-    -485,  -485,  2976,  2976,  2976,  2976,  2976,  2976,  2580,  -485,
-    -485,  2976,  -485,  -485,  2976,  2976,  2976,  2976,  2976,  2976,
-    2976,  2976,  2976,  2976,  2976,  2976,  2976,  2976,  2976,  2976,
-    2976,  2976,  -485,  -485,  -485,    75,  2679,  2976,  2976,  2976,
-    2976,  2976,  2976,  2976,  -485,   307,  -485,  -485,   311,  -485,
-    -485,  -485,  -485,  -485,   224,    36,  -485,  -485,   226,  -485,
-    -485,  -485,  -485,    32,  -485,  -485,  2976,  2976,  2976,  2976,
-    2976,  2976,  -485,  -485,  -485,  -485,  -485,   320,   320,  -485,
-    -485,  -485,   273,  -485,  -485,  -485,  2976,  2976,   118,  -485,
-    -485,  -485,   216,   330,  -485,  -485,  -485,   331,   284,   260,
-    2976,    -7,  -485,   348,  -485,  2778,   142,   242,    33,    55,
-      67,  -485,   342,   344,  -485,  2976,   357,   294,   294,  -485,
-    3151,   249,   133,  -485,   433,   430,   363,  3243,   504,   329,
-    3151,  3105,  1667,  1667,  1767,  1867,   538,   363,   363,   430,
-     430,   301,   142,   142,  2976,  2976,   271,   272,   274,  -485,
-     278,  2877,    23,   279,   270,  -485,  -485,   470,   253,   136,
-     302,   158,   364,   162,   407,   875,  -485,   372,  -485,  -485,
-       1,   375,  2976,  2976,  2976,  2976,  -485,   292,  -485,  -485,
-     305,  -485,  -485,  -485,  -485,  1683,    34,  -485,  2976,  2976,
-    -485,    41,  -485,    41,    41,    41,    41,    41,  -485,   332,
-     332,    30,   308,   -39,  -485,  2976,  -485,  -485,   309,  -485,
-    -485,  -485,  -485,   512,  -485,     5,   516,  -485,  -485,  -485,
-     178,  2976,   416,  -485,  -485,  2976,   418,   193,  -485,  -485,
-    -485,  -485,  -485,   519,  -485,  -485,  2976,  -485,   436,  -485,
-     438,  -485,   440,  -485,   447,  -485,  -485,  -485,   261,   216,
-    -485,  -485,   439,   353,    41,   358,   368,    41,   369,   356,
-    -485,  -485,  -485,  -485,   374,   373,   401,  -485,  2976,   381,
-     387,  2976,  -485,  -485,  -485,  -485,  2976,   423,  -485,   489,
-    -485,  -485,   490,  -485,  -485,    19,  -485,   239,  -485,  3197,
-     492,  -485,  -485,   398,  -485,  -485,  -485,  -485,   397,   216,
-     404,  -485,  2976,  -485,  -485,   496,   496,  2976,  2976,   496,
-    -485,   406,   408,   496,   496,  3151,    41,  -485,  -485,   410,
-    -485,  -485,  -485,  -485,   445,   414,  -485,  -485,  -485,  -485,
-     420,   496,   496,  -485,    37,    37,   434,   435,   217,  2976,
-    2976,   496,  -485,  -485,   976,  -485,  1077,  -485,  -485,  -485,
-    -485,  1178,  -485,   217,   217,  -485,   496,   442,  -485,  -485,
-     496,   496,  -485,   437,   449,   217,  -485,  -485,   -10,  -485,
-    -485,  -485,  1279,  -485,  2976,   217,   217,  -485,   496,  -485,
-     472,   531,  -485,  -485,   465,  -485,  -485,  -485,   217,  -485,
-    -485,  -485,   496,  1784,  -485,  1380,    37,   467,  -485,  -485,
-     496,  -485
+     842,  -456,  -456,  -456,  -456,  -456,  -456,  -456,    57,  -456,
+    2977,    17,  1583,  1482,  -456,  -456,  -456,  -456,  2086,  2977,
+    2977,     5,     5,     5,  -456,     5,     5,  -456,  -456,    50,
+     -13,  -456,  2977,  -456,  -456,  -456,  -456,  2977,    -7,    32,
+     -24,  1987,  1886,     5,  1987,  2185,     4,  2977,     0,  2977,
+    2977,  2977,  2977,  2977,  2977,  2977,  2284,     5,     5,   -11,
+     -10,  -456,    -1,  -456,   -41,    52,   -43,    64,  -456,  -456,
+    -456,  3106,  -456,  -456,    60,    72,    89,   230,  -456,   176,
+     318,   359,   216,  -456,  -456,  -456,  -456,  -456,     4,     4,
+     157,  -456,   100,   134,   140,   150,   272,   169,   172,    17,
+     148,  -456,   217,  -456,   175,   437,  1482,  -456,  -456,  -456,
+     673,  -456,    16,   775,  -456,    55,   -30,   -30,  -456,  -456,
+    -456,  -456,  -456,  -456,  -456,  2977,   201,   236,  2977,   209,
+     431,    17,   292,   251,  3106,   237,  2383,  2977,  1886,  -456,
+     431,   573,   -10,  -456,   477,  2977,  -456,  -456,   431,   331,
+     197,  -456,  -456,  2977,   431,  3076,  2482,   278,  -456,  -456,
+    -456,   431,   -10,   -30,   -30,   -30,    58,    58,   341,   313,
+    -456,  -456,  2977,  2977,  2977,  2977,  2977,  2977,  2581,  -456,
+    -456,  2977,  -456,  -456,  2977,  2977,  2977,  2977,  2977,  2977,
+    2977,  2977,  2977,  2977,  2977,  2977,  2977,  2977,  2977,  2977,
+    2977,  2977,  -456,  -456,  -456,    75,  2680,  2977,  2977,  2977,
+    2977,  2977,  2977,  2977,  -456,   340,  -456,  -456,   344,  -456,
+    -456,  -456,  -456,  -456,   270,    36,  -456,  -456,   267,  -456,
+    -456,  -456,  -456,    17,  -456,  -456,  2977,  2977,  2977,  2977,
+    2977,  2977,  -456,  -456,  -456,  -456,  -456,   352,   352,  -456,
+    -456,  -456,   300,  -456,  -456,  -456,  2977,  2977,   111,  -456,
+    -456,  -456,   251,   358,  -456,  -456,  -456,   379,   309,   281,
+    2977,   -10,  -456,   391,  -456,  2779,   -30,   278,    67,   105,
+     256,  -456,   440,   377,  -456,  2977,   396,   333,   333,  -456,
+    3106,   204,   114,  -456,   471,   431,  1929,  3198,   652,   301,
+    3106,   360,  1668,  1668,  1768,  1868,   539,  1929,  1929,   431,
+     431,   659,   -30,   -30,  2977,  2977,   303,   305,   307,  -456,
+     308,  2878,     2,   310,   302,  -456,  -456,   513,   299,   133,
+     320,   136,   390,   158,   419,   876,  -456,   404,  -456,  -456,
+      -3,   405,  2977,  2977,  2977,  2977,  -456,   316,  -456,  -456,
+     322,  -456,  -456,  -456,  -456,  1684,    27,  -456,  2977,  2977,
+    -456,  -456,   -11,  -456,   -11,  -456,  -456,  -456,  -456,  -456,
+     349,   349,    16,   327,   -35,  -456,  2977,  -456,  -456,   328,
+    -456,  -456,  -456,  -456,   517,  -456,   109,   520,  -456,  -456,
+    -456,   168,  2977,   423,  -456,  -456,  2977,   434,   183,  -456,
+    -456,  -456,  -456,  -456,   530,  -456,  -456,  2977,  -456,   426,
+    -456,   427,  -456,   429,  -456,   447,  -456,  -456,  -456,   292,
+     251,  -456,  -456,   439,   363,   -11,   367,   369,   -11,   370,
+     371,  -456,  -456,  -456,  -456,   378,   386,   280,  -456,  2977,
+     394,   395,  2977,  -456,  -456,  -456,  -456,  2977,   449,  -456,
+     498,  -456,  -456,   519,  -456,  -456,   194,  -456,   242,  -456,
+    3152,   521,  -456,  -456,   435,  -456,  -456,  -456,  -456,   432,
+     251,   436,  -456,  2977,  -456,  -456,   542,   542,  2977,  2977,
+     542,  -456,   465,   450,   542,   542,  3106,   -11,  -456,  -456,
+     468,  -456,  -456,  -456,  -456,   503,   470,  -456,  -456,  -456,
+    -456,   476,   542,   542,  -456,    43,    43,   481,   486,   217,
+    2977,  2977,   542,  -456,  -456,   977,  -456,  1078,  -456,  -456,
+    -456,  -456,  1179,  -456,   217,   217,  -456,   542,   492,  -456,
+    -456,   542,   542,  -456,   494,   497,   217,  -456,  -456,    18,
+    -456,  -456,  -456,  1280,  -456,  2977,   217,   217,  -456,   542,
+    -456,   533,   585,  -456,  -456,   504,  -456,  -456,  -456,   217,
+    -456,  -456,  -456,   542,  1785,  -456,  1381,    43,   505,  -456,
+    -456,   542,  -456
 };
 
   /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
      Performed when YYTABLE does not specify something else to do.  Zero
      means the default is an error.  */
-static const yytype_uint16 yydefact[] =
+static const yytype_int16 yydefact[] =
 {
        0,     2,     4,     6,     8,    10,    12,    14,     0,    18,
-     266,     0,     0,     0,    21,   117,     1,    21,     0,     0,
-       0,     0,     0,     0,   253,     0,     0,   224,   251,   212,
-     246,   248,   242,    87,   255,    87,    87,   234,   244,     0,
-       0,   237,   264,     0,     0,     0,     0,     0,     0,   240,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,   267,
-     128,   254,   219,   202,   164,   173,   165,   179,   203,   204,
-     205,   131,   209,     5,   225,   214,   217,   216,   218,   215,
-       0,     0,     0,    18,     7,    63,    29,    88,     0,     0,
-       0,    86,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,    59,    74,     9,     0,    64,     0,    11,    26,    25,
-       0,    15,   112,     0,   195,     0,   185,   186,   291,   294,
-     293,   292,   280,   281,   278,   264,     0,     0,     0,     0,
-     243,     0,    91,    93,   235,     0,     0,   266,   266,   238,
-     239,   291,   265,   138,   292,     0,   282,   201,   200,     0,
-       0,    89,    90,   264,   210,     0,     0,   257,   261,   263,
-     262,   241,   236,   187,   188,   207,   192,   193,   213,     0,
-     279,   284,     0,     0,     0,   129,     0,     0,     0,   176,
-     175,     0,   182,   181,     0,     0,     0,     0,     0,     0,
+     267,     0,     0,     0,    21,   118,     1,    21,     0,     0,
+       0,     0,     0,     0,   254,     0,     0,   225,   252,   213,
+     247,   249,   243,    88,   256,    88,    88,   235,   245,     0,
+       0,   238,   265,     0,     0,     0,     0,     0,     0,   241,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,   268,
+     129,   255,   220,   203,   165,   174,   166,   180,   204,   205,
+     206,   132,   210,     5,   226,   215,   218,   217,   219,   216,
+       0,     0,     0,    18,     7,    64,    29,    89,     0,     0,
+       0,    87,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,    59,    75,     9,     0,    65,     0,    11,    26,    25,
+       0,    15,   113,     0,   196,     0,   186,   187,   292,   295,
+     294,   293,   281,   282,   279,   265,     0,     0,     0,     0,
+     244,     0,    92,    94,   236,     0,     0,   267,   267,   239,
+     240,   292,   266,   139,   293,     0,   283,   202,   201,     0,
+       0,    90,    91,   265,   211,     0,     0,   258,   262,   264,
+     263,   242,   237,   188,   189,   208,   193,   194,   214,     0,
+     280,   285,     0,     0,     0,   130,     0,     0,     0,   177,
+     176,     0,   183,   182,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,   189,   190,   191,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,    21,    85,    86,    86,     0,    36,
+       0,     0,   190,   191,   192,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,    21,    86,    87,    87,     0,    36,
       18,    18,    18,    18,    18,     0,    18,    18,     0,    18,
       18,    42,    58,     0,    54,    57,     0,     0,     0,     0,
-       0,     0,    28,    27,    22,   100,   101,    98,    98,   108,
-     107,   111,   113,   118,   194,   136,   266,     0,     0,   247,
-     141,    92,    93,    95,    18,   245,   249,     0,     0,     0,
-       0,   132,   197,     0,   228,     0,   208,     0,   214,   217,
-     216,   260,     0,    97,   256,     0,   211,   126,   127,   125,
-     130,     0,     0,   155,     0,   178,   184,   168,   161,   162,
-     159,     0,   170,   171,   169,   167,   166,   183,   180,   177,
-     174,   163,   172,   160,     0,     0,   286,   288,     0,   143,
-       0,     0,     0,   290,   135,   144,   226,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,    84,     0,    31,    33,
-       0,     0,    79,     0,     0,     0,   276,     0,   277,   274,
-       0,   275,   271,   272,   273,     0,     0,    18,     0,     0,
-      75,    67,    68,    81,    65,    66,    69,    70,    99,   103,
-     103,   109,     0,   268,   157,   264,    18,    94,   114,   199,
-     250,   140,   139,     0,   196,   213,     0,   258,   259,    96,
-       0,     0,     0,   148,   154,     0,     0,     0,   230,   231,
-     232,   283,   152,     0,   229,   233,   266,   227,     0,   146,
-       0,   220,     0,   221,     0,    16,    18,    30,    91,    93,
-      18,    35,     0,     0,    80,     0,     0,    82,     0,     0,
-     270,    18,    78,    83,     0,     0,    64,    50,     0,     0,
-       0,   104,   106,   102,   110,   137,     0,     0,   142,     0,
-     198,   117,     0,   115,   133,   211,   158,     0,   151,   206,
-       0,   147,   153,     0,   149,   222,   223,   145,     0,    93,
-      18,    55,   264,    76,    76,     0,     0,     0,     0,     0,
-      45,     0,     0,     0,     0,   105,   269,   252,    21,     0,
-      21,   156,   150,   134,     0,    18,   123,    34,   122,    21,
-       0,     0,     0,    20,    71,    71,     0,     0,    74,    79,
-       0,     0,    40,    41,     0,   116,     0,    23,   120,    32,
-     119,     0,    37,    74,    74,    21,     0,     0,    38,    39,
-       0,     0,    53,     0,     0,    74,   121,   124,     0,    56,
-      43,    44,     0,    72,     0,    74,    74,    46,     0,    49,
-      61,     0,    24,    19,     0,    48,    52,    76,    74,    21,
-      60,    17,     0,     0,    51,     0,    71,     0,    62,    73,
-       0,    47
+       0,     0,    28,    27,    22,   101,   102,    99,    99,   109,
+     108,   112,   114,   119,   195,   137,   267,     0,     0,   248,
+     142,    93,    94,    96,    18,   246,   250,     0,     0,     0,
+       0,   133,   198,     0,   229,     0,   209,     0,   215,   218,
+     217,   261,     0,    98,   257,     0,   212,   127,   128,   126,
+     131,     0,     0,   156,     0,   179,   185,   169,   162,   163,
+     160,     0,   171,   172,   170,   168,   167,   184,   181,   178,
+     175,   164,   173,   161,     0,     0,   287,   289,     0,   144,
+       0,     0,     0,   291,   136,   145,   227,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    85,     0,    31,    33,
+       0,     0,    80,     0,     0,     0,   277,     0,   278,   275,
+       0,   276,   272,   273,   274,     0,     0,    18,     0,     0,
+      76,    68,    63,    69,    82,    66,    67,    70,    71,   100,
+     104,   104,   110,     0,   269,   158,   265,    18,    95,   115,
+     200,   251,   141,   140,     0,   197,   214,     0,   259,   260,
+      97,     0,     0,     0,   149,   155,     0,     0,     0,   231,
+     232,   233,   284,   153,     0,   230,   234,   267,   228,     0,
+     147,     0,   221,     0,   222,     0,    16,    18,    30,    92,
+      94,    18,    35,     0,     0,    81,     0,     0,    83,     0,
+       0,   271,    18,    79,    84,     0,     0,    65,    50,     0,
+       0,     0,   105,   107,   103,   111,   138,     0,     0,   143,
+       0,   199,   118,     0,   116,   134,   212,   159,     0,   152,
+     207,     0,   148,   154,     0,   150,   223,   224,   146,     0,
+      94,    18,    55,   265,    77,    77,     0,     0,     0,     0,
+       0,    45,     0,     0,     0,     0,   106,   270,   253,    21,
+       0,    21,   157,   151,   135,     0,    18,   124,    34,   123,
+      21,     0,     0,     0,    20,    72,    72,     0,     0,    75,
+      80,     0,     0,    40,    41,     0,   117,     0,    23,   121,
+      32,   120,     0,    37,    75,    75,    21,     0,     0,    38,
+      39,     0,     0,    53,     0,     0,    75,   122,   125,     0,
+      56,    43,    44,     0,    73,     0,    75,    75,    46,     0,
+      49,    61,     0,    24,    19,     0,    48,    52,    77,    75,
+      21,    60,    17,     0,     0,    51,     0,    72,     0,    62,
+      74,     0,    47
 };
 
   /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-    -485,  -485,  -485,  -485,  -485,  -485,  -485,  -485,  -485,   298,
-    -485,    -5,  -109,  -485,   -17,  -485,   561,   471,     0,  -485,
-    -485,  -485,  -485,  -485,  -485,  -485,  -485,  -485,  -340,  -484,
-    -159,  -456,  -485,    74,   243,  -336,    39,  -485,   -44,   143,
-    -485,   161,   173,  -242,   324,   362,  -485,  -485,   234,  -485,
-     240,  -485,  -485,  -485,  -485,   168,  -485,  -485,   110,  -485,
-     165,    -8,   -37,  -485,  -485,  -485,  -485,  -485,  -485,  -485,
-    -485,  -485,  -485,  -485,  -485,   103,  -485,  -485,   457,  -124,
-    -130,  -485,  -485,   257,  -485,  -485,   399,    38,   -45,   -42,
-    -485,  -485,  -485,  -485,  -485,    13
+    -456,  -456,  -456,  -456,  -456,  -456,  -456,  -456,  -456,   228,
+    -456,    -5,  -139,  -456,   -17,  -456,   596,   506,    12,  -456,
+    -456,  -456,  -456,  -456,  -456,  -456,  -456,  -456,   266,  -341,
+    -448,  -192,  -455,  -456,   104,   277,  -337,    49,  -456,   -44,
+     159,  -456,   149,   202,  -243,   348,   389,  -456,  -456,   268,
+    -456,   273,  -456,  -456,  -456,  -456,   188,  -456,  -456,   152,
+    -456,   181,    -8,   -37,  -456,  -456,  -456,  -456,  -456,  -456,
+    -456,  -456,  -456,  -456,  -456,  -456,   103,  -456,  -456,   491,
+    -124,   -97,  -456,  -456,   312,  -456,  -456,   444,    38,   -45,
+     -42,  -456,  -456,  -456,  -456,  -456,    13
 };
 
   /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
       -1,     8,     9,    10,    11,    12,    13,    14,    15,   102,
-     417,   378,   504,   525,   110,   538,   244,   108,   109,   418,
-     419,   341,   509,   557,   481,   499,   552,   560,   104,   528,
-     234,   501,   433,   423,   362,   426,   435,   337,   219,   131,
-     215,   153,   262,   264,   284,   369,   248,   249,   442,   250,
-     251,   252,   253,   452,   453,   111,   112,   519,   450,   497,
-     379,   105,    60,    61,   375,   324,    62,    63,    64,    65,
-      66,    67,    68,    69,    70,    71,   127,    72,   157,   143,
-      73,   447,   429,   349,   350,   227,    74,    75,    76,    77,
-      78,    79,    80,    81,    82,   170
+     418,   379,   505,   526,   110,   539,   244,   108,   109,   419,
+     420,   341,   510,   558,   482,   500,   553,   561,   361,   104,
+     529,   234,   502,   434,   424,   363,   427,   436,   337,   219,
+     131,   215,   153,   262,   264,   284,   370,   248,   249,   443,
+     250,   251,   252,   253,   453,   454,   111,   112,   520,   451,
+     498,   380,   105,    60,    61,   376,   324,    62,    63,    64,
+      65,    66,    67,    68,    69,    70,    71,   127,    72,   157,
+     143,    73,   448,   430,   349,   350,   227,    74,    75,    76,
+      77,    78,    79,    80,    81,    82,   170
 };
 
   /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
@@ -337,105 +338,95 @@ static const yytype_int16 yydefgoto[] =
      number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_int16 yytable[] =
 {
-     113,   255,    59,   159,    17,   142,   160,   268,   269,   428,
-     115,   420,   103,   162,   550,   432,    83,   285,   502,   434,
-     376,   529,   439,   440,   176,   151,   177,   118,    16,   274,
-     152,   391,   119,    83,   122,   123,   124,   150,   125,   126,
-     137,   175,    83,   207,   118,   208,   245,   246,   169,   119,
-      21,    22,    21,    22,    23,   145,   146,   179,   180,   121,
-     121,   121,   128,   121,   121,  -285,   207,  -285,   208,   182,
-     183,   171,   446,   175,   138,  -260,   129,  -287,   214,  -287,
-     144,   121,   569,   526,   527,   314,   158,   315,   142,  -259,
-     181,   316,   317,   318,   135,   121,   121,   319,   551,    21,
-      22,   563,   482,  -261,   348,  -285,   243,  -285,   271,   421,
-     279,   184,  -287,   280,  -287,    57,   142,   172,   173,   174,
-     258,   178,   116,   117,   254,  -263,   372,   136,   267,    59,
-      59,   374,    57,   404,   228,   130,   206,  -262,   320,   247,
-     134,   506,   507,    57,   140,    57,   393,   148,   282,   409,
-     154,   270,   161,   218,   163,   164,   165,   166,   167,  -290,
-    -290,  -290,   205,  -289,   287,   288,   289,   213,   291,   292,
-     294,   411,   338,   339,   534,   413,   144,   470,   132,   133,
-     353,   155,   321,   354,   322,   323,   220,   172,   173,   174,
-     156,   456,    57,   278,   172,   173,   174,   335,   327,   328,
-     329,   330,   331,   332,   333,   334,   461,   221,   554,   172,
+     113,   255,    59,   159,    17,   142,   160,   421,   429,   176,
+     115,   177,    83,   162,   433,    83,    21,    22,   435,   377,
+     503,   440,   441,   118,   103,   151,   118,    83,   119,   274,
+     152,   119,   245,   246,   122,   123,   124,   150,   125,   126,
+     268,   269,   551,    21,    22,   175,   182,   183,   169,   137,
+     179,   180,    21,    22,    23,   145,   146,    16,   530,   121,
+     121,   121,   128,   121,   121,   172,   173,   174,   254,   201,
+     175,   171,   202,   203,   204,   205,   447,   207,   214,   208,
+     144,   121,   207,   138,   208,   314,   158,   315,   142,   527,
+     528,   316,   317,   318,   129,   121,   121,   319,   155,  -286,
+     135,  -286,   483,   564,   348,   422,   178,   156,   271,    57,
+     279,    57,   405,   280,    57,  -286,   142,  -286,   243,   570,
+     258,   285,   116,   117,   375,   247,   552,   394,   267,    59,
+      59,   172,   173,   174,   228,   130,    57,  -262,   320,   136,
+     134,   507,   508,   181,   140,    57,   410,   148,   282,   412,
+     154,   270,   161,   184,   163,   164,   165,   166,   167,   373,
+    -291,  -291,  -291,   205,   287,   288,   289,   206,   291,   292,
+     294,   414,   338,   339,   535,  -264,   144,   471,   218,  -261,
+     353,   457,   321,   354,   322,   323,  -290,   172,   173,   174,
+     172,   173,   174,   278,   132,   133,   462,   335,   327,   328,
+     329,   330,   331,   332,   333,   334,   392,   220,   555,   172,
      173,   174,   172,   173,   174,   342,   343,   344,   345,   347,
-     373,   355,   356,   432,   358,   359,   222,   495,   361,   363,
-     364,   365,   366,   367,   172,   173,   174,   223,   172,   173,
-     174,   201,   224,   325,   202,   203,   204,   205,    59,   216,
-     217,   448,   491,   229,   172,   173,   174,   209,   276,   210,
-     232,   230,   383,   352,   211,   233,   212,   386,   235,   172,
-     173,   174,   225,   172,   173,   174,   463,   390,   290,   256,
-     257,   226,   259,    57,   295,   261,   263,   296,   297,   298,
+     374,   355,   356,   433,   358,   359,   213,   496,   362,   364,
+     362,   362,   362,   362,   172,   173,   174,   216,   217,    84,
+    -288,   221,  -288,   325,   172,   173,   174,   222,    59,   120,
+     120,   120,   449,   120,   120,   492,   232,   223,   276,   172,
+     173,   174,   384,   352,  -260,   233,  -288,   387,  -288,   139,
+     120,   120,   147,   172,   173,   174,   229,   391,   290,   230,
+     172,   173,   174,   235,   295,   120,   120,   296,   297,   298,
      299,   300,   301,   302,   303,   304,   305,   306,   307,   308,
-     309,   310,   311,   312,   313,   273,   396,   397,   265,    84,
-     272,   353,   283,   403,   354,   172,   173,   174,   285,   120,
-     120,   120,   346,   120,   120,   172,   173,   174,   336,   172,
-     173,   174,   340,   357,   424,   363,   427,   427,   142,   139,
-     120,   120,   147,   172,   173,   174,   368,   436,   500,   532,
-     427,   427,   438,   371,   377,   120,   120,   392,   381,   384,
-     121,   408,   186,   187,   540,   541,   382,   505,   389,   391,
-     508,   449,   174,   286,   512,   513,   549,   406,   172,   173,
-     174,   398,   399,   457,   400,   430,   555,   556,   401,   405,
-     186,   416,   523,   524,   352,   200,   422,   231,    59,   564,
-     201,    57,   535,   202,   203,   204,   205,   172,   173,   174,
-     410,   468,   431,   441,   445,   471,   451,   543,   172,   173,
-     174,   545,   546,   200,   186,   187,   478,   458,   201,   260,
-     427,   202,   203,   204,   205,   142,   120,   380,   486,   558,
-     172,   173,   174,   236,   237,   238,   239,   464,   388,   465,
-     240,   466,   241,   566,   197,   198,   199,   200,   467,   473,
-     472,   571,   201,   477,   474,   202,   203,   204,   205,   427,
-     427,   514,   412,   516,   475,   476,  -214,   172,   173,   174,
-     479,   480,   521,   172,   173,   174,   207,   483,   208,  -214,
-     449,   186,   187,   484,   172,   173,   174,   487,   459,   488,
-     490,   424,   427,   492,   493,   494,   503,   -82,   542,   172,
-     173,   174,   496,   510,   511,   414,   515,   517,  -214,  -214,
-    -214,  -214,   518,   199,   200,  -214,   460,  -214,   522,   201,
-    -214,   360,   202,   203,   204,   205,   427,  -214,  -214,   394,
-     530,   531,   565,   559,   485,   547,   172,   173,   174,   544,
-    -214,   561,  -214,  -214,  -214,   548,  -214,  -214,  -214,  -214,
-    -214,  -214,  -214,  -214,  -214,  -214,  -214,  -214,  -214,  -214,
-    -214,   562,  -253,   570,   107,  -214,   407,   242,  -214,  -214,
-    -214,  -214,  -214,   533,  -214,  -253,   425,  -214,   172,   173,
-     174,   469,   172,   173,   174,   172,   173,   174,   200,   186,
-     187,   387,   567,   201,   443,   520,   202,   203,   204,   205,
-     370,   444,   277,   437,  -253,  -253,  -253,  -253,   454,   489,
-     120,  -253,   455,  -253,   351,   462,  -253,   195,   196,   197,
-     198,   199,   200,  -253,  -253,   498,     0,   201,     0,     0,
-     202,   203,   204,   205,     0,     0,  -253,     0,  -253,  -253,
-    -253,     0,  -253,  -253,  -253,  -253,  -253,  -253,  -253,  -253,
-    -253,  -253,  -253,  -253,  -253,  -253,  -253,     0,     0,     0,
-       0,  -253,   -13,    85,  -253,  -253,  -253,  -253,  -253,     0,
-    -253,     0,    83,  -253,    18,     0,    19,    20,    21,    22,
-      23,     0,     0,    24,    25,    26,    27,    28,     0,    29,
-      30,    31,    32,    33,    34,    86,   106,    87,    88,    89,
-      35,    36,    90,    91,    92,    93,    94,    95,     0,     0,
-       0,    96,    97,    98,    99,    37,     0,   100,    38,    39,
-      40,    41,    42,     0,     0,    43,    44,    45,    46,    47,
-      48,    49,     1,     2,     3,     4,     5,     6,     7,     0,
-       0,    50,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,    51,    52,     0,
-      53,     0,    54,    55,    -3,    85,     0,     0,     0,    56,
-     101,    57,    58,     0,    83,     0,    18,     0,    19,    20,
-      21,    22,    23,     0,     0,    24,    25,    26,    27,    28,
-       0,    29,    30,    31,    32,    33,    34,    86,   106,    87,
-      88,    89,    35,    36,    90,    91,    92,    93,    94,    95,
-       0,     0,     0,    96,    97,    98,    99,    37,     0,   100,
-      38,    39,    40,    41,    42,     0,     0,    43,    44,    45,
-      46,    47,    48,    49,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,    50,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,    51,
-      52,     0,    53,     0,    54,    55,    85,     0,     0,     0,
-       0,    56,   101,    57,    58,    83,   415,    18,     0,    19,
+     309,   310,   311,   312,   313,   273,   397,   398,   256,   257,
+     464,   353,   393,   404,   354,   259,   261,   533,   172,   173,
+     174,   263,   236,   237,   238,   239,  -263,   231,   209,   240,
+     210,   241,   541,   542,   425,   364,   428,   428,   506,   142,
+     224,   509,   272,   265,   550,   513,   514,   437,   283,   501,
+     428,   428,   439,   285,   556,   557,   172,   173,   174,   260,
+     121,   336,   186,   524,   525,   340,   120,   565,   346,   211,
+     225,   212,   450,   536,   357,   172,   173,   174,   369,   226,
+     372,    57,   378,   382,   458,   431,   -83,   383,   544,   172,
+     173,   174,   546,   547,   352,   200,   172,   173,   174,    59,
+     201,   390,   385,   202,   203,   204,   205,   409,   392,   407,
+     559,   174,   469,   399,   185,   400,   472,   401,   402,   286,
+     406,   186,   187,   417,   567,    57,   423,   479,   411,   432,
+     442,   428,   572,   446,   459,   452,   142,   465,   466,   487,
+     467,   188,   189,   396,   190,   191,   192,   193,   194,   195,
+     196,   197,   198,   199,   200,   172,   173,   174,   468,   201,
+     473,   360,   202,   203,   204,   205,   172,   173,   174,   474,
+     428,   428,   515,   475,   517,   476,   477,  -215,   478,   236,
+     237,   238,   239,   522,   480,   381,   240,   207,   241,   208,
+    -215,   450,   186,   187,   481,   172,   173,   174,   413,   460,
+     484,   485,   425,   428,   365,   366,   367,   368,   489,   543,
+     172,   173,   174,   172,   173,   174,   172,   173,   174,  -215,
+    -215,  -215,  -215,   488,   199,   200,  -215,   415,  -215,   491,
+     201,  -215,   493,   202,   203,   204,   205,   428,  -215,  -215,
+     495,   494,   461,   566,   497,   486,   389,   172,   173,   174,
+     120,  -215,   504,  -215,  -215,  -215,   512,  -215,  -215,  -215,
+    -215,  -215,  -215,  -215,  -215,  -215,  -215,  -215,  -215,  -215,
+    -215,  -215,   511,  -254,   516,   518,  -215,   395,   519,  -215,
+    -215,  -215,  -215,  -215,   523,  -215,  -254,   531,  -215,   172,
+     173,   174,   532,   172,   173,   174,   172,   173,   174,   545,
+     186,   187,   548,   549,   560,   562,   172,   173,   174,   107,
+     563,   571,   242,   568,   534,  -254,  -254,  -254,  -254,   408,
+     426,   470,  -254,   455,  -254,   388,   456,  -254,   195,   196,
+     197,   198,   199,   200,  -254,  -254,   463,   371,   201,   444,
+     490,   202,   203,   204,   205,   445,   277,  -254,   521,  -254,
+    -254,  -254,   499,  -254,  -254,  -254,  -254,  -254,  -254,  -254,
+    -254,  -254,  -254,  -254,  -254,  -254,  -254,  -254,   438,   351,
+       0,     0,  -254,   -13,    85,  -254,  -254,  -254,  -254,  -254,
+       0,  -254,     0,    83,  -254,    18,     0,    19,    20,    21,
+      22,    23,     0,     0,    24,    25,    26,    27,    28,     0,
+      29,    30,    31,    32,    33,    34,    86,   106,    87,    88,
+      89,    35,    36,    90,    91,    92,    93,    94,    95,     0,
+     186,   187,    96,    97,    98,    99,    37,     0,   100,    38,
+      39,    40,    41,    42,     0,     0,    43,    44,    45,    46,
+      47,    48,    49,     0,     0,     0,   200,     0,     0,     0,
+       0,   201,    50,   200,   202,   203,   204,   205,   201,     0,
+       0,   202,   203,   204,   205,     0,     0,     0,    51,    52,
+       0,    53,     0,    54,    55,    -3,    85,     0,     0,     0,
+      56,   101,    57,    58,     0,    83,     0,    18,     0,    19,
       20,    21,    22,    23,     0,     0,    24,    25,    26,    27,
       28,     0,    29,    30,    31,    32,    33,    34,    86,   106,
       87,    88,    89,    35,    36,    90,    91,    92,    93,    94,
       95,     0,     0,     0,    96,    97,    98,    99,    37,     0,
      100,    38,    39,    40,    41,    42,     0,     0,    43,    44,
-      45,    46,    47,    48,    49,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,    50,     0,     0,     0,     0,     0,
+      45,    46,    47,    48,    49,     1,     2,     3,     4,     5,
+       6,     7,     0,     0,    50,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       51,    52,     0,    53,     0,    54,    55,    85,     0,     0,
-       0,     0,    56,   101,    57,    58,    83,   536,    18,     0,
+       0,     0,    56,   101,    57,    58,    83,   416,    18,     0,
       19,    20,    21,    22,    23,     0,     0,    24,    25,    26,
       27,    28,     0,    29,    30,    31,    32,    33,    34,    86,
      106,    87,    88,    89,    35,    36,    90,    91,    92,    93,
@@ -455,7 +446,7 @@ static const yytype_int16 yytable[] =
        0,     0,     0,     0,     0,     0,    50,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,    51,    52,     0,    53,     0,    54,    55,    85,
-       0,     0,     0,     0,    56,   101,    57,    58,    83,   539,
+       0,     0,     0,     0,    56,   101,    57,    58,    83,   538,
       18,     0,    19,    20,    21,    22,    23,     0,     0,    24,
       25,    26,    27,    28,     0,    29,    30,    31,    32,    33,
       34,    86,   106,    87,    88,    89,    35,    36,    90,    91,
@@ -466,7 +457,7 @@ static const yytype_int16 yytable[] =
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,    51,    52,     0,    53,     0,    54,    55,
       85,     0,     0,     0,     0,    56,   101,    57,    58,    83,
-     553,    18,     0,    19,    20,    21,    22,    23,     0,     0,
+     540,    18,     0,    19,    20,    21,    22,    23,     0,     0,
       24,    25,    26,    27,    28,     0,    29,    30,    31,    32,
       33,    34,    86,   106,    87,    88,    89,    35,    36,    90,
       91,    92,    93,    94,    95,     0,     0,     0,    96,    97,
@@ -476,13 +467,13 @@ static const yytype_int16 yytable[] =
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,    51,    52,     0,    53,     0,    54,
       55,    85,     0,     0,     0,     0,    56,   101,    57,    58,
-      83,     0,    18,     0,    19,    20,    21,    22,    23,     0,
+      83,   554,    18,     0,    19,    20,    21,    22,    23,     0,
        0,    24,    25,    26,    27,    28,     0,    29,    30,    31,
       32,    33,    34,    86,   106,    87,    88,    89,    35,    36,
       90,    91,    92,    93,    94,    95,     0,     0,     0,    96,
       97,    98,    99,    37,     0,   100,    38,    39,    40,    41,
       42,     0,     0,    43,    44,    45,    46,    47,    48,    49,
-       0,     0,   568,     0,     0,     0,     0,     0,     0,    50,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,    50,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,    51,    52,     0,    53,     0,
       54,    55,    85,     0,     0,     0,     0,    56,   101,    57,
@@ -492,13 +483,13 @@ static const yytype_int16 yytable[] =
       36,    90,    91,    92,    93,    94,    95,     0,     0,     0,
       96,    97,    98,    99,    37,     0,   100,    38,    39,    40,
       41,    42,     0,     0,    43,    44,    45,    46,    47,    48,
-      49,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+      49,     0,     0,   569,     0,     0,     0,     0,     0,     0,
       50,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,    51,    52,     0,    53,
        0,    54,    55,    85,     0,     0,     0,     0,    56,   101,
       57,    58,    83,     0,    18,     0,    19,    20,    21,    22,
       23,     0,     0,    24,    25,    26,    27,    28,     0,    29,
-      30,    31,    32,    33,    34,    86,     0,    87,    88,    89,
+      30,    31,    32,    33,    34,    86,   106,    87,    88,    89,
       35,    36,    90,    91,    92,    93,    94,    95,     0,     0,
        0,    96,    97,    98,    99,    37,     0,   100,    38,    39,
       40,    41,    42,     0,     0,    43,    44,    45,    46,    47,
@@ -506,47 +497,67 @@ static const yytype_int16 yytable[] =
        0,    50,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,    51,    52,     0,
       53,     0,    54,    55,    85,     0,     0,     0,     0,    56,
-     101,    57,    58,     0,     0,    18,     0,    19,    20,    21,
+     101,    57,    58,    83,     0,    18,     0,    19,    20,    21,
       22,    23,     0,     0,    24,    25,    26,    27,    28,     0,
-      29,    30,    31,    32,    33,    34,     0,     0,     0,     0,
-       0,    35,    36,     0,     0,     0,     0,     0,   186,   187,
-       0,     0,     0,     0,     0,     0,    37,     0,     0,    38,
+      29,    30,    31,    32,    33,    34,    86,     0,    87,    88,
+      89,    35,    36,    90,    91,    92,    93,    94,    95,     0,
+       0,     0,    96,    97,    98,    99,    37,     0,   100,    38,
       39,    40,    41,    42,     0,     0,    43,    44,    45,    46,
-      47,    48,    49,   192,   193,   194,   195,   196,   197,   198,
-     199,   200,    50,     0,     0,     0,   201,     0,     0,   202,
-     203,   204,   205,     0,     0,     0,     0,     0,    51,    52,
+      47,    48,    49,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    50,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,    51,    52,
        0,    53,     0,    54,    55,    85,     0,     0,     0,     0,
-      56,   -77,    57,    58,     0,     0,    18,     0,    19,    20,
+      56,   101,    57,    58,     0,     0,    18,     0,    19,    20,
       21,    22,    23,     0,     0,    24,    25,    26,    27,    28,
        0,    29,    30,    31,    32,    33,    34,     0,     0,     0,
-       0,     0,    35,    36,     0,     0,     0,     0,   186,   187,
-       0,     0,     0,     0,     0,     0,     0,    37,     0,     0,
+       0,     0,    35,    36,     0,     0,     0,     0,     0,   186,
+     187,     0,     0,     0,     0,     0,     0,    37,     0,     0,
       38,    39,    40,    41,    42,     0,     0,    43,    44,    45,
-      46,    47,    48,    49,   193,   194,   195,   196,   197,   198,
-     199,   200,     0,    50,     0,     0,   201,     0,     0,   202,
-     203,   204,   205,     0,     0,     0,     0,     0,     0,    51,
-      52,     0,    53,     0,    54,    55,     0,     0,     0,     0,
-     -77,    56,     0,    57,    58,    83,     0,    18,     0,    19,
-      20,    21,    22,    23,     0,     0,   141,    25,    26,    27,
-      28,   119,    29,    30,    31,    32,    33,    34,     0,     0,
-       0,     0,     0,    35,    36,     0,     0,     0,   186,   187,
-       0,     0,     0,     0,     0,     0,     0,     0,    37,     0,
+      46,    47,    48,    49,   192,   193,   194,   195,   196,   197,
+     198,   199,   200,    50,     0,     0,     0,   201,     0,     0,
+     202,   203,   204,   205,     0,     0,     0,     0,     0,    51,
+      52,     0,    53,     0,    54,    55,    85,     0,     0,     0,
+       0,    56,   -78,    57,    58,     0,     0,    18,     0,    19,
+      20,    21,    22,    23,     0,     0,    24,    25,    26,    27,
+      28,     0,    29,    30,    31,    32,    33,    34,     0,     0,
+       0,     0,     0,    35,    36,     0,     0,     0,     0,   186,
+     187,     0,     0,     0,     0,     0,     0,     0,    37,     0,
        0,    38,    39,    40,    41,    42,     0,     0,    43,    44,
-      45,    46,    47,    48,    49,   194,   195,   196,   197,   198,
-     199,   200,     0,     0,    50,     0,   201,     0,     0,   202,
-     203,   204,   205,     0,     0,     0,     0,     0,     0,     0,
+      45,    46,    47,    48,    49,   193,   194,   195,   196,   197,
+     198,   199,   200,     0,    50,     0,     0,   201,     0,     0,
+     202,   203,   204,   205,     0,     0,     0,     0,     0,     0,
       51,    52,     0,    53,     0,    54,    55,     0,     0,     0,
-       0,     0,    56,     0,    57,    58,    83,     0,    18,     0,
+       0,   -78,    56,     0,    57,    58,    83,     0,    18,     0,
+      19,    20,    21,    22,    23,     0,     0,   141,    25,    26,
+      27,    28,   119,    29,    30,    31,    32,    33,    34,     0,
+       0,     0,     0,     0,    35,    36,     0,     0,     0,   186,
+     187,     0,     0,     0,     0,     0,     0,     0,     0,    37,
+       0,     0,    38,    39,    40,    41,    42,     0,     0,    43,
+      44,    45,    46,    47,    48,    49,   194,   195,   196,   197,
+     198,   199,   200,     0,     0,    50,     0,   201,     0,     0,
+     202,   203,   204,   205,     0,     0,     0,     0,     0,     0,
+       0,    51,    52,     0,    53,     0,    54,    55,     0,     0,
+     186,   187,     0,    56,     0,    57,    58,    83,     0,    18,
+       0,    19,    20,    21,    22,    23,     0,     0,    24,    25,
+      26,    27,    28,     0,    29,    30,    31,    32,    33,    34,
+     197,   198,   199,   200,     0,    35,    36,     0,   201,     0,
+       0,   202,   203,   204,   205,     0,     0,     0,     0,     0,
+      37,     0,     0,    38,    39,    40,    41,    42,     0,     0,
+      43,    44,    45,    46,    47,    48,    49,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    50,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    51,    52,     0,    53,     0,    54,    55,     0,
+       0,     0,     0,     0,    56,     0,    57,    58,    18,   114,
       19,    20,    21,    22,    23,     0,     0,    24,    25,    26,
       27,    28,     0,    29,    30,    31,    32,    33,    34,     0,
-       0,     0,     0,     0,    35,    36,   236,   237,   238,   239,
-       0,     0,     0,   240,     0,   241,     0,     0,     0,    37,
+       0,     0,     0,     0,    35,    36,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,    37,
        0,     0,    38,    39,    40,    41,    42,     0,     0,    43,
       44,    45,    46,    47,    48,    49,     0,     0,     0,     0,
-     172,   173,   174,     0,     0,    50,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,    50,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,    51,    52,     0,    53,     0,    54,    55,     0,     0,
-       0,     0,     0,    56,     0,    57,    58,    18,   114,    19,
+       0,     0,     0,    56,     0,    57,    58,    18,     0,    19,
       20,    21,    22,    23,     0,     0,    24,    25,    26,    27,
       28,     0,    29,    30,    31,    32,    33,    34,     0,     0,
        0,     0,     0,    35,    36,     0,     0,     0,     0,     0,
@@ -556,7 +567,7 @@ static const yytype_int16 yytable[] =
        0,     0,     0,     0,    50,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       51,    52,     0,    53,     0,    54,    55,     0,     0,     0,
-       0,     0,    56,     0,    57,    58,    18,     0,    19,    20,
+       0,     0,    56,   149,    57,    58,    18,     0,    19,    20,
       21,    22,    23,     0,     0,    24,    25,    26,    27,    28,
        0,    29,    30,    31,    32,    33,    34,     0,     0,     0,
        0,     0,    35,    36,     0,     0,     0,     0,     0,     0,
@@ -566,7 +577,7 @@ static const yytype_int16 yytable[] =
        0,     0,     0,    50,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,    51,
       52,     0,    53,     0,    54,    55,     0,     0,     0,     0,
-       0,    56,   149,    57,    58,    18,     0,    19,    20,    21,
+     168,    56,     0,    57,    58,    18,     0,    19,    20,    21,
       22,    23,     0,     0,    24,    25,    26,    27,    28,     0,
       29,    30,    31,    32,    33,    34,     0,     0,     0,     0,
        0,    35,    36,     0,     0,     0,     0,     0,     0,     0,
@@ -575,7 +586,7 @@ static const yytype_int16 yytable[] =
       47,    48,    49,     0,     0,     0,     0,     0,     0,     0,
        0,     0,    50,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,    51,    52,
-       0,    53,     0,    54,    55,     0,     0,     0,     0,   168,
+       0,    53,     0,    54,    55,     0,     0,     0,     0,   266,
       56,     0,    57,    58,    18,     0,    19,    20,    21,    22,
       23,     0,     0,    24,    25,    26,    27,    28,     0,    29,
       30,    31,    32,    33,    34,     0,     0,     0,     0,     0,
@@ -585,7 +596,7 @@ static const yytype_int16 yytable[] =
       48,    49,     0,     0,     0,     0,     0,     0,     0,     0,
        0,    50,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,    51,    52,     0,
-      53,     0,    54,    55,     0,     0,     0,     0,   266,    56,
+      53,     0,    54,    55,     0,     0,     0,     0,   281,    56,
        0,    57,    58,    18,     0,    19,    20,    21,    22,    23,
        0,     0,    24,    25,    26,    27,    28,     0,    29,    30,
       31,    32,    33,    34,     0,     0,     0,     0,     0,    35,
@@ -595,7 +606,7 @@ static const yytype_int16 yytable[] =
       49,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       50,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,    51,    52,     0,    53,
-       0,    54,    55,     0,     0,     0,     0,   281,    56,     0,
+       0,    54,    55,     0,     0,     0,     0,   293,    56,     0,
       57,    58,    18,     0,    19,    20,    21,    22,    23,     0,
        0,    24,    25,    26,    27,    28,     0,    29,    30,    31,
       32,    33,    34,     0,     0,     0,     0,     0,    35,    36,
@@ -605,7 +616,7 @@ static const yytype_int16 yytable[] =
        0,     0,     0,     0,     0,     0,     0,     0,     0,    50,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,    51,    52,     0,    53,     0,
-      54,    55,     0,     0,     0,     0,   293,    56,     0,    57,
+      54,    55,     0,     0,     0,     0,   326,    56,     0,    57,
       58,    18,     0,    19,    20,    21,    22,    23,     0,     0,
       24,    25,    26,    27,    28,     0,    29,    30,    31,    32,
       33,    34,     0,     0,     0,     0,     0,    35,    36,     0,
@@ -615,7 +626,7 @@ static const yytype_int16 yytable[] =
        0,     0,     0,     0,     0,     0,     0,     0,    50,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,    51,    52,     0,    53,     0,    54,
-      55,     0,     0,     0,     0,   326,    56,     0,    57,    58,
+      55,     0,     0,     0,     0,   386,    56,     0,    57,    58,
       18,     0,    19,    20,    21,    22,    23,     0,     0,    24,
       25,    26,    27,    28,     0,    29,    30,    31,    32,    33,
       34,     0,     0,     0,     0,     0,    35,    36,     0,     0,
@@ -625,7 +636,7 @@ static const yytype_int16 yytable[] =
        0,     0,     0,     0,     0,     0,     0,    50,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,    51,    52,     0,    53,     0,    54,    55,
-       0,     0,     0,     0,   385,    56,     0,    57,    58,    18,
+       0,     0,     0,     0,   403,    56,     0,    57,    58,    18,
        0,    19,    20,    21,    22,    23,     0,     0,    24,    25,
       26,    27,    28,     0,    29,    30,    31,    32,    33,    34,
        0,     0,     0,     0,     0,    35,    36,     0,     0,     0,
@@ -635,7 +646,7 @@ static const yytype_int16 yytable[] =
        0,     0,     0,     0,     0,     0,    50,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,    51,    52,     0,    53,     0,    54,    55,     0,
-       0,     0,     0,   402,    56,     0,    57,    58,    18,     0,
+       0,     0,     0,     0,    56,     0,    57,    58,    18,     0,
       19,    20,    21,    22,    23,     0,     0,    24,    25,    26,
       27,    28,     0,    29,    30,    31,    32,    33,    34,     0,
        0,     0,     0,     0,    35,    36,     0,     0,     0,     0,
@@ -643,135 +654,111 @@ static const yytype_int16 yytable[] =
        0,     0,    38,    39,    40,    41,    42,     0,     0,    43,
       44,    45,    46,    47,    48,    49,     0,     0,     0,     0,
        0,     0,     0,     0,     0,    50,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     185,     0,     0,     0,     0,     0,     0,   186,   187,     0,
        0,    51,    52,     0,    53,     0,    54,    55,     0,     0,
-       0,     0,     0,    56,     0,    57,    58,    18,     0,    19,
-      20,    21,    22,    23,     0,     0,    24,    25,    26,    27,
-      28,     0,    29,    30,    31,    32,    33,    34,     0,     0,
-       0,     0,     0,    35,    36,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,    37,     0,
-       0,    38,    39,    40,    41,    42,     0,     0,    43,    44,
-      45,    46,    47,    48,    49,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,    50,     0,     0,     0,     0,   185,
-       0,     0,     0,     0,     0,     0,   186,   187,     0,     0,
-      51,    52,     0,    53,     0,    54,    55,     0,     0,     0,
-       0,     0,   275,     0,    57,    58,   188,   189,   395,   190,
-     191,   192,   193,   194,   195,   196,   197,   198,   199,   200,
-       0,     0,     0,     0,   201,   185,     0,   202,   203,   204,
-     205,     0,   186,   187,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,   188,   189,     0,   190,   191,   192,   193,   194,
-     195,   196,   197,   198,   199,   200,     0,     0,     0,     0,
-     201,   185,     0,   202,   203,   204,   205,     0,   186,   187,
+       0,     0,     0,   275,     0,    57,    58,   188,   189,     0,
+     190,   191,   192,   193,   194,   195,   196,   197,   198,   199,
+     200,     0,     0,     0,     0,   201,   185,     0,   202,   203,
+     204,   205,     0,   186,   187,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,   189,
-       0,   190,   191,   192,   193,   194,   195,   196,   197,   198,
-     199,   200,     0,     0,     0,     0,   201,  -290,     0,   202,
-     203,   204,   205,     0,   186,   187,     0,     0,     0,     0,
+       0,     0,     0,     0,   189,     0,   190,   191,   192,   193,
+     194,   195,   196,   197,   198,   199,   200,     0,     0,     0,
+       0,   201,  -291,     0,   202,   203,   204,   205,     0,   186,
+     187,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,   190,   191,   192,
-     193,   194,   195,   196,   197,   198,   199,   200,     0,     0,
-       0,     0,   201,     0,     0,   202,   203,   204,   205
+       0,     0,   190,   191,   192,   193,   194,   195,   196,   197,
+     198,   199,   200,     0,     0,     0,     0,   201,     0,     0,
+     202,   203,   204,   205
 };
 
 static const yytype_int16 yycheck[] =
 {
-      17,   125,    10,    48,     9,    42,    48,   137,   138,   345,
-      18,    10,    12,    50,    24,   355,    10,    12,   474,   355,
-     262,   505,   358,   359,    10,    21,    12,    21,     0,   153,
-      26,    12,    26,    10,    21,    22,    23,    45,    25,    26,
-      73,    80,    10,    10,    21,    12,    16,    17,    56,    26,
-      16,    17,    16,    17,    18,    42,    43,    91,    92,    21,
-      22,    23,    12,    25,    26,    10,    10,    12,    12,    89,
-      90,    58,   111,    80,   107,    70,   107,    10,    83,    12,
-      42,    43,   566,    46,    47,    10,    48,    12,   125,    70,
-      91,    16,    17,    18,   107,    57,    58,    22,   108,    16,
-      17,   557,   438,    70,    68,    10,   106,    12,   145,   108,
-     155,    89,    10,   155,    12,   109,   153,    76,    77,    78,
-     128,   107,    19,    20,    13,    70,   256,   107,   136,   137,
-     138,    13,   109,   110,    96,    32,   107,    70,    63,   109,
-      37,   477,   478,   109,    41,   109,    13,    44,   156,    13,
-      47,   138,    49,    21,    51,    52,    53,    54,    55,   102,
-     103,   104,   105,    10,   172,   173,   174,    10,   176,   177,
-     178,    13,   216,   217,   510,    13,   138,   419,    35,    36,
-     225,    98,   107,   225,   109,   110,   107,    76,    77,    78,
-     107,    13,   109,   155,    76,    77,    78,   214,   206,   207,
-     208,   209,   210,   211,   212,   213,    13,   107,   544,    76,
+      17,   125,    10,    48,     9,    42,    48,    10,   345,    10,
+      18,    12,    10,    50,   355,    10,    16,    17,   355,   262,
+     475,   358,   359,    21,    12,    21,    21,    10,    26,   153,
+      26,    26,    16,    17,    21,    22,    23,    45,    25,    26,
+     137,   138,    24,    16,    17,    80,    89,    90,    56,    73,
+      91,    92,    16,    17,    18,    42,    43,     0,   506,    21,
+      22,    23,    12,    25,    26,    76,    77,    78,    13,    99,
+      80,    58,   102,   103,   104,   105,   111,    10,    83,    12,
+      42,    43,    10,   107,    12,    10,    48,    12,   125,    46,
+      47,    16,    17,    18,   107,    57,    58,    22,    98,    10,
+     107,    12,   439,   558,    68,   108,   107,   107,   145,   109,
+     155,   109,   110,   155,   109,    10,   153,    12,   106,   567,
+     128,    12,    19,    20,    13,   109,   108,    13,   136,   137,
+     138,    76,    77,    78,    96,    32,   109,    70,    63,   107,
+      37,   478,   479,    91,    41,   109,    13,    44,   156,    13,
+      47,   138,    49,    89,    51,    52,    53,    54,    55,   256,
+     102,   103,   104,   105,   172,   173,   174,   107,   176,   177,
+     178,    13,   216,   217,   511,    70,   138,   420,    21,    70,
+     225,    13,   107,   225,   109,   110,    10,    76,    77,    78,
+      76,    77,    78,   155,    35,    36,    13,   214,   206,   207,
+     208,   209,   210,   211,   212,   213,    12,   107,   545,    76,
       77,    78,    76,    77,    78,   220,   221,   222,   223,   224,
-     257,   226,   227,   563,   229,   230,   107,   469,   236,   237,
-     238,   239,   240,   241,    76,    77,    78,   107,    76,    77,
-      78,    99,    68,   205,   102,   103,   104,   105,   256,    88,
-      89,   375,    13,   107,    76,    77,    78,    10,   155,    12,
-     108,   107,   270,   225,    10,    48,    12,   275,   108,    76,
-      77,    78,    98,    76,    77,    78,   406,   285,   175,   107,
-      73,   107,   106,   109,   181,    24,    70,   184,   185,   186,
+     257,   226,   227,   564,   229,   230,    10,   470,   236,   237,
+     238,   239,   240,   241,    76,    77,    78,    88,    89,    11,
+      10,   107,    12,   205,    76,    77,    78,   107,   256,    21,
+      22,    23,   376,    25,    26,    13,   108,   107,   155,    76,
+      77,    78,   270,   225,    70,    48,    10,   275,    12,    41,
+      42,    43,    44,    76,    77,    78,   107,   285,   175,   107,
+      76,    77,    78,   108,   181,    57,    58,   184,   185,   186,
      187,   188,   189,   190,   191,   192,   193,   194,   195,   196,
-     197,   198,   199,   200,   201,   108,   314,   315,   106,    11,
-      11,   356,    70,   321,   356,    76,    77,    78,    12,    21,
-      22,    23,    98,    25,    26,    76,    77,    78,    21,    76,
-      77,    78,    21,   107,   342,   343,   344,   345,   375,    41,
-      42,    43,    44,    76,    77,    78,    26,   355,   472,   508,
-     358,   359,   357,    80,    24,    57,    58,   108,    74,    11,
-     322,   108,    61,    62,   523,   524,   106,   476,    24,    12,
-     479,   376,    78,   106,   483,   484,   535,   107,    76,    77,
-      78,   110,   110,   391,   110,   347,   545,   546,   110,   110,
-      61,    19,   501,   502,   356,    94,    21,    99,   406,   558,
-      99,   109,   511,   102,   103,   104,   105,    76,    77,    78,
-     108,   416,   107,    81,   106,   420,   107,   526,    76,    77,
-      78,   530,   531,    94,    61,    62,   431,    11,    99,   131,
-     438,   102,   103,   104,   105,   472,   138,   106,   446,   548,
-      76,    77,    78,    42,    43,    44,    45,    11,   106,    11,
-      49,    11,    51,   562,    91,    92,    93,    94,    11,   106,
-      21,   570,    99,   107,   106,   102,   103,   104,   105,   477,
-     478,   488,   108,   490,   106,   106,     0,    76,    77,    78,
-     106,   108,   499,    76,    77,    78,    10,   106,    12,    13,
-     495,    61,    62,   106,    76,    77,    78,    74,   395,    10,
-      10,   509,   510,    11,   106,   108,    10,   106,   525,    76,
-      77,    78,   108,   107,   106,   108,   106,    72,    42,    43,
-      44,    45,   108,    93,    94,    49,   108,    51,   108,    99,
-      54,   233,   102,   103,   104,   105,   544,    61,    62,   106,
-     106,   106,   559,    71,   441,   108,    76,    77,    78,   107,
-      74,    20,    76,    77,    78,   106,    80,    81,    82,    83,
-      84,    85,    86,    87,    88,    89,    90,    91,    92,    93,
-      94,   106,     0,   106,    13,    99,   106,   106,   102,   103,
-     104,   105,   106,   509,   108,    13,   343,   111,    76,    77,
-      78,   418,    76,    77,    78,    76,    77,    78,    94,    61,
-      62,   277,   563,    99,   370,   495,   102,   103,   104,   105,
-     248,   371,   155,   356,    42,    43,    44,    45,   106,   451,
-     322,    49,   106,    51,   225,   106,    54,    89,    90,    91,
-      92,    93,    94,    61,    62,   470,    -1,    99,    -1,    -1,
-     102,   103,   104,   105,    -1,    -1,    74,    -1,    76,    77,
-      78,    -1,    80,    81,    82,    83,    84,    85,    86,    87,
-      88,    89,    90,    91,    92,    93,    94,    -1,    -1,    -1,
-      -1,    99,     0,     1,   102,   103,   104,   105,   106,    -1,
-     108,    -1,    10,   111,    12,    -1,    14,    15,    16,    17,
-      18,    -1,    -1,    21,    22,    23,    24,    25,    -1,    27,
-      28,    29,    30,    31,    32,    33,    34,    35,    36,    37,
-      38,    39,    40,    41,    42,    43,    44,    45,    -1,    -1,
-      -1,    49,    50,    51,    52,    53,    -1,    55,    56,    57,
-      58,    59,    60,    -1,    -1,    63,    64,    65,    66,    67,
-      68,    69,     3,     4,     5,     6,     7,     8,     9,    -1,
-      -1,    79,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    95,    96,    -1,
-      98,    -1,   100,   101,     0,     1,    -1,    -1,    -1,   107,
-     108,   109,   110,    -1,    10,    -1,    12,    -1,    14,    15,
-      16,    17,    18,    -1,    -1,    21,    22,    23,    24,    25,
-      -1,    27,    28,    29,    30,    31,    32,    33,    34,    35,
-      36,    37,    38,    39,    40,    41,    42,    43,    44,    45,
-      -1,    -1,    -1,    49,    50,    51,    52,    53,    -1,    55,
-      56,    57,    58,    59,    60,    -1,    -1,    63,    64,    65,
-      66,    67,    68,    69,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    79,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    95,
-      96,    -1,    98,    -1,   100,   101,     1,    -1,    -1,    -1,
-      -1,   107,   108,   109,   110,    10,    11,    12,    -1,    14,
+     197,   198,   199,   200,   201,   108,   314,   315,   107,    73,
+     407,   356,   108,   321,   356,   106,    24,   509,    76,    77,
+      78,    70,    42,    43,    44,    45,    70,    99,    10,    49,
+      12,    51,   524,   525,   342,   343,   344,   345,   477,   376,
+      68,   480,    11,   106,   536,   484,   485,   355,    70,   473,
+     358,   359,   357,    12,   546,   547,    76,    77,    78,   131,
+     322,    21,    61,   502,   503,    21,   138,   559,    98,    10,
+      98,    12,   377,   512,   107,    76,    77,    78,    26,   107,
+      80,   109,    24,    74,   392,   347,   106,   106,   527,    76,
+      77,    78,   531,   532,   356,    94,    76,    77,    78,   407,
+      99,    24,    11,   102,   103,   104,   105,   108,    12,   107,
+     549,    78,   417,   110,    54,   110,   421,   110,   110,   106,
+     110,    61,    62,    19,   563,   109,    21,   432,   108,   107,
+      81,   439,   571,   106,    11,   107,   473,    11,    11,   447,
+      11,    81,    82,    83,    84,    85,    86,    87,    88,    89,
+      90,    91,    92,    93,    94,    76,    77,    78,    11,    99,
+      21,   233,   102,   103,   104,   105,    76,    77,    78,   106,
+     478,   479,   489,   106,   491,   106,   106,     0,   107,    42,
+      43,    44,    45,   500,   106,   106,    49,    10,    51,    12,
+      13,   496,    61,    62,   108,    76,    77,    78,   108,   396,
+     106,   106,   510,   511,   238,   239,   240,   241,    10,   526,
+      76,    77,    78,    76,    77,    78,    76,    77,    78,    42,
+      43,    44,    45,    74,    93,    94,    49,   108,    51,    10,
+      99,    54,    11,   102,   103,   104,   105,   545,    61,    62,
+     108,   106,   108,   560,   108,   442,   106,    76,    77,    78,
+     322,    74,    10,    76,    77,    78,   106,    80,    81,    82,
+      83,    84,    85,    86,    87,    88,    89,    90,    91,    92,
+      93,    94,   107,     0,   106,    72,    99,   106,   108,   102,
+     103,   104,   105,   106,   108,   108,    13,   106,   111,    76,
+      77,    78,   106,    76,    77,    78,    76,    77,    78,   107,
+      61,    62,   108,   106,    71,    20,    76,    77,    78,    13,
+     106,   106,   106,   564,   510,    42,    43,    44,    45,   106,
+     343,   419,    49,   106,    51,   277,   106,    54,    89,    90,
+      91,    92,    93,    94,    61,    62,   106,   248,    99,   371,
+     452,   102,   103,   104,   105,   372,   155,    74,   496,    76,
+      77,    78,   471,    80,    81,    82,    83,    84,    85,    86,
+      87,    88,    89,    90,    91,    92,    93,    94,   356,   225,
+      -1,    -1,    99,     0,     1,   102,   103,   104,   105,   106,
+      -1,   108,    -1,    10,   111,    12,    -1,    14,    15,    16,
+      17,    18,    -1,    -1,    21,    22,    23,    24,    25,    -1,
+      27,    28,    29,    30,    31,    32,    33,    34,    35,    36,
+      37,    38,    39,    40,    41,    42,    43,    44,    45,    -1,
+      61,    62,    49,    50,    51,    52,    53,    -1,    55,    56,
+      57,    58,    59,    60,    -1,    -1,    63,    64,    65,    66,
+      67,    68,    69,    -1,    -1,    -1,    94,    -1,    -1,    -1,
+      -1,    99,    79,    94,   102,   103,   104,   105,    99,    -1,
+      -1,   102,   103,   104,   105,    -1,    -1,    -1,    95,    96,
+      -1,    98,    -1,   100,   101,     0,     1,    -1,    -1,    -1,
+     107,   108,   109,   110,    -1,    10,    -1,    12,    -1,    14,
       15,    16,    17,    18,    -1,    -1,    21,    22,    23,    24,
       25,    -1,    27,    28,    29,    30,    31,    32,    33,    34,
       35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
       45,    -1,    -1,    -1,    49,    50,    51,    52,    53,    -1,
       55,    56,    57,    58,    59,    60,    -1,    -1,    63,    64,
-      65,    66,    67,    68,    69,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    79,    -1,    -1,    -1,    -1,    -1,
+      65,    66,    67,    68,    69,     3,     4,     5,     6,     7,
+       8,     9,    -1,    -1,    79,    -1,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
       95,    96,    -1,    98,    -1,   100,   101,     1,    -1,    -1,
       -1,    -1,   107,   108,   109,   110,    10,    11,    12,    -1,
@@ -815,13 +802,13 @@ static const yytype_int16 yycheck[] =
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    95,    96,    -1,    98,    -1,   100,
      101,     1,    -1,    -1,    -1,    -1,   107,   108,   109,   110,
-      10,    -1,    12,    -1,    14,    15,    16,    17,    18,    -1,
+      10,    11,    12,    -1,    14,    15,    16,    17,    18,    -1,
       -1,    21,    22,    23,    24,    25,    -1,    27,    28,    29,
       30,    31,    32,    33,    34,    35,    36,    37,    38,    39,
       40,    41,    42,    43,    44,    45,    -1,    -1,    -1,    49,
       50,    51,    52,    53,    -1,    55,    56,    57,    58,    59,
       60,    -1,    -1,    63,    64,    65,    66,    67,    68,    69,
-      -1,    -1,    72,    -1,    -1,    -1,    -1,    -1,    -1,    79,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    79,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    95,    96,    -1,    98,    -1,
      100,   101,     1,    -1,    -1,    -1,    -1,   107,   108,   109,
@@ -831,13 +818,13 @@ static const yytype_int16 yycheck[] =
       39,    40,    41,    42,    43,    44,    45,    -1,    -1,    -1,
       49,    50,    51,    52,    53,    -1,    55,    56,    57,    58,
       59,    60,    -1,    -1,    63,    64,    65,    66,    67,    68,
-      69,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      69,    -1,    -1,    72,    -1,    -1,    -1,    -1,    -1,    -1,
       79,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    95,    96,    -1,    98,
       -1,   100,   101,     1,    -1,    -1,    -1,    -1,   107,   108,
      109,   110,    10,    -1,    12,    -1,    14,    15,    16,    17,
       18,    -1,    -1,    21,    22,    23,    24,    25,    -1,    27,
-      28,    29,    30,    31,    32,    33,    -1,    35,    36,    37,
+      28,    29,    30,    31,    32,    33,    34,    35,    36,    37,
       38,    39,    40,    41,    42,    43,    44,    45,    -1,    -1,
       -1,    49,    50,    51,    52,    53,    -1,    55,    56,    57,
       58,    59,    60,    -1,    -1,    63,    64,    65,    66,    67,
@@ -845,47 +832,67 @@ static const yytype_int16 yycheck[] =
       -1,    79,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    95,    96,    -1,
       98,    -1,   100,   101,     1,    -1,    -1,    -1,    -1,   107,
-     108,   109,   110,    -1,    -1,    12,    -1,    14,    15,    16,
+     108,   109,   110,    10,    -1,    12,    -1,    14,    15,    16,
       17,    18,    -1,    -1,    21,    22,    23,    24,    25,    -1,
-      27,    28,    29,    30,    31,    32,    -1,    -1,    -1,    -1,
-      -1,    38,    39,    -1,    -1,    -1,    -1,    -1,    61,    62,
-      -1,    -1,    -1,    -1,    -1,    -1,    53,    -1,    -1,    56,
+      27,    28,    29,    30,    31,    32,    33,    -1,    35,    36,
+      37,    38,    39,    40,    41,    42,    43,    44,    45,    -1,
+      -1,    -1,    49,    50,    51,    52,    53,    -1,    55,    56,
       57,    58,    59,    60,    -1,    -1,    63,    64,    65,    66,
-      67,    68,    69,    86,    87,    88,    89,    90,    91,    92,
-      93,    94,    79,    -1,    -1,    -1,    99,    -1,    -1,   102,
-     103,   104,   105,    -1,    -1,    -1,    -1,    -1,    95,    96,
+      67,    68,    69,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    79,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    95,    96,
       -1,    98,    -1,   100,   101,     1,    -1,    -1,    -1,    -1,
      107,   108,   109,   110,    -1,    -1,    12,    -1,    14,    15,
       16,    17,    18,    -1,    -1,    21,    22,    23,    24,    25,
       -1,    27,    28,    29,    30,    31,    32,    -1,    -1,    -1,
-      -1,    -1,    38,    39,    -1,    -1,    -1,    -1,    61,    62,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    53,    -1,    -1,
+      -1,    -1,    38,    39,    -1,    -1,    -1,    -1,    -1,    61,
+      62,    -1,    -1,    -1,    -1,    -1,    -1,    53,    -1,    -1,
       56,    57,    58,    59,    60,    -1,    -1,    63,    64,    65,
-      66,    67,    68,    69,    87,    88,    89,    90,    91,    92,
-      93,    94,    -1,    79,    -1,    -1,    99,    -1,    -1,   102,
-     103,   104,   105,    -1,    -1,    -1,    -1,    -1,    -1,    95,
-      96,    -1,    98,    -1,   100,   101,    -1,    -1,    -1,    -1,
-     106,   107,    -1,   109,   110,    10,    -1,    12,    -1,    14,
+      66,    67,    68,    69,    86,    87,    88,    89,    90,    91,
+      92,    93,    94,    79,    -1,    -1,    -1,    99,    -1,    -1,
+     102,   103,   104,   105,    -1,    -1,    -1,    -1,    -1,    95,
+      96,    -1,    98,    -1,   100,   101,     1,    -1,    -1,    -1,
+      -1,   107,   108,   109,   110,    -1,    -1,    12,    -1,    14,
       15,    16,    17,    18,    -1,    -1,    21,    22,    23,    24,
-      25,    26,    27,    28,    29,    30,    31,    32,    -1,    -1,
-      -1,    -1,    -1,    38,    39,    -1,    -1,    -1,    61,    62,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    53,    -1,
+      25,    -1,    27,    28,    29,    30,    31,    32,    -1,    -1,
+      -1,    -1,    -1,    38,    39,    -1,    -1,    -1,    -1,    61,
+      62,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    53,    -1,
       -1,    56,    57,    58,    59,    60,    -1,    -1,    63,    64,
-      65,    66,    67,    68,    69,    88,    89,    90,    91,    92,
-      93,    94,    -1,    -1,    79,    -1,    99,    -1,    -1,   102,
-     103,   104,   105,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      65,    66,    67,    68,    69,    87,    88,    89,    90,    91,
+      92,    93,    94,    -1,    79,    -1,    -1,    99,    -1,    -1,
+     102,   103,   104,   105,    -1,    -1,    -1,    -1,    -1,    -1,
       95,    96,    -1,    98,    -1,   100,   101,    -1,    -1,    -1,
-      -1,    -1,   107,    -1,   109,   110,    10,    -1,    12,    -1,
+      -1,   106,   107,    -1,   109,   110,    10,    -1,    12,    -1,
+      14,    15,    16,    17,    18,    -1,    -1,    21,    22,    23,
+      24,    25,    26,    27,    28,    29,    30,    31,    32,    -1,
+      -1,    -1,    -1,    -1,    38,    39,    -1,    -1,    -1,    61,
+      62,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    53,
+      -1,    -1,    56,    57,    58,    59,    60,    -1,    -1,    63,
+      64,    65,    66,    67,    68,    69,    88,    89,    90,    91,
+      92,    93,    94,    -1,    -1,    79,    -1,    99,    -1,    -1,
+     102,   103,   104,   105,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    95,    96,    -1,    98,    -1,   100,   101,    -1,    -1,
+      61,    62,    -1,   107,    -1,   109,   110,    10,    -1,    12,
+      -1,    14,    15,    16,    17,    18,    -1,    -1,    21,    22,
+      23,    24,    25,    -1,    27,    28,    29,    30,    31,    32,
+      91,    92,    93,    94,    -1,    38,    39,    -1,    99,    -1,
+      -1,   102,   103,   104,   105,    -1,    -1,    -1,    -1,    -1,
+      53,    -1,    -1,    56,    57,    58,    59,    60,    -1,    -1,
+      63,    64,    65,    66,    67,    68,    69,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    79,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    95,    96,    -1,    98,    -1,   100,   101,    -1,
+      -1,    -1,    -1,    -1,   107,    -1,   109,   110,    12,    13,
       14,    15,    16,    17,    18,    -1,    -1,    21,    22,    23,
       24,    25,    -1,    27,    28,    29,    30,    31,    32,    -1,
-      -1,    -1,    -1,    -1,    38,    39,    42,    43,    44,    45,
-      -1,    -1,    -1,    49,    -1,    51,    -1,    -1,    -1,    53,
+      -1,    -1,    -1,    -1,    38,    39,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    53,
       -1,    -1,    56,    57,    58,    59,    60,    -1,    -1,    63,
       64,    65,    66,    67,    68,    69,    -1,    -1,    -1,    -1,
-      76,    77,    78,    -1,    -1,    79,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    79,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
       -1,    95,    96,    -1,    98,    -1,   100,   101,    -1,    -1,
-      -1,    -1,    -1,   107,    -1,   109,   110,    12,    13,    14,
+      -1,    -1,    -1,   107,    -1,   109,   110,    12,    -1,    14,
       15,    16,    17,    18,    -1,    -1,    21,    22,    23,    24,
       25,    -1,    27,    28,    29,    30,    31,    32,    -1,    -1,
       -1,    -1,    -1,    38,    39,    -1,    -1,    -1,    -1,    -1,
@@ -895,7 +902,7 @@ static const yytype_int16 yycheck[] =
       -1,    -1,    -1,    -1,    79,    -1,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
       95,    96,    -1,    98,    -1,   100,   101,    -1,    -1,    -1,
-      -1,    -1,   107,    -1,   109,   110,    12,    -1,    14,    15,
+      -1,    -1,   107,   108,   109,   110,    12,    -1,    14,    15,
       16,    17,    18,    -1,    -1,    21,    22,    23,    24,    25,
       -1,    27,    28,    29,    30,    31,    32,    -1,    -1,    -1,
       -1,    -1,    38,    39,    -1,    -1,    -1,    -1,    -1,    -1,
@@ -905,7 +912,7 @@ static const yytype_int16 yycheck[] =
       -1,    -1,    -1,    79,    -1,    -1,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    95,
       96,    -1,    98,    -1,   100,   101,    -1,    -1,    -1,    -1,
-      -1,   107,   108,   109,   110,    12,    -1,    14,    15,    16,
+     106,   107,    -1,   109,   110,    12,    -1,    14,    15,    16,
       17,    18,    -1,    -1,    21,    22,    23,    24,    25,    -1,
       27,    28,    29,    30,    31,    32,    -1,    -1,    -1,    -1,
       -1,    38,    39,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
@@ -974,7 +981,7 @@ static const yytype_int16 yycheck[] =
       -1,    -1,    -1,    -1,    -1,    -1,    79,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
       -1,    -1,    95,    96,    -1,    98,    -1,   100,   101,    -1,
-      -1,    -1,    -1,   106,   107,    -1,   109,   110,    12,    -1,
+      -1,    -1,    -1,    -1,   107,    -1,   109,   110,    12,    -1,
       14,    15,    16,    17,    18,    -1,    -1,    21,    22,    23,
       24,    25,    -1,    27,    28,    29,    30,    31,    32,    -1,
       -1,    -1,    -1,    -1,    38,    39,    -1,    -1,    -1,    -1,
@@ -982,35 +989,21 @@ static const yytype_int16 yycheck[] =
       -1,    -1,    56,    57,    58,    59,    60,    -1,    -1,    63,
       64,    65,    66,    67,    68,    69,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    79,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      54,    -1,    -1,    -1,    -1,    -1,    -1,    61,    62,    -1,
       -1,    95,    96,    -1,    98,    -1,   100,   101,    -1,    -1,
-      -1,    -1,    -1,   107,    -1,   109,   110,    12,    -1,    14,
-      15,    16,    17,    18,    -1,    -1,    21,    22,    23,    24,
-      25,    -1,    27,    28,    29,    30,    31,    32,    -1,    -1,
-      -1,    -1,    -1,    38,    39,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    53,    -1,
-      -1,    56,    57,    58,    59,    60,    -1,    -1,    63,    64,
-      65,    66,    67,    68,    69,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    79,    -1,    -1,    -1,    -1,    54,
-      -1,    -1,    -1,    -1,    -1,    -1,    61,    62,    -1,    -1,
-      95,    96,    -1,    98,    -1,   100,   101,    -1,    -1,    -1,
-      -1,    -1,   107,    -1,   109,   110,    81,    82,    83,    84,
-      85,    86,    87,    88,    89,    90,    91,    92,    93,    94,
-      -1,    -1,    -1,    -1,    99,    54,    -1,   102,   103,   104,
-     105,    -1,    61,    62,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    81,    82,    -1,    84,    85,    86,    87,    88,
-      89,    90,    91,    92,    93,    94,    -1,    -1,    -1,    -1,
-      99,    54,    -1,   102,   103,   104,   105,    -1,    61,    62,
+      -1,    -1,    -1,   107,    -1,   109,   110,    81,    82,    -1,
+      84,    85,    86,    87,    88,    89,    90,    91,    92,    93,
+      94,    -1,    -1,    -1,    -1,    99,    54,    -1,   102,   103,
+     104,   105,    -1,    61,    62,    -1,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    82,
-      -1,    84,    85,    86,    87,    88,    89,    90,    91,    92,
-      93,    94,    -1,    -1,    -1,    -1,    99,    54,    -1,   102,
-     103,   104,   105,    -1,    61,    62,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    82,    -1,    84,    85,    86,    87,
+      88,    89,    90,    91,    92,    93,    94,    -1,    -1,    -1,
+      -1,    99,    54,    -1,   102,   103,   104,   105,    -1,    61,
+      62,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    84,    85,    86,
-      87,    88,    89,    90,    91,    92,    93,    94,    -1,    -1,
-      -1,    -1,    99,    -1,    -1,   102,   103,   104,   105
+      -1,    -1,    84,    85,    86,    87,    88,    89,    90,    91,
+      92,    93,    94,    -1,    -1,    -1,    -1,    99,    -1,    -1,
+     102,   103,   104,   105
 };
 
   /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -1022,59 +1015,59 @@ static const yytype_uint8 yystos[] =
       15,    16,    17,    18,    21,    22,    23,    24,    25,    27,
       28,    29,    30,    31,    32,    38,    39,    53,    56,    57,
       58,    59,    60,    63,    64,    65,    66,    67,    68,    69,
-      79,    95,    96,    98,   100,   101,   107,   109,   110,   173,
-     174,   175,   178,   179,   180,   181,   182,   183,   184,   185,
-     186,   187,   189,   192,   198,   199,   200,   201,   202,   203,
-     204,   205,   206,    10,   121,     1,    33,    35,    36,    37,
+      79,    95,    96,    98,   100,   101,   107,   109,   110,   174,
+     175,   176,   179,   180,   181,   182,   183,   184,   185,   186,
+     187,   188,   190,   193,   199,   200,   201,   202,   203,   204,
+     205,   206,   207,    10,   121,     1,    33,    35,    36,    37,
       40,    41,    42,    43,    44,    45,    49,    50,    51,    52,
-      55,   108,   121,   130,   140,   173,    34,   128,   129,   130,
-     126,   167,   168,   126,    13,   173,   187,   187,    21,    26,
-     121,   199,   207,   207,   207,   207,   207,   188,    12,   107,
-     187,   151,   151,   151,   187,   107,   107,    73,   107,   121,
-     187,    21,   174,   191,   199,   207,   207,   121,   187,   108,
-     173,    21,    26,   153,   187,    98,   107,   190,   199,   200,
-     201,   187,   174,   187,   187,   187,   187,   187,   106,   173,
-     207,   207,    76,    77,    78,    80,    10,    12,   107,    91,
+      55,   108,   121,   130,   141,   174,    34,   128,   129,   130,
+     126,   168,   169,   126,    13,   174,   188,   188,    21,    26,
+     121,   200,   208,   208,   208,   208,   208,   189,    12,   107,
+     188,   152,   152,   152,   188,   107,   107,    73,   107,   121,
+     188,    21,   175,   192,   200,   208,   208,   121,   188,   108,
+     174,    21,    26,   154,   188,    98,   107,   191,   200,   201,
+     202,   188,   175,   188,   188,   188,   188,   188,   106,   174,
+     208,   208,    76,    77,    78,    80,    10,    12,   107,    91,
       92,    91,    89,    90,    89,    54,    61,    62,    81,    82,
       84,    85,    86,    87,    88,    89,    90,    91,    92,    93,
       94,    99,   102,   103,   104,   105,   107,    10,    12,    10,
-      12,    10,    12,    10,   123,   152,   153,   153,    21,   150,
-     107,   107,   107,   107,    68,    98,   107,   197,   199,   107,
-     107,   121,   108,    48,   142,   108,    42,    43,    44,    45,
-      49,    51,   129,   130,   128,    16,    17,   109,   158,   159,
-     161,   162,   163,   164,    13,   191,   107,    73,   173,   106,
-     121,    24,   154,    70,   155,   106,   106,   173,   192,   192,
-     207,   174,    11,   108,   191,   107,   187,   190,   199,   200,
-     201,   106,   173,    70,   156,    12,   106,   173,   173,   173,
-     187,   173,   173,   106,   173,   187,   187,   187,   187,   187,
-     187,   187,   187,   187,   187,   187,   187,   187,   187,   187,
-     187,   187,   187,   187,    10,    12,    16,    17,    18,    22,
-      63,   107,   109,   110,   177,   199,   106,   173,   173,   173,
-     173,   173,   173,   173,   173,   126,    21,   149,   150,   150,
-      21,   133,   123,   123,   123,   123,    98,   123,    68,   195,
-     196,   198,   199,   200,   201,   123,   123,   107,   123,   123,
-     121,   173,   146,   173,   173,   173,   173,   173,    26,   157,
-     157,    80,   192,   174,    13,   176,   155,    24,   123,   172,
-     106,    74,   106,   173,    11,   106,   173,   156,   106,    24,
-     173,    12,   108,    13,   106,    83,   173,   173,   110,   110,
-     110,   110,   106,   173,   110,   110,   107,   106,   108,    13,
-     108,    13,   108,    13,   108,    11,    19,   122,   131,   132,
-      10,   108,    21,   145,   173,   146,   147,   173,   147,   194,
-     199,   107,   140,   144,   147,   148,   173,   195,   123,   147,
-     147,    81,   160,   160,   162,   106,   111,   193,   191,   123,
-     170,   107,   165,   166,   106,   106,    13,   173,    11,   187,
-     108,    13,   106,   192,    11,    11,    11,    11,   123,   154,
-     155,   123,    21,   106,   106,   106,   106,   107,   123,   106,
-     108,   136,   147,   106,   106,   187,   173,    74,    10,   167,
-      10,    13,    11,   106,   108,   155,   108,   171,   172,   137,
-     191,   143,   143,    10,   124,   124,   147,   147,   124,   134,
-     107,   106,   124,   124,   126,   106,   126,    72,   108,   169,
-     170,   126,   108,   124,   124,   125,    46,    47,   141,   141,
-     106,   106,   142,   145,   147,   124,    11,    11,   127,    11,
-     142,   142,   126,   124,   107,   124,   124,   108,   106,   142,
-      24,   108,   138,    11,   147,   142,   142,   135,   124,    71,
-     139,    20,   106,   143,   142,   126,   124,   148,    72,   141,
-     106,   124
+      12,    10,    12,    10,   123,   153,   154,   154,    21,   151,
+     107,   107,   107,   107,    68,    98,   107,   198,   200,   107,
+     107,   121,   108,    48,   143,   108,    42,    43,    44,    45,
+      49,    51,   129,   130,   128,    16,    17,   109,   159,   160,
+     162,   163,   164,   165,    13,   192,   107,    73,   174,   106,
+     121,    24,   155,    70,   156,   106,   106,   174,   193,   193,
+     208,   175,    11,   108,   192,   107,   188,   191,   200,   201,
+     202,   106,   174,    70,   157,    12,   106,   174,   174,   174,
+     188,   174,   174,   106,   174,   188,   188,   188,   188,   188,
+     188,   188,   188,   188,   188,   188,   188,   188,   188,   188,
+     188,   188,   188,   188,    10,    12,    16,    17,    18,    22,
+      63,   107,   109,   110,   178,   200,   106,   174,   174,   174,
+     174,   174,   174,   174,   174,   126,    21,   150,   151,   151,
+      21,   133,   123,   123,   123,   123,    98,   123,    68,   196,
+     197,   199,   200,   201,   202,   123,   123,   107,   123,   123,
+     121,   140,   174,   147,   174,   140,   140,   140,   140,    26,
+     158,   158,    80,   193,   175,    13,   177,   156,    24,   123,
+     173,   106,    74,   106,   174,    11,   106,   174,   157,   106,
+      24,   174,    12,   108,    13,   106,    83,   174,   174,   110,
+     110,   110,   110,   106,   174,   110,   110,   107,   106,   108,
+      13,   108,    13,   108,    13,   108,    11,    19,   122,   131,
+     132,    10,   108,    21,   146,   174,   147,   148,   174,   148,
+     195,   200,   107,   141,   145,   148,   149,   174,   196,   123,
+     148,   148,    81,   161,   161,   163,   106,   111,   194,   192,
+     123,   171,   107,   166,   167,   106,   106,    13,   174,    11,
+     188,   108,    13,   106,   193,    11,    11,    11,    11,   123,
+     155,   156,   123,    21,   106,   106,   106,   106,   107,   123,
+     106,   108,   136,   148,   106,   106,   188,   174,    74,    10,
+     168,    10,    13,    11,   106,   108,   156,   108,   172,   173,
+     137,   192,   144,   144,    10,   124,   124,   148,   148,   124,
+     134,   107,   106,   124,   124,   126,   106,   126,    72,   108,
+     170,   171,   126,   108,   124,   124,   125,    46,    47,   142,
+     142,   106,   106,   143,   146,   148,   124,    11,    11,   127,
+      11,   143,   143,   126,   124,   107,   124,   124,   108,   106,
+     143,    24,   108,   138,    11,   148,   143,   143,   135,   124,
+      71,   139,    20,   106,   144,   143,   126,   124,   149,    72,
+     142,   106,   124
 };
 
   /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
@@ -1086,34 +1079,34 @@ static const yytype_uint8 yyr1[] =
      130,   131,   130,   132,   130,   130,   133,   130,   130,   130,
      130,   130,   130,   130,   130,   134,   135,   130,   130,   130,
      136,   130,   130,   130,   130,   137,   130,   130,   130,   130,
-     138,   139,   139,   140,   140,   140,   140,   140,   140,   140,
-     140,   141,   141,   141,   142,   142,   143,   144,   144,   145,
-     145,   146,   147,   148,   149,   149,   150,   151,   152,   153,
-     153,   154,   154,   155,   155,   155,   156,   156,   157,   157,
-     158,   158,   159,   160,   160,   160,   161,   162,   162,   163,
-     163,   163,   164,   164,   165,   165,   166,   168,   167,   169,
-     169,   170,   171,   171,   172,   173,   173,   173,   173,   174,
-     174,   174,   175,   175,   175,   175,   175,   175,   175,   175,
-     175,   176,   175,   177,   177,   178,   178,   178,   178,   178,
-     178,   178,   178,   178,   178,   178,   178,   178,   178,   179,
+     138,   139,   139,   140,   141,   141,   141,   141,   141,   141,
+     141,   141,   142,   142,   142,   143,   143,   144,   145,   145,
+     146,   146,   147,   148,   149,   150,   150,   151,   152,   153,
+     154,   154,   155,   155,   156,   156,   156,   157,   157,   158,
+     158,   159,   159,   160,   161,   161,   161,   162,   163,   163,
+     164,   164,   164,   165,   165,   166,   166,   167,   169,   168,
+     170,   170,   171,   172,   172,   173,   174,   174,   174,   174,
+     175,   175,   175,   176,   176,   176,   176,   176,   176,   176,
+     176,   176,   177,   176,   178,   178,   179,   179,   179,   179,
      179,   179,   179,   179,   179,   179,   179,   179,   179,   179,
-     179,   179,   179,   180,   180,   180,   180,   181,   181,   182,
-     182,   182,   182,   183,   183,   184,   184,   184,   184,   184,
-     184,   184,   184,   184,   185,   185,   185,   185,   185,   185,
-     186,   186,   187,   187,   187,   187,   187,   187,   187,   187,
-     187,   187,   187,   187,   187,   187,   187,   187,   187,   187,
-     187,   187,   187,   187,   187,   187,   187,   187,   187,   187,
-     187,   187,   187,   187,   187,   187,   187,   187,   187,   187,
-     187,   187,   187,   187,   187,   187,   187,   187,   187,   187,
-     187,   188,   187,   187,   187,   187,   189,   189,   189,   190,
-     190,   190,   190,   190,   191,   191,   192,   192,   193,   193,
-     194,   195,   195,   195,   196,   196,   197,   197,   198,   199,
-     200,   201,   202,   202,   203,   204,   204,   205,   205,   206,
-     206,   207,   207,   207,   207
+     180,   180,   180,   180,   180,   180,   180,   180,   180,   180,
+     180,   180,   180,   180,   181,   181,   181,   181,   182,   182,
+     183,   183,   183,   183,   184,   184,   185,   185,   185,   185,
+     185,   185,   185,   185,   185,   186,   186,   186,   186,   186,
+     186,   187,   187,   188,   188,   188,   188,   188,   188,   188,
+     188,   188,   188,   188,   188,   188,   188,   188,   188,   188,
+     188,   188,   188,   188,   188,   188,   188,   188,   188,   188,
+     188,   188,   188,   188,   188,   188,   188,   188,   188,   188,
+     188,   188,   188,   188,   188,   188,   188,   188,   188,   188,
+     188,   188,   189,   188,   188,   188,   188,   190,   190,   190,
+     191,   191,   191,   191,   191,   192,   192,   193,   193,   194,
+     194,   195,   196,   196,   196,   197,   197,   198,   198,   199,
+     200,   201,   202,   203,   203,   204,   205,   205,   206,   206,
+     207,   207,   208,   208,   208,   208
 };
 
   /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
-static const yytype_uint8 yyr2[] =
+static const yytype_int8 yyr2[] =
 {
        0,     2,     0,     4,     0,     3,     0,     3,     0,     3,
        0,     3,     0,     3,     0,     3,     4,     7,     0,     4,
@@ -1121,30 +1114,30 @@ static const yytype_uint8 yyr2[] =
        4,     0,     7,     0,     6,     4,     0,     7,     7,     7,
        6,     6,     2,     8,     8,     0,     0,    13,     9,     8,
        0,    10,     9,     7,     2,     0,     8,     2,     2,     1,
-       2,     0,     3,     1,     1,     3,     3,     3,     3,     3,
-       3,     0,     2,     6,     0,     2,     0,     0,     1,     0,
-       1,     1,     1,     1,     1,     0,     0,     0,     0,     1,
-       1,     0,     1,     0,     2,     1,     2,     1,     0,     1,
-       1,     1,     3,     0,     1,     2,     3,     1,     1,     2,
-       3,     1,     0,     1,     0,     1,     3,     0,     2,     1,
-       1,     4,     1,     1,     5,     3,     3,     3,     1,     2,
-       3,     1,     3,     5,     6,     3,     3,     5,     2,     4,
-       4,     0,     5,     1,     1,     5,     4,     5,     4,     5,
-       6,     5,     4,     5,     4,     3,     6,     4,     5,     3,
-       3,     3,     3,     3,     1,     1,     3,     3,     3,     3,
-       3,     3,     3,     1,     3,     2,     2,     3,     3,     1,
-       3,     2,     2,     3,     3,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     3,     2,     4,     3,     5,     4,
-       2,     2,     1,     1,     1,     1,     5,     2,     3,     1,
-       2,     3,     1,     2,     1,     1,     1,     1,     1,     1,
-       4,     4,     5,     5,     1,     1,     3,     4,     3,     4,
-       4,     4,     4,     4,     1,     2,     2,     1,     2,     2,
-       1,     2,     1,     2,     1,     3,     1,     3,     1,     3,
-       4,     0,     6,     1,     1,     1,     3,     2,     4,     3,
-       2,     1,     1,     1,     0,     1,     0,     1,     0,     2,
-       1,     1,     1,     1,     1,     1,     2,     2,     2,     2,
-       2,     2,     2,     4,     2,     1,     3,     1,     3,     1,
-       3,     1,     1,     1,     1
+       2,     0,     3,     1,     1,     1,     3,     3,     3,     3,
+       3,     3,     0,     2,     6,     0,     2,     0,     0,     1,
+       0,     1,     1,     1,     1,     1,     0,     0,     0,     0,
+       1,     1,     0,     1,     0,     2,     1,     2,     1,     0,
+       1,     1,     1,     3,     0,     1,     2,     3,     1,     1,
+       2,     3,     1,     0,     1,     0,     1,     3,     0,     2,
+       1,     1,     4,     1,     1,     5,     3,     3,     3,     1,
+       2,     3,     1,     3,     5,     6,     3,     3,     5,     2,
+       4,     4,     0,     5,     1,     1,     5,     4,     5,     4,
+       5,     6,     5,     4,     5,     4,     3,     6,     4,     5,
+       3,     3,     3,     3,     3,     1,     1,     3,     3,     3,
+       3,     3,     3,     3,     1,     3,     2,     2,     3,     3,
+       1,     3,     2,     2,     3,     3,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     3,     2,     4,     3,     5,
+       4,     2,     2,     1,     1,     1,     1,     5,     2,     3,
+       1,     2,     3,     1,     2,     1,     1,     1,     1,     1,
+       1,     4,     4,     5,     5,     1,     1,     3,     4,     3,
+       4,     4,     4,     4,     4,     1,     2,     2,     1,     2,
+       2,     1,     2,     1,     2,     1,     3,     1,     3,     1,
+       3,     4,     0,     6,     1,     1,     1,     3,     2,     4,
+       3,     2,     1,     1,     1,     0,     1,     0,     1,     0,
+       2,     1,     1,     1,     1,     1,     1,     2,     2,     2,
+       2,     2,     2,     2,     4,     2,     1,     3,     1,     3,
+       1,     3,     1,     1,     1,     1
 };
 
 typedef enum {
@@ -1173,10 +1166,10 @@ static const toketypes yy_type_tab[] =
   toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_ival, toketype_opval,
   toketype_opval, toketype_ival, toketype_opval, toketype_ival, toketype_opval, toketype_opval,
   toketype_opval, toketype_opval, toketype_opval, toketype_ival, toketype_ival, toketype_ival, toketype_ival,
-  toketype_ival, toketype_ival, toketype_ival, toketype_opval, toketype_opval, toketype_opval, toketype_opval, toketype_opval,
-  toketype_ival, toketype_opval, toketype_opval, toketype_opval, toketype_opval, toketype_opval, toketype_opval,
-  toketype_ival, toketype_ival, toketype_ival, toketype_opval, toketype_opval,
-  toketype_opval, toketype_opval, toketype_opval, toketype_ival,
+  toketype_ival, toketype_ival, toketype_ival, toketype_opval, toketype_opval, toketype_opval, toketype_opval,
+  toketype_opval, toketype_opval, toketype_ival, toketype_opval, toketype_opval, toketype_opval, toketype_opval, toketype_opval,
+  toketype_opval, toketype_ival, toketype_ival, toketype_ival, toketype_opval,
+  toketype_opval, toketype_opval, toketype_opval, toketype_opval, toketype_ival,
   toketype_opval, toketype_opval, toketype_opval, toketype_opval, toketype_opval,
   toketype_opval, toketype_opval, toketype_opval, toketype_opval, toketype_ival,
   toketype_opval, toketype_opval, toketype_opval, toketype_opval, toketype_opval,
@@ -1189,6 +1182,6 @@ static const toketypes yy_type_tab[] =
 };
 
 /* Generated from:
- * f83d884147747f2d8f5a62eebc4ccd07d71b6b34e5ba1a8d7559526ad864dc97 perly.y
- * 01ce33b49f9f04b8d3112b7f042cde113a7d29763a846e870f9766072a5bc614 regen_perly.pl
+ * cb0b53384d9fa75068c8e30d8fe9016dec2e65e0a5c16ce6479563d6b41626d6 perly.y
+ * acf1cbfd2545faeaaa58b1cf0cf9d7f98b5be0752eb7a54528ef904a9e2e1ca7 regen_perly.pl
  * ex: set ro: */
diff --git a/perly.y b/perly.y
index 843a3b1..433de1f 100644 (file)
--- a/perly.y
+++ b/perly.y
@@ -69,6 +69,7 @@
 
 %type <opval> stmtseq fullstmt labfullstmt barestmt block mblock else
 %type <opval> expr term subscripted scalar ary hsh arylen star amper sideff
+%type <opval> condition
 %type <opval> sliceme kvslice gelem
 %type <opval> listexpr nexpr texpr iexpr mexpr mnexpr
 %type <opval> optlistexpr optexpr optrepl indirob listop method
@@ -124,7 +125,7 @@ grammar     :       GRAMPROG
                        }
                remember stmtseq
                        {
-                         newPROG(block_end($3,$4));
+                         newPROG(block_end($remember,$stmtseq));
                          PL_compiling.cop_seq = 0;
                          $$ = 0;
                        }
@@ -135,7 +136,7 @@ grammar     :       GRAMPROG
                        }
                optexpr
                        {
-                         PL_eval_root = $3;
+                         PL_eval_root = $optexpr;
                          $$ = 0;
                        }
        |       GRAMBLOCK
@@ -146,7 +147,7 @@ grammar     :       GRAMPROG
                block
                        {
                          PL_pad_reset_pending = TRUE;
-                         PL_eval_root = $3;
+                         PL_eval_root = $block;
                          $$ = 0;
                          yyunlex();
                          parser->yychar = yytoken = YYEOF;
@@ -159,7 +160,7 @@ grammar     :       GRAMPROG
                barestmt
                        {
                          PL_pad_reset_pending = TRUE;
-                         PL_eval_root = $3;
+                         PL_eval_root = $barestmt;
                          $$ = 0;
                          yyunlex();
                          parser->yychar = yytoken = YYEOF;
@@ -172,7 +173,7 @@ grammar     :       GRAMPROG
                fullstmt
                        {
                          PL_pad_reset_pending = TRUE;
-                         PL_eval_root = $3;
+                         PL_eval_root = $fullstmt;
                          $$ = 0;
                          yyunlex();
                          parser->yychar = yytoken = YYEOF;
@@ -184,7 +185,7 @@ grammar     :       GRAMPROG
                        }
                stmtseq
                        {
-                         PL_eval_root = $3;
+                         PL_eval_root = $stmtseq;
                          $$ = 0;
                        }
        |       GRAMSUBSIGNATURE
@@ -194,7 +195,7 @@ grammar     :       GRAMPROG
                        }
                subsigguts
                        {
-                         PL_eval_root = $3;
+                         PL_eval_root = $subsigguts;
                          $$ = 0;
                        }
        ;
@@ -203,7 +204,7 @@ grammar     :       GRAMPROG
 block  :       '{' remember stmtseq '}'
                        { if (parser->copline > (line_t)$1)
                              parser->copline = (line_t)$1;
-                         $$ = block_end($2, $3);
+                         $$ = block_end($remember, $stmtseq);
                        }
        ;
 
@@ -211,7 +212,7 @@ block       :       '{' remember stmtseq '}'
 formblock:     '=' remember ';' FORMRBRACK formstmtseq ';' '.'
                        { if (parser->copline > (line_t)$1)
                              parser->copline = (line_t)$1;
-                         $$ = block_end($2, $5);
+                         $$ = block_end($remember, $formstmtseq);
                        }
        ;
 
@@ -223,7 +224,7 @@ remember:   /* NULL */      /* start a full lexical scope */
 mblock :       '{' mremember stmtseq '}'
                        { if (parser->copline > (line_t)$1)
                              parser->copline = (line_t)$1;
-                         $$ = block_end($2, $3);
+                         $$ = block_end($mremember, $stmtseq);
                        }
        ;
 
@@ -235,10 +236,10 @@ mremember:        /* NULL */      /* start a partial lexical scope */
 /* A sequence of statements in the program */
 stmtseq        :       /* NULL */
                        { $$ = NULL; }
-       |       stmtseq fullstmt
-                       {   $$ = op_append_list(OP_LINESEQ, $1, $2);
+       |       stmtseq[list] fullstmt
+                       {   $$ = op_append_list(OP_LINESEQ, $list, $fullstmt);
                            PL_pad_reset_pending = TRUE;
-                           if ($1 && $2)
+                           if ($list && $fullstmt)
                                PL_hints |= HINT_BLOCK_SCOPE;
                        }
        ;
@@ -246,10 +247,10 @@ stmtseq   :       /* NULL */
 /* A sequence of format lines */
 formstmtseq:   /* NULL */
                        { $$ = NULL; }
-       |       formstmtseq formline
-                       {   $$ = op_append_list(OP_LINESEQ, $1, $2);
+       |       formstmtseq[list] formline
+                       {   $$ = op_append_list(OP_LINESEQ, $list, $formline);
                            PL_pad_reset_pending = TRUE;
-                           if ($1 && $2)
+                           if ($list && $formline)
                                PL_hints |= HINT_BLOCK_SCOPE;
                        }
        ;
@@ -257,35 +258,35 @@ formstmtseq:      /* NULL */
 /* A statement in the program, including optional labels */
 fullstmt:      barestmt
                        {
-                         $$ = $1 ? newSTATEOP(0, NULL, $1) : NULL;
+                         $$ = $barestmt ? newSTATEOP(0, NULL, $barestmt) : NULL;
                        }
        |       labfullstmt
-                       { $$ = $1; }
+                       { $$ = $labfullstmt; }
        ;
 
 labfullstmt:   LABEL barestmt
                        {
-                          SV *label = cSVOPx_sv($1);
+                          SV *label = cSVOPx_sv($LABEL);
                          $$ = newSTATEOP(SvFLAGS(label) & SVf_UTF8,
-                                            savepv(SvPVX_const(label)), $2);
-                          op_free($1);
+                                            savepv(SvPVX_const(label)), $barestmt);
+                          op_free($LABEL);
                        }
-       |       LABEL labfullstmt
+       |       LABEL labfullstmt[list]
                        {
-                          SV *label = cSVOPx_sv($1);
+                          SV *label = cSVOPx_sv($LABEL);
                          $$ = newSTATEOP(SvFLAGS(label) & SVf_UTF8,
-                                            savepv(SvPVX_const(label)), $2);
-                          op_free($1);
+                                            savepv(SvPVX_const(label)), $list);
+                          op_free($LABEL);
                        }
        ;
 
 /* A bare statement, lacking label and other aspects of state op */
 barestmt:      PLUGSTMT
-                       { $$ = $1; }
+                       { $$ = $PLUGSTMT; }
        |       FORMAT startformsub formname formblock
                        {
                          CV *fmtcv = PL_compcv;
-                         newFORM($2, $3, $4);
+                         newFORM($startformsub, $formname, $formblock);
                          $$ = NULL;
                          if (CvOUTSIDE(fmtcv) && !CvEVAL(CvOUTSIDE(fmtcv))) {
                              pad_add_weakref(fmtcv);
@@ -296,16 +297,16 @@ barestmt: PLUGSTMT
                     /* sub declaration or definition not within scope
                        of 'use feature "signatures"'*/
                        {
-                          init_named_cv(PL_compcv, $2);
+                          init_named_cv(PL_compcv, $subname);
                          parser->in_my = 0;
                          parser->in_my_stash = NULL;
                        }
                     proto subattrlist optsubbody
                        {
                          SvREFCNT_inc_simple_void(PL_compcv);
-                         $2->op_type == OP_CONST
-                             ? newATTRSUB($3, $2, $5, $6, $7)
-                             : newMYSUB($3, $2, $5, $6, $7)
+                         $subname->op_type == OP_CONST
+                             ? newATTRSUB($startsub, $subname, $proto, $subattrlist, $optsubbody)
+                             : newMYSUB($startsub, $subname, $proto, $subattrlist, $optsubbody)
                          ;
                          $$ = NULL;
                          intro_my();
@@ -317,82 +318,82 @@ barestmt: PLUGSTMT
                      * allowed in a declaration)
                      */
                        {
-                          init_named_cv(PL_compcv, $2);
+                          init_named_cv(PL_compcv, $subname);
                          parser->in_my = 0;
                          parser->in_my_stash = NULL;
                        }
                     subattrlist optsigsubbody
                        {
                          SvREFCNT_inc_simple_void(PL_compcv);
-                         $2->op_type == OP_CONST
-                             ? newATTRSUB($3, $2, NULL, $5, $6)
-                             : newMYSUB(  $3, $2, NULL, $5, $6)
+                         $subname->op_type == OP_CONST
+                             ? newATTRSUB($startsub, $subname, NULL, $subattrlist, $optsigsubbody)
+                             : newMYSUB(  $startsub, $subname, NULL, $subattrlist, $optsigsubbody)
                          ;
                          $$ = NULL;
                          intro_my();
                          parser->parsed_sub = 1;
                        }
-       |       PACKAGE BAREWORD BAREWORD ';'
+       |       PACKAGE BAREWORD[version] BAREWORD[package] ';'
                        {
-                         package($3);
-                         if ($2)
-                             package_version($2);
+                         package($package);
+                         if ($version)
+                             package_version($version);
                          $$ = NULL;
                        }
        |       USE startsub
                        { CvSPECIAL_on(PL_compcv); /* It's a BEGIN {} */ }
-               BAREWORD BAREWORD optlistexpr ';'
+               BAREWORD[version] BAREWORD[module] optlistexpr ';'
                        {
                          SvREFCNT_inc_simple_void(PL_compcv);
-                         utilize($1, $2, $4, $5, $6);
+                         utilize($USE, $startsub, $version, $module, $optlistexpr);
                          parser->parsed_sub = 1;
                          $$ = NULL;
                        }
        |       IF '(' remember mexpr ')' mblock else
                        {
-                         $$ = block_end($3,
-                             newCONDOP(0, $4, op_scope($6), $7));
-                         parser->copline = (line_t)$1;
+                         $$ = block_end($remember,
+                             newCONDOP(0, $mexpr, op_scope($mblock), $else));
+                         parser->copline = (line_t)$IF;
                        }
        |       UNLESS '(' remember mexpr ')' mblock else
                        {
-                         $$ = block_end($3,
-                              newCONDOP(0, $4, $7, op_scope($6)));
-                         parser->copline = (line_t)$1;
+                         $$ = block_end($remember,
+                              newCONDOP(0, $mexpr, $else, op_scope($mblock)));
+                         parser->copline = (line_t)$UNLESS;
                        }
        |       GIVEN '(' remember mexpr ')' mblock
                        {
-                         $$ = block_end($3, newGIVENOP($4, op_scope($6), 0));
-                         parser->copline = (line_t)$1;
+                         $$ = block_end($remember, newGIVENOP($mexpr, op_scope($mblock), 0));
+                         parser->copline = (line_t)$GIVEN;
                        }
        |       WHEN '(' remember mexpr ')' mblock
-                       { $$ = block_end($3, newWHENOP($4, op_scope($6))); }
+                       { $$ = block_end($remember, newWHENOP($mexpr, op_scope($mblock))); }
        |       DEFAULT block
-                       { $$ = newWHENOP(0, op_scope($2)); }
+                       { $$ = newWHENOP(0, op_scope($block)); }
        |       WHILE '(' remember texpr ')' mintro mblock cont
                        {
-                         $$ = block_end($3,
+                         $$ = block_end($remember,
                                  newWHILEOP(0, 1, NULL,
-                                     $4, $7, $8, $6));
-                         parser->copline = (line_t)$1;
+                                     $texpr, $mblock, $cont, $mintro));
+                         parser->copline = (line_t)$WHILE;
                        }
        |       UNTIL '(' remember iexpr ')' mintro mblock cont
                        {
-                         $$ = block_end($3,
+                         $$ = block_end($remember,
                                  newWHILEOP(0, 1, NULL,
-                                     $4, $7, $8, $6));
-                         parser->copline = (line_t)$1;
+                                     $iexpr, $mblock, $cont, $mintro));
+                         parser->copline = (line_t)$UNTIL;
                        }
-       |       FOR '(' remember mnexpr ';'
+       |       FOR '(' remember mnexpr[init_mnexpr] ';'
                        { parser->expect = XTERM; }
                texpr ';'
                        { parser->expect = XTERM; }
-               mintro mnexpr ')'
+               mintro mnexpr[iterate_mnexpr] ')'
                mblock
                        {
-                         OP *initop = $4;
+                         OP *initop = $init_mnexpr;
                          OP *forop = newWHILEOP(0, 1, NULL,
-                                     scalar($7), $13, $11, $10);
+                                     scalar($texpr), $mblock, $iterate_mnexpr, $mintro);
                          if (initop) {
                              forop = op_prepend_elem(OP_LINESEQ, initop,
                                  op_append_elem(OP_LINESEQ,
@@ -400,73 +401,73 @@ barestmt: PLUGSTMT
                                      forop));
                          }
                          PL_hints |= HINT_BLOCK_SCOPE;
-                         $$ = block_end($3, forop);
-                         parser->copline = (line_t)$1;
+                         $$ = block_end($remember, forop);
+                         parser->copline = (line_t)$FOR;
                        }
        |       FOR MY remember my_scalar '(' mexpr ')' mblock cont
                        {
-                         $$ = block_end($3, newFOROP(0, $4, $6, $8, $9));
-                         parser->copline = (line_t)$1;
+                         $$ = block_end($remember, newFOROP(0, $my_scalar, $mexpr, $mblock, $cont));
+                         parser->copline = (line_t)$FOR;
                        }
        |       FOR scalar '(' remember mexpr ')' mblock cont
                        {
-                         $$ = block_end($4, newFOROP(0,
-                                     op_lvalue($2, OP_ENTERLOOP), $5, $7, $8));
-                         parser->copline = (line_t)$1;
+                         $$ = block_end($remember, newFOROP(0,
+                                     op_lvalue($scalar, OP_ENTERLOOP), $mexpr, $mblock, $cont));
+                         parser->copline = (line_t)$FOR;
                        }
        |       FOR my_refgen remember my_var
-                       { parser->in_my = 0; $<opval>$ = my($4); }
+                       { parser->in_my = 0; $<opval>$ = my($my_var); }[variable]
                '(' mexpr ')' mblock cont
                        {
                          $$ = block_end(
-                               $3,
+                               $remember,
                                newFOROP(0,
                                         op_lvalue(
                                            newUNOP(OP_REFGEN, 0,
-                                                   $<opval>5),
+                                                   $<opval>variable),
                                            OP_ENTERLOOP),
-                                        $7, $9, $10)
+                                        $mexpr, $mblock, $cont)
                          );
-                         parser->copline = (line_t)$1;
+                         parser->copline = (line_t)$FOR;
                        }
        |       FOR REFGEN refgen_topic '(' remember mexpr ')' mblock cont
                        {
-                         $$ = block_end($5, newFOROP(
+                         $$ = block_end($remember, newFOROP(
                                0, op_lvalue(newUNOP(OP_REFGEN, 0,
-                                                    $3),
-                                            OP_ENTERLOOP), $6, $8, $9));
-                         parser->copline = (line_t)$1;
+                                                    $refgen_topic),
+                                            OP_ENTERLOOP), $mexpr, $mblock, $cont));
+                         parser->copline = (line_t)$FOR;
                        }
        |       FOR '(' remember mexpr ')' mblock cont
                        {
-                         $$ = block_end($3,
-                                 newFOROP(0, NULL, $4, $6, $7));
-                         parser->copline = (line_t)$1;
+                         $$ = block_end($remember,
+                                 newFOROP(0, NULL, $mexpr, $mblock, $cont));
+                         parser->copline = (line_t)$FOR;
                        }
        |       block cont
                        {
                          /* a block is a loop that happens once */
                          $$ = newWHILEOP(0, 1, NULL,
-                                 NULL, $1, $2, 0);
+                                 NULL, $block, $cont, 0);
                        }
-       |       PACKAGE BAREWORD BAREWORD '{' remember
+       |       PACKAGE BAREWORD[version] BAREWORD[package] '{' remember
                        {
-                         package($3);
-                         if ($2) {
-                             package_version($2);
+                         package($package);
+                         if ($version) {
+                             package_version($version);
                          }
                        }
                stmtseq '}'
                        {
                          /* a block is a loop that happens once */
                          $$ = newWHILEOP(0, 1, NULL,
-                                 NULL, block_end($5, $7), NULL, 0);
+                                 NULL, block_end($remember, $stmtseq), NULL, 0);
                          if (parser->copline > (line_t)$4)
                              parser->copline = (line_t)$4;
                        }
        |       sideff ';'
                        {
-                         $$ = $1;
+                         $$ = $sideff;
                        }
        |       YADAYADA ';'
                        {
@@ -483,12 +484,12 @@ barestmt: PLUGSTMT
 /* Format line */
 formline:      THING formarg
                        { OP *list;
-                         if ($2) {
-                             OP *term = $2;
-                             list = op_append_elem(OP_LIST, $1, term);
+                         if ($formarg) {
+                             OP *term = $formarg;
+                             list = op_append_elem(OP_LIST, $THING, term);
                          }
                          else {
-                             list = $1;
+                             list = $THING;
                          }
                          if (parser->copline == NOLINE)
                               parser->copline = CopLINE(PL_curcop)-1;
@@ -501,27 +502,30 @@ formline: THING formarg
 formarg        :       /* NULL */
                        { $$ = NULL; }
        |       FORMLBRACK stmtseq FORMRBRACK
-                       { $$ = op_unscope($2); }
+                       { $$ = op_unscope($stmtseq); }
        ;
 
+condition: expr
+;
+
 /* An expression which may have a side-effect */
 sideff :       error
                        { $$ = NULL; }
-       |       expr
-                       { $$ = $1; }
-       |       expr IF expr
-                       { $$ = newLOGOP(OP_AND, 0, $3, $1); }
-       |       expr UNLESS expr
-                       { $$ = newLOGOP(OP_OR, 0, $3, $1); }
-       |       expr WHILE expr
-                       { $$ = newLOOPOP(OPf_PARENS, 1, scalar($3), $1); }
-       |       expr UNTIL iexpr
-                       { $$ = newLOOPOP(OPf_PARENS, 1, $3, $1); }
-       |       expr FOR expr
-                       { $$ = newFOROP(0, NULL, $3, $1, NULL);
-                         parser->copline = (line_t)$2; }
-       |       expr WHEN expr
-                       { $$ = newWHENOP($3, op_scope($1)); }
+       |       expr[body]
+                       { $$ = $body; }
+       |       expr[body] IF condition
+                       { $$ = newLOGOP(OP_AND, 0, $condition, $body); }
+       |       expr[body] UNLESS condition
+                       { $$ = newLOGOP(OP_OR, 0, $condition, $body); }
+       |       expr[body] WHILE condition
+                       { $$ = newLOOPOP(OPf_PARENS, 1, scalar($condition), $body); }
+       |       expr[body] UNTIL iexpr
+                       { $$ = newLOOPOP(OPf_PARENS, 1, $iexpr, $body); }
+       |       expr[body] FOR condition
+                       { $$ = newFOROP(0, NULL, $condition, $body, NULL);
+                         parser->copline = (line_t)$FOR; }
+       |       expr[body] WHEN condition
+                       { $$ = newWHENOP($condition, op_scope($body)); }
        ;
 
 /* else and elsif blocks */
@@ -529,14 +533,14 @@ else      :       /* NULL */
                        { $$ = NULL; }
        |       ELSE mblock
                        {
-                         ($2)->op_flags |= OPf_PARENS;
-                         $$ = op_scope($2);
+                         ($mblock)->op_flags |= OPf_PARENS;
+                         $$ = op_scope($mblock);
                        }
-       |       ELSIF '(' mexpr ')' mblock else
-                       { parser->copline = (line_t)$1;
+       |       ELSIF '(' mexpr ')' mblock else[else.recurse]
+                       { parser->copline = (line_t)$ELSIF;
                            $$ = newCONDOP(0,
-                               newSTATEOP(OPf_SPECIAL,NULL,$3),
-                               op_scope($5), $6);
+                               newSTATEOP(OPf_SPECIAL,NULL,$mexpr),
+                               op_scope($mblock), $[else.recurse]);
                          PL_hints |= HINT_BLOCK_SCOPE;
                        }
        ;
@@ -545,7 +549,7 @@ else        :       /* NULL */
 cont   :       /* NULL */
                        { $$ = NULL; }
        |       CONTINUE block
-                       { $$ = op_scope($2); }
+                       { $$ = op_scope($block); }
        ;
 
 /* determine whether there are any new my declarations */
@@ -570,19 +574,19 @@ texpr     :       /* NULL means true */
 
 /* Inverted boolean expression */
 iexpr  :       expr
-                       { $$ = invert(scalar($1)); }
+                       { $$ = invert(scalar($expr)); }
        ;
 
 /* Expression with its own lexical scope */
 mexpr  :       expr
-                       { $$ = $1; intro_my(); }
+                       { $$ = $expr; intro_my(); }
        ;
 
 mnexpr :       nexpr
-                       { $$ = $1; intro_my(); }
+                       { $$ = $nexpr; intro_my(); }
        ;
 
-formname:      BAREWORD        { $$ = $1; }
+formname:      BAREWORD        { $$ = $BAREWORD; }
        |       /* NULL */      { $$ = NULL; }
        ;
 
@@ -617,14 +621,14 @@ proto     :       /* NULL */
 subattrlist:   /* NULL */
                        { $$ = NULL; }
        |       COLONATTR THING
-                       { $$ = $2; }
+                       { $$ = $THING; }
        |       COLONATTR
                        { $$ = NULL; }
        ;
 
 /* List of attributes for a "my" variable declaration */
 myattrlist:    COLONATTR THING
-                       { $$ = $2; }
+                       { $$ = $THING; }
        |       COLONATTR
                        { $$ = NULL; }
        ;
@@ -639,7 +643,7 @@ myattrlist: COLONATTR THING
 sigvarname:     /* NULL */
                        { parser->in_my = 0; $$ = NULL; }
         |       PRIVATEREF
-                        { parser->in_my = 0; $$ = $1; }
+                        { parser->in_my = 0; $$ = $PRIVATEREF; }
        ;
 
 sigslurpsigil:
@@ -651,9 +655,9 @@ sigslurpsigil:
 /* @, %, @foo, %foo */
 sigslurpelem: sigslurpsigil sigvarname sigdefault/* def only to catch errors */ 
                         {
-                            I32 sigil   = $1;
-                            OP *var     = $2;
-                            OP *defexpr = $3;
+                            I32 sigil   = $sigslurpsigil;
+                            OP *var     = $sigvarname;
+                            OP *defexpr = $sigdefault;
 
                             if (parser->sig_slurpy)
                                 yyerror("Multiple slurpy parameters not allowed");
@@ -673,15 +677,15 @@ sigdefault:       /* NULL */
         |       ASSIGNOP
                         { $$ = newOP(OP_NULL, 0); }
         |       ASSIGNOP term
-                        { $$ = $2; }
+                        { $$ = $term; }
 
 
 /* subroutine signature scalar element: e.g. '$x', '$=', '$x = $default' */
 sigscalarelem:
                 '$' sigvarname sigdefault
                         {
-                            OP *var     = $2;
-                            OP *defexpr = $3;
+                            OP *var     = $sigvarname;
+                            OP *defexpr = $sigdefault;
 
                             if (parser->sig_slurpy)
                                 yyerror("Slurpy parameter not last");
@@ -744,38 +748,38 @@ sigscalarelem:
 
 /* subroutine signature element: e.g. '$x = $default' or '%h' */
 sigelem:        sigscalarelem
-                        { parser->in_my = KEY_sigvar; $$ = $1; }
+                        { parser->in_my = KEY_sigvar; $$ = $sigscalarelem; }
         |       sigslurpelem
-                        { parser->in_my = KEY_sigvar; $$ = $1; }
+                        { parser->in_my = KEY_sigvar; $$ = $sigslurpelem; }
        ;
 
 /* list of subroutine signature elements */
 siglist:
-               siglist ','
-                       { $$ = $1; }
-       |       siglist ',' sigelem
+               siglist[list] ','
+                       { $$ = $list; }
+       |       siglist[list] ',' sigelem[element]
                        {
-                         $$ = op_append_list(OP_LINESEQ, $1, $3);
+                         $$ = op_append_list(OP_LINESEQ, $list, $element);
                        }
-        |      sigelem  %prec PREC_LOW
-                       { $$ = $1; }
+        |      sigelem[element]  %prec PREC_LOW
+                       { $$ = $element; }
        ;
 
 /* () or (....) */
 siglistornull:         /* NULL */
                        { $$ = NULL; }
        |       siglist
-                       { $$ = $1; }
+                       { $$ = $siglist; }
 
 /* optional subroutine signature */
 optsubsignature:       /* NULL */
                        { $$ = NULL; }
        |       subsignature
-                       { $$ = $1; }
+                       { $$ = $subsignature; }
 
 /* Subroutine signature */
 subsignature:  '(' subsigguts ')'
-                       { $$ = $2; }
+                       { $$ = $subsigguts; }
 
 subsigguts:
                         {
@@ -790,7 +794,7 @@ subsigguts:
                         }
                 siglistornull
                        {
-                            OP            *sigops = $2;
+                            OP            *sigops = $siglistornull;
                             struct op_argcheck_aux *aux;
                             OP            *check;
 
@@ -846,7 +850,7 @@ subsigguts:
        ;
 
 /* Optional subroutine body (for named subroutine declaration) */
-optsubbody:    subbody { $$ = $1; }
+optsubbody:    subbody { $$ = $subbody; }
        |       ';'     { $$ = NULL; }
        ;
 
@@ -856,14 +860,14 @@ subbody:  remember  '{' stmtseq '}'
                        {
                          if (parser->copline > (line_t)$2)
                              parser->copline = (line_t)$2;
-                         $$ = block_end($1, $3);
+                         $$ = block_end($remember, $stmtseq);
                        }
        ;
 
 
 /* optional [ Subroutine body with optional signature ] (for named
  * subroutine declaration) */
-optsigsubbody: sigsubbody { $$ = $1; }
+optsigsubbody: sigsubbody { $$ = $sigsubbody; }
        |       ';'        { $$ = NULL; }
 
 /* Subroutine body with optional signature */
@@ -871,78 +875,78 @@ sigsubbody:       remember optsubsignature '{' stmtseq '}'
                        {
                          if (parser->copline > (line_t)$3)
                              parser->copline = (line_t)$3;
-                         $$ = block_end($1,
-                               op_append_list(OP_LINESEQ, $2, $4));
+                         $$ = block_end($remember,
+                               op_append_list(OP_LINESEQ, $optsubsignature, $stmtseq));
                        }
        ;
 
 
 /* Ordinary expressions; logical combinations */
-expr   :       expr ANDOP expr
-                       { $$ = newLOGOP(OP_AND, 0, $1, $3); }
-       |       expr OROP expr
-                       { $$ = newLOGOP($2, 0, $1, $3); }
-       |       expr DOROP expr
-                       { $$ = newLOGOP(OP_DOR, 0, $1, $3); }
+expr   :       expr[lhs] ANDOP expr[rhs]
+                       { $$ = newLOGOP(OP_AND, 0, $lhs, $rhs); }
+       |       expr[lhs] OROP[operator] expr[rhs]
+                       { $$ = newLOGOP($operator, 0, $lhs, $rhs); }
+       |       expr[lhs] DOROP expr[rhs]
+                       { $$ = newLOGOP(OP_DOR, 0, $lhs, $rhs); }
        |       listexpr %prec PREC_LOW
        ;
 
 /* Expressions are a list of terms joined by commas */
-listexpr:      listexpr ','
-                       { $$ = $1; }
-       |       listexpr ',' term
+listexpr:      listexpr[list] ','
+                       { $$ = $list; }
+       |       listexpr[list] ',' term
                        {
-                         OP* term = $3;
-                         $$ = op_append_elem(OP_LIST, $1, term);
+                         OP* term = $term;
+                         $$ = op_append_elem(OP_LIST, $list, term);
                        }
        |       term %prec PREC_LOW
        ;
 
 /* List operators */
 listop :       LSTOP indirob listexpr /* map {...} @args or print $fh @args */
-                       { $$ = op_convert_list($1, OPf_STACKED,
-                               op_prepend_elem(OP_LIST, newGVREF($1,$2), $3) );
+                       { $$ = op_convert_list($LSTOP, OPf_STACKED,
+                               op_prepend_elem(OP_LIST, newGVREF($LSTOP,$indirob), $listexpr) );
                        }
        |       FUNC '(' indirob expr ')'      /* print ($fh @args */
-                       { $$ = op_convert_list($1, OPf_STACKED,
-                               op_prepend_elem(OP_LIST, newGVREF($1,$3), $4) );
+                       { $$ = op_convert_list($FUNC, OPf_STACKED,
+                               op_prepend_elem(OP_LIST, newGVREF($FUNC,$indirob), $expr) );
                        }
        |       term ARROW method '(' optexpr ')' /* $foo->bar(list) */
                        { $$ = op_convert_list(OP_ENTERSUB, OPf_STACKED,
                                op_append_elem(OP_LIST,
-                                   op_prepend_elem(OP_LIST, scalar($1), $5),
-                                   newMETHOP(OP_METHOD, 0, $3)));
+                                   op_prepend_elem(OP_LIST, scalar($term), $optexpr),
+                                   newMETHOP(OP_METHOD, 0, $method)));
                        }
        |       term ARROW method                     /* $foo->bar */
                        { $$ = op_convert_list(OP_ENTERSUB, OPf_STACKED,
-                               op_append_elem(OP_LIST, scalar($1),
-                                   newMETHOP(OP_METHOD, 0, $3)));
+                               op_append_elem(OP_LIST, scalar($term),
+                                   newMETHOP(OP_METHOD, 0, $method)));
                        }
        |       METHOD indirob optlistexpr           /* new Class @args */
                        { $$ = op_convert_list(OP_ENTERSUB, OPf_STACKED,
                                op_append_elem(OP_LIST,
-                                   op_prepend_elem(OP_LIST, $2, $3),
-                                   newMETHOP(OP_METHOD, 0, $1)));
+                                   op_prepend_elem(OP_LIST, $indirob, $optlistexpr),
+                                   newMETHOP(OP_METHOD, 0, $METHOD)));
                        }
        |       FUNCMETH indirob '(' optexpr ')'    /* method $object (@args) */
                        { $$ = op_convert_list(OP_ENTERSUB, OPf_STACKED,
                                op_append_elem(OP_LIST,
-                                   op_prepend_elem(OP_LIST, $2, $4),
-                                   newMETHOP(OP_METHOD, 0, $1)));
+                                   op_prepend_elem(OP_LIST, $indirob, $optexpr),
+                                   newMETHOP(OP_METHOD, 0, $FUNCMETH)));
                        }
        |       LSTOP optlistexpr                    /* print @args */
-                       { $$ = op_convert_list($1, 0, $2); }
+                       { $$ = op_convert_list($LSTOP, 0, $optlistexpr); }
        |       FUNC '(' optexpr ')'                 /* print (@args) */
-                       { $$ = op_convert_list($1, 0, $3); }
+                       { $$ = op_convert_list($FUNC, 0, $optexpr); }
        |       FUNC SUBLEXSTART optexpr SUBLEXEND          /* uc($arg) from "\U..." */
-                       { $$ = op_convert_list($1, 0, $3); }
+                       { $$ = op_convert_list($FUNC, 0, $optexpr); }
        |       LSTOPSUB startanonsub block /* sub f(&@);   f { foo } ... */
                        { SvREFCNT_inc_simple_void(PL_compcv);
-                         $<opval>$ = newANONATTRSUB($2, 0, NULL, $3); }
+                         $<opval>$ = newANONATTRSUB($startanonsub, 0, NULL, $block); }[anonattrsub]
                    optlistexpr         %prec LSTOP  /* ... @bar */
                        { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
                                 op_append_elem(OP_LIST,
-                                  op_prepend_elem(OP_LIST, $<opval>4, $5), $1));
+                                  op_prepend_elem(OP_LIST, $<opval>anonattrsub, $optlistexpr), $LSTOPSUB));
                        }
        ;
 
@@ -955,148 +959,148 @@ method  :       METHOD
 subscripted:    gelem '{' expr ';' '}'        /* *main::{something} */
                         /* In this and all the hash accessors, ';' is
                          * provided by the tokeniser */
-                       { $$ = newBINOP(OP_GELEM, 0, $1, scalar($3)); }
-       |       scalar '[' expr ']'          /* $array[$element] */
-                       { $$ = newBINOP(OP_AELEM, 0, oopsAV($1), scalar($3));
+                       { $$ = newBINOP(OP_GELEM, 0, $gelem, scalar($expr)); }
+       |       scalar[array] '[' expr ']'          /* $array[$element] */
+                       { $$ = newBINOP(OP_AELEM, 0, oopsAV($array), scalar($expr));
                        }
-       |       term ARROW '[' expr ']'      /* somearef->[$element] */
+       |       term[array_reference] ARROW '[' expr ']'      /* somearef->[$element] */
                        { $$ = newBINOP(OP_AELEM, 0,
-                                       ref(newAVREF($1),OP_RV2AV),
-                                       scalar($4));
+                                       ref(newAVREF($array_reference),OP_RV2AV),
+                                       scalar($expr));
                        }
-       |       subscripted '[' expr ']'    /* $foo->[$bar]->[$baz] */
+       |       subscripted[array_reference] '[' expr ']'    /* $foo->[$bar]->[$baz] */
                        { $$ = newBINOP(OP_AELEM, 0,
-                                       ref(newAVREF($1),OP_RV2AV),
-                                       scalar($3));
+                                       ref(newAVREF($array_reference),OP_RV2AV),
+                                       scalar($expr));
                        }
-       |       scalar '{' expr ';' '}'    /* $foo{bar();} */
-                       { $$ = newBINOP(OP_HELEM, 0, oopsHV($1), jmaybe($3));
+       |       scalar[hash] '{' expr ';' '}'    /* $foo{bar();} */
+                       { $$ = newBINOP(OP_HELEM, 0, oopsHV($hash), jmaybe($expr));
                        }
-       |       term ARROW '{' expr ';' '}' /* somehref->{bar();} */
+       |       term[hash_reference] ARROW '{' expr ';' '}' /* somehref->{bar();} */
                        { $$ = newBINOP(OP_HELEM, 0,
-                                       ref(newHVREF($1),OP_RV2HV),
-                                       jmaybe($4)); }
-       |       subscripted '{' expr ';' '}' /* $foo->[bar]->{baz;} */
+                                       ref(newHVREF($hash_reference),OP_RV2HV),
+                                       jmaybe($expr)); }
+       |       subscripted[hash_reference] '{' expr ';' '}' /* $foo->[bar]->{baz;} */
                        { $$ = newBINOP(OP_HELEM, 0,
-                                       ref(newHVREF($1),OP_RV2HV),
-                                       jmaybe($3)); }
-       |       term ARROW '(' ')'          /* $subref->() */
+                                       ref(newHVREF($hash_reference),OP_RV2HV),
+                                       jmaybe($expr)); }
+       |       term[code_reference] ARROW '(' ')'          /* $subref->() */
                        { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
-                                  newCVREF(0, scalar($1)));
+                                  newCVREF(0, scalar($code_reference)));
                          if (parser->expect == XBLOCK)
                              parser->expect = XOPERATOR;
                        }
-       |       term ARROW '(' expr ')'     /* $subref->(@args) */
+       |       term[code_reference] ARROW '(' expr ')'     /* $subref->(@args) */
                        { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
-                                  op_append_elem(OP_LIST, $4,
-                                      newCVREF(0, scalar($1))));
+                                  op_append_elem(OP_LIST, $expr,
+                                      newCVREF(0, scalar($code_reference))));
                          if (parser->expect == XBLOCK)
                              parser->expect = XOPERATOR;
                        }
 
-       |       subscripted '(' expr ')'   /* $foo->{bar}->(@args) */
+       |       subscripted[code_reference] '(' expr ')'   /* $foo->{bar}->(@args) */
                        { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
-                                  op_append_elem(OP_LIST, $3,
-                                              newCVREF(0, scalar($1))));
+                                  op_append_elem(OP_LIST, $expr,
+                                              newCVREF(0, scalar($code_reference))));
                          if (parser->expect == XBLOCK)
                              parser->expect = XOPERATOR;
                        }
-       |       subscripted '(' ')'        /* $foo->{bar}->() */
+       |       subscripted[code_reference] '(' ')'        /* $foo->{bar}->() */
                        { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
-                                  newCVREF(0, scalar($1)));
+                                  newCVREF(0, scalar($code_reference)));
                          if (parser->expect == XBLOCK)
                              parser->expect = XOPERATOR;
                        }
-       |       '(' expr ')' '[' expr ']'            /* list slice */
-                       { $$ = newSLICEOP(0, $5, $2); }
+       |       '(' expr[list] ')' '[' expr[slice] ']'            /* list slice */
+                       { $$ = newSLICEOP(0, $slice, $list); }
        |       QWLIST '[' expr ']'            /* list literal slice */
-                       { $$ = newSLICEOP(0, $3, $1); }
+                       { $$ = newSLICEOP(0, $expr, $QWLIST); }
        |       '(' ')' '[' expr ']'                 /* empty list slice! */
-                       { $$ = newSLICEOP(0, $4, NULL); }
+                       { $$ = newSLICEOP(0, $expr, NULL); }
     ;
 
 /* Binary operators between terms */
-termbinop:     term ASSIGNOP term                     /* $x = $y, $x += $y */
-                       { $$ = newASSIGNOP(OPf_STACKED, $1, $2, $3); }
-       |       term POWOP term                        /* $x ** $y */
-                       { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
-       |       term MULOP term                        /* $x * $y, $x x $y */
-                       {   if ($2 != OP_REPEAT)
-                               scalar($1);
-                           $$ = newBINOP($2, 0, $1, scalar($3));
-                       }
-       |       term ADDOP term                        /* $x + $y */
-                       { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
-       |       term SHIFTOP term                      /* $x >> $y, $x << $y */
-                       { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
+termbinop:     term[lhs] ASSIGNOP term[rhs]                     /* $x = $y, $x += $y */
+                       { $$ = newASSIGNOP(OPf_STACKED, $lhs, $ASSIGNOP, $rhs); }
+       |       term[lhs] POWOP term[rhs]                        /* $x ** $y */
+                       { $$ = newBINOP($POWOP, 0, scalar($lhs), scalar($rhs)); }
+       |       term[lhs] MULOP term[rhs]                        /* $x * $y, $x x $y */
+                       {   if ($MULOP != OP_REPEAT)
+                               scalar($lhs);
+                           $$ = newBINOP($MULOP, 0, $lhs, scalar($rhs));
+                       }
+       |       term[lhs] ADDOP term[rhs]                        /* $x + $y */
+                       { $$ = newBINOP($ADDOP, 0, scalar($lhs), scalar($rhs)); }
+       |       term[lhs] SHIFTOP term[rhs]                      /* $x >> $y, $x << $y */
+                       { $$ = newBINOP($SHIFTOP, 0, scalar($lhs), scalar($rhs)); }
        |       termrelop %prec PREC_LOW               /* $x > $y, etc. */
-                       { $$ = $1; }
+                       { $$ = $termrelop; }
        |       termeqop %prec PREC_LOW                /* $x == $y, $x cmp $y */
-                       { $$ = $1; }
-       |       term BITANDOP term                     /* $x & $y */
-                       { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
-       |       term BITOROP term                      /* $x | $y */
-                       { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
-       |       term DOTDOT term                       /* $x..$y, $x...$y */
-                       { $$ = newRANGE($2, scalar($1), scalar($3)); }
-       |       term ANDAND term                       /* $x && $y */
-                       { $$ = newLOGOP(OP_AND, 0, $1, $3); }
-       |       term OROR term                         /* $x || $y */
-                       { $$ = newLOGOP(OP_OR, 0, $1, $3); }
-       |       term DORDOR term                       /* $x // $y */
-                       { $$ = newLOGOP(OP_DOR, 0, $1, $3); }
-       |       term MATCHOP term                      /* $x =~ /$y/ */
-                       { $$ = bind_match($2, $1, $3); }
+                       { $$ = $termeqop; }
+       |       term[lhs] BITANDOP term[rhs]                     /* $x & $y */
+                       { $$ = newBINOP($BITANDOP, 0, scalar($lhs), scalar($rhs)); }
+       |       term[lhs] BITOROP term[rhs]                      /* $x | $y */
+                       { $$ = newBINOP($BITOROP, 0, scalar($lhs), scalar($rhs)); }
+       |       term[lhs] DOTDOT term[rhs]                       /* $x..$y, $x...$y */
+                       { $$ = newRANGE($DOTDOT, scalar($lhs), scalar($rhs)); }
+       |       term[lhs] ANDAND term[rhs]                       /* $x && $y */
+                       { $$ = newLOGOP(OP_AND, 0, $lhs, $rhs); }
+       |       term[lhs] OROR term[rhs]                         /* $x || $y */
+                       { $$ = newLOGOP(OP_OR, 0, $lhs, $rhs); }
+       |       term[lhs] DORDOR term[rhs]                       /* $x // $y */
+                       { $$ = newLOGOP(OP_DOR, 0, $lhs, $rhs); }
+       |       term[lhs] MATCHOP term[rhs]                      /* $x =~ /$y/ */
+                       { $$ = bind_match($MATCHOP, $lhs, $rhs); }
     ;
 
 termrelop:     relopchain %prec PREC_LOW
-                       { $$ = cmpchain_finish($1); }
-       |       term NCRELOP term
-                       { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
+                       { $$ = cmpchain_finish($relopchain); }
+       |       term[lhs] NCRELOP term[rhs]
+                       { $$ = newBINOP($NCRELOP, 0, scalar($lhs), scalar($rhs)); }
        |       termrelop NCRELOP
                        { yyerror("syntax error"); YYERROR; }
        |       termrelop CHRELOP
                        { yyerror("syntax error"); YYERROR; }
        ;
 
-relopchain:    term CHRELOP term
-                       { $$ = cmpchain_start($2, $1, $3); }
-       |       relopchain CHRELOP term
-                       { $$ = cmpchain_extend($2, $1, $3); }
+relopchain:    term[lhs] CHRELOP term[rhs]
+                       { $$ = cmpchain_start($CHRELOP, $lhs, $rhs); }
+       |       relopchain[lhs] CHRELOP term[rhs]
+                       { $$ = cmpchain_extend($CHRELOP, $lhs, $rhs); }
        ;
 
 termeqop:      eqopchain %prec PREC_LOW
-                       { $$ = cmpchain_finish($1); }
-       |       term NCEQOP term
-                       { $$ = newBINOP($2, 0, scalar($1), scalar($3)); }
+                       { $$ = cmpchain_finish($eqopchain); }
+       |       term[lhs] NCEQOP term[rhs]
+                       { $$ = newBINOP($NCEQOP, 0, scalar($lhs), scalar($rhs)); }
        |       termeqop NCEQOP
                        { yyerror("syntax error"); YYERROR; }
        |       termeqop CHEQOP
                        { yyerror("syntax error"); YYERROR; }
        ;
 
-eqopchain:     term CHEQOP term
-                       { $$ = cmpchain_start($2, $1, $3); }
-       |       eqopchain CHEQOP term
-                       { $$ = cmpchain_extend($2, $1, $3); }
+eqopchain:     term[lhs] CHEQOP term[rhs]
+                       { $$ = cmpchain_start($CHEQOP, $lhs, $rhs); }
+       |       eqopchain[lhs] CHEQOP term[rhs]
+                       { $$ = cmpchain_extend($CHEQOP, $lhs, $rhs); }
        ;
 
 /* Unary operators and terms */
 termunop : '-' term %prec UMINUS                       /* -$x */
-                       { $$ = newUNOP(OP_NEGATE, 0, scalar($2)); }
+                       { $$ = newUNOP(OP_NEGATE, 0, scalar($term)); }
        |       '+' term %prec UMINUS                  /* +$x */
-                       { $$ = $2; }
+                       { $$ = $term; }
 
        |       '!' term                               /* !$x */
-                       { $$ = newUNOP(OP_NOT, 0, scalar($2)); }
+                       { $$ = newUNOP(OP_NOT, 0, scalar($term)); }
        |       '~' term                               /* ~$x */
-                       { $$ = newUNOP($1, 0, scalar($2)); }
+                       { $$ = newUNOP($1, 0, scalar($term)); }
        |       term POSTINC                           /* $x++ */
                        { $$ = newUNOP(OP_POSTINC, 0,
-                                       op_lvalue(scalar($1), OP_POSTINC)); }
+                                       op_lvalue(scalar($term), OP_POSTINC)); }
        |       term POSTDEC                           /* $x-- */
                        { $$ = newUNOP(OP_POSTDEC, 0,
-                                       op_lvalue(scalar($1), OP_POSTDEC));}
+                                       op_lvalue(scalar($term), OP_POSTDEC));}
        |       term POSTJOIN    /* implicit join after interpolated ->@ */
                        { $$ = op_convert_list(OP_JOIN, 0,
                                       op_append_elem(
@@ -1105,184 +1109,184 @@ termunop : '-' term %prec UMINUS                       /* -$x */
                                            newSVOP(OP_CONST,0,
                                                    newSVpvs("\""))
                                        )),
-                                       $1
+                                       $term
                                       ));
                        }
        |       PREINC term                            /* ++$x */
                        { $$ = newUNOP(OP_PREINC, 0,
-                                       op_lvalue(scalar($2), OP_PREINC)); }
+                                       op_lvalue(scalar($term), OP_PREINC)); }
        |       PREDEC term                            /* --$x */
                        { $$ = newUNOP(OP_PREDEC, 0,
-                                       op_lvalue(scalar($2), OP_PREDEC)); }
+                                       op_lvalue(scalar($term), OP_PREDEC)); }
 
     ;
 
 /* Constructors for anonymous data */
 anonymous:     '[' expr ']'
-                       { $$ = newANONLIST($2); }
+                       { $$ = newANONLIST($expr); }
        |       '[' ']'
                        { $$ = newANONLIST(NULL);}
        |       HASHBRACK expr ';' '}'  %prec '(' /* { foo => "Bar" } */
-                       { $$ = newANONHASH($2); }
+                       { $$ = newANONHASH($expr); }
        |       HASHBRACK ';' '}'       %prec '(' /* { } (';' by tokener) */
                        { $$ = newANONHASH(NULL); }
        |       ANONSUB     startanonsub proto subattrlist subbody    %prec '('
                        { SvREFCNT_inc_simple_void(PL_compcv);
-                         $$ = newANONATTRSUB($2, $3, $4, $5); }
+                         $$ = newANONATTRSUB($startanonsub, $proto, $subattrlist, $subbody); }
        |       ANON_SIGSUB startanonsub subattrlist sigsubbody %prec '('
                        { SvREFCNT_inc_simple_void(PL_compcv);
-                         $$ = newANONATTRSUB($2, NULL, $3, $4); }
+                         $$ = newANONATTRSUB($startanonsub, NULL, $subattrlist, $sigsubbody); }
     ;
 
 /* Things called with "do" */
 termdo :       DO term %prec UNIOP                     /* do $filename */
-                       { $$ = dofile($2, $1);}
+                       { $$ = dofile($term, $DO);}
        |       DO block        %prec '('               /* do { code */
-                       { $$ = newUNOP(OP_NULL, OPf_SPECIAL, op_scope($2));}
+                       { $$ = newUNOP(OP_NULL, OPf_SPECIAL, op_scope($block));}
         ;
 
-term   :       termbinop
+term[product]  :       termbinop
        |       termunop
        |       anonymous
        |       termdo
-       |       term '?' term ':' term
-                       { $$ = newCONDOP(0, $1, $3, $5); }
-       |       REFGEN term                          /* \$x, \@y, \%z */
-                       { $$ = newUNOP(OP_REFGEN, 0, $2); }
-       |       MY REFGEN term
-                       { $$ = newUNOP(OP_REFGEN, 0, localize($3,1)); }
+       |       term[condition] '?' term[then] ':' term[else]
+                       { $$ = newCONDOP(0, $condition, $then, $else); }
+       |       REFGEN term[operand]                          /* \$x, \@y, \%z */
+                       { $$ = newUNOP(OP_REFGEN, 0, $operand); }
+       |       MY REFGEN term[operand]
+                       { $$ = newUNOP(OP_REFGEN, 0, localize($operand,1)); }
        |       myattrterm      %prec UNIOP
-                       { $$ = $1; }
-       |       LOCAL term      %prec UNIOP
-                       { $$ = localize($2,0); }
+                       { $$ = $myattrterm; }
+       |       LOCAL term[operand]     %prec UNIOP
+                       { $$ = localize($operand,0); }
        |       '(' expr ')'
-                       { $$ = sawparens($2); }
+                       { $$ = sawparens($expr); }
        |       QWLIST
-                       { $$ = $1; }
+                       { $$ = $QWLIST; }
        |       '(' ')'
                        { $$ = sawparens(newNULLLIST()); }
        |       scalar  %prec '('
-                       { $$ = $1; }
+                       { $$ = $scalar; }
        |       star    %prec '('
-                       { $$ = $1; }
+                       { $$ = $star; }
        |       hsh     %prec '('
-                       { $$ = $1; }
+                       { $$ = $hsh; }
        |       ary     %prec '('
-                       { $$ = $1; }
+                       { $$ = $ary; }
        |       arylen  %prec '('                    /* $#x, $#{ something } */
-                       { $$ = newUNOP(OP_AV2ARYLEN, 0, ref($1, OP_AV2ARYLEN));}
+                       { $$ = newUNOP(OP_AV2ARYLEN, 0, ref($arylen, OP_AV2ARYLEN));}
        |       subscripted
-                       { $$ = $1; }
+                       { $$ = $subscripted; }
        |       sliceme '[' expr ']'                     /* array slice */
                        { $$ = op_prepend_elem(OP_ASLICE,
                                newOP(OP_PUSHMARK, 0),
                                    newLISTOP(OP_ASLICE, 0,
-                                       list($3),
-                                       ref($1, OP_ASLICE)));
-                         if ($$ && $1)
+                                       list($expr),
+                                       ref($sliceme, OP_ASLICE)));
+                         if ($$ && $sliceme)
                              $$->op_private |=
-                                 $1->op_private & OPpSLICEWARNING;
+                                 $sliceme->op_private & OPpSLICEWARNING;
                        }
        |       kvslice '[' expr ']'                 /* array key/value slice */
                        { $$ = op_prepend_elem(OP_KVASLICE,
                                newOP(OP_PUSHMARK, 0),
                                    newLISTOP(OP_KVASLICE, 0,
-                                       list($3),
-                                       ref(oopsAV($1), OP_KVASLICE)));
-                         if ($$ && $1)
+                                       list($expr),
+                                       ref(oopsAV($kvslice), OP_KVASLICE)));
+                         if ($$ && $kvslice)
                              $$->op_private |=
-                                 $1->op_private & OPpSLICEWARNING;
+                                 $kvslice->op_private & OPpSLICEWARNING;
                        }
        |       sliceme '{' expr ';' '}'                 /* @hash{@keys} */
                        { $$ = op_prepend_elem(OP_HSLICE,
                                newOP(OP_PUSHMARK, 0),
                                    newLISTOP(OP_HSLICE, 0,
-                                       list($3),
-                                       ref(oopsHV($1), OP_HSLICE)));
-                         if ($$ && $1)
+                                       list($expr),
+                                       ref(oopsHV($sliceme), OP_HSLICE)));
+                         if ($$ && $sliceme)
                              $$->op_private |=
-                                 $1->op_private & OPpSLICEWARNING;
+                                 $sliceme->op_private & OPpSLICEWARNING;
                        }
        |       kvslice '{' expr ';' '}'                 /* %hash{@keys} */
                        { $$ = op_prepend_elem(OP_KVHSLICE,
                                newOP(OP_PUSHMARK, 0),
                                    newLISTOP(OP_KVHSLICE, 0,
-                                       list($3),
-                                       ref($1, OP_KVHSLICE)));
-                         if ($$ && $1)
+                                       list($expr),
+                                       ref($kvslice, OP_KVHSLICE)));
+                         if ($$ && $kvslice)
                              $$->op_private |=
-                                 $1->op_private & OPpSLICEWARNING;
+                                 $kvslice->op_private & OPpSLICEWARNING;
                        }
        |       THING   %prec '('
-                       { $$ = $1; }
+                       { $$ = $THING; }
        |       amper                                /* &foo; */
-                       { $$ = newUNOP(OP_ENTERSUB, 0, scalar($1)); }
+                       { $$ = newUNOP(OP_ENTERSUB, 0, scalar($amper)); }
        |       amper '(' ')'                 /* &foo() or foo() */
-                       { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1));
+                       { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($amper));
                        }
        |       amper '(' expr ')'          /* &foo(@args) or foo(@args) */
                        {
                          $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
-                               op_append_elem(OP_LIST, $3, scalar($1)));
+                               op_append_elem(OP_LIST, $expr, scalar($amper)));
                        }
        |       NOAMP subname optlistexpr       /* foo @args (no parens) */
                        { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
-                           op_append_elem(OP_LIST, $3, scalar($2)));
-                       }
-       |       term ARROW '$' '*'
-                       { $$ = newSVREF($1); }
-       |       term ARROW '@' '*'
-                       { $$ = newAVREF($1); }
-       |       term ARROW '%' '*'
-                       { $$ = newHVREF($1); }
-       |       term ARROW '&' '*'
+                           op_append_elem(OP_LIST, $optlistexpr, scalar($subname)));
+                       }
+       |       term[operand] ARROW '$' '*'
+                       { $$ = newSVREF($operand); }
+       |       term[operand] ARROW '@' '*'
+                       { $$ = newAVREF($operand); }
+       |       term[operand] ARROW '%' '*'
+                       { $$ = newHVREF($operand); }
+       |       term[operand] ARROW '&' '*'
                        { $$ = newUNOP(OP_ENTERSUB, 0,
-                                      scalar(newCVREF($3,$1))); }
-       |       term ARROW '*' '*'      %prec '('
-                       { $$ = newGVREF(0,$1); }
+                                      scalar(newCVREF($3,$operand))); }
+       |       term[operand] ARROW '*' '*'     %prec '('
+                       { $$ = newGVREF(0,$operand); }
        |       LOOPEX  /* loop exiting command (goto, last, dump, etc) */
-                       { $$ = newOP($1, OPf_SPECIAL);
+                       { $$ = newOP($LOOPEX, OPf_SPECIAL);
                            PL_hints |= HINT_BLOCK_SCOPE; }
-       |       LOOPEX term
-                       { $$ = newLOOPEX($1,$2); }
+       |       LOOPEX term[operand]
+                       { $$ = newLOOPEX($LOOPEX,$operand); }
        |       NOTOP listexpr                       /* not $foo */
-                       { $$ = newUNOP(OP_NOT, 0, scalar($2)); }
+                       { $$ = newUNOP(OP_NOT, 0, scalar($listexpr)); }
        |       UNIOP                                /* Unary op, $_ implied */
-                       { $$ = newOP($1, 0); }
+                       { $$ = newOP($UNIOP, 0); }
        |       UNIOP block                          /* eval { foo }* */
-                       { $$ = newUNOP($1, 0, $2); }
-       |       UNIOP term                           /* Unary op */
-                       { $$ = newUNOP($1, 0, $2); }
+                       { $$ = newUNOP($UNIOP, 0, $block); }
+       |       UNIOP term[operand]                           /* Unary op */
+                       { $$ = newUNOP($UNIOP, 0, $operand); }
        |       REQUIRE                              /* require, $_ implied */
-                       { $$ = newOP(OP_REQUIRE, $1 ? OPf_SPECIAL : 0); }
-       |       REQUIRE term                         /* require Foo */
-                       { $$ = newUNOP(OP_REQUIRE, $1 ? OPf_SPECIAL : 0, $2); }
+                       { $$ = newOP(OP_REQUIRE, $REQUIRE ? OPf_SPECIAL : 0); }
+       |       REQUIRE term[operand]                         /* require Foo */
+                       { $$ = newUNOP(OP_REQUIRE, $REQUIRE ? OPf_SPECIAL : 0, $operand); }
        |       UNIOPSUB
-                       { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); }
-       |       UNIOPSUB term                        /* Sub treated as unop */
+                       { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($UNIOPSUB)); }
+       |       UNIOPSUB term[operand]                        /* Sub treated as unop */
                        { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED,
-                           op_append_elem(OP_LIST, $2, scalar($1))); }
+                           op_append_elem(OP_LIST, $operand, scalar($UNIOPSUB))); }
        |       FUNC0                                /* Nullary operator */
-                       { $$ = newOP($1, 0); }
+                       { $$ = newOP($FUNC0, 0); }
        |       FUNC0 '(' ')'
-                       { $$ = newOP($1, 0);}
+                       { $$ = newOP($FUNC0, 0);}
        |       FUNC0OP       /* Same as above, but op created in toke.c */
-                       { $$ = $1; }
+                       { $$ = $FUNC0OP; }
        |       FUNC0OP '(' ')'
-                       { $$ = $1; }
+                       { $$ = $FUNC0OP; }
        |       FUNC0SUB                             /* Sub treated as nullop */
-                       { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($1)); }
+                       { $$ = newUNOP(OP_ENTERSUB, OPf_STACKED, scalar($FUNC0SUB)); }
        |       FUNC1 '(' ')'                        /* not () */
-                       { $$ = ($1 == OP_NOT)
-                          ? newUNOP($1, 0, newSVOP(OP_CONST, 0, newSViv(0)))
-                          : newOP($1, OPf_SPECIAL); }
+                       { $$ = ($FUNC1 == OP_NOT)
+                          ? newUNOP($FUNC1, 0, newSVOP(OP_CONST, 0, newSViv(0)))
+                          : newOP($FUNC1, OPf_SPECIAL); }
        |       FUNC1 '(' expr ')'                   /* not($foo) */
-                       { $$ = newUNOP($1, 0, $3); }
+                       { $$ = newUNOP($FUNC1, 0, $expr); }
        |       PMFUNC /* m//, s///, qr//, tr/// */
                        {
-                           if (   $1->op_type != OP_TRANS
-                               && $1->op_type != OP_TRANSR
-                               && (((PMOP*)$1)->op_pmflags & PMf_HAS_CV))
+                           if (   $PMFUNC->op_type != OP_TRANS
+                               && $PMFUNC->op_type != OP_TRANSR
+                               && (((PMOP*)$PMFUNC)->op_pmflags & PMf_HAS_CV))
                            {
                                $<ival>$ = start_subparse(FALSE, CVf_ANON);
                                SAVEFREESV(PL_compcv);
@@ -1290,7 +1294,7 @@ term      :       termbinop
                                $<ival>$ = 0;
                        }
                    SUBLEXSTART listexpr optrepl SUBLEXEND
-                       { $$ = pmruntime($1, $4, $5, 1, $<ival>2); }
+                       { $$ = pmruntime($PMFUNC, $listexpr, $optrepl, 1, $<ival>2); }
        |       BAREWORD
        |       listop
        |       PLUGEXPR
@@ -1298,50 +1302,50 @@ term    :       termbinop
 
 /* "my" declarations, with optional attributes */
 myattrterm:    MY myterm myattrlist
-                       { $$ = my_attrs($2,$3); }
+                       { $$ = my_attrs($myterm,$myattrlist); }
        |       MY myterm
-                       { $$ = localize($2,1); }
+                       { $$ = localize($myterm,1); }
        |       MY REFGEN myterm myattrlist
-                       { $$ = newUNOP(OP_REFGEN, 0, my_attrs($3,$4)); }
+                       { $$ = newUNOP(OP_REFGEN, 0, my_attrs($myterm,$myattrlist)); }
        ;
 
 /* Things that can be "my"'d */
 myterm :       '(' expr ')'
-                       { $$ = sawparens($2); }
+                       { $$ = sawparens($expr); }
        |       '(' ')'
                        { $$ = sawparens(newNULLLIST()); }
 
        |       scalar  %prec '('
-                       { $$ = $1; }
+                       { $$ = $scalar; }
        |       hsh     %prec '('
-                       { $$ = $1; }
+                       { $$ = $hsh; }
        |       ary     %prec '('
-                       { $$ = $1; }
+                       { $$ = $ary; }
        ;
 
 /* Basic list expressions */
 optlistexpr:   /* NULL */ %prec PREC_LOW
                        { $$ = NULL; }
        |       listexpr    %prec PREC_LOW
-                       { $$ = $1; }
+                       { $$ = $listexpr; }
        ;
 
 optexpr:       /* NULL */
                        { $$ = NULL; }
        |       expr
-                       { $$ = $1; }
+                       { $$ = $expr; }
        ;
 
 optrepl:       /* NULL */
                        { $$ = NULL; }
        |       '/' expr
-                       { $$ = $2; }
+                       { $$ = $expr; }
        ;
 
 /* A little bit of trickery to make "for my $foo (@bar)" actually be
    lexical */
 my_scalar:     scalar
-                       { parser->in_my = 0; $$ = my($1); }
+                       { parser->in_my = 0; $$ = my($scalar); }
        ;
 
 my_var :       scalar
@@ -1358,58 +1362,58 @@ my_refgen:      MY REFGEN
        ;
 
 amper  :       '&' indirob
-                       { $$ = newCVREF($1,$2); }
+                       { $$ = newCVREF($1,$indirob); }
        ;
 
 scalar :       '$' indirob
-                       { $$ = newSVREF($2); }
+                       { $$ = newSVREF($indirob); }
        ;
 
 ary    :       '@' indirob
-                       { $$ = newAVREF($2);
+                       { $$ = newAVREF($indirob);
                          if ($$) $$->op_private |= $1;
                        }
        ;
 
 hsh    :       '%' indirob
-                       { $$ = newHVREF($2);
+                       { $$ = newHVREF($indirob);
                          if ($$) $$->op_private |= $1;
                        }
        ;
 
 arylen :       DOLSHARP indirob
-                       { $$ = newAVREF($2); }
+                       { $$ = newAVREF($indirob); }
        |       term ARROW DOLSHARP '*'
-                       { $$ = newAVREF($1); }
+                       { $$ = newAVREF($term); }
        ;
 
 star   :       '*' indirob
-                       { $$ = newGVREF(0,$2); }
+                       { $$ = newGVREF(0,$indirob); }
        ;
 
 sliceme        :       ary
        |       term ARROW '@'
-                       { $$ = newAVREF($1); }
+                       { $$ = newAVREF($term); }
        ;
 
 kvslice        :       hsh
        |       term ARROW '%'
-                       { $$ = newHVREF($1); }
+                       { $$ = newHVREF($term); }
        ;
 
 gelem  :       star
        |       term ARROW '*'
-                       { $$ = newGVREF(0,$1); }
+                       { $$ = newGVREF(0,$term); }
        ;
 
 /* Indirect objects */
 indirob        :       BAREWORD
-                       { $$ = scalar($1); }
+                       { $$ = scalar($BAREWORD); }
        |       scalar %prec PREC_LOW
-                       { $$ = scalar($1); }
+                       { $$ = scalar($scalar); }
        |       block
-                       { $$ = op_scope($1); }
+                       { $$ = op_scope($block); }
 
        |       PRIVATEREF
-                       { $$ = $1; }
+                       { $$ = $PRIVATEREF; }
        ;
index e817912..691f907 100644 (file)
@@ -31,12 +31,12 @@ afsroot='/afs'
 alignbytes='4'
 aphostname='/bin/uname -n'
 api_revision='5'
-api_subversion='4'
+api_subversion='5'
 api_version='33'
-api_versionstring='5.33.4'
+api_versionstring='5.33.5'
 ar='ar'
-archlib='/sys/lib/perl5/5.33.4/386'
-archlibexp='/sys/lib/perl5/5.33.4/386'
+archlib='/sys/lib/perl5/5.33.5/386'
+archlibexp='/sys/lib/perl5/5.33.5/386'
 archname64=''
 archname='386'
 archobjs=''
@@ -248,6 +248,7 @@ d_gdbm_ndbm_h_uses_prototypes='undef'
 d_gdbmndbm_h_uses_prototypes='undef'
 d_getaddrinfo='undef'
 d_getcwd='define'
+d_getenv_preserves_other_thread='define'
 d_getespwnam='undef'
 d_getfsstat='undef'
 d_getgrent='define'
@@ -818,17 +819,17 @@ inc_version_list=' '
 inc_version_list_init='0'
 incpath=''
 inews=''
-installarchlib='/sys/lib/perl/5.33.4/386'
+installarchlib='/sys/lib/perl/5.33.5/386'
 installbin='/usr/bin'
 installman1dir='/sys/man/1pub'
 installman3dir='/sys/man/2pub'
 installprefix='/usr'
 installprefixexp='/usr'
-installprivlib='/sys/lib/perl/5.33.4'
+installprivlib='/sys/lib/perl/5.33.5'
 installscript='/usr/bin'
-installsitearch='/sys/lib/perl/5.33.4/site_perl/386'
+installsitearch='/sys/lib/perl/5.33.5/site_perl/386'
 installsitebin='/usr/bin'
-installsitelib='/sys/lib/perl/5.33.4/site_perl'
+installsitelib='/sys/lib/perl/5.33.5/site_perl'
 installstyle='lib/perl5'
 installusrbinperl='undef'
 installvendorarch=''
@@ -953,8 +954,8 @@ pmake=''
 pr=''
 prefix='/usr'
 prefixexp='/usr'
-privlib='/sys/lib/perl/5.33.4'
-privlibexp='/sys/lib/perl/5.33.4'
+privlib='/sys/lib/perl/5.33.5'
+privlibexp='/sys/lib/perl/5.33.5'
 procselfexe=''
 prototype='define'
 ptrsize='4'
@@ -1019,13 +1020,13 @@ sig_num='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 sig_num_init='0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 0'
 sig_size='50'
 signal_t='void'
-sitearch='/sys/lib/perl/5.33.4/site_perl/386'
+sitearch='/sys/lib/perl/5.33.5/site_perl/386'
 sitearchexp='/sys/lib/perl/site_perl/386'
 sitebin='/usr/bin'
 sitebinexp='/usr/bin'
-sitelib='/sys/lib/perl/5.33.4/site_perl'
-sitelib_stem='/sys/lib/perl/5.33.4/site_perl'
-sitelibexp='/sys/lib/perl/5.33.4/site_perl'
+sitelib='/sys/lib/perl/5.33.5/site_perl'
+sitelib_stem='/sys/lib/perl/5.33.5/site_perl'
+sitelibexp='/sys/lib/perl/5.33.5/site_perl'
 siteprefix='/usr'
 siteprefixexp='/usr'
 sizesize='4'
@@ -1058,7 +1059,7 @@ stdio_stream_array=''
 strerror_r_proto='0'
 strings='/sys/include/ape/string.h'
 submit=''
-subversion='4'
+subversion='5'
 sysman='/sys/man/1pub'
 tail=''
 tar=''
@@ -1139,8 +1140,8 @@ vendorlib_stem=''
 vendorlibexp=''
 vendorprefix=''
 vendorprefixexp=''
-version='5.33.4'
-version_patchlevel_string='version 33 subversion 4'
+version='5.33.5'
+version_patchlevel_string='version 33 subversion 5'
 versiononly='undef'
 vi=''
 xlibpth=''
@@ -1154,9 +1155,9 @@ config_args=''
 config_argc=0
 PERL_REVISION=5
 PERL_VERSION=33
-PERL_SUBVERSION=4
+PERL_SUBVERSION=5
 PERL_API_REVISION=5
 PERL_API_VERSION=33
-PERL_API_SUBVERSION=4
+PERL_API_SUBVERSION=5
 PERL_PATCHLEVEL=
 PERL_CONFIG_SH=true
diff --git a/pod/.gitignore b/pod/.gitignore
new file mode 100644 (file)
index 0000000..def64fd
--- /dev/null
@@ -0,0 +1,60 @@
+# arch-specific pods
+/perlaix.pod
+/perlamiga.pod
+/perlandroid.pod
+/perlbs2000.pod
+/perlcn.pod
+/perlcygwin.pod
+/perldos.pod
+/perlfreebsd.pod
+/perlhaiku.pod
+/perlhpux.pod
+/perlhurd.pod
+/perlirix.pod
+/perljp.pod
+/perlko.pod
+/perllinux.pod
+/perlmacos.pod
+/perlmacosx.pod
+/perlnetware.pod
+/perlopenbsd.pod
+/perlos2.pod
+/perlos390.pod
+/perlos400.pod
+/perlplan9.pod
+/perlqnx.pod
+/perlriscos.pod
+/perlsolaris.pod
+/perlsymbian.pod
+/perlsynology.pod
+/perltru64.pod
+/perltw.pod
+/perlvos.pod
+/perlwin32.pod
+
+# scripts etc
+/pod2html
+/pod2html.bat
+/pod2man
+/pod2man.bat
+/pod2text
+/pod2text.bat
+/pod2usage
+/pod2usage.bat
+/podchecker
+/podchecker.bat
+/podselect
+/podselect.bat
+/roffitall
+
+# generated
+/perl5335delta.pod
+/perlapi.pod
+/perlintern.pod
+/perlmodlib.pod
+/perltoc.pod
+/perluniprops.pod
+*.html
+*.man
+/perlfunc/
+/perlipc/
index 557c5db..eaccc2e 100644 (file)
@@ -96,6 +96,7 @@ aux h2ph h2xs perlbug pl2pm pod2html pod2man splain xsubpp
       perlpacktut      Perl pack() and unpack() tutorial
     perlpod            Perl plain old documentation
     perlpodspec        Perl plain old documentation format specification
+    perldocstyle       Perl style guide for core docs
     perlpodstyle       Perl POD style guide
     perldiag           Perl diagnostic messages
     perldeprecation     Perl deprecations
@@ -182,6 +183,7 @@ aux h2ph h2xs perlbug pl2pm pod2html pod2man splain xsubpp
 
     perlhist           Perl history records
     perldelta          Perl changes since previous version
+    perl5334delta      Perl changes in version 5.33.4
     perl5333delta      Perl changes in version 5.33.3
     perl5332delta      Perl changes in version 5.33.2
     perl5331delta      Perl changes in version 5.33.1
index 69c62ee..a1a4bbd 100644 (file)
@@ -2630,7 +2630,7 @@ L<[perl #126697]|https://rt.perl.org/Public/Bug/Display.html?id=126697>
 
 Using C<substr()> to modify a magic variable could access freed memory
 in some cases.
-L<[perl #129340]|https://rt.perl.org/Public/Bug/Display.html?id=129340>
+L<[perl #130766]|https://rt.perl.org/Public/Bug/Display.html?id=130766>
 
 =item *
 
diff --git a/pod/perl5334delta.pod b/pod/perl5334delta.pod
new file mode 100644 (file)
index 0000000..c1fc77d
--- /dev/null
@@ -0,0 +1,223 @@
+=encoding utf8
+
+=head1 NAME
+
+perl5334delta - what is new for perl v5.33.4
+
+=head1 DESCRIPTION
+
+This document describes differences between the 5.33.3 release and the 5.33.4
+release.
+
+If you are upgrading from an earlier release such as 5.33.2, first read
+L<perl5333delta>, which describes differences between 5.33.2 and 5.33.3.
+
+=head1 Modules and Pragmata
+
+=head2 Updated Modules and Pragmata
+
+=over 4
+
+=item *
+
+L<B> has been upgraded from version 1.81 to 1.82.
+
+=item *
+
+L<ExtUtils::CBuilder> has been upgraded from version 0.280234 to 0.280235.
+
+=item *
+
+L<ExtUtils::MakeMaker> has been upgraded from version 7.48 to 7.56.
+
+=item *
+
+L<File::Fetch> has been upgraded from version 0.56 to 1.00.
+
+=item *
+
+L<File::Path> has been upgraded from version 2.17 to 2.18.
+
+=item *
+
+L<File::Spec> has been upgraded from version 3.78 to 3.79.
+
+=item *
+
+L<IPC::SysV> has been upgraded from version 2.08 to 2.09.
+
+=item *
+
+L<Module::CoreList> has been upgraded from version 5.20201020 to 5.20201120.
+
+=item *
+
+L<Net::Ping> has been upgraded from version 2.73_01 to 2.74.
+
+=item *
+
+L<perlfaq> has been upgraded from version 5.20200523 to 5.20201107.
+
+=item *
+
+L<Pod::Html> has been upgraded from version 1.25 to 1.26.
+
+=item *
+
+L<Pod::Simple> has been upgraded from version 3.41 to 3.42.
+
+=item *
+
+L<Test::Simple> has been upgraded from version 1.302182 to 1.302183.
+
+=item *
+
+L<XS::APItest> has been upgraded from version 1.12 to 1.13.
+
+=back
+
+=head1 Documentation
+
+=head2 Changes to Existing Documentation
+
+We have attempted to update the documentation to reflect the changes
+listed in this document.  If you find any we have missed, open an issue
+at L<https://github.com/Perl/perl5/issues>.
+
+=head3 L<perlfaq>
+
+=over 4
+
+=item *
+
+The Perl FAQ was updated to CPAN version 5.20201107 with minor
+improvements.
+
+=back
+
+=head3 L<perlapi>
+
+=over 4
+
+=item *
+
+Efforts continue in improving the presentation of this document, and to
+document more API elements.
+
+=back
+
+=head1 Diagnostics
+
+The following additions or changes have been made to diagnostic output,
+including warnings and fatal error messages.  For the complete list of
+diagnostic messages, see L<perldiag>.
+
+=head2 Changes to Existing Diagnostics
+
+=over 4
+
+=item *
+
+L<\K not permitted in lookahead/lookbehind in regex; marked by <-- HERE in mE<sol>%sE<sol>|perldiag/"\K not permitted in lookahead/lookbehind in regex; marked by <-- HERE in m/%s/">
+
+This error was incorrectly produced in some cases involving nested
+lookarounds.  This has been fixed. [L<GH #18123|https://github.com/Perl/perl5/issues/18123>]
+
+=back
+
+=head1 Platform Support
+
+=head2 Platform-Specific Notes
+
+=over 4
+
+=item DragonFlyBSD
+
+Tests were updated to workaround DragonFlyBSD bugs in L<tc*()
+functions|https://bugs.dragonflybsd.org/issues/3252> and L<ctime
+updates|https://bugs.dragonflybsd.org/issues/3251>.
+
+=back
+
+=head1 Selected Bug Fixes
+
+=over 4
+
+=item *
+
+Magic is now called correctly for stacked file test operators.  [L<GH #18293|https://github.com/Perl/perl5/issues/18293>]
+
+=item *
+
+The C<@ary = split(...)> optimization no longer switches in the target
+array as the value stack. [L<GH #18232|https://github.com/Perl/perl5/issues/18232>] Also see discussion at
+L<https://github.com/Perl/perl5/pull/18014#issuecomment-671299506>.
+
+=back
+
+=head1 Acknowledgements
+
+Perl 5.33.4 represents approximately 4 weeks of development since Perl
+5.33.3 and contains approximately 6,900 lines of changes across 340 files
+from 16 authors.
+
+Excluding auto-generated files, documentation and release tools, there were
+approximately 4,200 lines of changes to 260 .pm, .t, .c and .h files.
+
+Perl continues to flourish into its fourth decade thanks to a vibrant
+community of users and developers. The following people are known to have
+contributed the improvements that became Perl 5.33.4:
+
+Ben Cornett, Chris 'BinGOs' Williams, Dan Book, David Mitchell, Giovanni
+Tataranni, James E Keenan, Karen Etheridge, Karl Williamson, Marcus
+Holland-Moritz, Nicolas R., Richard Leach, Scott Baker, Steve Hay, TAKAI
+Kousuke, Tom Hukins, Tony Cook.
+
+The list above is almost certainly incomplete as it is automatically
+generated from version control history. In particular, it does not include
+the names of the (very much appreciated) contributors who reported issues to
+the Perl bug tracker.
+
+Many of the changes included in this version originated in the CPAN modules
+included in Perl's core. We're grateful to the entire CPAN community for
+helping Perl to flourish.
+
+For a more complete list of all of Perl's historical contributors, please
+see the F<AUTHORS> file in the Perl source distribution.
+
+=head1 Reporting Bugs
+
+If you find what you think is a bug, you might check the perl bug database
+at L<https://github.com/Perl/perl5/issues>.  There may also be information at
+L<http://www.perl.org/>, the Perl Home Page.
+
+If you believe you have an unreported bug, please open an issue at
+L<https://github.com/Perl/perl5/issues>.  Be sure to trim your bug down to a
+tiny but sufficient test case.
+
+If the bug you are reporting has security implications which make it
+inappropriate to send to a public issue tracker, then see
+L<perlsec/SECURITY VULNERABILITY CONTACT INFORMATION>
+for details of how to report the issue.
+
+=head1 Give Thanks
+
+If you wish to thank the Perl 5 Porters for the work we had done in Perl 5,
+you can do so by running the C<perlthanks> program:
+
+    perlthanks
+
+This will send an email to the Perl 5 Porters list with your show of thanks.
+
+=head1 SEE ALSO
+
+The F<Changes> file for an explanation of how to view exhaustive details on
+what changed.
+
+The F<INSTALL> file for how to build Perl.
+
+The F<README> file for general stuff.
+
+The F<Artistic> and F<Copying> files for copyright information.
+
+=cut
index dc9dc6d..7cae8b2 100644 (file)
@@ -444,6 +444,7 @@ integer formats:
  0xff                # hex
  0xdead_beef         # more hex
  0377                # octal (only numbers, begins with 0)
+ 0o12_345            # alternative octal (introduced in Perl 5.33.5)
  0b011011            # binary
  0x1.999ap-4         # hexadecimal floating point (the 'p' is required)
 
index 80fa5f2..4827330 100644 (file)
@@ -2,15 +2,26 @@
 
 =head1 NAME
 
-perldelta - what is new for perl v5.33.4
+perldelta - what is new for perl v5.33.5
 
 =head1 DESCRIPTION
 
-This document describes differences between the 5.33.3 release and the 5.33.4
+This document describes differences between the 5.33.4 release and the 5.33.5
 release.
 
-If you are upgrading from an earlier release such as 5.33.2, first read
-L<perl5333delta>, which describes differences between 5.33.2 and 5.33.3.
+If you are upgrading from an earlier release such as 5.33.3, first read
+L<perl5334delta>, which describes differences between 5.33.3 and 5.33.4.
+
+=head1 Core Enhancements
+
+=head2 New octal syntax C<0oI<ddddd>>
+
+It is now possible to specify octal literals with C<0o> prefixes,
+as in C<0o123_456>, parallel to the existing construct to specify
+hexadecimal literal C<0xI<ddddd>> and binary literal C<0bI<ddddd>>.
+Also, the builtin C<oct()> function now accepts this new syntax.
+
+See L<perldata/Scalar value constructors> and L<perlfunc/oct EXPR>.
 
 =head1 Modules and Pragmata
 
@@ -20,122 +31,194 @@ L<perl5333delta>, which describes differences between 5.33.2 and 5.33.3.
 
 =item *
 
-L<B> has been upgraded from version 1.81 to 1.82.
+L<Carp> has been upgraded from version 1.50 to 1.51.
 
 =item *
 
-L<ExtUtils::CBuilder> has been upgraded from version 0.280234 to 0.280235.
+L<Config::Perl::V> has been upgraded from version 0.32 to 0.33.
 
 =item *
 
-L<ExtUtils::MakeMaker> has been upgraded from version 7.48 to 7.56.
+L<DynaLoader> has been upgraded from version 1.48 to 1.49.
 
 =item *
 
-L<File::Fetch> has been upgraded from version 0.56 to 1.00.
+L<Encode> has been upgraded from version 3.07 to 3.08.
 
 =item *
 
-L<File::Path> has been upgraded from version 2.17 to 2.18.
+L<ExtUtils::Install> has been upgraded from version 2.18 to 2.20.
 
 =item *
 
-L<File::Spec> has been upgraded from version 3.78 to 3.79.
+L<ExtUtils::ParseXS> has been upgraded from version 3.41 to 3.42.
 
 =item *
 
-L<IPC::SysV> has been upgraded from version 2.08 to 2.09.
+L<File::Copy> has been upgraded from version 2.34 to 2.35.
 
 =item *
 
-L<Module::CoreList> has been upgraded from version 5.20201020 to 5.20201120.
+L<File::Find> has been upgraded from version 1.37 to 1.38.
 
 =item *
 
-L<Net::Ping> has been upgraded from version 2.73_01 to 2.74.
+L<File::Spec> has been upgraded from version 3.79 to 3.80.
 
 =item *
 
-L<perlfaq> has been upgraded from version 5.20200523 to 5.20201107.
+The libnet distribution has been upgraded from version 3.11 to 3.12.
 
 =item *
 
-L<Pod::Html> has been upgraded from version 1.25 to 1.26.
+L<Module::CoreList> has been upgraded from version 5.20201120 to 5.20201220.
 
 =item *
 
-L<Pod::Simple> has been upgraded from version 3.41 to 3.42.
+L<ODBM_File> has been upgraded from version 1.16 to 1.17.
 
 =item *
 
-L<Test::Simple> has been upgraded from version 1.302182 to 1.302183.
+L<Opcode> has been upgraded from version 1.48 to 1.49.
 
 =item *
 
-L<XS::APItest> has been upgraded from version 1.12 to 1.13.
+L<PerlIO::via::QuotedPrint> has been upgraded from version 0.08 to 0.09.
+
+=item *
+
+L<POSIX> has been upgraded from version 1.95 to 1.96.
+
+=item *
+
+L<Test::Harness> has been upgraded from version 3.42 to 3.43.
+
+=item *
+
+L<Text::Balanced> has been upgraded from version 2.03 to 2.04.
+
+=item *
+
+L<Time::HiRes> has been upgraded from version 1.9765 to 1.9766.
+
+=item *
+
+L<warnings> has been upgraded from version 1.48 to 1.49.
+
+=item *
+
+L<XS::APItest> has been upgraded from version 1.13 to 1.14.
 
 =back
 
 =head1 Documentation
 
+=head2 New Documentation
+
+=head3 L<perldocstyle> has been added to F<pod/>.
+
+This document is a guide for the authorship and maintenance of the
+documentation that ships with Perl.
+
 =head2 Changes to Existing Documentation
 
 We have attempted to update the documentation to reflect the changes
 listed in this document.  If you find any we have missed, open an issue
 at L<https://github.com/Perl/perl5/issues>.
 
-=head3 L<perlfaq>
+Additionally, the following selected changes have been made:
+
+=head3 L<perlfunc>
 
 =over 4
 
 =item *
 
-The Perl FAQ was updated to CPAN version 5.20200523 with minor
-improvements.
+L<msgsnd()|perlfunc/msgsnd> documented a length field included in the
+packed C<MSG> parameter to msgsnd(), but there was no such field.
+C<MSG> contains only the type and the message content.
 
 =back
 
-=head3 L<perlapi>
+=head1 Testing
+
+Tests were added and changed to reflect the other additions and
+changes in this release.  Furthermore, these significant changes were
+made:
 
 =over 4
 
 =item *
 
-Efforts continue in improving the presentation of this document, and to
-document more API elements.
+When testing in parallel on many-core platforms, you can now cause the
+test suite to finish somewhat earlier, but with less logical ordering of
+the tests, by setting
 
-=back
+ PERL_TEST_HARNESS_ASAP=1
 
-=head1 Diagnostics
+while running the test suite.
 
-The following additions or changes have been made to diagnostic output,
-including warnings and fatal error messages.  For the complete list of
-diagnostic messages, see L<perldiag>.
+=back
 
-=head2 Changes to Existing Diagnostics
+=head2 Platform-Specific Notes
 
 =over 4
 
-=item *
+=item Windows
 
-L<\K not permitted in lookahead/lookbehind in regex; marked by <-- HERE in mE<sol>%sE<sol>|perldiag/"\K not permitted in lookahead/lookbehind in regex; marked by <-- HERE in m/%s/">
+Windows now supports L<symlink()|perlfunc/symlink> and
+L<readlink()|perlfunc/readlink>, and L<lstat()|perlfunc/lstat> is no
+longer an alias for L<stat()|perlfunc/stat>.
+L<[#18005]|https://github.com/Perl/perl5/issues/18005>.
 
-This error was incorrectly produced in some cases involving nested
-lookarounds.  This has been fixed. [L<GH #18123|https://github.com/Perl/perl5/issues/18123>]
+Unlike POSIX systems, creating a symbolic link on Windows requires
+either elevated privileges or Windows 10 1703 or later with Developer
+Mode enabled.
 
-=back
+stat(), including C<stat FILEHANDLE>, and lstat() now uses our own
+implementation that populates the device C<dev> and inode numbers
+C<ino> returned rather than always returning zero.  The number of
+links C<nlink> field is now always populated.
 
-=head1 Platform Support
+L<< C<${^WIN32_SLOPPY_STAT}> |perlvar/${^WIN32_SLOPPY_STAT} >> previously
+controlled whether the C<nlink> field was populated requiring a
+separate Windows API call to fetch, since nlink and the other
+information required for stat() is now retrieved in a single API call.
 
-=head2 Platform-Specific Notes
+The C<-r> and C<-w> operators now return true for the C<STDIN>,
+C<STDOUT> and C<STDERR> handles.  Unfortunately it still won't return
+true for duplicates of those handles.
+L<[#8502]|https://github.com/Perl/perl5/issues/8502>.
+
+The times returned by stat() and lstat() are no longer incorrect
+across Daylight Savings Time adjustments.
+L<[#6080]|https://github.com/Perl/perl5/issues/6080>.
+
+C<-x> on a filehandle should now match C<-x> on the corresponding
+filename on Vista or later.
+L<[#4145]|https://github.com/Perl/perl5/issues/4145>.
+
+C<-e '"'> no longer incorrectly returns true.
+L<[#12431]|https://github.com/Perl/perl5/issues/12431>.
+
+=back
+
+=head1 Internal Changes
 
 =over 4
 
-=item DragonFlyBSD
+=item *
+
+All C<SvTRUE>-ish functions now evaluate their arguments exactly once.
+In 5.32, plain L<perlapi/C<SvTRUE>> was changed to do that; now the rest
+do as well.
+
+=item *
 
-Tests were updated to workaround DragonFlyBSD bugs in L<tc*()
-functions|https://bugs.dragonflybsd.org/issues/3252> and L<ctime
-updates|https://bugs.dragonflybsd.org/issues/3251>.
+Unicode is now a first class citizen when considering the pattern /A*B/ where
+A and B are arbitrary.  The pattern matching code tries to make a tight loop
+to match the span of A's.  The logic of this was now really updated with
+support for UTF-8.
 
 =back
 
@@ -145,33 +228,68 @@ updates|https://bugs.dragonflybsd.org/issues/3251>.
 
 =item *
 
-Magic is now called correctly for stacked file test operators.  [L<GH #18293|https://github.com/Perl/perl5/issues/18293>]
+L<semctl()|perlfunc/semctl>, L<msgctl()|perlfunc/msgctl>, and
+L<shmctl()|perlfunc/shmctl> now properly reset the UTF-8 flag on the
+C<ARG> parameter if it's modified for C<IPC_STAT> or C<GETALL>
+operations.
 
 =item *
 
-The C<@ary = split(...)> optimization no longer switches in the target
-array as the value stack. [L<GH #18232|https://github.com/Perl/perl5/issues/18232>] Also see discussion at
-L<https://github.com/Perl/perl5/pull/18014#issuecomment-671299506>.
+semctl(), msgctl(), and shmctl() now attempt to downgrade the C<ARG>
+parameter if it's value is being used as input to C<IPC_SET> or
+C<SETALL> calls.  A failed downgrade will thrown an exception.
+
+=item *
+
+In cases where semctl(), msgctl() or shmctl() would treat the C<ARG>
+parameter as a pointer, an undefined value no longer generates a
+warning.  In most such calls the pointer isn't used anyway and this
+allows you to supply C<undef> for a value not used by the underlying
+function.
+
+=item *
+
+L<semop()|perlfunc/semop> now downgrades the C<OPSTRING> parameter,
+L<msgsnd()|perlfunc/msgsnd> now downgrades the C<MSG> parameter and
+L<shmwrite|perlfunc/shmwrite> now downgrades the C<STRING> parameter
+to treat them as bytes.  Previously they would be left upgraded,
+providing a corrupted structure to the underlying function call.
+
+=item *
+
+L<msgrcv()|perlfunc/msgrcv> now properly resets the UTF-8 flag the
+C<VAR> parameter when it is modified.  Previusly the UTF-8 flag could
+be left on, resulting in a possibly corrupt result in C<VAR>.
 
 =back
 
+=head1 Known Problems
+
+None
+
+=head1 Errata From Previous Releases
+
+None
+
 =head1 Acknowledgements
 
-Perl 5.33.4 represents approximately 4 weeks of development since Perl
-5.33.3 and contains approximately 6,900 lines of changes across 340 files
-from 16 authors.
+Perl 5.33.5 represents approximately 4 weeks of development since Perl
+5.33.4 and contains approximately 22,000 lines of changes across 370 files
+from 27 authors.
 
 Excluding auto-generated files, documentation and release tools, there were
-approximately 4,200 lines of changes to 260 .pm, .t, .c and .h files.
+approximately 15,000 lines of changes to 220 .pm, .t, .c and .h files.
 
 Perl continues to flourish into its fourth decade thanks to a vibrant
 community of users and developers. The following people are known to have
-contributed the improvements that became Perl 5.33.4:
-
-Ben Cornett, Chris 'BinGOs' Williams, Dan Book, David Mitchell, Giovanni
-Tataranni, James E Keenan, Karen Etheridge, Karl Williamson, Marcus
-Holland-Moritz, Nicolas R., Richard Leach, Scott Baker, Steve Hay, TAKAI
-Kousuke, Tom Hukins, Tony Cook.
+contributed the improvements that became Perl 5.33.5:
+
+Branislav Zahradník, Chris 'BinGOs' Williams, Dan Book, Dan Kogai, David
+Cantrell, David Mitchell, Graham Knop, H.Merijn Brand, Jae Bradley, James E
+Keenan, Jason McIntosh, jkahrman, John Karr, Karen Etheridge, Karl
+Williamson, Leon Timmermans, Max Maischein, Paul Evans, Sawyer X, Sevan
+Janiyan, Shlomi Fish, Steve Hay, TAKAI Kousuke, Thibault Duponchelle, Tomasz
+Konojacki, Tom Hukins, Tony Cook.
 
 The list above is almost certainly incomplete as it is automatically
 generated from version control history. In particular, it does not include
diff --git a/pod/perldocstyle.pod b/pod/perldocstyle.pod
new file mode 100644 (file)
index 0000000..f239ba1
--- /dev/null
@@ -0,0 +1,1118 @@
+=encoding utf8
+
+=head1 NAME
+
+perldocstyle - A style guide for writing Perl's documentation
+
+=head1 DESCRIPTION
+
+This document is a guide for the authorship and maintenance of the
+documentation that ships with Perl. This includes the following:
+
+=over
+
+=item *
+
+The several dozen manual sections whose filenames begin with "C<perl>",
+such as C<perlobj>, C<perlre>, and C<perlintro>. (And, yes, C<perl>.)
+
+=item *
+
+The documentation for all the modules included with Perl (as listed by
+L<C<perlmodlib>|perlmodlib>).
+
+=item *
+
+The hundreds of individually presented reference sections derived from
+the L<C<perlfunc>|perlfunc> file.
+
+=back
+
+This guide will hereafter refer to user-manual section files as I<man
+pages>, per Unix convention.
+
+=head2 Purpose of this guide
+
+This style guide aims to establish standards, procedures, and philosophies
+applicable to Perl's core documentation.
+
+Adherence to these standards will help ensure that any one part of
+Perl's manual has a tone and style consistent with that of any other. As
+with the rest of the Perl project, the language's documentation
+collection is an open-source project authored over a long period of time
+by many people. Maintaining consistency across such a wide swath of work
+presents a challenge; this guide provides a foundation to help mitigate
+this difficulty.
+
+This will help its readers--especially those new to Perl--to feel
+more welcome and engaged with Perl's documentation, and this in turn
+will help the Perl project itself grow stronger through having a larger,
+more diverse, and more confident population of knowledgeable users.
+
+=head2 Intended audience
+
+Anyone interested in contributing to Perl's core documentation should
+familiarize themselves with the standards outlined by this guide.
+
+Programmers documenting their own work apart from the Perl project
+itself may also find this guide worthwhile, especially if they wish
+their work to extend the tone and style of Perl's own manual.
+
+=head2 Status of this document
+
+This guide was initially drafted in late 2020, drawing from the
+documentation style guides of several open-source technologies
+contemporary with Perl. This has included Python, Raku, Rust, and the
+Linux kernel.
+
+The author intends to see this guide used as starting place from
+which to launch a review of Perl's reams of extant documentation, with
+the expectation that those conducting this review should grow and modify
+this guide as needed to account for the requirements and quirks
+particular to Perl's programming manual.
+
+=head1 FUNDAMENTALS
+
+=head2 Choice of markup: Pod
+
+All of Perl's core documentation uses Pod ("Plain Old Documentation"), a
+simple markup language, to format its source text. Pod is similar in
+spirit to other contemporary lightweight markup technologies, such as
+Markdown and reStructuredText, and has a decades-long shared history
+with Perl itself.
+
+For a comprehensive reference to Pod syntax, see L<C<perlpod>|perlpod>.
+For the sake of reading this guide, familiarity with the Pod syntax for
+section headers (C<=head2>, et cetera) and for inline text formatting
+(C<CE<lt>like thisE<gt>>) should suffice.
+
+Perl programmers also use Pod to document their own scripts, libraries,
+and modules. This use of Pod has its own style guide, outlined by
+L<C<perlpodstyle>|perlpodstyle>.
+
+=head2 Choice of language: American English
+
+Perl's core documentation is written in English, with a preference for
+American spelling of words and expression of phrases. That means "color"
+over "colour", "math" versus "maths", "the team has decided" and not
+"the team have decided", and so on.
+
+We name one style of English for the sake of consistency across Perl's
+documentation, much as a software project might declare a four-space
+indentation standard--even when that doesn't affect how well the code
+compiles. Both efforts result in an easier read by avoiding jarring,
+mid-document changes in format or style.
+
+Contributors to Perl's documentation should note that this rule
+describes the ultimate, published output of the project, and does not
+prescribe the dialect used within community contributions. The
+documentation team enthusiastically welcomes any English-language
+contributions, and will actively assist in Americanizing spelling and
+style when warranted.
+
+=head3 Other languages and translations
+
+Community-authored translations of Perl's documentation do exist,
+covering a variety of languages. While the Perl project appreciates
+these translation efforts and promotes them when applicable, it does not
+officially support or maintain any of them.
+
+That said, keeping Perl's documentation clear, simple, and short has a
+welcome side effect of aiding any such translation project.
+
+(Note that the Chinese, Japanese, and Korean-language README files
+included with Perl's source distributions provide an exception to this
+choice of language--but these documents fall outside the scope of this
+guide.)
+
+=head2 Choice of encoding: UTF-8
+
+Perl's core documentation files are encoded in UTF-8, and can make use
+of the full range of characters this encoding allows.
+
+As such, every core doc file (or the Pod section of every core module)
+should commence with an C<=encoding utf8> declaration.
+
+=head2 Choice of underlying style guide: CMOS
+
+Perl's documentation uses the L<Chicago Manual of
+Style|https://www.chicagomanualofstyle.org> (CMOS), 17th Edition, as
+its baseline guide for style and grammar. While the document you are
+currently reading endeavors to serve as an adequate stand-alone style guide
+for the purposes of documenting Perl, authors should consider CMOS the
+fallback authority for any pertinent topics not covered here.
+
+Because CMOS is not a free resource, access to it is not a prerequisite
+for contributing to Perl's documentation; the doc team will help
+contributors learn about and apply its guidelines as needed. However, we
+do encourage anyone interested in significant doc contributions to
+obtain or at least read through CMOS. (Copies are likely available
+through most public libraries, and CMOS-derived fundamentals can be
+found online as well.)
+
+=head2 Contributing to Perl's documentation
+
+Perl, like any programming language, is only as good as its
+documentation. Perl depends upon clear, friendly, and thorough
+documentation in order to welcome brand-new users, teach and explain the
+language's various concepts and components, and serve as a lifelong
+reference for experienced Perl programmers. As such, the Perl project
+welcomes and values all community efforts to improve the language's
+documentation.
+
+Perl accepts documentation contributions through the same open-source
+project pipeline as code contributions. See L<C<perlhack>|perlhack> for
+more information.
+
+=head1 FORMATTING AND STRUCTURE
+
+This section details specific Pod syntax and style that all core Perl
+documentation should adhere to, in the interest of consistency and
+readability.
+
+=head2 Document structure
+
+Each individual work of core Perl documentation, whether contained
+within a C<.pod> file or in the Pod section of a standard code module,
+patterns its structure after a number of long-time Unix man page
+conventions. (Hence this guide's use of "man page" to refer to any one
+self-contained part of Perl's documentation.)
+
+Adhering to these conventions helps Pod formatters present a Perl man
+page's content in different contexts--whether a terminal, the web, or
+even print. Many of the following requirements originate with
+L<C<perlpodstyle>|perlpodstyle>, which derives its recommendations in
+turn from these well-established practices.
+
+=head3 Name
+
+After its L<C<=encoding utf8> declaration|/Choice of encoding: UTF-8>, a
+Perl man page I<must> present a level-one header named "NAME" (literally),
+followed by a paragraph containing the page's name and a very brief
+description.
+
+The first few lines of a notional page named C<perlpodexample>:
+
+    =encoding utf8
+
+    =head1 NAME
+
+    perlpodexample - An example of formatting a manual page's title line
+
+=head3 Description and synopsis
+
+Most Perl man pages also contain a DESCRIPTION section featuring a
+summary of, or introduction to, the document's content and purpose.
+
+This section should also, one way or another, clearly identify the
+audience that the page addresses, especially if it has expectations
+about the reader's prior knowledge. For example, a man page that dives
+deep into the inner workings of Perl's regular expression engine should
+state its assumptions up front--and quickly redirect readers who are
+instead looking for a more basic reference or tutorial.
+
+Reference pages, when appropriate, can precede the DESCRIPTION with a
+SYNOPSIS section that lists, within one or more code blocks, some very
+brief examples of the referenced feature's use. This section should show
+a handful of common-case and best-practice examples, rather than an
+exhaustive list of every obscure method or alternate syntax available.
+
+=head3 Other sections and subsections
+
+Pages should conclude, when appropriate, with a SEE ALSO section
+containing hyperlinks to relevant sections of Perl's manual, other Unix
+man pages, or appropriate web pages. Hyperlink each such cross-reference via
+C<LE<lt>...E<gt>>.
+
+What other sections to include depends entirely upon the topic at hand.
+Authors should feel free to include further C<=head1>-level sections,
+whether other standard ones listed by C<perlpodstyle>, or ones specific
+to the page's topic; in either case, render these top-level headings in
+all-capital letters.
+
+You may then include as many subsections beneath them as needed to meet
+the standards of clarity, accessibility, and cross-reference affinity
+L<suggested elsewhere in this guide|/Apply one of the four documentation
+modes>.
+
+=head3 Author and copyright
+
+In most circumstances, Perl's stand-alone man pages--those contained
+within C<.pod> files--do not need to include any copyright or license
+information about themselves. Their source Pod files are part of Perl's
+own core software repository, and that already covers them under the
+same copyright and license terms as Perl itself. You do not need to
+include additional "LICENSE" or "COPYRIGHT" sections of your own.
+
+These man pages may optionally credit their primary author, or include a
+list of significant contributors, under "AUTHOR" or "CONTRIBUTORS"
+headings. Note that the presence of authors' names does not preclude a
+given page from L<writing in a voice consistent with the rest of Perl's
+documentation|/The documentation speaks with one voice>.
+
+Note that these guidelines do not apply to the core software modules
+that ship with Perl. These have their own standards for authorship and
+copyright statements, as found in C<perlpodstyle>.
+
+=head2 Formatting rules
+
+=head3 Line length and line wrap
+
+Each line within a Perl man page's Pod source file should measure 72
+characters or fewer in length.
+
+Please break paragraphs up into blocks of short lines, rather than
+"soft wrapping" paragraphs across hundreds of characters with no line
+breaks.
+
+=head3 Code blocks
+
+Just like the text around them, all code examples should be as short and
+readable as possible, displaying no more complexity than absolutely
+necessary to illustrate the concept at hand.
+
+For the sake of consistency within and across Perl's man pages, all
+examples must adhere to the code-layout principles set out by
+L<C<perlstyle>|perlstyle>.
+
+Sample code should deviate from these standards only when necessary:
+during a demonstration of how Perl disregards whitespace, for example,
+or to temporarily switch to two-column indentation for an unavoidably
+verbose illustration.
+
+You may include comments within example code to further clarify or label
+the code's behavior in-line. You may also use comments as placeholder
+for code normally present but not relevant to the current topic, like
+so:
+
+    while (my $line = <$fh>) {
+        #
+        # (Do something interesting with $line here.)
+        #
+    }
+
+Even the simplest code blocks often require the use of example
+variables and subroutines, L<whose names you should choose with
+care|/Use meaningful variable and symbol names in examples>.
+
+=head3 Inline code and literals
+
+Within a paragraph of text, use C<CE<lt>...E<gt>> when quoting or
+referring to any bit of Perl code--even if it is only one character
+long.
+
+For instance, when referring within an explanatory paragraph to Perl's
+operator for adding two numbers together, you'd write "C<CE<lt>+E<gt>>".
+
+=head3 Function names
+
+Use C<CE<lt>...E<gt>> to render all Perl function names in monospace,
+whenever they appear in text.
+
+Unless you need to specifically quote a function call with a list of
+arguments, do not follow a function's name in text with a pair of empty
+parentheses. That is, when referring in general to Perl's C<print>
+function, write it as "C<print>", not "C<print()>".
+
+=head3 Function arguments
+
+Represent functions' expected arguments in all-caps, with no sigils, and
+using C<CE<lt>...E<gt>> to render them in monospace. These arguments
+should have short names making their nature and purpose clear.
+Convention specifies a few ones commonly seen throughout Perl's
+documentation:
+
+=over
+
+=item *
+
+EXPR
+
+The "generic" argument: any scalar value, or a Perl expression that
+evaluates to one.
+
+=item *
+
+ARRAY
+
+An array, stored in a named variable.
+
+=item *
+
+HASH
+
+A hash, stored in a named variable.
+
+=item *
+
+BLOCK
+
+A curly-braced code block, or a subroutine reference.
+
+=item *
+
+LIST
+
+Any number of values, stored across any number of variables or
+expressions, which the function will "flatten" and treat as a single
+list. (And because it can contain any number of variables, it must be
+the I<last> argument, when present.)
+
+=back
+
+When possible, give scalar arguments names that suggest their purpose
+among the arguments. See, for example, L<C<substr>'s
+documentation|perlfunc/substr>, whose
+listed arguments include C<EXPR>, C<OFFSET>, C<LENGTH>, and C<REPLACEMENT>.
+
+=head3 Apostrophes, quotes, and dashes
+
+In Pod source, use straight quotes, and not "curly quotes":  "Like
+ this", not “like this”. The same goes for apostrophes:  Here's a
+ positive example, and here’s a negative one.
+
+Render em dashes as two hyphens--like this:
+
+    Render em dashes as two hyphens--like this.
+
+Leave it up to formatters to reformat and reshape these punctuation
+marks as best fits their respective target media.
+
+=head3 Unix programs and C functions
+
+When referring to a Unix program or C function with its own man page
+(outside of Perl's documentation), include its manual section number in
+parentheses. For example: C<malloc(3)>, or C<mkdir(1)>.
+
+If mentioning this program for the first time within a man page or
+section, make it a cross reference, e.g. C<LE<lt>malloc(3)E<gt>>.
+
+Do not otherwise style this text.
+
+=head3 Cross-references and hyperlinks
+
+Make generous use of Pod's C<LE<lt>...E<gt>> syntax to create hyperlinks
+to other parts of the current man page, or to other documents entirely
+-- whether elsewhere on the reader's computer, or somewhere on the
+internet, via URL.
+
+Use C<LE<lt>...E<gt>> to link to another section of the current man page
+when mentioning it, and make use of its page-and-section syntax to link to
+the most specific section of a separate page within Perl's
+documentation. Generally, the first time you refer to a specific
+function, program, or concept within a certain page or section, consider
+linking to its full documentation.
+
+Hyperlinks do not supersede other formatting required by this guide; Pod
+allows nested text formats, and you should use this feature as needed.
+
+Here is an example sentence that mentions Perl's C<say> function, with a
+link to its documentation section within the C<perlfunc> man page:
+
+    In version 5.10, Perl added support for the 
+    L<C<say>|perlfunc/say FILEHANDLE LIST> function.
+
+Note the use of the vertical pipe ("C<|>") to separate how the link will
+appear to readers ("C<CE<lt>sayE<gt>>") from the full page-and-section specifier
+that the formatter links to.
+
+=head3 Tables and diagrams
+
+Pod does not officially support tables. To best present tabular data,
+include the table as both HTML and plain-text representations--the
+latter as an indented code block. Use C<=begin> / C<=end> directives to
+target these tables at C<html> and C<text> Pod formatters, respectively.
+For example:
+
+    =head2 Table of fruits
+
+    =begin text
+
+     Name           Shape           Color
+     =====================================
+     Apple          Round           Red
+     Banana         Long            Yellow
+     Pear           Pear-shaped     Green
+
+    =end text
+
+    =begin html
+
+    <table>
+    <tr><th>Name</th><th>Shape</th><th>Color</th></tr>
+    <tr><td>Apple</td><td>Round</td><td>Red</td></tr>
+    <tr><td>Banana</td><td>Long</td><td>Yellow</td></tr>
+    <tr><td>Pear</td><td>Pear-shaped</td><td>Green</td></tr>
+    </table>
+
+    =end html
+
+The same holds true for figures and graphical illustrations. Pod does
+not natively support inline graphics, but you can mix HTML C<<< <img> >>> tags
+with monospaced text-art representations of those images' content.
+
+Due in part to these limitations, most Perl man pages use neither tables
+nor diagrams. Like any other tool in your documentation toolkit,
+however, you may consider their inclusion when they would improve an
+explanation's clarity without adding to its complexity.
+
+=head2 Adding comments
+
+Like any other kind of source code, Pod lets you insert comments visible
+only to other people reading the source directly, and ignored by the
+formatting programs that transform Pod into various human-friendly
+output formats (such as HTML or PDF). 
+
+To comment Pod text, use the C<=for> and C<=begin> / C<=end> Pod
+directives, aiming them at a (notional) formatter called "C<comment>". A
+couple of examples:
+
+    =for comment Using "=for comment" like this is good for short,
+    single-paragraph comments.
+
+    =begin comment
+
+    If you need to comment out more than one paragraph, use a
+    =begin/=end block, like this.
+
+    None of the text or markup in this whole example would be visible to
+    someone reading the documentation through normal means, so it's
+    great for leaving notes, explanations, or suggestions for your
+    fellow documentation writers.
+
+    =end comment
+
+In the tradition of any good open-source project, you should make free
+but judicious use of comments to leave in-line "meta-documentation" as
+needed for other Perl documentation writers (including your future
+self).
+
+=head2 Perlfunc has special rules
+
+The L<C<perlfunc> man page|perlfunc>, an exhaustive reference of every
+Perl built-in function, has a handful of formatting rules not seen
+elsewhere in Perl's documentation.
+
+Software used during Perl's build process
+(L<Pod::Functions|Pod::Functions>) parses this page according to certain
+rules, in order to build separate man pages for each of Perl's
+functions, as well as achieve other indexing effects. As such,
+contributors to perlfunc must know about and adhere to its particular
+rules.
+
+Most of the perfunc man page comprises a single list, found under the
+header L<"Alphabetical Listing of Perl Functions"|perlfunc/Alphabetical
+Listing of Perl Functions>. Each function reference is an entry on that
+list, made of three parts, in order:
+
+=over
+
+=item 1.
+
+A list of C<=item> lines which each demonstrate, in template format, a
+way to call this function. One line should exist for every combination
+of arguments that the function accepts (including no arguments at all,
+if applicable).
+
+If modern best practices prefer certain ways to invoke the function
+over others, then those ways should lead the list.
+
+The first item of the list should be immediately followed by one or
+more C<XE<lt>...E<gt>> terms listing index-worthy topics; if nothing
+else, then the name of the function, with no arguments.
+
+=item 2.
+
+A C<=for> line, directed at C<Pod::Functions>, containing a one-line
+description of what the function does. This is written as a phrase, led
+with an imperative verb, with neither leading capitalization nor ending
+punctuation. Examples include "quote a list of words" and "change a
+filename".
+
+=item 3.
+
+The function's definition and reference material, including all
+explanatory text and code examples.
+
+=back
+
+Complex functions that need their text divided into subsections (under
+the principles of L<"Apply section-breaks and examples
+generously"|/Apply section-breaks and examples generously>) may do so by
+using sublists, with C<=item> elements as header text.
+
+A fictional function "C<myfunc>", which takes a list as an optional
+argument, might have an entry in perlfunc shaped like this:
+
+    =item myfunc LIST
+    X<myfunc>
+
+    =item myfunc
+
+    =for Pod::Functions demonstrate a function's perlfunc section 
+
+    [ Main part of function definition goes here, with examples ]
+
+    =over
+
+    =item Legacy uses
+
+    [ Examples of deprecated syntax still worth documenting ]
+
+    =item Security considerations
+
+    [ And so on... ]
+
+    =back
+
+=head1 TONE AND STYLE
+
+=head2 Apply one of the four documentation modes
+
+Aside from "meta" documentation such as C<perlhist> or C<perlartistic>,
+each of Perl's man pages should conform to one of the four documentation
+"modes" suggested by L<I<The Documentation System> by Daniele
+Procida|https://documentation.divio.com>. These include tutorials,
+cookbooks, explainers, and references--terms that we define in further
+detail below.
+
+Each mode of documentation speaks to a different audience--not just
+people of different backgrounds and skill levels, but individual readers
+whose needs from language documentation can shift depending upon
+context. For example, a programmer with plenty of time to learn a new
+concept about Perl can ease into a tutorial about it, and later expand
+their knowledge further by studying an explainer. Later, that same
+programmer, wading knee-deep in live code and needing only to look up
+some function's exact syntax, will want to reach for a reference page
+instead.
+
+Perl's documentation must strive to meet these different situational
+expectations by limiting each man page to a single mode. This helps
+writers ensure they provide readers with the documentation needed or
+expected, despite ever-evolving situations.
+
+=head3 Tutorial
+
+A tutorial man page focuses on B<learning>, ideally by I<doing>. It
+presents the reader with small, interesting examples that allow them to
+follow along themselves using their own Perl interpreter. The tutorial
+inspires comprehension by letting its readers immediately experience
+(and experiment on) the concept in question. Examples include
+C<perlxstut>, C<perlpacktut>, and
+C<perlretut>.
+
+Tutorial man pages must strive for a welcoming and reassuring tone from
+their outset; they may very well be the first things that a newcomer to
+Perl reads, playing a significant role in whether they choose
+to stick around. Even an experienced programmer can benefit from the
+sense of courage imparted by a strong tutorial about a more advanced
+topic. After completing a tutorial, a reader should feel like they've
+been led from zero knowledge of its topic to having an invigorating
+spark of basic understanding, excited to learn more and experiment
+further.
+
+Tutorials can certainly use real-world examples when that helps make for
+clear, relatable demonstrations, so long as they keep the focus on
+teaching--more practical problem-solving should be left to the realm
+of cookbooks (as described below). Tutorials also needn't concern
+themselves with explanations into why or how things work beneath the
+surface, or explorations of alternate syntaxes and solutions; these are
+better handled by explainers and reference pages.
+
+=head3 Cookbook
+
+A cookbook man page focuses on B<results>. Just like its name suggests,
+it presents succinct, step-by-step solutions to a variety of real-world
+problems around some topic. A cookbook's code examples serve less to
+enlighten and more to provide quick, paste-ready solutions that the
+reader can apply immediately to the situation facing them.
+
+A Perl cookbook demonstrates ways that all the tools and techniques
+explained elsewhere can work together in order to achieve practical
+results. Any explanation deeper than that belongs in explainers and
+reference pages, instead. (Certainly, a cookbook can cross-reference
+other man pages in order to satisfy the curiosity of readers who, with
+their immediate problems solved, wish to learn more.)
+
+The most prominent cookbook pages that ship with Perl itself are its
+many FAQ pages, in particular C<perlfaq4> and up, which provide short
+solutions to practical questions in question-and-answer style.
+C<perlunicook> shows another example, containing a bevy of practical code
+snippets for a variety of internationally minded text manipulations.
+
+(An aside: I<The Documentation System> calls this mode "how-to", but
+Perl's history of creative cuisine prefers the more kitchen-ready term
+that we employ here.)
+
+=head3 Reference
+
+A reference page focuses on B<description>. Austere, uniform, and
+succinct, reference pages--often arranged into a whole section of
+mutually similar subpages--lend themselves well to "random access" by
+a reader who knows precisely what knowledge they need, requiring only
+the minimum amount of information before returning to the task at hand.
+
+Perl's own best example of a reference work is C<perlfunc>, the
+sprawling man page that details the operation of every function built
+into Perl, with each function's documentation presenting the same kinds
+of information in the same order as every other. For an example of a
+shorter reference on a single topic, look at C<perlreref>.
+
+Module documentation--including that of all the modules listed in
+L<C<perlmodlib>|perlmodlib>--also counts as reference. They follow
+precepts similar to those laid down by the C<perlpodstyle> man page, such
+as opening with an example-laden "SYNOPSIS" section, or featuring a
+"METHODS" section that succinctly lists and defines an object-oriented
+module's public interface.
+
+=head3 Explainer
+
+Explainer pages focus on B<discussion>. Each explainer dives as deep as
+needed into some Perl-relevant topic, taking all the time and space
+needed to give the reader a thorough understanding of it. Explainers
+mean to impart knowledge through study. They don't assume that the
+student has a Perl interpreter fired up and hungry for immediate examples
+(as with a tutorial), or specific Perl problems that they need quick
+answers for (which cookbooks and reference pages can help with).
+
+Outside of its reference pages, most of Perl's manual belongs to this
+mode. This includes the majority of the man pages whose names start with
+"C<perl>". A fine example is C<perlsyn>, the Perl Syntax page, which
+explores the whys and wherefores of Perl's unique syntax in a
+wide-ranging discussion laden with many references to the language's
+history, culture, and driving philosophies.
+
+Perl's explainer pages give authors a chance to explore Perl's penchant
+for L<TMTOWTDI|perlglossary/TMTOWTDI>, illustrating alternate and even
+obscure ways to use the language feature under discussion. However, as
+the remainder of this guide discusses, the ideal Perl documentation
+manages to deliver its message clearly and concisely, and not confuse
+mere wordiness for completeness.
+
+=head3 Further notes on documentation modes
+
+Keep in mind that the purpose of this categorization is not to dictate
+content--a very thorough explainer might contain short reference
+sections of its own, for example, or a reference page about a very
+complex function might resemble an explainer in places (e.g.
+L<C<open>|perlfunc/open FILEHANDLE,MODE,EXPR>). Rather, it makes sure
+that the authors and contributors of any given man page agree on what
+sort of audience that page addresses.
+
+If a new or otherwise uncategorized man page presents itself as
+resistant to fitting into only one of the four modes, consider breaking
+it up into separate pages. That may mean creating a new "C<perl[...]>"
+man page, or (in the case of module documentation) making new packages
+underneath that module's namespace that serve only to hold additional
+documentation. For instance, C<Example::Module>'s reference documentation
+might include a see-also link to C<Example::Module::Cookbook>.
+
+Perl's several man pages about Unicode--comprising a short tutorial, a
+thorough explainer, a cookbook, and a FAQ--provide a fine example of
+spreading a complicated topic across several man pages with different
+and clearly indicated purposes.
+
+=head2 Assume readers' intelligence, but not their knowledge
+
+Perl has grown a great deal from its humble beginnings as a tool for
+people already well versed in C programming and various Unix utilities.
+Today, a person learning Perl might come from any social or
+technological background, with a range of possible motivations
+stretching far beyond system administration.
+
+Perl's core documentation must recognize this by making as few
+assumptions as possible about the reader's prior knowledge. While you
+should assume that readers of Perl's documentation are smart, curious,
+and eager to learn, you should not confuse this for pre-existing
+knowledge about any other technology, or even programming in
+general--especially in tutorial or introductory material.
+
+=head3 Keep Perl's documentation about Perl
+
+Outside of pages tasked specifically with exploring Perl's relationship
+with other programming languages, the documentation should keep the
+focus on Perl. Avoid drawing analogies to other technologies that the
+reader may not have familiarity with.
+
+For example, when documenting one of Perl's built-in functions, write as
+if the reader is now learning about that function for the first time, in
+any programming language.
+
+Choosing to instead compare it to an equivalent or underlying C function
+will probably not illuminate much understanding in a contemporary
+reader. Worse, this can risk leaving readers unfamiliar with C feeling
+locked out from fully understanding of the topic--to say nothing of
+readers new to computer programming altogether.
+
+If, however, that function's ties to its C roots can lead to deeper
+understanding with practical applications for a Perl programmer, you may
+mention that link after its more immediately useful documentation.
+Otherwise, omit this information entirely, leaving it for other
+documentation or external articles more concerned with examining Perl's
+underlying implementation details.
+
+=head3 Deploy jargon when needed, but define it as well
+
+Domain-specific jargon has its place, especially within documentation.
+However, if a man page makes use of jargon that a typical reader might
+not already know, then that page should make an effort to define the
+term in question early-on--either explicitly, or via cross reference.
+
+For example, Perl loves working with filehandles, and as such that word
+appears throughout its documentation. A new Perl programmer arriving at
+a man page for the first time is quite likely to have no idea what a
+"filehandle" is, though. Any Perl man page mentioning filehandles
+should, at the very least, hyperlink that term to an explanation
+elsewhere in Perl's documentation. If appropriate--for example, in the
+lead-in to L<C<open> function's detailed reference|perlfunc/open
+FILEHANDLE,MODE,EXPR>--it can also include a very short in-place
+definition of the concept for the reader's convenience.
+
+=head2 Use meaningful variable and symbol names in examples
+
+When quickly sketching out examples, English-speaking programmers have a
+long tradition of using short nonsense words as placeholders for
+variables and other symbols--such as the venerable C<foo>, C<bar>, and
+C<baz>. Example code found in a programming language's official,
+permanent documentation, however, can and should make an effort to
+provide a little more clarity through specificity.
+
+Whenever possible, code examples should give variables, classes, and
+other programmer-defined symbols names that clearly demonstrate their
+function and their relationship to one another. For example, if an
+example requires that one class show an "is-a" relationship with
+another, consider naming them something like C<Apple> and C<Fruit>, rather
+than C<Foo> and C<Bar>. Similarly, sample code creating an instance of
+that class would do better to name it C<$apple>, rather than C<$baz>.
+
+Even the simplest examples benefit from clear language using concrete
+words. Prefer a construct like C<for my $item (@items) { ... }> over
+C<for my $blah (@blah) { ... }>.
+
+=head2 Write in English, but not just for English-speakers
+
+While this style guide does specify American English as the
+documentation's language for the sake of internal consistency, authors
+should avoid cultural or idiomatic references available only to
+English-speaking Americans (or any other specific culture or society).
+As much as possible, the language employed by Perl's core documentation
+should strive towards cultural universality, if not neutrality. Regional
+turns of phrase, examples drawing on popular-culture knowledge, and
+other rhetorical techniques of that nature should appear sparingly, if
+at all.
+
+Authors should feel free to let more freewheeling language flourish in
+"second-order" documentation about Perl, like books, blog entries, and
+magazine articles, published elsewhere and with a narrower readership in
+mind. But Perl's own docs should use language as accessible and
+welcoming to as wide an audience as possible.
+
+=head2 Omit placeholder text or commentary
+
+Placeholder text does not belong in the documentation that ships with
+Perl. No section header should be followed by text reading only "Watch
+this space", "To be included later", or the like. While Perl's source
+files may shift and alter as much as any other actively maintained
+technology, each released iteration of its technology should feel
+complete and self-contained, with no such future promises or other loose
+ends visible.
+
+Take advantage of Perl's regular release cycle. Instead of cluttering
+the docs with flags promising more information later--the presence of
+which do not help readers at all today--the documentation's
+maintenance team should treat any known documentation absences as an
+issue to address like any other in the Perl project. Let Perl's
+contributors, testers, and release engineers address that need, and
+resist the temptation to insert apologies, which have all the utility in
+documentation as undeleted debug messages do in production code.
+
+=head2 Apply section-breaks and examples generously
+
+No matter how accessible their tone, the sight of monolithic blocks of
+text in technical documentation can present a will-weakening challenge
+for the reader. Authors can improve this situation through breaking long
+passages up into subsections with short, meaningful headers.
+
+Since every section-header in Pod also acts as a potential end-point for
+a cross-reference (made via Pod's C<LE<lt>...E<gt>> syntax), putting
+plenty of subsections in your documentation lets other man pages more
+precisely link to a particular topic. This creates hyperlinks directly
+to the most appropriate section rather than to the whole page in
+general, and helps create a more cohesive sense of a rich, consistent,
+and interrelated manual for readers.
+
+Among the four documentation modes, sections belong more naturally in
+tutorials and explainers. The step-by-step instructions of cookbooks, or
+the austere definitions of reference pages, usually have no room for
+them. But authors can always make exceptions for unusually complex
+concepts that require further breakdown for clarity's sake.
+
+Example code, on the other hand, can be a welcome addition to any mode
+of documentation. Code blocks help break up a man page visually,
+reassuring the reader that no matter how deep the textual explanation
+gets, they are never far from another practical example showing how it
+all comes together using a small, easy-to-read snippet of tested Perl
+code.
+
+=head2 Lead with common cases and best practices
+
+Perl famously gives programmers more than one way to do things. Like any
+other long-lived programming language, Perl has also built up a large,
+community-held notion of best practices, blessing some ways to do things
+as better than others, usually for the sake of more maintainable code.
+
+=head3 Show the better ways first
+
+Whenever it needs to show the rules for a technique which Perl provides
+many avenues for, the documentation should always lead with best
+practices. And when discussing some part of the Perl toolkit with many
+applications, the docs should begin with a demonstration of its
+application to the most common cases.
+
+The C<open> function, for example, has myriad potential uses within Perl
+programs, but I<most of the time> programmers--and especially those new
+to Perl--turn to this reference because they simply wish to open a
+file for reading or writing. For this reason, C<open>'s documentation
+begins there, and only descends into the function's more obscure uses
+after thoroughly documenting and demonstrating how it works in the
+common case. Furthermore, while engaging in this demonstration, the
+C<open> documentation does not burden the reader right away with detailed
+explanations about calling C<open> via any route other than the
+best-practice, three-argument style. 
+
+=head3 Show the lesser ways when needed
+
+Sometimes, thoroughness demands documentation of deprecated techniques.
+For example, a certain Perl function might have an alternate syntax now
+considered outmoded and no longer best-practice, but which a maintainer
+of a legacy project might quite reasonably encounter when exploring old
+code. In this case, these features deserve documentation, but couched in
+clarity that modern Perl avoids such structures, and does not recommend
+their use in new projects.
+
+Another way to look at this philosophy (and one L<borrowed from our
+friends|https://devguide.python.org/documenting/#affirmative-tone> on
+Python's documentation team) involves writing while sympathizing with a
+programmer new to Perl, who may feel uncertain about learning a complex
+concept. By leading that concept's main documentation with clear,
+positive examples, we can immediately give these readers a simple and
+true picture of how it works in Perl, and boost their own confidence to
+start making use of this new knowledge. Certainly we should include
+alternate routes and admonitions as reasonably required, but we needn't
+emphasize them. Trust the reader to understand the basics quickly, and
+to keep reading for a deeper understanding if they feel so driven.
+
+=head2 Document Perl's present
+
+Perl's documentation should stay focused on Perl's present behavior,
+with a nod to future directions.
+
+=head3 Recount the past only when necessary
+
+=for comment
+The principles of this section caused a lot of lively discussion and
+debate among p5p when first proposed in October 2020. I am keeping the
+recommendations nonspecific, and expect this section to receive a lot of
+further refinement as we start to apply it to core docs.
+
+When some Perl feature changes its behavior, documentation about
+that feature should change too, and just as definitively. The docs have
+no obligation to keep descriptions of past behavior hanging around, even if
+attaching clauses like "Prior to version 5.10, [...]".
+
+Since Perl's core documentation is part of Perl's source distribution,
+it enjoys the same benefits of versioning and version-control as the
+source code of Perl itself. Take advantage of this, and update the text
+boldly when needed. Perl's history remains safe, even when you delete or
+replace outdated information from the current version's docs.
+
+Perl's docs can acknowledge or discuss former behavior when warranted,
+including notes that some feature appeared in the language as of some
+specific version number. Authors should consider applying principles
+similar to those for deprecated techniques, L<as described above|/Show
+the lesser ways when needed>: make the information present, but not
+prominent.
+
+Otherwise, keep the past in the past. A manual uncluttered with
+outdated instruction stays more succinct and relevant.
+
+=head3 Describe the uncertain future with care
+
+Perl features marked as "experimental"--those that generate warnings
+when used in code not invoking the L<C<experimental>|experimental>
+pragma--deserve documentation, but only in certain contexts, and even
+then with caveats. These features represent possible new directions for
+Perl, but they have unstable interfaces and uncertain future presence.
+
+The documentation should take both implications of "experimental"
+literally. It should not discourage these features' use by programmers
+who wish to try out new features in projects that can risk their
+inherent instability; this experimentation can help Perl grow and
+improve. By the same token, the docs should downplay these features' use
+in just about every other context.
+
+Introductory or overview material should omit coverage of experimental
+features altogether.
+
+More thorough reference materials or explanatory articles can include
+experimental features, but needs to clearly mark them as such, and not
+treat them with the same prominence as Perl's stable features. Using
+unstable features seldom coincides with best practices, and
+documentation that L<puts best practices first|/Lead with common cases
+and best practices> should reflect this.
+
+=head2 The documentation speaks with one voice
+
+Even though it comes from many hands and minds, criss-crossing through
+the many years of Perl's lifetime, the language's documentation should
+speak with a single, consistent voice. With few exceptions, the docs
+should avoid explicit first-person-singular statements, or similar
+self-reference to any individual's contributor's philosophies or
+experiences.
+
+Perl did begin life as a deeply personal expression by a single
+individual, and this famously carried through the first revisions of its
+documentation as well. Today, Perl's community understands that the
+language's continued development and support comes from many people
+working in concert, rather than any one person's vision or effort. Its
+documentation should not pretend otherwise.
+
+The documentation should, however, carry forward the best tradition that
+Larry Wall set forth in the language's earliest days: Write both
+economically and with a humble, subtle wit, resulting in a technical
+manual that mixes concision with a friendly approachability. It avoids
+the dryness that one might expect from technical documentation, while
+not leaning so hard into overt comedy as to distract and confuse from
+the nonetheless-technical topics at hand.
+
+Like the best written works, Perl's documentation has a soul. Get
+familiar with it as a reader to internalize its voice, and then find
+your own way to express it in your own contributions. Writing clearly,
+succinctly, and with knowledge of your audience's expectations will get
+you most of the way there, in the meantime.
+
+Every line in the docs--whether English sentence or Perl
+statement--should serve the purpose of bringing understanding to the
+reader. Should a sentence exist mainly to make a wry joke that doesn't
+further the reader's knowledge of Perl, set it aside, and consider
+recasting it into a personal blog post or other article instead.
+
+Write with a light heart, and a miserly hand. 
+
+=head1 INDEX OF PREFERRED TERMS
+
+L<As noted above|/Choice of underlying style guide: CMOS>, this guide
+"inherits" all the preferred terms listed in the Chicago Manual of
+Style, 17th edition, and adds the following terms of particular interest
+to Perl documentation.
+
+=over
+
+=item built-in function
+
+Not "builtin".
+
+=item Darwin
+
+See L<macOS|/macOS>.
+
+=item macOS
+
+Use this term for Apple's operating system instead of "Mac OS X" or
+variants thereof.
+
+This term is also preferable to "Darwin", unless one needs to refer
+to macOS's Unix layer specifically.
+
+=item man page
+
+One unit of Unix-style documentation. Not "manpage". Preferable to "manual page".
+
+=item Perl; perl
+
+The name of the programming language is Perl, with a leading capital
+"P", and the remainder in lowercase. (Never "PERL".)
+
+The interpreter program that reads and executes Perl code is named
+"C<perl>", in lowercase and in monospace (as with any other command
+name).
+
+Generally, unless you are specifically writing about the
+command-line C<perl> progam (as, for example, L<C<perlrun>|perlrun>
+does), use "Perl" instead.
+
+=item Perl 5
+
+Documentation need not follow Perl's name with a "5", or any other
+number, except during discussions of Perl's history, future plans,
+or explicit comparisons between major Perl versions.
+
+Before 2019, specifying "Perl 5" was sometimes needed to distinguish
+the language from Perl 6. With the latter's renaming to "Raku", this
+practice became unnecessary.
+
+=item Perl 6
+
+See L<Raku|/Raku>.
+
+=item Perl 5 Porters, the; porters, the; p5p
+
+The full name of the team responsible for Perl's ongoing maintenance
+and development is "the Perl 5 Porters", and this sobriquet should
+be spelled out in the first mention within any one document. It may
+thereafter call the team "the porters" or "p5p".
+
+Not "Perl5 Porters".
+
+=item program
+
+The most general descriptor for a stand-alone work made out of
+executable Perl code. Synonymous with, and preferable to, "script".
+
+=item Raku
+
+Perl's "sister language", whose homepage is L<https://raku.org>.
+
+Previously known as "Perl 6". In 2019, its design team renamed the
+language to better reflect its identity as a project independent from
+Perl. As such, Perl's documentation should always refer to this language
+as "Raku" and not "Perl 6".
+
+=item script
+
+See L<program|/program>.
+
+=item semicolon
+
+Perl code's frequently overlooked punctuation mark. Not "semi-colon".
+
+=item Unix
+
+Not "UNIX", "*nix", or "Un*x". Applicable to both the original operating
+system from the 1970s as well as all its conceptual descendants. You may
+simply write "Unix" and not "a Unix-like operating system" when
+referring to a Unix-like operating system.
+
+=back
+
+=head1 SEE ALSO
+
+=over
+
+=item *
+
+L<perlpod|perlpod>
+
+=item *
+
+L<perlpodstyle|perlpodstyle>
+
+=back
+
+=head1 AUTHOR
+
+This guide was initially drafted by Jason McIntosh
+(jmac@jmac.org), under a grant from The Perl Foundation.
+
+=for comment Additional contributors can get listed here (and this
+comment deleted), when there are some.
index d509eee..de24eef 100644 (file)
@@ -4326,9 +4326,8 @@ X<msgsnd>
 
 Calls the System V IPC function msgsnd to send the message MSG to the
 message queue ID.  MSG must begin with the native long integer message
-type, be followed by the length of the actual message, and then finally
-the message itself.  This kind of packing can be achieved with
-C<pack("l! a*", $type, $message)>.  Returns true if successful,
+type, followed by the message itself.  This kind of packing can be achieved
+with C<pack("l! a*", $type, $message)>.  Returns true if successful,
 false on error.  See also L<perlipc/"SysV IPC"> and the documentation
 for L<C<IPC::SysV>|IPC::SysV> and L<C<IPC::Msg>|IPC::Msg>.
 
@@ -4433,7 +4432,10 @@ X<oct> X<octal> X<hex> X<hexadecimal> X<binary> X<bin>
 =for Pod::Functions convert a string to an octal number
 
 Interprets EXPR as an octal string and returns the corresponding
-value.  (If EXPR happens to start off with C<0x> or C<x>, interprets it as a
+value.  An octal string consists of octal digits and, as of Perl 5.33.5,
+an optional C<0o> or C<o> prefix.  Each octal digit may be preceded by
+a single underscore, which will be ignored.
+(If EXPR happens to start off with C<0x> or C<x>, interprets it as a
 hex string.  If EXPR starts off with C<0b> or C<b>, it is interpreted as a
 binary string.  Leading whitespace is ignored in all three cases.)
 The following will handle decimal, binary, octal, and hex in standard
@@ -6150,6 +6152,18 @@ Will both leave the sentence as is.
 Normally, when accepting literal string input from the user,
 L<C<quotemeta>|/quotemeta EXPR> or C<\Q> must be used.
 
+Beware that if you put literal backslashes (those not inside
+interpolated variables) between C<\Q> and C<\E>, double-quotish
+backslash interpolation may lead to confusing results.  If you
+I<need> to use literal backslashes within C<\Q...\E>,
+consult L<perlop/"Gory details of parsing quoted constructs">.
+
+Because the result of S<C<"\Q I<STRING> \E">> has all metacharacters
+quoted, there is no way to insert a literal C<$> or C<@> inside a
+C<\Q\E> pair.  If protected by C<\>, C<$> will be quoted to become
+C<"\\\$">; if not, it is interpreted as the start of an interpolated
+scalar.
+
 In Perl v5.14, all non-ASCII characters are quoted in non-UTF-8-encoded
 strings, but not quoted in UTF-8 strings.
 
@@ -8223,6 +8237,11 @@ as supported by the compiler used to build Perl:
    z           interpret integer as C types "size_t" or
                "ssize_t" on Perl 5.14 or later
 
+Note that, in general, using the C<l> modifier (for example, when writing
+C<"%ld"> or C<"%lu"> instead of C<"%d"> and C<"%u">) is unnecessary
+when used from Perl code.  Moreover, it may be harmful, for example on
+Windows 64-bit where a long is 32-bits.
+
 As of 5.14, none of these raises an exception if they are not supported on
 your platform.  However, if warnings are enabled, a warning of the
 L<C<printf>|warnings> warning class is issued on an unsupported
index 1575619..965ca72 100644 (file)
@@ -1023,6 +1023,63 @@ as any other SV.
 
 For more information on references and blessings, consult L<perlref>.
 
+=head2 I/O Handles
+
+Like AVs and HVs, IO objects are another type of non-scalar SV which
+may contain input and output L<PerlIO|perlapio> objects or a C<DIR *>
+from opendir().
+
+You can create a new IO object:
+
+    IO*  newIO();
+
+Unlike other SVs, a new IO object is automatically blessed into the
+L<IO::File> class.
+
+The IO object contains an input and output PerlIO handle:
+
+  PerlIO *IoIFP(IO *io);
+  PerlIO *IoOFP(IO *io);
+
+Typically if the IO object has been opened on a file, the input handle
+is always present, but the output handle is only present if the file
+is open for output.  For a file, if both are present they will be the
+same PerlIO object.
+
+Distinct input and output PerlIO objects are created for sockets and
+character devices.
+
+The IO object also contains other data associated with Perl I/O
+handles:
+
+  IV IoLINES(io);                /* $. */
+  IV IoPAGE(io);                 /* $% */
+  IV IoPAGE_LEN(io);             /* $= */
+  IV IoLINES_LEFT(io);           /* $- */
+  char *IoTOP_NAME(io);          /* $^ */
+  GV *IoTOP_GV(io);              /* $^ */
+  char *IoFMT_NAME(io);          /* $~ */
+  GV *IoFMT_GV(io);              /* $~ */
+  char *IoBOTTOM_NAME(io);
+  GV *IoBOTTOM_GV(io);
+  char IoTYPE(io);
+  U8 IoFLAGS(io);
+
+Most of these are involved with L<formats|perlform>.
+
+IoFLAGs() may contain a combination of flags, the most interesting of
+which are C<IOf_FLUSH> (C<$|>) for autoflush and C<IOf_UNTAINT>,
+settable with L<< IO::Handle's untaint() method|IO::Handle/"$io->untaint" >>.
+
+The IO object may also contains a directory handle:
+
+  DIR *IoDIRP(io);
+
+suitable for use with PerlDir_read() etc.
+
+All of these accessors macros are lvalues, there are no distinct
+C<_set()> macros to modify the members of the IO object.
+
 =head2 Double-Typed SVs
 
 Scalar variables normally contain only one type of value, an integer,
index 1f66863..9d5b45a 100644 (file)
@@ -910,9 +910,10 @@ Sets PERL_SKIP_TTY_TEST to true before running normal test.
 =head2 Parallel tests
 
 The core distribution can now run its regression tests in parallel on
-Unix-like platforms.  Instead of running C<make test>, set C<TEST_JOBS>
-in your environment to the number of tests to run in parallel, and run
-C<make test_harness>.  On a Bourne-like shell, this can be done as
+Unix-like and Windows platforms.  On Unix, instead of running C<make
+test>, set C<TEST_JOBS> in your environment to the number of tests to
+run in parallel, and run C<make test_harness>.  On a Bourne-like shell,
+this can be done as
 
     TEST_JOBS=3 make test_harness  # Run 3 tests in parallel
 
@@ -921,9 +922,23 @@ because L<TAP::Harness> needs to be able to schedule individual
 non-conflicting test scripts itself, and there is no standard interface
 to C<make> utilities to interact with their job schedulers.
 
-Note that currently some test scripts may fail when run in parallel
-(most notably F<dist/IO/t/io_dir.t>).  If necessary, run just the
-failing scripts again sequentially and see if the failures go away.
+Tests are normally run in a logical order, with the sanity tests first,
+then the main tests of the Perl core functionality, then the tests for
+the non-core modules.  On many-core systems, this may not use the
+hardware as effectively as possible.  By also specifying
+
+ TEST_JOBS=19 PERL_TEST_HARNESS_ASAP=1 make -j19 test_harness
+
+you signal that you want the tests to finish in wall-clock time as short
+as possible.  After the sanity tests are completed, this causes the
+remaining ones to be packed into the available cores as tightly as
+we know how.  This has its greatest effect on slower, many-core systems.
+Throughput was sped up by 20% on an outmoded 24-core system; less on
+more recent faster ones with fewer cores.
+
+Note that the command line above added a C<-j> parameter to make, so as
+to cause parallel compilation.  This may or may not work on your
+platform.
 
 =head2 Running tests by hand
 
index 3bf6602..5b7c2e1 100644 (file)
@@ -700,6 +700,7 @@ the strings?).
  Sawyer X  5.33.2       2020-Sep-20
  Steve     5.33.3       2020-Oct-20
  Tom H     5.33.4       2020-Nov-20
+ Max M     5.33.5       2020-Dec-20
 
 =head2 SELECTED RELEASE SIZES
 
index f2c5206..8354fe2 100644 (file)
@@ -543,7 +543,7 @@ C<-Accflags='-DUSE_THREAD_SAFE_LOCALE'> to F<Configure>.
 
 The initial program is started up using the locale specified from the
 environment, as currently, described in L</ENVIRONMENT>.   All newly
-created threads start with C<LC_ALL> set to C<"C">>.  Each thread may
+created threads start with C<LC_ALL> set to C<"C">.  Each thread may
 use C<POSIX::setlocale()> to query or switch its locale at any time,
 without affecting any other thread.  All locale-dependent operations
 automatically use their thread's locale.
index a980980..63869d5 100644 (file)
@@ -1526,6 +1526,9 @@ C<-x>, C<-o>.
 (Win32, VMS, S<RISC OS>)
 C<-g>, C<-k>, C<-l>, C<-u>, C<-A> are not particularly meaningful.
 
+(Win32)
+C<-l> returns true for both symlinks and directory junctions.
+
 (VMS, S<RISC OS>)
 C<-p> is not particularly meaningful.
 
@@ -1571,6 +1574,12 @@ filehandle may be closed, or pointer may be in a different position.
 The value returned by L<C<tell>|perlfunc/tell FILEHANDLE> may be affected
 after the call, and the filehandle may be flushed.
 
+=item chdir
+
+(Win32)
+The current directory reported by the system may include any symbolic
+links specified to chdir().
+
 =item chmod
 
 (Win32)
@@ -1946,7 +1955,7 @@ but usually by no more than an hour.
 Not implemented.
 
 (Win32)
-Return values (especially for device and inode) may be bogus.
+Treats directory junctions as symlinks.
 
 =item msgctl
 
@@ -1976,9 +1985,13 @@ implications for your code.
 
 =item readlink
 
-(Win32, VMS, S<RISC OS>)
+(VMS, S<RISC OS>)
 Not implemented.
 
+(Win32)
+readlink() on a directory junction returns the object name, not a
+simple path.
+
 =item rename
 
 (Win32)
@@ -2074,9 +2087,6 @@ C<ctime> not supported on UFS.
 (Win32)
 C<ctime> is creation time instead of inode change time.
 
-(Win32)
-C<dev> and C<ino> are not meaningful.
-
 (VMS)
 C<dev> and C<ino> are not necessarily reliable.
 
@@ -2092,17 +2102,18 @@ meaningful and will differ between stat calls on the same file.
 Some versions of cygwin when doing a C<stat("foo")> and not finding it
 may then attempt to C<stat("foo.exe")>.
 
-(Win32)
-C<stat> needs to open the file to determine the link count
-and update attributes that may have been changed through hard links.
-Setting L<C<${^WIN32_SLOPPY_STAT}>|perlvar/${^WIN32_SLOPPY_STAT}> to a
-true value speeds up C<stat> by not performing this operation.
-
 =item symlink
 
-(Win32, S<RISC OS>)
+(S<RISC OS>)
 Not implemented.
 
+(Win32)
+Requires either elevated permissions or developer mode and a
+sufficiently recent version of Windows 10.  Since Windows needs to
+know whether the target is a directory or not when creating the link
+the target Perl will only create the link as a directory link when the
+target exists and is a directory.
+
 (VMS)
 Implemented on 64 bit VMS 8.3.  VMS requires the symbolic link to be in Unix
 syntax if it is intended to resolve to a valid path.
index 629a273..2c18b09 100644 (file)
@@ -1032,6 +1032,8 @@ also accepted.
     }
     # %hash is back to its original state
 
+This construct is supported since Perl v5.12.
+
 =head2 Lvalue subroutines
 X<lvalue> X<subroutine, lvalue>
 
index 6f87059..cea7a6f 100644 (file)
@@ -811,6 +811,11 @@ thing, but we'll have to go through the LIST field indirectly.
        return each $self->{LIST}->%*
     }
 
+If the object underlying your tied hash isn't a real hash and you don't have
+C<each> available, then you should return C<undef> or the empty list once you've
+reached the end of your list of keys. See L<C<each's own documentation>|perlfunc/each>
+for more details.
+
 =item SCALAR this
 X<SCALAR>
 
index 33157b8..2c295dd 100644 (file)
@@ -750,18 +750,9 @@ Mnemonic: use ^V for a version object.
 =item ${^WIN32_SLOPPY_STAT}
 X<${^WIN32_SLOPPY_STAT}> X<sitecustomize> X<sitecustomize.pl>
 
-If this variable is set to a true value, then C<stat()> on Windows will
-not try to open the file.  This means that the link count cannot be
-determined and file attributes may be out of date if additional
-hardlinks to the file exist.  On the other hand, not opening the file
-is considerably faster, especially for files on network drives.
+This variable no longer has any function.
 
-This variable could be set in the F<sitecustomize.pl> file to
-configure the local Perl installation to use "sloppy" C<stat()> by
-default.  See the documentation for B<-f> in L<perlrun|perlrun/-f>
-for more information about site customization.
-
-This variable was added in Perl v5.10.0.
+This variable was added in Perl v5.10.0 and removed in Perl v5.34.0.
 
 =item $EXECUTABLE_NAME
 
@@ -1515,7 +1506,7 @@ be better for something. :-)
 
 Setting C<$/> to an empty string -- the so-called I<paragraph mode> -- merits
 special attention.  When C<$/> is set to C<""> and the entire file is read in
-with that setting, any sequence of consecutive newlines C<"\n\n"> at the
+with that setting, any sequence of one or more consecutive newlines at the
 beginning of the file is discarded.  With the exception of the final record in
 the file, each sequence of characters ending in two or more newlines is
 treated as one record and is read in to end in exactly two newlines.  If the
diff --git a/pp.c b/pp.c
index 5b5e163..5e17063 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -3099,8 +3099,12 @@ PP(pp_oct)
         flags |= PERL_SCAN_DISALLOW_PREFIX;
         result_uv = grok_bin (tmps, &len, &flags, &result_nv);
     }
-    else
+    else {
+        if (isALPHA_FOLD_EQ(*tmps, 'o')) {
+            tmps++, len--;
+        }
         result_uv = grok_oct (tmps, &len, &flags, &result_nv);
+    }
 
     if (flags & PERL_SCAN_GREATER_THAN_UV_MAX) {
         SETn(result_nv);
index 5cb5a10..ed451c0 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1228,7 +1228,7 @@ PP(pp_flop)
            if ((SvOK(left) && !SvIOK(left) && SvNV_nomg(left) < IV_MIN) ||
                (SvOK(right) && (SvIOK(right)
                                 ? SvIsUV(right) && SvUV(right) > IV_MAX
-                                : SvNV_nomg(right) > IV_MAX)))
+                                : SvNV_nomg(right) > (NV) IV_MAX)))
                DIE(aTHX_ "Range iterator outside integer range");
            i = SvIV_nomg(left);
            j = SvIV_nomg(right);
index 5c9f768..8a6445e 100644 (file)
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -3774,13 +3774,13 @@ PP(pp_link)
 #  if defined(HAS_LINK) && defined(HAS_SYMLINK)
            /* Both present - need to choose which.  */
            (op_type == OP_LINK) ?
-           PerlLIO_link(tmps, tmps2) : symlink(tmps, tmps2);
+           PerlLIO_link(tmps, tmps2) : PerlLIO_symlink(tmps, tmps2);
 #  elif defined(HAS_LINK)
     /* Only have link, so calls to pp_symlink will have DIE()d above.  */
        PerlLIO_link(tmps, tmps2);
 #  elif defined(HAS_SYMLINK)
     /* Only have symlink, so calls to pp_link will have DIE()d above.  */
-       symlink(tmps, tmps2);
+       PerlLIO_symlink(tmps, tmps2);
 #  endif
     }
 
@@ -3811,7 +3811,7 @@ PP(pp_readlink)
     tmps = POPpconstx;
     /* NOTE: if the length returned by readlink() is sizeof(buf) - 1,
      * it is impossible to know whether the result was truncated. */
-    len = readlink(tmps, buf, sizeof(buf) - 1);
+    len = PerlLIO_readlink(tmps, buf, sizeof(buf) - 1);
     if (len < 0)
        RETPUSHUNDEF;
     buf[len] = '\0';
diff --git a/proto.h b/proto.h
index 5e1be02..46e69cc 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -117,6 +117,24 @@ PERL_STATIC_INLINE void    Perl_SvREFCNT_inc_void(SV *sv);
 #define PERL_ARGS_ASSERT_SVREFCNT_INC_VOID
 #endif
 #ifndef PERL_NO_INLINE_FUNCTIONS
+PERL_STATIC_INLINE bool        Perl_SvTRUE(pTHX_ SV *sv);
+#define PERL_ARGS_ASSERT_SVTRUE
+#endif
+#ifndef PERL_NO_INLINE_FUNCTIONS
+PERL_STATIC_INLINE bool        Perl_SvTRUE_NN(pTHX_ SV *sv);
+#define PERL_ARGS_ASSERT_SVTRUE_NN     \
+       assert(sv)
+#endif
+#ifndef PERL_NO_INLINE_FUNCTIONS
+PERL_STATIC_INLINE bool        Perl_SvTRUE_common(pTHX_ SV *sv, const bool sv_2bool_is_fallback);
+#define PERL_ARGS_ASSERT_SVTRUE_COMMON \
+       assert(sv)
+#endif
+#ifndef PERL_NO_INLINE_FUNCTIONS
+PERL_STATIC_INLINE bool        Perl_SvTRUE_nomg(pTHX_ SV *sv);
+#define PERL_ARGS_ASSERT_SVTRUE_NOMG
+#endif
+#ifndef PERL_NO_INLINE_FUNCTIONS
 PERL_STATIC_INLINE I32 Perl_TOPMARK(pTHX);
 #define PERL_ARGS_ASSERT_TOPMARK
 #endif
@@ -2138,10 +2156,8 @@ PERL_CALLCONV I32        Perl_my_fflush_all(pTHX);
 #define PERL_ARGS_ASSERT_MY_FFLUSH_ALL
 PERL_CALLCONV Pid_t    Perl_my_fork(void);
 #define PERL_ARGS_ASSERT_MY_FORK
-#ifndef NO_MATHOMS
-PERL_CALLCONV I32      Perl_my_lstat(pTHX);
+/* PERL_CALLCONV I32   my_lstat(pTHX); */
 #define PERL_ARGS_ASSERT_MY_LSTAT
-#endif
 PERL_CALLCONV I32      Perl_my_lstat_flags(pTHX_ const U32 flags);
 #define PERL_ARGS_ASSERT_MY_LSTAT_FLAGS
 PERL_CALLCONV int      Perl_my_mkostemp_cloexec(char *templte, int flags)
@@ -2166,10 +2182,8 @@ PERL_CALLCONV int        Perl_my_snprintf(char *buffer, const Size_t len, const char *f
 
 PERL_CALLCONV int      Perl_my_socketpair(int family, int type, int protocol, int fd[2]);
 #define PERL_ARGS_ASSERT_MY_SOCKETPAIR
-#ifndef NO_MATHOMS
-PERL_CALLCONV I32      Perl_my_stat(pTHX);
+/* PERL_CALLCONV I32   my_stat(pTHX); */
 #define PERL_ARGS_ASSERT_MY_STAT
-#endif
 PERL_CALLCONV I32      Perl_my_stat_flags(pTHX_ const U32 flags);
 #define PERL_ARGS_ASSERT_MY_STAT_FLAGS
 PERL_CALLCONV char*    Perl_my_strerror(pTHX_ const int errnum);
@@ -2625,6 +2639,7 @@ PERL_CALLCONV void        Perl_pad_block_start(pTHX_ int full);
 #define PERL_ARGS_ASSERT_PAD_BLOCK_START
 #ifndef NO_MATHOMS
 PERL_CALLCONV HV*      Perl_pad_compname_type(pTHX_ const PADOFFSET po)
+                       __attribute__deprecated__
                        __attribute__warn_unused_result__;
 #define PERL_ARGS_ASSERT_PAD_COMPNAME_TYPE
 #endif
@@ -4482,6 +4497,10 @@ STATIC void      S_validate_suid(pTHX_ PerlIO *rsfp);
        assert(rsfp)
 #  endif
 #endif
+#if !defined(USE_ITHREADS)
+/* PERL_CALLCONV void  CopFILEGV_set(pTHX_ COP * c, GV * gv); */
+#define PERL_ARGS_ASSERT_COPFILEGV_SET
+#endif
 #if !defined(UV_IS_QUAD)
 #  if defined(PERL_IN_UTF8_C)
 STATIC int     S_is_utf8_cp_above_31_bits(const U8 * const s, const U8 * const e, const bool consider_overlongs)
index d6688b2..9aa98ed 100644 (file)
 /*** GENERATED CODE ***/
 #define is_LNBREAK_safe(s,e,is_utf8)                                        \
 ( ((e)-(s) > 2) ?                                                           \
-    ( ( inRANGE(((const U8*)s)[0], '\n', '\f') ) ? 1                        \
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[0], '\n', '\f') ) ? 1            \
     : ( '\r' == ((const U8*)s)[0] ) ?                                       \
        ( ( '\n' == ((const U8*)s)[1] ) ? 2 : 1 )                           \
     : ( is_utf8 ) ?                                                         \
        ( ( 0xC2 == ((const U8*)s)[0] ) ?                                   \
            ( ( 0x85 == ((const U8*)s)[1] ) ? 2 : 0 )                       \
-       : ( ( ( 0xE2 == ((const U8*)s)[0] ) && ( 0x80 == ((const U8*)s)[1] ) ) && ( inRANGE(((const U8*)s)[2], 0xA8, 0xA9) ) ) ? 3 : 0 )\
+       : ( ( ( 0xE2 == ((const U8*)s)[0] ) && ( 0x80 == ((const U8*)s)[1] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0xA8, 0xA9) ) ) ? 3 : 0 )\
     : ( 0x85 == ((const U8*)s)[0] ) )                                       \
 : ((e)-(s) > 1) ?                                                           \
-    ( ( inRANGE(((const U8*)s)[0], '\n', '\f') ) ? 1                        \
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[0], '\n', '\f') ) ? 1            \
     : ( '\r' == ((const U8*)s)[0] ) ?                                       \
        ( ( '\n' == ((const U8*)s)[1] ) ? 2 : 1 )                           \
     : ( is_utf8 ) ?                                                         \
        ( ( ( 0xC2 == ((const U8*)s)[0] ) && ( 0x85 == ((const U8*)s)[1] ) ) ? 2 : 0 )\
     : ( 0x85 == ((const U8*)s)[0] ) )                                       \
 : ((e)-(s) > 0) ?                                                           \
-    ( ( inRANGE(((const U8*)s)[0], '\n', '\r') ) ? 1                        \
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[0], '\n', '\r') ) ? 1            \
     : ( !( is_utf8 ) ) ?                                                    \
        ( 0x85 == ((const U8*)s)[0] )                                       \
     : 0 )                                                                   \
 /*** GENERATED CODE ***/
 #define is_LNBREAK_utf8_safe(s,e)                                           \
 ( ((e)-(s) > 2) ?                                                           \
-    ( ( inRANGE(((const U8*)s)[0], '\n', '\f') ) ? 1                        \
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[0], '\n', '\f') ) ? 1            \
     : ( '\r' == ((const U8*)s)[0] ) ?                                       \
        ( ( '\n' == ((const U8*)s)[1] ) ? 2 : 1 )                           \
     : ( 0xC2 == ((const U8*)s)[0] ) ?                                       \
        ( ( 0x85 == ((const U8*)s)[1] ) ? 2 : 0 )                           \
-    : ( ( ( 0xE2 == ((const U8*)s)[0] ) && ( 0x80 == ((const U8*)s)[1] ) ) && ( inRANGE(((const U8*)s)[2], 0xA8, 0xA9) ) ) ? 3 : 0 )\
+    : ( ( ( 0xE2 == ((const U8*)s)[0] ) && ( 0x80 == ((const U8*)s)[1] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0xA8, 0xA9) ) ) ? 3 : 0 )\
 : ((e)-(s) > 1) ?                                                           \
-    ( ( inRANGE(((const U8*)s)[0], '\n', '\f') ) ? 1                        \
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[0], '\n', '\f') ) ? 1            \
     : ( '\r' == ((const U8*)s)[0] ) ?                                       \
        ( ( '\n' == ((const U8*)s)[1] ) ? 2 : 1 )                           \
     : ( ( 0xC2 == ((const U8*)s)[0] ) && ( 0x85 == ((const U8*)s)[1] ) ) ? 2 : 0 )\
 : ((e)-(s) > 0) ?                                                           \
-    ( inRANGE(((const U8*)s)[0], '\n', '\r') )                              \
+    ( inRANGE_helper_(U8, ((const U8*)s)[0], '\n', '\r') )                  \
 : 0 )
 
 /*** GENERATED CODE ***/
 #define is_LNBREAK_latin1_safe(s,e)                                         \
 ( ((e)-(s) > 1) ?                                                           \
-    ( ( inRANGE(((const U8*)s)[0], '\n', '\f') || 0x85 == ((const U8*)s)[0] ) ? 1\
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[0], '\n', '\f') || 0x85 == ((const U8*)s)[0] ) ? 1\
     : ( '\r' == ((const U8*)s)[0] ) ?                                       \
        ( ( '\n' == ((const U8*)s)[1] ) ? 2 : 1 )                           \
     : 0 )                                                                   \
 : ((e)-(s) > 0) ?                                                           \
-    ( inRANGE(((const U8*)s)[0], '\n', '\r') || 0x85 == ((const U8*)s)[0] ) \
+    ( inRANGE_helper_(U8, ((const U8*)s)[0], '\n', '\r') || 0x85 == ((const U8*)s)[0] )\
 : 0 )
 
 /*
     ( ( ( 0x9A == ((const U8*)s)[1] ) && ( 0x80 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 : ( 0xE2 == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x80 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x80, 0x8A) || 0xAF == ((const U8*)s)[2] ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x80, 0x8A) || 0xAF == ((const U8*)s)[2] ) ? 3 : 0 )\
     : ( ( 0x81 == ((const U8*)s)[1] ) && ( 0x9F == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 : ( ( ( 0xE3 == ((const U8*)s)[0] ) && ( 0x80 == ((const U8*)s)[1] ) ) && ( 0x80 == ((const U8*)s)[2] ) ) ? 3 : 0 )
 
 /*** GENERATED CODE ***/
 #define is_HORIZWS_cp_high(cp)                                              \
 ( 0x1680 == cp || ( 0x1680 < cp &&                                          \
-( inRANGE(cp, 0x2000, 0x200A) || ( 0x200A < cp &&                           \
+( inRANGE_helper_(UV, cp, 0x2000, 0x200A) || ( 0x200A < cp &&               \
 ( 0x202F == cp || ( 0x202F < cp &&                                          \
 ( 0x205F == cp || 0x3000 == cp ) ) ) ) ) ) )
 
 */
 /*** GENERATED CODE ***/
 #define is_VERTWS_high(s)                                                   \
-( ( ( ( 0xE2 == ((const U8*)s)[0] ) && ( 0x80 == ((const U8*)s)[1] ) ) && ( inRANGE(((const U8*)s)[2], 0xA8, 0xA9) ) ) ? 3 : 0 )
+( ( ( ( 0xE2 == ((const U8*)s)[0] ) && ( 0x80 == ((const U8*)s)[1] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0xA8, 0xA9) ) ) ? 3 : 0 )
 
 /*** GENERATED CODE ***/
 #define is_VERTWS_cp_high(cp)                                               \
-( 0x2028 == cp || 0x2029 == cp )
+( inRANGE_helper_(UV, cp, 0x2028, 0x2029) )
 
 /*
        XDIGIT: Hexadecimal digits
 #define is_XDIGIT_high(s)                                                   \
 ( ( 0xEF == ((const U8*)s)[0] ) ?                                           \
     ( ( 0xBC == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x90, 0x99) || inRANGE(((const U8*)s)[2], 0xA1, 0xA6) ) ? 3 : 0 )\
-    : ( ( 0xBD == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x81, 0x86) ) ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x90, 0x99) || inRANGE_helper_(U8, ((const U8*)s)[2], 0xA1, 0xA6) ) ? 3 : 0 )\
+    : ( ( 0xBD == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x81, 0x86) ) ) ? 3 : 0 )\
 : 0 )
 
 /*** GENERATED CODE ***/
 #define is_XDIGIT_cp_high(cp)                                               \
-( inRANGE(cp, 0xFF10, 0xFF19) || ( 0xFF19 < cp &&                           \
-( inRANGE(cp, 0xFF21, 0xFF26) || inRANGE(cp, 0xFF41, 0xFF46) ) ) )
+( inRANGE_helper_(UV, cp, 0xFF10, 0xFF19) || ( 0xFF19 < cp &&               \
+( inRANGE_helper_(UV, cp, 0xFF21, 0xFF26) || inRANGE_helper_(UV, cp, 0xFF41, 0xFF46) ) ) )
 
 /*
        XPERLSPACE: \p{XPerlSpace}
     ( ( ( 0x9A == ((const U8*)s)[1] ) && ( 0x80 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 : ( 0xE2 == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x80 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x80, 0x8A) || inRANGE(((const U8*)s)[2], 0xA8, 0xA9) || 0xAF == ((const U8*)s)[2] ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x80, 0x8A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0xA8, 0xA9) || 0xAF == ((const U8*)s)[2] ) ? 3 : 0 )\
     : ( ( 0x81 == ((const U8*)s)[1] ) && ( 0x9F == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 : ( ( ( 0xE3 == ((const U8*)s)[0] ) && ( 0x80 == ((const U8*)s)[1] ) ) && ( 0x80 == ((const U8*)s)[2] ) ) ? 3 : 0 )
 
 /*** GENERATED CODE ***/
 #define is_XPERLSPACE_cp_high(cp)                                           \
 ( 0x1680 == cp || ( 0x1680 < cp &&                                          \
-( inRANGE(cp, 0x2000, 0x200A) || ( 0x200A < cp &&                           \
-( 0x2028 == cp || ( 0x2028 < cp &&                                          \
-( 0x2029 == cp || ( 0x2029 < cp &&                                          \
+( inRANGE_helper_(UV, cp, 0x2000, 0x200A) || ( 0x200A < cp &&               \
+( inRANGE_helper_(UV, cp, 0x2028, 0x2029) || ( 0x2029 < cp &&               \
 ( 0x202F == cp || ( 0x202F < cp &&                                          \
-( 0x205F == cp || 0x3000 == cp ) ) ) ) ) ) ) ) ) ) )
+( 0x205F == cp || 0x3000 == cp ) ) ) ) ) ) ) ) )
 
 /*
        NONCHAR: Non character code points
 #define is_NONCHAR_utf8_safe(s,e)                                           \
 ( ( ( LIKELY((e) > (s)) ) && ( LIKELY(((e) - (s)) >= UTF8SKIP(s)) ) ) ? ( ( 0xEF == ((const U8*)s)[0] ) ?\
            ( ( 0xB7 == ((const U8*)s)[1] ) ?                               \
-               ( ( inRANGE(((const U8*)s)[2], 0x90, 0xAF) ) ? 3 : 0 )      \
-           : ( ( 0xBF == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0xBE, 0xBF) ) ) ? 3 : 0 )\
+               ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x90, 0xAF) ) ? 3 : 0 )\
+           : ( ( 0xBF == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0xBE, 0xBF) ) ) ? 3 : 0 )\
        : ( 0xF0 == ((const U8*)s)[0] ) ?                                   \
-           ( ( ( ( ((const U8*)s)[1] == 0x9F || ( ( ((const U8*)s)[1] & 0xEF ) == 0xAF ) ) && ( 0xBF == ((const U8*)s)[2] ) ) && ( inRANGE(((const U8*)s)[3], 0xBE, 0xBF) ) ) ? 4 : 0 )\
-       : ( inRANGE(((const U8*)s)[0], 0xF1, 0xF3) ) ?                      \
-           ( ( ( ( ( ((const U8*)s)[1] & 0xCF ) == 0x8F ) && ( 0xBF == ((const U8*)s)[2] ) ) && ( inRANGE(((const U8*)s)[3], 0xBE, 0xBF) ) ) ? 4 : 0 )\
-       : ( ( ( ( 0xF4 == ((const U8*)s)[0] ) && ( 0x8F == ((const U8*)s)[1] ) ) && ( 0xBF == ((const U8*)s)[2] ) ) && ( inRANGE(((const U8*)s)[3], 0xBE, 0xBF) ) ) ? 4 : 0 ) : 0 )
+           ( ( ( ( ((const U8*)s)[1] == 0x9F || ( ( ((const U8*)s)[1] & 0xEF ) == 0xAF ) ) && ( 0xBF == ((const U8*)s)[2] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0xBE, 0xBF) ) ) ? 4 : 0 )\
+       : ( inRANGE_helper_(U8, ((const U8*)s)[0], 0xF1, 0xF3) ) ?          \
+           ( ( ( ( ( ((const U8*)s)[1] & 0xCF ) == 0x8F ) && ( 0xBF == ((const U8*)s)[2] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0xBE, 0xBF) ) ) ? 4 : 0 )\
+       : ( ( ( ( 0xF4 == ((const U8*)s)[0] ) && ( 0x8F == ((const U8*)s)[1] ) ) && ( 0xBF == ((const U8*)s)[2] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0xBE, 0xBF) ) ) ? 4 : 0 ) : 0 )
 
 /*
        SURROGATE: Surrogate code points
 */
 /*** GENERATED CODE ***/
 #define is_SURROGATE_utf8_safe(s,e)                                         \
-( ( ( ( ( ((e) - (s)) >= 3 ) && ( 0xED == ((const U8*)s)[0] ) ) && ( inRANGE(((const U8*)s)[1], 0xA0, 0xBF) ) ) && ( inRANGE(((const U8*)s)[2], 0x80, 0xBF) ) ) ? 3 : 0 )
+( ( ( ( ( ((e) - (s)) >= 3 ) && ( 0xED == ((const U8*)s)[0] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[1], 0xA0, 0xBF) ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x80, 0xBF) ) ) ? 3 : 0 )
 
 /*
        QUOTEMETA: Meta-characters that \Q should quote
     ( ( 0x9C == ((const U8*)s)[1] ) ? 2 : 0 )                               \
 : ( 0xE1 == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x85 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x9F, 0xA0) ) ? 3 : 0 )              \
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x9F, 0xA0) ) ? 3 : 0 )  \
     : ( 0x9A == ((const U8*)s)[1] ) ?                                       \
        ( ( 0x80 == ((const U8*)s)[2] ) ? 3 : 0 )                           \
     : ( 0x9E == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0xB4, 0xB5) ) ? 3 : 0 )              \
-    : ( ( 0xA0 == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x8B, 0x8E) ) ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0xB4, 0xB5) ) ? 3 : 0 )  \
+    : ( ( 0xA0 == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x8B, 0x8E) ) ) ? 3 : 0 )\
 : ( 0xE2 == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x80 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x80, 0xBE) ) ? 3 : 0 )              \
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x80, 0xBE) ) ? 3 : 0 )  \
     : ( 0x81 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x81, 0x93) || inRANGE(((const U8*)s)[2], 0x95, 0xAF) ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x81, 0x93) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x95, 0xAF) ) ? 3 : 0 )\
     : ( 0x86 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x90, 0xBF) ) ? 3 : 0 )              \
-    : ( inRANGE(((const U8*)s)[1], 0x87, 0x90) || inRANGE(((const U8*)s)[1], 0x94, 0x9C) || inRANGE(((const U8*)s)[1], 0x9F, 0xAF) || inRANGE(((const U8*)s)[1], 0xB8, 0xB9) ) ?\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x90, 0xBF) ) ? 3 : 0 )  \
+    : ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x87, 0x90) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x94, 0x9C) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x9F, 0xAF) || inRANGE_helper_(U8, ((const U8*)s)[1], 0xB8, 0xB9) ) ?\
        3                                                                   \
     : ( 0x91 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x80, 0x9F) ) ? 3 : 0 )              \
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x80, 0x9F) ) ? 3 : 0 )  \
     : ( 0x9D == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x80, 0xB5) ) ? 3 : 0 )              \
-    : ( ( 0x9E == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x94, 0xBF) ) ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x80, 0xB5) ) ? 3 : 0 )  \
+    : ( ( 0x9E == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x94, 0xBF) ) ) ? 3 : 0 )\
 : ( 0xE3 == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x80 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x80, 0x83) || inRANGE(((const U8*)s)[2], 0x88, 0xA0) || 0xB0 == ((const U8*)s)[2] ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x80, 0x83) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x88, 0xA0) || 0xB0 == ((const U8*)s)[2] ) ? 3 : 0 )\
     : ( ( 0x85 == ((const U8*)s)[1] ) && ( 0xA4 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 : ( 0xEF == ((const U8*)s)[0] ) ?                                           \
     ( ( 0xB4 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0xBE, 0xBF) ) ? 3 : 0 )              \
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0xBE, 0xBF) ) ? 3 : 0 )  \
     : ( 0xB8 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x80, 0x8F) ) ? 3 : 0 )              \
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x80, 0x8F) ) ? 3 : 0 )  \
     : ( 0xB9 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x85, 0x86) ) ? 3 : 0 )              \
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x85, 0x86) ) ? 3 : 0 )  \
     : ( 0xBB == ((const U8*)s)[1] ) ?                                       \
        ( ( 0xBF == ((const U8*)s)[2] ) ? 3 : 0 )                           \
     : ( 0xBE == ((const U8*)s)[1] ) ?                                       \
        ( ( 0xA0 == ((const U8*)s)[2] ) ? 3 : 0 )                           \
-    : ( ( 0xBF == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0xB0, 0xB8) ) ) ? 3 : 0 )\
+    : ( ( 0xBF == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0xB0, 0xB8) ) ) ? 3 : 0 )\
 : ( 0xF0 == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x9B == ((const U8*)s)[1] ) ?                                       \
-       ( ( ( 0xB2 == ((const U8*)s)[2] ) && ( inRANGE(((const U8*)s)[3], 0xA0, 0xA3) ) ) ? 4 : 0 )\
-    : ( ( ( 0x9D == ((const U8*)s)[1] ) && ( 0x85 == ((const U8*)s)[2] ) ) && ( inRANGE(((const U8*)s)[3], 0xB3, 0xBA) ) ) ? 4 : 0 )\
+       ( ( ( 0xB2 == ((const U8*)s)[2] ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0xA0, 0xA3) ) ) ? 4 : 0 )\
+    : ( ( ( 0x9D == ((const U8*)s)[1] ) && ( 0x85 == ((const U8*)s)[2] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0xB3, 0xBA) ) ) ? 4 : 0 )\
 : ( ( 0xF3 == ((const U8*)s)[0] ) && ( 0xA0 == ((const U8*)s)[1] ) ) ? 4 : 0 )
 
 /*
        MULTI_CHAR_FOLD: multi-char strings that are folded to by a single character
 
-       &regcharclass_multi_char_folds::multi_char_folds('u', 'a')
+       %regcharclass_multi_char_folds::multi_char_folds('u', 'a')
 */
 /*** GENERATED CODE ***/
 #define is_MULTI_CHAR_FOLD_utf8_safe_part0(s,e)                             \
     : ( ( ((const U8*)s)[0] & 0xDF ) == 'J' ) ?                             \
        ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x8C == ((const U8*)s)[2] ) ) ? 3 : 0 )\
     : ( ( ((const U8*)s)[0] & 0xDF ) == 'S' ) ?                             \
-       ( ( inRANGE(((const U8*)s)[1], 'S', 'T') || inRANGE(((const U8*)s)[1], 's', 't') ) ? 2\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 'S', 'T') || inRANGE_helper_(U8, ((const U8*)s)[1], 's', 't') ) ? 2\
        : ( ( 0xC5 == ((const U8*)s)[1] ) && ( 0xBF == ((const U8*)s)[2] ) ) ? 3 : 0 )\
     : ( ( ((const U8*)s)[0] & 0xDF ) == 'T' ) ?                             \
        ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x88 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
        ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x8A == ((const U8*)s)[2] ) ) ? 3 : 0 )\
     : ( 0xC5 == ((const U8*)s)[0] ) ?                                       \
        ( ( 0xBF == ((const U8*)s)[1] ) ?                                   \
-           ( ( inRANGE(((const U8*)s)[2], 'S', 'T') || inRANGE(((const U8*)s)[2], 's', 't') ) ? 3\
+           ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 'S', 'T') || inRANGE_helper_(U8, ((const U8*)s)[2], 's', 't') ) ? 3\
            : ( ( 0xC5 == ((const U8*)s)[2] ) && ( 0xBF == ((const U8*)s)[3] ) ) ? 4 : 0 )\
        : 0 )                                                               \
     : ( 0xCA == ((const U8*)s)[0] ) ?                                       \
            ( ( 0xCC == ((const U8*)s)[2] ) ?                               \
                ( ( 0x88 == ((const U8*)s)[3] ) ?                           \
                    ( ( 0xCC == ((const U8*)s)[4] ) ?                       \
-                       ( ( inRANGE(((const U8*)s)[5], 0x80, 0x81) ) ? 6 : 0 )\
+                       ( ( inRANGE_helper_(U8, ((const U8*)s)[5], 0x80, 0x81) ) ? 6 : 0 )\
                    : ( ( 0xCD == ((const U8*)s)[4] ) && ( 0x82 == ((const U8*)s)[5] ) ) ? 6 : 0 )\
                : 0 )                                                       \
            : ( ( 0xCD == ((const U8*)s)[2] ) && ( 0x82 == ((const U8*)s)[3] ) ) ? 4 : 0 )\
            ( ( 0xCC == ((const U8*)s)[2] ) ?                               \
                ( ( 0x88 == ((const U8*)s)[3] ) ?                           \
                    ( ( 0xCC == ((const U8*)s)[4] ) ?                       \
-                       ( ( inRANGE(((const U8*)s)[5], 0x80, 0x81) ) ? 6 : 0 )\
+                       ( ( inRANGE_helper_(U8, ((const U8*)s)[5], 0x80, 0x81) ) ? 6 : 0 )\
                    : ( ( 0xCD == ((const U8*)s)[4] ) && ( 0x82 == ((const U8*)s)[5] ) ) ? 6 : 0 )\
                : ( 0x93 == ((const U8*)s)[3] ) ?                           \
                    ( ( 0xCC == ((const U8*)s)[4] ) ?                       \
-                       ( ( inRANGE(((const U8*)s)[5], 0x80, 0x81) ) ? 6 : 4 )\
+                       ( ( inRANGE_helper_(U8, ((const U8*)s)[5], 0x80, 0x81) ) ? 6 : 4 )\
                    : ( ( 0xCD == ((const U8*)s)[4] ) && ( 0x82 == ((const U8*)s)[5] ) ) ? 6 : 4 )\
                : 0 )                                                       \
            : ( ( 0xCD == ((const U8*)s)[2] ) && ( 0x82 == ((const U8*)s)[3] ) ) ? 4 : 0 )\
     : ( ( ((const U8*)s)[0] & 0xDF ) == 'J' ) ?                             \
        ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x8C == ((const U8*)s)[2] ) ) ? 3 : 0 )\
     : ( ( ((const U8*)s)[0] & 0xDF ) == 'S' ) ?                             \
-       ( ( inRANGE(((const U8*)s)[1], 'S', 'T') || inRANGE(((const U8*)s)[1], 's', 't') ) ? 2\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 'S', 'T') || inRANGE_helper_(U8, ((const U8*)s)[1], 's', 't') ) ? 2\
        : ( ( 0xC5 == ((const U8*)s)[1] ) && ( 0xBF == ((const U8*)s)[2] ) ) ? 3 : 0 )\
     : ( ( ((const U8*)s)[0] & 0xDF ) == 'T' ) ?                             \
        ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x88 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
        ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x8A == ((const U8*)s)[2] ) ) ? 3 : 0 )\
     : ( 0xC5 == ((const U8*)s)[0] ) ?                                       \
        ( ( 0xBF == ((const U8*)s)[1] ) ?                                   \
-           ( ( inRANGE(((const U8*)s)[2], 'S', 'T') || inRANGE(((const U8*)s)[2], 's', 't') ) ? 3\
+           ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 'S', 'T') || inRANGE_helper_(U8, ((const U8*)s)[2], 's', 't') ) ? 3\
            : ( ( 0xC5 == ((const U8*)s)[2] ) && ( 0xBF == ((const U8*)s)[3] ) ) ? 4 : 0 )\
        : 0 )                                                               \
     : ( 0xCA == ((const U8*)s)[0] ) ?                                       \
     : ( ( ((const U8*)s)[0] & 0xDF ) == 'J' ) ?                             \
        ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x8C == ((const U8*)s)[2] ) ) ? 3 : 0 )\
     : ( ( ((const U8*)s)[0] & 0xDF ) == 'S' ) ?                             \
-       ( ( inRANGE(((const U8*)s)[1], 'S', 'T') || inRANGE(((const U8*)s)[1], 's', 't') ) ? 2\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 'S', 'T') || inRANGE_helper_(U8, ((const U8*)s)[1], 's', 't') ) ? 2\
        : ( ( 0xC5 == ((const U8*)s)[1] ) && ( 0xBF == ((const U8*)s)[2] ) ) ? 3 : 0 )\
     : ( ( ((const U8*)s)[0] & 0xDF ) == 'T' ) ?                             \
        ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x88 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
     : ( ( ( ((const U8*)s)[0] & 0xDF ) == 'W' ) || ( ( ((const U8*)s)[0] & 0xDF ) == 'Y' ) ) ?\
        ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x8A == ((const U8*)s)[2] ) ) ? 3 : 0 )\
     : ( 0xC5 == ((const U8*)s)[0] ) ?                                       \
-       ( ( ( 0xBF == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 'S', 'T') || inRANGE(((const U8*)s)[2], 's', 't') ) ) ? 3 : 0 )\
+       ( ( ( 0xBF == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 'S', 'T') || inRANGE_helper_(U8, ((const U8*)s)[2], 's', 't') ) ) ? 3 : 0 )\
     : ( ( ( 0xCA == ((const U8*)s)[0] ) && ( 0xBC == ((const U8*)s)[1] ) ) && ( ( ((const U8*)s)[2] & 0xDF ) == 'N' ) ) ? 3 : 0 )\
 : ((e)-(s) > 1) ?                                                           \
     ( ( ( ((const U8*)s)[0] & 0xDF ) == 'F' ) ?                             \
        ( ( ( ( ((const U8*)s)[1] & 0xDF ) == 'F' ) || ( ( ((const U8*)s)[1] & 0xDF ) == 'I' ) || ( ( ((const U8*)s)[1] & 0xDF ) == 'L' ) ) ? 2 : 0 )\
-    : ( ( ( ((const U8*)s)[0] & 0xDF ) == 'S' ) && ( inRANGE(((const U8*)s)[1], 'S', 'T') || inRANGE(((const U8*)s)[1], 's', 't') ) ) ? 2 : 0 )\
+    : ( ( ( ((const U8*)s)[0] & 0xDF ) == 'S' ) && ( inRANGE_helper_(U8, ((const U8*)s)[1], 'S', 'T') || inRANGE_helper_(U8, ((const U8*)s)[1], 's', 't') ) ) ? 2 : 0 )\
 : 0 )
 
 
     : ( ( ((const U8*)s)[0] & 0xDF ) == 'J' ) ?                             \
        ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x8C == ((const U8*)s)[2] ) ) ? 3 : 0 )\
     : ( ( ((const U8*)s)[0] & 0xDF ) == 'S' ) ?                             \
-       ( ( inRANGE(((const U8*)s)[1], 'S', 'T') || inRANGE(((const U8*)s)[1], 's', 't') ) ? 2\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 'S', 'T') || inRANGE_helper_(U8, ((const U8*)s)[1], 's', 't') ) ? 2\
        : ( ( 0xC5 == ((const U8*)s)[1] ) && ( 0xBF == ((const U8*)s)[2] ) ) ? 3 : 0 )\
     : ( ( ((const U8*)s)[0] & 0xDF ) == 'T' ) ?                             \
        ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x88 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
        ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x8A == ((const U8*)s)[2] ) ) ? 3 : 0 )\
     : ( 0xC5 == ((const U8*)s)[0] ) ?                                       \
        ( ( 0xBF == ((const U8*)s)[1] ) ?                                   \
-           ( ( inRANGE(((const U8*)s)[2], 'S', 'T') || inRANGE(((const U8*)s)[2], 's', 't') ) ? 3\
+           ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 'S', 'T') || inRANGE_helper_(U8, ((const U8*)s)[2], 's', 't') ) ? 3\
            : ( ( 0xC5 == ((const U8*)s)[2] ) && ( 0xBF == ((const U8*)s)[3] ) ) ? 4 : 0 )\
        : 0 )                                                               \
     : ( 0xCA == ((const U8*)s)[0] ) ?                                       \
     : 0 )                                                                   \
 : ((e)-(s) > 3) ? is_MULTI_CHAR_FOLD_utf8_safe_part2(s,e) : is_MULTI_CHAR_FOLD_utf8_safe_part3(s,e) )
 
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part0(s,e)                           \
+( ( 0x81 == ((const U8*)s)[1] ) ?                                           \
+           ( ( ( 0xCC == ((const U8*)s)[2] ) && ( 0x93 == ((const U8*)s)[3] ) ) ? 0x1FE4 : 0 )\
+       : ( 0x85 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xCC == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x88 == ((const U8*)s)[3] ) ?                           \
+                   ( ( 0xCC == ((const U8*)s)[4] ) ?                       \
+                       ( ( 0x80 == ((const U8*)s)[5] ) ? 0x1FE2            \
+                       : ( 0x81 == ((const U8*)s)[5] ) ? 0x3B0 : 0 )       \
+                   : ( ( 0xCD == ((const U8*)s)[4] ) && ( 0x82 == ((const U8*)s)[5] ) ) ? 0x1FE7 : 0 )\
+               : ( 0x93 == ((const U8*)s)[3] ) ?                           \
+                   ( ( 0xCC == ((const U8*)s)[4] ) ?                       \
+                       ( ( 0x80 == ((const U8*)s)[5] ) ? 0x1F52            \
+                       : ( 0x81 == ((const U8*)s)[5] ) ? 0x1F54 : 0x1F50 ) \
+                   : ( ( 0xCD == ((const U8*)s)[4] ) && ( 0x82 == ((const U8*)s)[5] ) ) ? 0x1F56 : 0x1F50 )\
+               : 0 )                                                       \
+           : ( ( 0xCD == ((const U8*)s)[2] ) && ( 0x82 == ((const U8*)s)[3] ) ) ? 0x1FE6 : 0 )\
+       : ( 0x89 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xCD == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x82 == ((const U8*)s)[3] ) ?                           \
+                   ( ( ( 0xCE == ((const U8*)s)[4] ) && ( 0xB9 == ((const U8*)s)[5] ) ) ? 0x1FF7 : 0x1FF6 )\
+               : 0 )                                                       \
+           : ( ( 0xCE == ((const U8*)s)[2] ) && ( 0xB9 == ((const U8*)s)[3] ) ) ? 0x1FF3 : 0 )\
+       : ( ( ( 0x8E == ((const U8*)s)[1] ) && ( 0xCE == ((const U8*)s)[2] ) ) && ( 0xB9 == ((const U8*)s)[3] ) ) ? 0x1FF4 : 0 )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part1(s,e)                           \
+( ( 0xD5 == ((const U8*)s)[0] ) ?                                           \
+       ( ( 0xA5 == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xD6 == ((const U8*)s)[2] ) && ( 0x82 == ((const U8*)s)[3] ) ) ? 0x587 : 0 )\
+       : ( 0xB4 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xD5 == ((const U8*)s)[2] ) ?                               \
+               ( ( 0xA5 == ((const U8*)s)[3] ) ? 0xFB14                    \
+               : ( 0xAB == ((const U8*)s)[3] ) ? 0xFB15                    \
+               : ( 0xAD == ((const U8*)s)[3] ) ? 0xFB17                    \
+               : ( 0xB6 == ((const U8*)s)[3] ) ? 0xFB13 : 0 )              \
+           : 0 )                                                           \
+       : ( ( ( 0xBE == ((const U8*)s)[1] ) && ( 0xD5 == ((const U8*)s)[2] ) ) && ( 0xB6 == ((const U8*)s)[3] ) ) ? 0xFB16 : 0 )\
+    : ( 0xE1 == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0xBC == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x80 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F80 : 0 )\
+           : ( 0x81 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F81 : 0 )\
+           : ( 0x82 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F82 : 0 )\
+           : ( 0x83 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F83 : 0 )\
+           : ( 0x84 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F84 : 0 )\
+           : ( 0x85 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F85 : 0 )\
+           : ( 0x86 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F86 : 0 )\
+           : ( 0x87 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F87 : 0 )\
+           : ( 0xA0 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F90 : 0 )\
+           : ( 0xA1 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F91 : 0 )\
+           : ( 0xA2 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F92 : 0 )\
+           : ( 0xA3 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F93 : 0 )\
+           : ( 0xA4 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F94 : 0 )\
+           : ( 0xA5 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F95 : 0 )\
+           : ( 0xA6 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F96 : 0 )\
+           : ( ( ( 0xA7 == ((const U8*)s)[2] ) && ( 0xCE == ((const U8*)s)[3] ) ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F97 : 0 )\
+       : ( 0xBD == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xA0 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1FA0 : 0 )\
+           : ( 0xA1 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1FA1 : 0 )\
+           : ( 0xA2 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1FA2 : 0 )\
+           : ( 0xA3 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1FA3 : 0 )\
+           : ( 0xA4 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1FA4 : 0 )\
+           : ( 0xA5 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1FA5 : 0 )\
+           : ( 0xA6 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1FA6 : 0 )\
+           : ( 0xA7 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1FA7 : 0 )\
+           : ( 0xB0 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1FB2 : 0 )\
+           : ( 0xB4 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1FC2 : 0 )\
+           : ( ( ( 0xBC == ((const U8*)s)[2] ) && ( 0xCE == ((const U8*)s)[3] ) ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1FF2 : 0 )\
+       : 0 )                                                               \
+    : 0 )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part2(s,e)                           \
+( ( 0x81 == ((const U8*)s)[1] ) ?                                           \
+           ( ( ( 0xCC == ((const U8*)s)[2] ) && ( 0x93 == ((const U8*)s)[3] ) ) ? 0x1FE4 : 0 )\
+       : ( 0x85 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xCC == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x93 == ((const U8*)s)[3] ) ? 0x1F50 : 0 )              \
+           : ( ( 0xCD == ((const U8*)s)[2] ) && ( 0x82 == ((const U8*)s)[3] ) ) ? 0x1FE6 : 0 )\
+       : ( 0x89 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xCD == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x82 == ((const U8*)s)[3] ) ? 0x1FF6 : 0 )              \
+           : ( ( 0xCE == ((const U8*)s)[2] ) && ( 0xB9 == ((const U8*)s)[3] ) ) ? 0x1FF3 : 0 )\
+       : ( ( ( 0x8E == ((const U8*)s)[1] ) && ( 0xCE == ((const U8*)s)[2] ) ) && ( 0xB9 == ((const U8*)s)[3] ) ) ? 0x1FF4 : 0 )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part3(s,e)                           \
+( ( 0xD5 == ((const U8*)s)[0] ) ?                                           \
+       ( ( 0xA5 == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xD6 == ((const U8*)s)[2] ) && ( 0x82 == ((const U8*)s)[3] ) ) ? 0x587 : 0 )\
+       : ( 0xB4 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xD5 == ((const U8*)s)[2] ) ?                               \
+               ( ( 0xA5 == ((const U8*)s)[3] ) ? 0xFB14                    \
+               : ( 0xAB == ((const U8*)s)[3] ) ? 0xFB15                    \
+               : ( 0xAD == ((const U8*)s)[3] ) ? 0xFB17                    \
+               : ( 0xB6 == ((const U8*)s)[3] ) ? 0xFB13 : 0 )              \
+           : 0 )                                                           \
+       : ( ( ( 0xBE == ((const U8*)s)[1] ) && ( 0xD5 == ((const U8*)s)[2] ) ) && ( 0xB6 == ((const U8*)s)[3] ) ) ? 0xFB16 : 0 )\
+    : ( 0xE1 == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0xBC == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x80 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F80 : 0 )\
+           : ( 0x81 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F81 : 0 )\
+           : ( 0x82 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F82 : 0 )\
+           : ( 0x83 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F83 : 0 )\
+           : ( 0x84 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F84 : 0 )\
+           : ( 0x85 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F85 : 0 )\
+           : ( 0x86 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F86 : 0 )\
+           : ( 0x87 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F87 : 0 )\
+           : ( 0xA0 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F90 : 0 )\
+           : ( 0xA1 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F91 : 0 )\
+           : ( 0xA2 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F92 : 0 )\
+           : ( 0xA3 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F93 : 0 )\
+           : ( 0xA4 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F94 : 0 )\
+           : ( 0xA5 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F95 : 0 )\
+           : ( 0xA6 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F96 : 0 )\
+           : ( ( ( 0xA7 == ((const U8*)s)[2] ) && ( 0xCE == ((const U8*)s)[3] ) ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1F97 : 0 )\
+       : ( 0xBD == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xA0 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1FA0 : 0 )\
+           : ( 0xA1 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1FA1 : 0 )\
+           : ( 0xA2 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1FA2 : 0 )\
+           : ( 0xA3 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1FA3 : 0 )\
+           : ( 0xA4 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1FA4 : 0 )\
+           : ( 0xA5 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1FA5 : 0 )\
+           : ( 0xA6 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1FA6 : 0 )\
+           : ( 0xA7 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1FA7 : 0 )\
+           : ( 0xB0 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1FB2 : 0 )\
+           : ( 0xB4 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xCE == ((const U8*)s)[3] ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1FC2 : 0 )\
+           : ( ( ( 0xBC == ((const U8*)s)[2] ) && ( 0xCE == ((const U8*)s)[3] ) ) && ( 0xB9 == ((const U8*)s)[4] ) ) ? 0x1FF2 : 0 )\
+       : 0 )                                                               \
+    : 0 )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part4(s,e)                           \
+( ( ( ((const U8*)s)[0] & 0xDF ) == 'A' ) ?                                 \
+       ( ( ( 0xCA == ((const U8*)s)[1] ) && ( 0xBE == ((const U8*)s)[2] ) ) ? 0x1E9A : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'F' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xDF ) == 'F' ) ?                         \
+           ( ( ( ((const U8*)s)[2] & 0xDF ) == 'I' ) ? 0xFB03              \
+           : ( ( ((const U8*)s)[2] & 0xDF ) == 'L' ) ? 0xFB04 : 0xFB00 )   \
+       : ( ( ((const U8*)s)[1] & 0xDF ) == 'I' ) ? 0xFB01                  \
+       : ( ( ((const U8*)s)[1] & 0xDF ) == 'L' ) ? 0xFB02 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'H' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0xB1 == ((const U8*)s)[2] ) ) ? 0x1E96 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'I' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x87 == ((const U8*)s)[2] ) ) ? 0x130 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'J' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x8C == ((const U8*)s)[2] ) ) ? 0x1F0 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'S' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xDF ) == 'S' ) ? 0xDF                    \
+       : ( ( ((const U8*)s)[1] & 0xDF ) == 'T' ) ? 0xFB05                  \
+       : ( ( 0xC5 == ((const U8*)s)[1] ) && ( 0xBF == ((const U8*)s)[2] ) ) ? 0xDF : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'T' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x88 == ((const U8*)s)[2] ) ) ? 0x1E97 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'W' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x8A == ((const U8*)s)[2] ) ) ? 0x1E98 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'Y' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x8A == ((const U8*)s)[2] ) ) ? 0x1E99 : 0 )\
+    : ( 0xC5 == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0xBF == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( ((const U8*)s)[2] & 0xDF ) == 'S' ) ? 0xDF                \
+           : ( ( ((const U8*)s)[2] & 0xDF ) == 'T' ) ? 0xFB05              \
+           : ( ( 0xC5 == ((const U8*)s)[2] ) && ( 0xBF == ((const U8*)s)[3] ) ) ? 0xDF : 0 )\
+       : 0 )                                                               \
+    : ( 0xCA == ((const U8*)s)[0] ) ?                                       \
+       ( ( ( 0xBC == ((const U8*)s)[1] ) && ( ( ((const U8*)s)[2] & 0xDF ) == 'N' ) ) ? 0x149 : 0 )\
+    : ( 0xCE == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0xAC == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xCE == ((const U8*)s)[2] ) && ( 0xB9 == ((const U8*)s)[3] ) ) ? 0x1FB4 : 0 )\
+       : ( 0xAE == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xCE == ((const U8*)s)[2] ) && ( 0xB9 == ((const U8*)s)[3] ) ) ? 0x1FC4 : 0 )\
+       : ( 0xB1 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xCD == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x82 == ((const U8*)s)[3] ) ? 0x1FB6 : 0 )              \
+           : ( ( 0xCE == ((const U8*)s)[2] ) && ( 0xB9 == ((const U8*)s)[3] ) ) ? 0x1FB3 : 0 )\
+       : ( 0xB7 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xCD == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x82 == ((const U8*)s)[3] ) ? 0x1FC6 : 0 )              \
+           : ( ( 0xCE == ((const U8*)s)[2] ) && ( 0xB9 == ((const U8*)s)[3] ) ) ? 0x1FC3 : 0 )\
+       : ( ( ( 0xB9 == ((const U8*)s)[1] ) && ( 0xCD == ((const U8*)s)[2] ) ) && ( 0x82 == ((const U8*)s)[3] ) ) ? 0x1FD6 : 0 )\
+    : ( 0xCF == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0x81 == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xCC == ((const U8*)s)[2] ) && ( 0x93 == ((const U8*)s)[3] ) ) ? 0x1FE4 : 0 )\
+       : ( 0x85 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xCC == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x93 == ((const U8*)s)[3] ) ? 0x1F50 : 0 )              \
+           : ( ( 0xCD == ((const U8*)s)[2] ) && ( 0x82 == ((const U8*)s)[3] ) ) ? 0x1FE6 : 0 )\
+       : ( 0x89 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xCD == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x82 == ((const U8*)s)[3] ) ? 0x1FF6 : 0 )              \
+           : ( ( 0xCE == ((const U8*)s)[2] ) && ( 0xB9 == ((const U8*)s)[3] ) ) ? 0x1FF3 : 0 )\
+       : ( ( ( 0x8E == ((const U8*)s)[1] ) && ( 0xCE == ((const U8*)s)[2] ) ) && ( 0xB9 == ((const U8*)s)[3] ) ) ? 0x1FF4 : 0 )\
+    : ( 0xD5 == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0xA5 == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xD6 == ((const U8*)s)[2] ) && ( 0x82 == ((const U8*)s)[3] ) ) ? 0x587 : 0 )\
+       : ( 0xB4 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xD5 == ((const U8*)s)[2] ) ?                               \
+               ( ( 0xA5 == ((const U8*)s)[3] ) ? 0xFB14                    \
+               : ( 0xAB == ((const U8*)s)[3] ) ? 0xFB15                    \
+               : ( 0xAD == ((const U8*)s)[3] ) ? 0xFB17                    \
+               : ( 0xB6 == ((const U8*)s)[3] ) ? 0xFB13 : 0 )              \
+           : 0 )                                                           \
+       : ( ( ( 0xBE == ((const U8*)s)[1] ) && ( 0xD5 == ((const U8*)s)[2] ) ) && ( 0xB6 == ((const U8*)s)[3] ) ) ? 0xFB16 : 0 )\
+    : 0 )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part5(s,e)                           \
+( ((e)-(s) > 2) ?                                                           \
+    ( ( ( ((const U8*)s)[0] & 0xDF ) == 'A' ) ?                             \
+       ( ( ( 0xCA == ((const U8*)s)[1] ) && ( 0xBE == ((const U8*)s)[2] ) ) ? 0x1E9A : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'F' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xDF ) == 'F' ) ?                         \
+           ( ( ( ((const U8*)s)[2] & 0xDF ) == 'I' ) ? 0xFB03              \
+           : ( ( ((const U8*)s)[2] & 0xDF ) == 'L' ) ? 0xFB04 : 0xFB00 )   \
+       : ( ( ((const U8*)s)[1] & 0xDF ) == 'I' ) ? 0xFB01                  \
+       : ( ( ((const U8*)s)[1] & 0xDF ) == 'L' ) ? 0xFB02 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'H' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0xB1 == ((const U8*)s)[2] ) ) ? 0x1E96 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'I' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x87 == ((const U8*)s)[2] ) ) ? 0x130 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'J' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x8C == ((const U8*)s)[2] ) ) ? 0x1F0 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'S' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xDF ) == 'S' ) ? 0xDF                    \
+       : ( ( ((const U8*)s)[1] & 0xDF ) == 'T' ) ? 0xFB05                  \
+       : ( ( 0xC5 == ((const U8*)s)[1] ) && ( 0xBF == ((const U8*)s)[2] ) ) ? 0xDF : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'T' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x88 == ((const U8*)s)[2] ) ) ? 0x1E97 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'W' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x8A == ((const U8*)s)[2] ) ) ? 0x1E98 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'Y' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x8A == ((const U8*)s)[2] ) ) ? 0x1E99 : 0 )\
+    : ( 0xC5 == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0xBF == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( ((const U8*)s)[2] & 0xDF ) == 'S' ) ? 0xDF                \
+           : ( ( ((const U8*)s)[2] & 0xDF ) == 'T' ) ? 0xFB05 : 0 )        \
+       : 0 )                                                               \
+    : ( ( ( 0xCA == ((const U8*)s)[0] ) && ( 0xBC == ((const U8*)s)[1] ) ) && ( ( ((const U8*)s)[2] & 0xDF ) == 'N' ) ) ? 0x149 : 0 )\
+: ((e)-(s) > 1) ?                                                           \
+    ( ( ( ((const U8*)s)[0] & 0xDF ) == 'F' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xDF ) == 'F' ) ? 0xFB00                  \
+       : ( ( ((const U8*)s)[1] & 0xDF ) == 'I' ) ? 0xFB01                  \
+       : ( ( ((const U8*)s)[1] & 0xDF ) == 'L' ) ? 0xFB02 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'S' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xDF ) == 'S' ) ? 0xDF                    \
+       : ( ( ((const U8*)s)[1] & 0xDF ) == 'T' ) ? 0xFB05 : 0 )            \
+    : 0 )                                                                   \
+: 0 )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part6(s,e)                           \
+( ( ( ((const U8*)s)[0] & 0xDF ) == 'A' ) ?                                 \
+       ( ( ( 0xCA == ((const U8*)s)[1] ) && ( 0xBE == ((const U8*)s)[2] ) ) ? 0x1E9A : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'F' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xDF ) == 'F' ) ?                         \
+           ( ( ( ((const U8*)s)[2] & 0xDF ) == 'I' ) ? 0xFB03              \
+           : ( ( ((const U8*)s)[2] & 0xDF ) == 'L' ) ? 0xFB04 : 0xFB00 )   \
+       : ( ( ((const U8*)s)[1] & 0xDF ) == 'I' ) ? 0xFB01                  \
+       : ( ( ((const U8*)s)[1] & 0xDF ) == 'L' ) ? 0xFB02 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'H' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0xB1 == ((const U8*)s)[2] ) ) ? 0x1E96 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'I' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x87 == ((const U8*)s)[2] ) ) ? 0x130 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'J' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x8C == ((const U8*)s)[2] ) ) ? 0x1F0 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'S' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xDF ) == 'S' ) ? 0xDF                    \
+       : ( ( ((const U8*)s)[1] & 0xDF ) == 'T' ) ? 0xFB05                  \
+       : ( ( 0xC5 == ((const U8*)s)[1] ) && ( 0xBF == ((const U8*)s)[2] ) ) ? 0xDF : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'T' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x88 == ((const U8*)s)[2] ) ) ? 0x1E97 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'W' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x8A == ((const U8*)s)[2] ) ) ? 0x1E98 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'Y' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x8A == ((const U8*)s)[2] ) ) ? 0x1E99 : 0 )\
+    : ( 0xC5 == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0xBF == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( ((const U8*)s)[2] & 0xDF ) == 'S' ) ? 0xDF                \
+           : ( ( ((const U8*)s)[2] & 0xDF ) == 'T' ) ? 0xFB05              \
+           : ( ( 0xC5 == ((const U8*)s)[2] ) && ( 0xBF == ((const U8*)s)[3] ) ) ? 0xDF : 0 )\
+       : 0 )                                                               \
+    : ( 0xCA == ((const U8*)s)[0] ) ?                                       \
+       ( ( ( 0xBC == ((const U8*)s)[1] ) && ( ( ((const U8*)s)[2] & 0xDF ) == 'N' ) ) ? 0x149 : 0 )\
+    : ( 0xCE == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0xAC == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xCE == ((const U8*)s)[2] ) && ( 0xB9 == ((const U8*)s)[3] ) ) ? 0x1FB4 : 0 )\
+       : ( 0xAE == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xCE == ((const U8*)s)[2] ) && ( 0xB9 == ((const U8*)s)[3] ) ) ? 0x1FC4 : 0 )\
+       : ( 0xB1 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xCD == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x82 == ((const U8*)s)[3] ) ?                           \
+                   ( ( ( 0xCE == ((const U8*)s)[4] ) && ( 0xB9 == ((const U8*)s)[5] ) ) ? 0x1FB7 : 0x1FB6 )\
+               : 0 )                                                       \
+           : ( ( 0xCE == ((const U8*)s)[2] ) && ( 0xB9 == ((const U8*)s)[3] ) ) ? 0x1FB3 : 0 )\
+       : ( 0xB7 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xCD == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x82 == ((const U8*)s)[3] ) ?                           \
+                   ( ( ( 0xCE == ((const U8*)s)[4] ) && ( 0xB9 == ((const U8*)s)[5] ) ) ? 0x1FC7 : 0x1FC6 )\
+               : 0 )                                                       \
+           : ( ( 0xCE == ((const U8*)s)[2] ) && ( 0xB9 == ((const U8*)s)[3] ) ) ? 0x1FC3 : 0 )\
+       : ( 0xB9 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xCC == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x88 == ((const U8*)s)[3] ) ?                           \
+                   ( ( 0xCC == ((const U8*)s)[4] ) ?                       \
+                       ( ( 0x80 == ((const U8*)s)[5] ) ? 0x1FD2            \
+                       : ( 0x81 == ((const U8*)s)[5] ) ? 0x390 : 0 )       \
+                   : ( ( 0xCD == ((const U8*)s)[4] ) && ( 0x82 == ((const U8*)s)[5] ) ) ? 0x1FD7 : 0 )\
+               : 0 )                                                       \
+           : ( ( 0xCD == ((const U8*)s)[2] ) && ( 0x82 == ((const U8*)s)[3] ) ) ? 0x1FD6 : 0 )\
+       : 0 )                                                               \
+    : ( 0xCF == ((const U8*)s)[0] ) ? what_MULTI_CHAR_FOLD_utf8_safe_part0(s,e) : what_MULTI_CHAR_FOLD_utf8_safe_part1(s,e) )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part7(s,e)                           \
+( ((e)-(s) > 4) ?                                                           \
+    ( ( ( ((const U8*)s)[0] & 0xDF ) == 'A' ) ?                             \
+       ( ( ( 0xCA == ((const U8*)s)[1] ) && ( 0xBE == ((const U8*)s)[2] ) ) ? 0x1E9A : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'F' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xDF ) == 'F' ) ?                         \
+           ( ( ( ((const U8*)s)[2] & 0xDF ) == 'I' ) ? 0xFB03              \
+           : ( ( ((const U8*)s)[2] & 0xDF ) == 'L' ) ? 0xFB04 : 0xFB00 )   \
+       : ( ( ((const U8*)s)[1] & 0xDF ) == 'I' ) ? 0xFB01                  \
+       : ( ( ((const U8*)s)[1] & 0xDF ) == 'L' ) ? 0xFB02 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'H' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0xB1 == ((const U8*)s)[2] ) ) ? 0x1E96 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'I' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x87 == ((const U8*)s)[2] ) ) ? 0x130 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'J' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x8C == ((const U8*)s)[2] ) ) ? 0x1F0 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'S' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xDF ) == 'S' ) ? 0xDF                    \
+       : ( ( ((const U8*)s)[1] & 0xDF ) == 'T' ) ? 0xFB05                  \
+       : ( ( 0xC5 == ((const U8*)s)[1] ) && ( 0xBF == ((const U8*)s)[2] ) ) ? 0xDF : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'T' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x88 == ((const U8*)s)[2] ) ) ? 0x1E97 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'W' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x8A == ((const U8*)s)[2] ) ) ? 0x1E98 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'Y' ) ?                             \
+       ( ( ( 0xCC == ((const U8*)s)[1] ) && ( 0x8A == ((const U8*)s)[2] ) ) ? 0x1E99 : 0 )\
+    : ( 0xC5 == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0xBF == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( ((const U8*)s)[2] & 0xDF ) == 'S' ) ? 0xDF                \
+           : ( ( ((const U8*)s)[2] & 0xDF ) == 'T' ) ? 0xFB05              \
+           : ( ( 0xC5 == ((const U8*)s)[2] ) && ( 0xBF == ((const U8*)s)[3] ) ) ? 0xDF : 0 )\
+       : 0 )                                                               \
+    : ( 0xCA == ((const U8*)s)[0] ) ?                                       \
+       ( ( ( 0xBC == ((const U8*)s)[1] ) && ( ( ((const U8*)s)[2] & 0xDF ) == 'N' ) ) ? 0x149 : 0 )\
+    : ( 0xCE == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0xAC == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xCE == ((const U8*)s)[2] ) && ( 0xB9 == ((const U8*)s)[3] ) ) ? 0x1FB4 : 0 )\
+       : ( 0xAE == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xCE == ((const U8*)s)[2] ) && ( 0xB9 == ((const U8*)s)[3] ) ) ? 0x1FC4 : 0 )\
+       : ( 0xB1 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xCD == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x82 == ((const U8*)s)[3] ) ? 0x1FB6 : 0 )              \
+           : ( ( 0xCE == ((const U8*)s)[2] ) && ( 0xB9 == ((const U8*)s)[3] ) ) ? 0x1FB3 : 0 )\
+       : ( 0xB7 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xCD == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x82 == ((const U8*)s)[3] ) ? 0x1FC6 : 0 )              \
+           : ( ( 0xCE == ((const U8*)s)[2] ) && ( 0xB9 == ((const U8*)s)[3] ) ) ? 0x1FC3 : 0 )\
+       : ( ( ( 0xB9 == ((const U8*)s)[1] ) && ( 0xCD == ((const U8*)s)[2] ) ) && ( 0x82 == ((const U8*)s)[3] ) ) ? 0x1FD6 : 0 )\
+    : ( 0xCF == ((const U8*)s)[0] ) ? what_MULTI_CHAR_FOLD_utf8_safe_part2(s,e) : what_MULTI_CHAR_FOLD_utf8_safe_part3(s,e) )\
+: ((e)-(s) > 3) ? what_MULTI_CHAR_FOLD_utf8_safe_part4(s,e) : what_MULTI_CHAR_FOLD_utf8_safe_part5(s,e) )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe(s,e)                                 \
+( ((e)-(s) > 5) ? what_MULTI_CHAR_FOLD_utf8_safe_part6(s,e) : what_MULTI_CHAR_FOLD_utf8_safe_part7(s,e) )
+
 /*
        MULTI_CHAR_FOLD: multi-char strings that are folded to by a single character
 
-       &regcharclass_multi_char_folds::multi_char_folds('l', 'a')
+       %regcharclass_multi_char_folds::multi_char_folds('l', 'a')
 */
 /*** GENERATED CODE ***/
 #define is_MULTI_CHAR_FOLD_latin1_safe(s,e)                                 \
        ( ( ( ((const U8*)s)[1] & 0xDF ) == 'F' ) ?                         \
            ( ( ( ( ((const U8*)s)[2] & 0xDF ) == 'I' ) || ( ( ((const U8*)s)[2] & 0xDF ) == 'L' ) ) ? 3 : 2 )\
        : ( ( ( ((const U8*)s)[1] & 0xDF ) == 'I' ) || ( ( ((const U8*)s)[1] & 0xDF ) == 'L' ) ) ? 2 : 0 )\
-    : ( ( ( ((const U8*)s)[0] & 0xDF ) == 'S' ) && ( inRANGE(((const U8*)s)[1], 'S', 'T') || inRANGE(((const U8*)s)[1], 's', 't') ) ) ? 2 : 0 )\
+    : ( ( ( ((const U8*)s)[0] & 0xDF ) == 'S' ) && ( inRANGE_helper_(U8, ((const U8*)s)[1], 'S', 'T') || inRANGE_helper_(U8, ((const U8*)s)[1], 's', 't') ) ) ? 2 : 0 )\
 : ((e)-(s) > 1) ?                                                           \
     ( ( ( ((const U8*)s)[0] & 0xDF ) == 'F' ) ?                             \
        ( ( ( ( ((const U8*)s)[1] & 0xDF ) == 'F' ) || ( ( ((const U8*)s)[1] & 0xDF ) == 'I' ) || ( ( ((const U8*)s)[1] & 0xDF ) == 'L' ) ) ? 2 : 0 )\
-    : ( ( ( ((const U8*)s)[0] & 0xDF ) == 'S' ) && ( inRANGE(((const U8*)s)[1], 'S', 'T') || inRANGE(((const U8*)s)[1], 's', 't') ) ) ? 2 : 0 )\
+    : ( ( ( ((const U8*)s)[0] & 0xDF ) == 'S' ) && ( inRANGE_helper_(U8, ((const U8*)s)[1], 'S', 'T') || inRANGE_helper_(U8, ((const U8*)s)[1], 's', 't') ) ) ? 2 : 0 )\
+: 0 )
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_latin1_safe(s,e)                               \
+( ((e)-(s) > 2) ?                                                           \
+    ( ( ( ((const U8*)s)[0] & 0xDF ) == 'F' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xDF ) == 'F' ) ?                         \
+           ( ( ( ((const U8*)s)[2] & 0xDF ) == 'I' ) ? 0xFB03              \
+           : ( ( ((const U8*)s)[2] & 0xDF ) == 'L' ) ? 0xFB04 : 0xFB00 )   \
+       : ( ( ((const U8*)s)[1] & 0xDF ) == 'I' ) ? 0xFB01                  \
+       : ( ( ((const U8*)s)[1] & 0xDF ) == 'L' ) ? 0xFB02 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'S' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xDF ) == 'S' ) ? 0xDF                    \
+       : ( ( ((const U8*)s)[1] & 0xDF ) == 'T' ) ? 0xFB05 : 0 )            \
+    : 0 )                                                                   \
+: ((e)-(s) > 1) ?                                                           \
+    ( ( ( ((const U8*)s)[0] & 0xDF ) == 'F' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xDF ) == 'F' ) ? 0xFB00                  \
+       : ( ( ((const U8*)s)[1] & 0xDF ) == 'I' ) ? 0xFB01                  \
+       : ( ( ((const U8*)s)[1] & 0xDF ) == 'L' ) ? 0xFB02 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xDF ) == 'S' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xDF ) == 'S' ) ? 0xDF                    \
+       : ( ( ((const U8*)s)[1] & 0xDF ) == 'T' ) ? 0xFB05 : 0 )            \
+    : 0 )                                                                   \
 : 0 )
 
 /*
        THREE_CHAR_FOLD: A three-character multi-char fold
 
-       &regcharclass_multi_char_folds::multi_char_folds('u', '3')
+       %regcharclass_multi_char_folds::multi_char_folds('u', '3')
 */
 /*** GENERATED CODE ***/
 #define is_THREE_CHAR_FOLD_utf8_safe(s,e)                                   \
        ( ( 0xB1 == ((const U8*)s)[1] || 0xB7 == ((const U8*)s)[1] ) ?      \
            ( ( ( ( ( 0xCD == ((const U8*)s)[2] ) && ( 0x82 == ((const U8*)s)[3] ) ) && ( 0xCE == ((const U8*)s)[4] ) ) && ( 0xB9 == ((const U8*)s)[5] ) ) ? 6 : 0 )\
        : ( ( ( 0xB9 == ((const U8*)s)[1] ) && ( 0xCC == ((const U8*)s)[2] ) ) && ( 0x88 == ((const U8*)s)[3] ) ) ? ( ( 0xCC == ((const U8*)s)[4] ) ?\
-                       ( ( inRANGE(((const U8*)s)[5], 0x80, 0x81) ) ? 6 : 0 )\
+                       ( ( inRANGE_helper_(U8, ((const U8*)s)[5], 0x80, 0x81) ) ? 6 : 0 )\
                    : ( ( 0xCD == ((const U8*)s)[4] ) && ( 0x82 == ((const U8*)s)[5] ) ) ? 6 : 0 ) : 0 )\
     : ( 0xCF == ((const U8*)s)[0] ) ?                                       \
        ( ( 0x85 == ((const U8*)s)[1] ) ?                                   \
            ( ( ( 0xCC == ((const U8*)s)[2] ) && ( 0x88 == ((const U8*)s)[3] || 0x93 == ((const U8*)s)[3] ) ) ? ( ( 0xCC == ((const U8*)s)[4] ) ?\
-                       ( ( inRANGE(((const U8*)s)[5], 0x80, 0x81) ) ? 6 : 0 )\
+                       ( ( inRANGE_helper_(U8, ((const U8*)s)[5], 0x80, 0x81) ) ? 6 : 0 )\
                    : ( ( 0xCD == ((const U8*)s)[4] ) && ( 0x82 == ((const U8*)s)[5] ) ) ? 6 : 0 ) : 0 )\
        : ( ( ( ( ( 0x89 == ((const U8*)s)[1] ) && ( 0xCD == ((const U8*)s)[2] ) ) && ( 0x82 == ((const U8*)s)[3] ) ) && ( 0xCE == ((const U8*)s)[4] ) ) && ( 0xB9 == ((const U8*)s)[5] ) ) ? 6 : 0 )\
     : 0 )                                                                   \
 /*
        THREE_CHAR_FOLD: A three-character multi-char fold
 
-       &regcharclass_multi_char_folds::multi_char_folds('l', '3')
+       %regcharclass_multi_char_folds::multi_char_folds('l', '3')
 */
 /*** GENERATED CODE ***/
 #define is_THREE_CHAR_FOLD_latin1_safe(s,e)                                 \
 /*
        THREE_CHAR_FOLD_HEAD: The first two of three-character multi-char folds
 
-       &regcharclass_multi_char_folds::multi_char_folds('u', 'h')
+       %regcharclass_multi_char_folds::multi_char_folds('u', 'h')
 */
 /*** GENERATED CODE ***/
 #define is_THREE_CHAR_FOLD_HEAD_utf8_safe(s,e)                              \
 /*
        THREE_CHAR_FOLD_HEAD: The first two of three-character multi-char folds
 
-       &regcharclass_multi_char_folds::multi_char_folds('l', 'h')
+       %regcharclass_multi_char_folds::multi_char_folds('l', 'h')
 */
 /*** GENERATED CODE ***/
 #define is_THREE_CHAR_FOLD_HEAD_latin1_safe(s,e)                            \
     ( ( 0x87 == ((const U8*)s)[1] ) ? 2 : 0 )                               \
 : ( 0xE1 == ((const U8*)s)[0] ) ?                                           \
     ( ( 0xBA == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x96, 0x9A) || 0x9E == ((const U8*)s)[2] ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x96, 0x9A) || 0x9E == ((const U8*)s)[2] ) ? 3 : 0 )\
     : ( 0xBD == ((const U8*)s)[1] ) ?                                       \
        ( ( ( ((const U8*)s)[2] & 0xF9 ) == 0x90 ) ? 3 : 0 )                \
     : ( 0xBE == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x80, 0xAF) || inRANGE(((const U8*)s)[2], 0xB2, 0xB4) || inRANGE(((const U8*)s)[2], 0xB6, 0xB7) || 0xBC == ((const U8*)s)[2] ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x80, 0xAF) || inRANGE_helper_(U8, ((const U8*)s)[2], 0xB2, 0xB4) || inRANGE_helper_(U8, ((const U8*)s)[2], 0xB6, 0xB7) || 0xBC == ((const U8*)s)[2] ) ? 3 : 0 )\
     : ( ( 0xBF == ((const U8*)s)[1] ) && ( ( ( ((const U8*)s)[2] & 0xCA ) == 0x82 ) || ( ( ((const U8*)s)[2] & 0xF7 ) == 0x84 ) || ((const U8*)s)[2] == 0xA4 || ( ( ((const U8*)s)[2] & 0xF7 ) == 0xB4 ) ) ) ? 3 : 0 )\
-: ( ( ( 0xEF == ((const U8*)s)[0] ) && ( 0xAC == ((const U8*)s)[1] ) ) && ( inRANGE(((const U8*)s)[2], 0x80, 0x86) || inRANGE(((const U8*)s)[2], 0x93, 0x97) ) ) ? 3 : 0 )
+: ( ( ( 0xEF == ((const U8*)s)[0] ) && ( 0xAC == ((const U8*)s)[1] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x80, 0x86) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x93, 0x97) ) ) ? 3 : 0 )
 
 /*
        PROBLEMATIC_LOCALE_FOLD: characters whose fold is problematic under locale
 /*** GENERATED CODE ***/
 #define is_PROBLEMATIC_LOCALE_FOLD_utf8(s)                                  \
 ( ( ((const U8*)s)[0] <= 0x7F ) ? 1                                         \
-: ( inRANGE(((const U8*)s)[0], 0xC2, 0xC3) ) ?                              \
+: ( inRANGE_helper_(U8, ((const U8*)s)[0], 0xC2, 0xC3) ) ?                  \
     2                                                                       \
 : ( 0xC4 == ((const U8*)s)[0] ) ?                                           \
-    ( ( inRANGE(((const U8*)s)[1], 0xB0, 0xB1) ) ? 2 : 0 )                  \
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0xB0, 0xB1) ) ? 2 : 0 )      \
 : ( 0xC5 == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x89 == ((const U8*)s)[1] || 0xB8 == ((const U8*)s)[1] || 0xBF == ((const U8*)s)[1] ) ? 2 : 0 )\
 : ( 0xC7 == ((const U8*)s)[0] ) ?                                           \
 : ( 0xCE == ((const U8*)s)[0] ) ?                                           \
     ( ( ( ((const U8*)s)[1] & 0xDF ) == 0x9C ) ? 2 : 0 )                    \
 : ( 0xE1 == ((const U8*)s)[0] ) ?                                           \
-    ( ( ( 0xBA == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x96, 0x9A) || 0x9E == ((const U8*)s)[2] ) ) ? 3 : 0 )\
+    ( ( ( 0xBA == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x96, 0x9A) || 0x9E == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 : ( 0xE2 == ((const U8*)s)[0] ) ?                                           \
-    ( ( ( 0x84 == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0xAA, 0xAB) ) ) ? 3 : 0 )\
-: ( ( ( 0xEF == ((const U8*)s)[0] ) && ( 0xAC == ((const U8*)s)[1] ) ) && ( inRANGE(((const U8*)s)[2], 0x80, 0x86) ) ) ? 3 : 0 )
+    ( ( ( 0x84 == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0xAA, 0xAB) ) ) ? 3 : 0 )\
+: ( ( ( 0xEF == ((const U8*)s)[0] ) && ( 0xAC == ((const U8*)s)[1] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x80, 0x86) ) ) ? 3 : 0 )
 
 /*** GENERATED CODE ***/
 #define is_PROBLEMATIC_LOCALE_FOLD_cp(cp)                                   \
 ( cp <= 0xFF || ( 0xFF < cp &&                                              \
-( 0x130 == cp || ( 0x130 < cp &&                                            \
-( 0x131 == cp || ( 0x131 < cp &&                                            \
+( inRANGE_helper_(UV, cp, 0x130, 0x131) || ( 0x131 < cp &&                  \
 ( 0x149 == cp || ( 0x149 < cp &&                                            \
 ( 0x178 == cp || ( 0x178 < cp &&                                            \
 ( 0x17F == cp || ( 0x17F < cp &&                                            \
 ( 0x307 == cp || ( 0x307 < cp &&                                            \
 ( 0x39C == cp || ( 0x39C < cp &&                                            \
 ( 0x3BC == cp || ( 0x3BC < cp &&                                            \
-( inRANGE(cp, 0x1E96, 0x1E9A) || ( 0x1E9A < cp &&                           \
+( inRANGE_helper_(UV, cp, 0x1E96, 0x1E9A) || ( 0x1E9A < cp &&               \
 ( 0x1E9E == cp || ( 0x1E9E < cp &&                                          \
-( 0x212A == cp || ( 0x212A < cp &&                                          \
-( 0x212B == cp || inRANGE(cp, 0xFB00, 0xFB06) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )
+( inRANGE_helper_(UV, cp, 0x212A, 0x212B) || inRANGE_helper_(UV, cp, 0xFB00, 0xFB06) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )
 
 /*
        PROBLEMATIC_LOCALE_FOLDEDS_START: The first folded character of folds which are problematic under locale
 /*** GENERATED CODE ***/
 #define is_PROBLEMATIC_LOCALE_FOLDEDS_START_utf8(s)                         \
 ( ( ((const U8*)s)[0] <= 0x7F ) ? 1                                         \
-: ( inRANGE(((const U8*)s)[0], 0xC2, 0xC3) ) ?                              \
+: ( inRANGE_helper_(U8, ((const U8*)s)[0], 0xC2, 0xC3) ) ?                  \
     2                                                                       \
 : ( 0xC4 == ((const U8*)s)[0] ) ?                                           \
-    ( ( inRANGE(((const U8*)s)[1], 0xB0, 0xB1) ) ? 2 : 0 )                  \
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0xB0, 0xB1) ) ? 2 : 0 )      \
 : ( 0xC5 == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x89 == ((const U8*)s)[1] || 0xB8 == ((const U8*)s)[1] || 0xBF == ((const U8*)s)[1] ) ? 2 : 0 )\
 : ( 0xC7 == ((const U8*)s)[0] ) ?                                           \
 : ( 0xCE == ((const U8*)s)[0] ) ?                                           \
     ( ( ( ((const U8*)s)[1] & 0xDF ) == 0x9C ) ? 2 : 0 )                    \
 : ( 0xE1 == ((const U8*)s)[0] ) ?                                           \
-    ( ( ( 0xBA == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x96, 0x9A) || 0x9E == ((const U8*)s)[2] ) ) ? 3 : 0 )\
+    ( ( ( 0xBA == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x96, 0x9A) || 0x9E == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 : ( 0xE2 == ((const U8*)s)[0] ) ?                                           \
-    ( ( ( 0x84 == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0xAA, 0xAB) ) ) ? 3 : 0 )\
-: ( ( ( 0xEF == ((const U8*)s)[0] ) && ( 0xAC == ((const U8*)s)[1] ) ) && ( inRANGE(((const U8*)s)[2], 0x80, 0x86) ) ) ? 3 : 0 )
+    ( ( ( 0x84 == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0xAA, 0xAB) ) ) ? 3 : 0 )\
+: ( ( ( 0xEF == ((const U8*)s)[0] ) && ( 0xAC == ((const U8*)s)[1] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x80, 0x86) ) ) ? 3 : 0 )
 
 /*** GENERATED CODE ***/
 #define is_PROBLEMATIC_LOCALE_FOLDEDS_START_cp(cp)                          \
 ( cp <= 0xFF || ( 0xFF < cp &&                                              \
-( 0x130 == cp || ( 0x130 < cp &&                                            \
-( 0x131 == cp || ( 0x131 < cp &&                                            \
+( inRANGE_helper_(UV, cp, 0x130, 0x131) || ( 0x131 < cp &&                  \
 ( 0x149 == cp || ( 0x149 < cp &&                                            \
 ( 0x178 == cp || ( 0x178 < cp &&                                            \
 ( 0x17F == cp || ( 0x17F < cp &&                                            \
 ( 0x2BC == cp || ( 0x2BC < cp &&                                            \
 ( 0x39C == cp || ( 0x39C < cp &&                                            \
 ( 0x3BC == cp || ( 0x3BC < cp &&                                            \
-( inRANGE(cp, 0x1E96, 0x1E9A) || ( 0x1E9A < cp &&                           \
+( inRANGE_helper_(UV, cp, 0x1E96, 0x1E9A) || ( 0x1E9A < cp &&               \
 ( 0x1E9E == cp || ( 0x1E9E < cp &&                                          \
-( 0x212A == cp || ( 0x212A < cp &&                                          \
-( 0x212B == cp || inRANGE(cp, 0xFB00, 0xFB06) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )
+( inRANGE_helper_(UV, cp, 0x212A, 0x212B) || inRANGE_helper_(UV, cp, 0xFB00, 0xFB06) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )
 
 /*
        PATWS: pattern white space
 /*** GENERATED CODE ***/
 #define is_PATWS_safe(s,e,is_utf8)                                          \
 ( ( LIKELY((e) > (s)) ) ?                                                   \
-    ( ( inRANGE(((const U8*)s)[0], '\t', '\r') || ' ' == ((const U8*)s)[0] ) ? 1\
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[0], '\t', '\r') || ' ' == ((const U8*)s)[0] ) ? 1\
     : (! is_utf8 ) ?                                                        \
            ( 0x85 == ((const U8*)s)[0] )                                   \
        : ( LIKELY(((e) - (s)) >= UTF8SKIP(s)) ) ?                          \
            ( ( 0xC2 == ((const U8*)s)[0] ) ?                               \
                ( ( 0x85 == ((const U8*)s)[1] ) ? 2 : 0 )                   \
-           : ( ( ( 0xE2 == ((const U8*)s)[0] ) && ( 0x80 == ((const U8*)s)[1] ) ) && ( inRANGE(((const U8*)s)[2], 0x8E, 0x8F) || inRANGE(((const U8*)s)[2], 0xA8, 0xA9) ) ) ? 3 : 0 )\
+           : ( ( ( 0xE2 == ((const U8*)s)[0] ) && ( 0x80 == ((const U8*)s)[1] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x8E, 0x8F) || inRANGE_helper_(U8, ((const U8*)s)[2], 0xA8, 0xA9) ) ) ? 3 : 0 )\
        : 0 )                                                               \
 : 0 )
 
 */
 /*** GENERATED CODE ***/
 #define is_HANGUL_ED_utf8_safe(s,e)                                         \
-( ( ( ( ( ((e) - (s)) >= 3 ) && ( 0xED == ((const U8*)s)[0] ) ) && ( inRANGE(((const U8*)s)[1], 0x80, 0x9F) ) ) && ( inRANGE(((const U8*)s)[2], 0x80, 0xBF) ) ) ? 3 : 0 )
+( ( ( ( ( ((e) - (s)) >= 3 ) && ( 0xED == ((const U8*)s)[0] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x80, 0x9F) ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x80, 0xBF) ) ) ? 3 : 0 )
 
 #endif /* ASCII/Latin1 */
 
 /*** GENERATED CODE ***/
 #define is_LNBREAK_safe(s,e,is_utf8)                                        \
 ( ((e)-(s) > 2) ?                                                           \
-    ( ( inRANGE(((const U8*)s)[0], '\v', '\f') || '\n' == ((const U8*)s)[0] || 0x25 == ((const U8*)s)[0] ) ? 1\
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[0], '\v', '\f') || '\n' == ((const U8*)s)[0] || 0x25 == ((const U8*)s)[0] ) ? 1\
     : ( '\r' == ((const U8*)s)[0] ) ?                                       \
        ( ( '\n' == ((const U8*)s)[1] ) ? 2 : 1 )                           \
-    : ( ( ( ( is_utf8 ) && ( 0xCA == ((const U8*)s)[0] ) ) && ( 0x42 == ((const U8*)s)[1] ) ) && ( inRANGE(((const U8*)s)[2], 0x49, 0x4A) ) ) ? 3 : 0 )\
+    : ( ( ( ( is_utf8 ) && ( 0xCA == ((const U8*)s)[0] ) ) && ( 0x42 == ((const U8*)s)[1] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x49, 0x4A) ) ) ? 3 : 0 )\
 : ((e)-(s) > 1) ?                                                           \
-    ( ( inRANGE(((const U8*)s)[0], '\v', '\f') || '\n' == ((const U8*)s)[0] || 0x25 == ((const U8*)s)[0] ) ? 1\
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[0], '\v', '\f') || '\n' == ((const U8*)s)[0] || 0x25 == ((const U8*)s)[0] ) ? 1\
     : ( '\r' == ((const U8*)s)[0] ) ?                                       \
        ( ( '\n' == ((const U8*)s)[1] ) ? 2 : 1 )                           \
     : 0 )                                                                   \
 : ((e)-(s) > 0) ?                                                           \
-    ( inRANGE(((const U8*)s)[0], '\v', '\r') || '\n' == ((const U8*)s)[0] || 0x25 == ((const U8*)s)[0] )\
+    ( inRANGE_helper_(U8, ((const U8*)s)[0], '\v', '\r') || '\n' == ((const U8*)s)[0] || 0x25 == ((const U8*)s)[0] )\
 : 0 )
 
 /*** GENERATED CODE ***/
 #define is_LNBREAK_utf8_safe(s,e)                                           \
 ( ((e)-(s) > 2) ?                                                           \
-    ( ( inRANGE(((const U8*)s)[0], '\v', '\f') || '\n' == ((const U8*)s)[0] || 0x25 == ((const U8*)s)[0] ) ? 1\
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[0], '\v', '\f') || '\n' == ((const U8*)s)[0] || 0x25 == ((const U8*)s)[0] ) ? 1\
     : ( '\r' == ((const U8*)s)[0] ) ?                                       \
        ( ( '\n' == ((const U8*)s)[1] ) ? 2 : 1 )                           \
-    : ( ( ( 0xCA == ((const U8*)s)[0] ) && ( 0x42 == ((const U8*)s)[1] ) ) && ( inRANGE(((const U8*)s)[2], 0x49, 0x4A) ) ) ? 3 : 0 )\
+    : ( ( ( 0xCA == ((const U8*)s)[0] ) && ( 0x42 == ((const U8*)s)[1] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x49, 0x4A) ) ) ? 3 : 0 )\
 : ((e)-(s) > 1) ?                                                           \
-    ( ( inRANGE(((const U8*)s)[0], '\v', '\f') || '\n' == ((const U8*)s)[0] || 0x25 == ((const U8*)s)[0] ) ? 1\
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[0], '\v', '\f') || '\n' == ((const U8*)s)[0] || 0x25 == ((const U8*)s)[0] ) ? 1\
     : ( '\r' == ((const U8*)s)[0] ) ?                                       \
        ( ( '\n' == ((const U8*)s)[1] ) ? 2 : 1 )                           \
     : 0 )                                                                   \
 : ((e)-(s) > 0) ?                                                           \
-    ( inRANGE(((const U8*)s)[0], '\v', '\r') || '\n' == ((const U8*)s)[0] || 0x25 == ((const U8*)s)[0] )\
+    ( inRANGE_helper_(U8, ((const U8*)s)[0], '\v', '\r') || '\n' == ((const U8*)s)[0] || 0x25 == ((const U8*)s)[0] )\
 : 0 )
 
 /*** GENERATED CODE ***/
 #define is_LNBREAK_latin1_safe(s,e)                                         \
 ( ((e)-(s) > 1) ?                                                           \
-    ( ( inRANGE(((const U8*)s)[0], '\v', '\f') || '\n' == ((const U8*)s)[0] || 0x25 == ((const U8*)s)[0] ) ? 1\
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[0], '\v', '\f') || '\n' == ((const U8*)s)[0] || 0x25 == ((const U8*)s)[0] ) ? 1\
     : ( '\r' == ((const U8*)s)[0] ) ?                                       \
        ( ( '\n' == ((const U8*)s)[1] ) ? 2 : 1 )                           \
     : 0 )                                                                   \
 : ((e)-(s) > 0) ?                                                           \
-    ( inRANGE(((const U8*)s)[0], '\v', '\r') || '\n' == ((const U8*)s)[0] || 0x25 == ((const U8*)s)[0] )\
+    ( inRANGE_helper_(U8, ((const U8*)s)[0], '\v', '\r') || '\n' == ((const U8*)s)[0] || 0x25 == ((const U8*)s)[0] )\
 : 0 )
 
 /*
     ( ( ( 0x63 == ((const U8*)s)[1] ) && ( 0x41 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 : ( 0xCA == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x41 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || 0x51 == ((const U8*)s)[2] ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || 0x51 == ((const U8*)s)[2] ) ? 3 : 0 )\
     : ( 0x42 == ((const U8*)s)[1] ) ?                                       \
        ( ( 0x56 == ((const U8*)s)[2] ) ? 3 : 0 )                           \
     : ( ( 0x43 == ((const U8*)s)[1] ) && ( 0x73 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 /*** GENERATED CODE ***/
 #define is_HORIZWS_cp_high(cp)                                              \
 ( 0x1680 == cp || ( 0x1680 < cp &&                                          \
-( inRANGE(cp, 0x2000, 0x200A) || ( 0x200A < cp &&                           \
+( inRANGE_helper_(UV, cp, 0x2000, 0x200A) || ( 0x200A < cp &&               \
 ( 0x202F == cp || ( 0x202F < cp &&                                          \
 ( 0x205F == cp || 0x3000 == cp ) ) ) ) ) ) )
 
 */
 /*** GENERATED CODE ***/
 #define is_VERTWS_high(s)                                                   \
-( ( ( ( 0xCA == ((const U8*)s)[0] ) && ( 0x42 == ((const U8*)s)[1] ) ) && ( inRANGE(((const U8*)s)[2], 0x49, 0x4A) ) ) ? 3 : 0 )
+( ( ( ( 0xCA == ((const U8*)s)[0] ) && ( 0x42 == ((const U8*)s)[1] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x49, 0x4A) ) ) ? 3 : 0 )
 
 /*** GENERATED CODE ***/
 #define is_VERTWS_cp_high(cp)                                               \
-( 0x2028 == cp || 0x2029 == cp )
+( inRANGE_helper_(UV, cp, 0x2028, 0x2029) )
 
 /*
        XDIGIT: Hexadecimal digits
 /*** GENERATED CODE ***/
 #define is_XDIGIT_high(s)                                                   \
 ( ( ( 0xDD == ((const U8*)s)[0] ) && ( 0x73 == ((const U8*)s)[1] ) ) ? ( ( 0x67 == ((const U8*)s)[2] ) ?\
-           ( ( inRANGE(((const U8*)s)[3], 0x57, 0x59) || inRANGE(((const U8*)s)[3], 0x62, 0x68) ) ? 4 : 0 )\
-       : ( ( inRANGE(((const U8*)s)[2], 0x68, 0x69) ) && ( inRANGE(((const U8*)s)[3], 0x42, 0x47) ) ) ? 4 : 0 ) : 0 )
+           ( ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x57, 0x59) || inRANGE_helper_(U8, ((const U8*)s)[3], 0x62, 0x68) ) ? 4 : 0 )\
+       : ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x68, 0x69) ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x42, 0x47) ) ) ? 4 : 0 ) : 0 )
 
 /*** GENERATED CODE ***/
 #define is_XDIGIT_cp_high(cp)                                               \
-( inRANGE(cp, 0xFF10, 0xFF19) || ( 0xFF19 < cp &&                           \
-( inRANGE(cp, 0xFF21, 0xFF26) || inRANGE(cp, 0xFF41, 0xFF46) ) ) )
+( inRANGE_helper_(UV, cp, 0xFF10, 0xFF19) || ( 0xFF19 < cp &&               \
+( inRANGE_helper_(UV, cp, 0xFF21, 0xFF26) || inRANGE_helper_(UV, cp, 0xFF41, 0xFF46) ) ) )
 
 /*
        XPERLSPACE: \p{XPerlSpace}
     ( ( ( 0x63 == ((const U8*)s)[1] ) && ( 0x41 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 : ( 0xCA == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x41 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || 0x51 == ((const U8*)s)[2] ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || 0x51 == ((const U8*)s)[2] ) ? 3 : 0 )\
     : ( 0x42 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x49, 0x4A) || 0x56 == ((const U8*)s)[2] ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x49, 0x4A) || 0x56 == ((const U8*)s)[2] ) ? 3 : 0 )\
     : ( ( 0x43 == ((const U8*)s)[1] ) && ( 0x73 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 : ( ( ( 0xCE == ((const U8*)s)[0] ) && ( 0x41 == ((const U8*)s)[1] ) ) && ( 0x41 == ((const U8*)s)[2] ) ) ? 3 : 0 )
 
 /*** GENERATED CODE ***/
 #define is_XPERLSPACE_cp_high(cp)                                           \
 ( 0x1680 == cp || ( 0x1680 < cp &&                                          \
-( inRANGE(cp, 0x2000, 0x200A) || ( 0x200A < cp &&                           \
-( 0x2028 == cp || ( 0x2028 < cp &&                                          \
-( 0x2029 == cp || ( 0x2029 < cp &&                                          \
+( inRANGE_helper_(UV, cp, 0x2000, 0x200A) || ( 0x200A < cp &&               \
+( inRANGE_helper_(UV, cp, 0x2028, 0x2029) || ( 0x2029 < cp &&               \
 ( 0x202F == cp || ( 0x202F < cp &&                                          \
-( 0x205F == cp || 0x3000 == cp ) ) ) ) ) ) ) ) ) ) )
+( 0x205F == cp || 0x3000 == cp ) ) ) ) ) ) ) ) )
 
 /*
        NONCHAR: Non character code points
 ( ( ( LIKELY((e) > (s)) ) && ( LIKELY(((e) - (s)) >= UTF8SKIP(s)) ) ) ? ( ( 0xDD == ((const U8*)s)[0] ) ?\
            ( ( 0x73 == ((const U8*)s)[1] ) ?                               \
                ( ( 0x55 == ((const U8*)s)[2] ) ?                           \
-                   ( ( inRANGE(((const U8*)s)[3], 0x57, 0x59) || inRANGE(((const U8*)s)[3], 0x62, 0x6A) || inRANGE(((const U8*)s)[3], 0x70, 0x73) ) ? 4 : 0 )\
+                   ( ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x57, 0x59) || inRANGE_helper_(U8, ((const U8*)s)[3], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[3], 0x70, 0x73) ) ? 4 : 0 )\
                : ( 0x56 == ((const U8*)s)[2] ) ?                           \
-                   ( ( inRANGE(((const U8*)s)[3], 0x41, 0x4A) || inRANGE(((const U8*)s)[3], 0x51, 0x56) ) ? 4 : 0 )\
-               : ( ( 0x73 == ((const U8*)s)[2] ) && ( inRANGE(((const U8*)s)[3], 0x72, 0x73) ) ) ? 4 : 0 )\
+                   ( ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[3], 0x51, 0x56) ) ? 4 : 0 )\
+               : ( ( 0x73 == ((const U8*)s)[2] ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x72, 0x73) ) ) ? 4 : 0 )\
            : 0 )                                                           \
        : ( 0xDF == ((const U8*)s)[0] || 0xEA == ((const U8*)s)[0] || 0xEC == ((const U8*)s)[0] ) ?\
-           ( ( ( ( 0x73 == ((const U8*)s)[1] ) && ( 0x73 == ((const U8*)s)[2] ) ) && ( inRANGE(((const U8*)s)[3], 0x72, 0x73) ) ) ? 4 : 0 )\
+           ( ( ( ( 0x73 == ((const U8*)s)[1] ) && ( 0x73 == ((const U8*)s)[2] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x72, 0x73) ) ) ? 4 : 0 )\
        : ( 0xED == ((const U8*)s)[0] ) ?                                   \
-           ( ( ( ( ( ((const U8*)s)[1] == 0x4A || ((const U8*)s)[1] == 0x52 || ( ( ((const U8*)s)[1] & 0xFD ) == 0x54 ) || ((const U8*)s)[1] == 0x58 || ((const U8*)s)[1] == 0x62 || ( ( ((const U8*)s)[1] & 0xFD ) == 0x64 ) || ( ( ((const U8*)s)[1] & 0xFD ) == 0x68 ) || ( ( ((const U8*)s)[1] & 0xFD ) == 0x71 ) ) && ( 0x73 == ((const U8*)s)[2] ) ) && ( 0x73 == ((const U8*)s)[3] ) ) && ( inRANGE(((const U8*)s)[4], 0x72, 0x73) ) ) ? 5 : 0 )\
-       : ( ( ( ( ( 0xEE == ((const U8*)s)[0] ) && ( 0x42 == ((const U8*)s)[1] ) ) && ( 0x73 == ((const U8*)s)[2] ) ) && ( 0x73 == ((const U8*)s)[3] ) ) && ( inRANGE(((const U8*)s)[4], 0x72, 0x73) ) ) ? 5 : 0 ) : 0 )
+           ( ( ( ( ( ((const U8*)s)[1] == 0x4A || ((const U8*)s)[1] == 0x52 || ( ( ((const U8*)s)[1] & 0xFD ) == 0x54 ) || ((const U8*)s)[1] == 0x58 || ((const U8*)s)[1] == 0x62 || ( ( ((const U8*)s)[1] & 0xFD ) == 0x64 ) || ( ( ((const U8*)s)[1] & 0xFD ) == 0x68 ) || ( ( ((const U8*)s)[1] & 0xFD ) == 0x71 ) ) && ( 0x73 == ((const U8*)s)[2] ) ) && ( 0x73 == ((const U8*)s)[3] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[4], 0x72, 0x73) ) ) ? 5 : 0 )\
+       : ( ( ( ( ( 0xEE == ((const U8*)s)[0] ) && ( 0x42 == ((const U8*)s)[1] ) ) && ( 0x73 == ((const U8*)s)[2] ) ) && ( 0x73 == ((const U8*)s)[3] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[4], 0x72, 0x73) ) ) ? 5 : 0 ) : 0 )
 
 /*
        SURROGATE: Surrogate code points
 */
 /*** GENERATED CODE ***/
 #define is_SURROGATE_utf8_safe(s,e)                                         \
-( ( ( ( ( ( ((e) - (s)) >= 4 ) && ( 0xDD == ((const U8*)s)[0] ) ) && ( inRANGE(((const U8*)s)[1], 0x65, 0x66) ) ) && ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x59) || inRANGE(((const U8*)s)[2], 0x62, 0x6A) || inRANGE(((const U8*)s)[2], 0x70, 0x73) ) ) && ( inRANGE(((const U8*)s)[3], 0x41, 0x4A) || inRANGE(((const U8*)s)[3], 0x51, 0x59) || inRANGE(((const U8*)s)[3], 0x62, 0x6A) || inRANGE(((const U8*)s)[3], 0x70, 0x73) ) ) ? 4 : 0 )
+( ( ( ( ( ( ((e) - (s)) >= 4 ) && ( 0xDD == ((const U8*)s)[0] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x65, 0x66) ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x59) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x70, 0x73) ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[3], 0x51, 0x59) || inRANGE_helper_(U8, ((const U8*)s)[3], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[3], 0x70, 0x73) ) ) ? 4 : 0 )
 
 /*
        QUOTEMETA: Meta-characters that \Q should quote
        \p{_Perl_Quotemeta}
 */
 /*** GENERATED CODE ***/
-#define is_QUOTEMETA_high(s)                                                \
-( ( 0xB1 == ((const U8*)s)[0] ) ?                                           \
-    ( ( 0x56 == ((const U8*)s)[1] ) ? 2 : 0 )                               \
-: ( 0xB8 == ((const U8*)s)[0] ) ?                                           \
-    ( ( ( 0x57 == ((const U8*)s)[1] ) && ( 0x70 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
-: ( 0xBB == ((const U8*)s)[0] ) ?                                           \
-    ( ( 0x51 == ((const U8*)s)[1] ) ?                                       \
-       ( ( 0x73 == ((const U8*)s)[2] ) ? 3 : 0 )                           \
-    : ( ( 0x52 == ((const U8*)s)[1] ) && ( 0x41 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
-: ( 0xBC == ((const U8*)s)[0] ) ?                                           \
-    ( ( 0x63 == ((const U8*)s)[1] ) ?                                       \
+#define is_QUOTEMETA_high_part0(s)                                          \
+( ( 0x63 == ((const U8*)s)[1] ) ?                                           \
        ( ( 0x41 == ((const U8*)s)[2] ) ? 3 : 0 )                           \
-    : ( ( 0x71 == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x63, 0x64) ) ) ? 3 : 0 )\
-: ( 0xBE == ((const U8*)s)[0] ) ?                                           \
-    ( ( ( 0x41 == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x52, 0x55) ) ) ? 3 : 0 )\
+    : ( ( 0x71 == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x63, 0x64) ) ) ? 3 : 0 )
+
+
+/*** GENERATED CODE ***/
+#define is_QUOTEMETA_high_part1(s)                                          \
+( ( 0xBE == ((const U8*)s)[0] ) ?                                           \
+    ( ( ( 0x41 == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x52, 0x55) ) ) ? 3 : 0 )\
 : ( 0xCA == ((const U8*)s)[0] ) ?                                           \
-    ( ( 0x41 == ((const U8*)s)[1] || inRANGE(((const U8*)s)[1], 0x54, 0x59) || inRANGE(((const U8*)s)[1], 0x62, 0x6A) || inRANGE(((const U8*)s)[1], 0x70, 0x73) ) ?\
-       ( ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x59) || inRANGE(((const U8*)s)[2], 0x62, 0x6A) || inRANGE(((const U8*)s)[2], 0x70, 0x73) ) ? 3 : 0 )\
+    ( ( 0x41 == ((const U8*)s)[1] || inRANGE_helper_(U8, ((const U8*)s)[1], 0x54, 0x59) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x70, 0x73) ) ?\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x59) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x70, 0x73) ) ? 3 : 0 )\
     : ( 0x42 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x59) || inRANGE(((const U8*)s)[2], 0x62, 0x6A) || inRANGE(((const U8*)s)[2], 0x70, 0x72) ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x59) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x70, 0x72) ) ? 3 : 0 )\
     : ( 0x43 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x42, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x59) || 0x62 == ((const U8*)s)[2] || inRANGE(((const U8*)s)[2], 0x64, 0x6A) || inRANGE(((const U8*)s)[2], 0x70, 0x73) ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x42, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x59) || 0x62 == ((const U8*)s)[2] || inRANGE_helper_(U8, ((const U8*)s)[2], 0x64, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x70, 0x73) ) ? 3 : 0 )\
     : ( 0x44 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x56) ) ? 3 : 0 )\
-    : ( ( 0x53 == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x57, 0x59) || inRANGE(((const U8*)s)[2], 0x62, 0x6A) || inRANGE(((const U8*)s)[2], 0x70, 0x73) ) ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x56) ) ? 3 : 0 )\
+    : ( ( 0x53 == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x57, 0x59) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x70, 0x73) ) ) ? 3 : 0 )\
 : ( 0xCB == ((const U8*)s)[0] ) ?                                           \
-    ( ( inRANGE(((const U8*)s)[1], 0x41, 0x43) || inRANGE(((const U8*)s)[1], 0x49, 0x4A) || inRANGE(((const U8*)s)[1], 0x51, 0x59) || inRANGE(((const U8*)s)[1], 0x62, 0x69) || inRANGE(((const U8*)s)[1], 0x71, 0x73) ) ?\
-       ( ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x59) || inRANGE(((const U8*)s)[2], 0x62, 0x6A) || inRANGE(((const U8*)s)[2], 0x70, 0x73) ) ? 3 : 0 )\
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x41, 0x43) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x49, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x51, 0x59) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x62, 0x69) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x71, 0x73) ) ?\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x59) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x70, 0x73) ) ? 3 : 0 )\
     : ( 0x6A == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x59) || inRANGE(((const U8*)s)[2], 0x62, 0x64) ) ? 3 : 0 )\
-    : ( ( 0x70 == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x63, 0x6A) || inRANGE(((const U8*)s)[2], 0x70, 0x73) ) ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x59) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x64) ) ? 3 : 0 )\
+    : ( ( 0x70 == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x63, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x70, 0x73) ) ) ? 3 : 0 )\
 : ( 0xCC == ((const U8*)s)[0] ) ?                                           \
-    ( ( ( inRANGE(((const U8*)s)[1], 0x41, 0x4A) || inRANGE(((const U8*)s)[1], 0x51, 0x59) || inRANGE(((const U8*)s)[1], 0x62, 0x6A) || inRANGE(((const U8*)s)[1], 0x70, 0x73) ) && ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x59) || inRANGE(((const U8*)s)[2], 0x62, 0x6A) || inRANGE(((const U8*)s)[2], 0x70, 0x73) ) ) ? 3 : 0 )\
+    ( ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x51, 0x59) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x70, 0x73) ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x59) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x70, 0x73) ) ) ? 3 : 0 )\
 : ( 0xCD == ((const U8*)s)[0] ) ?                                           \
-    ( ( ( inRANGE(((const U8*)s)[1], 0x57, 0x59) || 0x62 == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x59) || inRANGE(((const U8*)s)[2], 0x62, 0x6A) || inRANGE(((const U8*)s)[2], 0x70, 0x73) ) ) ? 3 : 0 )\
+    ( ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x57, 0x59) || 0x62 == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x59) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x70, 0x73) ) ) ? 3 : 0 )\
 : ( 0xCE == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x41 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x41, 0x44) || inRANGE(((const U8*)s)[2], 0x49, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x59) || inRANGE(((const U8*)s)[2], 0x62, 0x6A) || inRANGE(((const U8*)s)[2], 0x70, 0x73) ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x44) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x49, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x59) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x70, 0x73) ) ? 3 : 0 )\
     : ( 0x42 == ((const U8*)s)[1] ) ?                                       \
        ( ( 0x41 == ((const U8*)s)[2] || 0x57 == ((const U8*)s)[2] ) ? 3 : 0 )\
     : ( ( 0x52 == ((const U8*)s)[1] ) && ( 0x45 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 : ( 0xDD == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x73 == ((const U8*)s)[1] ) ?                                       \
        ( ( 0x4A == ((const U8*)s)[2] ) ?                                   \
-           ( ( inRANGE(((const U8*)s)[3], 0x72, 0x73) ) ? 4 : 0 )          \
+           ( ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x72, 0x73) ) ? 4 : 0 )\
        : ( 0x57 == ((const U8*)s)[2] ) ?                                   \
-           ( ( inRANGE(((const U8*)s)[3], 0x41, 0x4A) || inRANGE(((const U8*)s)[3], 0x51, 0x56) ) ? 4 : 0 )\
+           ( ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[3], 0x51, 0x56) ) ? 4 : 0 )\
        : ( 0x59 == ((const U8*)s)[2] ) ?                                   \
-           ( ( inRANGE(((const U8*)s)[3], 0x46, 0x47) ) ? 4 : 0 )          \
+           ( ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x46, 0x47) ) ? 4 : 0 )\
        : ( 0x66 == ((const U8*)s)[2] ) ?                                   \
            ( ( 0x73 == ((const U8*)s)[3] ) ? 4 : 0 )                       \
        : ( 0x71 == ((const U8*)s)[2] ) ?                                   \
            ( ( 0x41 == ((const U8*)s)[3] ) ? 4 : 0 )                       \
-       : ( ( 0x73 == ((const U8*)s)[2] ) && ( inRANGE(((const U8*)s)[3], 0x57, 0x59) || inRANGE(((const U8*)s)[3], 0x62, 0x67) ) ) ? 4 : 0 )\
+       : ( ( 0x73 == ((const U8*)s)[2] ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x57, 0x59) || inRANGE_helper_(U8, ((const U8*)s)[3], 0x62, 0x67) ) ) ? 4 : 0 )\
     : 0 )                                                                   \
 : ( 0xDF == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x56 == ((const U8*)s)[1] ) ?                                       \
-       ( ( ( 0x46 == ((const U8*)s)[2] ) && ( inRANGE(((const U8*)s)[3], 0x41, 0x44) ) ) ? 4 : 0 )\
-    : ( ( ( 0x63 == ((const U8*)s)[1] ) && ( 0x52 == ((const U8*)s)[2] ) ) && ( inRANGE(((const U8*)s)[3], 0x62, 0x69) ) ) ? 4 : 0 )\
-: ( ( ( ( ( 0xED == ((const U8*)s)[0] ) && ( 0x70 == ((const U8*)s)[1] ) ) && ( inRANGE(((const U8*)s)[2], 0x41, 0x44) ) ) && ( inRANGE(((const U8*)s)[3], 0x41, 0x4A) || inRANGE(((const U8*)s)[3], 0x51, 0x59) || inRANGE(((const U8*)s)[3], 0x62, 0x6A) || inRANGE(((const U8*)s)[3], 0x70, 0x73) ) ) && ( inRANGE(((const U8*)s)[4], 0x41, 0x4A) || inRANGE(((const U8*)s)[4], 0x51, 0x59) || inRANGE(((const U8*)s)[4], 0x62, 0x6A) || inRANGE(((const U8*)s)[4], 0x70, 0x73) ) ) ? 5 : 0 )
+       ( ( ( 0x46 == ((const U8*)s)[2] ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x41, 0x44) ) ) ? 4 : 0 )\
+    : ( ( ( 0x63 == ((const U8*)s)[1] ) && ( 0x52 == ((const U8*)s)[2] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x62, 0x69) ) ) ? 4 : 0 )\
+: ( ( ( ( ( 0xED == ((const U8*)s)[0] ) && ( 0x70 == ((const U8*)s)[1] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x44) ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[3], 0x51, 0x59) || inRANGE_helper_(U8, ((const U8*)s)[3], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[3], 0x70, 0x73) ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[4], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[4], 0x51, 0x59) || inRANGE_helper_(U8, ((const U8*)s)[4], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[4], 0x70, 0x73) ) ) ? 5 : 0 )
+
+
+/*** GENERATED CODE ***/
+#define is_QUOTEMETA_high(s)                                                \
+( ( 0xB1 == ((const U8*)s)[0] ) ?                                           \
+    ( ( 0x56 == ((const U8*)s)[1] ) ? 2 : 0 )                               \
+: ( 0xB8 == ((const U8*)s)[0] ) ?                                           \
+    ( ( ( 0x57 == ((const U8*)s)[1] ) && ( 0x70 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
+: ( 0xBB == ((const U8*)s)[0] ) ?                                           \
+    ( ( 0x51 == ((const U8*)s)[1] ) ?                                       \
+       ( ( 0x73 == ((const U8*)s)[2] ) ? 3 : 0 )                           \
+    : ( ( 0x52 == ((const U8*)s)[1] ) && ( 0x41 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
+: ( 0xBC == ((const U8*)s)[0] ) ? is_QUOTEMETA_high_part0(s) : is_QUOTEMETA_high_part1(s) )
 
 /*
        MULTI_CHAR_FOLD: multi-char strings that are folded to by a single character
 
-       &regcharclass_multi_char_folds::multi_char_folds('u', 'a')
+       %regcharclass_multi_char_folds::multi_char_folds('u', 'a')
 */
 /*** GENERATED CODE ***/
 #define is_MULTI_CHAR_FOLD_utf8_safe_part0(s,e)                             \
-( ( ( 0xB0 == ((const U8*)s)[1] ) && ( 0x58 == ((const U8*)s)[2] ) ) ? 3 : 0 )
+( ( ( 0xAF == ((const U8*)s)[1] ) && ( 0x48 == ((const U8*)s)[2] ) ) ? 3 : 0 )
 
 
 /*** GENERATED CODE ***/
 #define is_MULTI_CHAR_FOLD_utf8_safe_part1(s,e)                             \
-( ( ( ((const U8*)s)[0] & 0xBF ) == 'i' ) ?                                 \
-       ( ( ( 0xAF == ((const U8*)s)[1] ) && ( 0x48 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
-    : ( 0x8F == ((const U8*)s)[0] ) ?                                       \
+( ( 0x8F == ((const U8*)s)[0] ) ?                                           \
        ( ( 0x73 == ((const U8*)s)[1] ) ?                                   \
            ( ( 0x8F == ((const U8*)s)[2] ) ?                               \
                ( ( 0x73 == ((const U8*)s)[3] ) ? 4 : 0 )                   \
            ( ( 0xAF == ((const U8*)s)[2] ) ?                               \
                ( ( 0x49 == ((const U8*)s)[3] ) ?                           \
                    ( ( 0xAF == ((const U8*)s)[4] ) ?                       \
-                       ( ( inRANGE(((const U8*)s)[5], 0x41, 0x42) ) ? 6 : 0 )\
+                       ( ( inRANGE_helper_(U8, ((const U8*)s)[5], 0x41, 0x42) ) ? 6 : 0 )\
                    : ( ( 0xB1 == ((const U8*)s)[4] ) && ( 0x43 == ((const U8*)s)[5] ) ) ? 6 : 0 )\
                : 0 )                                                       \
            : ( ( 0xB1 == ((const U8*)s)[2] ) && ( 0x43 == ((const U8*)s)[3] ) ) ? 4 : 0 )\
            ( ( 0xAF == ((const U8*)s)[2] ) ?                               \
                ( ( 0x49 == ((const U8*)s)[3] ) ?                           \
                    ( ( 0xAF == ((const U8*)s)[4] ) ?                       \
-                       ( ( inRANGE(((const U8*)s)[5], 0x41, 0x42) ) ? 6 : 0 )\
+                       ( ( inRANGE_helper_(U8, ((const U8*)s)[5], 0x41, 0x42) ) ? 6 : 0 )\
                    : ( ( 0xB1 == ((const U8*)s)[4] ) && ( 0x43 == ((const U8*)s)[5] ) ) ? 6 : 0 )\
                : ( 0x62 == ((const U8*)s)[3] ) ?                           \
                    ( ( 0xAF == ((const U8*)s)[4] ) ?                       \
-                       ( ( inRANGE(((const U8*)s)[5], 0x41, 0x42) ) ? 6 : 4 )\
+                       ( ( inRANGE_helper_(U8, ((const U8*)s)[5], 0x41, 0x42) ) ? 6 : 4 )\
                    : ( ( 0xB1 == ((const U8*)s)[4] ) && ( 0x43 == ((const U8*)s)[5] ) ) ? 6 : 4 )\
                : 0 )                                                       \
            : ( ( 0xB1 == ((const U8*)s)[2] ) && ( 0x43 == ((const U8*)s)[3] ) ) ? 4 : 0 )\
            : ( ( ( ( 0x72 == ((const U8*)s)[2] ) && ( 0xB8 == ((const U8*)s)[3] ) ) && ( 0x52 == ((const U8*)s)[4] ) ) && ( 0x65 == ((const U8*)s)[5] ) ) ? 6 : 0 )\
        : 0 )                                                               \
     : ( 0xBF == ((const U8*)s)[0] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[1], 0x67, 0x68) ) ?                      \
-           ( ( ( ( inRANGE(((const U8*)s)[2], 0x41, 0x48) ) && ( 0xB4 == ((const U8*)s)[3] ) ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 5 : 0 )\
-       : ( ( ( ( 0x6A == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x41, 0x48) || 0x57 == ((const U8*)s)[2] || 0x63 == ((const U8*)s)[2] || 0x70 == ((const U8*)s)[2] ) ) && ( 0xB4 == ((const U8*)s)[3] ) ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 5 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x67, 0x68) ) ?          \
+           ( ( ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x48) ) && ( 0xB4 == ((const U8*)s)[3] ) ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 5 : 0 )\
+       : ( ( ( ( 0x6A == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x48) || 0x57 == ((const U8*)s)[2] || 0x63 == ((const U8*)s)[2] || 0x70 == ((const U8*)s)[2] ) ) && ( 0xB4 == ((const U8*)s)[3] ) ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 5 : 0 )\
     : 0 )
 
 
            : ( ( 0xB4 == ((const U8*)s)[2] ) && ( 0x68 == ((const U8*)s)[3] ) ) ? 4 : 0 )\
        : ( ( ( 0x55 == ((const U8*)s)[1] ) && ( 0xB4 == ((const U8*)s)[2] ) ) && ( 0x68 == ((const U8*)s)[3] ) ) ? 4 : 0 )\
     : ( 0xBF == ((const U8*)s)[0] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[1], 0x67, 0x68) ) ?                      \
-           ( ( ( ( inRANGE(((const U8*)s)[2], 0x41, 0x48) ) && ( 0xB4 == ((const U8*)s)[3] ) ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 5 : 0 )\
-       : ( ( ( ( 0x6A == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x41, 0x48) || 0x57 == ((const U8*)s)[2] || 0x63 == ((const U8*)s)[2] || 0x70 == ((const U8*)s)[2] ) ) && ( 0xB4 == ((const U8*)s)[3] ) ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 5 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x67, 0x68) ) ?          \
+           ( ( ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x48) ) && ( 0xB4 == ((const U8*)s)[3] ) ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 5 : 0 )\
+       : ( ( ( ( 0x6A == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x48) || 0x57 == ((const U8*)s)[2] || 0x63 == ((const U8*)s)[2] || 0x70 == ((const U8*)s)[2] ) ) && ( 0xB4 == ((const U8*)s)[3] ) ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 5 : 0 )\
     : 0 )
 
 
        ( ( ( ((const U8*)s)[1] & 0xBF ) == 'f' ) ?                         \
            ( ( ( ( ((const U8*)s)[2] & 0xBF ) == 'i' ) || ( ( ((const U8*)s)[2] & 0xBF ) == 'l' ) ) ? 3 : 2 )\
        : ( ( ( ((const U8*)s)[1] & 0xBF ) == 'i' ) || ( ( ((const U8*)s)[1] & 0xBF ) == 'l' ) ) ? 2 : 0 )\
-    : ( ( ((const U8*)s)[0] & 0xBF ) == 'h' ) ? is_MULTI_CHAR_FOLD_utf8_safe_part0(s,e) : is_MULTI_CHAR_FOLD_utf8_safe_part1(s,e) )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'h' ) ?                             \
+       ( ( ( 0xB0 == ((const U8*)s)[1] ) && ( 0x58 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'i' ) ? is_MULTI_CHAR_FOLD_utf8_safe_part0(s,e) : is_MULTI_CHAR_FOLD_utf8_safe_part1(s,e) )\
 : ((e)-(s) > 4) ? is_MULTI_CHAR_FOLD_utf8_safe_part2(s,e) : is_MULTI_CHAR_FOLD_utf8_safe_part3(s,e) )
 
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part0(s,e)                           \
+( ( 0x52 == ((const U8*)s)[1] ) ?                                           \
+           ( ( 0x46 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( ( 0xB8 == ((const U8*)s)[3] ) && ( 0x53 == ((const U8*)s)[4] ) ) && ( 0x43 == ((const U8*)s)[5] ) ) ? 0x587 : 0 )\
+           : ( 0x63 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB8 == ((const U8*)s)[3] ) && ( 0x52 == ((const U8*)s)[4] ) ) ? ( ( 0x46 == ((const U8*)s)[5] ) ? 0xFB14\
+                       : ( 0x52 == ((const U8*)s)[5] ) ? 0xFB15            \
+                       : ( 0x54 == ((const U8*)s)[5] ) ? 0xFB17            \
+                       : ( 0x65 == ((const U8*)s)[5] ) ? 0xFB13 : 0 ) : 0 )\
+           : ( ( ( ( 0x72 == ((const U8*)s)[2] ) && ( 0xB8 == ((const U8*)s)[3] ) ) && ( 0x52 == ((const U8*)s)[4] ) ) && ( 0x65 == ((const U8*)s)[5] ) ) ? 0xFB16 : 0 )\
+       : 0 )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part1(s,e)                           \
+( ( 0xBF == ((const U8*)s)[0] ) ?                                           \
+       ( ( 0x67 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x41 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F80 : 0 )\
+           : ( 0x42 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F81 : 0 )\
+           : ( 0x43 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F82 : 0 )\
+           : ( 0x44 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F83 : 0 )\
+           : ( 0x45 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F84 : 0 )\
+           : ( 0x46 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F85 : 0 )\
+           : ( 0x47 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F86 : 0 )\
+           : ( ( ( 0x48 == ((const U8*)s)[2] ) && ( 0xB4 == ((const U8*)s)[3] ) ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F87 : 0 )\
+       : ( 0x68 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x41 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F90 : 0 )\
+           : ( 0x42 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F91 : 0 )\
+           : ( 0x43 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F92 : 0 )\
+           : ( 0x44 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F93 : 0 )\
+           : ( 0x45 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F94 : 0 )\
+           : ( 0x46 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F95 : 0 )\
+           : ( 0x47 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F96 : 0 )\
+           : ( ( ( 0x48 == ((const U8*)s)[2] ) && ( 0xB4 == ((const U8*)s)[3] ) ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F97 : 0 )\
+       : ( 0x6A == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x41 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1FA0 : 0 )\
+           : ( 0x42 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1FA1 : 0 )\
+           : ( 0x43 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1FA2 : 0 )\
+           : ( 0x44 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1FA3 : 0 )\
+           : ( 0x45 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1FA4 : 0 )\
+           : ( 0x46 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1FA5 : 0 )\
+           : ( 0x47 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1FA6 : 0 )\
+           : ( 0x48 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1FA7 : 0 )\
+           : ( 0x57 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1FB2 : 0 )\
+           : ( 0x63 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1FC2 : 0 )\
+           : ( ( ( 0x70 == ((const U8*)s)[2] ) && ( 0xB4 == ((const U8*)s)[3] ) ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1FF2 : 0 )\
+       : 0 )                                                               \
+    : 0 )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part2(s,e)                           \
+( ( ( ((const U8*)s)[1] & 0xBF ) == 'f' ) ?                                 \
+           ( ( ( ((const U8*)s)[2] & 0xBF ) == 'i' ) ? 0xFB03              \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 'l' ) ? 0xFB04 : 0xFB00 )   \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'i' ) ? 0xFB01                  \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'l' ) ? 0xFB02 : 0 )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part3(s,e)                           \
+( ( ( ((const U8*)s)[0] & 0xBF ) == 'h' ) ?                                 \
+       ( ( ( 0xB0 == ((const U8*)s)[1] ) && ( 0x58 == ((const U8*)s)[2] ) ) ? 0x1E96 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'i' ) ?                             \
+       ( ( ( 0xAF == ((const U8*)s)[1] ) && ( 0x48 == ((const U8*)s)[2] ) ) ? 0x130 : 0 )\
+    : ( 0x8F == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0x73 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x8F == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x73 == ((const U8*)s)[3] ) ? 0x59 : 0 )                \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 's' ) ? 0x59                \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 't' ) ? 0xFB05 : 0 )        \
+       : 0 )                                                               \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'j' ) ?                             \
+       ( ( ( 0xAF == ((const U8*)s)[1] ) && ( 0x53 == ((const U8*)s)[2] ) ) ? 0x1F0 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 's' ) ?                             \
+       ( ( 0x8F == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x73 == ((const U8*)s)[2] ) ? 0x59 : 0 )                    \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 's' ) ? 0x59                    \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 't' ) ? 0xFB05 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 't' ) ?                             \
+       ( ( ( 0xAF == ((const U8*)s)[1] ) && ( 0x49 == ((const U8*)s)[2] ) ) ? 0x1E97 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'w' ) ?                             \
+       ( ( ( 0xAF == ((const U8*)s)[1] ) && ( 0x51 == ((const U8*)s)[2] ) ) ? 0x1E98 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'y' ) ?                             \
+       ( ( ( 0xAF == ((const U8*)s)[1] ) && ( 0x51 == ((const U8*)s)[2] ) ) ? 0x1E99 : 0 )\
+    : ( 0xAB == ((const U8*)s)[0] ) ?                                       \
+       ( ( ( 0x70 == ((const U8*)s)[1] ) && ( ( ((const U8*)s)[2] & 0xBF ) == 'n' ) ) ? 0x149 : 0 )\
+    : ( 0xB4 == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0x53 == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xB4 == ((const U8*)s)[2] ) && ( 0x68 == ((const U8*)s)[3] ) ) ? 0x1FB4 : 0 )\
+       : ( 0x55 == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xB4 == ((const U8*)s)[2] ) && ( 0x68 == ((const U8*)s)[3] ) ) ? 0x1FC4 : 0 )\
+       : ( 0x58 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xB1 == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x43 == ((const U8*)s)[3] ) ?                           \
+                   ( ( ( 0xB4 == ((const U8*)s)[4] ) && ( 0x68 == ((const U8*)s)[5] ) ) ? 0x1FB7 : 0x1FB6 )\
+               : 0 )                                                       \
+           : ( ( 0xB4 == ((const U8*)s)[2] ) && ( 0x68 == ((const U8*)s)[3] ) ) ? 0x1FB3 : 0 )\
+       : ( 0x66 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xB1 == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x43 == ((const U8*)s)[3] ) ?                           \
+                   ( ( ( 0xB4 == ((const U8*)s)[4] ) && ( 0x68 == ((const U8*)s)[5] ) ) ? 0x1FC7 : 0x1FC6 )\
+               : 0 )                                                       \
+           : ( ( 0xB4 == ((const U8*)s)[2] ) && ( 0x68 == ((const U8*)s)[3] ) ) ? 0x1FC3 : 0 )\
+       : ( 0x68 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xAF == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x49 == ((const U8*)s)[3] ) ?                           \
+                   ( ( 0xAF == ((const U8*)s)[4] ) ?                       \
+                       ( ( 0x41 == ((const U8*)s)[5] ) ? 0x1FD2            \
+                       : ( 0x42 == ((const U8*)s)[5] ) ? 0x390 : 0 )       \
+                   : ( ( 0xB1 == ((const U8*)s)[4] ) && ( 0x43 == ((const U8*)s)[5] ) ) ? 0x1FD7 : 0 )\
+               : 0 )                                                       \
+           : ( ( 0xB1 == ((const U8*)s)[2] ) && ( 0x43 == ((const U8*)s)[3] ) ) ? 0x1FD6 : 0 )\
+       : 0 )                                                               \
+    : ( 0xB5 == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0x42 == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xAF == ((const U8*)s)[2] ) && ( 0x62 == ((const U8*)s)[3] ) ) ? 0x1FE4 : 0 )\
+       : ( 0x46 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xAF == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x49 == ((const U8*)s)[3] ) ?                           \
+                   ( ( 0xAF == ((const U8*)s)[4] ) ?                       \
+                       ( ( 0x41 == ((const U8*)s)[5] ) ? 0x1FE2            \
+                       : ( 0x42 == ((const U8*)s)[5] ) ? 0x3B0 : 0 )       \
+                   : ( ( 0xB1 == ((const U8*)s)[4] ) && ( 0x43 == ((const U8*)s)[5] ) ) ? 0x1FE7 : 0 )\
+               : ( 0x62 == ((const U8*)s)[3] ) ?                           \
+                   ( ( 0xAF == ((const U8*)s)[4] ) ?                       \
+                       ( ( 0x41 == ((const U8*)s)[5] ) ? 0x1F52            \
+                       : ( 0x42 == ((const U8*)s)[5] ) ? 0x1F54 : 0x1F50 ) \
+                   : ( ( 0xB1 == ((const U8*)s)[4] ) && ( 0x43 == ((const U8*)s)[5] ) ) ? 0x1F56 : 0x1F50 )\
+               : 0 )                                                       \
+           : ( ( 0xB1 == ((const U8*)s)[2] ) && ( 0x43 == ((const U8*)s)[3] ) ) ? 0x1FE6 : 0 )\
+       : ( 0x4A == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xB1 == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x43 == ((const U8*)s)[3] ) ?                           \
+                   ( ( ( 0xB4 == ((const U8*)s)[4] ) && ( 0x68 == ((const U8*)s)[5] ) ) ? 0x1FF7 : 0x1FF6 )\
+               : 0 )                                                       \
+           : ( ( 0xB4 == ((const U8*)s)[2] ) && ( 0x68 == ((const U8*)s)[3] ) ) ? 0x1FF3 : 0 )\
+       : ( ( ( 0x55 == ((const U8*)s)[1] ) && ( 0xB4 == ((const U8*)s)[2] ) ) && ( 0x68 == ((const U8*)s)[3] ) ) ? 0x1FF4 : 0 )\
+    : ( 0xB8 == ((const U8*)s)[0] ) ? what_MULTI_CHAR_FOLD_utf8_safe_part0(s,e) : what_MULTI_CHAR_FOLD_utf8_safe_part1(s,e) )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part4(s,e)                           \
+( ( 0x42 == ((const U8*)s)[1] ) ?                                           \
+           ( ( ( 0xAF == ((const U8*)s)[2] ) && ( 0x62 == ((const U8*)s)[3] ) ) ? 0x1FE4 : 0 )\
+       : ( 0x46 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xAF == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x62 == ((const U8*)s)[3] ) ? 0x1F50 : 0 )              \
+           : ( ( 0xB1 == ((const U8*)s)[2] ) && ( 0x43 == ((const U8*)s)[3] ) ) ? 0x1FE6 : 0 )\
+       : ( 0x4A == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xB1 == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x43 == ((const U8*)s)[3] ) ? 0x1FF6 : 0 )              \
+           : ( ( 0xB4 == ((const U8*)s)[2] ) && ( 0x68 == ((const U8*)s)[3] ) ) ? 0x1FF3 : 0 )\
+       : ( ( ( 0x55 == ((const U8*)s)[1] ) && ( 0xB4 == ((const U8*)s)[2] ) ) && ( 0x68 == ((const U8*)s)[3] ) ) ? 0x1FF4 : 0 )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part5(s,e)                           \
+( ( 0xBF == ((const U8*)s)[0] ) ?                                           \
+       ( ( 0x67 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x41 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F80 : 0 )\
+           : ( 0x42 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F81 : 0 )\
+           : ( 0x43 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F82 : 0 )\
+           : ( 0x44 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F83 : 0 )\
+           : ( 0x45 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F84 : 0 )\
+           : ( 0x46 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F85 : 0 )\
+           : ( 0x47 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F86 : 0 )\
+           : ( ( ( 0x48 == ((const U8*)s)[2] ) && ( 0xB4 == ((const U8*)s)[3] ) ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F87 : 0 )\
+       : ( 0x68 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x41 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F90 : 0 )\
+           : ( 0x42 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F91 : 0 )\
+           : ( 0x43 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F92 : 0 )\
+           : ( 0x44 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F93 : 0 )\
+           : ( 0x45 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F94 : 0 )\
+           : ( 0x46 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F95 : 0 )\
+           : ( 0x47 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F96 : 0 )\
+           : ( ( ( 0x48 == ((const U8*)s)[2] ) && ( 0xB4 == ((const U8*)s)[3] ) ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1F97 : 0 )\
+       : ( 0x6A == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x41 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1FA0 : 0 )\
+           : ( 0x42 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1FA1 : 0 )\
+           : ( 0x43 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1FA2 : 0 )\
+           : ( 0x44 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1FA3 : 0 )\
+           : ( 0x45 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1FA4 : 0 )\
+           : ( 0x46 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1FA5 : 0 )\
+           : ( 0x47 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1FA6 : 0 )\
+           : ( 0x48 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1FA7 : 0 )\
+           : ( 0x57 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1FB2 : 0 )\
+           : ( 0x63 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB4 == ((const U8*)s)[3] ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1FC2 : 0 )\
+           : ( ( ( 0x70 == ((const U8*)s)[2] ) && ( 0xB4 == ((const U8*)s)[3] ) ) && ( 0x68 == ((const U8*)s)[4] ) ) ? 0x1FF2 : 0 )\
+       : 0 )                                                               \
+    : 0 )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part6(s,e)                           \
+( ( ( ((const U8*)s)[0] & 0xBF ) == 'a' ) ?                                 \
+       ( ( ( 0xAB == ((const U8*)s)[1] ) && ( 0x72 == ((const U8*)s)[2] ) ) ? 0x1E9A : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'f' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xBF ) == 'f' ) ?                         \
+           ( ( ( ((const U8*)s)[2] & 0xBF ) == 'i' ) ? 0xFB03              \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 'l' ) ? 0xFB04 : 0xFB00 )   \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'i' ) ? 0xFB01                  \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'l' ) ? 0xFB02 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'h' ) ?                             \
+       ( ( ( 0xB0 == ((const U8*)s)[1] ) && ( 0x58 == ((const U8*)s)[2] ) ) ? 0x1E96 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'i' ) ?                             \
+       ( ( ( 0xAF == ((const U8*)s)[1] ) && ( 0x48 == ((const U8*)s)[2] ) ) ? 0x130 : 0 )\
+    : ( 0x8F == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0x73 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x8F == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x73 == ((const U8*)s)[3] ) ? 0x59 : 0 )                \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 's' ) ? 0x59                \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 't' ) ? 0xFB05 : 0 )        \
+       : 0 )                                                               \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'j' ) ?                             \
+       ( ( ( 0xAF == ((const U8*)s)[1] ) && ( 0x53 == ((const U8*)s)[2] ) ) ? 0x1F0 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 's' ) ?                             \
+       ( ( 0x8F == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x73 == ((const U8*)s)[2] ) ? 0x59 : 0 )                    \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 's' ) ? 0x59                    \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 't' ) ? 0xFB05 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 't' ) ?                             \
+       ( ( ( 0xAF == ((const U8*)s)[1] ) && ( 0x49 == ((const U8*)s)[2] ) ) ? 0x1E97 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'w' ) ?                             \
+       ( ( ( 0xAF == ((const U8*)s)[1] ) && ( 0x51 == ((const U8*)s)[2] ) ) ? 0x1E98 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'y' ) ?                             \
+       ( ( ( 0xAF == ((const U8*)s)[1] ) && ( 0x51 == ((const U8*)s)[2] ) ) ? 0x1E99 : 0 )\
+    : ( 0xAB == ((const U8*)s)[0] ) ?                                       \
+       ( ( ( 0x70 == ((const U8*)s)[1] ) && ( ( ((const U8*)s)[2] & 0xBF ) == 'n' ) ) ? 0x149 : 0 )\
+    : ( 0xB4 == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0x53 == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xB4 == ((const U8*)s)[2] ) && ( 0x68 == ((const U8*)s)[3] ) ) ? 0x1FB4 : 0 )\
+       : ( 0x55 == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xB4 == ((const U8*)s)[2] ) && ( 0x68 == ((const U8*)s)[3] ) ) ? 0x1FC4 : 0 )\
+       : ( 0x58 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xB1 == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x43 == ((const U8*)s)[3] ) ? 0x1FB6 : 0 )              \
+           : ( ( 0xB4 == ((const U8*)s)[2] ) && ( 0x68 == ((const U8*)s)[3] ) ) ? 0x1FB3 : 0 )\
+       : ( 0x66 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xB1 == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x43 == ((const U8*)s)[3] ) ? 0x1FC6 : 0 )              \
+           : ( ( 0xB4 == ((const U8*)s)[2] ) && ( 0x68 == ((const U8*)s)[3] ) ) ? 0x1FC3 : 0 )\
+       : ( ( ( 0x68 == ((const U8*)s)[1] ) && ( 0xB1 == ((const U8*)s)[2] ) ) && ( 0x43 == ((const U8*)s)[3] ) ) ? 0x1FD6 : 0 )\
+    : ( 0xB5 == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0x42 == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xAF == ((const U8*)s)[2] ) && ( 0x62 == ((const U8*)s)[3] ) ) ? 0x1FE4 : 0 )\
+       : ( 0x46 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xAF == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x62 == ((const U8*)s)[3] ) ? 0x1F50 : 0 )              \
+           : ( ( 0xB1 == ((const U8*)s)[2] ) && ( 0x43 == ((const U8*)s)[3] ) ) ? 0x1FE6 : 0 )\
+       : ( 0x4A == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xB1 == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x43 == ((const U8*)s)[3] ) ? 0x1FF6 : 0 )              \
+           : ( ( 0xB4 == ((const U8*)s)[2] ) && ( 0x68 == ((const U8*)s)[3] ) ) ? 0x1FF3 : 0 )\
+       : ( ( ( 0x55 == ((const U8*)s)[1] ) && ( 0xB4 == ((const U8*)s)[2] ) ) && ( 0x68 == ((const U8*)s)[3] ) ) ? 0x1FF4 : 0 )\
+    : 0 )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part7(s,e)                           \
+( ((e)-(s) > 2) ?                                                           \
+    ( ( ( ((const U8*)s)[0] & 0xBF ) == 'a' ) ?                             \
+       ( ( ( 0xAB == ((const U8*)s)[1] ) && ( 0x72 == ((const U8*)s)[2] ) ) ? 0x1E9A : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'f' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xBF ) == 'f' ) ?                         \
+           ( ( ( ((const U8*)s)[2] & 0xBF ) == 'i' ) ? 0xFB03              \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 'l' ) ? 0xFB04 : 0xFB00 )   \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'i' ) ? 0xFB01                  \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'l' ) ? 0xFB02 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'h' ) ?                             \
+       ( ( ( 0xB0 == ((const U8*)s)[1] ) && ( 0x58 == ((const U8*)s)[2] ) ) ? 0x1E96 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'i' ) ?                             \
+       ( ( ( 0xAF == ((const U8*)s)[1] ) && ( 0x48 == ((const U8*)s)[2] ) ) ? 0x130 : 0 )\
+    : ( 0x8F == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0x73 == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( ((const U8*)s)[2] & 0xBF ) == 's' ) ? 0x59                \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 't' ) ? 0xFB05 : 0 )        \
+       : 0 )                                                               \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'j' ) ?                             \
+       ( ( ( 0xAF == ((const U8*)s)[1] ) && ( 0x53 == ((const U8*)s)[2] ) ) ? 0x1F0 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 's' ) ?                             \
+       ( ( 0x8F == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x73 == ((const U8*)s)[2] ) ? 0x59 : 0 )                    \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 's' ) ? 0x59                    \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 't' ) ? 0xFB05 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 't' ) ?                             \
+       ( ( ( 0xAF == ((const U8*)s)[1] ) && ( 0x49 == ((const U8*)s)[2] ) ) ? 0x1E97 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'w' ) ?                             \
+       ( ( ( 0xAF == ((const U8*)s)[1] ) && ( 0x51 == ((const U8*)s)[2] ) ) ? 0x1E98 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'y' ) ?                             \
+       ( ( ( 0xAF == ((const U8*)s)[1] ) && ( 0x51 == ((const U8*)s)[2] ) ) ? 0x1E99 : 0 )\
+    : ( ( ( 0xAB == ((const U8*)s)[0] ) && ( 0x70 == ((const U8*)s)[1] ) ) && ( ( ((const U8*)s)[2] & 0xBF ) == 'n' ) ) ? 0x149 : 0 )\
+: ((e)-(s) > 1) ?                                                           \
+    ( ( ( ((const U8*)s)[0] & 0xBF ) == 'f' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xBF ) == 'f' ) ? 0xFB00                  \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'i' ) ? 0xFB01                  \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'l' ) ? 0xFB02 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 's' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xBF ) == 's' ) ? 0x59                    \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 't' ) ? 0xFB05 : 0 )            \
+    : 0 )                                                                   \
+: 0 )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe(s,e)                                 \
+( ((e)-(s) > 5) ?                                                           \
+    ( ( ( ((const U8*)s)[0] & 0xBF ) == 'a' ) ?                             \
+       ( ( ( 0xAB == ((const U8*)s)[1] ) && ( 0x72 == ((const U8*)s)[2] ) ) ? 0x1E9A : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'f' ) ? what_MULTI_CHAR_FOLD_utf8_safe_part2(s,e) : what_MULTI_CHAR_FOLD_utf8_safe_part3(s,e) )\
+: ((e)-(s) > 4) ?                                                           \
+    ( ( ( ((const U8*)s)[0] & 0xBF ) == 'a' ) ?                             \
+       ( ( ( 0xAB == ((const U8*)s)[1] ) && ( 0x72 == ((const U8*)s)[2] ) ) ? 0x1E9A : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'f' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xBF ) == 'f' ) ?                         \
+           ( ( ( ((const U8*)s)[2] & 0xBF ) == 'i' ) ? 0xFB03              \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 'l' ) ? 0xFB04 : 0xFB00 )   \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'i' ) ? 0xFB01                  \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'l' ) ? 0xFB02 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'h' ) ?                             \
+       ( ( ( 0xB0 == ((const U8*)s)[1] ) && ( 0x58 == ((const U8*)s)[2] ) ) ? 0x1E96 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'i' ) ?                             \
+       ( ( ( 0xAF == ((const U8*)s)[1] ) && ( 0x48 == ((const U8*)s)[2] ) ) ? 0x130 : 0 )\
+    : ( 0x8F == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0x73 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x8F == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x73 == ((const U8*)s)[3] ) ? 0x59 : 0 )                \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 's' ) ? 0x59                \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 't' ) ? 0xFB05 : 0 )        \
+       : 0 )                                                               \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'j' ) ?                             \
+       ( ( ( 0xAF == ((const U8*)s)[1] ) && ( 0x53 == ((const U8*)s)[2] ) ) ? 0x1F0 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 's' ) ?                             \
+       ( ( 0x8F == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x73 == ((const U8*)s)[2] ) ? 0x59 : 0 )                    \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 's' ) ? 0x59                    \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 't' ) ? 0xFB05 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 't' ) ?                             \
+       ( ( ( 0xAF == ((const U8*)s)[1] ) && ( 0x49 == ((const U8*)s)[2] ) ) ? 0x1E97 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'w' ) ?                             \
+       ( ( ( 0xAF == ((const U8*)s)[1] ) && ( 0x51 == ((const U8*)s)[2] ) ) ? 0x1E98 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'y' ) ?                             \
+       ( ( ( 0xAF == ((const U8*)s)[1] ) && ( 0x51 == ((const U8*)s)[2] ) ) ? 0x1E99 : 0 )\
+    : ( 0xAB == ((const U8*)s)[0] ) ?                                       \
+       ( ( ( 0x70 == ((const U8*)s)[1] ) && ( ( ((const U8*)s)[2] & 0xBF ) == 'n' ) ) ? 0x149 : 0 )\
+    : ( 0xB4 == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0x53 == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xB4 == ((const U8*)s)[2] ) && ( 0x68 == ((const U8*)s)[3] ) ) ? 0x1FB4 : 0 )\
+       : ( 0x55 == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xB4 == ((const U8*)s)[2] ) && ( 0x68 == ((const U8*)s)[3] ) ) ? 0x1FC4 : 0 )\
+       : ( 0x58 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xB1 == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x43 == ((const U8*)s)[3] ) ? 0x1FB6 : 0 )              \
+           : ( ( 0xB4 == ((const U8*)s)[2] ) && ( 0x68 == ((const U8*)s)[3] ) ) ? 0x1FB3 : 0 )\
+       : ( 0x66 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xB1 == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x43 == ((const U8*)s)[3] ) ? 0x1FC6 : 0 )              \
+           : ( ( 0xB4 == ((const U8*)s)[2] ) && ( 0x68 == ((const U8*)s)[3] ) ) ? 0x1FC3 : 0 )\
+       : ( ( ( 0x68 == ((const U8*)s)[1] ) && ( 0xB1 == ((const U8*)s)[2] ) ) && ( 0x43 == ((const U8*)s)[3] ) ) ? 0x1FD6 : 0 )\
+    : ( 0xB5 == ((const U8*)s)[0] ) ? what_MULTI_CHAR_FOLD_utf8_safe_part4(s,e) : what_MULTI_CHAR_FOLD_utf8_safe_part5(s,e) )\
+: ((e)-(s) > 3) ? what_MULTI_CHAR_FOLD_utf8_safe_part6(s,e) : what_MULTI_CHAR_FOLD_utf8_safe_part7(s,e) )
+
 /*
        MULTI_CHAR_FOLD: multi-char strings that are folded to by a single character
 
-       &regcharclass_multi_char_folds::multi_char_folds('l', 'a')
+       %regcharclass_multi_char_folds::multi_char_folds('l', 'a')
 */
 /*** GENERATED CODE ***/
 #define is_MULTI_CHAR_FOLD_latin1_safe(s,e)                                 \
     : ( ( ( ((const U8*)s)[0] & 0xBF ) == 's' ) && ( ( ((const U8*)s)[1] & 0xBE ) == 's' ) ) ? 2 : 0 )\
 : 0 )
 
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_latin1_safe(s,e)                               \
+( ((e)-(s) > 2) ?                                                           \
+    ( ( ( ((const U8*)s)[0] & 0xBF ) == 'f' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xBF ) == 'f' ) ?                         \
+           ( ( ( ((const U8*)s)[2] & 0xBF ) == 'i' ) ? 0xFB03              \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 'l' ) ? 0xFB04 : 0xFB00 )   \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'i' ) ? 0xFB01                  \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'l' ) ? 0xFB02 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 's' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xBF ) == 's' ) ? 0x59                    \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 't' ) ? 0xFB05 : 0 )            \
+    : 0 )                                                                   \
+: ((e)-(s) > 1) ?                                                           \
+    ( ( ( ((const U8*)s)[0] & 0xBF ) == 'f' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xBF ) == 'f' ) ? 0xFB00                  \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'i' ) ? 0xFB01                  \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'l' ) ? 0xFB02 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 's' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xBF ) == 's' ) ? 0x59                    \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 't' ) ? 0xFB05 : 0 )            \
+    : 0 )                                                                   \
+: 0 )
+
 /*
        THREE_CHAR_FOLD: A three-character multi-char fold
 
-       &regcharclass_multi_char_folds::multi_char_folds('u', '3')
+       %regcharclass_multi_char_folds::multi_char_folds('u', '3')
 */
 /*** GENERATED CODE ***/
 #define is_THREE_CHAR_FOLD_utf8_safe(s,e)                                   \
        ( ( 0x58 == ((const U8*)s)[1] || 0x66 == ((const U8*)s)[1] ) ?      \
            ( ( ( ( ( 0xB1 == ((const U8*)s)[2] ) && ( 0x43 == ((const U8*)s)[3] ) ) && ( 0xB4 == ((const U8*)s)[4] ) ) && ( 0x68 == ((const U8*)s)[5] ) ) ? 6 : 0 )\
        : ( ( ( 0x68 == ((const U8*)s)[1] ) && ( 0xAF == ((const U8*)s)[2] ) ) && ( 0x49 == ((const U8*)s)[3] ) ) ? ( ( 0xAF == ((const U8*)s)[4] ) ?\
-                       ( ( inRANGE(((const U8*)s)[5], 0x41, 0x42) ) ? 6 : 0 )\
+                       ( ( inRANGE_helper_(U8, ((const U8*)s)[5], 0x41, 0x42) ) ? 6 : 0 )\
                    : ( ( 0xB1 == ((const U8*)s)[4] ) && ( 0x43 == ((const U8*)s)[5] ) ) ? 6 : 0 ) : 0 )\
     : ( 0xB5 == ((const U8*)s)[0] ) ?                                       \
        ( ( 0x46 == ((const U8*)s)[1] ) ?                                   \
            ( ( ( 0xAF == ((const U8*)s)[2] ) && ( 0x49 == ((const U8*)s)[3] || 0x62 == ((const U8*)s)[3] ) ) ? ( ( 0xAF == ((const U8*)s)[4] ) ?\
-                       ( ( inRANGE(((const U8*)s)[5], 0x41, 0x42) ) ? 6 : 0 )\
+                       ( ( inRANGE_helper_(U8, ((const U8*)s)[5], 0x41, 0x42) ) ? 6 : 0 )\
                    : ( ( 0xB1 == ((const U8*)s)[4] ) && ( 0x43 == ((const U8*)s)[5] ) ) ? 6 : 0 ) : 0 )\
        : ( ( ( ( ( 0x4A == ((const U8*)s)[1] ) && ( 0xB1 == ((const U8*)s)[2] ) ) && ( 0x43 == ((const U8*)s)[3] ) ) && ( 0xB4 == ((const U8*)s)[4] ) ) && ( 0x68 == ((const U8*)s)[5] ) ) ? 6 : 0 )\
     : 0 )                                                                   \
 /*
        THREE_CHAR_FOLD: A three-character multi-char fold
 
-       &regcharclass_multi_char_folds::multi_char_folds('l', '3')
+       %regcharclass_multi_char_folds::multi_char_folds('l', '3')
 */
 /*** GENERATED CODE ***/
 #define is_THREE_CHAR_FOLD_latin1_safe(s,e)                                 \
 /*
        THREE_CHAR_FOLD_HEAD: The first two of three-character multi-char folds
 
-       &regcharclass_multi_char_folds::multi_char_folds('u', 'h')
+       %regcharclass_multi_char_folds::multi_char_folds('u', 'h')
 */
 /*** GENERATED CODE ***/
 #define is_THREE_CHAR_FOLD_HEAD_utf8_safe(s,e)                              \
     : ( 0xB8 == ((const U8*)s)[0] ) ?                                       \
        ( ( ( 0x52 == ((const U8*)s)[1] ) && ( 0x46 == ((const U8*)s)[2] || 0x63 == ((const U8*)s)[2] || 0x72 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
     : ( 0xBF == ((const U8*)s)[0] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[1], 0x67, 0x68) ) ?                      \
-           ( ( inRANGE(((const U8*)s)[2], 0x41, 0x48) ) ? 3 : 0 )          \
-       : ( ( 0x6A == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x41, 0x48) || 0x57 == ((const U8*)s)[2] || 0x63 == ((const U8*)s)[2] || 0x70 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x67, 0x68) ) ?          \
+           ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x48) ) ? 3 : 0 )\
+       : ( ( 0x6A == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x48) || 0x57 == ((const U8*)s)[2] || 0x63 == ((const U8*)s)[2] || 0x70 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
     : 0 )                                                                   \
 : ((e)-(s) > 2) ?                                                           \
     ( ( ( ( ((const U8*)s)[0] & 0xAF ) == 'a' ) || ( ( ((const U8*)s)[0] & 0xBE ) == 'h' ) || ( ( ((const U8*)s)[0] & 0xBE ) == 's' ) || ( ( ((const U8*)s)[0] & 0xBF ) == 'w' ) || ( ( ((const U8*)s)[0] & 0xBF ) == 'y' ) ) ? 1\
     : ( 0xB8 == ((const U8*)s)[0] ) ?                                       \
        ( ( ( 0x52 == ((const U8*)s)[1] ) && ( 0x46 == ((const U8*)s)[2] || 0x63 == ((const U8*)s)[2] || 0x72 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
     : ( 0xBF == ((const U8*)s)[0] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[1], 0x67, 0x68) ) ?                      \
-           ( ( inRANGE(((const U8*)s)[2], 0x41, 0x48) ) ? 3 : 0 )          \
-       : ( ( 0x6A == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x41, 0x48) || 0x57 == ((const U8*)s)[2] || 0x63 == ((const U8*)s)[2] || 0x70 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x67, 0x68) ) ?          \
+           ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x48) ) ? 3 : 0 )\
+       : ( ( 0x6A == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x48) || 0x57 == ((const U8*)s)[2] || 0x63 == ((const U8*)s)[2] || 0x70 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
     : 0 )                                                                   \
 : ((e)-(s) > 1) ?                                                           \
     ( ( ( ( ((const U8*)s)[0] & 0xAF ) == 'a' ) || ( ( ((const U8*)s)[0] & 0xBE ) == 'h' ) || ( ( ((const U8*)s)[0] & 0xBE ) == 's' ) || ( ( ((const U8*)s)[0] & 0xBF ) == 'w' ) || ( ( ((const U8*)s)[0] & 0xBF ) == 'y' ) ) ? 1\
 /*
        THREE_CHAR_FOLD_HEAD: The first two of three-character multi-char folds
 
-       &regcharclass_multi_char_folds::multi_char_folds('l', 'h')
+       %regcharclass_multi_char_folds::multi_char_folds('l', 'h')
 */
 /*** GENERATED CODE ***/
 #define is_THREE_CHAR_FOLD_HEAD_latin1_safe(s,e)                            \
 #define is_FOLDS_TO_MULTI_utf8(s)                                           \
 ( ( 0x8A == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x73 == ((const U8*)s)[1] ) ? 2 : 0 )                               \
-: ( 0x8D == ((const U8*)s)[0] || 0x9C == ((const U8*)s)[0] || inRANGE(((const U8*)s)[0], 0xB3, 0xB4) ) ?\
+: ( 0x8D == ((const U8*)s)[0] || 0x9C == ((const U8*)s)[0] || inRANGE_helper_(U8, ((const U8*)s)[0], 0xB3, 0xB4) ) ?\
     ( ( 0x57 == ((const U8*)s)[1] ) ? 2 : 0 )                               \
 : ( 0x8E == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x4A == ((const U8*)s)[1] ) ? 2 : 0 )                               \
     ( ( ( 0x53 == ((const U8*)s)[1] ) && ( 0x48 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 : ( 0xBF == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x63 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x65, 0x69) || 0x72 == ((const U8*)s)[2] ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x65, 0x69) || 0x72 == ((const U8*)s)[2] ) ? 3 : 0 )\
     : ( 0x69 == ((const U8*)s)[1] ) ?                                       \
        ( ( 0x57 == ((const U8*)s)[2] || 0x59 == ((const U8*)s)[2] || 0x63 == ((const U8*)s)[2] || 0x65 == ((const U8*)s)[2] ) ? 3 : 0 )\
     : ( 0x70 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x59) || inRANGE(((const U8*)s)[2], 0x62, 0x6A) || inRANGE(((const U8*)s)[2], 0x70, 0x73) ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x59) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x70, 0x73) ) ? 3 : 0 )\
     : ( 0x71 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x56) || 0x59 == ((const U8*)s)[2] || inRANGE(((const U8*)s)[2], 0x62, 0x63) || inRANGE(((const U8*)s)[2], 0x65, 0x66) || 0x70 == ((const U8*)s)[2] ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x56) || 0x59 == ((const U8*)s)[2] || inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x63) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x65, 0x66) || 0x70 == ((const U8*)s)[2] ) ? 3 : 0 )\
     : ( 0x72 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x43, 0x45) || inRANGE(((const U8*)s)[2], 0x47, 0x48) || 0x53 == ((const U8*)s)[2] || 0x59 == ((const U8*)s)[2] || 0x62 == ((const U8*)s)[2] || inRANGE(((const U8*)s)[2], 0x65, 0x66) ) ? 3 : 0 )\
-    : ( ( 0x73 == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x43, 0x45) || inRANGE(((const U8*)s)[2], 0x47, 0x48) || 0x59 == ((const U8*)s)[2] || inRANGE(((const U8*)s)[2], 0x62, 0x63) || inRANGE(((const U8*)s)[2], 0x65, 0x66) || 0x70 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
-: ( ( ( ( 0xDD == ((const U8*)s)[0] ) && ( 0x72 == ((const U8*)s)[1] ) ) && ( 0x67 == ((const U8*)s)[2] ) ) && ( inRANGE(((const U8*)s)[3], 0x41, 0x47) || inRANGE(((const U8*)s)[3], 0x62, 0x66) ) ) ? 4 : 0 )
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x43, 0x45) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x47, 0x48) || 0x53 == ((const U8*)s)[2] || 0x59 == ((const U8*)s)[2] || 0x62 == ((const U8*)s)[2] || inRANGE_helper_(U8, ((const U8*)s)[2], 0x65, 0x66) ) ? 3 : 0 )\
+    : ( ( 0x73 == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x43, 0x45) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x47, 0x48) || 0x59 == ((const U8*)s)[2] || inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x63) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x65, 0x66) || 0x70 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
+: ( ( ( ( 0xDD == ((const U8*)s)[0] ) && ( 0x72 == ((const U8*)s)[1] ) ) && ( 0x67 == ((const U8*)s)[2] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x41, 0x47) || inRANGE_helper_(U8, ((const U8*)s)[3], 0x62, 0x66) ) ) ? 4 : 0 )
 
 /*
        PROBLEMATIC_LOCALE_FOLD: characters whose fold is problematic under locale
 */
 /*** GENERATED CODE ***/
 #define is_PROBLEMATIC_LOCALE_FOLD_utf8(s)                                  \
-( ( ( ((const U8*)s)[0] <= ' ' ) || inRANGE(((const U8*)s)[0], '.', '&') || inRANGE(((const U8*)s)[0], '!', '/') || inRANGE(((const U8*)s)[0], ',', '?') || inRANGE(((const U8*)s)[0], '`', '"') || inRANGE(((const U8*)s)[0], 'a', 'i') || inRANGE(((const U8*)s)[0], 'j', 'r') || inRANGE(((const U8*)s)[0], '~', 'z') || '[' == ((const U8*)s)[0] || ']' == ((const U8*)s)[0] || inRANGE(((const U8*)s)[0], '{', 'I') || inRANGE(((const U8*)s)[0], '}', 'R') || '\\' == ((const U8*)s)[0] || inRANGE(((const U8*)s)[0], 'S', 'Z') || inRANGE(((const U8*)s)[0], '0', '9') || 0xFF == ((const U8*)s)[0] ) ? 1\
-: ( 0x80 == ((const U8*)s)[0] || inRANGE(((const U8*)s)[0], 0x8A, 0x8B) ) ? \
-    ( ( inRANGE(((const U8*)s)[1], 0x41, 0x4A) || inRANGE(((const U8*)s)[1], 0x51, 0x59) || inRANGE(((const U8*)s)[1], 0x62, 0x6A) || inRANGE(((const U8*)s)[1], 0x70, 0x73) ) ? 2 : 0 )\
+( ( ( ((const U8*)s)[0] <= ' ' ) || inRANGE_helper_(U8, ((const U8*)s)[0], '.', '&') || inRANGE_helper_(U8, ((const U8*)s)[0], '!', '/') || inRANGE_helper_(U8, ((const U8*)s)[0], ',', '?') || inRANGE_helper_(U8, ((const U8*)s)[0], '`', '"') || inRANGE_helper_(U8, ((const U8*)s)[0], 'a', 'i') || inRANGE_helper_(U8, ((const U8*)s)[0], 'j', 'r') || inRANGE_helper_(U8, ((const U8*)s)[0], '~', 'z') || '[' == ((const U8*)s)[0] || ']' == ((const U8*)s)[0] || inRANGE_helper_(U8, ((const U8*)s)[0], '{', 'I') || inRANGE_helper_(U8, ((const U8*)s)[0], '}', 'R') || '\\' == ((const U8*)s)[0] || inRANGE_helper_(U8, ((const U8*)s)[0], 'S', 'Z') || inRANGE_helper_(U8, ((const U8*)s)[0], '0', '9') || 0xFF == ((const U8*)s)[0] ) ? 1\
+: ( 0x80 == ((const U8*)s)[0] || inRANGE_helper_(U8, ((const U8*)s)[0], 0x8A, 0x8B) ) ?\
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x51, 0x59) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x70, 0x73) ) ? 2 : 0 )\
 : ( 0x8D == ((const U8*)s)[0] ) ?                                           \
-    ( ( inRANGE(((const U8*)s)[1], 0x57, 0x58) ) ? 2 : 0 )                  \
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x57, 0x58) ) ? 2 : 0 )      \
 : ( 0x8E == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x4A == ((const U8*)s)[1] ) ? 2 : 0 )                               \
 : ( 0x8F == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x57 == ((const U8*)s)[1] ) ? 2 : 0 )                               \
 : ( 0xAF == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x48 == ((const U8*)s)[1] ) ? 2 : 0 )                               \
-: ( inRANGE(((const U8*)s)[0], 0xB3, 0xB4) ) ?                              \
+: ( inRANGE_helper_(U8, ((const U8*)s)[0], 0xB3, 0xB4) ) ?                  \
     ( ( 0x70 == ((const U8*)s)[1] ) ? 2 : 0 )                               \
 : ( 0xBF == ((const U8*)s)[0] ) ?                                           \
-    ( ( ( 0x63 == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x65, 0x69) || 0x72 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
+    ( ( ( 0x63 == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x65, 0x69) || 0x72 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 : ( 0xCA == ((const U8*)s)[0] ) ?                                           \
-    ( ( ( 0x4A == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x51, 0x52) ) ) ? 3 : 0 )\
-: ( ( ( ( 0xDD == ((const U8*)s)[0] ) && ( 0x72 == ((const U8*)s)[1] ) ) && ( 0x67 == ((const U8*)s)[2] ) ) && ( inRANGE(((const U8*)s)[3], 0x41, 0x47) ) ) ? 4 : 0 )
+    ( ( ( 0x4A == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x52) ) ) ? 3 : 0 )\
+: ( ( ( ( 0xDD == ((const U8*)s)[0] ) && ( 0x72 == ((const U8*)s)[1] ) ) && ( 0x67 == ((const U8*)s)[2] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x41, 0x47) ) ) ? 4 : 0 )
 
 /*** GENERATED CODE ***/
 #define is_PROBLEMATIC_LOCALE_FOLD_cp(cp)                                   \
 ( cp <= 0xFF || ( 0xFF < cp &&                                              \
-( 0x130 == cp || ( 0x130 < cp &&                                            \
-( 0x131 == cp || ( 0x131 < cp &&                                            \
+( inRANGE_helper_(UV, cp, 0x130, 0x131) || ( 0x131 < cp &&                  \
 ( 0x149 == cp || ( 0x149 < cp &&                                            \
 ( 0x178 == cp || ( 0x178 < cp &&                                            \
 ( 0x17F == cp || ( 0x17F < cp &&                                            \
 ( 0x307 == cp || ( 0x307 < cp &&                                            \
 ( 0x39C == cp || ( 0x39C < cp &&                                            \
 ( 0x3BC == cp || ( 0x3BC < cp &&                                            \
-( inRANGE(cp, 0x1E96, 0x1E9A) || ( 0x1E9A < cp &&                           \
+( inRANGE_helper_(UV, cp, 0x1E96, 0x1E9A) || ( 0x1E9A < cp &&               \
 ( 0x1E9E == cp || ( 0x1E9E < cp &&                                          \
-( 0x212A == cp || ( 0x212A < cp &&                                          \
-( 0x212B == cp || inRANGE(cp, 0xFB00, 0xFB06) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )
+( inRANGE_helper_(UV, cp, 0x212A, 0x212B) || inRANGE_helper_(UV, cp, 0xFB00, 0xFB06) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )
 
 /*
        PROBLEMATIC_LOCALE_FOLDEDS_START: The first folded character of folds which are problematic under locale
 */
 /*** GENERATED CODE ***/
 #define is_PROBLEMATIC_LOCALE_FOLDEDS_START_utf8(s)                         \
-( ( ( ((const U8*)s)[0] <= ' ' ) || inRANGE(((const U8*)s)[0], '.', '&') || inRANGE(((const U8*)s)[0], '!', '/') || inRANGE(((const U8*)s)[0], ',', '?') || inRANGE(((const U8*)s)[0], '`', '"') || inRANGE(((const U8*)s)[0], 'a', 'i') || inRANGE(((const U8*)s)[0], 'j', 'r') || inRANGE(((const U8*)s)[0], '~', 'z') || '[' == ((const U8*)s)[0] || ']' == ((const U8*)s)[0] || inRANGE(((const U8*)s)[0], '{', 'I') || inRANGE(((const U8*)s)[0], '}', 'R') || '\\' == ((const U8*)s)[0] || inRANGE(((const U8*)s)[0], 'S', 'Z') || inRANGE(((const U8*)s)[0], '0', '9') || 0xFF == ((const U8*)s)[0] ) ? 1\
-: ( 0x80 == ((const U8*)s)[0] || inRANGE(((const U8*)s)[0], 0x8A, 0x8B) ) ? \
-    ( ( inRANGE(((const U8*)s)[1], 0x41, 0x4A) || inRANGE(((const U8*)s)[1], 0x51, 0x59) || inRANGE(((const U8*)s)[1], 0x62, 0x6A) || inRANGE(((const U8*)s)[1], 0x70, 0x73) ) ? 2 : 0 )\
+( ( ( ((const U8*)s)[0] <= ' ' ) || inRANGE_helper_(U8, ((const U8*)s)[0], '.', '&') || inRANGE_helper_(U8, ((const U8*)s)[0], '!', '/') || inRANGE_helper_(U8, ((const U8*)s)[0], ',', '?') || inRANGE_helper_(U8, ((const U8*)s)[0], '`', '"') || inRANGE_helper_(U8, ((const U8*)s)[0], 'a', 'i') || inRANGE_helper_(U8, ((const U8*)s)[0], 'j', 'r') || inRANGE_helper_(U8, ((const U8*)s)[0], '~', 'z') || '[' == ((const U8*)s)[0] || ']' == ((const U8*)s)[0] || inRANGE_helper_(U8, ((const U8*)s)[0], '{', 'I') || inRANGE_helper_(U8, ((const U8*)s)[0], '}', 'R') || '\\' == ((const U8*)s)[0] || inRANGE_helper_(U8, ((const U8*)s)[0], 'S', 'Z') || inRANGE_helper_(U8, ((const U8*)s)[0], '0', '9') || 0xFF == ((const U8*)s)[0] ) ? 1\
+: ( 0x80 == ((const U8*)s)[0] || inRANGE_helper_(U8, ((const U8*)s)[0], 0x8A, 0x8B) ) ?\
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x51, 0x59) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x70, 0x73) ) ? 2 : 0 )\
 : ( 0x8D == ((const U8*)s)[0] ) ?                                           \
-    ( ( inRANGE(((const U8*)s)[1], 0x57, 0x58) ) ? 2 : 0 )                  \
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x57, 0x58) ) ? 2 : 0 )      \
 : ( 0x8E == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x4A == ((const U8*)s)[1] ) ? 2 : 0 )                               \
 : ( 0x8F == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x67 == ((const U8*)s)[1] || 0x73 == ((const U8*)s)[1] ) ? 2 : 0 )  \
 : ( 0x9C == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x57 == ((const U8*)s)[1] ) ? 2 : 0 )                               \
-: ( 0xAB == ((const U8*)s)[0] || inRANGE(((const U8*)s)[0], 0xB3, 0xB4) ) ? \
+: ( 0xAB == ((const U8*)s)[0] || inRANGE_helper_(U8, ((const U8*)s)[0], 0xB3, 0xB4) ) ?\
     ( ( 0x70 == ((const U8*)s)[1] ) ? 2 : 0 )                               \
 : ( 0xBF == ((const U8*)s)[0] ) ?                                           \
-    ( ( ( 0x63 == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x65, 0x69) || 0x72 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
+    ( ( ( 0x63 == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x65, 0x69) || 0x72 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 : ( 0xCA == ((const U8*)s)[0] ) ?                                           \
-    ( ( ( 0x4A == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x51, 0x52) ) ) ? 3 : 0 )\
-: ( ( ( ( 0xDD == ((const U8*)s)[0] ) && ( 0x72 == ((const U8*)s)[1] ) ) && ( 0x67 == ((const U8*)s)[2] ) ) && ( inRANGE(((const U8*)s)[3], 0x41, 0x47) ) ) ? 4 : 0 )
+    ( ( ( 0x4A == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x52) ) ) ? 3 : 0 )\
+: ( ( ( ( 0xDD == ((const U8*)s)[0] ) && ( 0x72 == ((const U8*)s)[1] ) ) && ( 0x67 == ((const U8*)s)[2] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x41, 0x47) ) ) ? 4 : 0 )
 
 /*** GENERATED CODE ***/
 #define is_PROBLEMATIC_LOCALE_FOLDEDS_START_cp(cp)                          \
 ( cp <= 0xFF || ( 0xFF < cp &&                                              \
-( 0x130 == cp || ( 0x130 < cp &&                                            \
-( 0x131 == cp || ( 0x131 < cp &&                                            \
+( inRANGE_helper_(UV, cp, 0x130, 0x131) || ( 0x131 < cp &&                  \
 ( 0x149 == cp || ( 0x149 < cp &&                                            \
 ( 0x178 == cp || ( 0x178 < cp &&                                            \
 ( 0x17F == cp || ( 0x17F < cp &&                                            \
 ( 0x2BC == cp || ( 0x2BC < cp &&                                            \
 ( 0x39C == cp || ( 0x39C < cp &&                                            \
 ( 0x3BC == cp || ( 0x3BC < cp &&                                            \
-( inRANGE(cp, 0x1E96, 0x1E9A) || ( 0x1E9A < cp &&                           \
+( inRANGE_helper_(UV, cp, 0x1E96, 0x1E9A) || ( 0x1E9A < cp &&               \
 ( 0x1E9E == cp || ( 0x1E9E < cp &&                                          \
-( 0x212A == cp || ( 0x212A < cp &&                                          \
-( 0x212B == cp || inRANGE(cp, 0xFB00, 0xFB06) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )
+( inRANGE_helper_(UV, cp, 0x212A, 0x212B) || inRANGE_helper_(UV, cp, 0xFB00, 0xFB06) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )
 
 /*
        PATWS: pattern white space
 /*** GENERATED CODE ***/
 #define is_PATWS_safe(s,e,is_utf8)                                          \
 ( ( LIKELY((e) > (s)) ) ?                                                   \
-    ( ( '\t' == ((const U8*)s)[0] || inRANGE(((const U8*)s)[0], '\v', '\r') || '\n' == ((const U8*)s)[0] || 0x25 == ((const U8*)s)[0] || ' ' == ((const U8*)s)[0] ) ? 1\
+    ( ( '\t' == ((const U8*)s)[0] || inRANGE_helper_(U8, ((const U8*)s)[0], '\v', '\r') || '\n' == ((const U8*)s)[0] || 0x25 == ((const U8*)s)[0] || ' ' == ((const U8*)s)[0] ) ? 1\
     : ( ( is_utf8 && LIKELY(((e) - (s)) >= UTF8SKIP(s)) ) && ( 0xCA == ((const U8*)s)[0] ) ) ? ( ( 0x41 == ((const U8*)s)[1] ) ?\
-                   ( ( inRANGE(((const U8*)s)[2], 0x55, 0x56) ) ? 3 : 0 )  \
-               : ( ( 0x42 == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x49, 0x4A) ) ) ? 3 : 0 ) : 0 )\
+                   ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x55, 0x56) ) ? 3 : 0 )\
+               : ( ( 0x42 == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x49, 0x4A) ) ) ? 3 : 0 ) : 0 )\
 : 0 )
 
 #endif /* EBCDIC 1047 */
 /*** GENERATED CODE ***/
 #define is_LNBREAK_safe(s,e,is_utf8)                                        \
 ( ((e)-(s) > 2) ?                                                           \
-    ( ( inRANGE(((const U8*)s)[0], '\v', '\f') || 0x15 == ((const U8*)s)[0] || '\n' == ((const U8*)s)[0] ) ? 1\
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[0], '\v', '\f') || 0x15 == ((const U8*)s)[0] || '\n' == ((const U8*)s)[0] ) ? 1\
     : ( '\r' == ((const U8*)s)[0] ) ?                                       \
        ( ( '\n' == ((const U8*)s)[1] ) ? 2 : 1 )                           \
-    : ( ( ( ( is_utf8 ) && ( 0xCA == ((const U8*)s)[0] ) ) && ( 0x42 == ((const U8*)s)[1] ) ) && ( inRANGE(((const U8*)s)[2], 0x49, 0x4A) ) ) ? 3 : 0 )\
+    : ( ( ( ( is_utf8 ) && ( 0xCA == ((const U8*)s)[0] ) ) && ( 0x42 == ((const U8*)s)[1] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x49, 0x4A) ) ) ? 3 : 0 )\
 : ((e)-(s) > 1) ?                                                           \
-    ( ( inRANGE(((const U8*)s)[0], '\v', '\f') || 0x15 == ((const U8*)s)[0] || '\n' == ((const U8*)s)[0] ) ? 1\
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[0], '\v', '\f') || 0x15 == ((const U8*)s)[0] || '\n' == ((const U8*)s)[0] ) ? 1\
     : ( '\r' == ((const U8*)s)[0] ) ?                                       \
        ( ( '\n' == ((const U8*)s)[1] ) ? 2 : 1 )                           \
     : 0 )                                                                   \
 : ((e)-(s) > 0) ?                                                           \
-    ( inRANGE(((const U8*)s)[0], '\v', '\r') || 0x15 == ((const U8*)s)[0] || '\n' == ((const U8*)s)[0] )\
+    ( inRANGE_helper_(U8, ((const U8*)s)[0], '\v', '\r') || 0x15 == ((const U8*)s)[0] || '\n' == ((const U8*)s)[0] )\
 : 0 )
 
 /*** GENERATED CODE ***/
 #define is_LNBREAK_utf8_safe(s,e)                                           \
 ( ((e)-(s) > 2) ?                                                           \
-    ( ( inRANGE(((const U8*)s)[0], '\v', '\f') || 0x15 == ((const U8*)s)[0] || '\n' == ((const U8*)s)[0] ) ? 1\
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[0], '\v', '\f') || 0x15 == ((const U8*)s)[0] || '\n' == ((const U8*)s)[0] ) ? 1\
     : ( '\r' == ((const U8*)s)[0] ) ?                                       \
        ( ( '\n' == ((const U8*)s)[1] ) ? 2 : 1 )                           \
-    : ( ( ( 0xCA == ((const U8*)s)[0] ) && ( 0x42 == ((const U8*)s)[1] ) ) && ( inRANGE(((const U8*)s)[2], 0x49, 0x4A) ) ) ? 3 : 0 )\
+    : ( ( ( 0xCA == ((const U8*)s)[0] ) && ( 0x42 == ((const U8*)s)[1] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x49, 0x4A) ) ) ? 3 : 0 )\
 : ((e)-(s) > 1) ?                                                           \
-    ( ( inRANGE(((const U8*)s)[0], '\v', '\f') || 0x15 == ((const U8*)s)[0] || '\n' == ((const U8*)s)[0] ) ? 1\
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[0], '\v', '\f') || 0x15 == ((const U8*)s)[0] || '\n' == ((const U8*)s)[0] ) ? 1\
     : ( '\r' == ((const U8*)s)[0] ) ?                                       \
        ( ( '\n' == ((const U8*)s)[1] ) ? 2 : 1 )                           \
     : 0 )                                                                   \
 : ((e)-(s) > 0) ?                                                           \
-    ( inRANGE(((const U8*)s)[0], '\v', '\r') || 0x15 == ((const U8*)s)[0] || '\n' == ((const U8*)s)[0] )\
+    ( inRANGE_helper_(U8, ((const U8*)s)[0], '\v', '\r') || 0x15 == ((const U8*)s)[0] || '\n' == ((const U8*)s)[0] )\
 : 0 )
 
 /*** GENERATED CODE ***/
 #define is_LNBREAK_latin1_safe(s,e)                                         \
 ( ((e)-(s) > 1) ?                                                           \
-    ( ( inRANGE(((const U8*)s)[0], '\v', '\f') || 0x15 == ((const U8*)s)[0] || '\n' == ((const U8*)s)[0] ) ? 1\
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[0], '\v', '\f') || 0x15 == ((const U8*)s)[0] || '\n' == ((const U8*)s)[0] ) ? 1\
     : ( '\r' == ((const U8*)s)[0] ) ?                                       \
        ( ( '\n' == ((const U8*)s)[1] ) ? 2 : 1 )                           \
     : 0 )                                                                   \
 : ((e)-(s) > 0) ?                                                           \
-    ( inRANGE(((const U8*)s)[0], '\v', '\r') || 0x15 == ((const U8*)s)[0] || '\n' == ((const U8*)s)[0] )\
+    ( inRANGE_helper_(U8, ((const U8*)s)[0], '\v', '\r') || 0x15 == ((const U8*)s)[0] || '\n' == ((const U8*)s)[0] )\
 : 0 )
 
 /*
     ( ( ( 0x62 == ((const U8*)s)[1] ) && ( 0x41 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 : ( 0xCA == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x41 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || 0x51 == ((const U8*)s)[2] ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || 0x51 == ((const U8*)s)[2] ) ? 3 : 0 )\
     : ( 0x42 == ((const U8*)s)[1] ) ?                                       \
        ( ( 0x56 == ((const U8*)s)[2] ) ? 3 : 0 )                           \
     : ( ( 0x43 == ((const U8*)s)[1] ) && ( 0x72 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 /*** GENERATED CODE ***/
 #define is_HORIZWS_cp_high(cp)                                              \
 ( 0x1680 == cp || ( 0x1680 < cp &&                                          \
-( inRANGE(cp, 0x2000, 0x200A) || ( 0x200A < cp &&                           \
+( inRANGE_helper_(UV, cp, 0x2000, 0x200A) || ( 0x200A < cp &&               \
 ( 0x202F == cp || ( 0x202F < cp &&                                          \
 ( 0x205F == cp || 0x3000 == cp ) ) ) ) ) ) )
 
 */
 /*** GENERATED CODE ***/
 #define is_VERTWS_high(s)                                                   \
-( ( ( ( 0xCA == ((const U8*)s)[0] ) && ( 0x42 == ((const U8*)s)[1] ) ) && ( inRANGE(((const U8*)s)[2], 0x49, 0x4A) ) ) ? 3 : 0 )
+( ( ( ( 0xCA == ((const U8*)s)[0] ) && ( 0x42 == ((const U8*)s)[1] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x49, 0x4A) ) ) ? 3 : 0 )
 
 /*** GENERATED CODE ***/
 #define is_VERTWS_cp_high(cp)                                               \
-( 0x2028 == cp || 0x2029 == cp )
+( inRANGE_helper_(UV, cp, 0x2028, 0x2029) )
 
 /*
        XDIGIT: Hexadecimal digits
 /*** GENERATED CODE ***/
 #define is_XDIGIT_high(s)                                                   \
 ( ( ( 0xDD == ((const U8*)s)[0] ) && ( 0x72 == ((const U8*)s)[1] ) ) ? ( ( 0x66 == ((const U8*)s)[2] ) ?\
-           ( ( inRANGE(((const U8*)s)[3], 0x57, 0x59) || 0x5F == ((const U8*)s)[3] || inRANGE(((const U8*)s)[3], 0x62, 0x67) ) ? 4 : 0 )\
-       : ( ( inRANGE(((const U8*)s)[2], 0x67, 0x68) ) && ( inRANGE(((const U8*)s)[3], 0x42, 0x47) ) ) ? 4 : 0 ) : 0 )
+           ( ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x57, 0x59) || 0x5F == ((const U8*)s)[3] || inRANGE_helper_(U8, ((const U8*)s)[3], 0x62, 0x67) ) ? 4 : 0 )\
+       : ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x67, 0x68) ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x42, 0x47) ) ) ? 4 : 0 ) : 0 )
 
 /*** GENERATED CODE ***/
 #define is_XDIGIT_cp_high(cp)                                               \
-( inRANGE(cp, 0xFF10, 0xFF19) || ( 0xFF19 < cp &&                           \
-( inRANGE(cp, 0xFF21, 0xFF26) || inRANGE(cp, 0xFF41, 0xFF46) ) ) )
+( inRANGE_helper_(UV, cp, 0xFF10, 0xFF19) || ( 0xFF19 < cp &&               \
+( inRANGE_helper_(UV, cp, 0xFF21, 0xFF26) || inRANGE_helper_(UV, cp, 0xFF41, 0xFF46) ) ) )
 
 /*
        XPERLSPACE: \p{XPerlSpace}
     ( ( ( 0x62 == ((const U8*)s)[1] ) && ( 0x41 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 : ( 0xCA == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x41 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || 0x51 == ((const U8*)s)[2] ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || 0x51 == ((const U8*)s)[2] ) ? 3 : 0 )\
     : ( 0x42 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x49, 0x4A) || 0x56 == ((const U8*)s)[2] ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x49, 0x4A) || 0x56 == ((const U8*)s)[2] ) ? 3 : 0 )\
     : ( ( 0x43 == ((const U8*)s)[1] ) && ( 0x72 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 : ( ( ( 0xCE == ((const U8*)s)[0] ) && ( 0x41 == ((const U8*)s)[1] ) ) && ( 0x41 == ((const U8*)s)[2] ) ) ? 3 : 0 )
 
 /*** GENERATED CODE ***/
 #define is_XPERLSPACE_cp_high(cp)                                           \
 ( 0x1680 == cp || ( 0x1680 < cp &&                                          \
-( inRANGE(cp, 0x2000, 0x200A) || ( 0x200A < cp &&                           \
-( 0x2028 == cp || ( 0x2028 < cp &&                                          \
-( 0x2029 == cp || ( 0x2029 < cp &&                                          \
+( inRANGE_helper_(UV, cp, 0x2000, 0x200A) || ( 0x200A < cp &&               \
+( inRANGE_helper_(UV, cp, 0x2028, 0x2029) || ( 0x2029 < cp &&               \
 ( 0x202F == cp || ( 0x202F < cp &&                                          \
-( 0x205F == cp || 0x3000 == cp ) ) ) ) ) ) ) ) ) ) )
+( 0x205F == cp || 0x3000 == cp ) ) ) ) ) ) ) ) )
 
 /*
        NONCHAR: Non character code points
 ( ( ( LIKELY((e) > (s)) ) && ( LIKELY(((e) - (s)) >= UTF8SKIP(s)) ) ) ? ( ( 0xDD == ((const U8*)s)[0] ) ?\
            ( ( 0x72 == ((const U8*)s)[1] ) ?                               \
                ( ( 0x55 == ((const U8*)s)[2] ) ?                           \
-                   ( ( inRANGE(((const U8*)s)[3], 0x57, 0x59) || 0x5F == ((const U8*)s)[3] || inRANGE(((const U8*)s)[3], 0x62, 0x6A) || inRANGE(((const U8*)s)[3], 0x70, 0x72) ) ? 4 : 0 )\
+                   ( ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x57, 0x59) || 0x5F == ((const U8*)s)[3] || inRANGE_helper_(U8, ((const U8*)s)[3], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[3], 0x70, 0x72) ) ? 4 : 0 )\
                : ( 0x56 == ((const U8*)s)[2] ) ?                           \
-                   ( ( inRANGE(((const U8*)s)[3], 0x41, 0x4A) || inRANGE(((const U8*)s)[3], 0x51, 0x56) ) ? 4 : 0 )\
-               : ( ( 0x72 == ((const U8*)s)[2] ) && ( inRANGE(((const U8*)s)[3], 0x71, 0x72) ) ) ? 4 : 0 )\
+                   ( ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[3], 0x51, 0x56) ) ? 4 : 0 )\
+               : ( ( 0x72 == ((const U8*)s)[2] ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x71, 0x72) ) ) ? 4 : 0 )\
            : 0 )                                                           \
        : ( 0xDF == ((const U8*)s)[0] || 0xEA == ((const U8*)s)[0] || 0xEC == ((const U8*)s)[0] ) ?\
-           ( ( ( ( 0x72 == ((const U8*)s)[1] ) && ( 0x72 == ((const U8*)s)[2] ) ) && ( inRANGE(((const U8*)s)[3], 0x71, 0x72) ) ) ? 4 : 0 )\
+           ( ( ( ( 0x72 == ((const U8*)s)[1] ) && ( 0x72 == ((const U8*)s)[2] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x71, 0x72) ) ) ? 4 : 0 )\
        : ( 0xED == ((const U8*)s)[0] ) ?                                   \
-           ( ( ( ( ( ((const U8*)s)[1] == 0x4A || ((const U8*)s)[1] == 0x52 || ( ( ((const U8*)s)[1] & 0xFD ) == 0x54 ) || ((const U8*)s)[1] == 0x58 || ((const U8*)s)[1] == 0x5F || ((const U8*)s)[1] == 0x63 || ( ( ((const U8*)s)[1] & 0xFD ) == 0x65 ) || ((const U8*)s)[1] == 0x69 || ( ( ((const U8*)s)[1] & 0xFD ) == 0x70 ) ) && ( 0x72 == ((const U8*)s)[2] ) ) && ( 0x72 == ((const U8*)s)[3] ) ) && ( inRANGE(((const U8*)s)[4], 0x71, 0x72) ) ) ? 5 : 0 )\
-       : ( ( ( ( ( 0xEE == ((const U8*)s)[0] ) && ( 0x42 == ((const U8*)s)[1] ) ) && ( 0x72 == ((const U8*)s)[2] ) ) && ( 0x72 == ((const U8*)s)[3] ) ) && ( inRANGE(((const U8*)s)[4], 0x71, 0x72) ) ) ? 5 : 0 ) : 0 )
+           ( ( ( ( ( ((const U8*)s)[1] == 0x4A || ((const U8*)s)[1] == 0x52 || ( ( ((const U8*)s)[1] & 0xFD ) == 0x54 ) || ((const U8*)s)[1] == 0x58 || ((const U8*)s)[1] == 0x5F || ((const U8*)s)[1] == 0x63 || ( ( ((const U8*)s)[1] & 0xFD ) == 0x65 ) || ((const U8*)s)[1] == 0x69 || ( ( ((const U8*)s)[1] & 0xFD ) == 0x70 ) ) && ( 0x72 == ((const U8*)s)[2] ) ) && ( 0x72 == ((const U8*)s)[3] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[4], 0x71, 0x72) ) ) ? 5 : 0 )\
+       : ( ( ( ( ( 0xEE == ((const U8*)s)[0] ) && ( 0x42 == ((const U8*)s)[1] ) ) && ( 0x72 == ((const U8*)s)[2] ) ) && ( 0x72 == ((const U8*)s)[3] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[4], 0x71, 0x72) ) ) ? 5 : 0 ) : 0 )
 
 /*
        SURROGATE: Surrogate code points
 */
 /*** GENERATED CODE ***/
 #define is_SURROGATE_utf8_safe(s,e)                                         \
-( ( ( ( ( ( ((e) - (s)) >= 4 ) && ( 0xDD == ((const U8*)s)[0] ) ) && ( inRANGE(((const U8*)s)[1], 0x64, 0x65) ) ) && ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x59) || 0x5F == ((const U8*)s)[2] || inRANGE(((const U8*)s)[2], 0x62, 0x6A) || inRANGE(((const U8*)s)[2], 0x70, 0x72) ) ) && ( inRANGE(((const U8*)s)[3], 0x41, 0x4A) || inRANGE(((const U8*)s)[3], 0x51, 0x59) || 0x5F == ((const U8*)s)[3] || inRANGE(((const U8*)s)[3], 0x62, 0x6A) || inRANGE(((const U8*)s)[3], 0x70, 0x72) ) ) ? 4 : 0 )
+( ( ( ( ( ( ((e) - (s)) >= 4 ) && ( 0xDD == ((const U8*)s)[0] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x64, 0x65) ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x59) || 0x5F == ((const U8*)s)[2] || inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x70, 0x72) ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[3], 0x51, 0x59) || 0x5F == ((const U8*)s)[3] || inRANGE_helper_(U8, ((const U8*)s)[3], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[3], 0x70, 0x72) ) ) ? 4 : 0 )
 
 /*
        QUOTEMETA: Meta-characters that \Q should quote
 */
 /*** GENERATED CODE ***/
 #define is_QUOTEMETA_high_part0(s)                                          \
-( ( ( 0x57 == ((const U8*)s)[1] ) && ( 0x6A == ((const U8*)s)[2] ) ) ? 3 : 0 )
+( ( 0x41 == ((const U8*)s)[1] || inRANGE_helper_(U8, ((const U8*)s)[1], 0x54, 0x59) || 0x5F == ((const U8*)s)[1] || inRANGE_helper_(U8, ((const U8*)s)[1], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x70, 0x72) ) ?\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x59) || 0x5F == ((const U8*)s)[2] || inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x70, 0x72) ) ? 3 : 0 )\
+    : ( 0x42 == ((const U8*)s)[1] ) ?                                       \
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x59) || 0x5F == ((const U8*)s)[2] || inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x70, 0x71) ) ? 3 : 0 )\
+    : ( 0x43 == ((const U8*)s)[1] ) ?                                       \
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x42, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x59) || 0x5F == ((const U8*)s)[2] || inRANGE_helper_(U8, ((const U8*)s)[2], 0x63, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x70, 0x72) ) ? 3 : 0 )\
+    : ( 0x44 == ((const U8*)s)[1] ) ?                                       \
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x56) ) ? 3 : 0 )\
+    : ( ( 0x53 == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x57, 0x59) || 0x5F == ((const U8*)s)[2] || inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x70, 0x72) ) ) ? 3 : 0 )
 
 
 /*** GENERATED CODE ***/
 #define is_QUOTEMETA_high_part1(s)                                          \
-( ( 0xBC == ((const U8*)s)[0] ) ?                                           \
-    ( ( 0x51 == ((const U8*)s)[1] ) ?                                       \
-       ( ( 0x72 == ((const U8*)s)[2] ) ? 3 : 0 )                           \
-    : ( ( 0x52 == ((const U8*)s)[1] ) && ( 0x41 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
-: ( 0xBD == ((const U8*)s)[0] ) ?                                           \
-    ( ( 0x62 == ((const U8*)s)[1] ) ?                                       \
-       ( ( 0x41 == ((const U8*)s)[2] ) ? 3 : 0 )                           \
-    : ( ( 0x70 == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x62, 0x63) ) ) ? 3 : 0 )\
-: ( 0xBE == ((const U8*)s)[0] ) ?                                           \
-    ( ( ( 0x41 == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x52, 0x55) ) ) ? 3 : 0 )\
-: ( 0xCA == ((const U8*)s)[0] ) ?                                           \
-    ( ( 0x41 == ((const U8*)s)[1] || inRANGE(((const U8*)s)[1], 0x54, 0x59) || 0x5F == ((const U8*)s)[1] || inRANGE(((const U8*)s)[1], 0x62, 0x6A) || inRANGE(((const U8*)s)[1], 0x70, 0x72) ) ?\
-       ( ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x59) || 0x5F == ((const U8*)s)[2] || inRANGE(((const U8*)s)[2], 0x62, 0x6A) || inRANGE(((const U8*)s)[2], 0x70, 0x72) ) ? 3 : 0 )\
-    : ( 0x42 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x59) || 0x5F == ((const U8*)s)[2] || inRANGE(((const U8*)s)[2], 0x62, 0x6A) || inRANGE(((const U8*)s)[2], 0x70, 0x71) ) ? 3 : 0 )\
-    : ( 0x43 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x42, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x59) || 0x5F == ((const U8*)s)[2] || inRANGE(((const U8*)s)[2], 0x63, 0x6A) || inRANGE(((const U8*)s)[2], 0x70, 0x72) ) ? 3 : 0 )\
-    : ( 0x44 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x56) ) ? 3 : 0 )\
-    : ( ( 0x53 == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x57, 0x59) || 0x5F == ((const U8*)s)[2] || inRANGE(((const U8*)s)[2], 0x62, 0x6A) || inRANGE(((const U8*)s)[2], 0x70, 0x72) ) ) ? 3 : 0 )\
-: ( 0xCB == ((const U8*)s)[0] ) ?                                           \
-    ( ( inRANGE(((const U8*)s)[1], 0x41, 0x43) || inRANGE(((const U8*)s)[1], 0x49, 0x4A) || inRANGE(((const U8*)s)[1], 0x51, 0x59) || 0x5F == ((const U8*)s)[1] || inRANGE(((const U8*)s)[1], 0x62, 0x68) || inRANGE(((const U8*)s)[1], 0x70, 0x72) ) ?\
-       ( ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x59) || 0x5F == ((const U8*)s)[2] || inRANGE(((const U8*)s)[2], 0x62, 0x6A) || inRANGE(((const U8*)s)[2], 0x70, 0x72) ) ? 3 : 0 )\
+( ( 0xCB == ((const U8*)s)[0] ) ?                                           \
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x41, 0x43) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x49, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x51, 0x59) || 0x5F == ((const U8*)s)[1] || inRANGE_helper_(U8, ((const U8*)s)[1], 0x62, 0x68) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x70, 0x72) ) ?\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x59) || 0x5F == ((const U8*)s)[2] || inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x70, 0x72) ) ? 3 : 0 )\
     : ( 0x69 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x59) || 0x5F == ((const U8*)s)[2] || inRANGE(((const U8*)s)[2], 0x62, 0x63) ) ? 3 : 0 )\
-    : ( ( 0x6A == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x62, 0x6A) || inRANGE(((const U8*)s)[2], 0x70, 0x72) ) ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x59) || 0x5F == ((const U8*)s)[2] || inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x63) ) ? 3 : 0 )\
+    : ( ( 0x6A == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x70, 0x72) ) ) ? 3 : 0 )\
 : ( 0xCC == ((const U8*)s)[0] ) ?                                           \
-    ( ( ( inRANGE(((const U8*)s)[1], 0x41, 0x4A) || inRANGE(((const U8*)s)[1], 0x51, 0x59) || 0x5F == ((const U8*)s)[1] || inRANGE(((const U8*)s)[1], 0x62, 0x6A) || inRANGE(((const U8*)s)[1], 0x70, 0x72) ) && ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x59) || 0x5F == ((const U8*)s)[2] || inRANGE(((const U8*)s)[2], 0x62, 0x6A) || inRANGE(((const U8*)s)[2], 0x70, 0x72) ) ) ? 3 : 0 )\
+    ( ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x51, 0x59) || 0x5F == ((const U8*)s)[1] || inRANGE_helper_(U8, ((const U8*)s)[1], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x70, 0x72) ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x59) || 0x5F == ((const U8*)s)[2] || inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x70, 0x72) ) ) ? 3 : 0 )\
 : ( 0xCD == ((const U8*)s)[0] ) ?                                           \
-    ( ( ( inRANGE(((const U8*)s)[1], 0x57, 0x59) || 0x5F == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x59) || 0x5F == ((const U8*)s)[2] || inRANGE(((const U8*)s)[2], 0x62, 0x6A) || inRANGE(((const U8*)s)[2], 0x70, 0x72) ) ) ? 3 : 0 )\
+    ( ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x57, 0x59) || 0x5F == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x59) || 0x5F == ((const U8*)s)[2] || inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x70, 0x72) ) ) ? 3 : 0 )\
 : ( 0xCE == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x41 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x41, 0x44) || inRANGE(((const U8*)s)[2], 0x49, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x59) || 0x5F == ((const U8*)s)[2] || inRANGE(((const U8*)s)[2], 0x62, 0x6A) || inRANGE(((const U8*)s)[2], 0x70, 0x72) ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x44) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x49, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x59) || 0x5F == ((const U8*)s)[2] || inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x70, 0x72) ) ? 3 : 0 )\
     : ( 0x42 == ((const U8*)s)[1] ) ?                                       \
        ( ( 0x41 == ((const U8*)s)[2] || 0x57 == ((const U8*)s)[2] ) ? 3 : 0 )\
     : ( ( 0x52 == ((const U8*)s)[1] ) && ( 0x45 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 : ( 0xDD == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x72 == ((const U8*)s)[1] ) ?                                       \
        ( ( 0x4A == ((const U8*)s)[2] ) ?                                   \
-           ( ( inRANGE(((const U8*)s)[3], 0x71, 0x72) ) ? 4 : 0 )          \
+           ( ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x71, 0x72) ) ? 4 : 0 )\
        : ( 0x57 == ((const U8*)s)[2] ) ?                                   \
-           ( ( inRANGE(((const U8*)s)[3], 0x41, 0x4A) || inRANGE(((const U8*)s)[3], 0x51, 0x56) ) ? 4 : 0 )\
+           ( ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[3], 0x51, 0x56) ) ? 4 : 0 )\
        : ( 0x59 == ((const U8*)s)[2] ) ?                                   \
-           ( ( inRANGE(((const U8*)s)[3], 0x46, 0x47) ) ? 4 : 0 )          \
+           ( ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x46, 0x47) ) ? 4 : 0 )\
        : ( 0x65 == ((const U8*)s)[2] ) ?                                   \
            ( ( 0x72 == ((const U8*)s)[3] ) ? 4 : 0 )                       \
        : ( 0x70 == ((const U8*)s)[2] ) ?                                   \
            ( ( 0x41 == ((const U8*)s)[3] ) ? 4 : 0 )                       \
-       : ( ( 0x72 == ((const U8*)s)[2] ) && ( inRANGE(((const U8*)s)[3], 0x57, 0x59) || 0x5F == ((const U8*)s)[3] || inRANGE(((const U8*)s)[3], 0x62, 0x66) ) ) ? 4 : 0 )\
+       : ( ( 0x72 == ((const U8*)s)[2] ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x57, 0x59) || 0x5F == ((const U8*)s)[3] || inRANGE_helper_(U8, ((const U8*)s)[3], 0x62, 0x66) ) ) ? 4 : 0 )\
     : 0 )                                                                   \
 : ( 0xDF == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x56 == ((const U8*)s)[1] ) ?                                       \
-       ( ( ( 0x46 == ((const U8*)s)[2] ) && ( inRANGE(((const U8*)s)[3], 0x41, 0x44) ) ) ? 4 : 0 )\
-    : ( ( ( 0x62 == ((const U8*)s)[1] ) && ( 0x52 == ((const U8*)s)[2] ) ) && ( 0x5F == ((const U8*)s)[3] || inRANGE(((const U8*)s)[3], 0x62, 0x68) ) ) ? 4 : 0 )\
-: ( ( ( ( ( 0xED == ((const U8*)s)[0] ) && ( 0x6A == ((const U8*)s)[1] ) ) && ( inRANGE(((const U8*)s)[2], 0x41, 0x44) ) ) && ( inRANGE(((const U8*)s)[3], 0x41, 0x4A) || inRANGE(((const U8*)s)[3], 0x51, 0x59) || 0x5F == ((const U8*)s)[3] || inRANGE(((const U8*)s)[3], 0x62, 0x6A) || inRANGE(((const U8*)s)[3], 0x70, 0x72) ) ) && ( inRANGE(((const U8*)s)[4], 0x41, 0x4A) || inRANGE(((const U8*)s)[4], 0x51, 0x59) || 0x5F == ((const U8*)s)[4] || inRANGE(((const U8*)s)[4], 0x62, 0x6A) || inRANGE(((const U8*)s)[4], 0x70, 0x72) ) ) ? 5 : 0 )
+       ( ( ( 0x46 == ((const U8*)s)[2] ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x41, 0x44) ) ) ? 4 : 0 )\
+    : ( ( ( 0x62 == ((const U8*)s)[1] ) && ( 0x52 == ((const U8*)s)[2] ) ) && ( 0x5F == ((const U8*)s)[3] || inRANGE_helper_(U8, ((const U8*)s)[3], 0x62, 0x68) ) ) ? 4 : 0 )\
+: ( ( ( ( ( 0xED == ((const U8*)s)[0] ) && ( 0x6A == ((const U8*)s)[1] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x44) ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[3], 0x51, 0x59) || 0x5F == ((const U8*)s)[3] || inRANGE_helper_(U8, ((const U8*)s)[3], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[3], 0x70, 0x72) ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[4], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[4], 0x51, 0x59) || 0x5F == ((const U8*)s)[4] || inRANGE_helper_(U8, ((const U8*)s)[4], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[4], 0x70, 0x72) ) ) ? 5 : 0 )
 
 
 /*** GENERATED CODE ***/
 #define is_QUOTEMETA_high(s)                                                \
 ( ( 0xAF == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x56 == ((const U8*)s)[1] ) ? 2 : 0 )                               \
-: ( 0xB7 == ((const U8*)s)[0] ) ? is_QUOTEMETA_high_part0(s) : is_QUOTEMETA_high_part1(s) )
+: ( 0xB7 == ((const U8*)s)[0] ) ?                                           \
+    ( ( ( 0x57 == ((const U8*)s)[1] ) && ( 0x6A == ((const U8*)s)[2] ) ) ? 3 : 0 )\
+: ( 0xBC == ((const U8*)s)[0] ) ?                                           \
+    ( ( 0x51 == ((const U8*)s)[1] ) ?                                       \
+       ( ( 0x72 == ((const U8*)s)[2] ) ? 3 : 0 )                           \
+    : ( ( 0x52 == ((const U8*)s)[1] ) && ( 0x41 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
+: ( 0xBD == ((const U8*)s)[0] ) ?                                           \
+    ( ( 0x62 == ((const U8*)s)[1] ) ?                                       \
+       ( ( 0x41 == ((const U8*)s)[2] ) ? 3 : 0 )                           \
+    : ( ( 0x70 == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x63) ) ) ? 3 : 0 )\
+: ( 0xBE == ((const U8*)s)[0] ) ?                                           \
+    ( ( ( 0x41 == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x52, 0x55) ) ) ? 3 : 0 )\
+: ( 0xCA == ((const U8*)s)[0] ) ? is_QUOTEMETA_high_part0(s) : is_QUOTEMETA_high_part1(s) )
 
 /*
        MULTI_CHAR_FOLD: multi-char strings that are folded to by a single character
 
-       &regcharclass_multi_char_folds::multi_char_folds('u', 'a')
+       %regcharclass_multi_char_folds::multi_char_folds('u', 'a')
 */
 /*** GENERATED CODE ***/
 #define is_MULTI_CHAR_FOLD_utf8_safe_part0(s,e)                             \
-( ( ( 0xAE == ((const U8*)s)[1] ) && ( 0x58 == ((const U8*)s)[2] ) ) ? 3 : 0 )
+( ( ( 0xAD == ((const U8*)s)[1] ) && ( 0x48 == ((const U8*)s)[2] ) ) ? 3 : 0 )
 
 
 /*** GENERATED CODE ***/
 #define is_MULTI_CHAR_FOLD_utf8_safe_part1(s,e)                             \
-( ( ( ((const U8*)s)[0] & 0xBF ) == 'i' ) ?                                 \
-       ( ( ( 0xAD == ((const U8*)s)[1] ) && ( 0x48 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
-    : ( 0x8E == ((const U8*)s)[0] ) ?                                       \
+( ( 0x8E == ((const U8*)s)[0] ) ?                                           \
        ( ( 0x72 == ((const U8*)s)[1] ) ?                                   \
            ( ( 0x8E == ((const U8*)s)[2] ) ?                               \
                ( ( 0x72 == ((const U8*)s)[3] ) ? 4 : 0 )                   \
            ( ( 0xAD == ((const U8*)s)[2] ) ?                               \
                ( ( 0x49 == ((const U8*)s)[3] ) ?                           \
                    ( ( 0xAD == ((const U8*)s)[4] ) ?                       \
-                       ( ( inRANGE(((const U8*)s)[5], 0x41, 0x42) ) ? 6 : 0 )\
+                       ( ( inRANGE_helper_(U8, ((const U8*)s)[5], 0x41, 0x42) ) ? 6 : 0 )\
                    : ( ( 0xAF == ((const U8*)s)[4] ) && ( 0x43 == ((const U8*)s)[5] ) ) ? 6 : 0 )\
                : 0 )                                                       \
            : ( ( 0xAF == ((const U8*)s)[2] ) && ( 0x43 == ((const U8*)s)[3] ) ) ? 4 : 0 )\
            ( ( 0xAD == ((const U8*)s)[2] ) ?                               \
                ( ( 0x49 == ((const U8*)s)[3] ) ?                           \
                    ( ( 0xAD == ((const U8*)s)[4] ) ?                       \
-                       ( ( inRANGE(((const U8*)s)[5], 0x41, 0x42) ) ? 6 : 0 )\
+                       ( ( inRANGE_helper_(U8, ((const U8*)s)[5], 0x41, 0x42) ) ? 6 : 0 )\
                    : ( ( 0xAF == ((const U8*)s)[4] ) && ( 0x43 == ((const U8*)s)[5] ) ) ? 6 : 0 )\
                : ( 0x5F == ((const U8*)s)[3] ) ?                           \
                    ( ( 0xAD == ((const U8*)s)[4] ) ?                       \
-                       ( ( inRANGE(((const U8*)s)[5], 0x41, 0x42) ) ? 6 : 4 )\
+                       ( ( inRANGE_helper_(U8, ((const U8*)s)[5], 0x41, 0x42) ) ? 6 : 4 )\
                    : ( ( 0xAF == ((const U8*)s)[4] ) && ( 0x43 == ((const U8*)s)[5] ) ) ? 6 : 4 )\
                : 0 )                                                       \
            : ( ( 0xAF == ((const U8*)s)[2] ) && ( 0x43 == ((const U8*)s)[3] ) ) ? 4 : 0 )\
            : ( ( ( ( 0x71 == ((const U8*)s)[2] ) && ( 0xB7 == ((const U8*)s)[3] ) ) && ( 0x52 == ((const U8*)s)[4] ) ) && ( 0x64 == ((const U8*)s)[5] ) ) ? 6 : 0 )\
        : 0 )                                                               \
     : ( 0xBF == ((const U8*)s)[0] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[1], 0x66, 0x67) ) ?                      \
-           ( ( ( ( inRANGE(((const U8*)s)[2], 0x41, 0x48) ) && ( 0xB3 == ((const U8*)s)[3] ) ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 5 : 0 )\
-       : ( ( ( ( 0x69 == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x41, 0x48) || 0x57 == ((const U8*)s)[2] || 0x62 == ((const U8*)s)[2] || 0x6A == ((const U8*)s)[2] ) ) && ( 0xB3 == ((const U8*)s)[3] ) ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 5 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x66, 0x67) ) ?          \
+           ( ( ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x48) ) && ( 0xB3 == ((const U8*)s)[3] ) ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 5 : 0 )\
+       : ( ( ( ( 0x69 == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x48) || 0x57 == ((const U8*)s)[2] || 0x62 == ((const U8*)s)[2] || 0x6A == ((const U8*)s)[2] ) ) && ( 0xB3 == ((const U8*)s)[3] ) ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 5 : 0 )\
     : 0 )
 
 
            : ( ( 0xB3 == ((const U8*)s)[2] ) && ( 0x67 == ((const U8*)s)[3] ) ) ? 4 : 0 )\
        : ( ( ( 0x55 == ((const U8*)s)[1] ) && ( 0xB3 == ((const U8*)s)[2] ) ) && ( 0x67 == ((const U8*)s)[3] ) ) ? 4 : 0 )\
     : ( 0xBF == ((const U8*)s)[0] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[1], 0x66, 0x67) ) ?                      \
-           ( ( ( ( inRANGE(((const U8*)s)[2], 0x41, 0x48) ) && ( 0xB3 == ((const U8*)s)[3] ) ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 5 : 0 )\
-       : ( ( ( ( 0x69 == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x41, 0x48) || 0x57 == ((const U8*)s)[2] || 0x62 == ((const U8*)s)[2] || 0x6A == ((const U8*)s)[2] ) ) && ( 0xB3 == ((const U8*)s)[3] ) ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 5 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x66, 0x67) ) ?          \
+           ( ( ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x48) ) && ( 0xB3 == ((const U8*)s)[3] ) ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 5 : 0 )\
+       : ( ( ( ( 0x69 == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x48) || 0x57 == ((const U8*)s)[2] || 0x62 == ((const U8*)s)[2] || 0x6A == ((const U8*)s)[2] ) ) && ( 0xB3 == ((const U8*)s)[3] ) ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 5 : 0 )\
     : 0 )
 
 
        ( ( ( ((const U8*)s)[1] & 0xBF ) == 'f' ) ?                         \
            ( ( ( ( ((const U8*)s)[2] & 0xBF ) == 'i' ) || ( ( ((const U8*)s)[2] & 0xBF ) == 'l' ) ) ? 3 : 2 )\
        : ( ( ( ((const U8*)s)[1] & 0xBF ) == 'i' ) || ( ( ((const U8*)s)[1] & 0xBF ) == 'l' ) ) ? 2 : 0 )\
-    : ( ( ((const U8*)s)[0] & 0xBF ) == 'h' ) ? is_MULTI_CHAR_FOLD_utf8_safe_part0(s,e) : is_MULTI_CHAR_FOLD_utf8_safe_part1(s,e) )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'h' ) ?                             \
+       ( ( ( 0xAE == ((const U8*)s)[1] ) && ( 0x58 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'i' ) ? is_MULTI_CHAR_FOLD_utf8_safe_part0(s,e) : is_MULTI_CHAR_FOLD_utf8_safe_part1(s,e) )\
 : ((e)-(s) > 4) ? is_MULTI_CHAR_FOLD_utf8_safe_part2(s,e) : is_MULTI_CHAR_FOLD_utf8_safe_part3(s,e) )
 
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part0(s,e)                           \
+( ( 0x52 == ((const U8*)s)[1] ) ?                                           \
+           ( ( 0x46 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( ( 0xB7 == ((const U8*)s)[3] ) && ( 0x53 == ((const U8*)s)[4] ) ) && ( 0x43 == ((const U8*)s)[5] ) ) ? 0x587 : 0 )\
+           : ( 0x62 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB7 == ((const U8*)s)[3] ) && ( 0x52 == ((const U8*)s)[4] ) ) ? ( ( 0x46 == ((const U8*)s)[5] ) ? 0xFB14\
+                       : ( 0x52 == ((const U8*)s)[5] ) ? 0xFB15            \
+                       : ( 0x54 == ((const U8*)s)[5] ) ? 0xFB17            \
+                       : ( 0x64 == ((const U8*)s)[5] ) ? 0xFB13 : 0 ) : 0 )\
+           : ( ( ( ( 0x71 == ((const U8*)s)[2] ) && ( 0xB7 == ((const U8*)s)[3] ) ) && ( 0x52 == ((const U8*)s)[4] ) ) && ( 0x64 == ((const U8*)s)[5] ) ) ? 0xFB16 : 0 )\
+       : 0 )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part1(s,e)                           \
+( ( 0xBF == ((const U8*)s)[0] ) ?                                           \
+       ( ( 0x66 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x41 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F80 : 0 )\
+           : ( 0x42 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F81 : 0 )\
+           : ( 0x43 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F82 : 0 )\
+           : ( 0x44 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F83 : 0 )\
+           : ( 0x45 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F84 : 0 )\
+           : ( 0x46 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F85 : 0 )\
+           : ( 0x47 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F86 : 0 )\
+           : ( ( ( 0x48 == ((const U8*)s)[2] ) && ( 0xB3 == ((const U8*)s)[3] ) ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F87 : 0 )\
+       : ( 0x67 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x41 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F90 : 0 )\
+           : ( 0x42 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F91 : 0 )\
+           : ( 0x43 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F92 : 0 )\
+           : ( 0x44 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F93 : 0 )\
+           : ( 0x45 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F94 : 0 )\
+           : ( 0x46 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F95 : 0 )\
+           : ( 0x47 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F96 : 0 )\
+           : ( ( ( 0x48 == ((const U8*)s)[2] ) && ( 0xB3 == ((const U8*)s)[3] ) ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F97 : 0 )\
+       : ( 0x69 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x41 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1FA0 : 0 )\
+           : ( 0x42 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1FA1 : 0 )\
+           : ( 0x43 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1FA2 : 0 )\
+           : ( 0x44 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1FA3 : 0 )\
+           : ( 0x45 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1FA4 : 0 )\
+           : ( 0x46 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1FA5 : 0 )\
+           : ( 0x47 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1FA6 : 0 )\
+           : ( 0x48 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1FA7 : 0 )\
+           : ( 0x57 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1FB2 : 0 )\
+           : ( 0x62 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1FC2 : 0 )\
+           : ( ( ( 0x6A == ((const U8*)s)[2] ) && ( 0xB3 == ((const U8*)s)[3] ) ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1FF2 : 0 )\
+       : 0 )                                                               \
+    : 0 )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part2(s,e)                           \
+( ( ( ((const U8*)s)[1] & 0xBF ) == 'f' ) ?                                 \
+           ( ( ( ((const U8*)s)[2] & 0xBF ) == 'i' ) ? 0xFB03              \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 'l' ) ? 0xFB04 : 0xFB00 )   \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'i' ) ? 0xFB01                  \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'l' ) ? 0xFB02 : 0 )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part3(s,e)                           \
+( ( ( ((const U8*)s)[0] & 0xBF ) == 'h' ) ?                                 \
+       ( ( ( 0xAE == ((const U8*)s)[1] ) && ( 0x58 == ((const U8*)s)[2] ) ) ? 0x1E96 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'i' ) ?                             \
+       ( ( ( 0xAD == ((const U8*)s)[1] ) && ( 0x48 == ((const U8*)s)[2] ) ) ? 0x130 : 0 )\
+    : ( 0x8E == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0x72 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x8E == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x72 == ((const U8*)s)[3] ) ? 0x59 : 0 )                \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 's' ) ? 0x59                \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 't' ) ? 0xFB05 : 0 )        \
+       : 0 )                                                               \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'j' ) ?                             \
+       ( ( ( 0xAD == ((const U8*)s)[1] ) && ( 0x53 == ((const U8*)s)[2] ) ) ? 0x1F0 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 's' ) ?                             \
+       ( ( 0x8E == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x72 == ((const U8*)s)[2] ) ? 0x59 : 0 )                    \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 's' ) ? 0x59                    \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 't' ) ? 0xFB05 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 't' ) ?                             \
+       ( ( ( 0xAD == ((const U8*)s)[1] ) && ( 0x49 == ((const U8*)s)[2] ) ) ? 0x1E97 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'w' ) ?                             \
+       ( ( ( 0xAD == ((const U8*)s)[1] ) && ( 0x51 == ((const U8*)s)[2] ) ) ? 0x1E98 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'y' ) ?                             \
+       ( ( ( 0xAD == ((const U8*)s)[1] ) && ( 0x51 == ((const U8*)s)[2] ) ) ? 0x1E99 : 0 )\
+    : ( 0xAA == ((const U8*)s)[0] ) ?                                       \
+       ( ( ( 0x6A == ((const U8*)s)[1] ) && ( ( ((const U8*)s)[2] & 0xBF ) == 'n' ) ) ? 0x149 : 0 )\
+    : ( 0xB3 == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0x53 == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xB3 == ((const U8*)s)[2] ) && ( 0x67 == ((const U8*)s)[3] ) ) ? 0x1FB4 : 0 )\
+       : ( 0x55 == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xB3 == ((const U8*)s)[2] ) && ( 0x67 == ((const U8*)s)[3] ) ) ? 0x1FC4 : 0 )\
+       : ( 0x58 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xAF == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x43 == ((const U8*)s)[3] ) ?                           \
+                   ( ( ( 0xB3 == ((const U8*)s)[4] ) && ( 0x67 == ((const U8*)s)[5] ) ) ? 0x1FB7 : 0x1FB6 )\
+               : 0 )                                                       \
+           : ( ( 0xB3 == ((const U8*)s)[2] ) && ( 0x67 == ((const U8*)s)[3] ) ) ? 0x1FB3 : 0 )\
+       : ( 0x65 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xAF == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x43 == ((const U8*)s)[3] ) ?                           \
+                   ( ( ( 0xB3 == ((const U8*)s)[4] ) && ( 0x67 == ((const U8*)s)[5] ) ) ? 0x1FC7 : 0x1FC6 )\
+               : 0 )                                                       \
+           : ( ( 0xB3 == ((const U8*)s)[2] ) && ( 0x67 == ((const U8*)s)[3] ) ) ? 0x1FC3 : 0 )\
+       : ( 0x67 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xAD == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x49 == ((const U8*)s)[3] ) ?                           \
+                   ( ( 0xAD == ((const U8*)s)[4] ) ?                       \
+                       ( ( 0x41 == ((const U8*)s)[5] ) ? 0x1FD2            \
+                       : ( 0x42 == ((const U8*)s)[5] ) ? 0x390 : 0 )       \
+                   : ( ( 0xAF == ((const U8*)s)[4] ) && ( 0x43 == ((const U8*)s)[5] ) ) ? 0x1FD7 : 0 )\
+               : 0 )                                                       \
+           : ( ( 0xAF == ((const U8*)s)[2] ) && ( 0x43 == ((const U8*)s)[3] ) ) ? 0x1FD6 : 0 )\
+       : 0 )                                                               \
+    : ( 0xB4 == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0x42 == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xAD == ((const U8*)s)[2] ) && ( 0x5F == ((const U8*)s)[3] ) ) ? 0x1FE4 : 0 )\
+       : ( 0x46 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xAD == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x49 == ((const U8*)s)[3] ) ?                           \
+                   ( ( 0xAD == ((const U8*)s)[4] ) ?                       \
+                       ( ( 0x41 == ((const U8*)s)[5] ) ? 0x1FE2            \
+                       : ( 0x42 == ((const U8*)s)[5] ) ? 0x3B0 : 0 )       \
+                   : ( ( 0xAF == ((const U8*)s)[4] ) && ( 0x43 == ((const U8*)s)[5] ) ) ? 0x1FE7 : 0 )\
+               : ( 0x5F == ((const U8*)s)[3] ) ?                           \
+                   ( ( 0xAD == ((const U8*)s)[4] ) ?                       \
+                       ( ( 0x41 == ((const U8*)s)[5] ) ? 0x1F52            \
+                       : ( 0x42 == ((const U8*)s)[5] ) ? 0x1F54 : 0x1F50 ) \
+                   : ( ( 0xAF == ((const U8*)s)[4] ) && ( 0x43 == ((const U8*)s)[5] ) ) ? 0x1F56 : 0x1F50 )\
+               : 0 )                                                       \
+           : ( ( 0xAF == ((const U8*)s)[2] ) && ( 0x43 == ((const U8*)s)[3] ) ) ? 0x1FE6 : 0 )\
+       : ( 0x4A == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xAF == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x43 == ((const U8*)s)[3] ) ?                           \
+                   ( ( ( 0xB3 == ((const U8*)s)[4] ) && ( 0x67 == ((const U8*)s)[5] ) ) ? 0x1FF7 : 0x1FF6 )\
+               : 0 )                                                       \
+           : ( ( 0xB3 == ((const U8*)s)[2] ) && ( 0x67 == ((const U8*)s)[3] ) ) ? 0x1FF3 : 0 )\
+       : ( ( ( 0x55 == ((const U8*)s)[1] ) && ( 0xB3 == ((const U8*)s)[2] ) ) && ( 0x67 == ((const U8*)s)[3] ) ) ? 0x1FF4 : 0 )\
+    : ( 0xB7 == ((const U8*)s)[0] ) ? what_MULTI_CHAR_FOLD_utf8_safe_part0(s,e) : what_MULTI_CHAR_FOLD_utf8_safe_part1(s,e) )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part4(s,e)                           \
+( ( 0x42 == ((const U8*)s)[1] ) ?                                           \
+           ( ( ( 0xAD == ((const U8*)s)[2] ) && ( 0x5F == ((const U8*)s)[3] ) ) ? 0x1FE4 : 0 )\
+       : ( 0x46 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xAD == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x5F == ((const U8*)s)[3] ) ? 0x1F50 : 0 )              \
+           : ( ( 0xAF == ((const U8*)s)[2] ) && ( 0x43 == ((const U8*)s)[3] ) ) ? 0x1FE6 : 0 )\
+       : ( 0x4A == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xAF == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x43 == ((const U8*)s)[3] ) ? 0x1FF6 : 0 )              \
+           : ( ( 0xB3 == ((const U8*)s)[2] ) && ( 0x67 == ((const U8*)s)[3] ) ) ? 0x1FF3 : 0 )\
+       : ( ( ( 0x55 == ((const U8*)s)[1] ) && ( 0xB3 == ((const U8*)s)[2] ) ) && ( 0x67 == ((const U8*)s)[3] ) ) ? 0x1FF4 : 0 )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part5(s,e)                           \
+( ( 0xBF == ((const U8*)s)[0] ) ?                                           \
+       ( ( 0x66 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x41 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F80 : 0 )\
+           : ( 0x42 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F81 : 0 )\
+           : ( 0x43 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F82 : 0 )\
+           : ( 0x44 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F83 : 0 )\
+           : ( 0x45 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F84 : 0 )\
+           : ( 0x46 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F85 : 0 )\
+           : ( 0x47 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F86 : 0 )\
+           : ( ( ( 0x48 == ((const U8*)s)[2] ) && ( 0xB3 == ((const U8*)s)[3] ) ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F87 : 0 )\
+       : ( 0x67 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x41 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F90 : 0 )\
+           : ( 0x42 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F91 : 0 )\
+           : ( 0x43 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F92 : 0 )\
+           : ( 0x44 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F93 : 0 )\
+           : ( 0x45 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F94 : 0 )\
+           : ( 0x46 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F95 : 0 )\
+           : ( 0x47 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F96 : 0 )\
+           : ( ( ( 0x48 == ((const U8*)s)[2] ) && ( 0xB3 == ((const U8*)s)[3] ) ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1F97 : 0 )\
+       : ( 0x69 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x41 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1FA0 : 0 )\
+           : ( 0x42 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1FA1 : 0 )\
+           : ( 0x43 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1FA2 : 0 )\
+           : ( 0x44 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1FA3 : 0 )\
+           : ( 0x45 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1FA4 : 0 )\
+           : ( 0x46 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1FA5 : 0 )\
+           : ( 0x47 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1FA6 : 0 )\
+           : ( 0x48 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1FA7 : 0 )\
+           : ( 0x57 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1FB2 : 0 )\
+           : ( 0x62 == ((const U8*)s)[2] ) ?                               \
+               ( ( ( 0xB3 == ((const U8*)s)[3] ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1FC2 : 0 )\
+           : ( ( ( 0x6A == ((const U8*)s)[2] ) && ( 0xB3 == ((const U8*)s)[3] ) ) && ( 0x67 == ((const U8*)s)[4] ) ) ? 0x1FF2 : 0 )\
+       : 0 )                                                               \
+    : 0 )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part6(s,e)                           \
+( ( ( ((const U8*)s)[0] & 0xBF ) == 'a' ) ?                                 \
+       ( ( ( 0xAA == ((const U8*)s)[1] ) && ( 0x71 == ((const U8*)s)[2] ) ) ? 0x1E9A : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'f' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xBF ) == 'f' ) ?                         \
+           ( ( ( ((const U8*)s)[2] & 0xBF ) == 'i' ) ? 0xFB03              \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 'l' ) ? 0xFB04 : 0xFB00 )   \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'i' ) ? 0xFB01                  \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'l' ) ? 0xFB02 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'h' ) ?                             \
+       ( ( ( 0xAE == ((const U8*)s)[1] ) && ( 0x58 == ((const U8*)s)[2] ) ) ? 0x1E96 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'i' ) ?                             \
+       ( ( ( 0xAD == ((const U8*)s)[1] ) && ( 0x48 == ((const U8*)s)[2] ) ) ? 0x130 : 0 )\
+    : ( 0x8E == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0x72 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x8E == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x72 == ((const U8*)s)[3] ) ? 0x59 : 0 )                \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 's' ) ? 0x59                \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 't' ) ? 0xFB05 : 0 )        \
+       : 0 )                                                               \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'j' ) ?                             \
+       ( ( ( 0xAD == ((const U8*)s)[1] ) && ( 0x53 == ((const U8*)s)[2] ) ) ? 0x1F0 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 's' ) ?                             \
+       ( ( 0x8E == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x72 == ((const U8*)s)[2] ) ? 0x59 : 0 )                    \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 's' ) ? 0x59                    \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 't' ) ? 0xFB05 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 't' ) ?                             \
+       ( ( ( 0xAD == ((const U8*)s)[1] ) && ( 0x49 == ((const U8*)s)[2] ) ) ? 0x1E97 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'w' ) ?                             \
+       ( ( ( 0xAD == ((const U8*)s)[1] ) && ( 0x51 == ((const U8*)s)[2] ) ) ? 0x1E98 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'y' ) ?                             \
+       ( ( ( 0xAD == ((const U8*)s)[1] ) && ( 0x51 == ((const U8*)s)[2] ) ) ? 0x1E99 : 0 )\
+    : ( 0xAA == ((const U8*)s)[0] ) ?                                       \
+       ( ( ( 0x6A == ((const U8*)s)[1] ) && ( ( ((const U8*)s)[2] & 0xBF ) == 'n' ) ) ? 0x149 : 0 )\
+    : ( 0xB3 == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0x53 == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xB3 == ((const U8*)s)[2] ) && ( 0x67 == ((const U8*)s)[3] ) ) ? 0x1FB4 : 0 )\
+       : ( 0x55 == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xB3 == ((const U8*)s)[2] ) && ( 0x67 == ((const U8*)s)[3] ) ) ? 0x1FC4 : 0 )\
+       : ( 0x58 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xAF == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x43 == ((const U8*)s)[3] ) ? 0x1FB6 : 0 )              \
+           : ( ( 0xB3 == ((const U8*)s)[2] ) && ( 0x67 == ((const U8*)s)[3] ) ) ? 0x1FB3 : 0 )\
+       : ( 0x65 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xAF == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x43 == ((const U8*)s)[3] ) ? 0x1FC6 : 0 )              \
+           : ( ( 0xB3 == ((const U8*)s)[2] ) && ( 0x67 == ((const U8*)s)[3] ) ) ? 0x1FC3 : 0 )\
+       : ( ( ( 0x67 == ((const U8*)s)[1] ) && ( 0xAF == ((const U8*)s)[2] ) ) && ( 0x43 == ((const U8*)s)[3] ) ) ? 0x1FD6 : 0 )\
+    : ( 0xB4 == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0x42 == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xAD == ((const U8*)s)[2] ) && ( 0x5F == ((const U8*)s)[3] ) ) ? 0x1FE4 : 0 )\
+       : ( 0x46 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xAD == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x5F == ((const U8*)s)[3] ) ? 0x1F50 : 0 )              \
+           : ( ( 0xAF == ((const U8*)s)[2] ) && ( 0x43 == ((const U8*)s)[3] ) ) ? 0x1FE6 : 0 )\
+       : ( 0x4A == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xAF == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x43 == ((const U8*)s)[3] ) ? 0x1FF6 : 0 )              \
+           : ( ( 0xB3 == ((const U8*)s)[2] ) && ( 0x67 == ((const U8*)s)[3] ) ) ? 0x1FF3 : 0 )\
+       : ( ( ( 0x55 == ((const U8*)s)[1] ) && ( 0xB3 == ((const U8*)s)[2] ) ) && ( 0x67 == ((const U8*)s)[3] ) ) ? 0x1FF4 : 0 )\
+    : 0 )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe_part7(s,e)                           \
+( ((e)-(s) > 2) ?                                                           \
+    ( ( ( ((const U8*)s)[0] & 0xBF ) == 'a' ) ?                             \
+       ( ( ( 0xAA == ((const U8*)s)[1] ) && ( 0x71 == ((const U8*)s)[2] ) ) ? 0x1E9A : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'f' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xBF ) == 'f' ) ?                         \
+           ( ( ( ((const U8*)s)[2] & 0xBF ) == 'i' ) ? 0xFB03              \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 'l' ) ? 0xFB04 : 0xFB00 )   \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'i' ) ? 0xFB01                  \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'l' ) ? 0xFB02 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'h' ) ?                             \
+       ( ( ( 0xAE == ((const U8*)s)[1] ) && ( 0x58 == ((const U8*)s)[2] ) ) ? 0x1E96 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'i' ) ?                             \
+       ( ( ( 0xAD == ((const U8*)s)[1] ) && ( 0x48 == ((const U8*)s)[2] ) ) ? 0x130 : 0 )\
+    : ( 0x8E == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0x72 == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( ((const U8*)s)[2] & 0xBF ) == 's' ) ? 0x59                \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 't' ) ? 0xFB05 : 0 )        \
+       : 0 )                                                               \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'j' ) ?                             \
+       ( ( ( 0xAD == ((const U8*)s)[1] ) && ( 0x53 == ((const U8*)s)[2] ) ) ? 0x1F0 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 's' ) ?                             \
+       ( ( 0x8E == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x72 == ((const U8*)s)[2] ) ? 0x59 : 0 )                    \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 's' ) ? 0x59                    \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 't' ) ? 0xFB05 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 't' ) ?                             \
+       ( ( ( 0xAD == ((const U8*)s)[1] ) && ( 0x49 == ((const U8*)s)[2] ) ) ? 0x1E97 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'w' ) ?                             \
+       ( ( ( 0xAD == ((const U8*)s)[1] ) && ( 0x51 == ((const U8*)s)[2] ) ) ? 0x1E98 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'y' ) ?                             \
+       ( ( ( 0xAD == ((const U8*)s)[1] ) && ( 0x51 == ((const U8*)s)[2] ) ) ? 0x1E99 : 0 )\
+    : ( ( ( 0xAA == ((const U8*)s)[0] ) && ( 0x6A == ((const U8*)s)[1] ) ) && ( ( ((const U8*)s)[2] & 0xBF ) == 'n' ) ) ? 0x149 : 0 )\
+: ((e)-(s) > 1) ?                                                           \
+    ( ( ( ((const U8*)s)[0] & 0xBF ) == 'f' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xBF ) == 'f' ) ? 0xFB00                  \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'i' ) ? 0xFB01                  \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'l' ) ? 0xFB02 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 's' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xBF ) == 's' ) ? 0x59                    \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 't' ) ? 0xFB05 : 0 )            \
+    : 0 )                                                                   \
+: 0 )
+
+
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_utf8_safe(s,e)                                 \
+( ((e)-(s) > 5) ?                                                           \
+    ( ( ( ((const U8*)s)[0] & 0xBF ) == 'a' ) ?                             \
+       ( ( ( 0xAA == ((const U8*)s)[1] ) && ( 0x71 == ((const U8*)s)[2] ) ) ? 0x1E9A : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'f' ) ? what_MULTI_CHAR_FOLD_utf8_safe_part2(s,e) : what_MULTI_CHAR_FOLD_utf8_safe_part3(s,e) )\
+: ((e)-(s) > 4) ?                                                           \
+    ( ( ( ((const U8*)s)[0] & 0xBF ) == 'a' ) ?                             \
+       ( ( ( 0xAA == ((const U8*)s)[1] ) && ( 0x71 == ((const U8*)s)[2] ) ) ? 0x1E9A : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'f' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xBF ) == 'f' ) ?                         \
+           ( ( ( ((const U8*)s)[2] & 0xBF ) == 'i' ) ? 0xFB03              \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 'l' ) ? 0xFB04 : 0xFB00 )   \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'i' ) ? 0xFB01                  \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'l' ) ? 0xFB02 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'h' ) ?                             \
+       ( ( ( 0xAE == ((const U8*)s)[1] ) && ( 0x58 == ((const U8*)s)[2] ) ) ? 0x1E96 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'i' ) ?                             \
+       ( ( ( 0xAD == ((const U8*)s)[1] ) && ( 0x48 == ((const U8*)s)[2] ) ) ? 0x130 : 0 )\
+    : ( 0x8E == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0x72 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x8E == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x72 == ((const U8*)s)[3] ) ? 0x59 : 0 )                \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 's' ) ? 0x59                \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 't' ) ? 0xFB05 : 0 )        \
+       : 0 )                                                               \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'j' ) ?                             \
+       ( ( ( 0xAD == ((const U8*)s)[1] ) && ( 0x53 == ((const U8*)s)[2] ) ) ? 0x1F0 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 's' ) ?                             \
+       ( ( 0x8E == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0x72 == ((const U8*)s)[2] ) ? 0x59 : 0 )                    \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 's' ) ? 0x59                    \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 't' ) ? 0xFB05 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 't' ) ?                             \
+       ( ( ( 0xAD == ((const U8*)s)[1] ) && ( 0x49 == ((const U8*)s)[2] ) ) ? 0x1E97 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'w' ) ?                             \
+       ( ( ( 0xAD == ((const U8*)s)[1] ) && ( 0x51 == ((const U8*)s)[2] ) ) ? 0x1E98 : 0 )\
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 'y' ) ?                             \
+       ( ( ( 0xAD == ((const U8*)s)[1] ) && ( 0x51 == ((const U8*)s)[2] ) ) ? 0x1E99 : 0 )\
+    : ( 0xAA == ((const U8*)s)[0] ) ?                                       \
+       ( ( ( 0x6A == ((const U8*)s)[1] ) && ( ( ((const U8*)s)[2] & 0xBF ) == 'n' ) ) ? 0x149 : 0 )\
+    : ( 0xB3 == ((const U8*)s)[0] ) ?                                       \
+       ( ( 0x53 == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xB3 == ((const U8*)s)[2] ) && ( 0x67 == ((const U8*)s)[3] ) ) ? 0x1FB4 : 0 )\
+       : ( 0x55 == ((const U8*)s)[1] ) ?                                   \
+           ( ( ( 0xB3 == ((const U8*)s)[2] ) && ( 0x67 == ((const U8*)s)[3] ) ) ? 0x1FC4 : 0 )\
+       : ( 0x58 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xAF == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x43 == ((const U8*)s)[3] ) ? 0x1FB6 : 0 )              \
+           : ( ( 0xB3 == ((const U8*)s)[2] ) && ( 0x67 == ((const U8*)s)[3] ) ) ? 0x1FB3 : 0 )\
+       : ( 0x65 == ((const U8*)s)[1] ) ?                                   \
+           ( ( 0xAF == ((const U8*)s)[2] ) ?                               \
+               ( ( 0x43 == ((const U8*)s)[3] ) ? 0x1FC6 : 0 )              \
+           : ( ( 0xB3 == ((const U8*)s)[2] ) && ( 0x67 == ((const U8*)s)[3] ) ) ? 0x1FC3 : 0 )\
+       : ( ( ( 0x67 == ((const U8*)s)[1] ) && ( 0xAF == ((const U8*)s)[2] ) ) && ( 0x43 == ((const U8*)s)[3] ) ) ? 0x1FD6 : 0 )\
+    : ( 0xB4 == ((const U8*)s)[0] ) ? what_MULTI_CHAR_FOLD_utf8_safe_part4(s,e) : what_MULTI_CHAR_FOLD_utf8_safe_part5(s,e) )\
+: ((e)-(s) > 3) ? what_MULTI_CHAR_FOLD_utf8_safe_part6(s,e) : what_MULTI_CHAR_FOLD_utf8_safe_part7(s,e) )
+
 /*
        MULTI_CHAR_FOLD: multi-char strings that are folded to by a single character
 
-       &regcharclass_multi_char_folds::multi_char_folds('l', 'a')
+       %regcharclass_multi_char_folds::multi_char_folds('l', 'a')
 */
 /*** GENERATED CODE ***/
 #define is_MULTI_CHAR_FOLD_latin1_safe(s,e)                                 \
     : ( ( ( ((const U8*)s)[0] & 0xBF ) == 's' ) && ( ( ((const U8*)s)[1] & 0xBE ) == 's' ) ) ? 2 : 0 )\
 : 0 )
 
+/*** GENERATED CODE ***/
+#define what_MULTI_CHAR_FOLD_latin1_safe(s,e)                               \
+( ((e)-(s) > 2) ?                                                           \
+    ( ( ( ((const U8*)s)[0] & 0xBF ) == 'f' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xBF ) == 'f' ) ?                         \
+           ( ( ( ((const U8*)s)[2] & 0xBF ) == 'i' ) ? 0xFB03              \
+           : ( ( ((const U8*)s)[2] & 0xBF ) == 'l' ) ? 0xFB04 : 0xFB00 )   \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'i' ) ? 0xFB01                  \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'l' ) ? 0xFB02 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 's' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xBF ) == 's' ) ? 0x59                    \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 't' ) ? 0xFB05 : 0 )            \
+    : 0 )                                                                   \
+: ((e)-(s) > 1) ?                                                           \
+    ( ( ( ((const U8*)s)[0] & 0xBF ) == 'f' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xBF ) == 'f' ) ? 0xFB00                  \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'i' ) ? 0xFB01                  \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 'l' ) ? 0xFB02 : 0 )            \
+    : ( ( ((const U8*)s)[0] & 0xBF ) == 's' ) ?                             \
+       ( ( ( ((const U8*)s)[1] & 0xBF ) == 's' ) ? 0x59                    \
+       : ( ( ((const U8*)s)[1] & 0xBF ) == 't' ) ? 0xFB05 : 0 )            \
+    : 0 )                                                                   \
+: 0 )
+
 /*
        THREE_CHAR_FOLD: A three-character multi-char fold
 
-       &regcharclass_multi_char_folds::multi_char_folds('u', '3')
+       %regcharclass_multi_char_folds::multi_char_folds('u', '3')
 */
 /*** GENERATED CODE ***/
 #define is_THREE_CHAR_FOLD_utf8_safe(s,e)                                   \
        ( ( 0x58 == ((const U8*)s)[1] || 0x65 == ((const U8*)s)[1] ) ?      \
            ( ( ( ( ( 0xAF == ((const U8*)s)[2] ) && ( 0x43 == ((const U8*)s)[3] ) ) && ( 0xB3 == ((const U8*)s)[4] ) ) && ( 0x67 == ((const U8*)s)[5] ) ) ? 6 : 0 )\
        : ( ( ( 0x67 == ((const U8*)s)[1] ) && ( 0xAD == ((const U8*)s)[2] ) ) && ( 0x49 == ((const U8*)s)[3] ) ) ? ( ( 0xAD == ((const U8*)s)[4] ) ?\
-                       ( ( inRANGE(((const U8*)s)[5], 0x41, 0x42) ) ? 6 : 0 )\
+                       ( ( inRANGE_helper_(U8, ((const U8*)s)[5], 0x41, 0x42) ) ? 6 : 0 )\
                    : ( ( 0xAF == ((const U8*)s)[4] ) && ( 0x43 == ((const U8*)s)[5] ) ) ? 6 : 0 ) : 0 )\
     : ( 0xB4 == ((const U8*)s)[0] ) ?                                       \
        ( ( 0x46 == ((const U8*)s)[1] ) ?                                   \
            ( ( ( 0xAD == ((const U8*)s)[2] ) && ( 0x49 == ((const U8*)s)[3] || 0x5F == ((const U8*)s)[3] ) ) ? ( ( 0xAD == ((const U8*)s)[4] ) ?\
-                       ( ( inRANGE(((const U8*)s)[5], 0x41, 0x42) ) ? 6 : 0 )\
+                       ( ( inRANGE_helper_(U8, ((const U8*)s)[5], 0x41, 0x42) ) ? 6 : 0 )\
                    : ( ( 0xAF == ((const U8*)s)[4] ) && ( 0x43 == ((const U8*)s)[5] ) ) ? 6 : 0 ) : 0 )\
        : ( ( ( ( ( 0x4A == ((const U8*)s)[1] ) && ( 0xAF == ((const U8*)s)[2] ) ) && ( 0x43 == ((const U8*)s)[3] ) ) && ( 0xB3 == ((const U8*)s)[4] ) ) && ( 0x67 == ((const U8*)s)[5] ) ) ? 6 : 0 )\
     : 0 )                                                                   \
 /*
        THREE_CHAR_FOLD: A three-character multi-char fold
 
-       &regcharclass_multi_char_folds::multi_char_folds('l', '3')
+       %regcharclass_multi_char_folds::multi_char_folds('l', '3')
 */
 /*** GENERATED CODE ***/
 #define is_THREE_CHAR_FOLD_latin1_safe(s,e)                                 \
 /*
        THREE_CHAR_FOLD_HEAD: The first two of three-character multi-char folds
 
-       &regcharclass_multi_char_folds::multi_char_folds('u', 'h')
+       %regcharclass_multi_char_folds::multi_char_folds('u', 'h')
 */
 /*** GENERATED CODE ***/
 #define is_THREE_CHAR_FOLD_HEAD_utf8_safe(s,e)                              \
     : ( 0xB7 == ((const U8*)s)[0] ) ?                                       \
        ( ( ( 0x52 == ((const U8*)s)[1] ) && ( 0x46 == ((const U8*)s)[2] || 0x62 == ((const U8*)s)[2] || 0x71 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
     : ( 0xBF == ((const U8*)s)[0] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[1], 0x66, 0x67) ) ?                      \
-           ( ( inRANGE(((const U8*)s)[2], 0x41, 0x48) ) ? 3 : 0 )          \
-       : ( ( 0x69 == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x41, 0x48) || 0x57 == ((const U8*)s)[2] || 0x62 == ((const U8*)s)[2] || 0x6A == ((const U8*)s)[2] ) ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x66, 0x67) ) ?          \
+           ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x48) ) ? 3 : 0 )\
+       : ( ( 0x69 == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x48) || 0x57 == ((const U8*)s)[2] || 0x62 == ((const U8*)s)[2] || 0x6A == ((const U8*)s)[2] ) ) ? 3 : 0 )\
     : 0 )                                                                   \
 : ((e)-(s) > 2) ?                                                           \
     ( ( ( ( ((const U8*)s)[0] & 0xAF ) == 'a' ) || ( ( ((const U8*)s)[0] & 0xBE ) == 'h' ) || ( ( ((const U8*)s)[0] & 0xBE ) == 's' ) || ( ( ((const U8*)s)[0] & 0xBF ) == 'w' ) || ( ( ((const U8*)s)[0] & 0xBF ) == 'y' ) ) ? 1\
     : ( 0xB7 == ((const U8*)s)[0] ) ?                                       \
        ( ( ( 0x52 == ((const U8*)s)[1] ) && ( 0x46 == ((const U8*)s)[2] || 0x62 == ((const U8*)s)[2] || 0x71 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
     : ( 0xBF == ((const U8*)s)[0] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[1], 0x66, 0x67) ) ?                      \
-           ( ( inRANGE(((const U8*)s)[2], 0x41, 0x48) ) ? 3 : 0 )          \
-       : ( ( 0x69 == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x41, 0x48) || 0x57 == ((const U8*)s)[2] || 0x62 == ((const U8*)s)[2] || 0x6A == ((const U8*)s)[2] ) ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x66, 0x67) ) ?          \
+           ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x48) ) ? 3 : 0 )\
+       : ( ( 0x69 == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x48) || 0x57 == ((const U8*)s)[2] || 0x62 == ((const U8*)s)[2] || 0x6A == ((const U8*)s)[2] ) ) ? 3 : 0 )\
     : 0 )                                                                   \
 : ((e)-(s) > 1) ?                                                           \
     ( ( ( ( ((const U8*)s)[0] & 0xAF ) == 'a' ) || ( ( ((const U8*)s)[0] & 0xBE ) == 'h' ) || ( ( ((const U8*)s)[0] & 0xBE ) == 's' ) || ( ( ((const U8*)s)[0] & 0xBF ) == 'w' ) || ( ( ((const U8*)s)[0] & 0xBF ) == 'y' ) ) ? 1\
 /*
        THREE_CHAR_FOLD_HEAD: The first two of three-character multi-char folds
 
-       &regcharclass_multi_char_folds::multi_char_folds('l', 'h')
+       %regcharclass_multi_char_folds::multi_char_folds('l', 'h')
 */
 /*** GENERATED CODE ***/
 #define is_THREE_CHAR_FOLD_HEAD_latin1_safe(s,e)                            \
 #define is_FOLDS_TO_MULTI_utf8(s)                                           \
 ( ( 0x80 == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x72 == ((const U8*)s)[1] ) ? 2 : 0 )                               \
-: ( 0x8C == ((const U8*)s)[0] || 0x9B == ((const U8*)s)[0] || inRANGE(((const U8*)s)[0], 0xB2, 0xB3) ) ?\
+: ( 0x8C == ((const U8*)s)[0] || 0x9B == ((const U8*)s)[0] || inRANGE_helper_(U8, ((const U8*)s)[0], 0xB2, 0xB3) ) ?\
     ( ( 0x57 == ((const U8*)s)[1] ) ? 2 : 0 )                               \
 : ( 0x8D == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x4A == ((const U8*)s)[1] ) ? 2 : 0 )                               \
     ( ( ( 0x53 == ((const U8*)s)[1] ) && ( 0x48 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 : ( 0xBF == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x62 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x64, 0x68) || 0x71 == ((const U8*)s)[2] ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x64, 0x68) || 0x71 == ((const U8*)s)[2] ) ? 3 : 0 )\
     : ( 0x68 == ((const U8*)s)[1] ) ?                                       \
        ( ( 0x57 == ((const U8*)s)[2] || 0x59 == ((const U8*)s)[2] || 0x62 == ((const U8*)s)[2] || 0x64 == ((const U8*)s)[2] ) ? 3 : 0 )\
     : ( 0x6A == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x59) || 0x5F == ((const U8*)s)[2] || inRANGE(((const U8*)s)[2], 0x62, 0x6A) || inRANGE(((const U8*)s)[2], 0x70, 0x72) ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x59) || 0x5F == ((const U8*)s)[2] || inRANGE_helper_(U8, ((const U8*)s)[2], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x70, 0x72) ) ? 3 : 0 )\
     : ( 0x70 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x41, 0x4A) || inRANGE(((const U8*)s)[2], 0x51, 0x56) || 0x59 == ((const U8*)s)[2] || 0x5F == ((const U8*)s)[2] || 0x62 == ((const U8*)s)[2] || inRANGE(((const U8*)s)[2], 0x64, 0x65) || 0x6A == ((const U8*)s)[2] ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x56) || 0x59 == ((const U8*)s)[2] || 0x5F == ((const U8*)s)[2] || 0x62 == ((const U8*)s)[2] || inRANGE_helper_(U8, ((const U8*)s)[2], 0x64, 0x65) || 0x6A == ((const U8*)s)[2] ) ? 3 : 0 )\
     : ( 0x71 == ((const U8*)s)[1] ) ?                                       \
-       ( ( inRANGE(((const U8*)s)[2], 0x43, 0x45) || inRANGE(((const U8*)s)[2], 0x47, 0x48) || 0x53 == ((const U8*)s)[2] || 0x59 == ((const U8*)s)[2] || 0x5F == ((const U8*)s)[2] || inRANGE(((const U8*)s)[2], 0x64, 0x65) ) ? 3 : 0 )\
+       ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x43, 0x45) || inRANGE_helper_(U8, ((const U8*)s)[2], 0x47, 0x48) || 0x53 == ((const U8*)s)[2] || 0x59 == ((const U8*)s)[2] || 0x5F == ((const U8*)s)[2] || inRANGE_helper_(U8, ((const U8*)s)[2], 0x64, 0x65) ) ? 3 : 0 )\
     : ( ( 0x72 == ((const U8*)s)[1] ) && ( ( ( ((const U8*)s)[2] & 0xFB ) == 0x43 ) || ( ( ((const U8*)s)[2] & 0xDE ) == 0x44 ) || ((const U8*)s)[2] == 0x48 || ((const U8*)s)[2] == 0x59 || ((const U8*)s)[2] == 0x5F || ( ( ((const U8*)s)[2] & '7' ) == 0x62 ) ) ) ? 3 : 0 )\
-: ( ( ( ( 0xDD == ((const U8*)s)[0] ) && ( 0x71 == ((const U8*)s)[1] ) ) && ( 0x66 == ((const U8*)s)[2] ) ) && ( inRANGE(((const U8*)s)[3], 0x41, 0x47) || 0x5F == ((const U8*)s)[3] || inRANGE(((const U8*)s)[3], 0x62, 0x65) ) ) ? 4 : 0 )
+: ( ( ( ( 0xDD == ((const U8*)s)[0] ) && ( 0x71 == ((const U8*)s)[1] ) ) && ( 0x66 == ((const U8*)s)[2] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x41, 0x47) || 0x5F == ((const U8*)s)[3] || inRANGE_helper_(U8, ((const U8*)s)[3], 0x62, 0x65) ) ) ? 4 : 0 )
 
 /*
        PROBLEMATIC_LOCALE_FOLD: characters whose fold is problematic under locale
 */
 /*** GENERATED CODE ***/
 #define is_PROBLEMATIC_LOCALE_FOLD_utf8(s)                                  \
-( ( ( ((const U8*)s)[0] <= ' ' ) || inRANGE(((const U8*)s)[0], '.', '&') || inRANGE(((const U8*)s)[0], '!', ';') || inRANGE(((const U8*)s)[0], '-', '/') || inRANGE(((const U8*)s)[0], ',', '?') || inRANGE(((const U8*)s)[0], '`', '"') || inRANGE(((const U8*)s)[0], 'a', 'i') || inRANGE(((const U8*)s)[0], 'j', 'r') || inRANGE(((const U8*)s)[0], '~', 'z') || '^' == ((const U8*)s)[0] || inRANGE(((const U8*)s)[0], '[', ']') || inRANGE(((const U8*)s)[0], '{', 'I') || inRANGE(((const U8*)s)[0], '}', 'R') || '\\' == ((const U8*)s)[0] || inRANGE(((const U8*)s)[0], 'S', 'Z') || inRANGE(((const U8*)s)[0], '0', '9') || 0xFF == ((const U8*)s)[0] ) ? 1\
+( ( ( ((const U8*)s)[0] <= ' ' ) || inRANGE_helper_(U8, ((const U8*)s)[0], '.', '&') || inRANGE_helper_(U8, ((const U8*)s)[0], '!', ';') || inRANGE_helper_(U8, ((const U8*)s)[0], '-', '/') || inRANGE_helper_(U8, ((const U8*)s)[0], ',', '?') || inRANGE_helper_(U8, ((const U8*)s)[0], '`', '"') || inRANGE_helper_(U8, ((const U8*)s)[0], 'a', 'i') || inRANGE_helper_(U8, ((const U8*)s)[0], 'j', 'r') || inRANGE_helper_(U8, ((const U8*)s)[0], '~', 'z') || '^' == ((const U8*)s)[0] || inRANGE_helper_(U8, ((const U8*)s)[0], '[', ']') || inRANGE_helper_(U8, ((const U8*)s)[0], '{', 'I') || inRANGE_helper_(U8, ((const U8*)s)[0], '}', 'R') || '\\' == ((const U8*)s)[0] || inRANGE_helper_(U8, ((const U8*)s)[0], 'S', 'Z') || inRANGE_helper_(U8, ((const U8*)s)[0], '0', '9') || 0xFF == ((const U8*)s)[0] ) ? 1\
 : ( 0x78 == ((const U8*)s)[0] || 0x80 == ((const U8*)s)[0] || 0x8A == ((const U8*)s)[0] ) ?\
-    ( ( inRANGE(((const U8*)s)[1], 0x41, 0x4A) || inRANGE(((const U8*)s)[1], 0x51, 0x59) || 0x5F == ((const U8*)s)[1] || inRANGE(((const U8*)s)[1], 0x62, 0x6A) || inRANGE(((const U8*)s)[1], 0x70, 0x72) ) ? 2 : 0 )\
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x51, 0x59) || 0x5F == ((const U8*)s)[1] || inRANGE_helper_(U8, ((const U8*)s)[1], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x70, 0x72) ) ? 2 : 0 )\
 : ( 0x8C == ((const U8*)s)[0] ) ?                                           \
-    ( ( inRANGE(((const U8*)s)[1], 0x57, 0x58) ) ? 2 : 0 )                  \
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x57, 0x58) ) ? 2 : 0 )      \
 : ( 0x8D == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x4A == ((const U8*)s)[1] ) ? 2 : 0 )                               \
 : ( 0x8E == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x57 == ((const U8*)s)[1] ) ? 2 : 0 )                               \
 : ( 0xAD == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x48 == ((const U8*)s)[1] ) ? 2 : 0 )                               \
-: ( inRANGE(((const U8*)s)[0], 0xB2, 0xB3) ) ?                              \
+: ( inRANGE_helper_(U8, ((const U8*)s)[0], 0xB2, 0xB3) ) ?                  \
     ( ( 0x6A == ((const U8*)s)[1] ) ? 2 : 0 )                               \
 : ( 0xBF == ((const U8*)s)[0] ) ?                                           \
-    ( ( ( 0x62 == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x64, 0x68) || 0x71 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
+    ( ( ( 0x62 == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x64, 0x68) || 0x71 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 : ( 0xCA == ((const U8*)s)[0] ) ?                                           \
-    ( ( ( 0x4A == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x51, 0x52) ) ) ? 3 : 0 )\
-: ( ( ( ( 0xDD == ((const U8*)s)[0] ) && ( 0x71 == ((const U8*)s)[1] ) ) && ( 0x66 == ((const U8*)s)[2] ) ) && ( inRANGE(((const U8*)s)[3], 0x41, 0x47) ) ) ? 4 : 0 )
+    ( ( ( 0x4A == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x52) ) ) ? 3 : 0 )\
+: ( ( ( ( 0xDD == ((const U8*)s)[0] ) && ( 0x71 == ((const U8*)s)[1] ) ) && ( 0x66 == ((const U8*)s)[2] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x41, 0x47) ) ) ? 4 : 0 )
 
 /*** GENERATED CODE ***/
 #define is_PROBLEMATIC_LOCALE_FOLD_cp(cp)                                   \
 ( cp <= 0xFF || ( 0xFF < cp &&                                              \
-( 0x130 == cp || ( 0x130 < cp &&                                            \
-( 0x131 == cp || ( 0x131 < cp &&                                            \
+( inRANGE_helper_(UV, cp, 0x130, 0x131) || ( 0x131 < cp &&                  \
 ( 0x149 == cp || ( 0x149 < cp &&                                            \
 ( 0x178 == cp || ( 0x178 < cp &&                                            \
 ( 0x17F == cp || ( 0x17F < cp &&                                            \
 ( 0x307 == cp || ( 0x307 < cp &&                                            \
 ( 0x39C == cp || ( 0x39C < cp &&                                            \
 ( 0x3BC == cp || ( 0x3BC < cp &&                                            \
-( inRANGE(cp, 0x1E96, 0x1E9A) || ( 0x1E9A < cp &&                           \
+( inRANGE_helper_(UV, cp, 0x1E96, 0x1E9A) || ( 0x1E9A < cp &&               \
 ( 0x1E9E == cp || ( 0x1E9E < cp &&                                          \
-( 0x212A == cp || ( 0x212A < cp &&                                          \
-( 0x212B == cp || inRANGE(cp, 0xFB00, 0xFB06) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )
+( inRANGE_helper_(UV, cp, 0x212A, 0x212B) || inRANGE_helper_(UV, cp, 0xFB00, 0xFB06) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )
 
 /*
        PROBLEMATIC_LOCALE_FOLDEDS_START: The first folded character of folds which are problematic under locale
 */
 /*** GENERATED CODE ***/
 #define is_PROBLEMATIC_LOCALE_FOLDEDS_START_utf8(s)                         \
-( ( ( ((const U8*)s)[0] <= ' ' ) || inRANGE(((const U8*)s)[0], '.', '&') || inRANGE(((const U8*)s)[0], '!', ';') || inRANGE(((const U8*)s)[0], '-', '/') || inRANGE(((const U8*)s)[0], ',', '?') || inRANGE(((const U8*)s)[0], '`', '"') || inRANGE(((const U8*)s)[0], 'a', 'i') || inRANGE(((const U8*)s)[0], 'j', 'r') || inRANGE(((const U8*)s)[0], '~', 'z') || '^' == ((const U8*)s)[0] || inRANGE(((const U8*)s)[0], '[', ']') || inRANGE(((const U8*)s)[0], '{', 'I') || inRANGE(((const U8*)s)[0], '}', 'R') || '\\' == ((const U8*)s)[0] || inRANGE(((const U8*)s)[0], 'S', 'Z') || inRANGE(((const U8*)s)[0], '0', '9') || 0xFF == ((const U8*)s)[0] ) ? 1\
+( ( ( ((const U8*)s)[0] <= ' ' ) || inRANGE_helper_(U8, ((const U8*)s)[0], '.', '&') || inRANGE_helper_(U8, ((const U8*)s)[0], '!', ';') || inRANGE_helper_(U8, ((const U8*)s)[0], '-', '/') || inRANGE_helper_(U8, ((const U8*)s)[0], ',', '?') || inRANGE_helper_(U8, ((const U8*)s)[0], '`', '"') || inRANGE_helper_(U8, ((const U8*)s)[0], 'a', 'i') || inRANGE_helper_(U8, ((const U8*)s)[0], 'j', 'r') || inRANGE_helper_(U8, ((const U8*)s)[0], '~', 'z') || '^' == ((const U8*)s)[0] || inRANGE_helper_(U8, ((const U8*)s)[0], '[', ']') || inRANGE_helper_(U8, ((const U8*)s)[0], '{', 'I') || inRANGE_helper_(U8, ((const U8*)s)[0], '}', 'R') || '\\' == ((const U8*)s)[0] || inRANGE_helper_(U8, ((const U8*)s)[0], 'S', 'Z') || inRANGE_helper_(U8, ((const U8*)s)[0], '0', '9') || 0xFF == ((const U8*)s)[0] ) ? 1\
 : ( 0x78 == ((const U8*)s)[0] || 0x80 == ((const U8*)s)[0] || 0x8A == ((const U8*)s)[0] ) ?\
-    ( ( inRANGE(((const U8*)s)[1], 0x41, 0x4A) || inRANGE(((const U8*)s)[1], 0x51, 0x59) || 0x5F == ((const U8*)s)[1] || inRANGE(((const U8*)s)[1], 0x62, 0x6A) || inRANGE(((const U8*)s)[1], 0x70, 0x72) ) ? 2 : 0 )\
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x41, 0x4A) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x51, 0x59) || 0x5F == ((const U8*)s)[1] || inRANGE_helper_(U8, ((const U8*)s)[1], 0x62, 0x6A) || inRANGE_helper_(U8, ((const U8*)s)[1], 0x70, 0x72) ) ? 2 : 0 )\
 : ( 0x8C == ((const U8*)s)[0] ) ?                                           \
-    ( ( inRANGE(((const U8*)s)[1], 0x57, 0x58) ) ? 2 : 0 )                  \
+    ( ( inRANGE_helper_(U8, ((const U8*)s)[1], 0x57, 0x58) ) ? 2 : 0 )      \
 : ( 0x8D == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x4A == ((const U8*)s)[1] ) ? 2 : 0 )                               \
 : ( 0x8E == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x66 == ((const U8*)s)[1] || 0x72 == ((const U8*)s)[1] ) ? 2 : 0 )  \
 : ( 0x9B == ((const U8*)s)[0] ) ?                                           \
     ( ( 0x57 == ((const U8*)s)[1] ) ? 2 : 0 )                               \
-: ( 0xAA == ((const U8*)s)[0] || inRANGE(((const U8*)s)[0], 0xB2, 0xB3) ) ? \
+: ( 0xAA == ((const U8*)s)[0] || inRANGE_helper_(U8, ((const U8*)s)[0], 0xB2, 0xB3) ) ?\
     ( ( 0x6A == ((const U8*)s)[1] ) ? 2 : 0 )                               \
 : ( 0xBF == ((const U8*)s)[0] ) ?                                           \
-    ( ( ( 0x62 == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x64, 0x68) || 0x71 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
+    ( ( ( 0x62 == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x64, 0x68) || 0x71 == ((const U8*)s)[2] ) ) ? 3 : 0 )\
 : ( 0xCA == ((const U8*)s)[0] ) ?                                           \
-    ( ( ( 0x4A == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x51, 0x52) ) ) ? 3 : 0 )\
-: ( ( ( ( 0xDD == ((const U8*)s)[0] ) && ( 0x71 == ((const U8*)s)[1] ) ) && ( 0x66 == ((const U8*)s)[2] ) ) && ( inRANGE(((const U8*)s)[3], 0x41, 0x47) ) ) ? 4 : 0 )
+    ( ( ( 0x4A == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x51, 0x52) ) ) ? 3 : 0 )\
+: ( ( ( ( 0xDD == ((const U8*)s)[0] ) && ( 0x71 == ((const U8*)s)[1] ) ) && ( 0x66 == ((const U8*)s)[2] ) ) && ( inRANGE_helper_(U8, ((const U8*)s)[3], 0x41, 0x47) ) ) ? 4 : 0 )
 
 /*** GENERATED CODE ***/
 #define is_PROBLEMATIC_LOCALE_FOLDEDS_START_cp(cp)                          \
 ( cp <= 0xFF || ( 0xFF < cp &&                                              \
-( 0x130 == cp || ( 0x130 < cp &&                                            \
-( 0x131 == cp || ( 0x131 < cp &&                                            \
+( inRANGE_helper_(UV, cp, 0x130, 0x131) || ( 0x131 < cp &&                  \
 ( 0x149 == cp || ( 0x149 < cp &&                                            \
 ( 0x178 == cp || ( 0x178 < cp &&                                            \
 ( 0x17F == cp || ( 0x17F < cp &&                                            \
 ( 0x2BC == cp || ( 0x2BC < cp &&                                            \
 ( 0x39C == cp || ( 0x39C < cp &&                                            \
 ( 0x3BC == cp || ( 0x3BC < cp &&                                            \
-( inRANGE(cp, 0x1E96, 0x1E9A) || ( 0x1E9A < cp &&                           \
+( inRANGE_helper_(UV, cp, 0x1E96, 0x1E9A) || ( 0x1E9A < cp &&               \
 ( 0x1E9E == cp || ( 0x1E9E < cp &&                                          \
-( 0x212A == cp || ( 0x212A < cp &&                                          \
-( 0x212B == cp || inRANGE(cp, 0xFB00, 0xFB06) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )
+( inRANGE_helper_(UV, cp, 0x212A, 0x212B) || inRANGE_helper_(UV, cp, 0xFB00, 0xFB06) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )
 
 /*
        PATWS: pattern white space
 /*** GENERATED CODE ***/
 #define is_PATWS_safe(s,e,is_utf8)                                          \
 ( ( LIKELY((e) > (s)) ) ?                                                   \
-    ( ( '\t' == ((const U8*)s)[0] || inRANGE(((const U8*)s)[0], '\v', '\r') || 0x15 == ((const U8*)s)[0] || '\n' == ((const U8*)s)[0] || ' ' == ((const U8*)s)[0] ) ? 1\
+    ( ( '\t' == ((const U8*)s)[0] || inRANGE_helper_(U8, ((const U8*)s)[0], '\v', '\r') || 0x15 == ((const U8*)s)[0] || '\n' == ((const U8*)s)[0] || ' ' == ((const U8*)s)[0] ) ? 1\
     : ( ( is_utf8 && LIKELY(((e) - (s)) >= UTF8SKIP(s)) ) && ( 0xCA == ((const U8*)s)[0] ) ) ? ( ( 0x41 == ((const U8*)s)[1] ) ?\
-                   ( ( inRANGE(((const U8*)s)[2], 0x55, 0x56) ) ? 3 : 0 )  \
-               : ( ( 0x42 == ((const U8*)s)[1] ) && ( inRANGE(((const U8*)s)[2], 0x49, 0x4A) ) ) ? 3 : 0 ) : 0 )\
+                   ( ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x55, 0x56) ) ? 3 : 0 )\
+               : ( ( 0x42 == ((const U8*)s)[1] ) && ( inRANGE_helper_(U8, ((const U8*)s)[2], 0x49, 0x4A) ) ) ? 3 : 0 ) : 0 )\
 : 0 )
 
 #endif /* EBCDIC 037 */
  * ee0dd174fd5b158d82dfea95d7d822ca0bfcd490182669353dca3ab39a8ee807 lib/unicore/mktables
  * 50b85a67451145545a65cea370dab8d3444fbfe07e9c34cef560c5b7da9d3eef lib/unicore/version
  * 2680b9254eb236c5c090f11b149605043e8c8433661b96efc4a42fb4709342a5 regen/charset_translations.pl
- * 60185ff63360b1d3fc0c8df02a8493e63ea0283966612be245c30ff8f05b48db regen/regcharclass.pl
- * c0a5e4cb2b9ffad78691938e122c1310bbc98aca2364af243e5c6b2ec0f59dc3 regen/regcharclass_multi_char_folds.pl
+ * f0ac417314b8da8e05d386ca3d0d8074e38ecd9dc77a7d966aa48ec4ec247e2a regen/regcharclass.pl
+ * b2f896452d2b30da3e04800f478c60c1fd0b03d6b668689b020f1e3cf1f1cdd9 regen/regcharclass_multi_char_folds.pl
  * ex: set ro: */
index 853501c..d2433a4 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -143,13 +143,6 @@ EXTERN_C const struct regexp_engine wild_reg_engine;
 #include "invlist_inline.h"
 #include "unicode_constants.h"
 
-#define HAS_NONLATIN1_FOLD_CLOSURE(i) \
- _HAS_NONLATIN1_FOLD_CLOSURE_ONLY_FOR_USE_BY_REGCOMP_DOT_C_AND_REGEXEC_DOT_C(i)
-#define HAS_NONLATIN1_SIMPLE_FOLD_CLOSURE(i) \
- _HAS_NONLATIN1_SIMPLE_FOLD_CLOSURE_ONLY_FOR_USE_BY_REGCOMP_DOT_C_AND_REGEXEC_DOT_C(i)
-#define IS_NON_FINAL_FOLD(c) _IS_NON_FINAL_FOLD_ONLY_FOR_USE_BY_REGCOMP_DOT_C(c)
-#define IS_IN_SOME_FOLD_L1(c) _IS_IN_SOME_FOLD_ONLY_FOR_USE_BY_REGCOMP_DOT_C(c)
-
 #ifndef STATIC
 #define        STATIC  static
 #endif
@@ -2133,8 +2126,6 @@ S_ssc_clear_locale(regnode_ssc *ssc)
     ANYOF_FLAGS(ssc) &= ~ANYOF_LOCALE_FLAGS;
 }
 
-#define NON_OTHER_COUNT   NON_OTHER_COUNT_FOR_USE_ONLY_BY_REGCOMP_DOT_C
-
 STATIC bool
 S_is_ssc_worth_it(const RExC_state_t * pRExC_state, const regnode_ssc * ssc)
 {
@@ -21813,8 +21804,6 @@ Perl_regfree_internal(pTHX_ REGEXP * const rx)
                      Used in stclass optimization only */
                     U32 refcount;
                     reg_ac_data *aho=(reg_ac_data*)ri->data->data[n];
-#ifdef USE_ITHREADS
-#endif
                     OP_REFCNT_LOCK;
                     refcount = --aho->refcount;
                     OP_REFCNT_UNLOCK;
@@ -21841,8 +21830,6 @@ Perl_regfree_internal(pTHX_ REGEXP * const rx)
                    /* trie structure. */
                    U32 refcount;
                    reg_trie_data *trie=(reg_trie_data*)ri->data->data[n];
-#ifdef USE_ITHREADS
-#endif
                     OP_REFCNT_LOCK;
                     refcount = --trie->refcount;
                     OP_REFCNT_UNLOCK;
@@ -22237,8 +22224,6 @@ S_put_code_point(pTHX_ SV *sv, UV c)
     }
 }
 
-#define MAX_PRINT_A MAX_PRINT_A_FOR_USE_ONLY_BY_REGCOMP_DOT_C
-
 STATIC void
 S_put_range(pTHX_ SV *sv, UV start, const UV end, const bool allow_literals)
 {
index cbd2979..df66201 100755 (executable)
@@ -17,6 +17,7 @@
 # This script is normally invoked from regen.pl.
 
 use strict;
+my $restrict_to_core = "if defined(PERL_CORE) || defined(PERL_EXT)";
 
 BEGIN {
     # Get function prototypes
@@ -917,6 +918,7 @@ require './regen/op_private';
 #use Data::Dumper;
 #print Dumper \%LABELS, \%DEFINES, \%FLAGS, \%BITFIELDS;
 
+print $oc "#$restrict_to_core\n\n";
 
 # Emit defines.
 
@@ -954,6 +956,7 @@ require './regen/op_private';
     # If the last op was conditional, we need to close it out:
     unimplemented();
 }
+print $oc "\n#endif /* End of $restrict_to_core */\n\n";
 
 print $on "typedef enum opcode {\n";
 
index 56fa7dd..5fd8e25 100755 (executable)
@@ -366,6 +366,7 @@ my %n2a;    # Inversion of a2n, for each character set
 sub new {
     my $class= shift;
     my %opt= @_;
+    my %hash_return;
     for ( qw(op txt) ) {
         die "in " . __PACKAGE__ . " constructor '$_;' is a mandatory field"
           if !exists $opt{$_};
@@ -437,19 +438,31 @@ sub new {
             die "eval '$1' failed: $@" if $@;
             push @{$opt{txt}}, @results;
             next;
+        } elsif ($str =~ / ^ % \s* ( .* ) /x) { # user-furnished sub() call
+            %hash_return = eval "$1";
+            die "eval '$1' failed: $@" if $@;
+            push @{$opt{txt}}, keys %hash_return;
+            die "Only one multi character expansion currently allowed per rule"
+                                                        if  $self->{multi_maps};
+            next;
         } else {
             die "Unparsable line: $txt\n";
         }
         my ( $cp, $cp_high, $low, $latin1, $utf8 )
                                         = __uni_latin1($charset, $a2n, $str );
+        my $from;
+        if (defined $hash_return{"\"$str\""}) {
+            $from = $hash_return{"\"$str\""};
+            $from = $a2n->[$from] if $from < 256;
+        }
         my $UTF8= $low   || $utf8;
         my $LATIN1= $low || $latin1;
         my $high = (scalar grep { $_ < 256 } @$cp) ? 0 : $utf8;
         #die Dumper($txt,$cp,$low,$latin1,$utf8)
         #    if $txt=~/NEL/ or $utf8 and @$utf8>3;
 
-        @{ $self->{strs}{$str} }{qw( str txt low utf8 latin1 high cp cp_high UTF8 LATIN1 )}=
-          ( $str, $txt, $low, $utf8, $latin1, $high, $cp, $cp_high, $UTF8, $LATIN1 );
+        @{ $self->{strs}{$str} }{qw( str txt low utf8 latin1 high cp cp_high UTF8 LATIN1 from )}=
+          ( $str, $txt, $low, $utf8, $latin1, $high, $cp, $cp_high, $UTF8, $LATIN1, $from );
         my $rec= $self->{strs}{$str};
         foreach my $key ( qw(low utf8 latin1 high cp cp_high UTF8 LATIN1) ) {
             $self->{size}{$key}{ 0 + @{ $self->{strs}{$str}{$key} } }++
@@ -522,9 +535,6 @@ sub pop_count ($) {
 sub _optree {
     my ( $self, $trie, $test_type, $ret_type, $else, $depth )= @_;
     return unless defined $trie;
-    if ( $self->{has_multi} and $ret_type =~ /cp|both/ ) {
-        die "Can't do 'cp' optree from multi-codepoint strings";
-    }
     $ret_type ||= 'len';
     $else= 0  unless defined $else;
     $depth= 0 unless defined $depth;
@@ -535,13 +545,16 @@ sub _optree {
     if (exists $trie->{''} ) {
         # we can now update the "else" value, anything failing to match
         # after this point should return the value from this.
+        my $prefix = $self->{strs}{ $trie->{''} };
         if ( $ret_type eq 'cp' ) {
-            $else= $self->{strs}{ $trie->{''} }{cp}[0];
+            $else= $prefix->{from};
+            $else= $self->{strs}{ $trie->{''} }{cp}[0] unless defined $else;
             $else= $self->val_fmt($else) if $else > 9;
         } elsif ( $ret_type eq 'len' ) {
             $else= $depth;
         } elsif ( $ret_type eq 'both') {
-            $else= $self->{strs}{ $trie->{''} }{cp}[0];
+            $else= $prefix->{from};
+            $else= $self->{strs}{ $trie->{''} }{cp}[0] unless defined $else;
             $else= $self->val_fmt($else) if $else > 9;
             $else= "len=$depth, $else";
         }
@@ -1049,25 +1062,26 @@ sub _cond_as_str {
     my $is_cp_ret = $opts_ref->{ret_type} eq "cp";
     return "( $test )" if !defined $cond;
 
-    # rangify the list.
+    # rangify the list.  As we encounter a new value, it is placed in a new
+    # subarray by itself.  If the next value is adjacent to it, the end point
+    # of the subarray is merely incremented; and so on.  When the next value
+    # that isn't adjacent to the previous one is encountered, Update() is
+    # called to hoist any single-element subarray to be a scalar.
     my @ranges;
     my $Update= sub {
         # We skip this if there are optimizations that
         # we can apply (below) to the individual ranges
         if ( ($is_cp_ret || $combine) && @ranges && ref $ranges[-1]) {
-            if ( $ranges[-1][0] == $ranges[-1][1] ) {
-                $ranges[-1]= $ranges[-1][0];
-            } elsif ( $ranges[-1][0] + 1 == $ranges[-1][1] ) {
-                $ranges[-1]= $ranges[-1][0];
-                push @ranges, $ranges[-1] + 1;
-            }
+            $ranges[-1] = $ranges[-1][0] if $ranges[-1][0] == $ranges[-1][1];
         }
     };
     for my $condition ( @$cond ) {
         if ( !@ranges || $condition != $ranges[-1][1] + 1 ) {
+            # Not adjacent to the existing range.  Remove that from being a
+            # range if only a single value;
             $Update->();
             push @ranges, [ $condition, $condition ];
-        } else {
+        } else {    # Adjacent to the existing range; add to the range
             $ranges[-1][1]++;
         }
     }
@@ -1076,22 +1090,8 @@ sub _cond_as_str {
     return $self->_combine( $test, @ranges )
       if $combine;
 
-    if ($is_cp_ret) {
-        @ranges= map {
-            ref $_
-            ?   "isRANGE( $test, "
-              . $self->val_fmt($_[0]) . ", "
-              . $self->val_fmt($_[1]) . " )"
-            : $self->val_fmt($_) . " == $test";
-        } @ranges;
-
-        return "( " . join( " || ", @ranges ) . " )";
-    }
-
     # If the input set has certain characteristics, we can optimize tests
-    # for it.  This doesn't apply if returning the code point, as we want
-    # each element of the set individually.  The code above is for this
-    # simpler case.
+    # for it.
 
     return 1 if @$cond == 256;  # If all bytes match, is trivially true
 
@@ -1182,7 +1182,7 @@ sub _cond_as_str {
             # bounds.  But inRANGE() allows us to have a single conditional,
             # so the only cost of making sure it's a legal UTF-8 continuation
             # byte is an extra subtraction instruction, a trivial expense.
-            $ranges[$i] = "inRANGE($test, "
+            $ranges[$i] = "inRANGE_helper_(U8, $test, "
                         . $self->val_fmt($ranges[$i]->[0]) .", "
                         . $self->val_fmt($ranges[$i]->[1]) . ")";
         }
@@ -1215,7 +1215,7 @@ sub _combine {
             $cstr= "$test <= " . $self->val_fmt($item->[1]);
         }
         else {
-            $cstr = "inRANGE($test, "
+            $cstr = "inRANGE_helper_(UV, $test, "
                   . $self->val_fmt($item->[0]) . ", "
                   . $self->val_fmt($item->[1]) . ")";
         }
@@ -1661,36 +1661,36 @@ QUOTEMETA: Meta-characters that \Q should quote
 \p{_Perl_Quotemeta}
 
 MULTI_CHAR_FOLD: multi-char strings that are folded to by a single character
-=> UTF8 :safe
-&regcharclass_multi_char_folds::multi_char_folds('u', 'a')
+=> UTF8 UTF8-cp :safe
+%regcharclass_multi_char_folds::multi_char_folds('u', 'a')
 
 MULTI_CHAR_FOLD: multi-char strings that are folded to by a single character
-=> LATIN1 : safe
-&regcharclass_multi_char_folds::multi_char_folds('l', 'a')
+=> LATIN1 LATIN1-cp : safe
+%regcharclass_multi_char_folds::multi_char_folds('l', 'a')
 
 THREE_CHAR_FOLD: A three-character multi-char fold
 => UTF8 :safe
-&regcharclass_multi_char_folds::multi_char_folds('u', '3')
+%regcharclass_multi_char_folds::multi_char_folds('u', '3')
 
 THREE_CHAR_FOLD: A three-character multi-char fold
 => LATIN1 :safe
-&regcharclass_multi_char_folds::multi_char_folds('l', '3')
+%regcharclass_multi_char_folds::multi_char_folds('l', '3')
 
 THREE_CHAR_FOLD_HEAD: The first two of three-character multi-char folds
 => UTF8 :safe
-&regcharclass_multi_char_folds::multi_char_folds('u', 'h')
+%regcharclass_multi_char_folds::multi_char_folds('u', 'h')
 
 THREE_CHAR_FOLD_HEAD: The first two of three-character multi-char folds
 => LATIN1 :safe
-&regcharclass_multi_char_folds::multi_char_folds('l', 'h')
+%regcharclass_multi_char_folds::multi_char_folds('l', 'h')
 #
 #THREE_CHAR_FOLD_NON_FINAL: The first or middle character of multi-char folds
 #=> UTF8 :safe
-#&regcharclass_multi_char_folds::multi_char_folds('u', 'fm')
+#%regcharclass_multi_char_folds::multi_char_folds('u', 'fm')
 #
 #THREE_CHAR_FOLD_NON_FINAL: The first or middle character of multi-char folds
 #=> LATIN1 :safe
-#&regcharclass_multi_char_folds::multi_char_folds('l', 'fm')
+#%regcharclass_multi_char_folds::multi_char_folds('l', 'fm')
 
 FOLDS_TO_MULTI: characters that fold to multi-char strings
 => UTF8 :fast
index a72e149..e7c6fb9 100644 (file)
@@ -42,6 +42,7 @@ sub gen_combinations ($;) {
     my @ret;
 
     # Look at each element in this level's array.
+    if (ref $fold_ref->[$i]) {
     foreach my $j (0 .. @{$fold_ref->[$i]} - 1) {
 
         # Append its representation to what we have currently
@@ -56,6 +57,7 @@ sub gen_combinations ($;) {
             push @ret, &gen_combinations($fold_ref, $new_string, $i + 1);
         }
     }
+    }
 
     return @ret;
 }
@@ -87,7 +89,7 @@ sub multi_char_folds ($$) {
     }
 
     my @folds;
-    my @output_folds;
+    my %output_folds;
 
     for my $i (0 .. @$folds_ref - 1) {
         next unless ref $folds_ref->[$i];   # Skip single-char folds
@@ -122,10 +124,8 @@ sub multi_char_folds ($$) {
         $fold = "\"$fold\"";
 
         # Skip if something else already has this fold
-        next if grep { $_ eq $fold } @output_folds;
+        next if grep { $_ eq $fold } keys %output_folds;
 
-        # If the fold is to a cased letter, replace the entry with an
-        # array which also includes its upper case.
         my $this_fold_ref = \@folds;
         for my $j (0 .. @$this_fold_ref - 1) {
             my $this_ord = $this_fold_ref->[$j];
@@ -143,8 +143,7 @@ sub multi_char_folds ($$) {
         }
 
         # Then generate all combinations of upper/lower case of the fold.
-        push @output_folds, gen_combinations($this_fold_ref);
-
+        $output_folds{$_} = $cp_ref->[$i] for gen_combinations($this_fold_ref);
     }
 
     # \x17F is the small LONG S, which folds to 's'.  Both Capital and small
@@ -167,9 +166,9 @@ sub multi_char_folds ($$) {
     #
     # No combinations of this with 's' need be added, as any of these
     # containing 's' are prohibited under /iaa.
-    push @output_folds, '"\x{17F}\x{17F}"' if $type eq 'u' && $range eq 'a';
+    $output_folds{"\"\x{17F}\x{17F}\""} = 0xDF if $type eq 'u' && $range eq 'a';
 
-    return @output_folds;
+    return %output_folds;
 }
 
 1
index 34e7ec8..4994a8b 100644 (file)
@@ -397,9 +397,10 @@ sub print_state_def_line
     my $hanging = length $line;     # Indent any subsequent line to this pos
     $line .= sprintf "0x%02x", $id;
 
-    my $columns = 79;
+    my $columns = 78;
 
-    # wrap() needs 80 to achieve 79.
+    # From the documentation: 'In fact, every resulting line will have length
+    # of no more than "$columns - 1"'
     $line = wrap($columns + 1, "", " " x $hanging, "$line $comment");
     chomp $line;            # wrap always adds a trailing \n
     $line =~ s/ \s+ $ //x;  # trim, just in case.
index aba447a..44c633e 100644 (file)
@@ -162,9 +162,15 @@ foreach my $charset (get_supported_code_pages()) {
     for my $i (0x20 .. 0x7E) {
         $max_PRINT_A = $a2n[$i] if $a2n[$i] > $max_PRINT_A;
     }
-    printf $out_fh "#   define MAX_PRINT_A_FOR_USE_ONLY_BY_REGCOMP_DOT_C   0x%02X   /* The max code point that isPRINT_A */\n", $max_PRINT_A;
+    $max_PRINT_A = sprintf "0x%02X", $max_PRINT_A;
+    print $out_fh <<"EOT";
 
-    print $out_fh "\n" . get_conditional_compile_line_end();
+#    ifdef PERL_IN_REGCOMP_C
+#      define MAX_PRINT_A  $max_PRINT_A   /* The max code point that isPRINT_A */
+#    endif
+EOT
+
+    print $out_fh get_conditional_compile_line_end();
 
 }
 
@@ -178,9 +184,14 @@ for (my $i = 0; $i < @other_invlist; $i += 2) {
               : 0x110000)
               - $other_invlist[$i];
 }
-printf $out_fh "\n/* The number of code points not matching \\pC */\n"
-             . "#define NON_OTHER_COUNT_FOR_USE_ONLY_BY_REGCOMP_DOT_C  %d\n",
-            0x110000 - $count;
+$count = 0x110000 - $count;
+print $out_fh <<~"EOT";
+
+    /* The number of code points not matching \\pC */
+    #ifdef PERL_IN_REGCOMP_C
+    #  define NON_OTHER_COUNT  $count
+    #endif
+    EOT
 
 # If this release has both the CWCM and CWCF properties, find the highest code
 # point which changes under any case change.  We can use this to short-circuit
@@ -192,9 +203,14 @@ if (@cwcm) {
         my $max = ($cwcm[-1] < $cwcf[-1])
                   ? $cwcf[-1]
                   : $cwcm[-1];
-        printf $out_fh "\n/* The highest code point that has any type of case change */\n"
-             . "#define HIGHEST_CASE_CHANGING_CP_FOR_USE_ONLY_BY_UTF8_DOT_C  0x%X\n",
-            $max - 1;
+        $max = sprintf "0x%X", $max - 1;
+        print $out_fh <<~"EOS";
+
+            /* The highest code point that has any type of case change */
+            #ifdef PERL_IN_UTF8_C
+            #  define HIGHEST_CASE_CHANGING_CP  $max
+            #endif
+            EOS
     }
 }
 
index cf07974..498b93e 100644 (file)
@@ -16,7 +16,7 @@
 #
 # This script is normally invoked from regen.pl.
 
-$VERSION = '1.48';
+$VERSION = '1.49';
 
 BEGIN {
     require './regen/regen_lib.pl';
@@ -639,16 +639,24 @@ sub bits
 
 sub import
 {
-    shift;
-
-    my $mask = ${^WARNING_BITS} // ($^W ? $Bits{all} : $DEFAULT) ;
+    my $invocant = shift;
 
     # append 'all' when implied (empty import list or after a lone
     # "FATAL" or "NONFATAL")
     push @_, 'all'
-       if !@_ || (@_==1 && ($_[0] eq 'FATAL' || $_[0] eq 'NONFATAL'));
-
-    ${^WARNING_BITS} = _bits($mask, @_);
+        if !@_ || (@_==1 && ($_[0] eq 'FATAL' || $_[0] eq 'NONFATAL'));
+
+    my @fatal = ();
+    foreach my $warning (@_) {
+        if($warning =~ /^(NON)?FATAL$/) {
+            @fatal = ($warning);
+        } elsif(substr($warning, 0, 1) ne '-') {
+            my $mask = ${^WARNING_BITS} // ($^W ? $Bits{all} : $DEFAULT) ;
+            ${^WARNING_BITS} = _bits($mask, @fatal, $warning);
+        } else {
+            $invocant->unimport(substr($warning, 1));
+        }
+    }
 }
 
 sub unimport
@@ -875,7 +883,10 @@ warnings - Perl pragma to control optional warnings
     no warnings;
 
     use warnings "all";
-    no warnings "all";
+    no warnings "uninitialized";
+
+    # or equivalent to those last two ...
+    use warnings qw(all -uninitialized);
 
     use warnings::register;
     if (warnings::enabled()) {
@@ -962,6 +973,41 @@ be reported for the C<$x> variable.
 Note that neither the B<-w> flag or the C<$^W> can be used to
 disable/enable default warnings.  They are still mandatory in this case.
 
+=head2 "Negative warnings"
+
+As a convenience, you can (as of Perl 5.34) pass arguments to the
+C<import()> method both positively and negatively. Negative warnings
+are those with a C<-> sign prepended to their names; positive warnings
+are anything else. This lets you turn on some warnings and turn off
+others in one command. So, assuming that you've already turned on a
+bunch of warnings but want to tweak them a bit in some block, you can
+do this:
+
+    {
+        use warnings qw(uninitialized -redefine);
+        ...
+    }
+
+which is equivalent to:
+
+    {
+        use warnings qw(uninitialized);
+        no warnings qw(redefine);
+        ...
+    }
+
+The argument list is processed in the order you specify. So, for example, if you
+don't want to be warned about use of experimental features, except for C<somefeature>
+that you really dislike, you can say this:
+
+    use warnings qw(all -experimental experimental::somefeature);
+
+which is equivalent to:
+
+    use warnings 'all';
+    no warnings  'experimental';
+    use warnings 'experimental::somefeature';
+
 =head2 What's wrong with B<-w> and C<$^W>
 
 Although very useful, the big problem with using B<-w> on the command
index 044fd28..0abf939 100644 (file)
@@ -76,10 +76,10 @@ EOF
 
 # Don't change this to add new bison versions without testing that the generated
 # files actually work :-) Win32 in particular may not like them. :-(
-unless ($version =~ /\b(2\.[4567]|3\.[0-7])\b/) { die <<EOF; }
+unless ($version =~ /\b(2\.[567]|3\.[0-7])\b/) { die <<EOF; }
 
 You have the wrong version of bison in your path; currently versions
-2.4-2.7 or 3.0-3.7 are known to work.  Try installing
+2.5-2.7 or 3.0-3.7 are known to work.  Try installing
     http://ftp.gnu.org/gnu/bison/bison-3.3.tar.gz
 or similar.  Your bison identifies itself as:
 
index b80c082..597b492 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -118,8 +118,6 @@ static const char non_utf8_target_but_utf8_required[]
     goto target;                                                         \
 } STMT_END
 
-#define HAS_NONLATIN1_FOLD_CLOSURE(i) _HAS_NONLATIN1_FOLD_CLOSURE_ONLY_FOR_USE_BY_REGCOMP_DOT_C_AND_REGEXEC_DOT_C(i)
-
 #ifndef STATIC
 #define        STATIC  static
 #endif
@@ -211,7 +209,7 @@ static const char non_utf8_target_but_utf8_required[]
            rn = (rn->flags == 0) ? NEXTOPER(NEXTOPER(rn)) : rn + ARG(rn); \
        else rn += NEXT_OFF(rn); \
     } \
-} STMT_END 
+} STMT_END
 
 #define SLAB_FIRST(s) (&(s)->states[0])
 #define SLAB_LAST(s)  (&(s)->states[PERL_REGMATCH_SLAB_SLOTS-1])
@@ -252,7 +250,7 @@ S_regcppush(pTHX_ const regexp *rex, I32 parenfloor, U32 maxopenparen _pDEPTH)
                    (long)parenfloor);
 
     SSGROW(total_elems + REGCP_FRAME_ELEMS);
-    
+
     DEBUG_BUFFERS_r(
        if ((int)maxopenparen > (int)parenfloor)
             Perl_re_exec_indentf( aTHX_
@@ -1009,7 +1007,7 @@ Perl_re_intuit_start(pTHX_
                /* Substring at constant offset from beg-of-str... */
                SSize_t slen = SvCUR(check);
                 char *s = HOP3c(strpos, prog->check_offset_min, strend);
-           
+
                 DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
                     "  Looking for check substr at fixed offset %" IVdf "...\n",
                     (IV)prog->check_offset_min));
@@ -1055,7 +1053,7 @@ Perl_re_intuit_start(pTHX_
 #endif
 
   restart:
-    
+
     /* This is the (re)entry point of the main loop in this function.
      * The goal of this loop is to:
      * 1) find the "check" substring in the region rx_origin..strend
@@ -1096,7 +1094,7 @@ Perl_re_intuit_start(pTHX_
                 (IV)end_shift,
                 (IV)prog->check_end_shift);
         });
-        
+
         end_point = HOPBACK3(strend, end_shift, rx_origin);
         if (!end_point)
             goto fail_finish;
@@ -1414,7 +1412,7 @@ Perl_re_intuit_start(pTHX_
          * On the one hand you'd expect rare substrings to appear less
          * often than \n's. On the other hand, searching for \n means
          * we're effectively flipping between check_substr and "\n" on each
-         * iteration as the current "rarest" string candidate, which
+         * iteration as the current "rarest" candidate string, which
          * means for example that we'll quickly reject the whole string if
          * hasn't got a \n, rather than trying every substr position
          * first
@@ -1528,9 +1526,9 @@ Perl_re_intuit_start(pTHX_
            rx_max_float = HOP3c(check_at, -start_shift, strbeg);
            endpos = HOP3clim(rx_max_float, cl_l, strend);
         }
-        else 
+        else
             endpos= strend;
-                   
+
         DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
             "  looking for class: start_shift: %" IVdf " check_at: %" IVdf
             " rx_origin: %" IVdf " endpos: %" IVdf "\n",
@@ -2157,7 +2155,7 @@ S_get_break_val_cp_checked(SV* const invlist, const UV cp_in) {
 /* annoyingly all the vars in this routine have different names from their counterparts
    in regmatch. /grrr */
 STATIC char *
-S_find_byclass(pTHX_ regexp * prog, const regnode *c, char *s, 
+S_find_byclass(pTHX_ regexp * prog, const regnode *c, char *s,
     const char *strend, regmatch_info *reginfo)
 {
 
@@ -3673,13 +3671,13 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
     }
 
     multiline = prog->extflags & RXf_PMf_MULTILINE;
-    
+
     if (strend - s < (minlen+(prog->check_offset_min<0?prog->check_offset_min:0))) {
         DEBUG_EXECUTE_r(Perl_re_printf( aTHX_
                              "String too short [regexec_flags]...\n"));
        goto phooey;
     }
-    
+
     /* Check validity of program. */
     if (UCHARAT(progi->program) != REG_MAGIC) {
        Perl_croak(aTHX_ "corrupted regexp program");
@@ -3935,7 +3933,7 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
            back_max = prog->float_max_offset;
            back_min = prog->float_min_offset;
        }
-           
+
         if (back_min<0) {
            last = strend;
        } else {
@@ -3994,7 +3992,7 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
                              ((must == prog->anchored_substr || must == prog->anchored_utf8)
                               ? "anchored" : "floating"),
                 quoted, RE_SV_TAIL(must));
-        });                
+        });
        goto phooey;
     }
     else if ( (c = progi->regstclass) ) {
@@ -4162,7 +4160,7 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
 
     LEAVE_SCOPE(oldsave);
 
-    if (RXp_PAREN_NAMES(prog)) 
+    if (RXp_PAREN_NAMES(prog))
         (void)hv_iterinit(RXp_PAREN_NAMES(prog));
 
     /* make sure $`, $&, $', and $digit will work later */
@@ -4330,33 +4328,33 @@ S_debug_start_match(pTHX_ const REGEXP *prog, const bool utf8_target,
 
     PERL_ARGS_ASSERT_DEBUG_START_MATCH;
 
-    if (!PL_colorset)   
-            reginitcolors();    
+    if (!PL_colorset)
+            reginitcolors();
     {
-        RE_PV_QUOTED_DECL(s0, utf8_pat, PERL_DEBUG_PAD_ZERO(0), 
+        RE_PV_QUOTED_DECL(s0, utf8_pat, PERL_DEBUG_PAD_ZERO(0),
             RX_PRECOMP_const(prog), RX_PRELEN(prog), PL_dump_re_max_len);
-        
+
         RE_PV_QUOTED_DECL(s1, utf8_target, PERL_DEBUG_PAD_ZERO(1),
             start, end - start, PL_dump_re_max_len);
-        
+
         Perl_re_printf( aTHX_
-            "%s%s REx%s %s against %s\n", 
-                      PL_colors[4], blurb, PL_colors[5], s0, s1); 
-        
+            "%s%s REx%s %s against %s\n",
+                      PL_colors[4], blurb, PL_colors[5], s0, s1);
+
         if (utf8_target||utf8_pat)
             Perl_re_printf( aTHX_  "UTF-8 %s%s%s...\n",
                 utf8_pat ? "pattern" : "",
                 utf8_pat && utf8_target ? " and " : "",
                 utf8_target ? "string" : ""
-            ); 
+            );
     }
 }
 
 STATIC void
-S_dump_exec_pos(pTHX_ const char *locinput, 
-                      const regnode *scan, 
-                      const char *loc_regeol, 
-                      const char *loc_bostr, 
+S_dump_exec_pos(pTHX_ const char *locinput,
+                      const regnode *scan,
+                      const char *loc_regeol,
+                      const char *loc_bostr,
                       const char *loc_reg_starttry,
                       const bool utf8_target,
                       const U32 depth
@@ -4394,11 +4392,11 @@ S_dump_exec_pos(pTHX_ const char *locinput,
 
        RE_PV_COLOR_DECL(s0,len0,is_uni,PERL_DEBUG_PAD(0),
            (locinput - pref_len),pref0_len, PL_dump_re_max_len, 4, 5);
-       
+
        RE_PV_COLOR_DECL(s1,len1,is_uni,PERL_DEBUG_PAD(1),
                    (locinput - pref_len + pref0_len),
                    pref_len - pref0_len, PL_dump_re_max_len, 2, 3);
-       
+
        RE_PV_COLOR_DECL(s2,len2,is_uni,PERL_DEBUG_PAD(2),
                    locinput, loc_regeol - locinput, 10, 0, 1);
 
@@ -4419,7 +4417,7 @@ S_dump_exec_pos(pTHX_ const char *locinput,
 #endif
 
 /* reg_check_named_buff_matched()
- * Checks to see if a named buffer has matched. The data array of 
+ * Checks to see if a named buffer has matched. The data array of
  * buffer numbers corresponding to the buffer is expected to reside
  * in the regexp->data->data array in the slot stored in the ARG() of
  * node involved. Note that this routine doesn't actually care about the
@@ -4447,318 +4445,592 @@ S_reg_check_named_buff_matched(const regexp *rex, const regnode *scan)
     return 0;
 }
 
-#define CHRTEST_UNINIT -1001 /* c1/c2 haven't been calculated yet */
-#define CHRTEST_VOID   -1000 /* the c1/c2 "next char" test should be skipped */
-#define CHRTEST_NOT_A_CP_1 -999
-#define CHRTEST_NOT_A_CP_2 -998
-
 static bool
-S_setup_EXACTISH_ST_c1_c2(pTHX_ const regnode * const text_node, int *c1p,
-        U8* c1_utf8, int *c2p, U8* c2_utf8, regmatch_info *reginfo)
+S_setup_EXACTISH_ST(pTHX_ const regnode * const text_node,
+                          struct next_matchable_info * m,
+                          regmatch_info *reginfo)
 {
-    /* This function determines if there are zero, one, two, or more characters
-     * that match the first character of the passed-in EXACTish node
-     * <text_node>, and if there are one or two, it returns them in the
-     * passed-in pointers.
+    /* This function determines various characteristics about every possible
+     * initial match of the passed-in EXACTish <text_node>, and stores them in
+     * <*m>.
      *
-     * If it determines that no possible character in the target string can
-     * match, it returns FALSE; otherwise TRUE.  (The FALSE situation occurs if
-     * the first character in <text_node> requires UTF-8 to represent, and the
-     * target string isn't in UTF-8.)
+     * That includes a match string and a parallel mask, such that if you AND
+     * the target string with the mask and compare with the match string,
+     * you'll have a pretty good idea, perhaps even perfect, if that portion of
+     * the target matches or not.
      *
-     * If there are more than two characters that could match the beginning of
-     * <text_node>, or if more context is required to determine a match or not,
-     * it sets both *<c1p> and *<c2p> to CHRTEST_VOID.
+     * The motivation behind this function is to allow the caller to set up
+     * tight loops for matching.  Consider patterns like '.*B' or '.*?B' where
+     * B is an arbitrary EXACTish node.  To find the end of .*, we look for the
+     * beginning oF B, which is the passed in <text_node>  That's where this
+     * function comes in.  The values it returns can quickly be used to rule
+     * out many, or all, cases of possible matches not actually being the
+     * beginning of B, <text_node>.  It is also used in regrepeat() where we
+     * have 'A*', for arbitrary 'A'.  This sets up criteria to more efficiently
+     * determine where the span of 'A's stop.
      *
-     * The motiviation behind this function is to allow the caller to set up
-     * tight loops for matching.  If <text_node> is of type EXACT, there is
-     * only one possible character that can match its first character, and so
-     * the situation is quite simple.  But things get much more complicated if
-     * folding is involved.  It may be that the first character of an EXACTFish
-     * node doesn't participate in any possible fold, e.g., punctuation, so it
-     * can be matched only by itself.  The vast majority of characters that are
-     * in folds match just two things, their lower and upper-case equivalents.
+     * If <text_node> is of type EXACT, there is only one possible character
+     * that can match its first character, and so the situation is quite
+     * simple.  But things can get much more complicated if folding is
+     * involved.  It may be that the first character of an EXACTFish node
+     * doesn't participate in any possible fold, e.g., punctuation, so it can
+     * be matched only by itself.  The vast majority of characters that are in
+     * folds match just two things, their lower and upper-case equivalents.
      * But not all are like that; some have multiple possible matches, or match
      * sequences of more than one character.  This function sorts all that out.
      *
-     * Consider the patterns A*B or A*?B where A and B are arbitrary.  In a
-     * loop of trying to match A*, we know we can't exit where the thing
-     * following it isn't a B.  And something can't be a B unless it is the
-     * beginning of B.  By putting a quick test for that beginning in a tight
-     * loop, we can rule out things that can't possibly be B without having to
-     * break out of the loop, thus avoiding work.  Similarly, if A is a single
-     * character, we can make a tight loop matching A*, using the outputs of
-     * this function.
+     * It returns information about all possibilities of what the first
+     * character(s) of <text_node> could look like.  Again, if <text_node> is a
+     * plain EXACT node, that's just the actual first bytes of the first
+     * character; but otherwise it is the bytes, that when masked, match all
+     * possible combinations of all the initial bytes of all the characters
+     * that could match, folded.  (Actually, this is a slight over promise.  It
+     * handles only up to the initial 5 bytes, which is enough for all Unicode
+     * characters, but not for all non-Unicode ones.)
+     *
+     * Here's an example to clarify.  Suppose the first character of
+     * <text_node> is the letter 'C', and we are under /i matching.  That means
+     * 'c' also matches.  The representations of these two characters differ in
+     * just one bit, so the mask would be a zero in that position and ones in
+     * the other 7.  And the returned string would be the AND of these two
+     * characters, and would be one byte long, since these characters are each
+     * a single byte.  ANDing the target <text_node> with this mask will yield
+     * the returned string if and only if <text_node> begins with one of these
+     * two characters.  So, the function would also return that the definitive
+     * length matched is 1 byte.
+     *
+     * Now, suppose instead of the letter 'C',  <text_node> begins with the
+     * letter 'F'.  The situation is much more complicated because there are
+     * various ligatures such as LATIN SMALL LIGATURE FF, whose fold also
+     * begins with 'f', and hence could match.  We add these into the returned
+     * string and mask, but the result isn't definitive; the caller has to
+     * check further if its AND and compare pass.  But the failure of that
+     * compare will quickly rule out most possible inputs.
      *
-     * If the target string to match isn't in UTF-8, and there aren't
-     * complications which require CHRTEST_VOID, *<c1p> and *<c2p> are set to
-     * the one or two possible octets (which are characters in this situation)
-     * that can match.  In all cases, if there is only one character that can
-     * match, *<c1p> and *<c2p> will be identical.
+     * Much of this could be done in regcomp.c at compile time, except for
+     * locale-dependent, and UTF-8 target dependent data.  Extra data fields
+     * could be used for one or the other eventualities.
      *
-     * If the target string is in UTF-8, the buffers pointed to by <c1_utf8>
-     * and <c2_utf8> will contain the one or two UTF-8 sequences of bytes that
-     * can match the beginning of <text_node>.  They should be declared with at
-     * least length UTF8_MAXBYTES+1.  (If the target string isn't in UTF-8, it is
-     * undefined what these contain.)  If one or both of the buffers are
-     * invariant under UTF-8, *<c1p>, and *<c2p> will also be set to the
-     * corresponding invariant.  If variant, the corresponding *<c1p> and/or
-     * *<c2p> will be set to a negative number(s) that shouldn't match any code
-     * point (unless inappropriately coerced to unsigned).   *<c1p> will equal
-     * *<c2p> if and only if <c1_utf8> and <c2_utf8> are the same. */
+     * If this function determines that no possible character in the target
+     * string can match, it returns FALSE; otherwise TRUE.  (The FALSE
+     * situation occurs if the first character in <text_node> requires UTF-8 to
+     * represent, and the target string isn't in UTF-8.)
+     */
 
     const bool utf8_target = reginfo->is_utf8_target;
+    bool utf8_pat = reginfo->is_utf8_pat;
 
-    UV c1 = (UV)CHRTEST_NOT_A_CP_1;
-    UV c2 = (UV)CHRTEST_NOT_A_CP_2;
-    bool use_chrtest_void = FALSE;
-    const bool utf8_pat = reginfo->is_utf8_pat;
+    PERL_UINT_FAST8_T i;
 
-    /* Used when we have both utf8 input and utf8 output, to avoid converting
-     * to/from code points */
-    bool utf8_has_been_setup = FALSE;
+    /* Here and below, '15' is the value of UTF8_MAXBYTES_CASE, which requires at least :e
+     */
+    U8 matches[MAX_MATCHES][UTF8_MAXBYTES_CASE + 1] = { 0 };
+    U8 lengths[MAX_MATCHES] = { 0 };
 
+    U8 index_of_longest = 0;
 
     U8 *pat = (U8*)STRING(text_node);
-    U8 folded[UTF8_MAX_FOLD_CHAR_EXPAND * UTF8_MAXBYTES_CASE + 1] = { '\0' };
-    const U8 op = OP(text_node);
+    Size_t pat_len = STR_LEN(text_node);
+    U8 op = OP(text_node);
 
-    if (! isEXACTFish(OP(text_node))) {
+    U8 byte_mask[5]  = {0};
+    U8 byte_anded[5] = {0};
 
-        /* In an exact node, only one thing can be matched, that first
-         * character.  If both the pat and the target are UTF-8, we can just
-         * copy the input to the output, avoiding finding the code point of
-         * that character */
-        if (! utf8_pat) {
-            assert(! isEXACT_REQ8(OP(text_node)));
-            c2 = c1 = *pat;
-        }
-        else if (utf8_target) {
-            Copy(pat, c1_utf8, UTF8SKIP(pat), U8);
-            Copy(pat, c2_utf8, UTF8SKIP(pat), U8);
-            utf8_has_been_setup = TRUE;
-        }
-        else if (isEXACT_REQ8(OP(text_node))) {
-            return FALSE;   /* Can only match UTF-8 target */
+    /* There are some folds in Unicode to multiple characters.  This will hold
+     * such characters that could fold to the beginning of 'text_node' */
+    UV multi_fold_from = 0;
+
+    /* We may have to create a modified copy of the pattern */
+    U8 mod_pat[UTF8_MAXBYTES_CASE + 1] = { '\0' };
+
+    m->max_length = 0;
+    m->min_length = 255;
+    m->count = 0;
+
+    /* Even if the first character in the node can match something in Latin1,
+     * if there is anything in the node that can't, the match must fail */
+    if (! utf8_target && isEXACT_REQ8(op)) {
+        return FALSE;
+    }
+
+/* Define a temporary op for use in this function, using an existing one that
+ * should never be a real op during execution */
+#define TURKISH  PSEUDO
+
+    /* What to do about these two nodes had to be deferred to runtime (which is
+     * now).  If the extra information we now have so indicates, turn them into
+     * EXACTFU nodes */
+    if (   (op == EXACTF && utf8_target)
+        || (op == EXACTFL && IN_UTF8_CTYPE_LOCALE))
+    {
+        if (op == EXACTFL && PL_in_utf8_turkic_locale) {
+            op = TURKISH;
         }
         else {
-            c2 = c1 = valid_utf8_to_uvchr(pat, NULL);
-        }
-    }
-    else { /* an EXACTFish node */
-        U8 *pat_end = pat + STR_LENs(text_node);
-
-        /* An EXACTFL node has at least some characters unfolded, because what
-         * they match is not known until now.  So, now is the time to fold
-         * the first few of them, as many as are needed to determine 'c1' and
-         * 'c2' later in the routine.  If the pattern isn't UTF-8, we only need
-         * to fold if in a UTF-8 locale, and then only the Sharp S; everything
-         * else is 1-1 and isn't assumed to be folded.  In a UTF-8 pattern, we
-         * need to fold as many characters as a single character can fold to,
-         * so that later we can check if the first ones are such a multi-char
-         * fold.  But, in such a pattern only locale-problematic characters
-         * aren't folded, so we can skip this completely if the first character
-         * in the node isn't one of the tricky ones */
-        if (op == EXACTFL) {
-
-            if (! utf8_pat) {
-                if (IN_UTF8_CTYPE_LOCALE && *pat == LATIN_SMALL_LETTER_SHARP_S)
-                {
-                    folded[0] = folded[1] = 's';
-                    pat = folded;
-                    pat_end = folded + 2;
+            op = EXACTFU;
+        }
+
+        /* And certain situations are better handled if we create a modified
+         * version of the pattern */
+        if (utf8_pat) { /* Here, must have been EXACTFL, so look at the
+                           specific problematic characters */
+            if (is_PROBLEMATIC_LOCALE_FOLD_utf8(pat)) {
+
+                /* The node could start with characters that are the first ones
+                 * of a multi-character fold. */
+                multi_fold_from
+                          = what_MULTI_CHAR_FOLD_utf8_safe(pat, pat + pat_len);
+                if (multi_fold_from) {
+
+                    /* Here, they do form a sequence that matches the fold of a
+                     * single character.  That single character then is a
+                     * possible match.  Below we will look again at this, but
+                     * the code below is expecting every character in the
+                     * pattern to be folded, which the input isn't required to
+                     * be in this case.  So, just fold the single character,
+                     * and the result will be in the expected form. */
+                    _to_uni_fold_flags(multi_fold_from, mod_pat, &pat_len,
+                                       FOLD_FLAGS_FULL);
+                    pat = mod_pat;
                 }
-            }
-            else if (is_PROBLEMATIC_LOCALE_FOLDEDS_START_utf8(pat)) {
-                U8 *s = pat;
-                U8 *d = folded;
-                int i;
-
-                for (i = 0; i < UTF8_MAX_FOLD_CHAR_EXPAND && s < pat_end; i++) {
-                    if (isASCII(*s) && LIKELY(! PL_in_utf8_turkic_locale)) {
-                        *(d++) = (U8) toFOLD_LC(*s);
-                        s++;
+                         /* Turkish has a couple extra possibilities. */
+                else if (   UNLIKELY(op == TURKISH)
+                         &&  pat_len >= 3
+                         &&  isALPHA_FOLD_EQ(pat[0], 'f')
+                         && (   memBEGINs(pat + 1, pat_len - 1,
+                                    LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE_UTF8)
+                             || (   pat_len >= 4
+                                 && isALPHA_FOLD_EQ(pat[1], 'f')
+                                 && memBEGINs(pat + 2, pat_len - 2,
+                                    LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE_UTF8)
+                ))) {
+                    /* The macros for finding a multi-char fold don't include
+                     * the Turkish possibilities, in which U+130 folds to 'i'.
+                     * Hard-code these.  It's very unlikely that Unicode will
+                     * ever add any others.  */
+                    if (pat[1] == 'f') {
+                        pat_len = 3;
+                        Copy("ffi", mod_pat, pat_len, U8);
                     }
                     else {
-                        STRLEN len;
-                        _toFOLD_utf8_flags(s,
-                                           pat_end,
-                                           d,
-                                           &len,
-                                           FOLD_FLAGS_FULL | FOLD_FLAGS_LOCALE);
-                        d += len;
-                        s += UTF8SKIP(s);
+                        pat_len = 2;
+                        Copy("fi", mod_pat, pat_len, U8);
                     }
+                    pat = mod_pat;
+                }
+                else if (    UTF8_IS_DOWNGRADEABLE_START(*pat)
+                         &&  LIKELY(memNEs(pat, pat_len, MICRO_SIGN_UTF8))
+                         &&  LIKELY(memNEs(pat, pat_len,
+                                           LATIN_SMALL_LETTER_SHARP_S_UTF8))
+                         && (LIKELY(op != TURKISH || *pat != 'I')))
+                {
+                    /* For all cases of things between 0-255, except the ones
+                     * in the conditional above, the fold is just the lower
+                     * case, which is faster than the more general case. */
+                    mod_pat[0] = toLOWER_L1(EIGHT_BIT_UTF8_TO_NATIVE(pat[0],
+                                                                     pat[1]));
+                    pat_len = 1;
+                    pat = mod_pat;
+                    utf8_pat = FALSE;
+                }
+                else {  /* Code point above 255, or needs special handling */
+                    _to_utf8_fold_flags(pat, pat + pat_len,
+                                        mod_pat, &pat_len,
+                                        FOLD_FLAGS_FULL|FOLD_FLAGS_LOCALE);
+                    pat = mod_pat;
                 }
-
-                pat = folded;
-                pat_end = d;
             }
         }
+        else if /* Below is not a UTF-8 pattern; there's a somewhat different
+                   set of problematic characters */
+                ((multi_fold_from
+                          = what_MULTI_CHAR_FOLD_latin1_safe(pat, pat + pat_len)))
+        {
+            /* We may have to canonicalize a multi-char fold, as in the UTF-8
+             * case */
+            _to_uni_fold_flags(multi_fold_from, mod_pat, &pat_len,
+                               FOLD_FLAGS_FULL);
+            pat = mod_pat;
+        }
+        else if (UNLIKELY(*pat == LATIN_SMALL_LETTER_SHARP_S)) {
+            mod_pat[0] = mod_pat[1] = 's';
+            pat_len = 2;
+            utf8_pat = utf8_target; /* UTF-8ness immaterial for invariant
+                                       chars, and speeds copying */
+            pat = mod_pat;
+        }
+        else if (LIKELY(op != TURKISH || *pat != 'I')) {
+            mod_pat[0] = toLOWER_L1(*pat);
+            pat_len = 1;
+            pat = mod_pat;
+        }
+    }
+    else if /* Below isn't a node that we convert to UTF-8 */
+            (     utf8_target
+             && ! utf8_pat
+             &&   op == EXACTFAA_NO_TRIE
+             &&  *pat == LATIN_SMALL_LETTER_SHARP_S)
+    {
+        /* A very special case.  Folding U+DF goes to U+17F under /iaa.  We
+         * did this at compile time when the pattern was UTF-8 , but otherwise
+         * we couldn't do it earlier, because it requires a UTF-8 target for
+         * this match to be legal. */
+        pat_len = 2 * (sizeof(LATIN_SMALL_LETTER_LONG_S_UTF8) - 1);
+        Copy(LATIN_SMALL_LETTER_LONG_S_UTF8
+             LATIN_SMALL_LETTER_LONG_S_UTF8, mod_pat, pat_len, U8);
+        pat = mod_pat;
+        utf8_pat = TRUE;
+    }
+
+    /* Here, we have taken care of the initial work for a few very problematic
+     * situations, possibly creating a modified pattern.
+     *
+     * Now ready for the general case.  We build up all the possible things
+     * that could match the first character of the pattern into the elements of
+     * 'matches[]'
+     *
+     * Everything generally matches at least itself.  But if there is a
+     * UTF8ness mismatch, we have to convert to that of the target string. */
+    if (utf8_pat == utf8_target || UTF8_IS_INVARIANT(*pat)) {
+        lengths[0] = MIN(pat_len, C_ARRAY_LENGTH(matches[0]));
+        Copy(pat, matches[0], lengths[0], U8);
+        m->count++;
+    }
+    else if (utf8_target) { /* target is UTF-8; pattern isn't */
+        matches[0][0] = UTF8_EIGHT_BIT_HI(pat[0]);
+        matches[0][1] = UTF8_EIGHT_BIT_LO(pat[0]);
+        lengths[0] = 2;
+        m->count++;
+    }
+    else { /* pattern is UTF-8, target isn't */
+        if (UTF8_IS_DOWNGRADEABLE_START(*pat)) {
+            matches[0][0] = EIGHT_BIT_UTF8_TO_NATIVE(pat[0], pat[1]);
+            lengths[0] = 1;
+            m->count++;
+        }
+    }
+
+    /* Here we have taken care of any necessary node-type changes */
+
+    if (m->count) {
+        m->max_length = lengths[0];
+        m->min_length = lengths[0];
+    }
+
+    /* For non-folding nodes, there are no other possible candidate matches,
+     * but for foldable ones, we have to look further. */
+    if (UNLIKELY(op == TURKISH) || isEXACTFish(op)) { /* A folding node */
+        UV folded;  /* The first character in the pattern, folded */
+        U32 first_fold_from;    /* A character that folds to it */
+        const U32 * remaining_fold_froms;   /* The remaining characters that
+                                               fold to it, if any */
+        Size_t folds_to_count;  /* The total number of characters that fold to
+                                   'folded' */
+
+        /* If the node begins with a sequence of more than one character that
+         * together form the fold of a single character, it is called a
+         * 'multi-character fold', and the normal functions don't handle this
+         * case.  We set 'multi_fold_from' to the single folded-from character,
+         * which is handled in an extra iteration below */
+        if (utf8_pat) {
+            folded = valid_utf8_to_uvchr(pat, NULL);
+            multi_fold_from
+                          = what_MULTI_CHAR_FOLD_utf8_safe(pat, pat + pat_len);
+        }
+        else {
+            folded = *pat;
+
+            /* This may generate illegal combinations for things like EXACTF,
+             * but rather than repeat the logic and exclude them here, all such
+             * illegalities are checked for and skipped below in the loop */
+            multi_fold_from
+                        = what_MULTI_CHAR_FOLD_latin1_safe(pat, pat + pat_len);
+        }
 
-        if (    ( utf8_pat && is_MULTI_CHAR_FOLD_utf8_safe(pat, pat_end))
-             || (!utf8_pat && is_MULTI_CHAR_FOLD_latin1_safe(pat, pat_end)))
+        /* Everything matches at least itself; initialize to that because the
+         * only the branches below that set it are the ones where the number
+         * isn't 1. */
+        folds_to_count = 1;
+
+        /* There are a few special cases for locale-dependent nodes, where the
+         * run-time context was needed before we could know what matched */
+        if (UNLIKELY(op == EXACTFL) && folded < 256)  {
+            first_fold_from = PL_fold_locale[folded];
+        }
+        else if (   op == EXACTFL && utf8_target && utf8_pat
+                 && memBEGINs(pat, pat_len, LATIN_SMALL_LETTER_LONG_S_UTF8
+                                            LATIN_SMALL_LETTER_LONG_S_UTF8))
         {
-            /* Multi-character folds require more context to sort out.  Also
-             * PL_utf8_foldclosures used below doesn't handle them, so have to
-             * be handled outside this routine */
-            use_chrtest_void = TRUE;
-        }
-        else { /* an EXACTFish node which doesn't begin with a multi-char fold */
-            c1 = utf8_pat ? valid_utf8_to_uvchr(pat, NULL) : *pat;
-
-            if (   UNLIKELY(PL_in_utf8_turkic_locale)
-                && op == EXACTFL
-                && UNLIKELY(   c1 == 'i' || c1 == 'I'
-                            || c1 == LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE
-                            || c1 == LATIN_SMALL_LETTER_DOTLESS_I))
-            {   /* Hard-coded Turkish locale rules for these 4 characters
-                   override normal rules */
-                if (c1 == 'i') {
-                    c2 = LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE;
-                }
-                else if (c1 == 'I') {
-                    c2 = LATIN_SMALL_LETTER_DOTLESS_I;
-                }
-                else if (c1 == LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE) {
-                    c2 = 'i';
-                }
-                else if (c1 == LATIN_SMALL_LETTER_DOTLESS_I) {
-                    c2 = 'I';
-                }
+            first_fold_from = LATIN_CAPITAL_LETTER_SHARP_S;
+        }
+        else if (UNLIKELY(    op == TURKISH
+                          && (   isALPHA_FOLD_EQ(folded, 'i')
+                              || inRANGE(folded,
+                                         LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE,
+                                         LATIN_SMALL_LETTER_DOTLESS_I))))
+        {   /* Turkish folding requires special handling */
+            if (folded == 'i')
+                first_fold_from = LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE;
+            else if (folded == 'I')
+                first_fold_from = LATIN_SMALL_LETTER_DOTLESS_I;
+            else if (folded == LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE)
+                first_fold_from = 'i';
+            else first_fold_from = 'I';
+        }
+        else {
+            /* Here, isn't a special case: use the generic function to
+             * calculate what folds to this */
+          redo_multi:
+            /* Look up what code points (besides itself) fold to 'folded';
+             * e.g., [ 'K', KELVIN_SIGN ] both fold to 'k'. */
+            folds_to_count = _inverse_folds(folded, &first_fold_from,
+                                                       &remaining_fold_froms);
+        }
+
+        /* Add each character that folds to 'folded' to the list of them,
+         * subject to limitations based on the node type and target UTF8ness.
+         * If there was a character that folded to multiple characters, do an
+         * extra iteration for it.  (Note the extra iteration if there is a
+         * multi-character fold) */
+        for (i = 0; i < folds_to_count
+                      + UNLIKELY(multi_fold_from != 0); i++)
+        {
+            UV fold_from = 0;
+
+            if (i >= folds_to_count) {  /* Final iteration: handle the
+                                           multi-char */
+                fold_from = multi_fold_from;
             }
-            else if (c1 > 255) {
-                const U32 * remaining_folds;
-                U32 first_fold;
-
-                /* Look up what code points (besides c1) fold to c1;  e.g.,
-                 * [ 'K', KELVIN_SIGN ] both fold to 'k'. */
-                Size_t folds_count = _inverse_folds(c1, &first_fold,
-                                                       &remaining_folds);
-                if (folds_count == 0) {
-                    c2 = c1;    /* there is only a single character that could
-                                   match */
-                }
-                else if (folds_count != 1) {
-                    /* If there aren't exactly two folds to this (itself and
-                     * another), it is outside the scope of this function */
-                    use_chrtest_void = TRUE;
-                }
-                else {  /* There are two.  We already have one, get the other */
-                    c2 = first_fold;
-
-                    /* Folds that cross the 255/256 boundary are forbidden if
-                     * EXACTFL (and isnt a UTF8 locale), or EXACTFAA and one is
-                     * ASCIII.  The only other match to c1 is c2, and since c1
-                     * is above 255, c2 better be as well under these
-                     * circumstances.  If it isn't, it means the only legal
-                     * match of c1 is itself. */
-                    if (    c2 < 256
-                        && (   (   op == EXACTFL
-                                && ! IN_UTF8_CTYPE_LOCALE)
-                            || ((     op == EXACTFAA
-                                   || op == EXACTFAA_NO_TRIE)
-                                && (isASCII(c1) || isASCII(c2)))))
-                    {
-                        c2 = c1;
-                    }
-                }
+            else if (i == 0) {
+                fold_from = first_fold_from;
+            }
+            else if (i < folds_to_count) {
+                fold_from = remaining_fold_froms[i-1];
             }
-            else /* Here, c1 is <= 255 */
-                if (   utf8_target
-                    && HAS_NONLATIN1_FOLD_CLOSURE(c1)
-                    && ( ! (op == EXACTFL && ! IN_UTF8_CTYPE_LOCALE))
-                    && (   (   op != EXACTFAA
-                            && op != EXACTFAA_NO_TRIE)
-                        ||   ! isASCII(c1)))
+
+            if (folded == fold_from) {  /* We already added the character
+                                           itself */
+                continue;
+            }
+
+            /* EXACTF doesn't have any non-ascii folds */
+            if (op == EXACTF && (! isASCII(folded) || ! isASCII(fold_from))) {
+                continue;
+            }
+
+            /* In /iaa nodes, neither or both must be ASCII to be a legal fold
+             * */
+            if (    isASCII(folded) != isASCII(fold_from)
+                &&  inRANGE(op, EXACTFAA, EXACTFAA_NO_TRIE))
+
             {
-                /* Here, there could be something above Latin1 in the target
-                 * which folds to this character in the pattern.  All such
-                 * cases except LATIN SMALL LETTER Y WITH DIAERESIS have more
-                 * than two characters involved in their folds, so are outside
-                 * the scope of this function */
-                if (UNLIKELY(c1 == LATIN_SMALL_LETTER_Y_WITH_DIAERESIS)) {
-                    c2 = LATIN_CAPITAL_LETTER_Y_WITH_DIAERESIS;
-                }
-                else {
-                    use_chrtest_void = TRUE;
+                continue;
+            }
+
+            /* In /il nodes, can't cross 255/256 boundary (unless in a UTF-8
+             * locale, but those have been converted to EXACTFU above) */
+            if (   op == EXACTFL
+                && (folded < 256) != (fold_from < 256))
+            {
+                continue;
+            }
+
+            /* If this triggers, it likely is because of the unlikely case
+             * where a new Unicode standard has changed what MAX_MATCHES should
+             * be set to */
+            assert(m->count < MAX_MATCHES);
+
+            /* Add this character to the list of possible matches */
+            if (utf8_target) {
+                uvchr_to_utf8(matches[m->count], fold_from);
+                lengths[m->count] = UVCHR_SKIP(fold_from);
+                m->count++;
+            }
+            else { /* Non-UTF8 target: any code point above 255
+                      can't appear in it */
+                if (fold_from > 255) {
+                    continue;
                 }
+
+                matches[m->count][0] = fold_from;
+                lengths[m->count] = 1;
+                m->count++;
             }
-            else { /* Here nothing above Latin1 can fold to the pattern
-                      character */
-                switch (op) {
 
-                    case EXACTFL:   /* /l rules */
-                        c2 = PL_fold_locale[c1];
-                        break;
+            /* Update min and mlengths */
+            if (m->min_length > lengths[m->count-1]) {
+                m->min_length = lengths[m->count-1];
+            }
 
-                    case EXACTF:   /* This node only generated for non-utf8
-                                    patterns */
-                        assert(! utf8_pat);
-                        if (! utf8_target) {    /* /d rules */
-                            c2 = PL_fold[c1];
-                            break;
-                        }
-                        /* FALLTHROUGH */
-                        /* /u rules for all these.  This happens to work for
-                        * EXACTFAA as nothing in Latin1 folds to ASCII */
-                    case EXACTFAA_NO_TRIE:   /* This node only generated for
-                                                non-utf8 patterns */
-                        assert(! utf8_pat);
-                        /* FALLTHROUGH */
-                    case EXACTFAA:
-                    case EXACTFUP:
-                    case EXACTFU:
-                        c2 = PL_fold_latin1[c1];
-                        break;
-                    case EXACTFU_REQ8:
-                        return FALSE;
-                        NOT_REACHED; /* NOTREACHED */
+            if (m->max_length < lengths[m->count-1]) {
+                index_of_longest = m->count - 1;
+                m->max_length = lengths[index_of_longest];
+            }
+        } /* looped through each potential fold */
 
-                    default:
-                        Perl_croak(aTHX_ "panic: Unexpected op %u", op);
-                        NOT_REACHED; /* NOTREACHED */
+        /* If there is something that folded to an initial multi-character
+         * fold, repeat, using it.  This catches some edge cases.  An example
+         * of one is /ss/i when UTF-8 encoded.  The function
+         * what_MULTI_CHAR_FOLD_utf8_safe('ss') gets called and returns U+DF
+         * (LATIN SMALL SHARP S).  If it returned a list of characters, this
+         * code wouldn't be needed.  But since it doesn't, we have to look what
+         * folds to the U+DF.  In this case, U+1E9E does, and has to be added.
+         * */
+        if (multi_fold_from) {
+            folded = multi_fold_from;
+            multi_fold_from = 0;
+            goto redo_multi;
+        }
+    } /* End of finding things that participate in this fold */
+
+    if (m->count == 0) {    /* If nothing found, can't match */
+        m->min_length = 0;
+        return FALSE;
+    }
+
+    /* Have calculated all possible matches.  Now calculate the mask and AND
+     * values */
+    m->initial_exact = 0;
+    m->initial_definitive = 0;
+
+    {
+        unsigned int mask_ones = 0;
+        unsigned int possible_ones = 0;
+        U8 j;
+
+        /* For each byte that is in all possible matches ... */
+        for (j = 0; j < MIN(m->min_length, 5); j++) {
+
+            /* Initialize the accumulator for this byte */
+            byte_mask[j] = 0xFF;
+            byte_anded[j] = matches[0][j];
+
+            /* Then the rest of the rows (folds).  The mask is based on, like,
+             * ~('A' ^ 'a') is a 1 in all bits where these are the same, and 0
+             * where they differ. */
+            for (i = 1; i < (PERL_UINT_FAST8_T) m->count; i++) {
+                byte_mask[j]  &= ~ (byte_anded[j] ^ matches[i][j]);
+                byte_anded[j] &= matches[i][j];
+            }
+
+            /* Keep track of the number of initial mask bytes that are all one
+             * bits.  The code calling this can use this number to know that
+             * a string that matches this number of bytes in the pattern is an
+             * exact match of that pattern for this number of bytes.  But also
+             * counted are the number of initial bytes that in total have a
+             * single zero bit.  If a string matches those, masked, it must be
+             * one of two possibilites, both of which this function has
+             * determined are legal.  (But if that single 0 is one of the
+             * initial bits for masking a UTF-8 start byte, that could
+             * incorrectly lead to different length strings appearing to be
+             * equivalent, so only do this optimization when the matchables are
+             * all the same length.  This was uncovered by testing
+             * /\x{029E}/i.) */
+            if (m->min_length == m->max_length) {
+                mask_ones += PL_bitcount[byte_mask[j]];
+                possible_ones += 8;
+                if (mask_ones + 1 >= possible_ones) {
+                    m->initial_definitive++;
+                    if (mask_ones >= possible_ones) {
+                        m->initial_exact++;
+                    }
                 }
             }
         }
     }
 
-    /* Here have figured things out.  Set up the returns */
-    if (use_chrtest_void) {
-        *c2p = *c1p = CHRTEST_VOID;
+    /* The first byte is separate for speed */
+    m->first_byte_mask = byte_mask[0];
+    m->first_byte_anded = byte_anded[0];
+
+    /* Then pack up to the next 4 bytes into a word */
+    m->mask32 = m->anded32 = 0;
+    for (i = 1; i < MIN(m->min_length, 5); i++) {
+        U8 which = i;
+        U8 shift = (which - 1) * 8;
+        m->mask32  |= (U32) byte_mask[i]  << shift;
+        m->anded32 |= (U32) byte_anded[i] << shift;
     }
-    else if (utf8_target) {
-        if (! utf8_has_been_setup) {    /* Don't have the utf8; must get it */
-            uvchr_to_utf8(c1_utf8, c1);
-            uvchr_to_utf8(c2_utf8, c2);
+
+    /* Finally, take the match strings and place them sequentially into a
+     * one-dimensional array.  (This is done to save significant space in the
+     * structure.) Sort so the longest (presumably the least likely) is last.
+     * XXX When this gets moved to regcomp, may want to fully sort shortest
+     * first, but above we generally used the folded code point first, and
+     * those tend to be no longer than their upper case values, so this is
+     * already pretty well sorted by size.
+     *
+     * If the asserts fail, it's most likely because a new version of the
+     * Unicode standard requires more space; simply increase the declaration
+     * size. */
+    {
+        U8 cur_pos = 0;
+        U8 output_index = 0;
+
+        if (m->count > 1) { /* No need to sort a single entry */
+            for (i = 0; i < (PERL_UINT_FAST8_T) m->count; i++) {
+
+                /* Keep the same order for all but the longest */
+                if (i != index_of_longest) {
+                    assert(cur_pos + lengths[i] <= C_ARRAY_LENGTH(m->matches));
+                    Copy(matches[i], m->matches + cur_pos, lengths[i], U8);
+                    cur_pos += lengths[i];
+                    m->lengths[output_index++] = lengths[i];
+                }
+            }
         }
 
-        /* Invariants are stored in both the utf8 and byte outputs; Use
-         * negative numbers otherwise for the byte ones.  Make sure that the
-         * byte ones are the same iff the utf8 ones are the same */
-        *c1p = (UTF8_IS_INVARIANT(*c1_utf8)) ? *c1_utf8 : CHRTEST_NOT_A_CP_1;
-        *c2p = (UTF8_IS_INVARIANT(*c2_utf8))
-                ? *c2_utf8
-                : (c1 == c2)
-                  ? CHRTEST_NOT_A_CP_1
-                  : CHRTEST_NOT_A_CP_2;
-    }
-    else if (c1 > 255) {
-       if (c2 > 255) {  /* both possibilities are above what a non-utf8 string
-                           can represent */
-           return FALSE;
-       }
+        assert(cur_pos + lengths[index_of_longest] <= C_ARRAY_LENGTH(m->matches));
+        Copy(matches[index_of_longest], m->matches + cur_pos,
+             lengths[index_of_longest], U8);
 
-       *c1p = *c2p = c2;    /* c2 is the only representable value */
-    }
-    else {  /* c1 is representable; see about c2 */
-       *c1p = c1;
-       *c2p = (c2 < 256) ? c2 : c1;
+        /* Place the longest match last */
+        m->lengths[output_index] = lengths[index_of_longest];
     }
 
+
     return TRUE;
 }
 
+PERL_STATIC_FORCE_INLINE    /* We want speed at the expense of size */
+bool
+S_test_EXACTISH_ST(const char * loc,
+                   struct next_matchable_info info)
+{
+    /* This function uses the data set up in setup_EXACTISH_ST() to see if the
+     * bytes starting at 'loc' can match based on 'next_matchable_info' */
+
+    U32 input32 = 0;
+
+    /* Check the first byte */
+    if (((U8) loc[0] & info.first_byte_mask) != info.first_byte_anded)
+        return FALSE;
+
+    /* Pack the next up-to-4 bytes into a 32 bit word */
+    switch (info.min_length) {
+        default:
+            input32 |= (U32) ((U8) loc[4]) << 3 * 8;
+            /* FALLTHROUGH */
+        case 4:
+            input32 |= (U8) loc[3] << 2 * 8;
+            /* FALLTHROUGH */
+        case 3:
+            input32 |= (U8) loc[2] << 1 * 8;
+            /* FALLTHROUGH */
+        case 2:
+            input32 |= (U8) loc[1];
+            break;
+        case 1:
+            return TRUE;    /* We already tested and passed the 0th byte */
+        case 0:
+            ASSUME(0);
+    }
+
+    /* And AND that with the mask and compare that with the assembled ANDED
+     * values */
+    return (input32 & info.mask32) == info.anded32;
+}
+
 STATIC bool
 S_isGCB(pTHX_ const GCB_enum before, const GCB_enum after, const U8 * const strbeg, const U8 * const curpos, const bool utf8_target)
 {
@@ -6019,7 +6291,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
         3 * rex->nparens : MAX_RECURSE_EVAL_NOCHANGE_DEPTH;
     regmatch_state *yes_state = NULL; /* state to pop to on success of
                                                            subpattern */
-    /* mark_state piggy backs on the yes_state logic so that when we unwind 
+    /* mark_state piggy backs on the yes_state logic so that when we unwind
        the stack on success we can update the mark_state as we go */
     regmatch_state *mark_state = NULL; /* last mark state we have seen */
     regmatch_state *cur_eval = NULL; /* most recent EVAL_AB state */
@@ -6030,7 +6302,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
     char *startpoint = locinput;
     SV *popmark = NULL;     /* are we looking for a mark? */
     SV *sv_commit = NULL;   /* last mark name seen in failure */
-    SV *sv_yes_mark = NULL; /* last mark name we have seen 
+    SV *sv_yes_mark = NULL; /* last mark name we have seen
                                during a successful match */
     U32 lastopen = 0;       /* last open we saw */
     bool has_cutgroup = RXp_HAS_CUTGROUP(rex) ? 1 : 0;
@@ -6191,7 +6463,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
 #define ST st->u.trie
         case TRIEC: /* (ab|cd) with known charclass */
             /* In this case the charclass data is available inline so
-               we can fail fast without a lot of extra overhead. 
+               we can fail fast without a lot of extra overhead.
              */
             if ( !   NEXTCHR_IS_EOS
                 &&   locinput < loceol
@@ -6295,7 +6567,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
                   }
                 }
 
-            { 
+            {
                U8 *uc = ( U8* )locinput;
 
                STRLEN len = 0;
@@ -6540,7 +6812,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
                    tmp ? pv_pretty(sv, SvPV_nolen_const(*tmp), SvCUR(*tmp), 0,
                            PL_colors[0], PL_colors[1],
                            (SvUTF8(*tmp) ? PERL_PV_ESCAPE_UNI : 0)|PERL_PV_ESCAPE_NONASCII
-                       ) 
+                       )
                    : "not compiled under -Dr",
                    PL_colors[5] );
            });
@@ -7423,7 +7695,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
 
            }
            break;
-            
+
        case REFFLN:  /*  /\g{name}/il  */
        {   /* The capture buffer cases.  The ones beginning with N for the
               named buffers just convert to the equivalent numbered and
@@ -7586,7 +7858,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
             arg= (U32)ARG(scan);
             if (cur_eval && cur_eval->locinput == locinput) {
                 if ( ++nochange_depth > max_nochange_depth )
-                    Perl_croak(aTHX_ 
+                    Perl_croak(aTHX_
                         "Pattern subroutine nesting without pos change"
                         " exceeded limit in regex");
             } else {
@@ -7638,7 +7910,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
                     Perl_croak(aTHX_ "EVAL without pos change exceeded limit in regex");
             } else {
                 nochange_depth = 0;
-            }    
+            }
            {
                /* execute the code in the {...} */
 
@@ -7922,7 +8194,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
                 DEBUG_EXECUTE_r(
                     debug_start_match(re_sv, utf8_target, locinput,
                                     reginfo->strend, "EVAL/GOSUB: Matching embedded");
-               );              
+               );
                startpoint = rei->program + 1;
                 EVAL_CLOSE_PAREN_CLEAR(st); /* ST.close_paren = 0;
                                              * close_paren only for GOSUB */
@@ -8034,7 +8306,7 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
             is_utf8_pat = reginfo->is_utf8_pat = cBOOL(RX_UTF8(rex_sv));
            SET_reg_curpm(rex_sv);
            rex = ReANY(rex_sv);
-           rexi = RXi_GET(rex); 
+           rexi = RXi_GET(rex);
 
            REGCP_UNWIND(ST.lastcp);
             regcppop(rex, &maxopenparen);
@@ -8097,8 +8369,8 @@ S_regmatch(pTHX_ regmatch_info *reginfo, char *startpos, regnode *prog)
             if (ARG2L(scan)){
                 regnode *cursor;
                 for (cursor=scan;
-                     cursor && OP(cursor)!=END; 
-                     cursor=regnext(cursor)) 
+                     cursor && OP(cursor)!=END;
+                     cursor=regnext(cursor))
                 {
                     if ( OP(cursor)==CLOSE ){
                         n = ARG(cursor);
@@ -8217,19 +8489,19 @@ I and O refer to inner and outer, C and W refer to CURLYX and WHILEM:
 cur_
 curlyx backtrack stack
 ------ ---------------
-NULL   
+NULL
 CO     <CO prev=NULL> <WO>
-CI     <CO prev=NULL> <WO> <CI prev=CO> <WI> ai 
-CO     <CO prev=NULL> <WO> <CI prev=CO> <WI> ai <WI prev=CI> bi 
+CI     <CO prev=NULL> <WO> <CI prev=CO> <WI> ai
+CO     <CO prev=NULL> <WO> <CI prev=CO> <WI> ai <WI prev=CI> bi
 NULL   <CO prev=NULL> <WO> <CI prev=CO> <WI> ai <WI prev=CI> bi <WO prev=CO> bo
 
 At this point the pattern succeeds, and we work back down the stack to
 clean up, restoring as we go:
 
-CO     <CO prev=NULL> <WO> <CI prev=CO> <WI> ai <WI prev=CI> bi 
-CI     <CO prev=NULL> <WO> <CI prev=CO> <WI> ai 
+CO     <CO prev=NULL> <WO> <CI prev=CO> <WI> ai <WI prev=CI> bi
+CI     <CO prev=NULL> <WO> <CI prev=CO> <WI> ai
 CO     <CO prev=NULL> <WO>
-NULL   
+NULL
 
 *******************************************************************/
 
@@ -8239,7 +8511,7 @@ NULL
        {
            /* No need to save/restore up to this paren */
            I32 parenfloor = scan->flags;
-           
+
            assert(next); /* keep Coverity happy */
            if (OP(PREVOPER(next)) == NOTHING) /* LONGJMP */
                next += ARG(next);
@@ -8299,7 +8571,7 @@ NULL
            ST.save_lastloc = cur_curlyx->u.curlyx.lastloc;
            ST.cache_offset = 0;
            ST.cache_mask = 0;
-           
+
 
             DEBUG_EXECUTE_r( Perl_re_exec_indentf( aTHX_  "WHILEM: matched %ld out of %d..%d\n",
                   depth, (long)n, min, max)
@@ -8559,7 +8831,7 @@ NULL
             no_final = 1;
             if (st->u.mark.mark_name)
                 sv_commit = st->u.mark.mark_name;
-            sayNO;         
+            sayNO;
             NOT_REACHED; /* NOTREACHED */
 
         case BRANCH_next:
@@ -8586,7 +8858,7 @@ NULL
             }
            continue; /* execute next BRANCH[J] op */
             /* NOTREACHED */
-    
+
        case MINMOD: /* next op will be non-greedy, e.g. A*?  */
            minmod = 1;
            break;
@@ -8621,7 +8893,7 @@ NULL
            ST.count = 0;
            ST.minmod = minmod;
            minmod = 0;
-           ST.c1 = CHRTEST_UNINIT;
+           ST.Binfo.count = -1;
            REGCP_SET(ST.cp);
 
            if (!(ST.minmod ? ARG1(ST.me) : ARG2(ST.me))) /* min/max */
@@ -8656,7 +8928,7 @@ NULL
 
             if (EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)ST.me->flags))
                goto fake_end;
-               
+
            {
                I32 max = (ST.minmod ? ARG1(ST.me) : ARG2(ST.me));
                if ( max == REG_INFTY || ST.count < max )
@@ -8668,24 +8940,21 @@ NULL
            REGCP_UNWIND(ST.cp);
 
 
-           if (ST.minmod || ST.count < ARG1(ST.me) /* min*/ 
+           if (ST.minmod || ST.count < ARG1(ST.me) /* min*/
                 || EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)ST.me->flags))
                sayNO;
 
          curlym_do_B: /* execute the B in /A{m,n}B/  */
-           if (ST.c1 == CHRTEST_UNINIT) {
-               /* calculate c1 and c2 for possible match of 1st char
-                * following curly */
-               ST.c1 = ST.c2 = CHRTEST_VOID;
+           if (ST.Binfo.count < 0) {
+                /* calculate possible match of 1st char following curly */
                 assert(ST.B);
                if (HAS_TEXT(ST.B) || JUMPABLE(ST.B)) {
                    regnode *text_node = ST.B;
                    if (! HAS_TEXT(text_node))
                        FIND_NEXT_IMPT(text_node);
                    if (PL_regkind[OP(text_node)] == EXACT) {
-                        if (! S_setup_EXACTISH_ST_c1_c2(aTHX_
-                           text_node, &ST.c1, ST.c1_utf8, &ST.c2, ST.c2_utf8,
-                           reginfo))
+                        if (! S_setup_EXACTISH_ST(aTHX_ text_node,
+                                                        &ST.Binfo, reginfo))
                         {
                             sayNO;
                         }
@@ -8696,37 +8965,21 @@ NULL
            DEBUG_EXECUTE_r(
                 Perl_re_exec_indentf( aTHX_  "CURLYM trying tail with matches=%" IVdf "...\n",
                     depth, (IV)ST.count)
-               );
-           if (! NEXTCHR_IS_EOS && ST.c1 != CHRTEST_VOID) {
-                if (! UTF8_IS_INVARIANT(nextbyte) && utf8_target) {
-
-                           /* (We can use memEQ and memNE in this file without
-                            * having to worry about one being shorter than the
-                            * other, since the first byte of each gives the
-                            * length of the character) */
-                    if (   memNE(locinput, ST.c1_utf8, UTF8_SAFE_SKIP(locinput,
-                                                              reginfo->strend))
-                        && memNE(locinput, ST.c2_utf8, UTF8_SAFE_SKIP(locinput,
-                                                             reginfo->strend)))
-                    {
-                        /* simulate B failing */
-                        DEBUG_OPTIMISE_r(
-                            Perl_re_exec_indentf( aTHX_  "CURLYM Fast bail next target=0x%" UVXf " c1=0x%" UVXf " c2=0x%" UVXf "\n",
-                                depth,
-                                valid_utf8_to_uvchr((U8 *) locinput, NULL),
-                                valid_utf8_to_uvchr(ST.c1_utf8, NULL),
-                                valid_utf8_to_uvchr(ST.c2_utf8, NULL))
-                        );
-                        state_num = CURLYM_B_fail;
-                        goto reenter_switch;
-                    }
-                }
-                else if (nextbyte != ST.c1 && nextbyte != ST.c2) {
-                    /* simulate B failing */
+            );
+           if (! NEXTCHR_IS_EOS && ST.Binfo.count >= 0) {
+                assert(ST.Binfo.count > 0);
+
+                /* Do a quick test to hopefully rule out most non-matches */
+                if (     locinput + ST.Binfo.min_length > loceol
+                    || ! S_test_EXACTISH_ST(locinput, ST.Binfo))
+                {
                     DEBUG_OPTIMISE_r(
-                        Perl_re_exec_indentf( aTHX_  "CURLYM Fast bail next target=0x%X c1=0x%X c2=0x%X\n",
+                        Perl_re_exec_indentf( aTHX_
+                            "CURLYM Fast bail next target=0x%X anded==0x%X"
+                                                                " mask=0x%X\n",
                             depth,
-                            (int) nextbyte, ST.c1, ST.c2)
+                            (int) nextbyte, ST.Binfo.first_byte_anded,
+                                            ST.Binfo.first_byte_mask)
                     );
                     state_num = CURLYM_B_fail;
                     goto reenter_switch;
@@ -8746,13 +8999,13 @@ NULL
 
                 if (EVAL_CLOSE_PAREN_IS_TRUE(cur_eval,(U32)ST.me->flags))
                {
-                   if (ST.count) 
+                   if (ST.count)
                        goto fake_end;
                    else
                        sayNO;
                }
            }
-           
+
            PUSH_STATE_GOTO(CURLYM_B, ST.B, locinput, loceol,   /* match B */
                             script_run_begin);
            NOT_REACHED; /* NOTREACHED */
@@ -8842,24 +9095,23 @@ NULL
 
            assert(ST.min <= ST.max);
             if (! HAS_TEXT(next) && ! JUMPABLE(next)) {
-                ST.c1 = ST.c2 = CHRTEST_VOID;
+                ST.Binfo.count = 0;
             }
             else {
                regnode *text_node = next;
 
-               if (! HAS_TEXT(text_node)) 
+               if (! HAS_TEXT(text_node))
                    FIND_NEXT_IMPT(text_node);
 
                if (! HAS_TEXT(text_node))
-                   ST.c1 = ST.c2 = CHRTEST_VOID;
+                   ST.Binfo.count = 0;
                else {
                    if ( PL_regkind[OP(text_node)] != EXACT ) {
-                       ST.c1 = ST.c2 = CHRTEST_VOID;
+                       ST.Binfo.count = 0;
                    }
                    else {
-                        if (! S_setup_EXACTISH_ST_c1_c2(aTHX_
-                           text_node, &ST.c1, ST.c1_utf8, &ST.c2, ST.c2_utf8,
-                           reginfo))
+                        if (! S_setup_EXACTISH_ST(aTHX_ text_node,
+                                                        &ST.Binfo, reginfo))
                         {
                             sayNO;
                         }
@@ -8879,13 +9131,15 @@ NULL
                 SET_locinput(li);
                ST.count = ST.min;
                REGCP_SET(ST.cp);
-               if (ST.c1 == CHRTEST_VOID)
-                   goto curly_try_B_min;
+
+                if (ST.Binfo.count <= 0)
+                    goto curly_try_B_min;
 
                ST.oldloc = locinput;
 
                /* set ST.maxpos to the furthest point along the
-                * string that could possibly match */
+                 * string that could possibly match, i.e., that a match could
+                 * start at. */
                if  (ST.max == REG_INFTY) {
                    ST.maxpos = loceol - 1;
                    if (utf8_target)
@@ -8932,15 +9186,14 @@ NULL
            NOT_REACHED; /* NOTREACHED */
 
        case CURLY_B_min_fail:
-           /* failed to find B in a non-greedy match.
-             * Handles both cases where c1,c2 valid or not */
+           /* failed to find B in a non-greedy match. */
 
            REGCP_UNWIND(ST.cp);
             if (ST.paren) {
                 UNWIND_PAREN(ST.lastparen, ST.lastcloseparen);
             }
 
-            if (ST.c1 == CHRTEST_VOID) {
+            if (ST.Binfo.count == 0) {
                 /* failed -- move forward one */
                 char *li = locinput;
                 if (!regrepeat(rex, &li, ST.A, loceol, reginfo, 1)) {
@@ -8966,84 +9219,78 @@ NULL
 
               curly_try_B_min_known:
                 /* find the next place where 'B' could work, then call B */
-               if (utf8_target) {
-                   n = (ST.oldloc == locinput) ? 0 : 1;
-                   if (ST.c1 == ST.c2) {
-                       /* set n to utf8_distance(oldloc, locinput) */
-                       while (    locinput <= ST.maxpos
-                               &&  locinput < loceol
-                               &&  memNE(locinput, ST.c1_utf8,
-                                    UTF8_SAFE_SKIP(locinput, reginfo->strend)))
-                        {
-                           locinput += UTF8_SAFE_SKIP(locinput,
-                                                       reginfo->strend);
-                           n++;
-                       }
-                   }
-                   else {
-                       /* set n to utf8_distance(oldloc, locinput) */
-                       while (   locinput <= ST.maxpos
-                               && locinput < loceol
-                               && memNE(locinput, ST.c1_utf8,
-                                     UTF8_SAFE_SKIP(locinput, reginfo->strend))
-                               && memNE(locinput, ST.c2_utf8,
-                                    UTF8_SAFE_SKIP(locinput, reginfo->strend)))
-                        {
-                           locinput += UTF8_SAFE_SKIP(locinput, reginfo->strend);
-                           n++;
-                       }
-                   }
-               }
-               else {  /* Not utf8_target */
-                   if (ST.c1 == ST.c2) {
-                        locinput = (char *) memchr(locinput,
-                                                   ST.c1,
-                                                   ST.maxpos + 1 - locinput);
-                        if (! locinput) {
-                            locinput = ST.maxpos + 1;
+                if (locinput + ST.Binfo.initial_exact < loceol) {
+                    if (ST.Binfo.initial_exact >= ST.Binfo.max_length) {
+
+                        /* Here, the mask is all 1's for the entire length of
+                         * any possible match.  (That actually means that there
+                         * is only one possible match.)  Look for the next
+                         * occurrence */
+                        locinput = ninstr(locinput, loceol,
+                                        (char *) ST.Binfo.matches,
+                                        (char *) ST.Binfo.matches
+                                                    + ST.Binfo.initial_exact);
+                        if (locinput == NULL) {
+                            sayNO;
                         }
-                   }
-                    else {
-                        U8 c1_c2_bits_differing = ST.c1 ^ ST.c2;
-
-                        if (! isPOWER_OF_2(c1_c2_bits_differing)) {
-                            while (   locinput <= ST.maxpos
-                                   && UCHARAT(locinput) != ST.c1
-                                   && UCHARAT(locinput) != ST.c2)
-                            {
-                                locinput++;
-                            }
+                    }
+                    else do {
+                        /* If the first byte(s) of the mask are all ones, it
+                         * means those bytes must match identically, so can use
+                         * ninstr() to find the next possible matchpoint */
+                        if (ST.Binfo.initial_exact > 0) {
+                            locinput = ninstr(locinput, loceol,
+                                              (char *) ST.Binfo.matches,
+                                              (char *) ST.Binfo.matches
+                                                     + ST.Binfo.initial_exact);
                         }
-                        else {
-                            /* If c1 and c2 only differ by a single bit, we can
-                             * avoid a conditional each time through the loop,
-                             * at the expense of a little preliminary setup and
-                             * an extra mask each iteration.  By masking out
-                             * that bit, we match exactly two characters, c1
-                             * and c2, and so we don't have to test for both.
-                             * On both ASCII and EBCDIC platforms, most of the
-                             * ASCII-range and Latin1-range folded equivalents
-                             * differ only in a single bit, so this is actually
-                             * the most common case. (e.g. 'A' 0x41 vs 'a'
-                             * 0x61). */
-                            U8 c1_masked = ST.c1 &~ c1_c2_bits_differing;
-                            U8 c1_c2_mask = ~ c1_c2_bits_differing;
-                            while (   locinput <= ST.maxpos
-                                   && (UCHARAT(locinput) & c1_c2_mask)
-                                                                != c1_masked)
-                            {
-                                locinput++;
+                        else { /* Otherwise find the next byte that matches,
+                                  masked */
+                            locinput = (char *) find_next_masked(
+                                                (U8 *) locinput, (U8 *) loceol,
+                                                ST.Binfo.first_byte_anded,
+                                                ST.Binfo.first_byte_mask);
+                            /* Advance to the end of a multi-byte character */
+                            if (utf8_target) {
+                                while (   locinput < loceol
+                                    && UTF8_IS_CONTINUATION(*locinput))
+                                {
+                                    locinput++;
+                                }
                             }
                         }
-                    }
-                   n = locinput - ST.oldloc;
-               }
+                        if (   locinput == NULL
+                            || locinput + ST.Binfo.min_length > loceol)
+                        {
+                            sayNO;
+                        }
+
+                        /* Here, we have found a possible match point; if can't
+                         * rule it out, quit the loop so can check fully */
+                        if (S_test_EXACTISH_ST(locinput, ST.Binfo)) {
+                            break;
+                        }
+
+                        locinput += (utf8_target) ? UTF8SKIP(locinput) : 1;
+
+                    } while (locinput <= ST.maxpos);
+                }
+
                if (locinput > ST.maxpos)
                    sayNO;
+
+                n = (utf8_target)
+                    ? utf8_length((U8 *) ST.oldloc, (U8 *) locinput)
+                    : locinput - ST.oldloc;
+
+
+                /* Here is at the beginning of a character that meets the mask
+                 * criteria.  Need to make sure that some real possibility */
+
                if (n) {
                     /* In /a{m,n}b/, ST.oldloc is at "a" x m, locinput is
-                     * at b; check that everything between oldloc and
-                     * locinput matches */
+                     * at what may be the beginning of b; check that everything
+                     * between oldloc and locinput matches */
                     char *li = ST.oldloc;
                    ST.count += n;
                     if (regrepeat(rex, &li, ST.A, loceol, reginfo, n) < n)
@@ -9061,32 +9308,16 @@ NULL
 
           curly_try_B_max:
            /* a successful greedy match: now try to match B */
-           {
-               bool could_match = locinput <  loceol;
-
-               /* If it could work, try it. */
-                if (ST.c1 != CHRTEST_VOID && could_match) {
-                    if (! UTF8_IS_INVARIANT(UCHARAT(locinput)) && utf8_target)
-                    {
-                        could_match =  memEQ(locinput, ST.c1_utf8,
-                                             UTF8_SAFE_SKIP(locinput,
-                                                            reginfo->strend))
-                                    || memEQ(locinput, ST.c2_utf8,
-                                             UTF8_SAFE_SKIP(locinput,
-                                                            reginfo->strend));
-                    }
-                    else {
-                        could_match =   UCHARAT(locinput) == ST.c1
-                                     || UCHARAT(locinput) == ST.c2;
-                    }
-                }
-                if (ST.c1 == CHRTEST_VOID || could_match) {
-                   CURLY_SETPAREN(ST.paren, ST.count);
-                   PUSH_STATE_GOTO(CURLY_B_max, ST.B, locinput, loceol,
-                                    script_run_begin);
-                   NOT_REACHED; /* NOTREACHED */
-               }
-           }
+            if (        ST.Binfo.count <= 0
+                || (    ST.Binfo.count > 0
+                    &&  locinput + ST.Binfo.min_length <= loceol
+                    &&  S_test_EXACTISH_ST(locinput, ST.Binfo)))
+            {
+                CURLY_SETPAREN(ST.paren, ST.count);
+                PUSH_STATE_GOTO(CURLY_B_max, ST.B, locinput, loceol,
+                                script_run_begin);
+                NOT_REACHED; /* NOTREACHED */
+            }
            /* FALLTHROUGH */
 
        case CURLY_B_max_fail:
@@ -9150,7 +9381,7 @@ NULL
                                      (long)(locinput - startpos),
                                      (long)(reginfo->till - startpos),
                                      PL_colors[5]));
-                                                     
+
                sayNO_SILENT;           /* Cannot match: too short. */
            }
            sayYES;                     /* Success! */
@@ -9169,7 +9400,7 @@ NULL
            ST.start = locinput;
            ST.end = loceol;
             ST.count = 1;
-           goto do_ifmatch;    
+           goto do_ifmatch;
 
        case UNLESSM:   /* -ve lookaround: (?!A), or with 'flags', (?<!A) */
            ST.wanted = 0;
@@ -9224,7 +9455,7 @@ NULL
            ST.me = scan;
            ST.logical = logical;
            logical = 0; /* XXX: reset state of logical once it has been saved into ST */
-           
+
            /* execute body of (?...A) */
            PUSH_YES_STATE_GOTO(IFMATCH_A, NEXTOPER(NEXTOPER(scan)), ST.start,
                                 ST.end, script_run_begin);
@@ -9290,8 +9521,8 @@ NULL
            NOT_REACHED; /* NOTREACHED */
 
        case COMMIT_next_fail:
-           no_final = 1;    
-           /* FALLTHROUGH */       
+           no_final = 1;
+           /* FALLTHROUGH */
             sayNO;
             NOT_REACHED; /* NOTREACHED */
 
@@ -9312,7 +9543,7 @@ NULL
 #define ST st->u.mark
         case MARKPOINT: /*  (*MARK:foo)  */
             ST.prev_mark = mark_state;
-            ST.mark_name = sv_commit = sv_yes_mark 
+            ST.mark_name = sv_commit = sv_yes_mark
                 = MUTABLE_SV(rexi->data->data[ ARG( scan ) ]);
             mark_state = st;
             ST.mark_loc = locinput;
@@ -9326,7 +9557,7 @@ NULL
             NOT_REACHED; /* NOTREACHED */
 
         case MARKPOINT_next_fail:
-            if (popmark && sv_eq(ST.mark_name,popmark)) 
+            if (popmark && sv_eq(ST.mark_name,popmark))
             {
                 if (ST.mark_loc > startpoint)
                    reginfo->cutpoint = HOPBACKc(ST.mark_loc, 1);
@@ -9340,7 +9571,7 @@ NULL
                });
             }
             mark_state = ST.prev_mark;
-            sv_yes_mark = mark_state ? 
+            sv_yes_mark = mark_state ?
                 mark_state->u.mark.mark_name : NULL;
             sayNO;
             NOT_REACHED; /* NOTREACHED */
@@ -9353,15 +9584,15 @@ NULL
                 PUSH_STATE_GOTO(SKIP_next,next, locinput, loceol,
                                 script_run_begin);
             } else {
-                /* (*SKIP:NAME) : if there is a (*MARK:NAME) fail where it was, 
-                   otherwise do nothing.  Meaning we need to scan 
+                /* (*SKIP:NAME) : if there is a (*MARK:NAME) fail where it was,
+                   otherwise do nothing.  Meaning we need to scan
                  */
                 regmatch_state *cur = mark_state;
                 SV *find = MUTABLE_SV(rexi->data->data[ ARG( scan ) ]);
-                
+
                 while (cur) {
-                    if ( sv_eq( cur->u.mark.mark_name, 
-                                find ) ) 
+                    if ( sv_eq( cur->u.mark.mark_name,
+                                find ) )
                     {
                         ST.mark_name = find;
                         PUSH_STATE_GOTO( SKIP_next, next, locinput, loceol,
@@ -9369,26 +9600,26 @@ NULL
                     }
                     cur = cur->u.mark.prev_mark;
                 }
-            }    
+            }
             /* Didn't find our (*MARK:NAME) so ignore this (*SKIP:NAME) */
-            break;    
+            break;
 
        case SKIP_next_fail:
            if (ST.mark_name) {
-               /* (*CUT:NAME) - Set up to search for the name as we 
+               /* (*CUT:NAME) - Set up to search for the name as we
                   collapse the stack*/
-               popmark = ST.mark_name;    
+               popmark = ST.mark_name;
            } else {
                /* (*CUT) - No name, we cut here.*/
                if (ST.mark_loc > startpoint)
                    reginfo->cutpoint = HOPBACKc(ST.mark_loc, 1);
                /* but we set sv_commit to latest mark_name if there
                   is one so they can test to see how things lead to this
-                  cut */    
-                if (mark_state) 
-                    sv_commit=mark_state->u.mark.mark_name;                
-            } 
-            no_final = 1; 
+                  cut */
+                if (mark_state)
+                    sv_commit=mark_state->u.mark.mark_name;
+            }
+            no_final = 1;
             sayNO;
             NOT_REACHED; /* NOTREACHED */
 #undef ST
@@ -9419,8 +9650,8 @@ NULL
             else
                 locinput++;
             break;
-           
-       } /* end switch */ 
+
+       } /* end switch */
 
         /* switch break jumps here */
        scan = next; /* prepare to execute the next op and ... */
@@ -9465,7 +9696,7 @@ NULL
            st->locinput = locinput;
            st->loceol = loceol;
             st->sr0 = script_run_begin;
-           newst = st+1; 
+           newst = st+1;
            if (newst >  SLAB_LAST(PL_regmatch_slab))
                newst = S_push_slab(aTHX);
            PL_regmatch_state = newst;
@@ -9503,7 +9734,7 @@ NULL
            }
            DEBUG_STATE_r({
                if (no_final) {
-                   DEBUG_STATE_pp("pop (no final)");        
+                   DEBUG_STATE_pp("pop (no final)");
                } else {
                    DEBUG_STATE_pp("pop (yes)");
                }
@@ -9524,7 +9755,7 @@ NULL
        st = yes_state;
        yes_state = st->u.yes.prev_yes_state;
        PL_regmatch_state = st;
-        
+
         if (no_final) {
             locinput= st->locinput;
             loceol= st->loceol;
@@ -9569,7 +9800,7 @@ NULL
         } else {
             goto final_exit;
         }
-    }    
+    }
     if (depth) {
        /* there's a previous state to backtrack to */
        st--;
@@ -9599,10 +9830,10 @@ NULL
         SV *sv_mrk = get_sv("REGMARK", 1);
         if (result) {
             sv_commit = &PL_sv_no;
-            if (!sv_yes_mark) 
+            if (!sv_yes_mark)
                 sv_yes_mark = &PL_sv_yes;
         } else {
-            if (!sv_commit) 
+            if (!sv_commit)
                 sv_commit = &PL_sv_yes;
             sv_yes_mark = &PL_sv_no;
         }
@@ -9652,7 +9883,6 @@ S_regrepeat(pTHX_ regexp *prog, char **startposp, const regnode *p,
     I32 hardcount = 0;  /* How many matches so far */
     bool utf8_target = reginfo->is_utf8_target;
     unsigned int to_complement = 0;  /* Invert the result? */
-    UV utf8_flags = 0;
     _char_class_number classnum;
 
     PERL_ARGS_ASSERT_REGREPEAT;
@@ -9670,22 +9900,22 @@ S_regrepeat(pTHX_ regexp *prog, char **startposp, const regnode *p,
        this_eol = scan + max;
 
     /* Here, for the case of a non-UTF-8 target we have adjusted <this_eol> down
-     * to the maximum of how far we should go in it (leaving it set to the real
-     * end, if the maximum permissible would take us beyond that).  This allows
-     * us to make the loop exit condition that we haven't gone past <this_eol> to
-     * also mean that we haven't exceeded the max permissible count, saving a
-     * test each time through the loops.  But it assumes that the OP matches a
-     * single byte, which is true for most of the OPs below when applied to a
-     * non-UTF-8 target.  Those relatively few OPs that don't have this
-     * characteristic will have to compensate.
+     * to the maximum of how far we should go in it (but leaving it set to the
+     * real end if the maximum permissible would take us beyond that).  This
+     * allows us to make the loop exit condition that we haven't gone past
+     * <this_eol> to also mean that we haven't exceeded the max permissible
+     * count, saving a test each time through the loop.  But it assumes that
+     * the OP matches a single byte, which is true for most of the OPs below
+     * when applied to a non-UTF-8 target.  Those relatively few OPs that don't
+     * have this characteristic have to compensate.
      *
-     * There is no adjustment for UTF-8 targets, as the number of bytes per
-     * character varies.  OPs will have to test both that the count is less
-     * than the max permissible (using <hardcount> to keep track), and that we
-     * are still within the bounds of the string (using <this_eol>.  A few OPs
-     * match a single byte no matter what the encoding.  They can omit the max
-     * test if, for the UTF-8 case, they do the adjustment that was skipped
-     * above.
+     * There is no such adjustment for UTF-8 targets, sinc the number of bytes
+     * per character can vary.  OPs will have to test both that the count is
+     * less than the max permissible (using <hardcount> to keep track), and
+     * that we are still within the bounds of the string (using <this_eol>.  A
+     * few OPs match a single byte no matter what the encoding.  They can omit
+     * the max test if, for the UTF-8 case, they do the adjustment that was
+     * skipped above.
      *
      * Thus, the code above sets things up for the common case; and exceptional
      * cases need extra work; the common case is to make sure <scan> doesn't
@@ -9717,220 +9947,171 @@ S_regrepeat(pTHX_ regexp *prog, char **startposp, const regnode *p,
            scan = this_eol;
        break;
 
-    case LEXACT_REQ8:
-        if (! utf8_target) {
-            break;
-        }
-        /* FALLTHROUGH */
-
-    case LEXACT:
-      {
-        U8 * string;
-        Size_t str_len;
-
-       string = (U8 *) STRINGl(p);
-        str_len = STR_LENl(p);
-        goto join_short_long_exact;
-
     case EXACTL:
-        _CHECK_AND_WARN_PROBLEMATIC_LOCALE;
         if (utf8_target && UTF8_IS_ABOVE_LATIN1(*scan)) {
             _CHECK_AND_OUTPUT_WIDE_LOCALE_UTF8_MSG(scan, loceol);
         }
+        /* FALLTHROUGH */
+
+    case EXACTFL:
+    case EXACTFLU8:
+        _CHECK_AND_WARN_PROBLEMATIC_LOCALE;
         goto do_exact;
 
     case EXACT_REQ8:
+    case LEXACT_REQ8:
+    case EXACTFU_REQ8:
         if (! utf8_target) {
             break;
         }
         /* FALLTHROUGH */
-    case EXACT:
-      do_exact:
-       string = (U8 *) STRINGs(p);
-        str_len = STR_LENs(p);
-
-      join_short_long_exact:
-        assert(str_len == reginfo->is_utf8_pat ? UTF8SKIP(string) : 1);
-
-       c = *string;
-
-        /* Can use a simple find if the pattern char to match on is invariant
-         * under UTF-8, or both target and pattern aren't UTF-8.  Note that we
-         * can use UTF8_IS_INVARIANT() even if the pattern isn't UTF-8, as it's
-         * true iff it doesn't matter if the argument is in UTF-8 or not */
-        if (UTF8_IS_INVARIANT(c) || (! utf8_target && ! reginfo->is_utf8_pat)) {
-            if (utf8_target && this_eol - scan > max) {
-                /* We didn't adjust <this_eol> because is UTF-8, but ok to do so,
-                 * since here, to match at all, 1 char == 1 byte */
-                this_eol = scan + max;
-            }
-            scan = (char *) find_span_end((U8 *) scan, (U8 *) this_eol, (U8) c);
-       }
-       else if (reginfo->is_utf8_pat) {
-            if (utf8_target) {
-                STRLEN scan_char_len;
-
-                /* When both target and pattern are UTF-8, we have to do
-                 * string EQ */
-                while (hardcount < max
-                       && scan < this_eol
-                       && (scan_char_len = UTF8SKIP(scan)) <= str_len
-                       && memEQ(scan, string, scan_char_len))
-                {
-                    scan += scan_char_len;
-                    hardcount++;
-                }
-            }
-            else if (! UTF8_IS_ABOVE_LATIN1(c)) {
-
-                /* Target isn't utf8; convert the character in the UTF-8
-                 * pattern to non-UTF8, and do a simple find */
-                c = EIGHT_BIT_UTF8_TO_NATIVE(c, *(string + 1));
-                scan = (char *) find_span_end((U8 *) scan, (U8 *) this_eol, (U8) c);
-            } /* else pattern char is above Latin1, can't possibly match the
-                 non-UTF-8 target */
-        }
-        else {
 
-            /* Here, the string must be utf8; pattern isn't, and <c> is
-             * different in utf8 than not, so can't compare them directly.
-             * Outside the loop, find the two utf8 bytes that represent c, and
-             * then look for those in sequence in the utf8 string */
-           U8 high = UTF8_TWO_BYTE_HI(c);
-           U8 low = UTF8_TWO_BYTE_LO(c);
+    case LEXACT:
+    case EXACT:
+    case EXACTF:
+    case EXACTFAA_NO_TRIE:
+    case EXACTFAA:
+    case EXACTFU:
+    case EXACTFUP:
 
-           while (hardcount < max
-                   && scan + 1 < this_eol
-                   && UCHARAT(scan) == high
-                   && UCHARAT(scan + 1) == low)
-           {
-               scan += 2;
-               hardcount++;
-           }
-       }
-       break;
-      }
+      do_exact: {
+        struct next_matchable_info Binfo;
+        PERL_UINT_FAST8_T definitive_len;
 
-    case EXACTFAA_NO_TRIE: /* This node only generated for non-utf8 patterns */
-        assert(! reginfo->is_utf8_pat);
-        /* FALLTHROUGH */
-    case EXACTFAA:
-        utf8_flags = FOLDEQ_UTF8_NOMIX_ASCII;
-        if (reginfo->is_utf8_pat || ! utf8_target) {
+        assert(STR_LEN(p) == reginfo->is_utf8_pat ? UTF8SKIP(STRING(p)) : 1);
 
-            /* The possible presence of a MICRO SIGN in the pattern forbids us
-             * to view a non-UTF-8 pattern as folded when there is a UTF-8
-             * target.  */
-            utf8_flags |= FOLDEQ_S2_ALREADY_FOLDED|FOLDEQ_S2_FOLDS_SANE;
+        /* Set up termination info, and quit if we can rule out that we've
+         * gotten a match of the termination criteria */
+        if (   ! S_setup_EXACTISH_ST(aTHX_ p, &Binfo, reginfo)
+            ||   scan + Binfo.min_length > this_eol
+            || ! S_test_EXACTISH_ST(scan, Binfo))
+        {
+            break;
         }
-        goto do_exactf;
 
-    case EXACTFL:
-        _CHECK_AND_WARN_PROBLEMATIC_LOCALE;
-       utf8_flags = FOLDEQ_LOCALE;
-       goto do_exactf;
+        definitive_len = Binfo.initial_definitive;
 
-    case EXACTF:   /* This node only generated for non-utf8 patterns */
-        assert(! reginfo->is_utf8_pat);
-        goto do_exactf;
+        /* Here there are potential matches, and the first byte(s) matched our
+         * filter
+         *
+         * If we got a definitive match of some initial bytes, there is no
+         * possibility of false positives as far as it got */
+        if (definitive_len > 0) {
 
-    case EXACTFLU8:
-        if (! utf8_target) {
-            break;
-        }
-        utf8_flags =  FOLDEQ_LOCALE | FOLDEQ_S2_ALREADY_FOLDED
-                                    | FOLDEQ_S2_FOLDS_SANE;
-        goto do_exactf;
+            /* If as far as it got is the maximum possible, there were no false
+             * positives at all.  Since we have everything set up, see how many
+             * repeats there are. */
+            if (definitive_len >= Binfo.max_length) {
 
-    case EXACTFU_REQ8:
-        if (! utf8_target) {
-            break;
-        }
-       assert(reginfo->is_utf8_pat);
-       utf8_flags = FOLDEQ_S2_ALREADY_FOLDED;
-        goto do_exactf;
+                /* We've already found one match */
+                scan += definitive_len;
+                hardcount++;
 
-    case EXACTFU:
-        utf8_flags = FOLDEQ_S2_ALREADY_FOLDED;
-        /* FALLTHROUGH */
+                /* If want more than the one match, and there is room for more,
+                 * see if there are any */
+                if (hardcount < max && scan + definitive_len <= this_eol) {
 
-    case EXACTFUP:
+                    /* If the character is only a single byte long, just span
+                     * all such bytes. */
+                    if (definitive_len == 1) {
+                        const char * orig_scan = scan;
 
-      do_exactf: {
-        int c1, c2;
-        U8 c1_utf8[UTF8_MAXBYTES+1], c2_utf8[UTF8_MAXBYTES+1];
+                        this_eol = MIN(this_eol, scan + max - hardcount);
 
-        assert(STR_LENs(p) == reginfo->is_utf8_pat ? UTF8SKIP(STRINGs(p)) : 1);
+                        /* Use different routines depending on whether it's an
+                         * exact match or matches with a mask */
+                        if (Binfo.initial_exact == 1) {
+                            scan = (char *) find_span_end((U8 *) scan,
+                                                          (U8 *) this_eol,
+                                                          Binfo.matches[0]);
+                        }
+                        else {
+                            scan = (char *) find_span_end_mask(
+                                                       (U8 *) scan,
+                                                       (U8 *) this_eol,
+                                                       Binfo.first_byte_anded,
+                                                       Binfo.first_byte_mask);
+                        }
 
-        if (S_setup_EXACTISH_ST_c1_c2(aTHX_ p, &c1, c1_utf8, &c2, c2_utf8,
-                                        reginfo))
-        {
-            if (c1 == CHRTEST_VOID) {
-                /* Use full Unicode fold matching */
-                char *tmpeol = loceol;
-                STRLEN pat_len = reginfo->is_utf8_pat ? UTF8SKIP(STRINGs(p)) : 1;
-                while (hardcount < max
-                        && foldEQ_utf8_flags(scan, &tmpeol, 0, utf8_target,
-                                             STRINGs(p), NULL, pat_len,
-                                             reginfo->is_utf8_pat, utf8_flags))
-                {
-                    scan = tmpeol;
-                    tmpeol = loceol;
-                    hardcount++;
-                }
-            }
-            else if (utf8_target) {
-                if (c1 == c2) {
-                    while (scan < this_eol
-                           && hardcount < max
-                           && memEQ(scan, c1_utf8, UTF8_SAFE_SKIP(scan,
-                                                                  loceol)))
-                    {
-                        scan += UTF8SKIP(c1_utf8);
-                        hardcount++;
+                        hardcount += scan - orig_scan;
                     }
-                }
-                else {
-                    while (scan < this_eol
-                           && hardcount < max
-                           && (   memEQ(scan, c1_utf8, UTF8_SAFE_SKIP(scan,
-                                                                     loceol))
-                               || memEQ(scan, c2_utf8, UTF8_SAFE_SKIP(scan,
-                                                                     loceol))))
-                    {
-                        scan += UTF8_SAFE_SKIP(scan, loceol);
-                        hardcount++;
+                    else { /* Here, the full character definitive match is more
+                              than one byte */
+                        while (   hardcount < max
+                               && scan + definitive_len <= this_eol
+                               && S_test_EXACTISH_ST(scan, Binfo))
+                        {
+                                scan += definitive_len;
+                                hardcount++;
+                        }
                     }
                 }
-            }
-            else if (c1 == c2) {
-                scan = (char *) find_span_end((U8 *) scan, (U8 *) this_eol, (U8) c1);
-            }
-            else {
-                /* See comments in regmatch() CURLY_B_min_known_fail.  We avoid
-                 * a conditional each time through the loop if the characters
-                 * differ only in a single bit, as is the usual situation */
-                U8 c1_c2_bits_differing = c1 ^ c2;
 
-                if (isPOWER_OF_2(c1_c2_bits_differing)) {
-                    U8 c1_c2_mask = ~ c1_c2_bits_differing;
+                break;
+            }   /* End of a full character is definitively matched */
 
-                    scan = (char *) find_span_end_mask((U8 *) scan,
-                                                       (U8 *) this_eol,
-                                                       c1 & c1_c2_mask,
-                                                       c1_c2_mask);
-                }
-                else {
-                    while (    scan < this_eol
-                           && (UCHARAT(scan) == c1 || UCHARAT(scan) == c2))
+            /* Here, an initial portion of the character matched definitively,
+             * and the rest matched as well, but could have false positives */
+
+            do {
+                PERL_INT_FAST8_T i;
+                U8 * matches = Binfo.matches;
+
+                /* The first bytes were definitive.  Look at the remaining */
+                for (i = 0; i < Binfo.count; i++) {
+                    if (memEQ(scan + definitive_len,
+                              matches + definitive_len,
+                              Binfo.lengths[i] - definitive_len))
                     {
-                        scan++;
+                        goto found_a_completion;
                     }
+
+                    matches += Binfo.lengths[i];
                 }
+
+                /* Didn't find anything to complete our initial match.  Stop
+                 * here */
+                break;
+
+              found_a_completion:
+
+                /* Here, matched a full character, Include it in the result,
+                 * and then look to see if the next char matches */
+                hardcount++;
+                scan += Binfo.lengths[i];
+
+            } while (   hardcount < max
+                     && scan + definitive_len < this_eol
+                     && S_test_EXACTISH_ST(scan, Binfo));
+
+            /* Here, have advanced as far as possible */
+            break;
+        } /* End of found some initial bytes that definitively matched */
+
+        /* Here, we can't rule out that we have found the beginning of 'B', but
+         * there were no initial bytes that could rule out anything
+         * definitively. Use brute force to examine all the possibilities */
+        while (scan < this_eol && hardcount < max) {
+            PERL_INT_FAST8_T i;
+            U8 * matches = Binfo.matches;
+
+            for (i = 0; i < Binfo.count; i++) {
+                if (memEQ(scan, matches, Binfo.lengths[i])) {
+                    goto found1;
+                }
+
+                matches += Binfo.lengths[i];
             }
-       }
+
+            break;
+
+          found1:
+            hardcount++;
+            scan += Binfo.lengths[i];
+        }
+
        break;
-    }
+      }
     case ANYOFPOSIXL:
     case ANYOFL:
         _CHECK_AND_WARN_PROBLEMATIC_LOCALE;
@@ -10300,7 +10481,7 @@ S_regrepeat(pTHX_ regexp *prog, char **startposp, const regnode *p,
 
 /*
  - reginclass - determine if a character falls into a character class
+
   n is the ANYOF-type regnode
   p is the target string
   p_end points to one byte beyond the end of the target string
index d9f1a40..cfb8d44 100644 (file)
--- a/regexp.h
+++ b/regexp.h
@@ -706,6 +706,32 @@ typedef struct {
 #  define MAX_RECURSE_EVAL_NOCHANGE_DEPTH 10
 #endif
 
+/* The +3 is based on the current Unicode standards needs, and is unlikely to
+ * change.  An assertion should fail in regexec.c if it is too low.  It is
+ * needed for certain edge cases involving multi-character folds when the first
+ * component also participates in a fold individually. */
+#define MAX_MATCHES (MAX_FOLD_FROMS + 3)
+
+struct next_matchable_info {
+    U8     first_byte_mask;
+    U8     first_byte_anded;
+    U32    mask32;
+    U32    anded32;
+    PERL_INT_FAST8_T count; /* Negative means not initialized */
+    PERL_UINT_FAST8_T min_length;
+    PERL_UINT_FAST8_T max_length;
+    PERL_UINT_FAST8_T initial_definitive;
+    PERL_UINT_FAST8_T initial_exact;
+    PERL_UINT_FAST8_T lengths[MAX_MATCHES];
+
+    /* The size is from trial and error, and could change with new Unicode
+     * standards, in which case there is an assertion that should start
+     * failing.  This size could be calculated in one of the regen scripts
+     * dealing with Unicode, but khw thinks the likelihood of it changing is
+     * low enough that it isn't worth the effort. */
+    U8 matches[18];
+};
+
 typedef I32 CHECKPOINT;
 
 typedef struct regmatch_state {
@@ -854,7 +880,6 @@ typedef struct regmatch_state {
        struct {
            /* this first element must match u.yes */
            struct regmatch_state *prev_yes_state;
-           int c1, c2;         /* case fold search */
            CHECKPOINT cp;
            U32 lastparen;
            U32 lastcloseparen;
@@ -863,8 +888,7 @@ typedef struct regmatch_state {
            bool minmod;
            regnode *A, *B;     /* the nodes corresponding to /A*B/  */
            regnode *me;        /* the curlym node */
-            U8 c1_utf8[UTF8_MAXBYTES+1];  /* */
-            U8 c2_utf8[UTF8_MAXBYTES+1];
+            struct next_matchable_info Binfo;
        } curlym;
 
        struct {
@@ -872,14 +896,12 @@ typedef struct regmatch_state {
            CHECKPOINT cp;
            U32 lastparen;
            U32 lastcloseparen;
-           int c1, c2;         /* case fold search */
            char *maxpos;       /* highest possible point in string to match */
            char *oldloc;       /* the previous locinput */
            int count;
            int min, max;       /* {m,n} */
            regnode *A, *B;     /* the nodes corresponding to /A*B/  */
-            U8 c1_utf8[UTF8_MAXBYTES+1];  /* */
-            U8 c2_utf8[UTF8_MAXBYTES+1];
+            struct next_matchable_info Binfo;
        } curly; /* and CURLYN/PLUS/STAR */
 
     } u;
index 98de0bb..94b7110 100644 (file)
 #define BOUNDL_t8_pb                    38  /*      0x026 */
 #define BOUNDL_t8_p8                    39  /*      0x027 */
 
-#define BOUNDU                       10     /* 0x0a Match "" at any boundary of
-                                               a given type using /u rules. */
+#define BOUNDU                       10     /* 0x0a Match "" at any boundary
+                                               of a given type using /u rules.
+                                            */
 #define BOUNDU_tb_pb                    40  /*      0x028 */
 #define BOUNDU_tb_p8                    41  /*      0x029 */
 #define BOUNDU_t8_pb                    42  /*      0x02a */
 #define NBOUND_t8_pb                    50  /*      0x032 */
 #define NBOUND_t8_p8                    51  /*      0x033 */
 
-#define NBOUNDL                      13     /* 0x0d Like NBOUND/NBOUNDU, but \w
-                                               and \W are defined by current
-                                               locale */
+#define NBOUNDL                      13     /* 0x0d Like NBOUND/NBOUNDU, but
+                                               \w and \W are defined by
+                                               current locale */
 #define NBOUNDL_tb_pb                   52  /*      0x034 */
 #define NBOUNDL_tb_p8                   53  /*      0x035 */
 #define NBOUNDL_t8_pb                   54  /*      0x036 */
 #define REG_ANY_t8_pb                   66  /*      0x042 */
 #define REG_ANY_t8_p8                   67  /*      0x043 */
 
-#define SANY                         17     /* 0x11 Match any one character. */
+#define SANY                         17     /* 0x11 Match any one character.
+                                            */
 #define SANY_tb_pb                      68  /*      0x044 */
 #define SANY_tb_p8                      69  /*      0x045 */
 #define SANY_t8_pb                      70  /*      0x046 */
 
 #define ANYOFH                       22     /* 0x16 Like ANYOF, but only has
                                                "High" matches, none in the
-                                               bitmap; the flags field contains
-                                               the lowest matchable UTF-8 start
-                                               byte */
+                                               bitmap; the flags field
+                                               contains the lowest matchable
+                                               UTF-8 start byte */
 #define ANYOFH_tb_pb                    88  /*      0x058 */
 #define ANYOFH_tb_p8                    89  /*      0x059 */
 #define ANYOFH_t8_pb                    90  /*      0x05a */
 #define ANYOFHb_t8_p8                   95  /*      0x05f */
 
 #define ANYOFHr                      24     /* 0x18 Like ANYOFH, but the flags
-                                               field contains packed bounds for
-                                               all matchable UTF-8 start bytes.
-                                            */
+                                               field contains packed bounds
+                                               for all matchable UTF-8 start
+                                               bytes. */
 #define ANYOFHr_tb_pb                   96  /*      0x060 */
 #define ANYOFHr_tb_p8                   97  /*      0x061 */
 #define ANYOFHr_t8_pb                   98  /*      0x062 */
 #define NPOSIXA_t8_pb                  150  /*      0x096 */
 #define NPOSIXA_t8_p8                  151  /*      0x097 */
 
-#define CLUMP                        38     /* 0x26 Match any extended grapheme
-                                               cluster sequence */
+#define CLUMP                        38     /* 0x26 Match any extended
+                                               grapheme cluster sequence */
 #define CLUMP_tb_pb                    152  /*      0x098 */
 #define CLUMP_tb_p8                    153  /*      0x099 */
 #define CLUMP_t8_pb                    154  /*      0x09a */
 #define EXACTL_t8_pb                   170  /*      0x0aa */
 #define EXACTL_t8_p8                   171  /*      0x0ab */
 
-#define EXACTF                       43     /* 0x2b Like EXACT, but match using
-                                               /id rules; (string not UTF-8,
-                                               ASCII folded; non-ASCII not) */
+#define EXACTF                       43     /* 0x2b Like EXACT, but match
+                                               using /id rules; (string not
+                                               UTF-8, ASCII folded; non-ASCII
+                                               not) */
 #define EXACTF_tb_pb                   172  /*      0x0ac */
 #define EXACTF_tb_p8                   173  /*      0x0ad */
 #define EXACTF_t8_pb                   174  /*      0x0ae */
 #define EXACTF_t8_p8                   175  /*      0x0af */
 
-#define EXACTFL                      44     /* 0x2c Like EXACT, but match using
-                                               /il rules; (string not likely to
-                                               be folded) */
+#define EXACTFL                      44     /* 0x2c Like EXACT, but match
+                                               using /il rules; (string not
+                                               likely to be folded) */
 #define EXACTFL_tb_pb                  176  /*      0x0b0 */
 #define EXACTFL_tb_p8                  177  /*      0x0b1 */
 #define EXACTFL_t8_pb                  178  /*      0x0b2 */
 #define EXACTFL_t8_p8                  179  /*      0x0b3 */
 
-#define EXACTFU                      45     /* 0x2d Like EXACT, but match using
-                                               /iu rules; (string folded) */
+#define EXACTFU                      45     /* 0x2d Like EXACT, but match
+                                               using /iu rules; (string
+                                               folded) */
 #define EXACTFU_tb_pb                  180  /*      0x0b4 */
 #define EXACTFU_tb_p8                  181  /*      0x0b5 */
 #define EXACTFU_t8_pb                  182  /*      0x0b6 */
 #define EXACTFU_t8_p8                  183  /*      0x0b7 */
 
-#define EXACTFAA                     46     /* 0x2e Like EXACT, but match using
-                                               /iaa rules; (string folded
-                                               except MICRO in non-UTF8
+#define EXACTFAA                     46     /* 0x2e Like EXACT, but match
+                                               using /iaa rules; (string
+                                               folded except MICRO in non-UTF8
                                                patterns; doesn't contain SHARP
-                                               S unless UTF-8; folded length <=
-                                               unfolded) */
+                                               S unless UTF-8; folded length
+                                               <= unfolded) */
 #define EXACTFAA_tb_pb                 184  /*      0x0b8 */
 #define EXACTFAA_tb_p8                 185  /*      0x0b9 */
 #define EXACTFAA_t8_pb                 186  /*      0x0ba */
 #define EXACTFAA_NO_TRIE_t8_pb         190  /*      0x0be */
 #define EXACTFAA_NO_TRIE_t8_p8         191  /*      0x0bf */
 
-#define EXACTFUP                     48     /* 0x30 Like EXACT, but match using
-                                               /iu rules; (string not UTF-8,
-                                               folded except MICRO: hence
-                                               Problematic) */
+#define EXACTFUP                     48     /* 0x30 Like EXACT, but match
+                                               using /iu rules; (string not
+                                               UTF-8, folded except MICRO:
+                                               hence Problematic) */
 #define EXACTFUP_tb_pb                 192  /*      0x0c0 */
 #define EXACTFUP_tb_p8                 193  /*      0x0c1 */
 #define EXACTFUP_t8_pb                 194  /*      0x0c2 */
 
 #define EXACTFLU8                    49     /* 0x31 Like EXACTFU, but use /il,
                                                UTF-8, (string is folded, and
-                                               everything in it is above 255 */
+                                               everything in it is above 255
+                                            */
 #define EXACTFLU8_tb_pb                196  /*      0x0c4 */
 #define EXACTFLU8_tb_p8                197  /*      0x0c5 */
 #define EXACTFLU8_t8_pb                198  /*      0x0c6 */
 #define EXACT_REQ8_t8_pb               202  /*      0x0ca */
 #define EXACT_REQ8_t8_p8               203  /*      0x0cb */
 
-#define LEXACT_REQ8                  51     /* 0x33 Like LEXACT, but only UTF-8
-                                               encoded targets can match */
+#define LEXACT_REQ8                  51     /* 0x33 Like LEXACT, but only
+                                               UTF-8 encoded targets can match
+                                            */
 #define LEXACT_REQ8_tb_pb              204  /*      0x0cc */
 #define LEXACT_REQ8_tb_p8              205  /*      0x0cd */
 #define LEXACT_REQ8_t8_pb              206  /*      0x0ce */
 #define EXACTFU_S_EDGE               53     /* 0x35 /di rules, but nothing in
                                                it precludes /ui, except begins
                                                and/or ends with [Ss]; (string
-                                               not UTF-8; compile-time only) */
+                                               not UTF-8; compile-time only)
+                                            */
 #define EXACTFU_S_EDGE_tb_pb           212  /*      0x0d4 */
 #define EXACTFU_S_EDGE_tb_p8           213  /*      0x0d5 */
 #define EXACTFU_S_EDGE_t8_pb           214  /*      0x0d6 */
 #define TAIL_t8_pb                     242  /*      0x0f2 */
 #define TAIL_t8_p8                     243  /*      0x0f3 */
 
-#define STAR                         61     /* 0x3d Match this (simple) thing 0
-                                               or more times. */
+#define STAR                         61     /* 0x3d Match this (simple) thing
+                                               or more times. */
 #define STAR_tb_pb                     244  /*      0x0f4 */
 #define STAR_tb_p8                     245  /*      0x0f5 */
 #define STAR_t8_pb                     246  /*      0x0f6 */
 #define STAR_t8_p8                     247  /*      0x0f7 */
 
-#define PLUS                         62     /* 0x3e Match this (simple) thing 1
-                                               or more times. */
+#define PLUS                         62     /* 0x3e Match this (simple) thing
+                                               or more times. */
 #define PLUS_tb_pb                     248  /*      0x0f8 */
 #define PLUS_tb_p8                     249  /*      0x0f9 */
 #define PLUS_t8_pb                     250  /*      0x0fa */
 #define CURLYN_t8_pb                   258  /*      0x102 */
 #define CURLYN_t8_p8                   259  /*      0x103 */
 
-#define CURLYM                       65     /* 0x41 Capture this medium-complex
-                                               thing {n,m} times. */
+#define CURLYM                       65     /* 0x41 Capture this
+                                               medium-complex thing {n,m}
+                                               times. */
 #define CURLYM_tb_pb                   260  /*      0x104 */
 #define CURLYM_tb_p8                   261  /*      0x105 */
 #define CURLYM_t8_pb                   262  /*      0x106 */
 #define CURLYX_t8_pb                   266  /*      0x10a */
 #define CURLYX_t8_p8                   267  /*      0x10b */
 
-#define WHILEM                       67     /* 0x43 Do curly processing and see
-                                               if rest matches. */
+#define WHILEM                       67     /* 0x43 Do curly processing and
+                                               see if rest matches. */
 #define WHILEM_tb_pb                   268  /*      0x10c */
 #define WHILEM_tb_p8                   269  /*      0x10d */
 #define WHILEM_t8_pb                   270  /*      0x10e */
 #define WHILEM_t8_p8                   271  /*      0x10f */
 
-#define OPEN                         68     /* 0x44 Mark this point in input as
-                                               start of #n. */
+#define OPEN                         68     /* 0x44 Mark this point in input
+                                               as start of #n. */
 #define OPEN_tb_pb                     272  /*      0x110 */
 #define OPEN_tb_p8                     273  /*      0x111 */
 #define OPEN_t8_pb                     274  /*      0x112 */
 #define OPEN_t8_p8                     275  /*      0x113 */
 
-#define CLOSE                        69     /* 0x45 Close corresponding OPEN of
-                                               #n. */
+#define CLOSE                        69     /* 0x45 Close corresponding OPEN
+                                               of #n. */
 #define CLOSE_tb_pb                    276  /*      0x114 */
 #define CLOSE_tb_p8                    277  /*      0x115 */
 #define CLOSE_t8_pb                    278  /*      0x116 */
 #define LONGJMP_t8_pb                  330  /*      0x14a */
 #define LONGJMP_t8_p8                  331  /*      0x14b */
 
-#define BRANCHJ                      83     /* 0x53 BRANCH with long offset. */
+#define BRANCHJ                      83     /* 0x53 BRANCH with long offset.
+                                            */
 #define BRANCHJ_tb_pb                  332  /*      0x14c */
 #define BRANCHJ_tb_p8                  333  /*      0x14d */
 #define BRANCHJ_t8_pb                  334  /*      0x14e */
 #define ENDLIKE_t8_pb                  390  /*      0x186 */
 #define ENDLIKE_t8_p8                  391  /*      0x187 */
 
-#define OPFAIL                       98     /* 0x62 Same as (?!), but with verb
-                                               arg */
+#define OPFAIL                       98     /* 0x62 Same as (?!), but with
+                                               verb arg */
 #define OPFAIL_tb_pb                   392  /*      0x188 */
 #define OPFAIL_tb_p8                   393  /*      0x189 */
 #define OPFAIL_t8_pb                   394  /*      0x18a */
 #define OPFAIL_t8_p8                   395  /*      0x18b */
 
-#define ACCEPT                       99     /* 0x63 Accepts the current matched
-                                               string, with verbar */
+#define ACCEPT                       99     /* 0x63 Accepts the current
+                                               matched string, with verbar */
 #define ACCEPT_tb_pb                   396  /*      0x18c */
 #define ACCEPT_tb_p8                   397  /*      0x18d */
 #define ACCEPT_t8_pb                   398  /*      0x18e */
 #define MARKPOINT_t8_pb                410  /*      0x19a */
 #define MARKPOINT_t8_p8                411  /*      0x19b */
 
-#define SKIP                        103     /* 0x67 On failure skip forward (to
-                                               the mark) before retrying */
+#define SKIP                        103     /* 0x67 On failure skip forward
+                                               (to the mark) before retrying
+                                            */
 #define SKIP_tb_pb                     412  /*      0x19c */
 #define SKIP_tb_p8                     413  /*      0x19d */
 #define SKIP_t8_pb                     414  /*      0x19e */
diff --git a/scope.c b/scope.c
index cea1500..19281d1 100644 (file)
--- a/scope.c
+++ b/scope.c
@@ -512,14 +512,22 @@ Perl_save_I32(pTHX_ I32 *intp)
 void
 Perl_save_strlen(pTHX_ STRLEN *ptr)
 {
+    const IV i = *ptr;
+    UV type = ((I32)((U32)i << SAVE_TIGHT_SHIFT) | SAVEt_STRLEN_SMALL);
+    int size = 2;
     dSS_ADD;
 
     PERL_ARGS_ASSERT_SAVE_STRLEN;
 
-    SS_ADD_IV(*ptr);
+    if (UNLIKELY((I32)(type >> SAVE_TIGHT_SHIFT) != i)) {
+        SS_ADD_IV(*ptr);
+        type = SAVEt_STRLEN;
+        size++;
+    }
+
     SS_ADD_PTR(ptr);
-    SS_ADD_UV(SAVEt_STRLEN);
-    SS_ADD_END(3);
+    SS_ADD_UV(type);
+    SS_ADD_END(size);
 }
 
 void
@@ -840,6 +848,7 @@ static const U8 arg_counts[] = {
     1, /* SAVEt_STACK_POS          */
     1, /* SAVEt_READONLY_OFF       */
     1, /* SAVEt_FREEPADNAME        */
+    1, /* SAVEt_STRLEN_SMALL       */
     2, /* SAVEt_AV                 */
     2, /* SAVEt_DESTRUCTOR         */
     2, /* SAVEt_DESTRUCTOR_X       */
@@ -1045,6 +1054,11 @@ Perl_leave_scope(pTHX_ I32 base)
            *(int*)a1.any_ptr = (int)a0.any_i32;
            break;
 
+        case SAVEt_STRLEN_SMALL:
+           a0 = ap[0];
+           *(STRLEN*)a0.any_ptr = (STRLEN)(uv >> SAVE_TIGHT_SHIFT);
+            break;
+
        case SAVEt_STRLEN:                      /* STRLEN/size_t ref */
             a0 = ap[0]; a1 = ap[1];
            *(STRLEN*)a1.any_ptr = (STRLEN)a0.any_iv;
diff --git a/scope.h b/scope.h
index 5b611c2..a7dee13 100644 (file)
--- a/scope.h
+++ b/scope.h
 #define SAVEt_STACK_POS                20
 #define SAVEt_READONLY_OFF     21
 #define SAVEt_FREEPADNAME      22
+#define SAVEt_STRLEN_SMALL      23
 
 /* two args */
 
-#define SAVEt_AV               23
-#define SAVEt_DESTRUCTOR       24
-#define SAVEt_DESTRUCTOR_X     25
-#define SAVEt_GENERIC_PVREF    26
-#define SAVEt_GENERIC_SVREF    27
-#define SAVEt_GP               28
-#define SAVEt_GVSV             29
-#define SAVEt_HINTS            30
-#define SAVEt_HPTR             31
-#define SAVEt_HV               32
-#define SAVEt_I32              33
-#define SAVEt_INT              34
-#define SAVEt_ITEM             35
-#define SAVEt_IV               36
-#define SAVEt_LONG             37
-#define SAVEt_PPTR             38
-#define SAVEt_SAVESWITCHSTACK  39
-#define SAVEt_SHARED_PVREF     40
-#define SAVEt_SPTR             41
-#define SAVEt_STRLEN           42
-#define SAVEt_SV               43
-#define SAVEt_SVREF            44
-#define SAVEt_VPTR             45
-#define SAVEt_ADELETE          46
-#define SAVEt_APTR             47
+#define SAVEt_AV               24
+#define SAVEt_DESTRUCTOR       25
+#define SAVEt_DESTRUCTOR_X     26
+#define SAVEt_GENERIC_PVREF    27
+#define SAVEt_GENERIC_SVREF    28
+#define SAVEt_GP               29
+#define SAVEt_GVSV             30
+#define SAVEt_HINTS            31
+#define SAVEt_HPTR             32
+#define SAVEt_HV               33
+#define SAVEt_I32              34
+#define SAVEt_INT              35
+#define SAVEt_ITEM             36
+#define SAVEt_IV               37
+#define SAVEt_LONG             38
+#define SAVEt_PPTR             39
+#define SAVEt_SAVESWITCHSTACK  40
+#define SAVEt_SHARED_PVREF     41
+#define SAVEt_SPTR             42
+#define SAVEt_STRLEN           43
+#define SAVEt_SV               44
+#define SAVEt_SVREF            45
+#define SAVEt_VPTR             46
+#define SAVEt_ADELETE          47
+#define SAVEt_APTR             48
 
 /* three args */
 
-#define SAVEt_HELEM            48
-#define SAVEt_PADSV_AND_MORTALIZE 49
-#define SAVEt_SET_SVFLAGS      50
-#define SAVEt_GVSLOT           51
-#define SAVEt_AELEM            52
-#define SAVEt_DELETE           53
-#define SAVEt_HINTS_HH         54
+#define SAVEt_HELEM            49
+#define SAVEt_PADSV_AND_MORTALIZE 50
+#define SAVEt_SET_SVFLAGS      51
+#define SAVEt_GVSLOT           52
+#define SAVEt_AELEM            53
+#define SAVEt_DELETE           54
+#define SAVEt_HINTS_HH         55
 
 
 #define SAVEf_SETMAGIC         1
diff --git a/sv.c b/sv.c
index 4e9f45a..d4df78f 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -181,7 +181,7 @@ perl_destruct() to physically free all the arenas allocated since the
 start of the interpreter.
 
 The internal function visit() scans the SV arenas list, and calls a specified
-function for each SV it finds which is still live - ie which has an SvTYPE
+function for each SV it finds which is still live, I<i.e.> which has an SvTYPE
 other than all 1's, and a non-zero SvREFCNT. visit() is used by the
 following functions (specified as [function that calls visit()] / [function
 called by visit() for each SV]):
@@ -2055,7 +2055,7 @@ S_sv_2iuv_non_preserve(pTHX_ SV *const sv
     (void)SvNOK_on(sv);
     /* Can't use strtol etc to convert this string.  (See truth table in
        sv_2iv  */
-    if (SvNVX(sv) <= (UV)IV_MAX) {
+    if (SvNVX(sv) < IV_MAX_P1) {
         SvIV_set(sv, I_V(SvNVX(sv)));
         if ((NV)(SvIVX(sv)) == SvNVX(sv)) {
             SvIOK_on(sv); /* Integer is precise. NOK, IOK */
@@ -3424,7 +3424,7 @@ Perl_sv_2bool_flags(pTHX_ SV *sv, I32 flags)
     if (SvNOK(sv) && !SvPOK(sv))
         return SvNVX(sv) != 0.0;
 
-    return SvTRUE_common(sv, isGV_with_GP(sv) ? 1 : 0);
+    return SvTRUE_common(sv, 0);
 }
 
 /*
@@ -5561,14 +5561,32 @@ Perl_sv_catsv_flags(pTHX_ SV *const dsv, SV *const sstr, const I32 flags)
 
 /*
 =for apidoc sv_catpv
+=for apidoc_item sv_catpv_flags
+=for apidoc_item sv_catpv_mg
+=for apidoc_item sv_catpv_nomg
 
-Concatenates the C<NUL>-terminated string C<sstr> onto the end of the string which is
-in the SV.
+These concatenate the C<NUL>-terminated string C<sstr> onto the end of the
+string which is in the SV.
 If the SV has the UTF-8 status set, then the bytes appended should be
-valid UTF-8.  Handles 'get' magic, but not 'set' magic.  See
-C<L</sv_catpv_mg>>.
+valid UTF-8.
 
-=cut */
+They differ only in how they handle magic:
+
+C<sv_catpv_mg> performs both 'get' and 'set' magic.
+
+C<sv_catpv> performs only 'get' magic.
+
+C<sv_catpv_nomg> skips all magic.
+
+C<sv_catpv_flags> has an extra C<flags> parameter which allows you to specify
+any combination of magic handling (using C<SV_GMAGIC> and/or C<SV_SMAGIC>), and
+to also override the UTF-8 handling.  By supplying the C<SV_CATUTF8> flag, the
+appended string is forced to be interpreted as UTF-8; by supplying instead the
+C<SV_CATBYTES> flag, it will be interpreted as just bytes.  Either the SV or
+the string appended will be upgraded to UTF-8 if necessary.
+
+=cut
+*/
 
 void
 Perl_sv_catpv(pTHX_ SV *const dsv, const char *sstr)
@@ -5592,18 +5610,6 @@ Perl_sv_catpv(pTHX_ SV *const dsv, const char *sstr)
     SvTAINT(dsv);
 }
 
-/*
-=for apidoc sv_catpv_flags
-
-Concatenates the C<NUL>-terminated string onto the end of the string which is
-in the SV.
-If the SV has the UTF-8 status set, then the bytes appended should
-be valid UTF-8.  If C<flags> has the C<SV_SMAGIC> bit set, will C<L</mg_set>>
-on the modified SV if appropriate.
-
-=cut
-*/
-
 void
 Perl_sv_catpv_flags(pTHX_ SV *dsv, const char *sstr, const I32 flags)
 {
@@ -5611,14 +5617,6 @@ Perl_sv_catpv_flags(pTHX_ SV *dsv, const char *sstr, const I32 flags)
     sv_catpvn_flags(dsv, sstr, strlen(sstr), flags);
 }
 
-/*
-=for apidoc sv_catpv_mg
-
-Like C<sv_catpv>, but also handles 'set' magic.
-
-=cut
-*/
-
 void
 Perl_sv_catpv_mg(pTHX_ SV *const dsv, const char *const sstr)
 {
@@ -8878,9 +8876,13 @@ Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 append)
 
 /*
 =for apidoc sv_inc
+=for apidoc_item sv_inc_nomg
+
+These auto-increment the value in the SV, doing string to numeric conversion
+if necessary.  They both handle operator overloading.
 
-Auto-increment of the value in the SV, doing string to numeric conversion
-if necessary.  Handles 'get' magic and operator overloading.
+They differ only in that C<sv_inc> performs 'get' magic; C<sv_inc_nomg> skips
+any magic.
 
 =cut
 */
@@ -8894,15 +8896,6 @@ Perl_sv_inc(pTHX_ SV *const sv)
     sv_inc_nomg(sv);
 }
 
-/*
-=for apidoc sv_inc_nomg
-
-Auto-increment of the value in the SV, doing string to numeric conversion
-if necessary.  Handles operator overloading.  Skips handling 'get' magic.
-
-=cut
-*/
-
 void
 Perl_sv_inc_nomg(pTHX_ SV *const sv)
 {
@@ -9748,13 +9741,13 @@ Perl_newRV(pTHX_ SV *const sv)
 
 /*
 =for apidoc newSVsv
+=for apidoc_item newSVsv_nomg
 
-Creates a new SV which is an exact duplicate of the original SV.
+These create a new SV which is an exact duplicate of the original SV.
 (Uses C<sv_setsv>.)
 
-=for apidoc newSVsv_nomg
-
-Like C<newSVsv> but does not process get magic.
+They differ only in that C<newSVsv> performs 'get' magic; C<newSVsv_nomg> skips
+any magic.
 
 =cut
 */
@@ -10677,9 +10670,12 @@ Perl_sv_tainted(pTHX_ SV *const sv)
 
 /*
 =for apidoc sv_setpviv
+=for apidoc_item sv_setpviv_mg
+
+These copy an integer into the given SV, also updating its string value.
 
-Copies an integer into the given SV, also updating its string value.
-Does not handle 'set' magic.  See C<L</sv_setpviv_mg>>.
+They differ only in that C<sv_setpviv_mg> performs 'set' magic; C<sv_setpviv>
+skips any magic.
 
 =cut
 */
@@ -10701,14 +10697,6 @@ Perl_sv_setpviv(pTHX_ SV *const sv, const IV iv)
     sv_setpvn(sv, ptr, ebuf - ptr);
 }
 
-/*
-=for apidoc sv_setpviv_mg
-
-Like C<sv_setpviv>, but also handles 'set' magic.
-
-=cut
-*/
-
 void
 Perl_sv_setpviv_mg(pTHX_ SV *const sv, const IV iv)
 {
@@ -10766,14 +10754,21 @@ Perl_sv_setpvf_mg_nocontext(SV *const sv, const char *const pat, ...)
 
 /*
 =for apidoc sv_setpvf
+=for apidoc_item sv_setpvf_nocontext
+=for apidoc_item sv_setpvf_mg
+=for apidoc_item sv_setpvf_mg_nocontext
 
-Works like C<sv_catpvf> but copies the text into the SV instead of
-appending it.  Does not handle 'set' magic.  See C<L</sv_setpvf_mg>>.
+These work like C<L</sv_catpvf>> but copy the text into the SV instead of
+appending it.
 
-=for apidoc sv_setpvf_nocontext
-Like C<L</sv_setpvf>> but does not take a thread context (C<aTHX>) parameter,
-so is used in situations where the caller doesn't already have the thread
-context.
+The differences between these are:
+
+C<sv_setpvf> and C<sv_setpvf_nocontext> do not handle 'set' magic;
+C<sv_setpvf_mg> and C<sv_setpvf_mg_nocontext> do.
+
+C<sv_setpvf_nocontext> and C<sv_setpvf_mg_nocontext> do not take a thread
+context (C<aTHX>) parameter, so are used in situations where the caller
+doesn't already have the thread context.
 
 =cut
 */
@@ -10792,11 +10787,16 @@ Perl_sv_setpvf(pTHX_ SV *const sv, const char *const pat, ...)
 
 /*
 =for apidoc sv_vsetpvf
+=for apidoc_item sv_vsetpvf_mg
+
+These work like C<L</sv_vcatpvf>> but copy the text into the SV instead of
+appending it.
 
-Works like C<sv_vcatpvf> but copies the text into the SV instead of
-appending it.  Does not handle 'set' magic.  See C<L</sv_vsetpvf_mg>>.
+They differ only in that C<sv_vsetpvf_mg> performs 'set' magic;
+C<sv_vsetpvf> skips all magic.
 
-Usually used via its frontend C<sv_setpvf>.
+They are usually used via their frontends, C<L</sv_setpvf>> and
+C<L</sv_setpvf_mg>>.
 
 =cut
 */
@@ -10809,19 +10809,6 @@ Perl_sv_vsetpvf(pTHX_ SV *const sv, const char *const pat, va_list *const args)
     sv_vsetpvfn(sv, pat, strlen(pat), args, NULL, 0, NULL);
 }
 
-/*
-=for apidoc sv_setpvf_mg
-
-Like C<sv_setpvf>, but also handles 'set' magic.
-
-=for apidoc sv_setpvf_mg_nocontext
-Like C<L</sv_setpvf_mg>>, but does not take a thread context (C<aTHX>)
-parameter, so is used in situations where the caller doesn't already have the
-thread context.
-
-=cut
-*/
-
 void
 Perl_sv_setpvf_mg(pTHX_ SV *const sv, const char *const pat, ...)
 {
@@ -10834,16 +10821,6 @@ Perl_sv_setpvf_mg(pTHX_ SV *const sv, const char *const pat, ...)
     va_end(args);
 }
 
-/*
-=for apidoc sv_vsetpvf_mg
-
-Like C<sv_vsetpvf>, but also handles 'set' magic.
-
-Usually used via its frontend C<sv_setpvf_mg>.
-
-=cut
-*/
-
 void
 Perl_sv_vsetpvf_mg(pTHX_ SV *const sv, const char *const pat, va_list *const args)
 {
@@ -10895,23 +10872,31 @@ Perl_sv_catpvf_mg_nocontext(SV *const sv, const char *const pat, ...)
 
 /*
 =for apidoc sv_catpvf
+=for apidoc_item sv_catpvf_nocontext
+=for apidoc_item sv_catpvf_mg
+=for apidoc_item sv_catpvf_mg_nocontext
+
+These process their arguments like C<sprintf>, and append the formatted
+output to an SV.  As with C<sv_vcatpvfn>, argument reordering is not supporte
+when called with a non-null C-style variable argument list.
 
-Processes its arguments like C<sprintf>, and appends the formatted
-output to an SV.  As with C<sv_vcatpvfn> called with a non-null C-style
-variable argument list, argument reordering is not supported.
 If the appended data contains "wide" characters
 (including, but not limited to, SVs with a UTF-8 PV formatted with C<%s>,
 and characters >255 formatted with C<%c>), the original SV might get
-upgraded to UTF-8.  Handles 'get' magic, but not 'set' magic.  See
-C<L</sv_catpvf_mg>>.  If the original SV was UTF-8, the pattern should be
+upgraded to UTF-8.
+
+If the original SV was UTF-8, the pattern should be
 valid UTF-8; if the original SV was bytes, the pattern should be too.
 
-=for apidoc sv_catpvf_nocontext
-Like C<L</sv_catpvf>> but does not take a thread context (C<aTHX>) parameter,
-so is used in situations where the caller doesn't already have the thread
-context.
+All perform 'get' magic, but only C<sv_catpvf_mg> and C<sv_catpvf_mg_nocontext>
+perform 'set' magic.
 
-=cut */
+C<sv_catpvf_nocontext> and C<sv_catpvf_mg_nocontext> do not take a thread
+context (C<aTHX>) parameter, so are used in situations where the caller
+doesn't already have the thread context.
+
+=cut
+*/
 
 void
 Perl_sv_catpvf(pTHX_ SV *const sv, const char *const pat, ...)
@@ -10927,12 +10912,18 @@ Perl_sv_catpvf(pTHX_ SV *const sv, const char *const pat, ...)
 
 /*
 =for apidoc sv_vcatpvf
+=for apidoc_item sv_vcatpvf_mg
+
+These process their arguments like C<sv_vcatpvfn> called with a non-null
+C-style variable argument list, and append the formatted output to C<sv>.
+
+They differ only in that C<sv_vcatpvf_mg> performs 'set' magic;
+C<sv_vcatpvf> skips 'set' magic.
 
-Processes its arguments like C<sv_vcatpvfn> called with a non-null C-style
-variable argument list, and appends the formatted output
-to an SV.  Does not handle 'set' magic.  See C<L</sv_vcatpvf_mg>>.
+Both perform 'get' magic.
 
-Usually used via its frontend C<sv_catpvf>.
+They are usually accessed via their frontends C<L</sv_catpvf>> and
+C<L</sv_catpvf_mg>>.
 
 =cut
 */
@@ -10945,19 +10936,6 @@ Perl_sv_vcatpvf(pTHX_ SV *const sv, const char *const pat, va_list *const args)
     sv_vcatpvfn_flags(sv, pat, strlen(pat), args, NULL, 0, NULL, SV_GMAGIC|SV_SMAGIC);
 }
 
-/*
-=for apidoc sv_catpvf_mg
-
-Like C<sv_catpvf>, but also handles 'set' magic.
-
-=for apidoc sv_catpvf_mg_nocontext
-Like C<L</sv_catpvf_mg>> but does not take a thread context (C<aTHX>) parameter,
-so is used in situations where the caller doesn't already have the thread
-context.
-
-=cut
-*/
-
 void
 Perl_sv_catpvf_mg(pTHX_ SV *const sv, const char *const pat, ...)
 {
@@ -10971,16 +10949,6 @@ Perl_sv_catpvf_mg(pTHX_ SV *const sv, const char *const pat, ...)
     va_end(args);
 }
 
-/*
-=for apidoc sv_vcatpvf_mg
-
-Like C<sv_vcatpvf>, but also handles 'set' magic.
-
-Usually used via its frontend C<sv_catpvf_mg>.
-
-=cut
-*/
-
 void
 Perl_sv_vcatpvf_mg(pTHX_ SV *const sv, const char *const pat, va_list *const args)
 {
@@ -11150,7 +11118,7 @@ S_F0convert(NV nv, char *const endbuf, STRLEN *const len)
     assert(!Perl_isinfnan(nv));
     if (neg)
        nv = -nv;
-    if (nv != 0.0 && nv < UV_MAX) {
+    if (nv != 0.0 && nv < (NV) UV_MAX) {
        char *p = endbuf;
        uv = (UV)nv;
        if (uv != nv) {
@@ -14882,6 +14850,7 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
            ptr = POPPTR(ss,ix);
            TOPPTR(nss,ix) = any_dup(ptr, proto_perl);
            /* FALLTHROUGH */
+       case SAVEt_STRLEN_SMALL:
        case SAVEt_INT_SMALL:
        case SAVEt_I32_SMALL:
        case SAVEt_I16:                         /* I16 reference */
@@ -15438,6 +15407,10 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     /* op_free() hook */
     PL_opfreehook      = proto_perl->Iopfreehook;
 
+#  ifdef PERL_MEM_LOG
+    Zero(PL_mem_log, sizeof(PL_mem_log), char);
+#  endif
+
 #ifdef USE_REENTRANT_API
     /* XXX: things like -Dm will segfault here in perlio, but doing
      *  PERL_SET_CONTEXT(proto_perl);
diff --git a/sv.h b/sv.h
index fc35f34..246f612 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -281,52 +281,50 @@ Returns the value of the object's reference count. Exposed
 to perl code via Internals::SvREFCNT().
 
 =for apidoc SvREFCNT_inc
-Increments the reference count of the given SV, returning the SV.
+=for apidoc_item SvREFCNT_inc_NN
+=for apidoc_item SvREFCNT_inc_void
+=for apidoc_item |void|SvREFCNT_inc_void_NN|SV* sv
+=for apidoc_item |SV*|SvREFCNT_inc_simple|SV* sv
+=for apidoc_item |SV*|SvREFCNT_inc_simple_NN|SV* sv
+=for apidoc_item |void|SvREFCNT_inc_simple_void|SV* sv
+=for apidoc_item |void|SvREFCNT_inc_simple_void_NN|SV* sv
 
-All of the following C<SvREFCNT_inc>* are optimized versions of
-C<SvREFCNT_inc>, and can be replaced with C<SvREFCNT_inc>.
+These all increment the reference count of the given SV.
+The ones without C<void> in their names return the SV.
 
-=for apidoc SvREFCNT_inc_NN
-Same as C<SvREFCNT_inc>, but can only be used if you know C<sv>
-is not C<NULL>.  Since we don't have to check the NULLness, it's faster
-and smaller.
+C<SvREFCNT_inc> is the base operation; the rest are optimizations if various
+input constraints are known to be true; hence, all can be replaced with
+C<SvREFCNT_inc>.
 
-=for apidoc SvREFCNT_inc_void
-Same as C<SvREFCNT_inc>, but can only be used if you don't need the
+C<SvREFCNT_inc_NN> can only be used if you know C<sv> is not C<NULL>.  Since we
+don't have to check the NULLness, it's faster and smaller.
+
+C<SvREFCNT_inc_void> can only be used if you don't need the
 return value.  The macro doesn't need to return a meaningful value.
 
-=for apidoc Am|void|SvREFCNT_inc_void_NN|SV* sv
-Same as C<SvREFCNT_inc>, but can only be used if you don't need the return
-value, and you know that C<sv> is not C<NULL>.  The macro doesn't need
-to return a meaningful value, or check for NULLness, so it's smaller
-and faster.
+C<SvREFCNT_inc_void_NN> can only be used if you both don't need the return
+value, and you know that C<sv> is not C<NULL>.  The macro doesn't need to
+return a meaningful value, or check for NULLness, so it's smaller and faster.
 
-=for apidoc Am|SV*|SvREFCNT_inc_simple|SV* sv
-Same as C<SvREFCNT_inc>, but can only be used with expressions without side
+C<SvREFCNT_inc_simple> can only be used with expressions without side
 effects.  Since we don't have to store a temporary value, it's faster.
 
-=for apidoc Am|SV*|SvREFCNT_inc_simple_NN|SV* sv
-Same as C<SvREFCNT_inc_simple>, but can only be used if you know C<sv>
-is not C<NULL>.  Since we don't have to check the NULLness, it's faster
-and smaller.
+C<SvREFCNT_inc_simple_NN> can only be used with expressions without side
+effects and you know C<sv> is not C<NULL>.  Since we don't have to store a
+temporary value, nor check for NULLness, it's faster and smaller.
 
-=for apidoc Am|void|SvREFCNT_inc_simple_void|SV* sv
-Same as C<SvREFCNT_inc_simple>, but can only be used if you don't need the
-return value.  The macro doesn't need to return a meaningful value.
+C<SvREFCNT_inc_simple_void> can only be used with expressions without side
+effects and you don't need the return value.
 
-=for apidoc Am|void|SvREFCNT_inc_simple_void_NN|SV* sv
-Same as C<SvREFCNT_inc>, but can only be used if you don't need the return
-value, and you know that C<sv> is not C<NULL>.  The macro doesn't need
-to return a meaningful value, or check for NULLness, so it's smaller
-and faster.
+C<SvREFCNT_inc_simple_void_NN> can only be used with expressions without side
+effects, you don't need the return value, and you know C<sv> is not C<NULL>.
 
 =for apidoc SvREFCNT_dec
-Decrements the reference count of the given SV.  C<sv> may be C<NULL>.
+=for apidoc_item SvREFCNT_dec_NN
+
+These decrement the reference count of the given SV.
 
-=for apidoc SvREFCNT_dec_NN
-Same as C<SvREFCNT_dec>, but can only be used if you know C<sv>
-is not C<NULL>.  Since we don't have to check the NULLness, it's faster
-and smaller.
+C<SvREFCNT_dec_NN> may only be used when C<sv> is known to not be C<NULL>.
 
 =for apidoc Am|svtype|SvTYPE|SV* sv
 Returns the type of the SV.  See C<L</svtype>>.
@@ -782,14 +780,26 @@ Returns the raw value in the SV's NV slot, without checks or conversions.
 Only use when you are sure C<SvNOK> is true.  See also C<L</SvNV>>.
 
 =for apidoc Am|char*|SvPVX|SV* sv
-Returns a pointer to the physical string in the SV.  The SV must contain a
-string.  Prior to 5.9.3 it is not safe
-to execute this macro unless the SV's
+=for apidoc_item |char*|SvPVXx|SV* sv
+=for apidoc_item |const char*|SvPVX_const|SV* sv
+=for apidoc_item |char*|SvPVX_mutable|SV* sv
+
+These return a pointer to the physical string in the SV.  The SV must contain a
+string.  Prior to 5.9.3 it is not safe to execute these unless the SV's
 type >= C<SVt_PV>.
 
-This is also used to store the name of an autoloaded subroutine in an XS
+These are also used to store the name of an autoloaded subroutine in an XS
 AUTOLOAD routine.  See L<perlguts/Autoloading with XSUBs>.
 
+C<SvPVXx> is identical to C<SvPVX>.
+
+C<SvPVX_mutable> is merely a synonym for C<SvPVX>, but its name emphasizes that
+the string is modifiable by the caller.
+
+C<SvPVX_const> differs in that the return value has been cast so that the
+compiler will complain if you were to try to modify the contents of the string,
+(unless you cast away const yourself).
+
 =for apidoc Am|STRLEN|SvCUR|SV* sv
 Returns the length of the string which is in the SV.  See C<L</SvLEN>>.
 
@@ -1196,7 +1206,7 @@ object type. Exposed to perl code via Internals::SvREADONLY().
 
 #  define SvMAGIC(sv)  (0 + *(assert_(SvTYPE(sv) >= SVt_PVMG) &((XPVMG*)  SvANY(sv))->xmg_u.xmg_magic))
 #  define SvSTASH(sv)  (0 + *(assert_(SvTYPE(sv) >= SVt_PVMG) &((XPVMG*)  SvANY(sv))->xmg_stash))
-#else
+#else   /* Below is not PERL_DEBUG_COW */
 # ifdef PERL_CORE
 #  define SvLEN(sv) (0 + ((XPV*) SvANY(sv))->xpv_len)
 # else
@@ -1277,7 +1287,7 @@ object type. Exposed to perl code via Internals::SvREADONLY().
            assert(SvTYPE(_svstash) >= SVt_PVMG);                       \
            &(((XPVMG*) MUTABLE_PTR(SvANY(_svstash)))->xmg_stash);      \
          }))
-#  else
+#  else     /* Below is not DEBUGGING or can't use brace groups */
 #    define SvPVX(sv) ((sv)->sv_u.svu_pv)
 #    define SvCUR(sv) ((XPV*) SvANY(sv))->xpv_cur
 #    define SvIVX(sv) ((XPVIV*) SvANY(sv))->xiv_iv
@@ -1532,9 +1542,23 @@ attention to precisely which outputs are influenced by which inputs.
 
 /*
 =for apidoc Am|char*|SvPV_force|SV* sv|STRLEN len
-Like C<SvPV> but will force the SV into containing a string (C<SvPOK>), and
-only a string (C<SvPOK_only>), by hook or by crook.  You need force if you are
-going to update the C<SvPVX> directly.  Processes get magic.
+=for apidoc_item ||SvPV_force_nolen|SV* sv
+=for apidoc_item ||SvPVx_force|SV* sv|STRLEN len
+=for apidoc_item ||SvPV_force_nomg|SV* sv|STRLEN len
+=for apidoc_item ||SvPV_force_nomg_nolen|SV * sv
+=for apidoc_item ||SvPV_force_mutable|SV * sv|STRLEN len
+=for apidoc_item ||SvPV_force_flags|SV * sv|STRLEN len|U32 flags
+=for apidoc_item ||SvPV_force_flags_nolen|SV * sv|U32 flags
+=for apidoc_item ||SvPV_force_flags_mutable|SV * sv|STRLEN len|U32 flags
+=for apidoc_item ||SvPVbyte_force
+=for apidoc_item ||SvPVbytex_force
+=for apidoc_item ||SvPVutf8_force
+=for apidoc_item ||SvPVutf8x_force
+
+These are like C<L</SvPV>> but will force the SV into containing a string
+(C<L</SvPOK>>), and only a string (C<L</SvPOK_only>>), by hook or by crook.
+You need to use one of these C<force> routines if you are going to update the
+C<L</SvPVX>> directly.
 
 Note that coercing an arbitrary scalar into a plain PV will potentially
 strip useful data from it.  For example if the SV was C<SvROK>, then the
@@ -1542,8 +1566,34 @@ referent will have its reference count decremented, and the SV itself may
 be converted to an C<SvPOK> scalar with a string buffer containing a value
 such as C<"ARRAY(0x1234)">.
 
-=for apidoc Am|char*|SvPV_force_nomg|SV* sv|STRLEN len
-Like C<SvPV_force>, but doesn't process get magic.
+The differences between the forms are:
+
+The forms with C<flags> in their names allow you to use the C<flags> parameter
+to specify to perform 'get' magic (by setting the C<SV_GMAGIC> flag) or to skip
+'get' magic (by clearing it).  The other forms do perform 'get' magic, except
+for the ones with C<nomg> in their names, which skip 'get' magic.
+
+The forms with C<nolen> in their names do not return the length of the string.
+They should be used only when it is known that the PV is a C string, terminated by
+a NUL byte, and without intermediate NUL characters; or when you don't care
+about its length.
+
+The forms with C<mutable> in their names are effectively the same as those without,
+but the name emphasizes that the string is modifiable by the caller, which it is
+in all the forms.
+
+C<SvPVutf8_force> is like C<SvPV_force>, but converts C<sv> to UTF-8 first if
+not already UTF-8.
+
+C<SvPVutf8x_force> is like C<SvPVutf8_force>, but guarantees to evaluate C<sv>
+only once; use the more efficient C<SvPVutf8_force> otherwise.
+
+C<SvPVbyte_force> is like C<SvPV_force>, but converts C<sv> to byte
+representation first if currently encoded as UTF-8.  If the SV cannot be
+downgraded from UTF-8, this croaks.
+
+C<SvPVbytex_force> is like C<SvPVbyte_force>, but guarantees to evaluate C<sv>
+only once; use the more efficient C<SvPVbyte_force> otherwise.
 
 =for apidoc Am|char*|SvPV|SV* sv|STRLEN len
 Returns a pointer to the string in the SV, or a stringified form of
@@ -1577,77 +1627,74 @@ Like C<SvPV> but doesn't set a length variable.
 Like C<SvPV_nolen> but doesn't process magic.
 
 =for apidoc Am|IV|SvIV|SV* sv
-Coerces the given SV to IV and returns it.  The returned value in many
-circumstances will get stored in C<sv>'s IV slot, but not in all cases.  (Use
-C<L</sv_setiv>> to make sure it does).
+=for apidoc_item SvIVx
+=for apidoc_item SvIV_nomg
 
-See C<L</SvIVx>> for a version which guarantees to evaluate C<sv> only once.
-
-=for apidoc Am|IV|SvIV_nomg|SV* sv
-Like C<SvIV> but doesn't process magic.
-
-=for apidoc Am|IV|SvIVx|SV* sv
-Coerces the given SV to IV and returns it.  The returned value in many
+These coerce the given SV to IV and return it.  The returned value in many
 circumstances will get stored in C<sv>'s IV slot, but not in all cases.  (Use
 C<L</sv_setiv>> to make sure it does).
 
-This form guarantees to evaluate C<sv> only once.  Only use this if C<sv> is an
-expression with side effects, otherwise use the more efficient C<SvIV>.
-
-=for apidoc Am|NV|SvNV|SV* sv
-Coerces the given SV to NV and returns it.  The returned value in many
-circumstances will get stored in C<sv>'s NV slot, but not in all cases.  (Use
-C<L</sv_setnv>> to make sure it does).
+C<SvIVx> is different from the others in that it is guaranteed to evaluate
+C<sv> exactly once; the others may evaluate it multiple times.  Only use this
+form if C<sv> is an expression with side effects, otherwise use the more
+efficient C<SvIV>.
 
-See C<L</SvNVx>> for a version which guarantees to evaluate C<sv> only once.
+C<SvIV_nomg> is the same as C<SvIV>, but does not perform 'get' magic.
 
-=for apidoc Am|NV|SvNV_nomg|SV* sv
-Like C<SvNV> but doesn't process magic.
+=for apidoc Am|NV|SvNV|SV* sv
+=for apidoc_item SvNVx
+=for apidoc_item SvNV_nomg
 
-=for apidoc Am|NV|SvNVx|SV* sv
-Coerces the given SV to NV and returns it.  The returned value in many
+These coerce the given SV to NV and return it.  The returned value in many
 circumstances will get stored in C<sv>'s NV slot, but not in all cases.  (Use
 C<L</sv_setnv>> to make sure it does).
 
-This form guarantees to evaluate C<sv> only once.  Only use this if C<sv> is an
-expression with side effects, otherwise use the more efficient C<SvNV>.
+C<SvNVx> is different from the others in that it is guaranteed to evaluate
+C<sv> exactly once; the others may evaluate it multiple times.  Only use this
+form if C<sv> is an expression with side effects, otherwise use the more
+efficient C<SvNV>.
+
+C<SvNV_nomg> is the same as C<SvNV>, but does not perform 'get' magic.
 
 =for apidoc Am|UV|SvUV|SV* sv
-Coerces the given SV to UV and returns it.  The returned value in many
+=for apidoc_item SvUVx
+=for apidoc_item SvUV_nomg
+
+These coerce the given SV to UV and return it.  The returned value in many
 circumstances will get stored in C<sv>'s UV slot, but not in all cases.  (Use
 C<L</sv_setuv>> to make sure it does).
 
-See C<L</SvUVx>> for a version which guarantees to evaluate C<sv> only once.
+C<SvUVx> is different from the others in that it is guaranteed to evaluate
+C<sv> exactly once; the others may evaluate it multiple times.  Only use this
+form if C<sv> is an expression with side effects, otherwise use the more
+efficient C<SvUV>.
 
-=for apidoc Am|UV|SvUV_nomg|SV* sv
-Like C<SvUV> but doesn't process magic.
+C<SvUV_nomg> is the same as C<SvUV>, but does not perform 'get' magic.
 
-=for apidoc Am|UV|SvUVx|SV* sv
-Coerces the given SV to UV and returns it.  The returned value in many
-circumstances will get stored in C<sv>'s UV slot, but not in all cases.  (Use
-C<L</sv_setuv>> to make sure it does).
+=for apidoc SvTRUE
+=for apidoc_item SvTRUEx
+=for apidoc_item SvTRUE_nomg
+=for apidoc_item SvTRUE_NN
+=for apidoc_item SvTRUE_nomg_NN
 
-This form guarantees to evaluate C<sv> only once.  Only use this if C<sv> is an
-expression with side effects, otherwise use the more efficient C<SvUV>.
+These return a boolean indicating whether Perl would evaluate the SV as true or
+false.  See C<L</SvOK>> for a defined/undefined test.
 
-=for apidoc Am|bool|SvTRUE|SV* sv
-Returns a boolean indicating whether Perl would evaluate the SV as true or
-false.  See C<L</SvOK>> for a defined/undefined test.  Handles 'get' magic
-unless the scalar is already C<SvPOK>, C<SvIOK> or C<SvNOK> (the public, not the
-private flags).
+As of Perl 5.32, all are guaranteed to evaluate C<sv> only once.  Prior to that
+release, only C<SvTRUEx> guaranteed single evaluation; now C<SvTRUEx> is
+identical to C<SvTRUE>.
 
-As of Perl 5.32, this is guaranteed to evaluate C<sv> only once.  Prior to that
-release, use C<L</SvTRUEx>> for single evaluation.
+C<SvTRUE_nomg> and C<TRUE_nomg_NN> do not perform 'get' magic; the others do
+unless the scalar is already C<SvPOK>, C<SvIOK>, or C<SvNOK> (the public, not
+the private flags).
 
-=for apidoc Am|bool|SvTRUE_nomg|SV* sv
-Returns a boolean indicating whether Perl would evaluate the SV as true or
-false.  See C<L</SvOK>> for a defined/undefined test.  Does not handle 'get' magic.
+C<SvTRUE_NN> is like C<L</SvTRUE>>, but C<sv> is assumed to be
+non-null (NN).  If there is a possibility that it is NULL, use plain
+C<SvTRUE>.
 
-=for apidoc Am|bool|SvTRUEx|SV* sv
-Identical to C<L</SvTRUE>>.  Prior to 5.32, they differed in that only this one
-was guaranteed to evaluate C<sv> only once; in 5.32 they both evaluated it
-once, but C<SvTRUEx> was slightly slower on some platforms; now they are
-identical.
+C<SvTRUE_nomg_NN> is like C<L</SvTRUE_nomg>>, but C<sv> is assumed to be
+non-null (NN).  If there is a possibility that it is NULL, use plain
+C<SvTRUE_nomg>.
 
 =for apidoc Am|char*|SvPVutf8_force|SV* sv|STRLEN len
 Like C<SvPV_force>, but converts C<sv> to UTF-8 first if necessary.
@@ -1688,21 +1735,12 @@ Like C<SvPVbyte_or_null>, but does not process get magic.
 Like C<SvPV_nolen>, but converts C<sv> to byte representation first if
 necessary.  If the SV cannot be downgraded from UTF-8, this croaks.
 
-=for apidoc Am|char*|SvPVutf8x_force|SV* sv|STRLEN len
-Like C<SvPV_force>, but converts C<sv> to UTF-8 first if necessary.
-Guarantees to evaluate C<sv> only once; use the more efficient C<SvPVutf8_force>
-otherwise.
 
 =for apidoc Am|char*|SvPVutf8x|SV* sv|STRLEN len
 Like C<SvPV>, but converts C<sv> to UTF-8 first if necessary.
 Guarantees to evaluate C<sv> only once; use the more efficient C<SvPVutf8>
 otherwise.
 
-=for apidoc Am|char*|SvPVbytex_force|SV* sv|STRLEN len
-Like C<SvPV_force>, but converts C<sv> to byte representation first if necessary.
-Guarantees to evaluate C<sv> only once; use the more efficient C<SvPVbyte_force>
-otherwise.  If the SV cannot be downgraded from UTF-8, this croaks.
-
 =for apidoc Am|char*|SvPVbytex|SV* sv|STRLEN len
 Like C<SvPV>, but converts C<sv> to byte representation first if necessary.
 Guarantees to evaluate C<sv> only once; use the more efficient C<SvPVbyte>
@@ -1717,9 +1755,6 @@ COW).
 Returns a boolean indicating whether the SV is Copy-On-Write shared hash key
 scalar.
 
-=for apidoc Am|void|sv_catpv_nomg|SV* sv|const char* ptr
-Like C<sv_catpv> but doesn't process magic.
-
 =cut
 */
 
@@ -1857,25 +1892,9 @@ Like C<sv_catpv> but doesn't process magic.
 #define SvPVutf8x_force(sv, len) sv_pvutf8n_force(sv, &len)
 #define SvPVbytex_force(sv, len) sv_pvbyten_force(sv, &len)
 
-#define SvTRUE(sv)         Perl_SvTRUE(aTHX_ sv)
 #define SvTRUEx(sv)        SvTRUE(sv)
-#define SvTRUE_nomg(sv)    (LIKELY(sv) && SvTRUE_nomg_NN(sv))
-#define SvTRUE_NN(sv)      (SvGETMAGIC(sv), SvTRUE_nomg_NN(sv))
-#define SvTRUE_nomg_NN(sv) (SvTRUE_common(sv, sv_2bool_nomg(sv)))
-
-#define SvTRUE_common(sv,fallback) (                   \
-      SvIMMORTAL_INTERP(sv)                             \
-        ? SvIMMORTAL_TRUE(sv)                           \
-    : !SvOK(sv)                                                \
-       ? 0                                             \
-    : SvPOK(sv)                                                \
-       ? SvPVXtrue(sv)                                 \
-    : SvIOK(sv)                                                \
-        ? (SvIVX(sv) != 0 /* cast to bool */)           \
-    : (SvROK(sv) && !(   SvOBJECT(SvRV(sv))             \
-                      && HvAMAGIC(SvSTASH(SvRV(sv)))))  \
-        ? TRUE                                          \
-    : (fallback))
+#define SvTRUEx_nomg(sv)   SvTRUE_nomg(sv)
+#define SvTRUE_nomg_NN(sv) SvTRUE_common(sv, TRUE)
 
 #if defined(PERL_USE_GCC_BRACE_GROUPS)
 
@@ -1889,7 +1908,6 @@ Like C<sv_catpv> but doesn't process magic.
 #  define SvPVutf8x(sv, len) ({SV *_sv = (sv); SvPVutf8(_sv, len); })
 #  define SvPVbytex(sv, len) ({SV *_sv = (sv); SvPVbyte(_sv, len); })
 #  define SvPVbytex_nolen(sv) ({SV *_sv = (sv); SvPVbyte_nolen(_sv); })
-#  define SvTRUEx_nomg(sv) ({SV *_sv = (sv); SvTRUE_nomg(_sv); })
 
 #else /* __GNUC__ */
 
@@ -1906,7 +1924,6 @@ Like C<sv_catpv> but doesn't process magic.
 #  define SvPVutf8x(sv, len) ((PL_Sv = (sv)), SvPVutf8(PL_Sv, len))
 #  define SvPVbytex(sv, len) ((PL_Sv = (sv)), SvPVbyte(PL_Sv, len))
 #  define SvPVbytex_nolen(sv) ((PL_Sv = (sv)), SvPVbyte_nolen(PL_Sv))
-#  define SvTRUEx_nomg(sv) ((PL_Sv = (sv)), SvTRUE_nomg(PL_Sv))
 #endif /* __GNU__ */
 
 #define SvPVXtrue(sv)  (                                       \
@@ -1927,6 +1944,12 @@ Like C<sv_catpv> but doesn't process magic.
 
 #define SvSHARED_HEK_FROM_PV(pvx) \
        ((struct hek*)(pvx - STRUCT_OFFSET(struct hek, hek_key)))
+/*
+=for apidoc Am|struct hek*|SvSHARED_HASH|SV * sv
+Returns the hash for C<sv> created by C<L</newSVpvn_share>>.
+
+=cut
+*/
 #define SvSHARED_HASH(sv) (0 + SvSHARED_HEK_FROM_PV(SvPVX_const(sv))->hek_hash)
 
 /* flag values for sv_*_flags functions */
@@ -2099,7 +2122,7 @@ incremented.
 /* the following macros update any magic values this C<sv> is associated with */
 
 /*
-=for apidoc_section $magic
+=for apidoc_section $SV
 
 =for apidoc Am|void|SvGETMAGIC|SV* sv
 Invokes C<L</mg_get>> on an SV if it has 'get' magic.  For example, this
@@ -2113,18 +2136,21 @@ or a tied variable (it calls C<STORE>).  This macro evaluates its
 argument more than once.
 
 =for apidoc Am|void|SvSetSV|SV* dsv|SV* ssv
-Calls C<sv_setsv> if C<dsv> is not the same as C<ssv>.  May evaluate arguments
-more than once.  Does not handle 'set' magic on the destination SV.
+=for apidoc_item SvSetMagicSV
+=for apidoc_item SvSetSV_nosteal
+=for apidoc_item SvSetMagicSV_nosteal
 
-=for apidoc Am|void|SvSetSV_nosteal|SV* dsv|SV* ssv
-Calls a non-destructive version of C<sv_setsv> if C<dsv> is not the same as
-C<ssv>.  May evaluate arguments more than once.
+if C<dsv> is the same as C<ssv>, these do nothing.  Otherwise they all call
+some form of C<L</sv_setsv>>.  They may evaluate their arguments more than
+once.
 
-=for apidoc Am|void|SvSetMagicSV|SV* dsv|SV* ssv
-Like C<SvSetSV>, but does any set magic required afterwards.
+The only differences are:
 
-=for apidoc Am|void|SvSetMagicSV_nosteal|SV* dsv|SV* ssv
-Like C<SvSetSV_nosteal>, but does any set magic required afterwards.
+C<SvSetMagicSV> and C<SvSetMagicSV_nosteal> perform any required 'set' magic
+afterwards on the destination SV; C<SvSetSV> and C<SvSetSV_nosteal> do not.
+
+C<SvSetSV_nosteal> C<SvSetMagicSV_nosteal> call a non-destructive version of
+C<sv_setsv>.
 
 =for apidoc Am|void|SvSHARE|SV* sv
 Arranges for C<sv> to be shared between threads if a suitable module
@@ -2236,6 +2262,13 @@ See also C<L</PL_sv_yes>> and C<L</PL_sv_no>>.
 #define isGV(sv) (SvTYPE(sv) == SVt_PVGV)
 /* If I give every macro argument a different name, then there won't be bugs
    where nested macros get confused. Been there, done that.  */
+/*
+=for apidoc Am|bool|isGV_with_GP|SV * sv
+Returns a boolean as to whether or not C<sv> is a GV with a pointer to a GP
+(glob pointer).
+
+=cut
+*/
 #define isGV_with_GP(pwadak) \
        (((SvFLAGS(pwadak) & (SVp_POK|SVpgv_GP)) == SVpgv_GP)   \
        && (SvTYPE(pwadak) == SVt_PVGV || SvTYPE(pwadak) == SVt_PVLV))
@@ -2368,51 +2401,54 @@ Evaluates C<sv> more than once.  Sets C<len> to 0 if C<SvOOK(sv)> is false.
 
 #define newIO()        MUTABLE_IO(newSV_type(SVt_PVIO))
 
-#define SV_CONST(name) \
+#if defined(PERL_CORE) || defined(PERL_EXT)
+
+#  define SV_CONST(name) \
        PL_sv_consts[SV_CONST_##name] \
                ? PL_sv_consts[SV_CONST_##name] \
                : (PL_sv_consts[SV_CONST_##name] = newSVpv_share(#name, 0))
 
-#define SV_CONST_TIESCALAR 0
-#define SV_CONST_TIEARRAY 1
-#define SV_CONST_TIEHASH 2
-#define SV_CONST_TIEHANDLE 3
-
-#define SV_CONST_FETCH 4
-#define SV_CONST_FETCHSIZE 5
-#define SV_CONST_STORE 6
-#define SV_CONST_STORESIZE 7
-#define SV_CONST_EXISTS 8
-
-#define SV_CONST_PUSH 9
-#define SV_CONST_POP 10
-#define SV_CONST_SHIFT 11
-#define SV_CONST_UNSHIFT 12
-#define SV_CONST_SPLICE 13
-#define SV_CONST_EXTEND 14
-
-#define SV_CONST_FIRSTKEY 15
-#define SV_CONST_NEXTKEY 16
-#define SV_CONST_SCALAR 17
-
-#define SV_CONST_OPEN 18
-#define SV_CONST_WRITE 19
-#define SV_CONST_PRINT 20
-#define SV_CONST_PRINTF 21
-#define SV_CONST_READ 22
-#define SV_CONST_READLINE 23
-#define SV_CONST_GETC 24
-#define SV_CONST_SEEK 25
-#define SV_CONST_TELL 26
-#define SV_CONST_EOF 27
-#define SV_CONST_BINMODE 28
-#define SV_CONST_FILENO 29
-#define SV_CONST_CLOSE 30
-
-#define SV_CONST_DELETE 31
-#define SV_CONST_CLEAR 32
-#define SV_CONST_UNTIE 33
-#define SV_CONST_DESTROY 34
+#  define SV_CONST_TIESCALAR 0
+#  define SV_CONST_TIEARRAY 1
+#  define SV_CONST_TIEHASH 2
+#  define SV_CONST_TIEHANDLE 3
+
+#  define SV_CONST_FETCH 4
+#  define SV_CONST_FETCHSIZE 5
+#  define SV_CONST_STORE 6
+#  define SV_CONST_STORESIZE 7
+#  define SV_CONST_EXISTS 8
+
+#  define SV_CONST_PUSH 9
+#  define SV_CONST_POP 10
+#  define SV_CONST_SHIFT 11
+#  define SV_CONST_UNSHIFT 12
+#  define SV_CONST_SPLICE 13
+#  define SV_CONST_EXTEND 14
+
+#  define SV_CONST_FIRSTKEY 15
+#  define SV_CONST_NEXTKEY 16
+#  define SV_CONST_SCALAR 17
+
+#  define SV_CONST_OPEN 18
+#  define SV_CONST_WRITE 19
+#  define SV_CONST_PRINT 20
+#  define SV_CONST_PRINTF 21
+#  define SV_CONST_READ 22
+#  define SV_CONST_READLINE 23
+#  define SV_CONST_GETC 24
+#  define SV_CONST_SEEK 25
+#  define SV_CONST_TELL 26
+#  define SV_CONST_EOF 27
+#  define SV_CONST_BINMODE 28
+#  define SV_CONST_FILENO 29
+#  define SV_CONST_CLOSE 30
+
+#  define SV_CONST_DELETE 31
+#  define SV_CONST_CLEAR 32
+#  define SV_CONST_UNTIE 33
+#  define SV_CONST_DESTROY 34
+#endif
 
 #define SV_CONSTS_COUNT 35
 
index 6ccc0cf..2e66bc9 100644 (file)
@@ -1,6 +1,6 @@
 #!./perl
 
-print "1..53\n";
+print "1..56\n";
 
 # First test whether the number stringification works okay.
 # (Testing with == would exercise the IV/NV part, not the PV.)
@@ -211,3 +211,14 @@ print $a eq "16702650"     ? "ok 52\n" : "not ok 52 # $a\n";
 
 $a = 0B1101; "$a";
 print $a eq "13"           ? "ok 53\n" : "not ok 53 # $a\n";
+
+# 0odddd octal constants
+
+$a = 0o100; "$a";
+print $a eq "64"       ? "ok 54\n" : "not ok 54 # $a\n";
+
+$a = 0o100; "$a";
+print $a + 1 == 0o101  ? "ok 55\n" : "not ok 55 #" . $a + 1 . "\n";
+
+$a = 0O1703; "$a";
+print $a eq "963"      ? "ok 56\n" : "not ok 56 # $a\n";
index 79b930e..fbfe539 100644 (file)
@@ -8,7 +8,7 @@ BEGIN {
     chdir 't' if -d 't';
 }
 
-print "1..188\n";
+print "1..190\n";
 
 sub failed {
     my ($got, $expected, $name) = @_;
@@ -243,7 +243,7 @@ eval q[
 like($@, qr/Missing right curly/, 'nested sub syntax error' );
 
 eval q[
-    sub { my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$r);
+    sub { my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s);
            sub { my $z
 ];
 like($@, qr/Missing right curly/, 'nested sub syntax error 2' );
@@ -256,7 +256,7 @@ eval q[
 like($@, qr/Can't locate DieDieDie.pm/, 'croak cleanup' );
 
 eval q[
-    sub { my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$r);
+    sub { my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s);
            use DieDieDie;
 ];
 
@@ -265,7 +265,7 @@ like($@, qr/Can't locate DieDieDie.pm/, 'croak cleanup 2' );
 
 eval q[
     my @a;
-    my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$r);
+    my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s);
     @a =~ s/a/b/; # compile-time error
     use DieDieDie;
 ];
@@ -513,16 +513,18 @@ is $@, "Illegal division by zero at maggapom line 2.\n",
 is +(${[{a=>214}]}[0])->{a}, 214, '($array[...])->{...}';
 
 # This used to fail an assertion because of the OPf_SPECIAL flag on an
-# OP_GV that started out as an OP_CONST.  No test output is necessary, as
-# successful parsing is sufficient.
-sub FILE1 () { 1 }
-sub dummy { tell FILE1 }
+# OP_GV that started out as an OP_CONST.
+
+  sub FILE1 () { 1 }
+  sub dummy { tell FILE1 }
 
 # More potential multideref assertion failures
 # OPf_PARENS on OP_RV2SV in subscript
-$x[($_)];
+  $x[($_)];
+  is(1,1, "PASS: Previous line successfully parsed. OPf_PARENS on OP_RV2SV");
 # OPf_SPECIAL on OP_GV in subscript
-$x[FILE1->[0]];
+  $x[FILE1->[0]];
+  is(1,1, "PASS: Previous line successfully parsed. OPf_SPECIAL on OP_GV");
 
 # Used to crash [perl #123542]
 eval 's /${<>{}) //';
@@ -637,10 +639,10 @@ check($this_file, 3, "bare line");
 # line 5
 check($this_file, 5, "bare line with leading space");
 
-#line 7 
+#line 7
 check($this_file, 7, "trailing space still valid");
 
-# line 11 
+# line 11
 check($this_file, 11, "leading and trailing");
 
 #      line 13
@@ -664,7 +666,7 @@ check(qr/^CLINK CLOINK BZZT$/, 31, "filename with spaces in quotes");
 #line 37 "THOOM        THOOM"
 check(qr/^THOOM        THOOM$/, 37, "filename with tabs in quotes");
 
-#line 41 "GLINK PLINK GLUNK DINK" 
+#line 41 "GLINK PLINK GLUNK DINK"
 check(qr/^GLINK PLINK GLUNK DINK$/, 41, "a space after the quotes");
 
 #line 43 "BBFRPRAFPGHPP
index 58a212f..c3cf906 100644 (file)
--- a/t/harness
+++ b/t/harness
@@ -117,11 +117,20 @@ if (@ARGV) {
     unless (@tests) {
        my @seq = <base/*.t>;
 
-       my @next = qw(comp run cmd io re opbasic op uni mro lib porting perf);
-       push @next, 'japh' if $torture;
-       push @next, 'win32' if $^O eq 'MSWin32';
-       push @next, 'benchmark' if $ENV{PERL_BENCHMARK};
-       push @next, 'bigmem' if $ENV{PERL_TEST_MEMORY};
+        my @last;
+       my @next = qw(comp run cmd);
+
+        # The remaining core tests are either intermixed with the non-core for
+        # more parallelism (if PERL_TEST_HARNESS_ASAP is set non-zero) or done
+        # after the above basic sanity tests, before any non-core ones.
+        my $which = $ENV{PERL_TEST_HARNESS_ASAP} ? \@last : \@next;
+
+        push @$which, qw(io re opbasic op uni mro lib porting perf);
+       push @$which, 'japh' if $torture;
+       push @$which, 'win32' if $^O eq 'MSWin32';
+       push @$which, 'benchmark' if $ENV{PERL_BENCHMARK};
+       push @$which, 'bigmem' if $ENV{PERL_TEST_MEMORY};
+
        # Hopefully TAP::Parser::Scheduler will support this syntax soon.
        # my $next = { par => '{' . join (',', @next) . '}/*.t' };
        my $next = { par => [
@@ -129,6 +138,9 @@ if (@ARGV) {
                            ] };
        @tests = _extract_tests ($next);
 
+       my $last = { par => '{' . join (',', @last) . '}/*.t' };
+       @last = _extract_tests ($last);
+
        # This is a bit of a game, because we only want to sort these tests in
        # speed order. base/*.t wants to run first, and ext,lib etc last and in
        # MANIFEST order
@@ -147,7 +159,6 @@ if (@ARGV) {
        @tests = (@seq, @tests);
        push @seq, $next;
 
-       my @last;
        push @last,
            _tests_from_manifest($Config{extensions}, $Config{known_extensions});
        my %times;
@@ -171,7 +182,7 @@ if (@ARGV) {
 
             # Keep a list of the distinct directory names, and another list of
             # those which contain a file whose name begins with a 0
-            if ( m! \A \.\. /
+            if ( m! \A (?: \.\. / )?
                                 ( .*? )         # $1 is the directory path name
                             /
                                 ( [^/]* \.t )   # $2 is the .t name
@@ -210,7 +221,7 @@ if (@ARGV) {
        for (@last) {
             # Treat every file in each non-serial directory as its own
             # "directory", so that it can be executed in parallel
-            m! \A ( \.\. / (?: $non_serials )
+            m! \A ( (?: \.\. / )? (?: $non_serials )
                          / [^/]+ \.t \z | .* [/] ) !x
                 or die "'$_'";
            push @{$dir{$1}}, $_;
diff --git a/t/io/msg.t b/t/io/msg.t
new file mode 100644 (file)
index 0000000..2c3f75b
--- /dev/null
@@ -0,0 +1,76 @@
+#!perl
+
+BEGIN {
+  chdir 't' if -d 't';
+
+  require "./test.pl";
+  set_up_inc( '../lib' ) if -d '../lib' && -d '../ext';
+  require Config; import Config;
+
+  if ($ENV{'PERL_CORE'} && $Config{'extensions'} !~ m[\bIPC/SysV\b]) {
+    skip_all('-- IPC::SysV was not built');
+  }
+  skip_all_if_miniperl();
+  if ($Config{'d_msg'} ne 'define') {
+    skip_all('-- $Config{d_msg} undefined');
+  }
+}
+
+use strict;
+use warnings;
+our $TODO;
+
+use sigtrap qw/die normal-signals error-signals/;
+use IPC::SysV qw/ IPC_PRIVATE S_IRUSR S_IWUSR IPC_RMID IPC_CREAT IPC_STAT IPC_CREAT IPC_NOWAIT/;
+
+my $id;
+END { msgctl $id, IPC_RMID, 0 if defined $id }
+
+{
+    local $SIG{SYS} = sub { skip_all("SIGSYS caught") } if exists $SIG{SYS};
+    $id = msgget IPC_PRIVATE, S_IRUSR | S_IWUSR | IPC_CREAT;
+}
+
+if (not defined $id) {
+    my $info = "msgget failed: $!";
+    if ($! == &IPC::SysV::ENOSPC || $! == &IPC::SysV::ENOSYS ||
+       $! == &IPC::SysV::ENOMEM || $! == &IPC::SysV::EACCES) {
+        skip_all($info);
+    }
+    else {
+        die $info;
+    }
+}
+else {
+    pass('acquired msg queue');
+}
+
+{
+    # basic send/receive
+    my $type = 0x1F0;
+    my $content = "AB\xFF\xC0";
+
+    my $msg = pack("l! a*", $type, $content);
+    if (ok(msgsnd($id, $msg, IPC_NOWAIT), "send a message")) {
+        my $rcvbuf;
+        ok(msgrcv($id, $rcvbuf, 1024, 0, IPC_NOWAIT), "receive it");
+        is($rcvbuf, $msg, "received should match sent");
+    }
+
+    # try upgraded send
+    utf8::upgrade(my $umsg = $msg);
+    if (ok(msgsnd($id, $umsg, IPC_NOWAIT), "send a message (upgraded)")) {
+        my $rcvbuf;
+        ok(msgrcv($id, $rcvbuf, 1024, 0, IPC_NOWAIT), "receive it");
+        is($rcvbuf, $msg, "received should match sent");
+    }
+
+    # try a receive buffer that starts upgraded
+    if (ok(msgsnd($id, $msg, IPC_NOWAIT), "send a message (upgraded receiver)")) {
+        my $rcvbuf = "\x{101}";
+        ok(msgrcv($id, $rcvbuf, 1024, 0, IPC_NOWAIT), "receive it (upgraded receiver)");
+        is($rcvbuf, $msg, "received should match sent (upgraded receiver)");
+    }
+}
+
+done_testing();
index 7a911fc..bfac1c8 100644 (file)
@@ -17,13 +17,15 @@ BEGIN {
 }
 
 use strict;
+use warnings;
 our $TODO;
 
 use sigtrap qw/die normal-signals error-signals/;
-use IPC::SysV qw/ IPC_PRIVATE S_IRUSR S_IWUSR IPC_RMID SETVAL GETVAL SETALL GETALL IPC_CREAT /;
+use IPC::SysV qw/ IPC_PRIVATE S_IRUSR S_IWUSR IPC_RMID SETVAL GETVAL SETALL GETALL IPC_CREAT IPC_STAT /;
 
 my $id;
 my $nsem = 10;
+my $ignored = 0;
 END { semctl $id, 0, IPC_RMID, 0 if defined $id }
 
 {
@@ -42,21 +44,23 @@ if (not defined $id) {
     }
 }
 else {
-    plan(tests => 7);
+    plan(tests => 22);
     pass('acquired semaphore');
 }
 
+my @warnings;
+$SIG{__WARN__} = sub { push @warnings, "@_"; print STDERR @_; };
 { # [perl #120635] 64 bit big-endian semctl SETVAL bug
-    ok(semctl($id, "ignore", SETALL, pack("s!*",(0)x$nsem)),
+    ok(semctl($id, $ignored, SETALL, pack("s!*",(0)x$nsem)),
        "Initialize all $nsem semaphores to zero");
 
     my $sem2set = 3;
-    my $semval = 17;
+    my $semval = 192;
     ok(semctl($id, $sem2set, SETVAL, $semval),
        "Set semaphore $sem2set to $semval");
 
     my $semvals;
-    ok(semctl($id, "ignore", GETALL, $semvals),
+    ok(semctl($id, $ignored, GETALL, $semvals),
        'Get current semaphore values');
 
     my @semvals = unpack("s!*", $semvals);
@@ -66,7 +70,64 @@ else {
     is($semvals[$sem2set], $semval, 
        "Checking value of semaphore $sem2set");
 
-    is(semctl($id, $sem2set, GETVAL, "ignored"), $semval,
+    is(semctl($id, $sem2set, GETVAL, $ignored), $semval,
        "Check value via GETVAL");
+
+    # check utf-8 flag handling
+    # first that we reset it on a fetch
+    utf8::upgrade($semvals);
+    ok(semctl($id, $ignored, GETALL, $semvals),
+       "fetch into an already UTF-8 buffer");
+    @semvals = unpack("s!*", $semvals);
+    is($semvals[$sem2set], $semval,
+       "Checking value of semaphore $sem2set after fetch into originally UTF-8 buffer");
+
+    # second that we treat it as bytes on input
+    @semvals = ( 0 ) x $nsem;
+    $semvals[$sem2set] = $semval + 1;
+    $semvals = pack "s!*", @semvals;
+    utf8::upgrade($semvals);
+    # eval{} since it would crash due to the UTF-8 form being longer
+    ok(eval { semctl($id, $ignored, SETALL, $semvals) },
+       "set all semaphores from an upgraded string");
+    # undef here to test it doesn't warn
+    is(semctl($id, $sem2set, GETVAL, undef), $semval+1,
+       "test value set from UTF-8");
+
+    # third, that we throw on a code point above 0xFF
+    substr($semvals, 0, 1) = chr(0x101);
+    ok(!eval { semctl($id, $ignored, SETALL, $semvals); 1 },
+       "throws on code points above 0xff");
+    like($@, qr/Wide character/, "with the expected error");
+
+    {
+        # semop tests
+        ok(semctl($id, $sem2set, SETVAL, 0),
+           "reset our working entry");
+        # sanity check without UTF-8
+        my $op = pack "s!*", $sem2set, $semval, 0;
+        ok(semop($id, $op), "add to entry $sem2set");
+        is(semctl($id, $sem2set, GETVAL, 0), $semval,
+           "check it added to the entry");
+        utf8::upgrade($op);
+        # unlike semctl this doesn't throw on a bad size, so we don't need an
+        # eval with the buggy code
+        ok(semop($id, $op), "add more to entry $sem2set (UTF-8)");
+        is(semctl($id, $sem2set, GETVAL, 0), $semval*2,
+           "check it added to the entry");
+
+        substr($op, 0, 1) = chr(0x101);
+        ok(!eval { semop($id, $op); 1 },
+           "test semop throws if the op string isn't 'bytes'");
+        like($@, qr/Wide character/, "with the expected error");
+    }
+}
+
+{
+    my $stat;
+    # shouldn't warn
+    semctl($id, $ignored, IPC_STAT, $stat);
+    ok(defined $stat, "it statted");
 }
 
+is(scalar @warnings, 0, "no warnings");
index 3feb303..8ff1b33 100644 (file)
@@ -1,3 +1,4 @@
+#!perl
 ################################################################################
 #
 #  $Revision: 6 $
@@ -15,9 +16,9 @@
 ################################################################################
 
 BEGIN {
-  chdir 't' if -d 't' && $ENV{'PERL_CORE'};
+  chdir 't' if -d 't';
   require "./test.pl";
-  set_up_inc('../lib') if $ENV{'PERL_CORE'} && -d '../lib' && -d '../ext';
+  set_up_inc('../lib') if -d '../lib' && -d '../ext';
 
   require Config; import Config;
 
@@ -53,7 +54,7 @@ if (not defined $key) {
   }
 }
 else {
-       plan(tests => 15);
+       plan(tests => 21);
        pass('acquired shared mem');
 }
 
@@ -88,3 +89,19 @@ tie $ct, 'Counted';
 shmread $key, $ct, 0, 1;
 is($fetch, 1, "shmread FETCH once");
 is($store, 1, "shmread STORE once");
+
+{
+    # check reading into an upgraded buffer is sane
+    my $text = "\xC0\F0AB";
+    ok(shmwrite($key, $text, 0, 4), "setup text");
+    my $rdbuf = "\x{101}";
+    ok(shmread($key, $rdbuf, 0, 4), "read it back");
+    is($rdbuf, $text, "check we got back the expected");
+
+    # check writing from an upgraded buffer
+    utf8::upgrade(my $utext = $text);
+    ok(shmwrite($key, $utext, 0, 4), "setup text (upgraded source)");
+    $rdbuf = "";
+    ok(shmread($key, $rdbuf, 0, 4), "read it back (upgraded source)");
+    is($rdbuf, $text, "check we got back the expected (upgraded source)");
+}
index 0d20acb..2a660b6 100644 (file)
@@ -503,7 +503,7 @@ EXPECT
 syntax error at - line 4, next token ???
 Execution of - aborted due to compilation errors.
 ########
-# NAME [perl #134045] incomplete hex number
+# NAME [perl #134125] [gh #17010] incomplete hex number
 0x x 2;
 0xx 2;
 0x_;
index 4df98e2..f66b758 100644 (file)
@@ -79,6 +79,57 @@ EXPECT
 Useless use of a constant ("foobar") in void context at - line 3.
 ########
 
+# Check -negative import with no other args
+use warnings qw(-syntax);
+sub foo { 'foo' }
+my $a =+ 1 ;          # syntax:        shouldn't warn, it was never turned on
+*foo = sub { 'bar' }; # redefine:      shouldn't warn, it was never turned on
+$a = 'foo' . undef;   # uninitialized: shouldn't warn, it was never turned on
+EXPECT
+########
+
+# Check -negative import after turning all warnings on
+use warnings qw(all -syntax);
+sub foo { 'foo' }
+my $a =+ 1 ;          # syntax:        shouldn't warn, we've turned that off
+*foo = sub { 'bar' }; # redefine:      should warn, as there was an explicit 'all'
+$a = 'foo' . undef;   # uninitialized: should warn, as there was an explicit 'all'
+EXPECT
+Subroutine main::foo redefined at - line 6.
+Use of uninitialized value in concatenation (.) or string at - line 7.
+########
+
+# Check -negative import with an explicit import
+use warnings qw(redefine -syntax);
+sub foo { 'foo' }
+my $a =+ 1 ;          # syntax:        shouldn't warn, it was never turned on
+*foo = sub { 'bar' }; # redefine:      should warn, as there was an explicit 'redefine'
+$a = 'foo' . undef;   # uninitialized: shouldn't warn, as explicit 'redefine' means no implicit 'all'
+EXPECT
+Subroutine main::foo redefined at - line 6.
+########
+
+# Check multiple -negative imports
+use warnings qw(all -syntax -uninitialized);
+sub foo { 'foo' }
+my $a =+ 1 ;          # syntax:        shouldn't warn, we've turned that off
+*foo = sub { 'bar' }; # redefine:      should warn, as there was an explicit 'all'
+$a = 'foo' . undef;   # uninitialized: shouldn't warn, we've turned it off
+EXPECT
+Subroutine main::foo redefined at - line 6.
+########
+
+# Check mixed list of +ve and -ve imports
+use warnings qw(all -once -syntax parenthesis);
+sub foo { 'foo' }
+*foo = sub { 'bar' };  # redefined:   should warn, as it was turned on by 'all'
+my $a =+ 1 ;           # syntax:      shouldn't warn, we've turned that off
+my $foo, $bar = @_;    # parenthesis: should warn, as we turned that back on after disabling 'syntax'
+EXPECT
+Parentheses missing around "my" list at - line 7.
+Subroutine main::foo redefined at - line 5.
+########
+
 --FILE-- abc
 my $a =+ 1 ;
 1;
index 6283df5..29db4c1 100644 (file)
@@ -797,15 +797,19 @@ SKIP: {
        env_is(__NoNeLoCaL => '');
 
     SKIP: {
-           skip("\$0 check only on Linux and FreeBSD", 2)
-               unless $^O =~ /^(linux|android|freebsd)$/
-                   && open CMDLINE, "/proc/$$/cmdline";
-
-           chomp(my $line = scalar <CMDLINE>);
-           my $me = (split /\0/, $line)[0];
-           is $me, $0, 'altering $0 is effective (testing with /proc/)';
-           close CMDLINE;
-            skip("\$0 check with 'ps' only on Linux (but not Android) and FreeBSD", 1) if $^O eq 'android';
+           skip("\$0 check only on Linux, Dragonfly BSD and FreeBSD", 2)
+               unless $^O =~ /^(linux|android|dragonfly|freebsd)$/;
+
+            SKIP: {
+                skip("No procfs cmdline support", 1)
+                    unless open CMDLINE, "/proc/$$/cmdline";
+
+                chomp(my $line = scalar <CMDLINE>);
+                my $me = (split /\0/, $line)[0];
+                is $me, $0, 'altering $0 is effective (testing with /proc/)';
+                close CMDLINE;
+            }
+            skip("No \$0 check with 'ps' on Android", 1) if $^O eq 'android';
             # perlbug #22811
             my $mydollarzero = sub {
               my($arg) = shift;
@@ -815,23 +819,25 @@ SKIP: {
               my $ps = (`ps -o command= -p $$`)[-1];
               return if $?;
               chomp $ps;
-              printf "# 0[%s]ps[%s]\n", $0, $ps;
               $ps;
             };
             my $ps = $mydollarzero->("x");
-            ok(!$ps  # we allow that something goes wrong with the ps command
-              # In Linux 2.4 we would get an exact match ($ps eq 'x') but
-              # in Linux 2.2 there seems to be something funny going on:
-              # it seems as if the original length of the argv[] would
-              # be stored in the proc struct and then used by ps(1),
-              # no matter what characters we use to pad the argv[].
-              # (And if we use \0:s, they are shown as spaces.)  Sigh.
-               || $ps =~ /^x\s*$/
-              # FreeBSD cannot get rid of both the leading "perl :"
-              # and the trailing " (perl)": some FreeBSD versions
-              # can get rid of the first one.
-              || ($^O eq 'freebsd' && $ps =~ m/^(?:perl: )?x(?: \(perl\))?$/),
-                      'altering $0 is effective (testing with `ps`)');
+            # we allow that something goes wrong with the ps command
+            !$ps && skip("The ps command failed", 1);
+            my $ps_re = ( $^O =~ /^(dragonfly|freebsd)$/ )
+                # FreeBSD cannot get rid of both the leading "perl :"
+                # and the trailing " (perl)": some FreeBSD versions
+                # can get rid of the first one.
+                ? qr/^(?:perl: )?x(?: \(perl\))?$/
+                # In Linux 2.4 we would get an exact match ($ps eq 'x') but
+                # in Linux 2.2 there seems to be something funny going on:
+                # it seems as if the original length of the argv[] would
+                # be stored in the proc struct and then used by ps(1),
+                # no matter what characters we use to pad the argv[].
+                # (And if we use \0:s, they are shown as spaces.)  Sigh.
+               : qr/^x\s*$/
+            ;
+            like($ps, $ps_re, 'altering $0 is effective (testing with `ps`)');
        }
 }
 
index 84814b1..6d16ed0 100644 (file)
@@ -1,12 +1,12 @@
 #!./perl
 
-# Tests 51 onwards are intentionally not all-warnings-clean
+# Tests 53 onwards are intentionally not all-warnings-clean
 
 chdir 't' if -d 't';
 require './test.pl';
 use strict;
 
-plan(tests => 77);
+plan(tests => 79);
 
 foreach(['0b1_0101', 0b101_01],
        ['0b10_101', 0_2_5],
@@ -55,6 +55,9 @@ foreach(['0b1_0101', 0b101_01],
        ["XCAFE", 0xCAFE],
        ["0B101001", 0b101001],
        ["B101001", 0b101001],
+        # Additional syntax for octals
+        ["0o7_654_321", 2054353],
+        ["O4567", 0o4_567],
        ) {
     my ($string, $value) = @$_;
     my $result = oct $string;
index 663ad9d..099a3f1 100644 (file)
@@ -27,6 +27,8 @@ if ($^O eq 'MSWin32') {
     ${^WIN32_SLOPPY_STAT} = 0;
 }
 
+my $Errno_loaded = eval { require Errno };
+
 plan tests => 110;
 
 my $Perl = which_perl();
@@ -241,7 +243,10 @@ ok(! -f '.',          '!-f cwd' );
 SKIP: {
     unlink($tmpfile_link);
     my $symlink_rslt = eval { symlink $tmpfile, $tmpfile_link };
+    my $error = 0 + $!;
     skip "symlink not implemented", 3 if $@ =~ /unimplemented/;
+    skip "symlink not available or we can't check", 3
+        if $^O eq "MSWin32" && (!$Errno_loaded || $error == &Errno::ENOSYS || $error == &Errno::EPERM);
 
     is( $@, '',     'symlink() implemented' );
     ok( $symlink_rslt,      'symlink() ok' );
@@ -502,14 +507,19 @@ like $@, qr/^The stat preceding lstat\(\) wasn't an lstat at /,
 }
   
 SKIP: {
-    skip "No lstat", 2 unless $Config{d_lstat};
+    skip "No lstat", 2 unless $Config{d_lstat} && $Config{d_symlink};
 
     # bug id 20020124.004 (#8334)
-    # If we have d_lstat, we should have symlink()
     my $linkname = 'stat-' . rand =~ y/.//dr;
     my $target = $Perl;
     $target =~ s/;\d+\z// if $Is_VMS; # symlinks don't like version numbers
-    symlink $target, $linkname or die "# Can't symlink $0: $!";
+    unless (symlink $target, $linkname) {
+        if ($^O eq "MSWin32") {
+            # likely we don't have permission
+            skip "symlink failed: $!", 2;
+        }
+        die "# Can't symlink $0: $!";
+    }
     lstat $linkname;
     -T _;
     eval { lstat _ };
@@ -629,7 +639,6 @@ SKIP:
 {
     skip "There is a file named '2', which invalidates this test", 2 if -e '2';
 
-    my $Errno_loaded = eval { require Errno };
     my @statarg = ($statfile, $statfile);
     no warnings 'syntax';
     ok !stat(@statarg),
index 73246a0..607a305 100644 (file)
@@ -1498,7 +1498,11 @@ violates_taint(sub { link $TAINT, '' }, 'link');
        unlink($symlink);
        my $sl = "/something/naughty";
        # it has to be a real path on Mac OS
-       symlink($sl, $symlink) or die "symlink: $!\n";
+       unless (symlink($sl, $symlink)) {
+            skip "symlink not available or no priviliges", 1,
+                if $^O eq "MSWin32";
+            die "symlink: $!\n";
+        }
        my $readlink = readlink($symlink);
        is_tainted($readlink);
        unlink($symlink);
index 08acf8a..bf97579 100644 (file)
@@ -1,7 +1,6 @@
 # Regenerate this file using:
 #     cd t
 #     ./perl -I../lib porting/customized.t --regen
-Config::Perl::V cpan/Config-Perl-V/V.pm 0a0f7207e6505b78ee345a933acb0246a13579f5
 ExtUtils::Constant cpan/ExtUtils-Constant/t/Constant.t d5c75c41d6736a0c5897130f534af0896a7d6f4d
 ExtUtils::PL2Bat cpan/ExtUtils-PL2Bat/t/make_executable.t 2f58339b567d943712488812f06d99f907af46ab
 Filter::Util::Call pod/perlfilter.pod 2d98239c4f4a930ad165444c3879629bb91f4cef
@@ -22,6 +21,7 @@ Net::Ping dist/Net-Ping/t/450_service.t f6578680f2872d7fc9f24dd75388d55654761875
 Net::Ping dist/Net-Ping/t/500_ping_icmp.t 3eeb60181c01b85f876bd6658644548fdf2e24d4
 Net::Ping dist/Net-Ping/t/501_ping_icmpv6.t 54373de5858f8fb7e078e4998a4b3b8dbca91783
 Pod::Perldoc cpan/Pod-Perldoc/lib/Pod/Perldoc.pm 582be34c077c9ff44d99914724a0cc2140bcd48c
+Test::Harness cpan/Test-Harness/t/source.t aaa3939591114c0c52ecd44159218336d1f762b9
 Win32API::File cpan/Win32API-File/File.pm 8fd212857f821cb26648878b96e57f13bf21b99e
 Win32API::File cpan/Win32API-File/File.xs beb870fed4490d2faa547b4a8576b8d64d1d27c5
 experimental cpan/experimental/t/basic.t cb9da8dd05b854375809872a05dd32637508d5da
index 8eb9fc5..5783359 100644 (file)
@@ -369,52 +369,50 @@ XML::LibXML
 YAML
 YAML::Syck
 YAML::Tiny
-dist/data-dumper/changes       Verbatim line length including indents exceeds 79 by    1
+dist/data-dumper/changes       Verbatim line length including indents exceeds 78 by    1
 dist/data-dumper/dumper.pm     ? Should you be using L<...> instead of 1
 dist/devel-ppport/parts/inc/ppphdoc    Unknown directive: =dontwarn    1
 dist/devel-ppport/parts/inc/ppphdoc    Unknown directive: =implementation      1
 dist/devel-ppport/parts/inc/ppphdoc    Unknown directive: =provides    1
 dist/env/lib/env.pm    ? Should you be using F<...> or maybe L<...> instead of 1
-dist/exporter/lib/exporter.pm  Verbatim line length including indents exceeds 79 by    2
+dist/exporter/lib/exporter.pm  Verbatim line length including indents exceeds 78 by    1
 dist/net-ping/lib/net/ping.pm  Apparent broken link    2
-ext/amiga-exec/exec.pm Verbatim line length including indents exceeds 79 by    1
-ext/dynaloader/dynaloader.pm   Verbatim line length including indents exceeds 79 by    1
-ext/hash-util/lib/hash/util.pm Verbatim line length including indents exceeds 79 by    2
-ext/pod-html/testdir/perlpodspec-copy.pod      Verbatim line length including indents exceeds 79 by    2
+ext/amiga-exec/exec.pm Verbatim line length including indents exceeds 78 by    1
+ext/dynaloader/dynaloader.pm   Verbatim line length including indents exceeds 78 by    1
+ext/hash-util/lib/hash/util.pm Verbatim line length including indents exceeds 78 by    2
 ext/pod-html/testdir/perlvar-copy.pod  ? Should you be using L<...> instead of 3
-ext/pod-html/testdir/perlvar-copy.pod  Verbatim line length including indents exceeds 79 by    6
-ext/vms-filespec/lib/vms/filespec.pm   Verbatim line length including indents exceeds 79 by    1
+ext/pod-html/testdir/perlvar-copy.pod  Verbatim line length including indents exceeds 78 by    5
+ext/vms-filespec/lib/vms/filespec.pm   Verbatim line length including indents exceeds 78 by    1
 install        ? Should you be using F<...> or maybe L<...> instead of 1
-pod/perl.pod   Verbatim line length including indents exceeds 79 by    8
-pod/perlandroid.pod    Verbatim line length including indents exceeds 79 by    3
-pod/perlbook.pod       Verbatim line length including indents exceeds 79 by    1
-pod/perldebguts.pod    Verbatim line length including indents exceeds 79 by    -1
-pod/perldebtut.pod     Verbatim line length including indents exceeds 79 by    3
-pod/perldtrace.pod     Verbatim line length including indents exceeds 79 by    7
+pod/perl.pod   Verbatim line length including indents exceeds 78 by    5
+pod/perlandroid.pod    Verbatim line length including indents exceeds 78 by    3
+pod/perlbook.pod       Verbatim line length including indents exceeds 78 by    1
+pod/perldebguts.pod    Verbatim line length including indents exceeds 78 by    24
+pod/perldebtut.pod     Verbatim line length including indents exceeds 78 by    2
+pod/perldtrace.pod     Verbatim line length including indents exceeds 78 by    7
 pod/perlgit.pod        ? Should you be using F<...> or maybe L<...> instead of 1
-pod/perlgit.pod        Verbatim line length including indents exceeds 79 by    1
+pod/perlgit.pod        Verbatim line length including indents exceeds 78 by    1
 pod/perlguts.pod       ? Should you be using L<...> instead of 1
 pod/perlhack.pod       ? Should you be using L<...> instead of 1
-pod/perlhack.pod       Verbatim line length including indents exceeds 79 by    2
-pod/perlhist.pod       Verbatim line length including indents exceeds 79 by    1
-pod/perlhpux.pod       Verbatim line length including indents exceeds 79 by    1
+pod/perlhack.pod       Verbatim line length including indents exceeds 78 by    1
+pod/perlhist.pod       Verbatim line length including indents exceeds 78 by    1
 pod/perlinterp.pod     ? Should you be using L<...> instead of 1
-pod/perlirix.pod       Verbatim line length including indents exceeds 79 by    1
-pod/perlmacosx.pod     Verbatim line length including indents exceeds 79 by    3
+pod/perlirix.pod       Verbatim line length including indents exceeds 78 by    1
+pod/perlmacosx.pod     Verbatim line length including indents exceeds 78 by    3
 pod/perlmroapi.pod     ? Should you be using L<...> instead of 1
 pod/perlos2.pod        ? Should you be using L<...> instead of 2
-pod/perlos2.pod        Verbatim line length including indents exceeds 79 by    5
-pod/perlos390.pod      Verbatim line length including indents exceeds 79 by    3
-pod/perlperf.pod       Verbatim line length including indents exceeds 79 by    114
+pod/perlos2.pod        Verbatim line length including indents exceeds 78 by    5
+pod/perlos390.pod      Verbatim line length including indents exceeds 78 by    2
+pod/perlperf.pod       Verbatim line length including indents exceeds 78 by    113
 pod/perlport.pod       ? Should you be using L<...> instead of 1
-pod/perlrun.pod        Verbatim line length including indents exceeds 79 by    3
-pod/perlsolaris.pod    Verbatim line length including indents exceeds 79 by    13
-pod/perltie.pod        Verbatim line length including indents exceeds 79 by    3
-pod/perltru64.pod      Verbatim line length including indents exceeds 79 by    1
-pod/perlwin32.pod      Verbatim line length including indents exceeds 79 by    7
-porting/epigraphs.pod  Verbatim line length including indents exceeds 79 by    -1
-porting/release_managers_guide.pod     Verbatim line length including indents exceeds 79 by    2
+pod/perlrun.pod        Verbatim line length including indents exceeds 78 by    3
+pod/perlsolaris.pod    Verbatim line length including indents exceeds 78 by    13
+pod/perltie.pod        Verbatim line length including indents exceeds 78 by    3
+pod/perltru64.pod      Verbatim line length including indents exceeds 78 by    1
+pod/perlwin32.pod      Verbatim line length including indents exceeds 78 by    7
+porting/epigraphs.pod  Verbatim line length including indents exceeds 78 by    28
+porting/release_managers_guide.pod     Verbatim line length including indents exceeds 78 by    2
 porting/todo.pod       ? Should you be using F<...> or maybe L<...> instead of 1
-lib/benchmark.pm       Verbatim line length including indents exceeds 79 by    2
+lib/benchmark.pm       Verbatim line length including indents exceeds 78 by    2
 lib/config.pod ? Should you be using L<...> instead of -1
 lib/perl5db.pl ? Should you be using L<...> instead of 1
index 0797d57..ca19def 100644 (file)
@@ -114,8 +114,8 @@ The pedantic checks are:
 
 It's annoying to have lines wrap when displaying pod documentation in a
 terminal window.  This checks that all verbatim lines fit in a standard 80
-column window, even when using a pager that reserves a column for its own use.
-(Thus the check is for a net of 79 columns.)
+column window, even when using a pager that reserves 2 columns for its own
+use.  (Thus the check is for a net of 78 columns.)
 For those lines that don't fit, it tells you how much needs to be cut in
 order to fit.
 
@@ -359,8 +359,9 @@ my $known_issues = File::Spec->catfile($data_dir, 'known_pod_issues.dat');
 my $MANIFEST = File::Spec->catfile(File::Spec->updir($original_dir), 'MANIFEST');
 my $copy_fh;
 
-my $MAX_LINE_LENGTH = 79;   # 79 columns
-my $INDENT = 7;             # default nroff indent
+my $MAX_LINE_LENGTH = 78;   # 78 columns
+my $INDENT = 4;             # Things besides =head lines are indented at this
+                            #least much
 
 # Our warning messages.  Better not have [('"] in them, as those are used as
 # delimiters for variable parts of the messages by poderror.
@@ -895,7 +896,7 @@ package My::Pod::Checker {      # Extend Pod::Checker
         return $self->SUPER::start_Para(@_);
     }
 
-    sub start_item_text {
+    sub start_item {
         my $self = shift;
         check_see_but_not_link($self);
 
@@ -904,6 +905,13 @@ package My::Pod::Checker {      # Extend Pod::Checker
         $running_CFL_text{$addr} = "";
         $running_simple_text{$addr} = "";
 
+    }
+
+    sub start_item_text {
+        my $self = shift;
+        start_item($self);
+        my $addr = Scalar::Util::refaddr $self;
+
         # This is the only =item that is linkable
         $linkable_item{$addr} = 1;
 
@@ -912,24 +920,14 @@ package My::Pod::Checker {      # Extend Pod::Checker
 
     sub start_item_number {
         my $self = shift;
-        check_see_but_not_link($self);
-
-        my $addr = Scalar::Util::refaddr $self;
-        $start_line{$addr} = $_[0]->{start_line};
-        $running_CFL_text{$addr} = "";
-        $running_simple_text{$addr} = "";
+        start_item($self);
 
         return $self->SUPER::start_item_number(@_);
     }
 
     sub start_item_bullet {
         my $self = shift;
-        check_see_but_not_link($self);
-
-        my $addr = Scalar::Util::refaddr $self;
-        $start_line{$addr} = $_[0]->{start_line};
-        $running_CFL_text{$addr} = "";
-        $running_simple_text{$addr} = "";
+        start_item($self);
 
         return $self->SUPER::start_item_bullet(@_);
     }
diff --git a/t/win32/stat.t b/t/win32/stat.t
new file mode 100644 (file)
index 0000000..3ce66ed
--- /dev/null
@@ -0,0 +1,238 @@
+#!./perl
+
+BEGIN {
+    chdir 't' if -d 't';
+    @INC = '../lib';
+    require "./test.pl";
+}
+
+use strict;
+use Fcntl ":seek";
+
+Win32::FsType() eq 'NTFS'
+    or skip_all("need NTFS");
+
+my (undef, $maj, $min) = Win32::GetOSVersion();
+
+my $vista_or_later = $maj >= 6;
+
+my $tmpfile1 = tempfile();
+
+# test some of the win32 specific stat code, since we
+# don't depend on the CRT for some of it
+
+ok(link($0, $tmpfile1), "make a link to test nlink");
+
+my @st = stat $0;
+open my $fh, "<", $0 or die;
+my @fst = stat $fh;
+
+ok(seek($fh, 0, SEEK_END), "seek to end");
+my $size = tell($fh);
+close $fh;
+
+# the ucrt stat() is inconsistent here, using an A=0 drive letter for stat()
+# and the fd for fstat(), I assume that's something backward compatible.
+#
+# I don't see anything we could reasonable populate it with either.
+$st[6] = $fst[6] = 0;
+
+is("@st", "@fst", "check named stat vs handle stat");
+
+ok($st[0], "we set dev by default now");
+ok($st[1], "and ino");
+
+# unlikely, but someone else might have linked to win32/stat.t
+cmp_ok($st[3], '>', 1, "should be more than one link");
+
+# we now populate all stat fields ourselves, so check what we can
+is($st[7], $size, "we fetch size correctly");
+
+cmp_ok($st[9], '<=', time(), "modification time before or on now");
+ok(-f $0, "yes, we are a file");
+ok(-d "win32", "and win32 is a directory");
+pipe(my ($p1, $p2));
+ok(-p $p1, "a pipe is a pipe");
+close $p1; close $p2;
+ok(-r $0, "we are readable");
+ok(!-x $0, "but not executable");
+ok(-e $0, "we exist");
+
+ok(open(my $nul, ">", "nul"), "open nul");
+ok(-c $nul, "nul is a character device");
+close $nul;
+
+my $nlink = $st[3];
+
+# check we get nlinks etc for a directory
+@st = stat("win32");
+ok($st[0], "got dev for a directory");
+ok($st[1], "got ino for a directory");
+ok($st[3], "got nlink for a directory");
+
+# symbolic links
+unlink($tmpfile1); # no more hard link
+
+if (open my $fh, ">", "$tmpfile1.bat") {
+    ok(-x "$tmpfile1.bat", 'batch file is "executable"');
+    SKIP: {
+        skip "executable bit for handles needs vista or later", 1
+            unless $vista_or_later;
+        ok(-x $fh, 'batch file handle is "executable"');
+    }
+    close $fh;
+    unlink "$tmpfile1.bat";
+}
+
+# mklink is available from Vista onwards
+# this may only work in an admin shell
+# MKLINK [[/D] | [/H] | [/J]] Link Target
+if (system("mklink $tmpfile1 win32\\stat.t") == 0) {
+    ok(-l $tmpfile1, "lstat sees a symlink");
+
+    # check stat on file vs symlink
+    @st = stat $0;
+    my @lst = stat $tmpfile1;
+
+    $st[6] = $lst[6] = 0;
+
+    is("@st", "@lst", "check stat on file vs link");
+
+    # our hard link no longer exists, check that is reflected in nlink
+    is($st[3], $nlink-1, "check nlink updated");
+
+    unlink($tmpfile1);
+}
+
+# similarly for a directory
+if (system("mklink /d $tmpfile1 win32") == 0) {
+    ok(-l $tmpfile1, "lstat sees a symlink on the directory symlink");
+
+    # check stat on directory vs symlink
+    @st = stat "win32";
+    my @lst = stat $tmpfile1;
+
+    $st[6] = $lst[6] = 0;
+
+    is("@st", "@lst", "check stat on dir vs link");
+
+    # for now at least, we need to rmdir symlinks to directories
+    rmdir( $tmpfile1 );
+}
+
+# check a junction looks like a symlink
+
+if (system("mklink /j $tmpfile1 win32") == 0) {
+    ok(-l $tmpfile1, "lstat sees a symlink on the directory junction");
+
+    rmdir( $tmpfile1 );
+}
+
+# test interaction between stat and utime
+if (ok(open(my $fh, ">", $tmpfile1), "make a work file")) {
+    # make our test file
+    close $fh;
+
+    my @st = stat $tmpfile1;
+    ok(@st, "stat our work file");
+
+    # switch to the other half of the year, to flip from/to daylight
+    # savings time.  It won't always do so, but it's close enough and
+    # avoids having to deal with working out exactly when it
+    # starts/ends (if it does), along with the hemisphere.
+    #
+    # By basing this on the current file times and using an offset
+    # that's the multiple of an hour we ensure the filesystem
+    # resolution supports the time we set.
+    my $moffset = 6 * 30 * 24 * 3600;
+    my $aoffset = $moffset - 24 * 3600;;
+    my $mymt = $st[9] - $moffset;
+    my $myat = $st[8] - $aoffset;
+    ok(utime($myat, $mymt, $tmpfile1), "set access and mod times");
+    my @mst = stat $tmpfile1;
+    ok(@mst, "fetch stat after utime");
+    is($mst[9], $mymt, "check mod time");
+    is($mst[8], $myat, "check access time");
+
+    unlink $tmpfile1;
+}
+
+# same for a directory
+if (ok(mkdir($tmpfile1), "make a work directory")) {
+    my @st = stat $tmpfile1;
+    ok(@st, "stat our work directory");
+
+    my $moffset = 6 * 30 * 24 * 3600;
+    my $aoffset = $moffset - 24 * 3600;;
+    my $mymt = $st[9] - $moffset;
+    my $myat = $st[8] - $aoffset;
+    ok(utime($myat, $mymt, $tmpfile1), "set access and mod times");
+    my @mst = stat $tmpfile1;
+    ok(@mst, "fetch stat after utime");
+    is($mst[9], $mymt, "check mod time");
+    is($mst[8], $myat, "check access time");
+
+    rmdir $tmpfile1;
+}
+
+# Other stat issues possibly fixed by the stat() re-work
+
+# https://github.com/Perl/perl5/issues/9025 - win32 - file test operators don't work for //?/UNC/server/file filenames
+# can't really make a reliable regression test for this
+# reproduced original problem with a gcc build
+# confirmed fixed with a gcc build
+
+# https://github.com/Perl/perl5/issues/8502 - filetest problem with STDIN/OUT on Windows
+
+{
+    ok(-r *STDIN, "check stdin is readable");
+    ok(-w *STDOUT, "check stdout is writable");
+
+    # CompareObjectHandles() could fix this, but requires Windows 10
+    local our $TODO = "dupped *STDIN and *STDOUT not read/write";
+    open my $dupin, "<&STDIN" or die;
+    open my $dupout, ">&STDOUT" or die;
+    ok(-r $dupin, "check duplicated stdin is readable");
+    ok(-w $dupout, "check duplicated stdout is writable");
+}
+
+# https://github.com/Perl/perl5/issues/6080 - Last mod time from stat() can be wrong on Windows NT/2000/XP
+# tested already
+
+# https://github.com/Perl/perl5/issues/4145 - Problem with filetest -x _ on Win2k AS Perl build 626
+# tested already
+
+# https://github.com/Perl/perl5/issues/14687 -  Function lstat behavior case differs between Windows and Unix #14687
+
+{
+    local our $TODO = "... .... treated as .. by Win32 API";
+    ok(!-e ".....", "non-existing many dots shouldn't returned existence");
+}
+
+# https://github.com/Perl/perl5/issues/7410 - -e tests not reliable under Win32
+{
+    # there's to issues here:
+    # 1) CreateFile() successfully opens " . . " when opened with backup
+    # semantics/directory
+    # 2) opendir(" . . ") becomes FindFirstFile(" . . /*") which fails
+    #
+    # So we end up with success for the first and failure for the second,
+    # making them inconsistent, there may be a Vista level fix for this,
+    # but if we expect -e " . . " to fail we need a more complex fix.
+    local our $TODO = "strange space handling by Windows";
+    ok(!-e " ", "filename ' ' shouldn't exist");
+    ok(!-e " . . ", "filename ' . . ' shouldn't exist");
+    ok(!-e " .. ", "filename ' .. ' shouldn't exist");
+    ok(!-e " . ", "filename ' . ' shouldn't exist");
+
+    ok(!!-e " . . " == !!opendir(FOO, " . . "),
+       "these should be consistent");
+}
+
+# https://github.com/Perl/perl5/issues/12431 - Win32: -e '"' always returns true
+
+{
+    ok(!-e '"', qq(filename '"' shouldn't exist));
+}
+
+done_testing();
diff --git a/t/win32/symlink.t b/t/win32/symlink.t
new file mode 100644 (file)
index 0000000..96ed7a1
--- /dev/null
@@ -0,0 +1,106 @@
+#!./perl
+
+BEGIN {
+    chdir 't' if -d 't';
+    @INC = '../lib';
+    require "./test.pl";
+}
+
+use Errno;
+
+Win32::FsType() eq 'NTFS'
+    or skip_all("need NTFS");
+
+plan skip_all => "no symlink available in this Windows"
+    if !symlink('', '') && $! == &Errno::ENOSYS;
+
+my $tmpfile1 = tempfile();
+my $tmpfile2 = tempfile();
+
+my $ok = symlink($tmpfile1, $tmpfile2);
+plan skip_all => "no access to symlink as this user"
+     if !$ok && $! == &Errno::EPERM;
+
+ok($ok, "create a dangling symbolic link");
+ok(-l $tmpfile2, "-l sees it as a symlink");
+ok(unlink($tmpfile2), "and remove it");
+
+ok(mkdir($tmpfile1), "make a directory");
+ok(!-l $tmpfile1, "doesn't look like a symlink");
+ok(symlink($tmpfile1, $tmpfile2), "and symlink to it");
+ok(-l $tmpfile2, "which does look like a symlink");
+ok(!-d _, "-d on the lstat result is false");
+ok(-d $tmpfile2, "normal -d sees it as a directory");
+is(readlink($tmpfile2), $tmpfile1, "readlink works");
+check_stat($tmpfile1, $tmpfile2, "check directory and link stat are the same");
+ok(unlink($tmpfile2), "and we can unlink the symlink (rather than only rmdir)");
+
+# test our various name based directory tests
+{
+    use Win32API::File qw(GetFileAttributes FILE_ATTRIBUTE_DIRECTORY
+                          INVALID_FILE_ATTRIBUTES);
+    # we can't use lstat() here, since the directory && symlink state
+    # can't be preserved in it's result, and normal stat would
+    # follow the link (which is broken for most of these)
+    # GetFileAttributes() doesn't follow the link and can present the
+    # directory && symlink state
+    my @tests =
+        (
+         "x:",
+         "x:\\",
+         "x:/",
+         "unknown\\",
+         "unknown/",
+         ".",
+         "..",
+        );
+    for my $path (@tests) {
+        ok(symlink($path, $tmpfile2), "symlink $path");
+        my $attr = GetFileAttributes($tmpfile2);
+        ok($attr != INVALID_FILE_ATTRIBUTES && ($attr & FILE_ATTRIBUTE_DIRECTORY) != 0,
+           "symlink $path: treated as a directory");
+        unlink($tmpfile2);
+    }
+}
+
+# to check the unlink code for symlinks isn't mis-handling non-symlink
+# directories
+ok(!unlink($tmpfile1), "we can't unlink the original directory");
+
+ok(rmdir($tmpfile1), "we can rmdir it");
+
+ok(open(my $fh, ">", $tmpfile1), "make a file");
+close $fh if $fh;
+ok(symlink($tmpfile1, $tmpfile2), "link to it");
+ok(-l $tmpfile2, "-l sees a link");
+ok(!-f _, "-f on the lstat result is false");
+ok(-f $tmpfile2, "normal -d sees it as a file");
+is(readlink($tmpfile2), $tmpfile1, "readlink works");
+check_stat($tmpfile1, $tmpfile2, "check file and link stat are the same");
+ok(unlink($tmpfile2), "unlink the symlink");
+ok(unlink($tmpfile1), "and the file");
+
+# test we don't treat directory junctions like symlinks
+ok(mkdir($tmpfile1), "make a directory");
+
+# mklink is available from Vista onwards
+# this may only work in an admin shell
+# MKLINK [[/D] | [/H] | [/J]] Link Target
+if (system("mklink /j $tmpfile2 $tmpfile1") == 0) {
+    ok(-l $tmpfile2, "junction does look like a symlink");
+    like(readlink($tmpfile2), qr/\Q$tmpfile1\E$/,
+         "readlink() works on a junction");
+    ok(unlink($tmpfile2), "unlink magic for junctions");
+}
+rmdir($tmpfile1);
+
+done_testing();
+
+sub check_stat {
+    my ($file1, $file2, $name) = @_;
+
+    my @stat1 = stat($file1);
+    my @stat2 = stat($file2);
+
+    is("@stat1", "@stat2", $name);
+}
index e695889..99679b2 100644 (file)
--- a/thread.h
+++ b/thread.h
     } STMT_END
 #endif /* COND_INIT */
 
+#if defined(MUTEX_LOCK) && defined(MUTEX_UNLOCK)                \
+ && defined(COND_SIGNAL) && defined(COND_WAIT)
+
+/* These emulate native many-reader/1-writer locks.
+ * Basically a locking reader just locks the semaphore long enough to increment
+ * a counter; and similarly decrements it when when through.  Any writer will
+ * run only when the count of readers is 0.  That is because it blocks on that
+ * semaphore (doing a COND_WAIT) until it gets control of it, which won't
+ * happen unless the count becomes 0.  ALL readers and other writers are then
+ * blocked until it releases the semaphore.  The reader whose unlocking causes
+ * the count to become 0 signals any waiting writers, and the system guarantees
+ * that only one gets control at a time */
+
+#  define PERL_READ_LOCK(mutex)                                     \
+    STMT_START {                                                    \
+        MUTEX_LOCK(&(mutex)->lock);                                 \
+        (mutex)->readers_count++;                                   \
+        MUTEX_UNLOCK(&(mutex)->lock);                               \
+    } STMT_END
+
+#  define PERL_READ_UNLOCK(mutex)                                   \
+    STMT_START {                                                    \
+        MUTEX_LOCK(&(mutex)->lock);                                 \
+        (mutex)->readers_count--;                                   \
+        if ((mutex)->readers_count <= 0) {                          \
+            assert((mutex)->readers_count == 0);                    \
+            COND_SIGNAL(&(mutex)->wakeup);                          \
+            (mutex)->readers_count = 0;                             \
+        }                                                           \
+        MUTEX_UNLOCK(&(mutex)->lock);                               \
+    } STMT_END
+
+#  define PERL_WRITE_LOCK(mutex)                                    \
+    STMT_START {                                                    \
+        MUTEX_LOCK(&(mutex)->lock);                                 \
+        do {                                                        \
+            if ((mutex)->readers_count <= 0) {                      \
+                assert((mutex)->readers_count == 0);                \
+                (mutex)->readers_count = 0;                         \
+                break;                                              \
+            }                                                       \
+            COND_WAIT(&(mutex)->wakeup, &(mutex)->lock);            \
+        }                                                           \
+        while (1);                                                  \
+                                                                    \
+        /* Here, the mutex is locked, with no readers */            \
+    } STMT_END
+
+#  define PERL_WRITE_UNLOCK(mutex)                                  \
+    STMT_START {                                                    \
+        COND_SIGNAL(&(mutex)->wakeup);                              \
+        MUTEX_UNLOCK(&(mutex)->lock);                               \
+    } STMT_END
+
+#  define PERL_RW_MUTEX_INIT(mutex)                                 \
+    STMT_START {                                                    \
+        MUTEX_INIT(&(mutex)->lock);                                 \
+        COND_INIT(&(mutex)->wakeup);                                \
+        (mutex)->readers_count = 0;                                 \
+    } STMT_END
+
+#  define PERL_RW_MUTEX_DESTROY(mutex)                              \
+    STMT_START {                                                    \
+        COND_DESTROY(&(mutex)->wakeup);                             \
+        MUTEX_DESTROY(&(mutex)->lock);                              \
+    } STMT_END
+
+#endif
+
 /* DETACH(t) must only be called while holding t->mutex */
 #ifndef DETACH
 #  define DETACH(t) \
 #  define COND_DESTROY(c)         NOOP
 #endif
 
+#ifndef PERL_READ_LOCK
+#  define PERL_READ_LOCK          NOOP
+#  define PERL_READ_UNLOCK        NOOP
+#  define PERL_WRITE_LOCK         NOOP
+#  define PERL_WRITE_UNLOCK       NOOP
+#  define PERL_RW_MUTEX_INIT      NOOP
+#  define PERL_RW_MUTEX_DESTROY   NOOP
+#endif
+
 #ifndef LOCK_DOLLARZERO_MUTEX
 #  define LOCK_DOLLARZERO_MUTEX   NOOP
 #endif
index 7fc50af..52d99cd 100644 (file)
--- a/time64.c
+++ b/time64.c
@@ -479,7 +479,7 @@ struct TM *Perl_localtime64_r (const Time64_T *time, struct TM *local_tm)
     struct tm safe_date;
     const struct tm * result;
     struct TM gm_tm;
-    Year orig_year;
+    Year orig_year = 0; /* initialise to avoid spurious compiler warning */
     int month_diff;
     const bool use_system = SHOULD_USE_SYSTEM_LOCALTIME(*time);
     dTHX;
index 0bebebb..8a8dbef 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef PERL_TIME64_CONFIG_H_
 #    define PERL_TIME64_CONFIG_H_
 
+#include "reentr.h"
+
 /* Configuration
    -------------
    Define as appropriate for your system.
diff --git a/toke.c b/toke.c
index 9dcc7c3..9d9495f 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -11366,7 +11366,7 @@ Perl_scan_str(pTHX_ char *start, int keep_bracketed_quoted, int keep_delims, int
   \d(_?\d)*(\.(\d(_?\d)*)?)?[Ee][\+\-]?(\d(_?\d)*)     12 12.34 12.
   \.\d(_?\d)*[Ee][\+\-]?(\d(_?\d)*)                    .34
   0b[01](_?[01])*                                       binary integers
-  0[0-7](_?[0-7])*                                      octal integers
+  0o?[0-7](_?[0-7])*                                    octal integers
   0x[0-9A-Fa-f](_?[0-9A-Fa-f])*                         hexadecimal integers
   0x[0-9A-Fa-f](_?[0-9A-Fa-f])*(?:\.\d*)?p[+-]?[0-9]+   hexadecimal floats
 
@@ -11422,6 +11422,7 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
     NV hexfp_mult = 1.0;
     UV high_non_zero = 0; /* highest digit */
     int non_zero_integer_digits = 0;
+    bool new_octal = FALSE;     /* octal with "0o" prefix */
 
     PERL_ARGS_ASSERT_SCAN_NUM;
 
@@ -11459,7 +11460,6 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
                "",
                "037777777777",
                "0xffffffff" };
-           const char *base, *Base, *max;
 
            /* check for hex */
            if (isALPHA_FOLD_EQ(s[1], 'x')) {
@@ -11478,6 +11478,11 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
            else {
                shift = 3;
                s++;
+                if (isALPHA_FOLD_EQ(*s, 'o')) {
+                    s++;
+                    just_zero = FALSE;
+                    new_octal = TRUE;
+                }
            }
 
            if (*s == '_') {
@@ -11485,10 +11490,6 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
               lastub = s++;
            }
 
-           base = bases[shift];
-           Base = Bases[shift];
-           max  = maxima[shift];
-
            /* read the rest of the number */
            for (;;) {
                /* x is used in the overflow test,
@@ -11552,7 +11553,7 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
                            n = (NV) u;
                            Perl_ck_warner_d(aTHX_ packWARN(WARN_OVERFLOW),
                                             "Integer overflow in %s number",
-                                            base);
+                                             bases[shift]);
                        } else
                            u = x | b;          /* add the digit to the end */
                    }
@@ -11755,8 +11756,8 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
                 }
             }
 
-            if (shift != 3 && !has_digs) {
-                /* 0x or 0b with no digits, treat it as an error.
+            if (!just_zero && !has_digs) {
+                /* 0x, 0o or 0b with no digits, treat it as an error.
                    Originally this backed up the parse before the b or
                    x, but that has the potential for silent changes in
                    behaviour, like for: "0x.3" and "0x+$foo".
@@ -11766,7 +11767,7 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
                 if (*d) ++d; /* so the user sees the bad non-digit */
                 PL_bufptr = (char *)d; /* so yyerror reports the context */
                 yyerror(Perl_form(aTHX_ "No digits found for %s literal",
-                                  shift == 4 ? "hexadecimal" : "binary"));
+                                  bases[shift]));
                 PL_bufptr = oldbp;
             }
 
@@ -11774,7 +11775,8 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
                if (n > 4294967295.0)
                    Perl_ck_warner(aTHX_ packWARN(WARN_PORTABLE),
                                   "%s number > %s non-portable",
-                                  Base, max);
+                                   Bases[shift],
+                                   new_octal ? "0o37777777777" : maxima[shift]);
                sv = newSVnv(n);
            }
            else {
@@ -11782,7 +11784,8 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
                if (u > 0xffffffff)
                    Perl_ck_warner(aTHX_ packWARN(WARN_PORTABLE),
                                   "%s number > %s non-portable",
-                                  Base, max);
+                                   Bases[shift],
+                                   new_octal ? "0o37777777777" : maxima[shift]);
 #endif
                sv = newSVuv(u);
            }
@@ -11814,6 +11817,11 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
                 s = start + 2;
                 break;
             case 3:
+                if (new_octal) {
+                    *d++ = 'o';
+                    s = start + 2;
+                    break;
+                }
                 s = start + 1;
                 break;
             case 1:
index 21a06ca..9df1564 100644 (file)
--- a/uconfig.h
+++ b/uconfig.h
  */
 /*#define DEFAULT_INC_EXCLUDES_DOT     / **/
 
-/* USE_STRICT_BY_DEFAULT
+/* USE_STRICT_BY_DEFAULT:
  *     This symbol, if defined, enables additional defaults.
  *     At this time it only enables implicit strict by default.
  */
 /*#define HAS_ENDSERVENT_R     / **/
 #define ENDSERVENT_R_PROTO 0   /**/
 
+/* GETENV_PRESERVES_OTHER_THREAD:
+ *     This symbol, if defined, indicates that the getenv system call doesn't
+ *     zap the static buffer of getenv() in a different thread.
+ *
+ *     The typical getenv() implementation will return a pointer to the proper
+ *     position in **environ.  But some may instead copy them to a static
+ *     buffer in getenv().  If there is a per-thread instance of that buffer,
+ *     or the return points to **environ, then a many-reader/1-writer mutex
+ *     will work; otherwise an exclusive locking mutex is required to prevent
+ *     races.
+ */
+#define GETENV_PRESERVES_OTHER_THREAD  /**/
+
 /* HAS_GETGRENT_R:
  *     This symbol, if defined, indicates that the getgrent_r routine
  *     is available to getgrent re-entrantly.
 #endif
 
 /* Generated from:
- * c61677bd68360e1b03a0e5fd070cc1a739c01e71988872c4e414e3c69328bc9b config_h.SH
- * 4c3159a6a9875b7811c2a920d7936d5199193afdb163473c313b9531ba2c0648 uconfig.sh
+ * 53ec858c462f9fa2669095834b3d350458c955777a07a0ad7a3a73162ff8ef0e config_h.SH
+ * b53784d20c0f250807f47a3130cdc8e01a92da948e6747af87ebc24f11904722 uconfig.sh
  * ex: set ro: */
index 7747dd6..392070d 100644 (file)
@@ -187,6 +187,7 @@ d_gdbm_ndbm_h_uses_prototypes='undef'
 d_gdbmndbm_h_uses_prototypes='undef'
 d_getaddrinfo='undef'
 d_getcwd='undef'
+d_getenv_preserves_other_thread='define'
 d_getespwnam='undef'
 d_getfsstat='undef'
 d_getgrent='undef'
index f87cb05..6f238fc 100644 (file)
@@ -187,6 +187,7 @@ d_gdbm_ndbm_h_uses_prototypes='undef'
 d_gdbmndbm_h_uses_prototypes='undef'
 d_getaddrinfo='undef'
 d_getcwd='undef'
+d_getenv_preserves_other_thread='define'
 d_getespwnam='undef'
 d_getfsstat='undef'
 d_getgrent='undef'
index 232f18c..eea66f6 100644 (file)
@@ -88,8 +88,10 @@ bytes.
 #   define LATIN_SMALL_LETTER_Y_WITH_DIAERESIS_NATIVE  0xFF    /* U+00FF */
 #   define MICRO_SIGN_NATIVE  0xB5    /* U+00B5 */
 #   define MICRO_SIGN_UTF8  "\xC2\xB5"    /* U+00B5 */
-#   define MAX_PRINT_A_FOR_USE_ONLY_BY_REGCOMP_DOT_C   0x7E   /* The max code point that isPRINT_A */
 
+#    ifdef PERL_IN_REGCOMP_C
+#      define MAX_PRINT_A  0x7E   /* The max code point that isPRINT_A */
+#    endif
 #endif /* ASCII/Latin1 */
 
 #if 'A' == 193 /* EBCDIC 1047 */ \
@@ -133,8 +135,10 @@ bytes.
 #   define LATIN_SMALL_LETTER_Y_WITH_DIAERESIS_NATIVE  0xDF    /* U+00FF */
 #   define MICRO_SIGN_NATIVE  0xA0    /* U+00B5 */
 #   define MICRO_SIGN_UTF8  "\x80\x64"    /* U+00B5 */
-#   define MAX_PRINT_A_FOR_USE_ONLY_BY_REGCOMP_DOT_C   0xF9   /* The max code point that isPRINT_A */
 
+#    ifdef PERL_IN_REGCOMP_C
+#      define MAX_PRINT_A  0xF9   /* The max code point that isPRINT_A */
+#    endif
 #endif /* EBCDIC 1047 */
 
 #if 'A' == 193 /* EBCDIC 037 */ \
@@ -178,15 +182,21 @@ bytes.
 #   define LATIN_SMALL_LETTER_Y_WITH_DIAERESIS_NATIVE  0xDF    /* U+00FF */
 #   define MICRO_SIGN_NATIVE  0xA0    /* U+00B5 */
 #   define MICRO_SIGN_UTF8  "\x78\x63"    /* U+00B5 */
-#   define MAX_PRINT_A_FOR_USE_ONLY_BY_REGCOMP_DOT_C   0xF9   /* The max code point that isPRINT_A */
 
+#    ifdef PERL_IN_REGCOMP_C
+#      define MAX_PRINT_A  0xF9   /* The max code point that isPRINT_A */
+#    endif
 #endif /* EBCDIC 037 */
 
 /* The number of code points not matching \pC */
-#define NON_OTHER_COUNT_FOR_USE_ONLY_BY_REGCOMP_DOT_C  143698
+#ifdef PERL_IN_REGCOMP_C
+#  define NON_OTHER_COUNT  143698
+#endif
 
 /* The highest code point that has any type of case change */
-#define HIGHEST_CASE_CHANGING_CP_FOR_USE_ONLY_BY_UTF8_DOT_C  0x1E943
+#ifdef PERL_IN_UTF8_C
+#  define HIGHEST_CASE_CHANGING_CP  0x1E943
+#endif
 
 #endif /* PERL_UNICODE_CONSTANTS_H_ */
 
diff --git a/utf8.c b/utf8.c
index aaa620c..add8c09 100644 (file)
--- a/utf8.c
+++ b/utf8.c
@@ -3335,10 +3335,8 @@ S__to_utf8_case(pTHX_ const UV uv1, const U8 *p,
                     }
                     goto cases_to_self;
                 }
-#ifdef HIGHEST_CASE_CHANGING_CP_FOR_USE_ONLY_BY_UTF8_DOT_C
-                if (UNLIKELY(uv1
-                    > HIGHEST_CASE_CHANGING_CP_FOR_USE_ONLY_BY_UTF8_DOT_C))
-                {
+#ifdef HIGHEST_CASE_CHANGING_CP
+                if (UNLIKELY(uv1 > HIGHEST_CASE_CHANGING_CP)) {
 
                     goto cases_to_self;
                 }
diff --git a/utf8.h b/utf8.h
index e254b8b..f52317b 100644 (file)
--- a/utf8.h
+++ b/utf8.h
@@ -873,7 +873,7 @@ fit in an IV on the current machine.
                    &&  UNLIKELY(    NATIVE_UTF8_TO_I8(*(s)) >  0xF9         \
                                 || (NATIVE_UTF8_TO_I8(*((s) + 1)) >= 0xA2)) \
                    &&  LIKELY((s) + UTF8SKIP(s) <= (e)))                    \
-                 ?  is_utf8_char_helper(s, s + UTF8SKIP(s), 0) : 0
+                 ?  is_utf8_char_helper(s, s + UTF8SKIP(s), 0) : 0)
 #else
 #   define UTF8_IS_SUPER(s, e)                                              \
                    ((    ((e) > (s) + 3)                                    \
diff --git a/util.c b/util.c
index 5989a58..4cd23e8 100644 (file)
--- a/util.c
+++ b/util.c
@@ -3087,8 +3087,6 @@ Perl_rsignal_state(pTHX_ int signo)
 int
 Perl_rsignal_save(pTHX_ int signo, Sighandler_t handler, Sigsave_t *save)
 {
-#ifdef USE_ITHREADS
-#endif
     struct sigaction act;
 
     PERL_ARGS_ASSERT_RSIGNAL_SAVE;
@@ -3116,8 +3114,6 @@ Perl_rsignal_save(pTHX_ int signo, Sighandler_t handler, Sigsave_t *save)
 int
 Perl_rsignal_restore(pTHX_ int signo, Sigsave_t *save)
 {
-#ifdef USE_ITHREADS
-#endif
     PERL_UNUSED_CONTEXT;
 #ifdef USE_ITHREADS
     /* only "parent" interpreter can diddle signals */
@@ -5005,10 +5001,13 @@ S_mem_log_common(enum mem_log_type mlt, const UV n,
                 const char *funcname)
 {
     const char *pmlenv;
+    dTHX;
 
     PERL_ARGS_ASSERT_MEM_LOG_COMMON;
 
+    PL_mem_log[0] |= 0x2;   /* Flag that the call is from this code */
     pmlenv = PerlEnv_getenv("PERL_MEM_LOG");
+    PL_mem_log[0] &= ~0x2;
     if (!pmlenv)
        return;
     if (mlt < MLT_NEW_SV ? strchr(pmlenv,'m') : strchr(pmlenv,'s'))
diff --git a/utils/.gitignore b/utils/.gitignore
new file mode 100644 (file)
index 0000000..b922755
--- /dev/null
@@ -0,0 +1,5 @@
+*
+!/.gitignore
+!/.github
+!/*.SH
+!/*.PL
index dd12252..0323f06 100644 (file)
@@ -313,7 +313,7 @@ utils : $(utils1) $(utils2) $(utils3) $(utils4) $(utils5)
 extra.pods : miniperl
        @ @extra_pods.com
 
-PERLDELTA_CURRENT = [.pod]perl5334delta.pod
+PERLDELTA_CURRENT = [.pod]perl5335delta.pod
 
 $(PERLDELTA_CURRENT) : [.pod]perldelta.pod
        Copy/NoConfirm/Log $(MMS$SOURCE) $(PERLDELTA_CURRENT)
diff --git a/win32/.gitignore b/win32/.gitignore
new file mode 100644 (file)
index 0000000..56dee9f
--- /dev/null
@@ -0,0 +1,14 @@
+/config.h
+/xconfig.h
+/config.w32
+/perl.base
+bin/*.bat
+html/
+mini/
+Extensions_static
+.coreheaders
+dlutils.c
+perllibst.h
+perlmain.c
+perlmainst.c
+!perlexe.ico
index 8dfe0cf..cb8c5cb 100644 (file)
@@ -64,7 +64,7 @@ INST_TOP := $(INST_DRV)\perl
 # versioned installation can be obtained by setting INST_TOP above to a
 # path that includes an arbitrary version string.
 #
-#INST_VER      := \5.33.4
+#INST_VER      := \5.33.5
 
 #
 # Comment this out if you DON'T want your perl installation to have
@@ -116,13 +116,6 @@ USE_IMP_SYS        := define
 USE_PERLIO     := define
 
 #
-# Comment this out if you don't want to enable large file support for
-# some reason.  Should normally only be changed to maintain compatibility
-# with an older release of perl.
-#
-USE_LARGE_FILES        := define
-
-#
 # Uncomment this if you're building a 32-bit perl and want 64-bit integers.
 # (If you're building a 64-bit perl then you will have 64-bit integers whether
 # or not this is uncommented.)
@@ -1213,7 +1206,6 @@ CFG_VARS  =                                       \
                "useperlio=$(USE_PERLIO)"               \
                "use64bitint=$(USE_64_BIT_INT)"         \
                "uselongdouble=$(USE_LONG_DOUBLE)"      \
-               "uselargefiles=$(USE_LARGE_FILES)"      \
                "usesitecustomize=$(USE_SITECUST)"      \
                "default_inc_excludes_dot=$(DEFAULT_INC_EXCLUDES_DOT)"  \
                "LINK_FLAGS=$(subst ",\",$(LINK_FLAGS))"\
@@ -1287,7 +1279,7 @@ endif
 # with MULTI, ITHREADS, IMP_SYS, LARGE_FILES and PERLIO off), then make
 # this target to regenerate config_H.gc.
 regen_config_h:
-       $(MINIPERL) -I..\lib config_sh.PL $(CFG_VARS) $(CFGSH_TMPL) > ..\config.sh
+       $(MINIPERL) -I..\lib config_sh.PL --prebuilt $(CFG_VARS) $(CFGSH_TMPL) > ..\config.sh
        $(MINIPERL) -I..\lib ..\configpm --chdir=..
        -del /f $(CFGH_TMPL)
        -$(MINIPERL) -I..\lib config_h.PL "ARCHPREFIX=$(ARCHPREFIX)"
@@ -1331,9 +1323,6 @@ $(MINIDIR)\.exists : $(CFGH_TMPL)
        @(echo.&& \
        echo #ifndef _config_h_footer_&& \
        echo #define _config_h_footer_&& \
-       echo #undef Off_t&& \
-       echo #undef LSEEKSIZE&& \
-       echo #undef Off_t_size&& \
        echo #undef PTRSIZE&& \
        echo #undef SSize_t&& \
        echo #undef HAS_ATOLL&& \
@@ -1403,15 +1392,6 @@ else ifeq ($(CCTYPE),MSVC142)
        echo #define FILE_bufsiz^(fp^) ^(PERLIO_FILE_cnt^(fp^) + PERLIO_FILE_ptr^(fp^) - PERLIO_FILE_base^(fp^)^)&& \
        echo #define I_STDBOOL)>> config.h
 endif
-ifeq ($(USE_LARGE_FILES),define)
-       @(echo #define Off_t $(INT64)&& \
-       echo #define LSEEKSIZE ^8&& \
-       echo #define Off_t_size ^8)>> config.h
-else
-       @(echo #define Off_t long&& \
-       echo #define LSEEKSIZE ^4&& \
-       echo #define Off_t_size ^4)>> config.h
-endif
 ifeq ($(WIN64),define)
 ifeq ($(CCTYPE),GCC)
        @(echo #define LONG_DOUBLESIZE ^16)>> config.h
@@ -1743,7 +1723,7 @@ utils: $(HAVEMINIPERL) ..\utils\Makefile
        copy ..\README.tw       ..\pod\perltw.pod
        copy ..\README.vos      ..\pod\perlvos.pod
        copy ..\README.win32    ..\pod\perlwin32.pod
-       copy ..\pod\perldelta.pod ..\pod\perl5334delta.pod
+       copy ..\pod\perldelta.pod ..\pod\perl5335delta.pod
        $(MINIPERL) -I..\lib $(PL2BAT) $(UTILS)
        $(MINIPERL) -I..\lib ..\autodoc.pl ..
        $(MINIPERL) -I..\lib ..\pod\perlmodlib.PL -q ..
@@ -1841,7 +1821,7 @@ distclean: realclean
        -if exist $(LIBDIR)\Win32API rmdir /s /q $(LIBDIR)\Win32API
        -if exist $(LIBDIR)\XS rmdir /s /q $(LIBDIR)\XS
        -cd $(PODDIR) && del /f *.html *.bat roffitall \
-           perl5334delta.pod perlaix.pod perlamiga.pod perlandroid.pod \
+           perl5335delta.pod perlaix.pod perlamiga.pod perlandroid.pod \
            perlapi.pod perlbs2000.pod perlcn.pod perlcygwin.pod \
            perldos.pod perlfreebsd.pod perlhaiku.pod perlhpux.pod \
            perlhurd.pod perlintern.pod perlirix.pod perljp.pod perlko.pod \
index 000462b..efd6d4b 100644 (file)
@@ -38,7 +38,7 @@ INST_TOP      = $(INST_DRV)\perl
 # versioned installation can be obtained by setting INST_TOP above to a
 # path that includes an arbitrary version string.
 #
-#INST_VER      = \5.33.4
+#INST_VER      = \5.33.5
 
 #
 # Comment this out if you DON'T want your perl installation to have
@@ -81,13 +81,6 @@ USE_ITHREADS = define
 USE_IMP_SYS    = define
 
 #
-# Comment this out if you don't want to enable large file support for
-# some reason.  Should normally only be changed to maintain compatibility
-# with an older release of perl.
-#
-USE_LARGE_FILES        = define
-
-#
 # Uncomment this if you're building a 32-bit perl and want 64-bit integers.
 # (If you're building a 64-bit perl then you will have 64-bit integers whether
 # or not this is uncommented.)
@@ -296,10 +289,6 @@ USE_ITHREADS       = undef
 USE_IMP_SYS    = undef
 !ENDIF
 
-!IF "$(USE_LARGE_FILES)" == ""
-USE_LARGE_FILES        = undef
-!ENDIF
-
 !IF "$(USE_64_BIT_INT)" == ""
 USE_64_BIT_INT = undef
 !ENDIF
@@ -915,7 +904,6 @@ CFG_VARS    =                                       \
                "usemultiplicity=$(USE_MULTI)"          \
                "use64bitint=$(USE_64_BIT_INT)"         \
                "uselongdouble=undef"                   \
-               "uselargefiles=$(USE_LARGE_FILES)"      \
                "usesitecustomize=$(USE_SITECUST)"      \
                "default_inc_excludes_dot=$(DEFAULT_INC_EXCLUDES_DOT)"  \
                "LINK_FLAGS=$(LINK_FLAGS:"=\")"         \
@@ -966,13 +954,13 @@ perlglob$(o)  : perlglob.c
 # ITHREADS, IMP_SYS and LARGE_FILES off), then make this target
 # to regenerate config_H.vc.
 regen_config_h:
-       $(MINIPERL) -I..\lib config_sh.PL $(CFG_VARS) $(CFGSH_TMPL) > ..\config.sh
+       $(MINIPERL) -I..\lib config_sh.PL --prebuilt $(CFG_VARS) $(CFGSH_TMPL) > ..\config.sh
        $(MINIPERL) -I..\lib ..\configpm --chdir=..
        -del /f $(CFGH_TMPL)
        -$(MINIPERL) -I..\lib config_h.PL
        rename config.h $(CFGH_TMPL)
 
-$(CONFIGPM) : $(MINIPERL) ..\config.sh config_h.PL
+$(CONFIGPM) : $(MINIPERL) ..\config.sh config_h.PL ..\git_version.h
        $(MINIPERL) -I..\lib ..\configpm --chdir=..
        $(XCOPY) ..\*.h $(COREDIR)\*.*
        $(XCOPY) *.h $(COREDIR)\*.*
@@ -1007,9 +995,6 @@ $(MINIDIR)\.exists : $(CFGH_TMPL)
        @(echo.&& \
        echo #ifndef _config_h_footer_&& \
        echo #define _config_h_footer_&& \
-       echo #undef Off_t&& \
-       echo #undef LSEEKSIZE&& \
-       echo #undef Off_t_size&& \
        echo #undef PTRSIZE&& \
        echo #undef SSize_t&& \
        echo #undef HAS_ATOLL&& \
@@ -1041,15 +1026,6 @@ $(MINIDIR)\.exists : $(CFGH_TMPL)
        echo #define FILE_bufsiz^(fp^) ^(PERLIO_FILE_cnt^(fp^) + PERLIO_FILE_ptr^(fp^) - PERLIO_FILE_base^(fp^)^)&& \
        echo #define I_STDBOOL)>> config.h
 !ENDIF
-!IF "$(USE_LARGE_FILES)"=="define"
-       @(echo #define Off_t $(INT64)&& \
-       echo #define LSEEKSIZE ^8&& \
-       echo #define Off_t_size ^8)>> config.h
-!ELSE
-       @(echo #define Off_t long&& \
-       echo #define LSEEKSIZE ^4&& \
-       echo #define Off_t_size ^4)>> config.h
-!ENDIF
 !IF "$(WIN64)"=="define"
        @(echo #define PTRSIZE ^8&& \
        echo #define SSize_t $(INT64)&& \
@@ -1124,7 +1100,7 @@ $(WIN32_OBJ)      : $(CORE_H)
 $(CORE_OBJ)    : $(CORE_H)
 $(DLL_OBJ)     : $(CORE_H)
 
-perldll.def : $(MINIPERL) $(CONFIGPM) ..\embed.fnc ..\makedef.pl create_perllibst_h.pl
+perldll.def : $(MINIPERL) $(CONFIGPM) ..\embed.fnc ..\makedef.pl create_perllibst_h.pl ..\git_version.h
        $(MINIPERL) -I..\lib create_perllibst_h.pl
        $(MINIPERL) -I..\lib -w ..\makedef.pl PLATFORM=win32 $(OPTIMIZE) $(DEFINES) $(BUILDOPT) \
            CCTYPE=$(CCTYPE) TARG_DIR=..\ > perldll.def
@@ -1264,7 +1240,7 @@ utils: $(PERLEXE) ..\utils\Makefile
        copy ..\README.tw       ..\pod\perltw.pod
        copy ..\README.vos      ..\pod\perlvos.pod
        copy ..\README.win32    ..\pod\perlwin32.pod
-       copy ..\pod\perldelta.pod ..\pod\perl5334delta.pod
+       copy ..\pod\perldelta.pod ..\pod\perl5335delta.pod
        cd ..\win32
        $(PERLEXE) $(PL2BAT) $(UTILS)
        $(MINIPERL) -I..\lib ..\autodoc.pl ..
@@ -1363,7 +1339,7 @@ distclean: realclean
        -if exist $(LIBDIR)\Win32API rmdir /s /q $(LIBDIR)\Win32API
        -if exist $(LIBDIR)\XS rmdir /s /q $(LIBDIR)\XS
        -cd $(PODDIR) && del /f *.html *.bat roffitall \
-           perl5334delta.pod perlaix.pod perlamiga.pod perlandroid.pod \
+           perl5335delta.pod perlaix.pod perlamiga.pod perlandroid.pod \
            perlapi.pod perlbs2000.pod perlcn.pod perlcygwin.pod \
            perldos.pod perlfreebsd.pod perlhaiku.pod perlhpux.pod \
            perlhurd.pod perlintern.pod perlirix.pod perljp.pod perlko.pod \
index b0af7d4..b6e298f 100644 (file)
@@ -235,6 +235,7 @@ d_gdbm_ndbm_h_uses_prototypes='undef'
 d_gdbmndbm_h_uses_prototypes='undef'
 d_getaddrinfo='undef'
 d_getcwd='define'
+d_getenv_preserves_other_thread='define'
 d_getespwnam='undef'
 d_getfsstat='undef'
 d_getgrent='undef'
@@ -358,7 +359,7 @@ d_lrintl='define'
 d_lround='define'
 d_lroundl='define'
 d_lseekproto='define'
-d_lstat='undef'
+d_lstat='define'
 d_madvise='undef'
 d_malloc_good_size='undef'
 d_malloc_size='undef'
@@ -446,7 +447,7 @@ d_random_r='undef'
 d_readdir64_r='undef'
 d_readdir='define'
 d_readdir_r='undef'
-d_readlink='undef'
+d_readlink='define'
 d_readv='undef'
 d_recvmsg='undef'
 d_regcomp='undef'
@@ -571,7 +572,7 @@ d_strtoull='undef'
 d_strtouq='undef'
 d_strxfrm='define'
 d_suidsafe='undef'
-d_symlink='undef'
+d_symlink='define'
 d_syscall='undef'
 d_syscallproto='undef'
 d_sysconf='undef'
@@ -888,8 +889,8 @@ longsize='4'
 lp=''
 lpr=''
 ls='dir'
-lseeksize='4'
-lseektype='long'
+lseeksize='8'
+lseektype='long long'
 mad='undef'
 mail=''
 mailx=''
@@ -1126,7 +1127,7 @@ usedtrace='undef'
 usefaststdio='undef'
 useithreads='undef'
 usekernprocpathname='undef'
-uselargefiles='undef'
+uselargefiles='define'
 uselongdouble='undef'
 usemallocwrap='define'
 usemorebits='undef'
index 234de8d..f4625bf 100644 (file)
@@ -235,6 +235,7 @@ d_gdbm_ndbm_h_uses_prototypes='undef'
 d_gdbmndbm_h_uses_prototypes='undef'
 d_getaddrinfo='undef'
 d_getcwd='define'
+d_getenv_preserves_other_thread='define'
 d_getespwnam='undef'
 d_getfsstat='undef'
 d_getgrent='undef'
@@ -358,7 +359,7 @@ d_lrintl='undef'
 d_lround='undef'
 d_lroundl='undef'
 d_lseekproto='define'
-d_lstat='undef'
+d_lstat='define'
 d_madvise='undef'
 d_malloc_good_size='undef'
 d_malloc_size='undef'
@@ -446,7 +447,7 @@ d_random_r='undef'
 d_readdir64_r='undef'
 d_readdir='define'
 d_readdir_r='undef'
-d_readlink='undef'
+d_readlink='define'
 d_readv='undef'
 d_recvmsg='undef'
 d_regcomp='undef'
@@ -571,7 +572,7 @@ d_strtoull='undef'
 d_strtouq='undef'
 d_strxfrm='define'
 d_suidsafe='undef'
-d_symlink='undef'
+d_symlink='define'
 d_syscall='undef'
 d_syscallproto='undef'
 d_sysconf='undef'
@@ -887,8 +888,8 @@ longsize='4'
 lp=''
 lpr=''
 ls='dir'
-lseeksize='4'
-lseektype='long'
+lseeksize='8'
+lseektype='__int64'
 mad='undef'
 mail=''
 mailx=''
@@ -1125,7 +1126,7 @@ usedtrace='undef'
 usefaststdio='undef'
 useithreads='undef'
 usekernprocpathname='undef'
-uselargefiles='undef'
+uselargefiles='define'
 uselongdouble='undef'
 usemallocwrap='define'
 usemorebits='undef'
index 72b7013..46a13c3 100644 (file)
@@ -9,8 +9,8 @@
 
 /* Package name      : perl5
  * Source directory  : 
- * Configuration time: Tue Oct 17 08:44:03 2017
- * Configured by     : shay
+ * Configuration time: Mon Oct 19 14:19:25 2020
+ * Configured by     : tony
  * Target system     : 
  */
 
@@ -32,7 +32,7 @@
  *     This symbol, if defined, indicates that the cbrt() (cube root)
  *     function is available.
  */
-#define HAS_CBRT               /**/
+#define HAS_CBRT       /**/
 
 /* HAS_CHOWN:
  *     This symbol, if defined, indicates that the chown routine is
  *     This symbol, if defined, indicates that the lstat routine is
  *     available to do file stats on symbolic links.
  */
-/*#define HAS_LSTAT            / **/
+#define HAS_LSTAT              /**/
 
 /* HAS_MBLEN:
  *     This symbol, if defined, indicates that the mblen routine is available
  */
 #define HAS_MKTIME             /**/
 
+/* HAS_MSG:
+ *     This symbol, if defined, indicates that the entire msg*(2) library is
+ *     supported (IPC mechanism based on message queues).
+ */
+/*#define HAS_MSG              / **/
+
 /* HAS_MSYNC:
  *     This symbol, if defined, indicates that the msync system call is
  *     available to synchronize a mapped file.
  *     This symbol, if defined, indicates that the readlink routine is
  *     available to read the value of a symbolic link.
  */
-/*#define HAS_READLINK         / **/
+#define HAS_READLINK           /**/
 
 /* HAS_REGCOMP:
  *     This symbol, if defined, indicates that the regcomp() routine is
  */
 #define HAS_SELECT     /**/
 
+/* HAS_SEM:
+ *     This symbol, if defined, indicates that the entire sem*(2) library is
+ *     supported.
+ */
+/*#define HAS_SEM              / **/
+
 /* HAS_SETEGID:
  *     This symbol, if defined, indicates that the setegid routine is available
  *     to change the effective gid of the current program.
  */
 /*#define HAS_SETLINEBUF               / **/
 
-/* HAS_SETLOCALE:
- *     This symbol, if defined, indicates that the setlocale routine is
- *     available to handle locale-specific ctype implementations.
- */
-#define HAS_SETLOCALE  /**/
-
 /* HAS_SETPGID:
  *     This symbol, if defined, indicates that the setpgid(pid, gpid)
  *     routine is available to set process group ID.
  *     This symbol, if defined, indicates that the symlink routine is available
  *     to create symbolic links.
  */
-/*#define HAS_SYMLINK  / **/
+#define HAS_SYMLINK    /**/
 
 /* HAS_SYSCALL:
  *     This symbol, if defined, indicates that the syscall routine is
 /*#define HAS_EACCESS          / **/
 
 /* I_SYS_ACCESS:
- *     This symbol, if defined, indicates to the C program that it should
- *     include <sys/access.h>.
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <sys/access.h>.
  */
 /*#define   I_SYS_ACCESS                / **/
 
 /* I_SYS_SECURITY:
- *     This symbol, if defined, indicates to the C program that it should
- *     include <sys/security.h>.
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <sys/security.h>.
  */
 /*#define   I_SYS_SECURITY     / **/
 
  *     This symbol contains the number of bytes required to align a
  *     double, or a long double when applicable. Usual values are 2,
  *     4 and 8. The default is eight, for safety.  For cross-compiling
- *     or multiarch support, Configure will set a minimum of 8.
+ *     or multiarch support, Configure will set a minimum of 8.
  */
 #define MEM_ALIGNBYTES 8
 
 #    endif
 #  endif
 #else
-#define BYTEORDER 0x1234       /* large digits for MSB */
+#define BYTEORDER 0x12345678   /* large digits for MSB */
 #endif
 
 /* CHARBITS:
  *     the GNU C library is being used.  A better check is to use
  *     the __GLIBC__ and __GLIBC_MINOR__ symbols supplied with glibc.
  */
-/*#define HAS_GNULIBC          / **/
+/*#define HAS_GNULIBC  / **/
 #if defined(HAS_GNULIBC) && !defined(_GNU_SOURCE)
 #   define _GNU_SOURCE
 #endif
  *     This symbol is defined if using the FILE_ptr macro as an lvalue
  *     to increase the pointer by n leaves File_cnt(fp) unchanged.
  */
-#define USE_STDIO_PTR  /**/
+#define USE_STDIO_PTR  /**/
 #ifdef USE_STDIO_PTR
 #define FILE_ptr(fp)   ((fp)->_ptr)
-#define STDIO_PTR_LVALUE               /**/
+#define STDIO_PTR_LVALUE               /**/
 #define FILE_cnt(fp)   ((fp)->_cnt)
-#define STDIO_CNT_LVALUE               /**/
+#define STDIO_CNT_LVALUE               /**/
 /*#define STDIO_PTR_LVAL_SETS_CNT      / **/
 #define STDIO_PTR_LVAL_NOCHANGE_CNT    /**/
 #endif
  *     structure pointed to its argument. This macro will always be defined
  *     if USE_STDIO_BASE is defined.
  */
-#define USE_STDIO_BASE         /**/
+#define USE_STDIO_BASE /**/
 #ifdef USE_STDIO_BASE
 #define FILE_base(fp)  ((fp)->_base)
 #define FILE_bufsiz(fp)        ((fp)->_cnt + (fp)->_ptr - (fp)->_base)
 #define DOUBLESIZE 8           /**/
 
 /* I_TIME:
- *     This symbol, if defined, indicates to the C program that it should
- *     include <time.h>.
+ *     This symbol is always defined, and indicates to the C program that
+ *     it should include <time.h>.
  */
 /* I_SYS_TIME:
  *     This symbol, if defined, indicates to the C program that it should
  *     the compiler supports (void *); otherwise it will be
  *     sizeof(char *).
  */
-#define PTRSIZE 4              /**/
+#define PTRSIZE 8              /**/
 
 /* Drand01:
  *     This macro is to be used to generate uniformly distributed
  *     to get any typedef'ed information.
  *     We will pick a type such that sizeof(SSize_t) == sizeof(Size_t).
  */
-#define SSize_t int     /* signed count of bytes */
+#define SSize_t long long      /* signed count of bytes */
 
 /* EBCDIC:
  *     This symbol, if defined, indicates that this system uses
  *     EBCDIC encoding.
  */
-/*#define      EBCDIC          / **/
+/*#define      EBCDIC          / **/
 
 /* ARCHLIB:
  *     This variable, if defined, holds the name of the directory in
  */
 #define BIN "c:\\perl\\bin"    /**/
 #define BIN_EXP "c:\\perl\\bin"        /**/
-#define PERL_RELOCATABLE_INC "undef"           /**/
+#define PERL_RELOCATABLE_INC "undef"           /**/
 
 /* PERL_INC_VERSION_LIST:
  *     This variable specifies the list of subdirectories in over
 
 /* INSTALL_USR_BIN_PERL:
  *     This symbol, if defined, indicates that Perl is to be installed
- *     also as /usr/bin/perl.
+ *     also as /usr/bin/perl.
  */
 /*#define INSTALL_USR_BIN_PERL / **/
 
  *     feature tests from Configure are generally more reliable.
  */
 #define OSNAME "MSWin32"               /**/
-#define OSVERS "6.1"           /**/
+#define OSVERS "10.0.18363.1139"               /**/
 
 /* CAT2:
  *     This macro concatenates 2 tokens together.
  */
 #if 42 == 1
 #define CAT2(a,b)      a/**/b
-#undef STRINGIFY
 #define STRINGIFY(a)   "a"
 #endif
 #if 42 == 42
 #define PeRl_StGiFy(a) #a
 #define CAT2(a,b)      PeRl_CaTiFy(a,b)
 #define StGiFy(a)      PeRl_StGiFy(a)
-#undef STRINGIFY
 #define STRINGIFY(a)   PeRl_StGiFy(a)
 #endif
 #if 42 != 1 && 42 != 42
 /* CPPSTDIN:
  *     This symbol contains the first part of the string which will invoke
  *     the C preprocessor on the standard input and produce to standard
- *     output.  Typical value of "cc -E" or "/lib/cpp", but it can also
+ *     output.  Typical value of "cc -E" or "/lib/cpp", but it can also
  *     call a wrapper. See CPPRUN.
  */
 /* CPPMINUS:
  */
 #define HAS_ACCESS             /**/
 
-
-/* The HASATTRIBUTE_* defines are left undefined here because they vary from
- * one version of GCC to another.  Instead, they are defined on the basis of
- * the compiler version in <perl.h>.
- */
 /* HASATTRIBUTE_FORMAT:
  *     Can we handle GCC attribute for checking printf-style formats
  */
 /* HASATTRIBUTE_WARN_UNUSED_RESULT:
  *     Can we handle GCC attribute for warning on unused results
  */
+/* HASATTRIBUTE_ALWAYS_INLINE:
+ *     Can we handle GCC attribute for functions that should always be
+ *     inlined.
+ */
 /*#define HASATTRIBUTE_DEPRECATED      / **/
 /*#define HASATTRIBUTE_FORMAT  / **/
 /*#define PRINTF_FORMAT_NULL_OK        / **/
 /*#define HASATTRIBUTE_PURE    / **/
 /*#define HASATTRIBUTE_UNUSED  / **/
 /*#define HASATTRIBUTE_WARN_UNUSED_RESULT      / **/
+/*#define HASATTRIBUTE_ALWAYS_INLINE   / **/
 
 /* HAS_BACKTRACE:
  *     This symbol, if defined, indicates that the backtrace() routine is
  *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_BE
  *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_BE
  *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_LE
+ *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN
+ *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN
  *     LONG_DOUBLE_IS_VAX_H_FLOAT
  *     LONG_DOUBLE_IS_UNKNOWN_FORMAT
  *     It is only defined if the system supports long doubles.
  *     This symbol, if defined, indicates that the long double is
  *     the 128-bit VAX format H.
  */
-#define HAS_LDEXPL             /**/
+#define  HAS_LDEXPL            /**/
 #define HAS_LONG_DOUBLE                /**/
 #ifdef HAS_LONG_DOUBLE
-#define LONG_DOUBLESIZE 12             /**/
+#define LONG_DOUBLESIZE 16             /**/
 #define LONG_DOUBLEKIND 3              /**/
 #define LONG_DOUBLE_IS_DOUBLE                          0
 #define LONG_DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN  1
  *     available to exclusively create and open a uniquely named
  *     temporary file.
  */
-#if __MINGW64_VERSION_MAJOR >= 4
-#define HAS_MKSTEMP
-#endif
+/*#define HAS_MKSTEMP          / **/
 
 /* HAS_MMAP:
  *     This symbol, if defined, indicates that the mmap system call is
 /*#define HAS_MMAP             / **/
 #define Mmap_t void *  /**/
 
-/* HAS_MSG:
- *     This symbol, if defined, indicates that the entire msg*(2) library is
- *     supported (IPC mechanism based on message queues).
- */
-/*#define HAS_MSG              / **/
-
-/* HAS_SEM:
- *     This symbol, if defined, indicates that the entire sem*(2) library is
- *     supported.
- */
-/*#define HAS_SEM              / **/
-
 /* HAS_SETGRENT:
  *     This symbol, if defined, indicates that the setgrent routine is
  *     available for initializing sequential access of the group database.
  *     This symbol, if defined, indicates the availability of
  *     struct sockaddr_in6;
  */
+/* HAS_SOCKADDR_STORAGE:
+ *     This symbol, if defined, indicates the availability of
+ *     struct sockaddr_storage;
+ */
 /* HAS_SIN6_SCOPE_ID:
  *     This symbol, if defined, indicates that the struct sockaddr_in6
  *     structure has a member called sin6_scope_id.
 /*#define      HAS_SOCKETPAIR  / **/
 /*#define      HAS_SOCKADDR_SA_LEN     / **/
 /*#define      HAS_SOCKADDR_IN6        / **/
+#define        HAS_SOCKADDR_STORAGE    /**/
 #define        HAS_SIN6_SCOPE_ID       /**/
 /*#define      HAS_IP_MREQ     / **/
 /*#define      HAS_IP_MREQ_SOURCE      / **/
  *     st_blksize and st_blocks.
  */
 #ifndef USE_STAT_BLOCKS
-/*#define USE_STAT_BLOCKS      / **/
+/*#define USE_STAT_BLOCKS      / **/
 #endif
 
 /* HAS_SYS_ERRLIST:
  *     This symbol, if defined, indicates that the union semun is
  *     defined by including <sys/sem.h>.  If not, the user code
  *     probably needs to define it as:
- *     union semun {
+ *      union semun {
  *         int val;
  *         struct semid_ds *buf;
  *         unsigned short *array;
- *     }
+ *      }
  */
 /* USE_SEMCTL_SEMUN:
  *     This symbol, if defined, indicates that union semun is
 
 /* Free_t:
  *     This variable contains the return type of free().  It is usually
- * void, but occasionally int.
+ *     void, but occasionally int.
  */
 /* Malloc_t:
  *     This symbol is the type of pointer returned by malloc and realloc.
  *     This symbol, if defined, indicates that the atoll routine is
  *     available to convert strings into long longs.
  */
-/*#define HAS_ATOLL            / **/
+#define HAS_ATOLL              /**/
 
 /* HAS__FWALK:
  *     This symbol, if defined, indicates that the _fwalk system call is
  */
 /*#define HAS__FWALK           / **/
 
+/* HAS_ACCEPT4:
+ *     This symbol, if defined, indicates that the accept4 routine is
+ *     available to accept socket connections.
+ */
+/*#define HAS_ACCEPT4  / **/
+
 /* HAS_ACOSH:
  *     This symbol, if defined, indicates that the acosh routine is
  *     available to do the inverse hyperbolic cosine function.
 /*#define HAS_BUILTIN_EXPECT   / **/
 /*#define HAS_BUILTIN_CHOOSE_EXPR      / **/
 
+/* HAS_BUILTIN_ADD_OVERFLOW:
+ *     This symbol, if defined, indicates that the compiler supports
+ *     __builtin_add_overflow for adding integers with overflow checks.
+ */
+/* HAS_BUILTIN_SUB_OVERFLOW:
+ *     This symbol, if defined, indicates that the compiler supports
+ *     __builtin_sub_overflow for subtracting integers with overflow checks.
+ */
+/* HAS_BUILTIN_MUL_OVERFLOW:
+ *     This symbol, if defined, indicates that the compiler supports
+ *     __builtin_mul_overflow for multiplying integers with overflow checks.
+ */
+/*#define HAS_BUILTIN_ADD_OVERFLOW     / **/
+/*#define HAS_BUILTIN_SUB_OVERFLOW     / **/
+/*#define HAS_BUILTIN_MUL_OVERFLOW     / **/
+
 /* HAS_C99_VARIADIC_MACROS:
  *     If defined, the compiler supports C99 variadic macros.
  */
  *     makes sense if you *have* dlsym, which we will presume is the
  *     case if you're using dl_dlopen.xs.
  */
-/*#define      DLSYM_NEEDS_UNDERSCORE  / **/
+/*#define      DLSYM_NEEDS_UNDERSCORE  / **/
+
+/* HAS_DUP3:
+ *     This symbol, if defined, indicates that the dup3 routine is
+ *     available to duplicate file descriptors.
+ */
+/*#define HAS_DUP3     / **/
 
 /* HAS_ERF:
  *     This symbol, if defined, indicates that the erf routine is
  *     available to classify doubles.  Available for example in HP-UX.
  *     The returned values are defined in <math.h> and are
  *
- *           FP_NORMAL     Normalized
- *           FP_ZERO       Zero
- *           FP_INFINITE   Infinity
- *           FP_SUBNORMAL  Denormalized
- *           FP_NAN        NaN
+ *       FP_NORMAL     Normalized
+ *       FP_ZERO       Zero
+ *       FP_INFINITE   Infinity
+ *       FP_SUBNORMAL  Denormalized
+ *       FP_NAN        NaN
  *
  */
 /* HAS_FP_CLASSIFY:
  *     This symbol, if defined, indicates that the fp_classify routine is
  *     available to classify doubles. The values are defined in <math.h>
  *
- *           FP_NORMAL     Normalized
- *           FP_ZERO       Zero
- *           FP_INFINITE   Infinity
- *           FP_SUBNORMAL  Denormalized
- *           FP_NAN        NaN
+ *       FP_NORMAL     Normalized
+ *       FP_ZERO       Zero
+ *       FP_INFINITE   Infinity
+ *       FP_SUBNORMAL  Denormalized
+ *       FP_NAN        NaN
  *
  */
 /*#define      HAS_FPCLASSIFY          / **/
 /* HAS_FPOS64_T:
  *     This symbol will be defined if the C compiler supports fpos64_t.
  */
-/*#define      HAS_FPOS64_T            / **/
+/*#define      HAS_FPOS64_T    / **/
 
 /* HAS_FREXPL:
  *     This symbol, if defined, indicates that the frexpl routine is
 /*#define HAS_INETPTON         / **/
 
 /* HAS_INT64_T:
- *     This symbol will defined if the C compiler supports int64_t.
- *     Usually the <inttypes.h> needs to be included, but sometimes
+ *     This symbol will defined if the C compiler supports int64_t.
+ *     Usually the <inttypes.h> needs to be included, but sometimes
  *     <sys/types.h> is enough.
  */
 /*#define     HAS_INT64_T               / **/
  *     j0l() function is available for Bessel functions of the first
  *     kind of the order zero, for long doubles.
  */
-#define HAS_J0         /**/
+#define        HAS_J0          /**/
 /*#define      HAS_J0L         / **/
 
 /* HAS_LC_MONETARY_2008:
  *     of significant digits in a long double precision number. Unlike
  *     for DBL_DIG, there's no good guess for LDBL_DIG if it is undefined.
  */
-#define HAS_LDBL_DIG   /**/
+#define HAS_LDBL_DIG   /**/
 
 /* HAS_LGAMMA:
  *     This symbol, if defined, indicates that the lgamma routine is
  *     This symbol, if defined, indicates that the memmem routine is
  *     available to return a pointer to the start of the first occurrence
  *     of a substring in a memory area (or NULL if not found).
+ *     In glibc, memmem is a GNU extension.  The function is visible in
+ *     libc, but the prototype is only visible if _GNU_SOURCE is #defined.
+ *     Thus we only define this if both the prototype and symbol are found.
  */
 /*#define HAS_MEMMEM           / **/
 
  */
 /*#define HAS_MKDTEMP          / **/
 
+/* HAS_MKOSTEMP:
+ *     This symbol, if defined, indicates that the mkostemp routine is
+ *     available to exclusively create and open a uniquely named (with a
+ *     suffix) temporary file.
+ */
+/*#define HAS_MKOSTEMP / **/
+
 /* HAS_MKSTEMPS:
  *     This symbol, if defined, indicates that the mkstemps routine is
  *     available to exclusively create and open a uniquely named
  *     to the program to supply one.
  */
 #define HAS_MODFL              /**/
-/*#define HAS_MODFL_PROTO              / **/
+#define HAS_MODFL_PROTO                /**/
 
 /* HAS_MPROTECT:
  *     This symbol, if defined, indicates that the mprotect system call is
  */
 #define HAS_NAN                /**/
 
+/* HAS_NANOSLEEP:
+ *     This symbol, if defined, indicates that the nanosleep
+ *     system call is available to sleep with 1E-9 sec accuracy.
+ */
+/*#define HAS_NANOSLEEP                / **/
+
 /* HAS_NEARBYINT:
  *     This symbol, if defined, indicates that the nearbyint routine is
  *     available to return the integral value closest to (according to
  *     This symbol, if defined, indicates that the uselocale routine is
  *     available to set the current locale for the calling thread.
  */
+/* HAS_DUPLOCALE:
+ *     This symbol, if defined, indicates that the duplocale routine is
+ *     available to duplicate a locale object.
+ */
 /* HAS_QUERYLOCALE:
  *     This symbol, if defined, indicates that the querylocale routine is
  *     available to return the name of the locale for a category mask.
 /*#define      HAS_NEWLOCALE   / **/
 /*#define      HAS_FREELOCALE  / **/
 /*#define      HAS_USELOCALE   / **/
+/*#define      HAS_DUPLOCALE   / **/
 /*#define      HAS_QUERYLOCALE / **/
 /*#define      I_XLOCALE               / **/
 
 /* HAS_OFF64_T:
  *     This symbol will be defined if the C compiler supports off64_t.
  */
-/*#define      HAS_OFF64_T             / **/
+/*#define      HAS_OFF64_T             / **/
+
+/* HAS_PIPE2:
+ *     This symbol, if defined, indicates that the pipe2 routine is
+ *     available to create an inter-process channel.
+ */
+/*#define HAS_PIPE2            / **/
 
 /* HAS_PRCTL:
  *     This symbol, if defined, indicates that the prctl routine is
 /* HAS_PTRDIFF_T:
  *     This symbol will be defined if the C compiler supports ptrdiff_t.
  */
-#define        HAS_PTRDIFF_T                   /**/
+#define        HAS_PTRDIFF_T           /**/
 
 /* HAS_READV:
  *     This symbol, if defined, indicates that the readv routine is
  */
 /*#define HAS_SETITIMER                / **/
 
+/* HAS_SETLOCALE:
+ *     This symbol, if defined, indicates that the setlocale routine is
+ *     available to handle locale-specific ctype implementations.
+ */
+/* SETLOCALE_ACCEPTS_ANY_LOCALE_NAME:
+ *     This symbol, if defined, indicates that the setlocale routine is
+ *     available and it accepts any input locale name as valid.
+ */
+#define HAS_SETLOCALE  /**/
+/*#define SETLOCALE_ACCEPTS_ANY_LOCALE_NAME    / **/
+
 /* HAS_SETPROCTITLE:
  *     This symbol, if defined, indicates that the setproctitle routine is
  *     available to set process title.
  */
 /*#define HAS_STRLCPY          / **/
 
+/* HAS_STRNLEN:
+ *     This symbol, if defined, indicates that the strnlen () routine is
+ *     available to check the length of a string up to a maximum.
+ */
+/*#define HAS_STRNLEN          / **/
+
 /* HAS_STRTOLD:
  *     This symbol, if defined, indicates that the strtold routine is
  *     available to convert strings to long doubles.
  *     This symbol, if defined, indicates that the strtoll routine is
  *     available to convert strings to long longs.
  */
-/*#define HAS_STRTOLL          / **/
+#define HAS_STRTOLL            /**/
 
 /* HAS_STRTOQ:
  *     This symbol, if defined, indicates that the strtoq routine is
  *     This symbol, if defined, indicates that the strtoull routine is
  *     available to convert strings to unsigned long longs.
  */
-/*#define HAS_STRTOULL         / **/
+#define HAS_STRTOULL           /**/
 
 /* HAS_STRTOUQ:
  *     This symbol, if defined, indicates that the strtouq routine is
  */
 /*#define HAS_TIMEGM           / **/
 
+/* HAS_TOWLOWER:
+ *     This symbol, if defined, indicates that the towlower () routine is
+ *     available to do case conversion.
+ */
+/*#define HAS_TOWLOWER         / **/
+
+/* HAS_TOWUPPER:
+ *     This symbol, if defined, indicates that the towupper () routine is
+ *     available to do case conversion.
+ */
+/*#define HAS_TOWUPPER         / **/
+
 /* HAS_TRUNC:
  *     This symbol, if defined, indicates that the trunc routine is
  *     available to round doubles towards zero.
  */
 #define DEFAULT_INC_EXCLUDES_DOT       /**/
 
+/* USE_STRICT_BY_DEFAULT:
+ *     This symbol, if defined, enables additional defaults.
+ *     At this time it only enables implicit strict by default.
+ */
+/*#define USE_STRICT_BY_DEFAULT        / * use strict by default */
+
 /* USE_DYNAMIC_LOADING:
  *     This symbol, if defined, indicates that dynamic loading of
  *     some sort is available.
  *     Note that if fflushNULL is defined, fflushall will not
  *     even be probed for and will be left undefined.
  */
-#define        FFLUSH_NULL             /**/
-/*#define      FFLUSH_ALL              / **/
+#define        FFLUSH_NULL             /**/
+/*#define      FFLUSH_ALL              / **/
 
 /* I_BFD:
  *     This symbol, if defined, indicates that <bfd.h> exists and
  *     For DB version 1 this is always 0.
  */
 #define DB_Hash_t      int             /**/
-#define DB_Prefix_t    int     /**/
-#define DB_VERSION_MAJOR_CFG   0       /**/
-#define DB_VERSION_MINOR_CFG   0       /**/
-#define DB_VERSION_PATCH_CFG   0       /**/
+#define DB_Prefix_t    int             /**/
+#define DB_VERSION_MAJOR_CFG   0       /**/
+#define DB_VERSION_MINOR_CFG   0       /**/
+#define DB_VERSION_PATCH_CFG   0       /**/
 
 /* I_FENV:
  *     This symbol, if defined, indicates to the C program that it should
 /*#define      I_IEEEFP                / **/
 
 /* I_INTTYPES:
- *     This symbol, if defined, indicates to the C program that it should
- *     include <inttypes.h>.
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <inttypes.h>.
  */
 /*#define   I_INTTYPES                / **/
 
 /*#define      I_MNTENT                / **/
 
 /* I_NETINET_TCP:
- *     This symbol, if defined, indicates to the C program that it should
- *     include <netinet/tcp.h>.
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <netinet/tcp.h>.
  */
 /*#define   I_NETINET_TCP                / **/
 
  */
 /*#define      I_USTAT         / **/
 
+/* I_WCHAR:
+ *     This symbol, if defined, indicates to the C program that <wchar.h>
+ *     is available for inclusion
+ */
+/*#define   I_WCHAR    / **/
+
+/* I_WCTYPE:
+ *     This symbol, if defined, indicates that <wctype.h> exists.
+ */
+/*#define      I_WCTYPE                / **/
+
 /* DOUBLEINFBYTES:
  *     This symbol, if defined, is a comma-separated list of
  *     hexadecimal bytes for the double precision infinity.
  */
 #define DOUBLEINFBYTES  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f         /**/
 #define DOUBLENANBYTES  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f         /**/
-#define LONGDBLINFBYTES 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x7f, 0x00, 0x00         /**/
-#define LONGDBLNANBYTES 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x00, 0x00         /**/
+#define LONGDBLINFBYTES 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00         /**/
+#define LONGDBLNANBYTES 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00         /**/
 
 /* PERL_PRIfldbl:
  *     This symbol, if defined, contains the string used by stdio to
  *     This symbol, if defined, indicates that a variable of type NVTYPE
  *     stores 0.0 in memory as all bits zero.
  */
-#define        IVTYPE          long            /**/
-#define        UVTYPE          unsigned long           /**/
+#define        IVTYPE          long long               /**/
+#define        UVTYPE          unsigned long long              /**/
 #define        I8TYPE          char            /**/
 #define        U8TYPE          unsigned char           /**/
 #define        I16TYPE         short   /**/
 #define        U64TYPE         unsigned long long      /**/
 #endif
 #define        NVTYPE          double          /**/
-#define        IVSIZE          4               /**/
-#define        UVSIZE          4               /**/
+#define        IVSIZE          8               /**/
+#define        UVSIZE          8               /**/
 #define        I8SIZE          1               /**/
 #define        U8SIZE          1               /**/
 #define        I16SIZE         2       /**/
 #define        U64SIZE         8       /**/
 #endif
 #define        NVSIZE          8               /**/
-#define        NV_PRESERVES_UV
-#define        NV_PRESERVES_UV_BITS    32
-#define        NV_OVERFLOWS_INTEGERS_AT        256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0
+#undef NV_PRESERVES_UV
+#define        NV_PRESERVES_UV_BITS    53
+#define        NV_OVERFLOWS_INTEGERS_AT        (256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0)
 #define        NV_ZERO_IS_ALLBITS_ZERO
 #if UVSIZE == 8
 #   ifdef BYTEORDER
  *     This symbol defines the format string used for printing a Perl NV
  *     using %g-ish floating point format.
  */
-#define        IVdf            "ld"            /**/
-#define        UVuf            "lu"            /**/
-#define        UVof            "lo"            /**/
-#define        UVxf            "lx"            /**/
-#define        UVXf            "lX"            /**/
+#define        IVdf            "I64d"          /**/
+#define        UVuf            "I64u"          /**/
+#define        UVof            "I64o"          /**/
+#define        UVxf            "I64x"          /**/
+#define        UVXf            "I64X"          /**/
 #define        NVef            "e"             /**/
 #define        NVff            "f"             /**/
 #define        NVgf            "g"             /**/
  *     is either n or 32*ceil(n/32), especially many little-endians do
  *     the latter.  This is only useful if you have select(), naturally.
  */
-#define SELECT_MIN_BITS        32      /**/
+#define SELECT_MIN_BITS        32      /**/
 
 /* ST_INO_SIZE:
  *     This variable contains the size of struct stat's st_ino in bytes.
  *     1 for unsigned, -1 for signed.
  */
 #define ST_INO_SIGN 1  /* st_ino sign */
-#define ST_INO_SIZE 4  /* st_ino size */
+#define ST_INO_SIZE 8  /* st_ino size */
 
 /* STARTPERL:
  *     This variable contains the string to put in front of a perl
  *     you may need at least to reboot your OS to 64-bit mode.
  */
 #ifndef USE_64_BIT_INT
-/*#define      USE_64_BIT_INT          / **/
+#define        USE_64_BIT_INT          /**/
 #endif
 #ifndef USE_64_BIT_ALL
 /*#define      USE_64_BIT_ALL          / **/
 /* USE_KERN_PROC_PATHNAME:
  *     This symbol, if defined, indicates that we can use sysctl with
  *     KERN_PROC_PATHNAME to get a full path for the executable, and hence
- *     convert $^X to an absolute path.
+ *     convert $^X to an absolute path.
  */
 /*#define USE_KERN_PROC_PATHNAME       / **/
 
  *     is defined, and 'int *' otherwise.  This is only useful if you
  *     have select(), of course.
  */
-#define Select_fd_set_t        Perl_fd_set *   /**/
+#define Select_fd_set_t        Perl_fd_set *   /**/
 
 /* Sock_size_t:
  *     This symbol holds the type used for the size argument of
  *     where library files may be held under a private library, for
  *     instance.
  */
-#define ARCHNAME "MSWin32-x86-perlio"          /**/
+#define ARCHNAME "MSWin32-x64-perlio"          /**/
 
 /* HAS_ASCTIME_R:
  *     This symbol, if defined, indicates that the asctime_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_asctime_r
  *     is defined.
  */
-/*#define HAS_ASCTIME_R           / **/
-#define ASCTIME_R_PROTO 0         /**/
+/*#define HAS_ASCTIME_R        / **/
+#define ASCTIME_R_PROTO 0      /**/
 
 /* HAS_CRYPT_R:
  *     This symbol, if defined, indicates that the crypt_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_crypt_r
  *     is defined.
  */
-/*#define HAS_CRYPT_R     / **/
-#define CRYPT_R_PROTO 0           /**/
+/*#define HAS_CRYPT_R  / **/
+#define CRYPT_R_PROTO 0        /**/
 
 /* HAS_CTERMID_R:
  *     This symbol, if defined, indicates that the ctermid_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_ctermid_r
  *     is defined.
  */
-/*#define HAS_CTERMID_R           / **/
-#define CTERMID_R_PROTO 0         /**/
+/*#define HAS_CTERMID_R        / **/
+#define CTERMID_R_PROTO 0      /**/
 
 /* HAS_CTIME_R:
  *     This symbol, if defined, indicates that the ctime_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_ctime_r
  *     is defined.
  */
-/*#define HAS_CTIME_R     / **/
-#define CTIME_R_PROTO 0           /**/
+/*#define HAS_CTIME_R  / **/
+#define CTIME_R_PROTO 0        /**/
 
 /* HAS_DRAND48_R:
  *     This symbol, if defined, indicates that the drand48_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_drand48_r
  *     is defined.
  */
-/*#define HAS_DRAND48_R           / **/
-#define DRAND48_R_PROTO 0         /**/
+/*#define HAS_DRAND48_R        / **/
+#define DRAND48_R_PROTO 0      /**/
 
 /* HAS_ENDGRENT_R:
  *     This symbol, if defined, indicates that the endgrent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_endgrent_r
  *     is defined.
  */
-/*#define HAS_ENDGRENT_R          / **/
-#define ENDGRENT_R_PROTO 0        /**/
+/*#define HAS_ENDGRENT_R       / **/
+#define ENDGRENT_R_PROTO 0     /**/
 
 /* HAS_ENDHOSTENT_R:
  *     This symbol, if defined, indicates that the endhostent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_endhostent_r
  *     is defined.
  */
-/*#define HAS_ENDHOSTENT_R        / **/
-#define ENDHOSTENT_R_PROTO 0      /**/
+/*#define HAS_ENDHOSTENT_R     / **/
+#define ENDHOSTENT_R_PROTO 0   /**/
 
 /* HAS_ENDNETENT_R:
  *     This symbol, if defined, indicates that the endnetent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_endnetent_r
  *     is defined.
  */
-/*#define HAS_ENDNETENT_R         / **/
-#define ENDNETENT_R_PROTO 0       /**/
+/*#define HAS_ENDNETENT_R      / **/
+#define ENDNETENT_R_PROTO 0    /**/
 
 /* HAS_ENDPROTOENT_R:
  *     This symbol, if defined, indicates that the endprotoent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_endprotoent_r
  *     is defined.
  */
-/*#define HAS_ENDPROTOENT_R       / **/
-#define ENDPROTOENT_R_PROTO 0     /**/
+/*#define HAS_ENDPROTOENT_R    / **/
+#define ENDPROTOENT_R_PROTO 0  /**/
 
 /* HAS_ENDPWENT_R:
  *     This symbol, if defined, indicates that the endpwent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_endpwent_r
  *     is defined.
  */
-/*#define HAS_ENDPWENT_R          / **/
-#define ENDPWENT_R_PROTO 0        /**/
+/*#define HAS_ENDPWENT_R       / **/
+#define ENDPWENT_R_PROTO 0     /**/
 
 /* HAS_ENDSERVENT_R:
  *     This symbol, if defined, indicates that the endservent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_endservent_r
  *     is defined.
  */
-/*#define HAS_ENDSERVENT_R        / **/
-#define ENDSERVENT_R_PROTO 0      /**/
+/*#define HAS_ENDSERVENT_R     / **/
+#define ENDSERVENT_R_PROTO 0   /**/
 
 /* HAS_GETGRENT_R:
  *     This symbol, if defined, indicates that the getgrent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getgrent_r
  *     is defined.
  */
-/*#define HAS_GETGRENT_R          / **/
-#define GETGRENT_R_PROTO 0        /**/
+/*#define HAS_GETGRENT_R       / **/
+#define GETGRENT_R_PROTO 0     /**/
 
 /* HAS_GETGRGID_R:
  *     This symbol, if defined, indicates that the getgrgid_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getgrgid_r
  *     is defined.
  */
-/*#define HAS_GETGRGID_R          / **/
-#define GETGRGID_R_PROTO 0        /**/
+/*#define HAS_GETGRGID_R       / **/
+#define GETGRGID_R_PROTO 0     /**/
 
 /* HAS_GETGRNAM_R:
  *     This symbol, if defined, indicates that the getgrnam_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getgrnam_r
  *     is defined.
  */
-/*#define HAS_GETGRNAM_R          / **/
-#define GETGRNAM_R_PROTO 0        /**/
+/*#define HAS_GETGRNAM_R       / **/
+#define GETGRNAM_R_PROTO 0     /**/
 
 /* HAS_GETHOSTBYADDR_R:
  *     This symbol, if defined, indicates that the gethostbyaddr_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_gethostbyaddr_r
  *     is defined.
  */
-/*#define HAS_GETHOSTBYADDR_R     / **/
-#define GETHOSTBYADDR_R_PROTO 0           /**/
+/*#define HAS_GETHOSTBYADDR_R  / **/
+#define GETHOSTBYADDR_R_PROTO 0        /**/
 
 /* HAS_GETHOSTBYNAME_R:
  *     This symbol, if defined, indicates that the gethostbyname_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_gethostbyname_r
  *     is defined.
  */
-/*#define HAS_GETHOSTBYNAME_R     / **/
-#define GETHOSTBYNAME_R_PROTO 0           /**/
+/*#define HAS_GETHOSTBYNAME_R  / **/
+#define GETHOSTBYNAME_R_PROTO 0        /**/
 
 /* HAS_GETHOSTENT_R:
  *     This symbol, if defined, indicates that the gethostent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_gethostent_r
  *     is defined.
  */
-/*#define HAS_GETHOSTENT_R        / **/
-#define GETHOSTENT_R_PROTO 0      /**/
+/*#define HAS_GETHOSTENT_R     / **/
+#define GETHOSTENT_R_PROTO 0   /**/
 
 /* HAS_GETLOGIN_R:
  *     This symbol, if defined, indicates that the getlogin_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getlogin_r
  *     is defined.
  */
-/*#define HAS_GETLOGIN_R          / **/
-#define GETLOGIN_R_PROTO 0        /**/
+/*#define HAS_GETLOGIN_R       / **/
+#define GETLOGIN_R_PROTO 0     /**/
 
 /* HAS_GETNETBYADDR_R:
  *     This symbol, if defined, indicates that the getnetbyaddr_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getnetbyaddr_r
  *     is defined.
  */
-/*#define HAS_GETNETBYADDR_R      / **/
-#define GETNETBYADDR_R_PROTO 0    /**/
+/*#define HAS_GETNETBYADDR_R   / **/
+#define GETNETBYADDR_R_PROTO 0 /**/
 
 /* HAS_GETNETBYNAME_R:
  *     This symbol, if defined, indicates that the getnetbyname_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getnetbyname_r
  *     is defined.
  */
-/*#define HAS_GETNETBYNAME_R      / **/
-#define GETNETBYNAME_R_PROTO 0    /**/
+/*#define HAS_GETNETBYNAME_R   / **/
+#define GETNETBYNAME_R_PROTO 0 /**/
 
 /* HAS_GETNETENT_R:
  *     This symbol, if defined, indicates that the getnetent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getnetent_r
  *     is defined.
  */
-/*#define HAS_GETNETENT_R         / **/
-#define GETNETENT_R_PROTO 0       /**/
+/*#define HAS_GETNETENT_R      / **/
+#define GETNETENT_R_PROTO 0    /**/
 
 /* HAS_GETPROTOBYNAME_R:
  *     This symbol, if defined, indicates that the getprotobyname_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getprotobyname_r
  *     is defined.
  */
-/*#define HAS_GETPROTOBYNAME_R    / **/
-#define GETPROTOBYNAME_R_PROTO 0          /**/
+/*#define HAS_GETPROTOBYNAME_R / **/
+#define GETPROTOBYNAME_R_PROTO 0       /**/
 
 /* HAS_GETPROTOBYNUMBER_R:
  *     This symbol, if defined, indicates that the getprotobynumber_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getprotobynumber_r
  *     is defined.
  */
-/*#define HAS_GETPROTOBYNUMBER_R          / **/
-#define GETPROTOBYNUMBER_R_PROTO 0        /**/
+/*#define HAS_GETPROTOBYNUMBER_R       / **/
+#define GETPROTOBYNUMBER_R_PROTO 0     /**/
 
 /* HAS_GETPROTOENT_R:
  *     This symbol, if defined, indicates that the getprotoent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getprotoent_r
  *     is defined.
  */
-/*#define HAS_GETPROTOENT_R       / **/
-#define GETPROTOENT_R_PROTO 0     /**/
+/*#define HAS_GETPROTOENT_R    / **/
+#define GETPROTOENT_R_PROTO 0  /**/
 
 /* HAS_GETPWENT_R:
  *     This symbol, if defined, indicates that the getpwent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getpwent_r
  *     is defined.
  */
-/*#define HAS_GETPWENT_R          / **/
-#define GETPWENT_R_PROTO 0        /**/
+/*#define HAS_GETPWENT_R       / **/
+#define GETPWENT_R_PROTO 0     /**/
 
 /* HAS_GETPWNAM_R:
  *     This symbol, if defined, indicates that the getpwnam_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getpwnam_r
  *     is defined.
  */
-/*#define HAS_GETPWNAM_R          / **/
-#define GETPWNAM_R_PROTO 0        /**/
+/*#define HAS_GETPWNAM_R       / **/
+#define GETPWNAM_R_PROTO 0     /**/
 
 /* HAS_GETPWUID_R:
  *     This symbol, if defined, indicates that the getpwuid_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getpwuid_r
  *     is defined.
  */
-/*#define HAS_GETPWUID_R          / **/
-#define GETPWUID_R_PROTO 0        /**/
+/*#define HAS_GETPWUID_R       / **/
+#define GETPWUID_R_PROTO 0     /**/
 
 /* HAS_GETSERVBYNAME_R:
  *     This symbol, if defined, indicates that the getservbyname_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getservbyname_r
  *     is defined.
  */
-/*#define HAS_GETSERVBYNAME_R     / **/
-#define GETSERVBYNAME_R_PROTO 0           /**/
+/*#define HAS_GETSERVBYNAME_R  / **/
+#define GETSERVBYNAME_R_PROTO 0        /**/
 
 /* HAS_GETSERVBYPORT_R:
  *     This symbol, if defined, indicates that the getservbyport_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getservbyport_r
  *     is defined.
  */
-/*#define HAS_GETSERVBYPORT_R     / **/
-#define GETSERVBYPORT_R_PROTO 0           /**/
+/*#define HAS_GETSERVBYPORT_R  / **/
+#define GETSERVBYPORT_R_PROTO 0        /**/
 
 /* HAS_GETSERVENT_R:
  *     This symbol, if defined, indicates that the getservent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getservent_r
  *     is defined.
  */
-/*#define HAS_GETSERVENT_R        / **/
-#define GETSERVENT_R_PROTO 0      /**/
+/*#define HAS_GETSERVENT_R     / **/
+#define GETSERVENT_R_PROTO 0   /**/
 
 /* HAS_GETSPNAM_R:
  *     This symbol, if defined, indicates that the getspnam_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getspnam_r
  *     is defined.
  */
-/*#define HAS_GETSPNAM_R          / **/
-#define GETSPNAM_R_PROTO 0        /**/
+/*#define HAS_GETSPNAM_R       / **/
+#define GETSPNAM_R_PROTO 0     /**/
 
 /* HAS_GMTIME_R:
  *     This symbol, if defined, indicates that the gmtime_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_gmtime_r
  *     is defined.
  */
-/*#define HAS_GMTIME_R    / **/
-#define GMTIME_R_PROTO 0          /**/
+/*#define HAS_GMTIME_R / **/
+#define GMTIME_R_PROTO 0       /**/
+
+/* HAS_LOCALECONV_L:
+ *     This symbol, if defined, indicates that the localeconv_l routine is
+ *     available to query certain information about a locale.
+ */
+/*#define HAS_LOCALECONV_L             / **/
 
 /* HAS_LOCALTIME_R:
  *     This symbol, if defined, indicates that the localtime_r routine
 #define L_R_TZSET
 #endif
 
+/* L_R_TZSET:
+ *     If localtime_r() needs tzset, it is defined in this define
+ */
 /* LOCALTIME_R_PROTO:
  *     This symbol encodes the prototype of localtime_r.
  *     It is zero if d_localtime_r is undef, and one of the
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_localtime_r
  *     is defined.
  */
-/*#define HAS_LOCALTIME_R         / **/
-#define LOCALTIME_R_PROTO 0       /**/
+/*#define HAS_LOCALTIME_R      / **/
+#define LOCALTIME_R_PROTO 0    /**/
+
+/* HAS_MBRLEN:
+ *     This symbol, if defined, indicates that the mbrlen routine is
+ *     available to get the length of multi-byte character strings.
+ */
+/*#define HAS_MBRLEN   / **/
+
+/* HAS_MBRTOWC:
+ *     This symbol, if defined, indicates that the mbrtowc routine is
+ *     available to convert a multi-byte character into a wide character.
+ */
+/*#define HAS_MBRTOWC  / **/
+
+/* HAS_THREAD_SAFE_NL_LANGINFO_L:
+ *     This symbol, when defined, indicates presence of the nl_langinfo_l()
+ *     function, and that it is thread-safe.
+ */
+/*#define HAS_THREAD_SAFE_NL_LANGINFO_L        / **/
 
 /* OLD_PTHREAD_CREATE_JOINABLE:
  *     This symbol, if defined, indicates how to create pthread
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_random_r
  *     is defined.
  */
-/*#define HAS_RANDOM_R    / **/
-#define RANDOM_R_PROTO 0          /**/
+/*#define HAS_RANDOM_R / **/
+#define RANDOM_R_PROTO 0       /**/
 
 /* HAS_READDIR64_R:
  *     This symbol, if defined, indicates that the readdir64_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_readdir64_r
  *     is defined.
  */
-/*#define HAS_READDIR64_R         / **/
-#define READDIR64_R_PROTO 0       /**/
+/*#define HAS_READDIR64_R      / **/
+#define READDIR64_R_PROTO 0    /**/
 
 /* HAS_READDIR_R:
  *     This symbol, if defined, indicates that the readdir_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_readdir_r
  *     is defined.
  */
-/*#define HAS_READDIR_R           / **/
-#define READDIR_R_PROTO 0         /**/
+/*#define HAS_READDIR_R        / **/
+#define READDIR_R_PROTO 0      /**/
 
 /* HAS_SETGRENT_R:
  *     This symbol, if defined, indicates that the setgrent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_setgrent_r
  *     is defined.
  */
-/*#define HAS_SETGRENT_R          / **/
-#define SETGRENT_R_PROTO 0        /**/
+/*#define HAS_SETGRENT_R       / **/
+#define SETGRENT_R_PROTO 0     /**/
 
 /* HAS_SETHOSTENT_R:
  *     This symbol, if defined, indicates that the sethostent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_sethostent_r
  *     is defined.
  */
-/*#define HAS_SETHOSTENT_R        / **/
-#define SETHOSTENT_R_PROTO 0      /**/
+/*#define HAS_SETHOSTENT_R     / **/
+#define SETHOSTENT_R_PROTO 0   /**/
 
 /* HAS_SETLOCALE_R:
  *     This symbol, if defined, indicates that the setlocale_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_setlocale_r
  *     is defined.
  */
-/*#define HAS_SETLOCALE_R         / **/
-#define SETLOCALE_R_PROTO 0       /**/
+/*#define HAS_SETLOCALE_R      / **/
+#define SETLOCALE_R_PROTO 0    /**/
 
 /* HAS_SETNETENT_R:
  *     This symbol, if defined, indicates that the setnetent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_setnetent_r
  *     is defined.
  */
-/*#define HAS_SETNETENT_R         / **/
-#define SETNETENT_R_PROTO 0       /**/
+/*#define HAS_SETNETENT_R      / **/
+#define SETNETENT_R_PROTO 0    /**/
 
 /* HAS_SETPROTOENT_R:
  *     This symbol, if defined, indicates that the setprotoent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_setprotoent_r
  *     is defined.
  */
-/*#define HAS_SETPROTOENT_R       / **/
-#define SETPROTOENT_R_PROTO 0     /**/
+/*#define HAS_SETPROTOENT_R    / **/
+#define SETPROTOENT_R_PROTO 0  /**/
 
 /* HAS_SETPWENT_R:
  *     This symbol, if defined, indicates that the setpwent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_setpwent_r
  *     is defined.
  */
-/*#define HAS_SETPWENT_R          / **/
-#define SETPWENT_R_PROTO 0        /**/
+/*#define HAS_SETPWENT_R       / **/
+#define SETPWENT_R_PROTO 0     /**/
 
 /* HAS_SETSERVENT_R:
  *     This symbol, if defined, indicates that the setservent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_setservent_r
  *     is defined.
  */
-/*#define HAS_SETSERVENT_R        / **/
-#define SETSERVENT_R_PROTO 0      /**/
+/*#define HAS_SETSERVENT_R     / **/
+#define SETSERVENT_R_PROTO 0   /**/
 
 /* HAS_SRAND48_R:
  *     This symbol, if defined, indicates that the srand48_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_srand48_r
  *     is defined.
  */
-/*#define HAS_SRAND48_R           / **/
-#define SRAND48_R_PROTO 0         /**/
+/*#define HAS_SRAND48_R        / **/
+#define SRAND48_R_PROTO 0      /**/
 
 /* HAS_SRANDOM_R:
  *     This symbol, if defined, indicates that the srandom_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_srandom_r
  *     is defined.
  */
-/*#define HAS_SRANDOM_R           / **/
-#define SRANDOM_R_PROTO 0         /**/
+/*#define HAS_SRANDOM_R        / **/
+#define SRANDOM_R_PROTO 0      /**/
 
 /* HAS_STRERROR_R:
  *     This symbol, if defined, indicates that the strerror_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_strerror_r
  *     is defined.
  */
-/*#define HAS_STRERROR_R          / **/
-#define STRERROR_R_PROTO 0        /**/
+/*#define HAS_STRERROR_R       / **/
+#define STRERROR_R_PROTO 0     /**/
+
+/* HAS_STRTOD_L:
+ *     This symbol, if defined, indicates that the strtod_l routine is
+ *     available to convert strings to long doubles.
+ */
+/*#define HAS_STRTOD_L         / **/
+
+/* HAS_STRTOLD_L:
+ *     This symbol, if defined, indicates that the strtold_l routine is
+ *     available to convert strings to long doubles.
+ */
+/*#define HAS_STRTOLD_L                / **/
 
 /* HAS_TMPNAM_R:
  *     This symbol, if defined, indicates that the tmpnam_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_tmpnam_r
  *     is defined.
  */
-/*#define HAS_TMPNAM_R    / **/
-#define TMPNAM_R_PROTO 0          /**/
+/*#define HAS_TMPNAM_R / **/
+#define TMPNAM_R_PROTO 0       /**/
 
 /* HAS_TTYNAME_R:
  *     This symbol, if defined, indicates that the ttyname_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_ttyname_r
  *     is defined.
  */
-/*#define HAS_TTYNAME_R           / **/
-#define TTYNAME_R_PROTO 0         /**/
+/*#define HAS_TTYNAME_R        / **/
+#define TTYNAME_R_PROTO 0      /**/
+
+/* HAS_WCRTOMB:
+ *     This symbol, if defined, indicates that the wcrtomb routine is
+ *     available to convert a wide character into a multi-byte character.
+ */
+/*#define HAS_WCRTOMB  / **/
 
 /* I_MACH_CTHREADS:
- *     This symbol, if defined, indicates to the C program that it should
- *     include <mach/cthreads.h>.
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <mach/cthreads.h>.
  */
 /*#define   I_MACH_CTHREADS    / **/
 
 /* I_PTHREAD:
- *     This symbol, if defined, indicates to the C program that it should
- *     include <pthread.h>.
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <pthread.h>.
  */
 /*#define   I_PTHREAD  / **/
 
 /* HAS_TIMES:
  *     This symbol, if defined, indicates that the times() routine exists.
  *     Note that this became obsolete on some systems (SUNOS), which now
- * use getrusage(). It may be necessary to include <sys/times.h>.
+ *     use getrusage(). It may be necessary to include <sys/times.h>.
  */
 #define HAS_TIMES              /**/
 
 /* Size_t_size:
  *     This symbol holds the size of a Size_t in bytes.
  */
-#define Size_t_size 4          /**/
+#define Size_t_size 8          /**/
 
 /* Size_t:
  *     This symbol holds the type used to declare length parameters
index be0d90a..d067e1d 100644 (file)
@@ -9,8 +9,8 @@
 
 /* Package name      : perl5
  * Source directory  : 
- * Configuration time: Tue Oct 17 08:29:51 2017
- * Configured by     : shay
+ * Configuration time: Mon Oct 19 14:24:24 2020
+ * Configured by     : tony
  * Target system     : 
  */
 
  *     This symbol, if defined, indicates that the lstat routine is
  *     available to do file stats on symbolic links.
  */
-/*#define HAS_LSTAT            / **/
+#define HAS_LSTAT              /**/
 
 /* HAS_MBLEN:
  *     This symbol, if defined, indicates that the mblen routine is available
  */
 #define HAS_MKTIME             /**/
 
+/* HAS_MSG:
+ *     This symbol, if defined, indicates that the entire msg*(2) library is
+ *     supported (IPC mechanism based on message queues).
+ */
+/*#define HAS_MSG              / **/
+
 /* HAS_MSYNC:
  *     This symbol, if defined, indicates that the msync system call is
  *     available to synchronize a mapped file.
  *     This symbol, if defined, indicates that the readlink routine is
  *     available to read the value of a symbolic link.
  */
-/*#define HAS_READLINK         / **/
+#define HAS_READLINK           /**/
 
 /* HAS_REGCOMP:
  *     This symbol, if defined, indicates that the regcomp() routine is
  */
 #define HAS_SELECT     /**/
 
+/* HAS_SEM:
+ *     This symbol, if defined, indicates that the entire sem*(2) library is
+ *     supported.
+ */
+/*#define HAS_SEM              / **/
+
 /* HAS_SETEGID:
  *     This symbol, if defined, indicates that the setegid routine is available
  *     to change the effective gid of the current program.
  */
 /*#define HAS_SETLINEBUF               / **/
 
-/* HAS_SETLOCALE:
- *     This symbol, if defined, indicates that the setlocale routine is
- *     available to handle locale-specific ctype implementations.
- */
-#define HAS_SETLOCALE  /**/
-
 /* HAS_SETPGID:
  *     This symbol, if defined, indicates that the setpgid(pid, gpid)
  *     routine is available to set process group ID.
  *     This symbol, if defined, indicates that the symlink routine is available
  *     to create symbolic links.
  */
-/*#define HAS_SYMLINK  / **/
+#define HAS_SYMLINK    /**/
 
 /* HAS_SYSCALL:
  *     This symbol, if defined, indicates that the syscall routine is
 /*#define HAS_EACCESS          / **/
 
 /* I_SYS_ACCESS:
- *     This symbol, if defined, indicates to the C program that it should
- *     include <sys/access.h>.
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <sys/access.h>.
  */
 /*#define   I_SYS_ACCESS                / **/
 
 /* I_SYS_SECURITY:
- *     This symbol, if defined, indicates to the C program that it should
- *     include <sys/security.h>.
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <sys/security.h>.
  */
 /*#define   I_SYS_SECURITY     / **/
 
  *     This symbol contains the number of bytes required to align a
  *     double, or a long double when applicable. Usual values are 2,
  *     4 and 8. The default is eight, for safety.  For cross-compiling
- *     or multiarch support, Configure will set a minimum of 8.
+ *     or multiarch support, Configure will set a minimum of 8.
  */
 #define MEM_ALIGNBYTES 8
 
 #    endif
 #  endif
 #else
-#define BYTEORDER 0x1234       /* large digits for MSB */
+#define BYTEORDER 0x12345678   /* large digits for MSB */
 #endif
 
 /* CHARBITS:
  *     the GNU C library is being used.  A better check is to use
  *     the __GLIBC__ and __GLIBC_MINOR__ symbols supplied with glibc.
  */
-/*#define HAS_GNULIBC          / **/
+/*#define HAS_GNULIBC  / **/
 #if defined(HAS_GNULIBC) && !defined(_GNU_SOURCE)
 #   define _GNU_SOURCE
 #endif
  *     This symbol is defined if using the FILE_ptr macro as an lvalue
  *     to increase the pointer by n leaves File_cnt(fp) unchanged.
  */
-#define USE_STDIO_PTR  /**/
+#define USE_STDIO_PTR  /**/
 #ifdef USE_STDIO_PTR
-#define FILE_ptr(fp)   ((fp)->_ptr)
-#define STDIO_PTR_LVALUE               /**/
-#define FILE_cnt(fp)   ((fp)->_cnt)
-#define STDIO_CNT_LVALUE               /**/
+#define FILE_ptr(fp)   PERLIO_FILE_ptr(fp)
+#define STDIO_PTR_LVALUE               /**/
+#define FILE_cnt(fp)   PERLIO_FILE_cnt(fp)
+#define STDIO_CNT_LVALUE               /**/
 /*#define STDIO_PTR_LVAL_SETS_CNT      / **/
 #define STDIO_PTR_LVAL_NOCHANGE_CNT    /**/
 #endif
  *     structure pointed to its argument. This macro will always be defined
  *     if USE_STDIO_BASE is defined.
  */
-#define USE_STDIO_BASE         /**/
+#define USE_STDIO_BASE /**/
 #ifdef USE_STDIO_BASE
-#define FILE_base(fp)  ((fp)->_base)
-#define FILE_bufsiz(fp)        ((fp)->_cnt + (fp)->_ptr - (fp)->_base)
+#define FILE_base(fp)  PERLIO_FILE_base(fp)
+#define FILE_bufsiz(fp)        (PERLIO_FILE_cnt(fp) + PERLIO_FILE_ptr(fp) - PERLIO_FILE_base(fp))
 #endif
 
 /* DOUBLESIZE:
 #define DOUBLESIZE 8           /**/
 
 /* I_TIME:
- *     This symbol, if defined, indicates to the C program that it should
- *     include <time.h>.
+ *     This symbol is always defined, and indicates to the C program that
+ *     it should include <time.h>.
  */
 /* I_SYS_TIME:
  *     This symbol, if defined, indicates to the C program that it should
  *     the compiler supports (void *); otherwise it will be
  *     sizeof(char *).
  */
-#define PTRSIZE 4              /**/
+#define PTRSIZE 8              /**/
 
 /* Drand01:
  *     This macro is to be used to generate uniformly distributed
  *     to get any typedef'ed information.
  *     We will pick a type such that sizeof(SSize_t) == sizeof(Size_t).
  */
-#define SSize_t int     /* signed count of bytes */
+#define SSize_t __int64        /* signed count of bytes */
 
 /* EBCDIC:
  *     This symbol, if defined, indicates that this system uses
  *     EBCDIC encoding.
  */
-/*#define      EBCDIC          / **/
+/*#define      EBCDIC          / **/
 
 /* ARCHLIB:
  *     This variable, if defined, holds the name of the directory in
  */
 #define BIN "c:\\perl\\bin"    /**/
 #define BIN_EXP "c:\\perl\\bin"        /**/
-#define PERL_RELOCATABLE_INC "undef"           /**/
+#define PERL_RELOCATABLE_INC "undef"           /**/
 
 /* PERL_INC_VERSION_LIST:
  *     This variable specifies the list of subdirectories in over
 
 /* INSTALL_USR_BIN_PERL:
  *     This symbol, if defined, indicates that Perl is to be installed
- *     also as /usr/bin/perl.
+ *     also as /usr/bin/perl.
  */
 /*#define INSTALL_USR_BIN_PERL / **/
 
  *     feature tests from Configure are generally more reliable.
  */
 #define OSNAME "MSWin32"               /**/
-#define OSVERS "6.1"           /**/
+#define OSVERS "10.0.18363.1139"               /**/
 
 /* CAT2:
  *     This macro concatenates 2 tokens together.
 /* CPPSTDIN:
  *     This symbol contains the first part of the string which will invoke
  *     the C preprocessor on the standard input and produce to standard
- *     output.  Typical value of "cc -E" or "/lib/cpp", but it can also
+ *     output.  Typical value of "cc -E" or "/lib/cpp", but it can also
  *     call a wrapper. See CPPRUN.
  */
 /* CPPMINUS:
 /* HASATTRIBUTE_WARN_UNUSED_RESULT:
  *     Can we handle GCC attribute for warning on unused results
  */
+/* HASATTRIBUTE_ALWAYS_INLINE:
+ *     Can we handle GCC attribute for functions that should always be
+ *     inlined.
+ */
 /*#define HASATTRIBUTE_DEPRECATED      / **/
 /*#define HASATTRIBUTE_FORMAT  / **/
 /*#define PRINTF_FORMAT_NULL_OK        / **/
 /*#define HASATTRIBUTE_PURE    / **/
 /*#define HASATTRIBUTE_UNUSED  / **/
 /*#define HASATTRIBUTE_WARN_UNUSED_RESULT      / **/
+/*#define HASATTRIBUTE_ALWAYS_INLINE   / **/
 
 /* HAS_BACKTRACE:
  *     This symbol, if defined, indicates that the backtrace() routine is
  *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_BE
  *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_BE
  *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_LE
+ *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN
+ *     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN
  *     LONG_DOUBLE_IS_VAX_H_FLOAT
  *     LONG_DOUBLE_IS_UNKNOWN_FORMAT
  *     It is only defined if the system supports long doubles.
 /*#define HAS_MMAP             / **/
 #define Mmap_t void *  /**/
 
-/* HAS_MSG:
- *     This symbol, if defined, indicates that the entire msg*(2) library is
- *     supported (IPC mechanism based on message queues).
- */
-/*#define HAS_MSG              / **/
-
-/* HAS_SEM:
- *     This symbol, if defined, indicates that the entire sem*(2) library is
- *     supported.
- */
-/*#define HAS_SEM              / **/
-
 /* HAS_SETGRENT:
  *     This symbol, if defined, indicates that the setgrent routine is
  *     available for initializing sequential access of the group database.
  *     This symbol, if defined, indicates the availability of
  *     struct sockaddr_in6;
  */
+/* HAS_SOCKADDR_STORAGE:
+ *     This symbol, if defined, indicates the availability of
+ *     struct sockaddr_storage;
+ */
 /* HAS_SIN6_SCOPE_ID:
  *     This symbol, if defined, indicates that the struct sockaddr_in6
  *     structure has a member called sin6_scope_id.
 /*#define      HAS_SOCKETPAIR  / **/
 /*#define      HAS_SOCKADDR_SA_LEN     / **/
 /*#define      HAS_SOCKADDR_IN6        / **/
+#define        HAS_SOCKADDR_STORAGE    /**/
 #define        HAS_SIN6_SCOPE_ID       /**/
 /*#define      HAS_IP_MREQ     / **/
 /*#define      HAS_IP_MREQ_SOURCE      / **/
  *     st_blksize and st_blocks.
  */
 #ifndef USE_STAT_BLOCKS
-/*#define USE_STAT_BLOCKS      / **/
+/*#define USE_STAT_BLOCKS      / **/
 #endif
 
 /* HAS_SYS_ERRLIST:
  *     This symbol, if defined, indicates that the union semun is
  *     defined by including <sys/sem.h>.  If not, the user code
  *     probably needs to define it as:
- *     union semun {
+ *      union semun {
  *         int val;
  *         struct semid_ds *buf;
  *         unsigned short *array;
- *     }
+ *      }
  */
 /* USE_SEMCTL_SEMUN:
  *     This symbol, if defined, indicates that union semun is
 
 /* Free_t:
  *     This variable contains the return type of free().  It is usually
- * void, but occasionally int.
+ *     void, but occasionally int.
  */
 /* Malloc_t:
  *     This symbol is the type of pointer returned by malloc and realloc.
  *     This symbol, if defined, indicates that the atoll routine is
  *     available to convert strings into long longs.
  */
-/*#define HAS_ATOLL            / **/
+#define HAS_ATOLL              /**/
 
 /* HAS__FWALK:
  *     This symbol, if defined, indicates that the _fwalk system call is
  */
 /*#define HAS__FWALK           / **/
 
+/* HAS_ACCEPT4:
+ *     This symbol, if defined, indicates that the accept4 routine is
+ *     available to accept socket connections.
+ */
+/*#define HAS_ACCEPT4  / **/
+
 /* HAS_ACOSH:
  *     This symbol, if defined, indicates that the acosh routine is
  *     available to do the inverse hyperbolic cosine function.
 /*#define HAS_BUILTIN_EXPECT   / **/
 /*#define HAS_BUILTIN_CHOOSE_EXPR      / **/
 
+/* HAS_BUILTIN_ADD_OVERFLOW:
+ *     This symbol, if defined, indicates that the compiler supports
+ *     __builtin_add_overflow for adding integers with overflow checks.
+ */
+/* HAS_BUILTIN_SUB_OVERFLOW:
+ *     This symbol, if defined, indicates that the compiler supports
+ *     __builtin_sub_overflow for subtracting integers with overflow checks.
+ */
+/* HAS_BUILTIN_MUL_OVERFLOW:
+ *     This symbol, if defined, indicates that the compiler supports
+ *     __builtin_mul_overflow for multiplying integers with overflow checks.
+ */
+/*#define HAS_BUILTIN_ADD_OVERFLOW     / **/
+/*#define HAS_BUILTIN_SUB_OVERFLOW     / **/
+/*#define HAS_BUILTIN_MUL_OVERFLOW     / **/
+
 /* HAS_C99_VARIADIC_MACROS:
  *     If defined, the compiler supports C99 variadic macros.
  */
  *     makes sense if you *have* dlsym, which we will presume is the
  *     case if you're using dl_dlopen.xs.
  */
-/*#define      DLSYM_NEEDS_UNDERSCORE  / **/
+/*#define      DLSYM_NEEDS_UNDERSCORE  / **/
+
+/* HAS_DUP3:
+ *     This symbol, if defined, indicates that the dup3 routine is
+ *     available to duplicate file descriptors.
+ */
+/*#define HAS_DUP3     / **/
 
 /* HAS_ERF:
  *     This symbol, if defined, indicates that the erf routine is
  *     available to classify doubles.  Available for example in HP-UX.
  *     The returned values are defined in <math.h> and are
  *
- *           FP_NORMAL     Normalized
- *           FP_ZERO       Zero
- *           FP_INFINITE   Infinity
- *           FP_SUBNORMAL  Denormalized
- *           FP_NAN        NaN
+ *       FP_NORMAL     Normalized
+ *       FP_ZERO       Zero
+ *       FP_INFINITE   Infinity
+ *       FP_SUBNORMAL  Denormalized
+ *       FP_NAN        NaN
  *
  */
 /* HAS_FP_CLASSIFY:
  *     This symbol, if defined, indicates that the fp_classify routine is
  *     available to classify doubles. The values are defined in <math.h>
  *
- *           FP_NORMAL     Normalized
- *           FP_ZERO       Zero
- *           FP_INFINITE   Infinity
- *           FP_SUBNORMAL  Denormalized
- *           FP_NAN        NaN
+ *       FP_NORMAL     Normalized
+ *       FP_ZERO       Zero
+ *       FP_INFINITE   Infinity
+ *       FP_SUBNORMAL  Denormalized
+ *       FP_NAN        NaN
  *
  */
 /*#define      HAS_FPCLASSIFY          / **/
 /* HAS_FPOS64_T:
  *     This symbol will be defined if the C compiler supports fpos64_t.
  */
-/*#define      HAS_FPOS64_T            / **/
+/*#define      HAS_FPOS64_T    / **/
 
 /* HAS_FREXPL:
  *     This symbol, if defined, indicates that the frexpl routine is
 /*#define HAS_INETPTON         / **/
 
 /* HAS_INT64_T:
- *     This symbol will defined if the C compiler supports int64_t.
- *     Usually the <inttypes.h> needs to be included, but sometimes
+ *     This symbol will defined if the C compiler supports int64_t.
+ *     Usually the <inttypes.h> needs to be included, but sometimes
  *     <sys/types.h> is enough.
  */
 /*#define     HAS_INT64_T               / **/
  *     of significant digits in a long double precision number. Unlike
  *     for DBL_DIG, there's no good guess for LDBL_DIG if it is undefined.
  */
-#define HAS_LDBL_DIG   /**/
+#define HAS_LDBL_DIG   /**/
 
 /* HAS_LGAMMA:
  *     This symbol, if defined, indicates that the lgamma routine is
  *     This symbol, if defined, indicates that the memmem routine is
  *     available to return a pointer to the start of the first occurrence
  *     of a substring in a memory area (or NULL if not found).
+ *     In glibc, memmem is a GNU extension.  The function is visible in
+ *     libc, but the prototype is only visible if _GNU_SOURCE is #defined.
+ *     Thus we only define this if both the prototype and symbol are found.
  */
 /*#define HAS_MEMMEM           / **/
 
  */
 /*#define HAS_MKDTEMP          / **/
 
+/* HAS_MKOSTEMP:
+ *     This symbol, if defined, indicates that the mkostemp routine is
+ *     available to exclusively create and open a uniquely named (with a
+ *     suffix) temporary file.
+ */
+/*#define HAS_MKOSTEMP / **/
+
 /* HAS_MKSTEMPS:
  *     This symbol, if defined, indicates that the mkstemps routine is
  *     available to exclusively create and open a uniquely named
  */
 /*#define HAS_NAN              / **/
 
+/* HAS_NANOSLEEP:
+ *     This symbol, if defined, indicates that the nanosleep
+ *     system call is available to sleep with 1E-9 sec accuracy.
+ */
+/*#define HAS_NANOSLEEP                / **/
+
 /* HAS_NEARBYINT:
  *     This symbol, if defined, indicates that the nearbyint routine is
  *     available to return the integral value closest to (according to
  *     This symbol, if defined, indicates that the uselocale routine is
  *     available to set the current locale for the calling thread.
  */
+/* HAS_DUPLOCALE:
+ *     This symbol, if defined, indicates that the duplocale routine is
+ *     available to duplicate a locale object.
+ */
 /* HAS_QUERYLOCALE:
  *     This symbol, if defined, indicates that the querylocale routine is
  *     available to return the name of the locale for a category mask.
 /*#define      HAS_NEWLOCALE   / **/
 /*#define      HAS_FREELOCALE  / **/
 /*#define      HAS_USELOCALE   / **/
+/*#define      HAS_DUPLOCALE   / **/
 /*#define      HAS_QUERYLOCALE / **/
 /*#define      I_XLOCALE               / **/
 
 /* HAS_OFF64_T:
  *     This symbol will be defined if the C compiler supports off64_t.
  */
-/*#define      HAS_OFF64_T             / **/
+/*#define      HAS_OFF64_T             / **/
+
+/* HAS_PIPE2:
+ *     This symbol, if defined, indicates that the pipe2 routine is
+ *     available to create an inter-process channel.
+ */
+/*#define HAS_PIPE2            / **/
 
 /* HAS_PRCTL:
  *     This symbol, if defined, indicates that the prctl routine is
 /* HAS_PTRDIFF_T:
  *     This symbol will be defined if the C compiler supports ptrdiff_t.
  */
-#define        HAS_PTRDIFF_T                   /**/
+#define        HAS_PTRDIFF_T           /**/
 
 /* HAS_READV:
  *     This symbol, if defined, indicates that the readv routine is
  */
 /*#define HAS_SETITIMER                / **/
 
+/* HAS_SETLOCALE:
+ *     This symbol, if defined, indicates that the setlocale routine is
+ *     available to handle locale-specific ctype implementations.
+ */
+/* SETLOCALE_ACCEPTS_ANY_LOCALE_NAME:
+ *     This symbol, if defined, indicates that the setlocale routine is
+ *     available and it accepts any input locale name as valid.
+ */
+#define HAS_SETLOCALE  /**/
+/*#define SETLOCALE_ACCEPTS_ANY_LOCALE_NAME    / **/
+
 /* HAS_SETPROCTITLE:
  *     This symbol, if defined, indicates that the setproctitle routine is
  *     available to set process title.
  */
 /*#define HAS_STRLCPY          / **/
 
+/* HAS_STRNLEN:
+ *     This symbol, if defined, indicates that the strnlen () routine is
+ *     available to check the length of a string up to a maximum.
+ */
+/*#define HAS_STRNLEN          / **/
+
 /* HAS_STRTOLD:
  *     This symbol, if defined, indicates that the strtold routine is
  *     available to convert strings to long doubles.
  *     This symbol, if defined, indicates that the strtoll routine is
  *     available to convert strings to long longs.
  */
-/*#define HAS_STRTOLL          / **/
+#define HAS_STRTOLL            /**/
 
 /* HAS_STRTOQ:
  *     This symbol, if defined, indicates that the strtoq routine is
  *     This symbol, if defined, indicates that the strtoull routine is
  *     available to convert strings to unsigned long longs.
  */
-/*#define HAS_STRTOULL         / **/
+#define HAS_STRTOULL           /**/
 
 /* HAS_STRTOUQ:
  *     This symbol, if defined, indicates that the strtouq routine is
  */
 /*#define HAS_TIMEGM           / **/
 
+/* HAS_TOWLOWER:
+ *     This symbol, if defined, indicates that the towlower () routine is
+ *     available to do case conversion.
+ */
+/*#define HAS_TOWLOWER         / **/
+
+/* HAS_TOWUPPER:
+ *     This symbol, if defined, indicates that the towupper () routine is
+ *     available to do case conversion.
+ */
+/*#define HAS_TOWUPPER         / **/
+
 /* HAS_TRUNC:
  *     This symbol, if defined, indicates that the trunc routine is
  *     available to round doubles towards zero.
  */
 #define DEFAULT_INC_EXCLUDES_DOT       /**/
 
+/* USE_STRICT_BY_DEFAULT:
+ *     This symbol, if defined, enables additional defaults.
+ *     At this time it only enables implicit strict by default.
+ */
+/*#define USE_STRICT_BY_DEFAULT        / * use strict by default */
+
 /* USE_DYNAMIC_LOADING:
  *     This symbol, if defined, indicates that dynamic loading of
  *     some sort is available.
  *     Note that if fflushNULL is defined, fflushall will not
  *     even be probed for and will be left undefined.
  */
-#define        FFLUSH_NULL             /**/
-/*#define      FFLUSH_ALL              / **/
+#define        FFLUSH_NULL             /**/
+/*#define      FFLUSH_ALL              / **/
 
 /* I_BFD:
  *     This symbol, if defined, indicates that <bfd.h> exists and
  *     For DB version 1 this is always 0.
  */
 #define DB_Hash_t      int             /**/
-#define DB_Prefix_t    int     /**/
-#define DB_VERSION_MAJOR_CFG   0       /**/
-#define DB_VERSION_MINOR_CFG   0       /**/
-#define DB_VERSION_PATCH_CFG   0       /**/
+#define DB_Prefix_t    int             /**/
+#define DB_VERSION_MAJOR_CFG   0       /**/
+#define DB_VERSION_MINOR_CFG   0       /**/
+#define DB_VERSION_PATCH_CFG   0       /**/
 
 /* I_FENV:
  *     This symbol, if defined, indicates to the C program that it should
 /*#define      I_IEEEFP                / **/
 
 /* I_INTTYPES:
- *     This symbol, if defined, indicates to the C program that it should
- *     include <inttypes.h>.
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <inttypes.h>.
  */
 /*#define   I_INTTYPES                / **/
 
 /*#define      I_MNTENT                / **/
 
 /* I_NETINET_TCP:
- *     This symbol, if defined, indicates to the C program that it should
- *     include <netinet/tcp.h>.
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <netinet/tcp.h>.
  */
 /*#define   I_NETINET_TCP                / **/
 
  */
 /*#define      I_USTAT         / **/
 
+/* I_WCHAR:
+ *     This symbol, if defined, indicates to the C program that <wchar.h>
+ *     is available for inclusion
+ */
+/*#define   I_WCHAR    / **/
+
+/* I_WCTYPE:
+ *     This symbol, if defined, indicates that <wctype.h> exists.
+ */
+/*#define      I_WCTYPE                / **/
+
 /* DOUBLEINFBYTES:
  *     This symbol, if defined, is a comma-separated list of
  *     hexadecimal bytes for the double precision infinity.
  *     This symbol, if defined, indicates that a variable of type NVTYPE
  *     stores 0.0 in memory as all bits zero.
  */
-#define        IVTYPE          long            /**/
-#define        UVTYPE          unsigned long           /**/
+#define        IVTYPE          __int64         /**/
+#define        UVTYPE          unsigned __int64                /**/
 #define        I8TYPE          char            /**/
 #define        U8TYPE          unsigned char           /**/
 #define        I16TYPE         short   /**/
 #define        U64TYPE         unsigned __int64        /**/
 #endif
 #define        NVTYPE          double          /**/
-#define        IVSIZE          4               /**/
-#define        UVSIZE          4               /**/
+#define        IVSIZE          8               /**/
+#define        UVSIZE          8               /**/
 #define        I8SIZE          1               /**/
 #define        U8SIZE          1               /**/
 #define        I16SIZE         2       /**/
 #define        U64SIZE         8       /**/
 #endif
 #define        NVSIZE          8               /**/
-#define        NV_PRESERVES_UV
-#define        NV_PRESERVES_UV_BITS    32
-#define        NV_OVERFLOWS_INTEGERS_AT        256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0
+#undef NV_PRESERVES_UV
+#define        NV_PRESERVES_UV_BITS    53
+#define        NV_OVERFLOWS_INTEGERS_AT        (256.0*256.0*256.0*256.0*256.0*256.0*2.0*2.0*2.0*2.0*2.0)
 #define        NV_ZERO_IS_ALLBITS_ZERO
 #if UVSIZE == 8
 #   ifdef BYTEORDER
  *     This symbol defines the format string used for printing a Perl NV
  *     using %g-ish floating point format.
  */
-#define        IVdf            "ld"            /**/
-#define        UVuf            "lu"            /**/
-#define        UVof            "lo"            /**/
-#define        UVxf            "lx"            /**/
-#define        UVXf            "lX"            /**/
+#define        IVdf            "I64d"          /**/
+#define        UVuf            "I64u"          /**/
+#define        UVof            "I64o"          /**/
+#define        UVxf            "I64x"          /**/
+#define        UVXf            "I64X"          /**/
 #define        NVef            "e"             /**/
 #define        NVff            "f"             /**/
 #define        NVgf            "g"             /**/
  *     is either n or 32*ceil(n/32), especially many little-endians do
  *     the latter.  This is only useful if you have select(), naturally.
  */
-#define SELECT_MIN_BITS        32      /**/
+#define SELECT_MIN_BITS        32      /**/
 
 /* ST_INO_SIZE:
  *     This variable contains the size of struct stat's st_ino in bytes.
  *     1 for unsigned, -1 for signed.
  */
 #define ST_INO_SIGN 1  /* st_ino sign */
-#define ST_INO_SIZE 4  /* st_ino size */
+#define ST_INO_SIZE 8  /* st_ino size */
 
 /* STARTPERL:
  *     This variable contains the string to put in front of a perl
  *     This symbol contains the minimum value for the time_t offset that
  *     the system function localtime () accepts, and defaults to 0
  */
-#define GMTIME_MAX             2147483647      /**/
+#define GMTIME_MAX             32535291599     /**/
 #define GMTIME_MIN             0       /**/
-#define LOCALTIME_MAX  2147483647      /**/
+#define LOCALTIME_MAX  32535244799     /**/
 #define LOCALTIME_MIN  0       /**/
 
 /* USE_64_BIT_INT:
  *     you may need at least to reboot your OS to 64-bit mode.
  */
 #ifndef USE_64_BIT_INT
-/*#define      USE_64_BIT_INT          / **/
+#define        USE_64_BIT_INT          /**/
 #endif
 #ifndef USE_64_BIT_ALL
 /*#define      USE_64_BIT_ALL          / **/
 /* USE_KERN_PROC_PATHNAME:
  *     This symbol, if defined, indicates that we can use sysctl with
  *     KERN_PROC_PATHNAME to get a full path for the executable, and hence
- *     convert $^X to an absolute path.
+ *     convert $^X to an absolute path.
  */
 /*#define USE_KERN_PROC_PATHNAME       / **/
 
  *     is defined, and 'int *' otherwise.  This is only useful if you
  *     have select(), of course.
  */
-#define Select_fd_set_t        Perl_fd_set *   /**/
+#define Select_fd_set_t        Perl_fd_set *   /**/
 
 /* Sock_size_t:
  *     This symbol holds the type used for the size argument of
  *     where library files may be held under a private library, for
  *     instance.
  */
-#define ARCHNAME "MSWin32-x86-perlio"          /**/
+#define ARCHNAME "MSWin32-x64-perlio"          /**/
 
 /* HAS_ASCTIME_R:
  *     This symbol, if defined, indicates that the asctime_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_asctime_r
  *     is defined.
  */
-/*#define HAS_ASCTIME_R           / **/
-#define ASCTIME_R_PROTO 0         /**/
+/*#define HAS_ASCTIME_R        / **/
+#define ASCTIME_R_PROTO 0      /**/
 
 /* HAS_CRYPT_R:
  *     This symbol, if defined, indicates that the crypt_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_crypt_r
  *     is defined.
  */
-/*#define HAS_CRYPT_R     / **/
-#define CRYPT_R_PROTO 0           /**/
+/*#define HAS_CRYPT_R  / **/
+#define CRYPT_R_PROTO 0        /**/
 
 /* HAS_CTERMID_R:
  *     This symbol, if defined, indicates that the ctermid_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_ctermid_r
  *     is defined.
  */
-/*#define HAS_CTERMID_R           / **/
-#define CTERMID_R_PROTO 0         /**/
+/*#define HAS_CTERMID_R        / **/
+#define CTERMID_R_PROTO 0      /**/
 
 /* HAS_CTIME_R:
  *     This symbol, if defined, indicates that the ctime_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_ctime_r
  *     is defined.
  */
-/*#define HAS_CTIME_R     / **/
-#define CTIME_R_PROTO 0           /**/
+/*#define HAS_CTIME_R  / **/
+#define CTIME_R_PROTO 0        /**/
 
 /* HAS_DRAND48_R:
  *     This symbol, if defined, indicates that the drand48_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_drand48_r
  *     is defined.
  */
-/*#define HAS_DRAND48_R           / **/
-#define DRAND48_R_PROTO 0         /**/
+/*#define HAS_DRAND48_R        / **/
+#define DRAND48_R_PROTO 0      /**/
 
 /* HAS_ENDGRENT_R:
  *     This symbol, if defined, indicates that the endgrent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_endgrent_r
  *     is defined.
  */
-/*#define HAS_ENDGRENT_R          / **/
-#define ENDGRENT_R_PROTO 0        /**/
+/*#define HAS_ENDGRENT_R       / **/
+#define ENDGRENT_R_PROTO 0     /**/
 
 /* HAS_ENDHOSTENT_R:
  *     This symbol, if defined, indicates that the endhostent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_endhostent_r
  *     is defined.
  */
-/*#define HAS_ENDHOSTENT_R        / **/
-#define ENDHOSTENT_R_PROTO 0      /**/
+/*#define HAS_ENDHOSTENT_R     / **/
+#define ENDHOSTENT_R_PROTO 0   /**/
 
 /* HAS_ENDNETENT_R:
  *     This symbol, if defined, indicates that the endnetent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_endnetent_r
  *     is defined.
  */
-/*#define HAS_ENDNETENT_R         / **/
-#define ENDNETENT_R_PROTO 0       /**/
+/*#define HAS_ENDNETENT_R      / **/
+#define ENDNETENT_R_PROTO 0    /**/
 
 /* HAS_ENDPROTOENT_R:
  *     This symbol, if defined, indicates that the endprotoent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_endprotoent_r
  *     is defined.
  */
-/*#define HAS_ENDPROTOENT_R       / **/
-#define ENDPROTOENT_R_PROTO 0     /**/
+/*#define HAS_ENDPROTOENT_R    / **/
+#define ENDPROTOENT_R_PROTO 0  /**/
 
 /* HAS_ENDPWENT_R:
  *     This symbol, if defined, indicates that the endpwent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_endpwent_r
  *     is defined.
  */
-/*#define HAS_ENDPWENT_R          / **/
-#define ENDPWENT_R_PROTO 0        /**/
+/*#define HAS_ENDPWENT_R       / **/
+#define ENDPWENT_R_PROTO 0     /**/
 
 /* HAS_ENDSERVENT_R:
  *     This symbol, if defined, indicates that the endservent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_endservent_r
  *     is defined.
  */
-/*#define HAS_ENDSERVENT_R        / **/
-#define ENDSERVENT_R_PROTO 0      /**/
+/*#define HAS_ENDSERVENT_R     / **/
+#define ENDSERVENT_R_PROTO 0   /**/
 
 /* HAS_GETGRENT_R:
  *     This symbol, if defined, indicates that the getgrent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getgrent_r
  *     is defined.
  */
-/*#define HAS_GETGRENT_R          / **/
-#define GETGRENT_R_PROTO 0        /**/
+/*#define HAS_GETGRENT_R       / **/
+#define GETGRENT_R_PROTO 0     /**/
 
 /* HAS_GETGRGID_R:
  *     This symbol, if defined, indicates that the getgrgid_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getgrgid_r
  *     is defined.
  */
-/*#define HAS_GETGRGID_R          / **/
-#define GETGRGID_R_PROTO 0        /**/
+/*#define HAS_GETGRGID_R       / **/
+#define GETGRGID_R_PROTO 0     /**/
 
 /* HAS_GETGRNAM_R:
  *     This symbol, if defined, indicates that the getgrnam_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getgrnam_r
  *     is defined.
  */
-/*#define HAS_GETGRNAM_R          / **/
-#define GETGRNAM_R_PROTO 0        /**/
+/*#define HAS_GETGRNAM_R       / **/
+#define GETGRNAM_R_PROTO 0     /**/
 
 /* HAS_GETHOSTBYADDR_R:
  *     This symbol, if defined, indicates that the gethostbyaddr_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_gethostbyaddr_r
  *     is defined.
  */
-/*#define HAS_GETHOSTBYADDR_R     / **/
-#define GETHOSTBYADDR_R_PROTO 0           /**/
+/*#define HAS_GETHOSTBYADDR_R  / **/
+#define GETHOSTBYADDR_R_PROTO 0        /**/
 
 /* HAS_GETHOSTBYNAME_R:
  *     This symbol, if defined, indicates that the gethostbyname_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_gethostbyname_r
  *     is defined.
  */
-/*#define HAS_GETHOSTBYNAME_R     / **/
-#define GETHOSTBYNAME_R_PROTO 0           /**/
+/*#define HAS_GETHOSTBYNAME_R  / **/
+#define GETHOSTBYNAME_R_PROTO 0        /**/
 
 /* HAS_GETHOSTENT_R:
  *     This symbol, if defined, indicates that the gethostent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_gethostent_r
  *     is defined.
  */
-/*#define HAS_GETHOSTENT_R        / **/
-#define GETHOSTENT_R_PROTO 0      /**/
+/*#define HAS_GETHOSTENT_R     / **/
+#define GETHOSTENT_R_PROTO 0   /**/
 
 /* HAS_GETLOGIN_R:
  *     This symbol, if defined, indicates that the getlogin_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getlogin_r
  *     is defined.
  */
-/*#define HAS_GETLOGIN_R          / **/
-#define GETLOGIN_R_PROTO 0        /**/
+/*#define HAS_GETLOGIN_R       / **/
+#define GETLOGIN_R_PROTO 0     /**/
 
 /* HAS_GETNETBYADDR_R:
  *     This symbol, if defined, indicates that the getnetbyaddr_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getnetbyaddr_r
  *     is defined.
  */
-/*#define HAS_GETNETBYADDR_R      / **/
-#define GETNETBYADDR_R_PROTO 0    /**/
+/*#define HAS_GETNETBYADDR_R   / **/
+#define GETNETBYADDR_R_PROTO 0 /**/
 
 /* HAS_GETNETBYNAME_R:
  *     This symbol, if defined, indicates that the getnetbyname_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getnetbyname_r
  *     is defined.
  */
-/*#define HAS_GETNETBYNAME_R      / **/
-#define GETNETBYNAME_R_PROTO 0    /**/
+/*#define HAS_GETNETBYNAME_R   / **/
+#define GETNETBYNAME_R_PROTO 0 /**/
 
 /* HAS_GETNETENT_R:
  *     This symbol, if defined, indicates that the getnetent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getnetent_r
  *     is defined.
  */
-/*#define HAS_GETNETENT_R         / **/
-#define GETNETENT_R_PROTO 0       /**/
+/*#define HAS_GETNETENT_R      / **/
+#define GETNETENT_R_PROTO 0    /**/
 
 /* HAS_GETPROTOBYNAME_R:
  *     This symbol, if defined, indicates that the getprotobyname_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getprotobyname_r
  *     is defined.
  */
-/*#define HAS_GETPROTOBYNAME_R    / **/
-#define GETPROTOBYNAME_R_PROTO 0          /**/
+/*#define HAS_GETPROTOBYNAME_R / **/
+#define GETPROTOBYNAME_R_PROTO 0       /**/
 
 /* HAS_GETPROTOBYNUMBER_R:
  *     This symbol, if defined, indicates that the getprotobynumber_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getprotobynumber_r
  *     is defined.
  */
-/*#define HAS_GETPROTOBYNUMBER_R          / **/
-#define GETPROTOBYNUMBER_R_PROTO 0        /**/
+/*#define HAS_GETPROTOBYNUMBER_R       / **/
+#define GETPROTOBYNUMBER_R_PROTO 0     /**/
 
 /* HAS_GETPROTOENT_R:
  *     This symbol, if defined, indicates that the getprotoent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getprotoent_r
  *     is defined.
  */
-/*#define HAS_GETPROTOENT_R       / **/
-#define GETPROTOENT_R_PROTO 0     /**/
+/*#define HAS_GETPROTOENT_R    / **/
+#define GETPROTOENT_R_PROTO 0  /**/
 
 /* HAS_GETPWENT_R:
  *     This symbol, if defined, indicates that the getpwent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getpwent_r
  *     is defined.
  */
-/*#define HAS_GETPWENT_R          / **/
-#define GETPWENT_R_PROTO 0        /**/
+/*#define HAS_GETPWENT_R       / **/
+#define GETPWENT_R_PROTO 0     /**/
 
 /* HAS_GETPWNAM_R:
  *     This symbol, if defined, indicates that the getpwnam_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getpwnam_r
  *     is defined.
  */
-/*#define HAS_GETPWNAM_R          / **/
-#define GETPWNAM_R_PROTO 0        /**/
+/*#define HAS_GETPWNAM_R       / **/
+#define GETPWNAM_R_PROTO 0     /**/
 
 /* HAS_GETPWUID_R:
  *     This symbol, if defined, indicates that the getpwuid_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getpwuid_r
  *     is defined.
  */
-/*#define HAS_GETPWUID_R          / **/
-#define GETPWUID_R_PROTO 0        /**/
+/*#define HAS_GETPWUID_R       / **/
+#define GETPWUID_R_PROTO 0     /**/
 
 /* HAS_GETSERVBYNAME_R:
  *     This symbol, if defined, indicates that the getservbyname_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getservbyname_r
  *     is defined.
  */
-/*#define HAS_GETSERVBYNAME_R     / **/
-#define GETSERVBYNAME_R_PROTO 0           /**/
+/*#define HAS_GETSERVBYNAME_R  / **/
+#define GETSERVBYNAME_R_PROTO 0        /**/
 
 /* HAS_GETSERVBYPORT_R:
  *     This symbol, if defined, indicates that the getservbyport_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getservbyport_r
  *     is defined.
  */
-/*#define HAS_GETSERVBYPORT_R     / **/
-#define GETSERVBYPORT_R_PROTO 0           /**/
+/*#define HAS_GETSERVBYPORT_R  / **/
+#define GETSERVBYPORT_R_PROTO 0        /**/
 
 /* HAS_GETSERVENT_R:
  *     This symbol, if defined, indicates that the getservent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getservent_r
  *     is defined.
  */
-/*#define HAS_GETSERVENT_R        / **/
-#define GETSERVENT_R_PROTO 0      /**/
+/*#define HAS_GETSERVENT_R     / **/
+#define GETSERVENT_R_PROTO 0   /**/
 
 /* HAS_GETSPNAM_R:
  *     This symbol, if defined, indicates that the getspnam_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_getspnam_r
  *     is defined.
  */
-/*#define HAS_GETSPNAM_R          / **/
-#define GETSPNAM_R_PROTO 0        /**/
+/*#define HAS_GETSPNAM_R       / **/
+#define GETSPNAM_R_PROTO 0     /**/
 
 /* HAS_GMTIME_R:
  *     This symbol, if defined, indicates that the gmtime_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_gmtime_r
  *     is defined.
  */
-/*#define HAS_GMTIME_R    / **/
-#define GMTIME_R_PROTO 0          /**/
+/*#define HAS_GMTIME_R / **/
+#define GMTIME_R_PROTO 0       /**/
+
+/* HAS_LOCALECONV_L:
+ *     This symbol, if defined, indicates that the localeconv_l routine is
+ *     available to query certain information about a locale.
+ */
+/*#define HAS_LOCALECONV_L             / **/
 
 /* HAS_LOCALTIME_R:
  *     This symbol, if defined, indicates that the localtime_r routine
 #define L_R_TZSET
 #endif
 
+/* L_R_TZSET:
+ *     If localtime_r() needs tzset, it is defined in this define
+ */
 /* LOCALTIME_R_PROTO:
  *     This symbol encodes the prototype of localtime_r.
  *     It is zero if d_localtime_r is undef, and one of the
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_localtime_r
  *     is defined.
  */
-/*#define HAS_LOCALTIME_R         / **/
-#define LOCALTIME_R_PROTO 0       /**/
+/*#define HAS_LOCALTIME_R      / **/
+#define LOCALTIME_R_PROTO 0    /**/
+
+/* HAS_MBRLEN:
+ *     This symbol, if defined, indicates that the mbrlen routine is
+ *     available to get the length of multi-byte character strings.
+ */
+/*#define HAS_MBRLEN   / **/
+
+/* HAS_MBRTOWC:
+ *     This symbol, if defined, indicates that the mbrtowc routine is
+ *     available to convert a multi-byte character into a wide character.
+ */
+/*#define HAS_MBRTOWC  / **/
+
+/* HAS_THREAD_SAFE_NL_LANGINFO_L:
+ *     This symbol, when defined, indicates presence of the nl_langinfo_l()
+ *     function, and that it is thread-safe.
+ */
+/*#define HAS_THREAD_SAFE_NL_LANGINFO_L        / **/
 
 /* OLD_PTHREAD_CREATE_JOINABLE:
  *     This symbol, if defined, indicates how to create pthread
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_random_r
  *     is defined.
  */
-/*#define HAS_RANDOM_R    / **/
-#define RANDOM_R_PROTO 0          /**/
+/*#define HAS_RANDOM_R / **/
+#define RANDOM_R_PROTO 0       /**/
 
 /* HAS_READDIR64_R:
  *     This symbol, if defined, indicates that the readdir64_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_readdir64_r
  *     is defined.
  */
-/*#define HAS_READDIR64_R         / **/
-#define READDIR64_R_PROTO 0       /**/
+/*#define HAS_READDIR64_R      / **/
+#define READDIR64_R_PROTO 0    /**/
 
 /* HAS_READDIR_R:
  *     This symbol, if defined, indicates that the readdir_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_readdir_r
  *     is defined.
  */
-/*#define HAS_READDIR_R           / **/
-#define READDIR_R_PROTO 0         /**/
+/*#define HAS_READDIR_R        / **/
+#define READDIR_R_PROTO 0      /**/
 
 /* HAS_SETGRENT_R:
  *     This symbol, if defined, indicates that the setgrent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_setgrent_r
  *     is defined.
  */
-/*#define HAS_SETGRENT_R          / **/
-#define SETGRENT_R_PROTO 0        /**/
+/*#define HAS_SETGRENT_R       / **/
+#define SETGRENT_R_PROTO 0     /**/
 
 /* HAS_SETHOSTENT_R:
  *     This symbol, if defined, indicates that the sethostent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_sethostent_r
  *     is defined.
  */
-/*#define HAS_SETHOSTENT_R        / **/
-#define SETHOSTENT_R_PROTO 0      /**/
+/*#define HAS_SETHOSTENT_R     / **/
+#define SETHOSTENT_R_PROTO 0   /**/
 
 /* HAS_SETLOCALE_R:
  *     This symbol, if defined, indicates that the setlocale_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_setlocale_r
  *     is defined.
  */
-/*#define HAS_SETLOCALE_R         / **/
-#define SETLOCALE_R_PROTO 0       /**/
+/*#define HAS_SETLOCALE_R      / **/
+#define SETLOCALE_R_PROTO 0    /**/
 
 /* HAS_SETNETENT_R:
  *     This symbol, if defined, indicates that the setnetent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_setnetent_r
  *     is defined.
  */
-/*#define HAS_SETNETENT_R         / **/
-#define SETNETENT_R_PROTO 0       /**/
+/*#define HAS_SETNETENT_R      / **/
+#define SETNETENT_R_PROTO 0    /**/
 
 /* HAS_SETPROTOENT_R:
  *     This symbol, if defined, indicates that the setprotoent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_setprotoent_r
  *     is defined.
  */
-/*#define HAS_SETPROTOENT_R       / **/
-#define SETPROTOENT_R_PROTO 0     /**/
+/*#define HAS_SETPROTOENT_R    / **/
+#define SETPROTOENT_R_PROTO 0  /**/
 
 /* HAS_SETPWENT_R:
  *     This symbol, if defined, indicates that the setpwent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_setpwent_r
  *     is defined.
  */
-/*#define HAS_SETPWENT_R          / **/
-#define SETPWENT_R_PROTO 0        /**/
+/*#define HAS_SETPWENT_R       / **/
+#define SETPWENT_R_PROTO 0     /**/
 
 /* HAS_SETSERVENT_R:
  *     This symbol, if defined, indicates that the setservent_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_setservent_r
  *     is defined.
  */
-/*#define HAS_SETSERVENT_R        / **/
-#define SETSERVENT_R_PROTO 0      /**/
+/*#define HAS_SETSERVENT_R     / **/
+#define SETSERVENT_R_PROTO 0   /**/
 
 /* HAS_SRAND48_R:
  *     This symbol, if defined, indicates that the srand48_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_srand48_r
  *     is defined.
  */
-/*#define HAS_SRAND48_R           / **/
-#define SRAND48_R_PROTO 0         /**/
+/*#define HAS_SRAND48_R        / **/
+#define SRAND48_R_PROTO 0      /**/
 
 /* HAS_SRANDOM_R:
  *     This symbol, if defined, indicates that the srandom_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_srandom_r
  *     is defined.
  */
-/*#define HAS_SRANDOM_R           / **/
-#define SRANDOM_R_PROTO 0         /**/
+/*#define HAS_SRANDOM_R        / **/
+#define SRANDOM_R_PROTO 0      /**/
 
 /* HAS_STRERROR_R:
  *     This symbol, if defined, indicates that the strerror_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_strerror_r
  *     is defined.
  */
-/*#define HAS_STRERROR_R          / **/
-#define STRERROR_R_PROTO 0        /**/
+/*#define HAS_STRERROR_R       / **/
+#define STRERROR_R_PROTO 0     /**/
+
+/* HAS_STRTOD_L:
+ *     This symbol, if defined, indicates that the strtod_l routine is
+ *     available to convert strings to long doubles.
+ */
+/*#define HAS_STRTOD_L         / **/
+
+/* HAS_STRTOLD_L:
+ *     This symbol, if defined, indicates that the strtold_l routine is
+ *     available to convert strings to long doubles.
+ */
+/*#define HAS_STRTOLD_L                / **/
 
 /* HAS_TMPNAM_R:
  *     This symbol, if defined, indicates that the tmpnam_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_tmpnam_r
  *     is defined.
  */
-/*#define HAS_TMPNAM_R    / **/
-#define TMPNAM_R_PROTO 0          /**/
+/*#define HAS_TMPNAM_R / **/
+#define TMPNAM_R_PROTO 0       /**/
 
 /* HAS_TTYNAME_R:
  *     This symbol, if defined, indicates that the ttyname_r routine
  *     REENTRANT_PROTO_T_ABC macros of reentr.h if d_ttyname_r
  *     is defined.
  */
-/*#define HAS_TTYNAME_R           / **/
-#define TTYNAME_R_PROTO 0         /**/
+/*#define HAS_TTYNAME_R        / **/
+#define TTYNAME_R_PROTO 0      /**/
+
+/* HAS_WCRTOMB:
+ *     This symbol, if defined, indicates that the wcrtomb routine is
+ *     available to convert a wide character into a multi-byte character.
+ */
+/*#define HAS_WCRTOMB  / **/
 
 /* I_MACH_CTHREADS:
- *     This symbol, if defined, indicates to the C program that it should
- *     include <mach/cthreads.h>.
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <mach/cthreads.h>.
  */
 /*#define   I_MACH_CTHREADS    / **/
 
 /* I_PTHREAD:
- *     This symbol, if defined, indicates to the C program that it should
- *     include <pthread.h>.
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <pthread.h>.
  */
 /*#define   I_PTHREAD  / **/
 
 /* HAS_TIMES:
  *     This symbol, if defined, indicates that the times() routine exists.
  *     Note that this became obsolete on some systems (SUNOS), which now
- * use getrusage(). It may be necessary to include <sys/times.h>.
+ *     use getrusage(). It may be necessary to include <sys/times.h>.
  */
 #define HAS_TIMES              /**/
 
 /* Size_t_size:
  *     This symbol holds the size of a Size_t in bytes.
  */
-#define Size_t_size 4          /**/
+#define Size_t_size 8          /**/
 
 /* Size_t:
  *     This symbol holds the type used to declare length parameters
index bffd4ec..72300c5 100644 (file)
@@ -37,6 +37,12 @@ sub loadopts {
     }
 }
 
+my $prebuilt; # are we making the prebuilt config used to bootstrap?
+if (@ARGV && $ARGV[0] eq '--prebuilt') {
+    ++$prebuilt;
+    shift;
+}
+
 my %opt;
 
 my $optref = loadopts();
@@ -117,16 +123,6 @@ elsif ($opt{cc} =~ /\bgcc\b/) {
     $int64  = 'long long';
 }
 
-# set large files options
-if ($opt{uselargefiles} eq 'define') {
-    $opt{lseeksize} = 8;
-    $opt{lseektype} = $int64;
-}
-else {
-    $opt{lseeksize} = 4;
-    $opt{lseektype} = 'long';
-}
-
 # set 64-bit options
 if ($opt{WIN64} eq 'define') {
     $opt{d_atoll} = 'define';
@@ -267,7 +263,7 @@ if ($opt{cc} =~ /\bcl/ and $opt{ccversion} =~ /^(\d+)/) {
        $opt{sGMTIME_max} = 32535291599;
        $opt{sLOCALTIME_max} = 32535244799;
     }
-    if ($ccversion >= 16) { # VC10+
+    if ($ccversion >= 16 && !$prebuilt) { # VC10+
        $opt{i_stdint} = 'define';
     }
     if ($ccversion >= 19) { # VC14+
@@ -275,7 +271,7 @@ if ($opt{cc} =~ /\bcl/ and $opt{ccversion} =~ /^(\d+)/) {
        $opt{stdio_bufsiz} = '(PERLIO_FILE_cnt(fp) + PERLIO_FILE_ptr(fp) - PERLIO_FILE_base(fp))';
        $opt{stdio_cnt} = 'PERLIO_FILE_cnt(fp)';
        $opt{stdio_ptr} = 'PERLIO_FILE_ptr(fp)';
-       $opt{i_stdbool} = 'define';
+       $opt{i_stdbool} = 'define' unless $prebuilt;
     }
 }
 # find out which MSVC this ICC is using
index a3b3bf6..1e3d5e0 100644 (file)
@@ -45,7 +45,7 @@ INST_TOP      *= $(INST_DRV)\perl
 # versioned installation can be obtained by setting INST_TOP above to a
 # path that includes an arbitrary version string.
 #
-#INST_VER      *= \5.33.4
+#INST_VER      *= \5.33.5
 
 #
 # Comment this out if you DON'T want your perl installation to have
@@ -88,13 +88,6 @@ USE_ITHREADS *= define
 USE_IMP_SYS    *= define
 
 #
-# Comment this out if you don't want to enable large file support for
-# some reason.  Should normally only be changed to maintain compatibility
-# with an older release of perl.
-#
-USE_LARGE_FILES        *= define
-
-#
 # Uncomment this if you're building a 32-bit perl and want 64-bit integers.
 # (If you're building a 64-bit perl then you will have 64-bit integers whether
 # or not this is uncommented.)
@@ -306,7 +299,6 @@ USE_SITECUST        *= undef
 USE_MULTI      *= undef
 USE_ITHREADS   *= undef
 USE_IMP_SYS    *= undef
-USE_LARGE_FILES        *= undef
 USE_64_BIT_INT *= undef
 USE_LONG_DOUBLE        *= undef
 DEFAULT_INC_EXCLUDES_DOT *= undef
@@ -1156,7 +1148,6 @@ CFG_VARS  =                                       \
                usemultiplicity=$(USE_MULTI)    ~       \
                use64bitint=$(USE_64_BIT_INT)   ~       \
                uselongdouble=$(USE_LONG_DOUBLE)        ~       \
-               uselargefiles=$(USE_LARGE_FILES)        ~       \
                usesitecustomize=$(USE_SITECUST)        ~       \
                default_inc_excludes_dot=$(DEFAULT_INC_EXCLUDES_DOT)    ~       \
                LINK_FLAGS=$(LINK_FLAGS)        ~       \
@@ -1236,7 +1227,7 @@ $(GLOBEXE) : perlglob.c
 # with MULTI, ITHREADS, IMP_SYS and LARGE_FILES off), then make
 # this target to regenerate config_H.gc.
 regen_config_h:
-       $(MINIPERL) -I..\lib config_sh.PL --cfgsh-option-file $(mktmp $(CFG_VARS)) \
+       $(MINIPERL) -I..\lib config_sh.PL --prebuilt --cfgsh-option-file $(mktmp $(CFG_VARS)) \
            $(CFGSH_TMPL) > ..\config.sh
        $(MINIPERL) -I..\lib ..\configpm --chdir=..
        -del /f $(CFGH_TMPL)
@@ -1279,9 +1270,6 @@ $(MINIDIR)\.exists : $(CFGH_TMPL)
        @(echo.&& \
        echo #ifndef _config_h_footer_&& \
        echo #define _config_h_footer_&& \
-       echo #undef Off_t&& \
-       echo #undef LSEEKSIZE&& \
-       echo #undef Off_t_size&& \
        echo #undef PTRSIZE&& \
        echo #undef SSize_t&& \
        echo #undef HAS_ATOLL&& \
@@ -1331,15 +1319,6 @@ $(MINIDIR)\.exists : $(CFGH_TMPL)
        echo #define FILE_bufsiz^(fp^) ^(PERLIO_FILE_cnt^(fp^) + PERLIO_FILE_ptr^(fp^) - PERLIO_FILE_base^(fp^)^)&& \
        echo #define I_STDBOOL)>> config.h
 .ENDIF
-.IF "$(USE_LARGE_FILES)"=="define"
-       @(echo #define Off_t $(INT64)&& \
-       echo #define LSEEKSIZE ^8&& \
-       echo #define Off_t_size ^8)>> config.h
-.ELSE
-       @(echo #define Off_t long&& \
-       echo #define LSEEKSIZE ^4&& \
-       echo #define Off_t_size ^4)>> config.h
-.ENDIF
 .IF "$(WIN64)"=="define"
 .IF "$(CCTYPE)" == "GCC"
        @(echo #define LONG_DOUBLESIZE ^16)>> config.h
@@ -1662,7 +1641,7 @@ utils: $(HAVEMINIPERL) ..\utils\Makefile
        copy ..\README.tw       ..\pod\perltw.pod
        copy ..\README.vos      ..\pod\perlvos.pod
        copy ..\README.win32    ..\pod\perlwin32.pod
-       copy ..\pod\perldelta.pod ..\pod\perl5334delta.pod
+       copy ..\pod\perldelta.pod ..\pod\perl5335delta.pod
        $(MINIPERL) -I..\lib $(PL2BAT) $(UTILS)
        $(MINIPERL) -I..\lib ..\autodoc.pl ..
        $(MINIPERL) -I..\lib ..\pod\perlmodlib.PL -q ..
@@ -1760,7 +1739,7 @@ distclean: realclean
        -if exist $(LIBDIR)\Win32API rmdir /s /q $(LIBDIR)\Win32API
        -if exist $(LIBDIR)\XS rmdir /s /q $(LIBDIR)\XS
        -cd $(PODDIR) && del /f *.html *.bat roffitall \
-           perl5334delta.pod perlaix.pod perlamiga.pod perlandroid.pod \
+           perl5335delta.pod perlaix.pod perlamiga.pod perlandroid.pod \
            perlapi.pod perlbs2000.pod perlcn.pod perlcygwin.pod \
            perldos.pod perlfreebsd.pod perlhaiku.pod perlhpux.pod \
            perlhurd.pod perlintern.pod perlirix.pod perljp.pod perlko.pod \
index f5ffca0..6d12abf 100644 (file)
@@ -986,6 +986,18 @@ PerlLIOLink(struct IPerlLIO* piPerl, const char*oldname, const char *newname)
     return win32_link(oldname, newname);
 }
 
+int
+PerlLIOSymLink(struct IPerlLIO* piPerl, const char*oldname, const char *newname)
+{
+    return win32_symlink(oldname, newname);
+}
+
+int
+PerlLIOReadLink(struct IPerlLIO* piPerl, const char *path, char *buf, size_t bufsiz)
+{
+    return win32_readlink(path, buf, bufsiz);
+}
+
 Off_t
 PerlLIOLseek(struct IPerlLIO* piPerl, int handle, Off_t offset, int origin)
 {
@@ -995,7 +1007,7 @@ PerlLIOLseek(struct IPerlLIO* piPerl, int handle, Off_t offset, int origin)
 int
 PerlLIOLstat(struct IPerlLIO* piPerl, const char *path, Stat_t *buffer)
 {
-    return win32_stat(path, buffer);
+    return win32_lstat(path, buffer);
 }
 
 char*
@@ -1098,6 +1110,8 @@ const struct IPerlLIO perlLIO =
     PerlLIOUnlink,
     PerlLIOUtime,
     PerlLIOWrite,
+    PerlLIOSymLink,
+    PerlLIOReadLink
 };
 
 
index 20454fd..9261aff 100644 (file)
@@ -68,6 +68,7 @@ POD = perl.pod        \
        perl5332delta.pod       \
        perl5333delta.pod       \
        perl5334delta.pod       \
+       perl5335delta.pod       \
        perl561delta.pod        \
        perl56delta.pod \
        perl581delta.pod        \
@@ -98,6 +99,7 @@ POD = perl.pod        \
        perldelta.pod   \
        perldeprecation.pod     \
        perldiag.pod    \
+       perldocstyle.pod        \
        perldsc.pod     \
        perldtrace.pod  \
        perlebcdic.pod  \
@@ -232,6 +234,7 @@ MAN = perl.man      \
        perl5332delta.man       \
        perl5333delta.man       \
        perl5334delta.man       \
+       perl5335delta.man       \
        perl561delta.man        \
        perl56delta.man \
        perl581delta.man        \
@@ -262,6 +265,7 @@ MAN = perl.man      \
        perldelta.man   \
        perldeprecation.man     \
        perldiag.man    \
+       perldocstyle.man        \
        perldsc.man     \
        perldtrace.man  \
        perlebcdic.man  \
@@ -396,6 +400,7 @@ HTML = perl.html    \
        perl5332delta.html      \
        perl5333delta.html      \
        perl5334delta.html      \
+       perl5335delta.html      \
        perl561delta.html       \
        perl56delta.html        \
        perl581delta.html       \
@@ -426,6 +431,7 @@ HTML = perl.html    \
        perldelta.html  \
        perldeprecation.html    \
        perldiag.html   \
+       perldocstyle.html       \
        perldsc.html    \
        perldtrace.html \
        perlebcdic.html \
@@ -560,6 +566,7 @@ TEX = perl.tex      \
        perl5332delta.tex       \
        perl5333delta.tex       \
        perl5334delta.tex       \
+       perl5335delta.tex       \
        perl561delta.tex        \
        perl56delta.tex \
        perl581delta.tex        \
@@ -590,6 +597,7 @@ TEX = perl.tex      \
        perldelta.tex   \
        perldeprecation.tex     \
        perldiag.tex    \
+       perldocstyle.tex        \
        perldsc.tex     \
        perldtrace.tex  \
        perlebcdic.tex  \
index 9719f14..9f0259a 100644 (file)
 #define PERLIO_NOT_STDIO 0
 #define WIN32_LEAN_AND_MEAN
 #define WIN32IO_IS_STDIO
+/* for CreateSymbolicLinkA() etc */
+#define _WIN32_WINNT 0x0601
 #include <tchar.h>
 
 #ifdef __GNUC__
 #  define Win32_Winsock
 #endif
 
-#ifndef _WIN32_WINNT
-#  define _WIN32_WINNT 0x0500     /* needed for CreateHardlink() etc. */
-#endif
-
 #include <windows.h>
 
 #ifndef HWND_MESSAGE
@@ -39,6 +37,7 @@
 #include <tlhelp32.h>
 #include <io.h>
 #include <signal.h>
+#include <winioctl.h>
 
 /* #include "config.h" */
 
@@ -163,6 +162,8 @@ static HWND get_hwnd_delay(pTHX, long child, DWORD tries);
 static void    win32_csighandler(int sig);
 #endif
 
+static void translate_to_errno(void);
+
 START_EXTERN_C
 HANDLE w32_perldll_handle = INVALID_HANDLE_VALUE;
 char   w32_module_name[MAX_PATH+1];
@@ -179,6 +180,22 @@ static HKEY HKCU_Perl_hnd;
 static HKEY HKLM_Perl_hnd;
 #endif
 
+/* the time_t epoch start time as a filetime expressed as a large integer */
+static ULARGE_INTEGER time_t_epoch_base_filetime;
+
+static const SYSTEMTIME time_t_epoch_base_systemtime = {
+    1970,    /* wYear         */
+    1,       /* wMonth        */
+    0,       /* wDayOfWeek    */
+    1,       /* wDay          */
+    0,       /* wHour         */
+    0,       /* wMinute       */
+    0,       /* wSecond       */
+    0        /* wMilliseconds */
+};
+
+#define FILETIME_CHUNKS_PER_SECOND (10000000UL)
+
 #ifdef SET_INVALID_PARAMETER_HANDLER
 static BOOL silent_invalid_parameter_handler = FALSE;
 
@@ -1454,129 +1471,401 @@ win32_kill(int pid, int sig)
     return -1;
 }
 
+PERL_STATIC_INLINE
+time_t
+translate_ft_to_time_t(FILETIME ft) {
+    SYSTEMTIME st, local_st;
+    struct tm pt;
+
+    if (!FileTimeToSystemTime(&ft, &st) ||
+        !SystemTimeToTzSpecificLocalTime(NULL, &st, &local_st)) {
+        return -1;
+    }
+
+    Zero(&pt, 1, struct tm);
+    pt.tm_year = local_st.wYear - 1900;
+    pt.tm_mon = local_st.wMonth - 1;
+    pt.tm_mday = local_st.wDay;
+    pt.tm_hour = local_st.wHour;
+    pt.tm_min = local_st.wMinute;
+    pt.tm_sec = local_st.wSecond;
+    pt.tm_isdst = -1;
+
+    return mktime(&pt);
+}
+
+typedef DWORD (__stdcall *pGetFinalPathNameByHandleA_t)(HANDLE, LPSTR, DWORD, DWORD);
+
+static int
+win32_stat_low(HANDLE handle, const char *path, STRLEN len, Stat_t *sbuf) {
+    DWORD type = GetFileType(handle);
+    BY_HANDLE_FILE_INFORMATION bhi;
+
+    Zero(sbuf, 1, Stat_t);
+
+    type &= ~FILE_TYPE_REMOTE;
+
+    switch (type) {
+    case FILE_TYPE_DISK:
+        if (GetFileInformationByHandle(handle, &bhi)) {
+            sbuf->st_dev = bhi.dwVolumeSerialNumber;
+            sbuf->st_ino = bhi.nFileIndexHigh;
+            sbuf->st_ino <<= 32;
+            sbuf->st_ino |= bhi.nFileIndexLow;
+            sbuf->st_nlink = bhi.nNumberOfLinks;
+            sbuf->st_uid = 0;
+            sbuf->st_gid = 0;
+            /* ucrt sets this to the drive letter for
+               stat(), lets not reproduce that mistake */
+            sbuf->st_rdev = 0;
+            sbuf->st_size = bhi.nFileSizeHigh;
+            sbuf->st_size <<= 32;
+            sbuf->st_size |= bhi.nFileSizeLow;
+
+            sbuf->st_atime = translate_ft_to_time_t(bhi.ftLastAccessTime);
+            sbuf->st_mtime = translate_ft_to_time_t(bhi.ftLastWriteTime);
+            sbuf->st_ctime = translate_ft_to_time_t(bhi.ftCreationTime);
+
+            if (bhi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+                sbuf->st_mode = _S_IFDIR | _S_IREAD | _S_IEXEC;
+                /* duplicate the logic from the end of the old win32_stat() */
+                if (!(bhi.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) {
+                    sbuf->st_mode |= S_IWRITE;
+                }
+            }
+            else {
+                char path_buf[MAX_PATH+1];
+                sbuf->st_mode = _S_IFREG;
+
+                if (!path) {
+                    pGetFinalPathNameByHandleA_t pGetFinalPathNameByHandleA =
+                        (pGetFinalPathNameByHandleA_t)GetProcAddress(GetModuleHandle("kernel32.dll"), "GetFinalPathNameByHandleA");
+                    if (pGetFinalPathNameByHandleA) {
+                        len = pGetFinalPathNameByHandleA(handle, path_buf, sizeof(path_buf), 0);
+                    }
+                    else {
+                        len = 0;
+                    }
+
+                    /* < to ensure there's space for the \0 */
+                    if (len && len < sizeof(path_buf)) {
+                        path = path_buf;
+                    }
+                }
+
+                if (path && len > 4 &&
+                    (_stricmp(path + len - 4, ".exe") == 0 ||
+                     _stricmp(path + len - 4, ".bat") == 0 ||
+                     _stricmp(path + len - 4, ".cmd") == 0 ||
+                     _stricmp(path + len - 4, ".com") == 0)) {
+                    sbuf->st_mode |= _S_IEXEC;
+                }
+                if (!(bhi.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) {
+                    sbuf->st_mode |= _S_IWRITE;
+                }
+                sbuf->st_mode |= _S_IREAD;
+            }
+        }
+        else {
+            translate_to_errno();
+            return -1;
+        }
+        break;
+
+    case FILE_TYPE_CHAR:
+    case FILE_TYPE_PIPE:
+        sbuf->st_mode = (type == FILE_TYPE_CHAR) ? _S_IFCHR : _S_IFIFO;
+        if (handle == GetStdHandle(STD_INPUT_HANDLE) ||
+            handle == GetStdHandle(STD_OUTPUT_HANDLE) ||
+            handle == GetStdHandle(STD_ERROR_HANDLE)) {
+            sbuf->st_mode |= _S_IWRITE | _S_IREAD;
+        }
+        break;
+
+    default:
+        return -1;
+    }
+
+    /* owner == user == group */
+    sbuf->st_mode |= (sbuf->st_mode & 0700) >> 3;
+    sbuf->st_mode |= (sbuf->st_mode & 0700) >> 6;
+
+    return 0;
+}
+
 DllExport int
 win32_stat(const char *path, Stat_t *sbuf)
 {
-    char       buffer[MAX_PATH+1];
-    int                l = strlen(path);
+    size_t     l = strlen(path);
     dTHX;
-    int                res;
-    int         nlink = 1;
     BOOL        expect_dir = FALSE;
+    int result;
+    HANDLE handle;
 
-    if (l > 1) {
-       switch(path[l - 1]) {
-       /* FindFirstFile() and stat() are buggy with a trailing
-        * slashes, except for the root directory of a drive */
-       case '\\':
-        case '/':
-           if (l > sizeof(buffer)) {
-               errno = ENAMETOOLONG;
-               return -1;
-           }
-            --l;
-            strncpy(buffer, path, l);
-            /* remove additional trailing slashes */
-            while (l > 1 && (buffer[l-1] == '/' || buffer[l-1] == '\\'))
-                --l;
-            /* add back slash if we otherwise end up with just a drive letter */
-            if (l == 2 && isALPHA(buffer[0]) && buffer[1] == ':')
-                buffer[l++] = '\\';
-            buffer[l] = '\0';
-            path = buffer;
-            expect_dir = TRUE;
-           break;
+    path = PerlDir_mapA(path);
+    l = strlen(path);
 
-       /* FindFirstFile() is buggy with "x:", so add a dot :-( */
-       case ':':
-           if (l == 2 && isALPHA(path[0])) {
-               buffer[0] = path[0];
-               buffer[1] = ':';
-               buffer[2] = '.';
-               buffer[3] = '\0';
-               l = 3;
-               path = buffer;
-           }
-           break;
-       }
+    handle =
+        CreateFileA(path, FILE_READ_ATTRIBUTES,
+                    FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+                    NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+    if (handle != INVALID_HANDLE_VALUE) {
+        result = win32_stat_low(handle, path, l, sbuf);
+        CloseHandle(handle);
+    }
+    else {
+        translate_to_errno();
+        result = -1;
     }
 
-    path = PerlDir_mapA(path);
-    l = strlen(path);
+    return result;
+}
 
-    if (!w32_sloppystat) {
-        /* We must open & close the file once; otherwise file attribute changes  */
-        /* might not yet have propagated to "other" hard links of the same file. */
-        /* This also gives us an opportunity to determine the number of links.   */
-        HANDLE handle = CreateFileA(path, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
-        if (handle != INVALID_HANDLE_VALUE) {
-            BY_HANDLE_FILE_INFORMATION bhi;
-            if (GetFileInformationByHandle(handle, &bhi))
-                nlink = bhi.nNumberOfLinks;
-            CloseHandle(handle);
-        }
-       else {
-           DWORD err = GetLastError();
-           /* very common case, skip CRT stat and its also failing syscalls */
-           if(err == ERROR_FILE_NOT_FOUND) {
-               errno = ENOENT;
-               return -1;
-           }
-       }
+static void
+translate_to_errno(void)
+{
+    /* This isn't perfect, eg. Win32 returns ERROR_ACCESS_DENIED for
+       both permissions errors and if the source is a directory, while
+       POSIX wants EACCES and EPERM respectively.
+    */
+    switch (GetLastError()) {
+    case ERROR_BAD_NET_NAME:
+    case ERROR_BAD_NETPATH:
+    case ERROR_BAD_PATHNAME:
+    case ERROR_FILE_NOT_FOUND:
+    case ERROR_FILENAME_EXCED_RANGE:
+    case ERROR_INVALID_DRIVE:
+    case ERROR_PATH_NOT_FOUND:
+      errno = ENOENT;
+      break;
+    case ERROR_ALREADY_EXISTS:
+      errno = EEXIST;
+      break;
+    case ERROR_ACCESS_DENIED:
+      errno = EACCES;
+      break;
+    case ERROR_PRIVILEGE_NOT_HELD:
+      errno = EPERM;
+      break;
+    case ERROR_NOT_SAME_DEVICE:
+      errno = EXDEV;
+      break;
+    case ERROR_DISK_FULL:
+      errno = ENOSPC;
+      break;
+    case ERROR_NOT_ENOUGH_QUOTA:
+      errno = EDQUOT;
+      break;
+    default:
+      /* ERROR_INVALID_FUNCTION - eg. symlink on a FAT volume */
+      errno = EINVAL;
+      break;
     }
+}
 
-    /* path will be mapped correctly above */
-#if defined(WIN64) || defined(USE_LARGE_FILES)
-    res = _stati64(path, sbuf);
-#else
-    res = stat(path, sbuf);
+/* Adapted from:
+
+https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_reparse_data_buffer
+
+Renamed to avoid conflicts, apparently some SDKs define this
+structure.
+
+Hoisted the symlink and mount point data into a new type to allow us
+to make a pointer to it, and to avoid C++ scoping issues.
+
+*/
+
+typedef struct {
+    USHORT SubstituteNameOffset;
+    USHORT SubstituteNameLength;
+    USHORT PrintNameOffset;
+    USHORT PrintNameLength;
+    ULONG  Flags;
+    WCHAR  PathBuffer[MAX_PATH*3];
+} MY_SYMLINK_REPARSE_BUFFER, *PMY_SYMLINK_REPARSE_BUFFER;
+
+typedef struct {
+    USHORT SubstituteNameOffset;
+    USHORT SubstituteNameLength;
+    USHORT PrintNameOffset;
+    USHORT PrintNameLength;
+    WCHAR  PathBuffer[MAX_PATH*3];
+} MY_MOUNT_POINT_REPARSE_BUFFER;
+
+typedef struct {
+  ULONG  ReparseTag;
+  USHORT ReparseDataLength;
+  USHORT Reserved;
+  union {
+    MY_SYMLINK_REPARSE_BUFFER SymbolicLinkReparseBuffer;
+    MY_MOUNT_POINT_REPARSE_BUFFER MountPointReparseBuffer;
+    struct {
+      UCHAR DataBuffer[1];
+    } GenericReparseBuffer;
+  } Data;
+} MY_REPARSE_DATA_BUFFER, *PMY_REPARSE_DATA_BUFFER;
+
+#ifndef IO_REPARSE_TAG_SYMLINK
+#  define IO_REPARSE_TAG_SYMLINK                  (0xA000000CL)
 #endif
-    sbuf->st_nlink = nlink;
-
-    if (res < 0) {
-       /* CRT is buggy on sharenames, so make sure it really isn't.
-        * XXX using GetFileAttributesEx() will enable us to set
-        * sbuf->st_*time (but note that's not available on the
-        * Windows of 1995) */
-       DWORD r = GetFileAttributesA(path);
-       if (r != 0xffffffff && (r & FILE_ATTRIBUTE_DIRECTORY)) {
-           /* sbuf may still contain old garbage since stat() failed */
-           Zero(sbuf, 1, Stat_t);
-           sbuf->st_mode = S_IFDIR | S_IREAD;
-           errno = 0;
-           if (!(r & FILE_ATTRIBUTE_READONLY))
-               sbuf->st_mode |= S_IWRITE | S_IEXEC;
-           return 0;
-       }
+
+static BOOL
+is_symlink(HANDLE h) {
+    MY_REPARSE_DATA_BUFFER linkdata;
+    const MY_SYMLINK_REPARSE_BUFFER * const sd =
+        &linkdata.Data.SymbolicLinkReparseBuffer;
+    DWORD linkdata_returned;
+
+    if (!DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, NULL, 0, &linkdata, sizeof(linkdata), &linkdata_returned, NULL)) {
+        return FALSE;
     }
-    else {
-       if (l == 3 && isALPHA(path[0]) && path[1] == ':'
-           && (path[2] == '\\' || path[2] == '/'))
-       {
-           /* The drive can be inaccessible, some _stat()s are buggy */
-           if (!GetVolumeInformationA(path,NULL,0,NULL,NULL,NULL,NULL,0)) {
-               errno = ENOENT;
-               return -1;
-           }
-       }
-        if (expect_dir && !S_ISDIR(sbuf->st_mode)) {
-            errno = ENOTDIR;
-            return -1;
+
+    if (linkdata_returned < offsetof(MY_REPARSE_DATA_BUFFER, Data.SymbolicLinkReparseBuffer.PathBuffer)
+        || (linkdata.ReparseTag != IO_REPARSE_TAG_SYMLINK
+            && linkdata.ReparseTag != IO_REPARSE_TAG_MOUNT_POINT)) {
+        /* some other type of reparse point */
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+static BOOL
+is_symlink_name(const char *name) {
+    HANDLE f = CreateFileA(name, GENERIC_READ, 0, NULL, OPEN_EXISTING,
+                           FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 0);
+    BOOL result;
+
+    if (f == INVALID_HANDLE_VALUE) {
+        return FALSE;
+    }
+    result = is_symlink(f);
+    CloseHandle(f);
+
+    return result;
+}
+
+DllExport int
+win32_readlink(const char *pathname, char *buf, size_t bufsiz) {
+    MY_REPARSE_DATA_BUFFER linkdata;
+    HANDLE hlink;
+    DWORD fileattr = GetFileAttributes(pathname);
+    DWORD linkdata_returned;
+    int bytes_out;
+    BOOL used_default;
+
+    if (fileattr == INVALID_FILE_ATTRIBUTES) {
+        translate_to_errno();
+        return -1;
+    }
+
+    if (!(fileattr & FILE_ATTRIBUTE_REPARSE_POINT)) {
+        /* not a symbolic link */
+        errno = EINVAL;
+        return -1;
+    }
+
+    hlink =
+        CreateFileA(pathname, GENERIC_READ, 0, NULL, OPEN_EXISTING,
+                    FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 0);
+    if (hlink == INVALID_HANDLE_VALUE) {
+        translate_to_errno();
+        return -1;
+    }
+
+    if (!DeviceIoControl(hlink, FSCTL_GET_REPARSE_POINT, NULL, 0, &linkdata, sizeof(linkdata), &linkdata_returned, NULL)) {
+        translate_to_errno();
+        CloseHandle(hlink);
+        return -1;
+    }
+    CloseHandle(hlink);
+
+    switch (linkdata.ReparseTag) {
+    case IO_REPARSE_TAG_SYMLINK:
+        {
+            const MY_SYMLINK_REPARSE_BUFFER * const sd =
+                &linkdata.Data.SymbolicLinkReparseBuffer;
+            if (linkdata_returned < offsetof(MY_REPARSE_DATA_BUFFER, Data.SymbolicLinkReparseBuffer.PathBuffer)) {
+                errno = EINVAL;
+                return -1;
+            }
+            bytes_out =
+                WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS,
+                                    sd->PathBuffer + sd->SubstituteNameOffset/2,
+                                    sd->SubstituteNameLength/2,
+                                    buf, (int)bufsiz, NULL, &used_default);
         }
-       if (S_ISDIR(sbuf->st_mode)) {
-           /* Ensure the "write" bit is switched off in the mode for
-            * directories with the read-only attribute set. Some compilers
-            * switch it on for directories, which is technically correct
-            * (directories are indeed always writable unless denied by DACLs),
-            * but we want stat() and -w to reflect the state of the read-only
-            * attribute for symmetry with chmod(). */
-           DWORD r = GetFileAttributesA(path);
-           if (r != 0xffffffff && (r & FILE_ATTRIBUTE_READONLY)) {
-               sbuf->st_mode &= ~S_IWRITE;
-           }
-       }
+        break;
+    case IO_REPARSE_TAG_MOUNT_POINT:
+        {
+            const MY_MOUNT_POINT_REPARSE_BUFFER * const rd =
+                &linkdata.Data.MountPointReparseBuffer;
+            if (linkdata_returned < offsetof(MY_REPARSE_DATA_BUFFER, Data.MountPointReparseBuffer.PathBuffer)) {
+                errno = EINVAL;
+                return -1;
+            }
+            bytes_out =
+                WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS,
+                                    rd->PathBuffer + rd->SubstituteNameOffset/2,
+                                    rd->SubstituteNameLength/2,
+                                    buf, (int)bufsiz, NULL, &used_default);
+        }
+        break;
+
+    default:
+        errno = EINVAL;
+        return -1;
+    }
+
+    if (bytes_out == 0 || used_default) {
+        /* failed conversion from unicode to ANSI or otherwise failed */
+        errno = EINVAL;
+        return -1;
+    }
+    if ((size_t)bytes_out > bufsiz) {
+        errno = EINVAL;
+        return -1;
+    }
+
+    return bytes_out;
+}
+
+DllExport int
+win32_lstat(const char *path, Stat_t *sbuf)
+{
+    HANDLE f;
+    int result;
+    DWORD attr = GetFileAttributes(path); /* doesn't follow symlinks */
+
+    if (attr == INVALID_FILE_ATTRIBUTES) {
+        translate_to_errno();
+        return -1;
+    }
+
+    if (!(attr & FILE_ATTRIBUTE_REPARSE_POINT)) {
+        return win32_stat(path, sbuf);
+    }
+
+    f = CreateFileA(path, GENERIC_READ, 0, NULL, OPEN_EXISTING,
+                           FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 0);
+    if (f == INVALID_HANDLE_VALUE) {
+        translate_to_errno();
+        return -1;
+    }
+
+    if (!is_symlink(f)) {
+        CloseHandle(f);
+        return win32_stat(path, sbuf);
     }
-    return res;
+
+    result = win32_stat_low(f, NULL, 0, sbuf);
+    CloseHandle(f);
+
+    if (result != -1){
+        sbuf->st_mode = (sbuf->st_mode & ~_S_IFMT) | _S_IFLNK;
+    }
+
+    return result;
 }
 
 #define isSLASH(c) ((c) == '/' || (c) == '\\')
@@ -1672,7 +1961,6 @@ win32_longpath(char *path)
        }
        else {
            /* failed a step, just return without side effects */
-           /*PerlIO_printf(Perl_debug_log, "Failed to find %s\n", path);*/
            errno = EINVAL;
            return NULL;
        }
@@ -1932,27 +2220,35 @@ win32_times(struct tms *timebuf)
     return process_time_so_far;
 }
 
-/* fix utime() so it works on directories in NT */
 static BOOL
 filetime_from_time(PFILETIME pFileTime, time_t Time)
 {
-    struct tm *pTM = localtime(&Time);
-    SYSTEMTIME SystemTime;
-    FILETIME LocalTime;
+    struct tm *pt;
+    SYSTEMTIME st;
 
-    if (pTM == NULL)
-       return FALSE;
+    pt = gmtime(&Time);
+    if (!pt) {
+        pFileTime->dwLowDateTime = 0;
+        pFileTime->dwHighDateTime = 0;
+        fprintf(stderr, "fail bad gmtime\n");
+        return FALSE;
+    }
+
+    st.wYear = pt->tm_year + 1900;
+    st.wMonth = pt->tm_mon + 1;
+    st.wDay = pt->tm_mday;
+    st.wHour = pt->tm_hour;
+    st.wMinute = pt->tm_min;
+    st.wSecond = pt->tm_sec;
+    st.wMilliseconds = 0;
 
-    SystemTime.wYear   = pTM->tm_year + 1900;
-    SystemTime.wMonth  = pTM->tm_mon + 1;
-    SystemTime.wDay    = pTM->tm_mday;
-    SystemTime.wHour   = pTM->tm_hour;
-    SystemTime.wMinute = pTM->tm_min;
-    SystemTime.wSecond = pTM->tm_sec;
-    SystemTime.wMilliseconds = 0;
+    if (!SystemTimeToFileTime(&st, pFileTime)) {
+        pFileTime->dwLowDateTime = 0;
+        pFileTime->dwHighDateTime = 0;
+        return FALSE;
+    }
 
-    return SystemTimeToFileTime(&SystemTime, &LocalTime) &&
-           LocalFileTimeToFileTime(&LocalTime, pFileTime);
+    return TRUE;
 }
 
 DllExport int
@@ -1974,8 +2270,14 @@ win32_unlink(const char *filename)
         if (ret == -1)
             (void)SetFileAttributesA(filename, attrs);
     }
-    else
+    else if ((attrs & (FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY))
+        == (FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY)
+             && is_symlink_name(filename)) {
+        ret = rmdir(filename);
+    }
+    else {
         ret = unlink(filename);
+    }
     return ret;
 }
 
@@ -1984,38 +2286,38 @@ win32_utime(const char *filename, struct utimbuf *times)
 {
     dTHX;
     HANDLE handle;
-    FILETIME ftCreate;
     FILETIME ftAccess;
     FILETIME ftWrite;
     struct utimbuf TimeBuffer;
-    int rc;
+    int rc = -1;
 
     filename = PerlDir_mapA(filename);
-    rc = utime(filename, times);
-
-    /* EACCES: path specifies directory or readonly file */
-    if (rc == 0 || errno != EACCES)
-       return rc;
-
-    if (times == NULL) {
-       times = &TimeBuffer;
-       time(&times->actime);
-       times->modtime = times->actime;
-    }
-
     /* This will (and should) still fail on readonly files */
     handle = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE,
-                         FILE_SHARE_READ | FILE_SHARE_DELETE, NULL,
+                         FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                          OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
-    if (handle == INVALID_HANDLE_VALUE)
-       return rc;
+    if (handle == INVALID_HANDLE_VALUE) {
+        translate_to_errno();
+        return -1;
+    }
 
-    if (GetFileTime(handle, &ftCreate, &ftAccess, &ftWrite) &&
-       filetime_from_time(&ftAccess, times->actime) &&
-       filetime_from_time(&ftWrite, times->modtime) &&
-       SetFileTime(handle, &ftCreate, &ftAccess, &ftWrite))
-    {
-       rc = 0;
+    if (times == NULL) {
+        times = &TimeBuffer;
+        time(&times->actime);
+        times->modtime = times->actime;
+    }
+
+    if (filetime_from_time(&ftAccess, times->actime) &&
+       filetime_from_time(&ftWrite, times->modtime)) {
+        if (SetFileTime(handle, NULL, &ftAccess, &ftWrite)) {
+            rc = 0;
+        }
+        else {
+            translate_to_errno();
+        }
+    }
+    else {
+        errno = EINVAL; /* bad time? */
     }
 
     CloseHandle(handle);
@@ -2853,20 +3155,15 @@ win32_fflush(FILE *pf)
 DllExport Off_t
 win32_ftell(FILE *pf)
 {
-#if defined(WIN64) || defined(USE_LARGE_FILES)
     fpos_t pos;
     if (fgetpos(pf, &pos))
        return -1;
     return (Off_t)pos;
-#else
-    return ftell(pf);
-#endif
 }
 
 DllExport int
 win32_fseek(FILE *pf, Off_t offset,int origin)
 {
-#if defined(WIN64) || defined(USE_LARGE_FILES)
     fpos_t pos;
     switch (origin) {
     case SEEK_CUR:
@@ -2886,9 +3183,6 @@ win32_fseek(FILE *pf, Off_t offset,int origin)
        return -1;
     }
     return fsetpos(pf, &offset);
-#else
-    return fseek(pf, (long)offset, origin);
-#endif
 }
 
 DllExport int
@@ -2967,11 +3261,9 @@ win32_abort(void)
 DllExport int
 win32_fstat(int fd, Stat_t *sbufptr)
 {
-#if defined(WIN64) || defined(USE_LARGE_FILES)
-    return _fstati64(fd, sbufptr);
-#else
-    return fstat(fd, sbufptr);
-#endif
+    HANDLE handle = (HANDLE)win32_get_osfhandle(fd);
+
+    return win32_stat_low(handle, NULL, 0, sbufptr);
 }
 
 DllExport int
@@ -3166,44 +3458,114 @@ win32_link(const char *oldname, const char *newname)
     {
        return 0;
     }
-    /* This isn't perfect, eg. Win32 returns ERROR_ACCESS_DENIED for
-       both permissions errors and if the source is a directory, while
-       POSIX wants EACCES and EPERM respectively.
+    translate_to_errno();
+    return -1;
+}
 
-       Determined by experimentation on Windows 7 x64 SP1, since MS
-       don't document what error codes are returned.
+typedef BOOLEAN (__stdcall *pCreateSymbolicLinkA_t)(LPCSTR, LPCSTR, DWORD);
+
+#ifndef SYMBOLIC_LINK_FLAG_DIRECTORY
+#  define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1
+#endif
+
+#ifndef SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
+#  define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE 0x2
+#endif
+
+DllExport int
+win32_symlink(const char *oldfile, const char *newfile)
+{
+    dTHX;
+    size_t oldfile_len = strlen(oldfile);
+    pCreateSymbolicLinkA_t pCreateSymbolicLinkA =
+        (pCreateSymbolicLinkA_t)GetProcAddress(GetModuleHandle("kernel32.dll"), "CreateSymbolicLinkA");
+    DWORD create_flags = 0;
+
+    /* this flag can be used only on Windows 10 1703 or newer */
+    if (g_osver.dwMajorVersion > 10 ||
+        (g_osver.dwMajorVersion == 10 &&
+         (g_osver.dwMinorVersion > 0 || g_osver.dwBuildNumber > 15063)))
+    {
+        create_flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
+    }
+
+    if (!pCreateSymbolicLinkA) {
+        errno = ENOSYS;
+        return -1;
+    }
+
+    /* oldfile might be relative and we don't want to change that,
+       so don't map that.
     */
-    switch (GetLastError()) {
-    case ERROR_BAD_NET_NAME:
-    case ERROR_BAD_NETPATH:
-    case ERROR_BAD_PATHNAME:
-    case ERROR_FILE_NOT_FOUND:
-    case ERROR_FILENAME_EXCED_RANGE:
-    case ERROR_INVALID_DRIVE:
-    case ERROR_PATH_NOT_FOUND:
-      errno = ENOENT;
-      break;
-    case ERROR_ALREADY_EXISTS:
-      errno = EEXIST;
-      break;
-    case ERROR_ACCESS_DENIED:
-      errno = EACCES;
-      break;
-    case ERROR_NOT_SAME_DEVICE:
-      errno = EXDEV;
-      break;
-    case ERROR_DISK_FULL:
-      errno = ENOSPC;
-      break;
-    case ERROR_NOT_ENOUGH_QUOTA:
-      errno = EDQUOT;
-      break;
-    default:
-      /* ERROR_INVALID_FUNCTION - eg. on a FAT volume */
-      errno = EINVAL;
-      break;
+    newfile = PerlDir_mapA(newfile);
+
+    /* are we linking to a directory?
+       CreateSymlinkA() needs to know if the target is a directory,
+       If it looks like a directory name:
+        - ends in slash
+        - is just . or ..
+        - ends in /. or /.. (with either slash)
+        - is a simple drive letter
+       assume it's a directory.
+
+       Otherwise if the oldfile is relative we need to make a relative path
+       based on the newfile to check if the target is a directory.
+    */
+    if ((oldfile_len >= 1 && isSLASH(oldfile[oldfile_len-1])) ||
+        strEQ(oldfile, "..") ||
+        strEQ(oldfile, ".") ||
+        (isSLASH(oldfile[oldfile_len-2]) && oldfile[oldfile_len-1] == '.') ||
+        strEQ(oldfile+oldfile_len-3, "\\..") ||
+        strEQ(oldfile+oldfile_len-3, "/..") ||
+        (oldfile_len == 2 && oldfile[1] == ':')) {
+        create_flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
     }
-    return -1;
+    else {
+        DWORD dest_attr;
+        const char *dest_path = oldfile;
+        char szTargetName[MAX_PATH+1];
+
+        if (oldfile_len >= 3 && oldfile[1] == ':' && oldfile[2] != '\\' && oldfile[2] != '/') {
+            /* relative to current directory on a drive */
+            /* dest_path = oldfile; already done */
+        }
+        else if (oldfile[0] != '\\' && oldfile[0] != '/') {
+            size_t newfile_len = strlen(newfile);
+            char *last_slash = strrchr(newfile, '/');
+            char *last_bslash = strrchr(newfile, '\\');
+            char *end_dir = last_slash && last_bslash
+                ? ( last_slash > last_bslash ? last_slash : last_bslash)
+                : last_slash ? last_slash : last_bslash ? last_bslash : NULL;
+
+            if (end_dir) {
+                if ((end_dir - newfile + 1) + oldfile_len > MAX_PATH) {
+                    /* too long */
+                    errno = EINVAL;
+                    return -1;
+                }
+
+                memcpy(szTargetName, newfile, end_dir - newfile + 1);
+                strcpy(szTargetName + (end_dir - newfile + 1), oldfile);
+                dest_path = szTargetName;
+            }
+            else {
+                /* newpath is just a filename */
+                /* dest_path = oldfile; */
+            }
+        }
+
+        dest_attr = GetFileAttributes(dest_path);
+        if (dest_attr != (DWORD)-1 && (dest_attr & FILE_ATTRIBUTE_DIRECTORY)) {
+            create_flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
+        }
+    }
+
+    if (!pCreateSymbolicLinkA(newfile, oldfile, create_flags)) {
+        translate_to_errno();
+        return -1;
+    }
+
+    return 0;
 }
 
 DllExport int
@@ -3256,7 +3618,6 @@ win32_setmode(int fd, int mode)
 DllExport int
 win32_chsize(int fd, Off_t size)
 {
-#if defined(WIN64) || defined(USE_LARGE_FILES)
     int retval = 0;
     Off_t cur, end, extend;
 
@@ -3296,29 +3657,18 @@ win32_chsize(int fd, Off_t size)
     }
     win32_lseek(fd, cur, SEEK_SET);
     return retval;
-#else
-    return chsize(fd, (long)size);
-#endif
 }
 
 DllExport Off_t
 win32_lseek(int fd, Off_t offset, int origin)
 {
-#if defined(WIN64) || defined(USE_LARGE_FILES)
     return _lseeki64(fd, offset, origin);
-#else
-    return lseek(fd, (long)offset, origin);
-#endif
 }
 
 DllExport Off_t
 win32_tell(int fd)
 {
-#if defined(WIN64) || defined(USE_LARGE_FILES)
     return _telli64(fd);
-#else
-    return tell(fd);
-#endif
 }
 
 DllExport int
@@ -4544,6 +4894,17 @@ Perl_win32_init(int *argcp, char ***argvp)
        }
     }
 #endif
+
+    {
+        FILETIME ft;
+        if (!SystemTimeToFileTime(&time_t_epoch_base_systemtime,
+                                  &ft)) {
+           fprintf(stderr, "panic: cannot convert base system time to filetime\n"); /* no interp */
+           exit(1);
+        }
+        time_t_epoch_base_filetime.LowPart  = ft.dwLowDateTime;
+        time_t_epoch_base_filetime.HighPart = ft.dwHighDateTime;
+    }
 }
 
 void
@@ -4743,11 +5104,6 @@ Perl_sys_intern_init(pTHX)
     w32_timerid                 = 0;
     w32_message_hwnd            = CAST_HWND__(INVALID_HANDLE_VALUE);
     w32_poll_count              = 0;
-#ifdef PERL_IS_MINIPERL
-    w32_sloppystat              = TRUE;
-#else
-    w32_sloppystat              = FALSE;
-#endif
     for (i=0; i < SIG_SIZE; i++) {
        w32_sighandler[i] = SIG_DFL;
     }
@@ -4816,7 +5172,6 @@ Perl_sys_intern_dup(pTHX_ struct interp_intern *src, struct interp_intern *dst)
     dst->timerid                = 0;
     dst->message_hwnd          = CAST_HWND__(INVALID_HANDLE_VALUE);
     dst->poll_count             = 0;
-    dst->sloppystat             = src->sloppystat;
     Copy(src->sigtable,dst->sigtable,SIG_SIZE,Sighandler_t);
 }
 #  endif /* USE_ITHREADS */
index 00d052a..40ab7e0 100644 (file)
@@ -563,7 +563,6 @@ struct interp_intern {
     UINT       timerid;
     unsigned   poll_count;
     Sighandler_t sigtable[SIG_SIZE];
-    bool sloppystat;
 };
 
 #define WIN32_POLL_INTERVAL 32768
@@ -597,7 +596,6 @@ struct interp_intern {
 #define w32_init_socktype      (PL_sys_intern.thr_intern.Winit_socktype)
 #define w32_use_showwindow     (PL_sys_intern.thr_intern.Wuse_showwindow)
 #define w32_showwindow (PL_sys_intern.thr_intern.Wshowwindow)
-#define w32_sloppystat (PL_sys_intern.sloppystat)
 
 #ifdef USE_ITHREADS
 void win32_wait_for_children(pTHX);
@@ -731,5 +729,37 @@ DllExport void *win32_signal_context(void);
 #  define O_ACCMODE (O_RDWR | O_WRONLY | O_RDONLY)
 #endif
 
+/* ucrt at least seems to allocate a whole bit per type,
+   just mask off one bit from the mask for our symlink
+   file type.
+*/
+#define _S_IFLNK ((unsigned)(_S_IFMT ^ (_S_IFMT & -_S_IFMT)))
+#undef S_ISLNK
+#define S_ISLNK(mode) (((mode) & _S_IFMT) == _S_IFLNK)
+
+/*
+
+The default CRT struct stat uses unsigned short for st_dev and st_ino
+which obviously isn't enough, so we define our own structure.
+
+ */
+
+typedef DWORD Dev_t;
+typedef unsigned __int64 Ino_t;
+
+struct w32_stat {
+    Dev_t st_dev;
+    Ino_t st_ino;
+    unsigned short st_mode;
+    DWORD st_nlink;
+    short st_uid;
+    short st_gid;
+    Dev_t st_rdev;
+    Off_t st_size;
+    time_t st_atime;
+    time_t st_mtime;
+    time_t st_ctime;
+};
+
 #endif /* _INC_WIN32_PERL5 */
 
index 559e1f9..fd6b1c1 100644 (file)
@@ -69,6 +69,7 @@ DllExport  FILE*      win32_tmpfile(void);
 DllExport  void                win32_abort(void);
 DllExport  int         win32_fstat(int fd,Stat_t *sbufptr);
 DllExport  int         win32_stat(const char *name,Stat_t *sbufptr);
+DllExport  int         win32_lstat(const char *name,Stat_t *sbufptr);
 DllExport  int         win32_pipe( int *phandles, unsigned int psize, int textmode );
 DllExport  PerlIO*     win32_popen( const char *command, const char *mode );
 DllExport  PerlIO*     win32_popenlist(const char *mode, IV narg, SV **args);
@@ -136,6 +137,8 @@ DllExport  char*    win32_longpath(char *path);
 DllExport  char*       win32_ansipath(const WCHAR *path);
 DllExport  int         win32_ioctl(int i, unsigned int u, char *data);
 DllExport  int          win32_link(const char *oldname, const char *newname);
+DllExport  int          win32_symlink(const char *oldname, const char *newname);
+DllExport  int          win32_readlink(const char *path, char *buf, size_t bufsiz);
 DllExport  int         win32_unlink(const char *f);
 DllExport  int         win32_utime(const char *f, struct utimbuf *t);
 DllExport  int         win32_gettimeofday(struct timeval *tp, void *not_used);
@@ -241,6 +244,7 @@ END_EXTERN_C
 #  undef stat
 #endif
 #define stat(pth,bufptr)       win32_stat(pth,bufptr)
+#define lstat(pth,bufptr)      win32_lstat(pth,bufptr)
 #define longpath(pth)          win32_longpath(pth)
 #define ansipath(pth)          win32_ansipath(pth)
 #define rename(old,new)                win32_rename(old,new)
@@ -285,7 +289,6 @@ END_EXTERN_C
 #define access(p,m)            win32_access(p,m)
 #define chmod(p,m)             win32_chmod(p,m)
 
-
 #if !defined(MYMALLOC) || !defined(PERL_CORE)
 #undef malloc
 #undef calloc
@@ -307,6 +310,8 @@ END_EXTERN_C
 #define times                  win32_times
 #define ioctl                  win32_ioctl
 #define link                   win32_link
+#define symlink                        win32_symlink
+#define readlink               win32_readlink
 #define unlink                 win32_unlink
 #define utime                  win32_utime
 #define gettimeofday           win32_gettimeofday