diff --git a/dev/import-perl5/config.yaml b/dev/import-perl5/config.yaml index 0ca531b235..8f05b67d44 100644 --- a/dev/import-perl5/config.yaml +++ b/dev/import-perl5/config.yaml @@ -749,10 +749,12 @@ imports: # CPAN.pm - Main CPAN client - source: perl5/cpan/CPAN/lib/CPAN.pm target: src/main/perl/lib/CPAN.pm + patch: CPAN.pm.patch # App::Cpan - Command-line interface for CPAN.pm (used by jcpan) - source: perl5/cpan/CPAN/lib/App/Cpan.pm target: src/main/perl/lib/App/Cpan.pm + patch: App-Cpan.pm.patch # autouse - Postpone loading of modules until a function is used - source: perl5/dist/autouse/lib/autouse.pm @@ -785,6 +787,16 @@ imports: target: src/main/perl/lib/CPAN/HandleConfig.pm patch: CPAN-HandleConfig.pm.patch + - source: perl5/cpan/CPAN/lib/CPAN/Index.pm + target: src/main/perl/lib/CPAN/Index.pm + patch: CPAN-Index.pm.patch + protected: true + + - source: perl5/cpan/CPAN/lib/CPAN/Shell.pm + target: src/main/perl/lib/CPAN/Shell.pm + patch: CPAN-Shell.pm.patch + protected: true + # CPAN::Meta - Metadata handling for CPAN distributions - source: perl5/cpan/CPAN-Meta/lib/CPAN/Meta.pm target: src/main/perl/lib/CPAN/Meta.pm diff --git a/dev/import-perl5/patches/App-Cpan.pm.patch b/dev/import-perl5/patches/App-Cpan.pm.patch new file mode 100644 index 0000000000..cd789092d3 --- /dev/null +++ b/dev/import-perl5/patches/App-Cpan.pm.patch @@ -0,0 +1,37 @@ +--- perl5/cpan/CPAN/lib/App/Cpan.pm 2026-04-10 11:04:21 ++++ src/main/perl/lib/App/Cpan.pm 2026-08-10 10:12:19 +@@ -652,6 +652,7 @@ + $action->( $arg ); + + my $error = _cpanpm_output_indicates_failure(); ++ $error ||= _cpanpm_status_indicates_failure(); + push @errors, $error if $error; + } + +@@ -752,7 +753,7 @@ + + BEGIN { + my $epic_fail_words = join '|', +- qw( Error stop(?:ping)? problems force not unsupported ++ qw( Error stop(?:ping)? problems force unsupported + fail(?:ed)? Cannot\s+install ); + + sub _cpanpm_output_indicates_failure +@@ -763,6 +764,17 @@ + return A_MODULE_FAILED_TO_INSTALL if $last_line =~ /\b(?:Cannot\s+install)\b/i; + + $result || (); ++ } ++ ++sub _cpanpm_status_indicates_failure ++ { ++ # CPAN already records structured phase status for every distribution in ++ # the current command, including recursively installed prerequisites. ++ # Prefer that state when App::Cpan's legacy last-output-line heuristic is ++ # fooled by trailing hints or report suggestions. ++ my @failed = CPAN::Shell->find_failed($CPAN::CurrentCommandId); ++ return A_MODULE_FAILED_TO_INSTALL if grep { $_->[5] } @failed; ++ return; + } + } + diff --git a/dev/import-perl5/patches/CPAN-HandleConfig.pm.patch b/dev/import-perl5/patches/CPAN-HandleConfig.pm.patch index e2e5a4ef3a..ece82cd9f5 100644 --- a/dev/import-perl5/patches/CPAN-HandleConfig.pm.patch +++ b/dev/import-perl5/patches/CPAN-HandleConfig.pm.patch @@ -1,12 +1,32 @@ ---- perl5/cpan/CPAN/lib/CPAN/HandleConfig.pm -+++ src/main/perl/lib/CPAN/HandleConfig.pm -@@ -546,8 +546,11 @@ +--- perl5/cpan/CPAN/lib/CPAN/HandleConfig.pm 2026-04-10 11:04:21 ++++ src/main/perl/lib/CPAN/HandleConfig.pm 2026-08-10 10:13:33 +@@ -137,6 +137,7 @@ + "make", + "make_install_make_command", + "prefer_installer", ++ "recommends_policy", + "test_report", + ); + +@@ -527,6 +528,11 @@ + + # prioritized list of possible places for finding "CPAN/MyConfig.pm" + sub cpan_home_dir_candidates { ++ if (defined $ENV{PERLONJAVA_HOME} && length $ENV{PERLONJAVA_HOME}) { ++ my $dir = File::Spec->catdir($ENV{PERLONJAVA_HOME}, 'cpan'); ++ return wantarray ? ($dir) : $dir; ++ } ++ + my @dirs; + my $old_v = $CPAN::Config->{load_module_verbosity}; + $CPAN::Config->{load_module_verbosity} = q[none]; +@@ -546,8 +552,11 @@ push @dirs, $ENV{USERPROFILE} if $ENV{USERPROFILE}; $CPAN::Config->{load_module_verbosity} = $old_v; - my $dotcpan = $^O eq 'VMS' ? '_cpan' : '.cpan'; - @dirs = map { File::Spec->catdir($_, $dotcpan) } grep { defined } @dirs; -+ # PerlOnJava uses ~/.perlonjava/cpan as its CPAN home to stay separate ++ # PerlOnJava uses ~/.perlonjava/cpan as its default CPAN home to stay separate + # from the user's system CPAN (~/.cpan), which would otherwise override + # our prefs_dir and other PerlOnJava-specific defaults. + my @suffix = $^O eq 'VMS' ? ('_cpan') : ('.perlonjava', 'cpan'); diff --git a/dev/import-perl5/patches/CPAN-Index.pm.patch b/dev/import-perl5/patches/CPAN-Index.pm.patch new file mode 100644 index 0000000000..bf016bae8e --- /dev/null +++ b/dev/import-perl5/patches/CPAN-Index.pm.patch @@ -0,0 +1,19 @@ +--- perl5/cpan/CPAN/lib/CPAN/Index.pm 2026-04-10 11:04:21 ++++ src/main/perl/lib/CPAN/Index.pm 2026-08-10 10:13:33 +@@ -597,11 +597,11 @@ + while(my($class,$v) = each %$cache) { + next unless $class =~ /^CPAN::/; + $CPAN::META->{readonly}{$class} = $v; # unsafe meta access, ok +- while (my($id,$ro) = each %$v) { +- $CPAN::META->{readwrite}{$class}{$id} ||= +- $class->new(ID=>$id, RO=>$ro); +- $idcnt++; +- } ++ # Mutable CPAN objects are created lazily by CPAN::instance (or in ++ # bulk by CPAN::all_objects). Eagerly blessing every cached module, ++ # distribution, and author makes a normal jcpan invocation spend ++ # minutes allocating objects it will never use. ++ $idcnt += scalar keys %$v; + $clcnt++; + } + unless ($clcnt) { # sanity check diff --git a/dev/import-perl5/patches/CPAN-Shell.pm.patch b/dev/import-perl5/patches/CPAN-Shell.pm.patch new file mode 100644 index 0000000000..5a5767d0dd --- /dev/null +++ b/dev/import-perl5/patches/CPAN-Shell.pm.patch @@ -0,0 +1,15 @@ +--- perl5/cpan/CPAN/lib/CPAN/Shell.pm 2026-04-10 11:04:21 ++++ src/main/perl/lib/CPAN/Shell.pm 2026-08-10 10:13:33 +@@ -1111,7 +1111,11 @@ + sub find_failed { + my($self,$only_id) = @_; + my @failed; +- DIST: for my $d (sort { $a->id cmp $b->id } $CPAN::META->all_objects("CPAN::Distribution")) { ++ # Failure status is session state. Iterating the mutable objects is both ++ # sufficient and avoids inflating the complete cached distribution index ++ # merely to print the command summary. ++ DIST: for my $d (sort { $a->id cmp $b->id } ++ values %{ $CPAN::META->{readwrite}{'CPAN::Distribution'} || {} }) { + my $failed = ""; + NAY: for my $nosayer ( # order matters! + "unwrapped", diff --git a/dev/import-perl5/patches/CPAN.pm.patch b/dev/import-perl5/patches/CPAN.pm.patch new file mode 100644 index 0000000000..73119eb03e --- /dev/null +++ b/dev/import-perl5/patches/CPAN.pm.patch @@ -0,0 +1,39 @@ +--- perl5/cpan/CPAN/lib/CPAN.pm 2026-04-10 11:04:21 ++++ src/main/perl/lib/CPAN.pm 2026-08-10 10:12:28 +@@ -703,6 +703,13 @@ + CPAN::HandleConfig->load unless $CPAN::Config_loaded++; + CPAN->debug("mgr[$mgr] class[$class]") if $CPAN::DEBUG; + CPAN::Index->reload; ++ # Metadata caches can contain hundreds of thousands of entries. Keep ++ # startup cheap by creating their mutable session wrappers only when a ++ # command really asks to enumerate the whole class. ++ for my $id (keys %{ $META->{readonly}{$class} || {} }) { ++ $META->{readwrite}{$class}{$id} ||= ++ $class->new(ID => $id, RO => $META->{readonly}{$class}{$id}); ++ } + values %{ $META->{readwrite}{$class} }; # unsafe meta access, ok + } + +@@ -1320,7 +1327,9 @@ + $id ||= ""; + # unsafe meta access, ok? + return $META->{readwrite}{$class}{$id} if exists $META->{readwrite}{$class}{$id}; +- $META->{readwrite}{$class}{$id} ||= $class->new(ID => $id); ++ my $ro = $META->{readonly}{$class}{$id}; ++ $META->{readwrite}{$class}{$id} ||= ++ $class->new(ID => $id, defined($ro) ? (RO => $ro) : ()); + } + + #-> sub CPAN::new ; +@@ -1441,7 +1450,10 @@ + if ($foul) { + $CPAN::Frontend->mywarn("Lost build_dir detected ($foul), giving up all cached test results of currently running session.\n"); + for my $dbd (sort keys %{$self->{is_tested}}) { # distro-build-dir +- SEARCH: for my $d (sort { $a->id cmp $b->id } $CPAN::META->all_objects("CPAN::Distribution")) { ++ # build_dir and test state exist only on mutable objects touched in ++ # this session; cached read-only distributions cannot match here. ++ SEARCH: for my $d (sort { $a->id cmp $b->id } ++ values %{ $CPAN::META->{readwrite}{'CPAN::Distribution'} || {} }) { + if ($d->{build_dir} && $d->{build_dir} eq $dbd) { + $CPAN::Frontend->mywarn(sprintf "Flushing cache for %s\n", $d->pretty_id); + $d->fforce(""); diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a2d5e99a4c..4dbb3bb8af 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,24 +4,24 @@ bouncycastle = "1.85" commons-compress = "1.28.0" commons-csv = "1.14.1" icu4j = "78.3" -junit-jupiter = "6.1.2" -jsoup = "1.22.2" -snakeyaml-engine = "3.0.1" -sqlite-jdbc = "3.53.2.0" +jsoup = "1.23.1" +junit-jupiter = "6.1.3" +snakeyaml-engine = "3.1.1" +sqlite-jdbc = "3.53.2.1" tomlj = "1.1.1" [libraries] asm = { module = "org.ow2.asm:asm", version.ref = "asm" } asm-util = { module = "org.ow2.asm:asm-util", version.ref = "asm" } bcpkix = { module = "org.bouncycastle:bcpkix-jdk18on", version.ref = "bouncycastle" } -bcprov = { module = "org.bouncycastle:bcprov-jdk18on", version.ref = "bouncycastle" } +bcprov = "org.bouncycastle:bcprov-jdk18on:1.85.2" commons-compress = { module = "org.apache.commons:commons-compress", version.ref = "commons-compress" } commons-csv = { module = "org.apache.commons:commons-csv", version.ref = "commons-csv" } icu4j = { module = "com.ibm.icu:icu4j", version.ref = "icu4j" } +jsoup = { module = "org.jsoup:jsoup", version.ref = "jsoup" } junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit-jupiter" } junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit-jupiter" } junit-jupiter-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "junit-jupiter" } -jsoup = { module = "org.jsoup:jsoup", version.ref = "jsoup" } snakeyaml-engine = { module = "org.snakeyaml:snakeyaml-engine", version.ref = "snakeyaml-engine" } sqlite-jdbc = { module = "org.xerial:sqlite-jdbc", version.ref = "sqlite-jdbc" } tomlj = { module = "org.tomlj:tomlj", version.ref = "tomlj" } @@ -30,4 +30,4 @@ tomlj = { module = "org.tomlj:tomlj", version.ref = "tomlj" } cyclonedx = "org.cyclonedx.bom:2.3.0" ospackage = "com.netflix.nebula.ospackage:12.3.0" shadow = "com.gradleup.shadow:9.3.1" -version-catalog-update = "nl.littlerobots.version-catalog-update:1.1.0" +version-catalog-update = "nl.littlerobots.version-catalog-update:1.1.1" diff --git a/pom.xml b/pom.xml index 3227048523..b6a1c54645 100644 --- a/pom.xml +++ b/pom.xml @@ -31,19 +31,19 @@ org.junit.jupiter junit-jupiter-api - 6.1.2 + 6.1.3 test org.junit.jupiter junit-jupiter-engine - 6.1.2 + 6.1.3 test org.junit.jupiter junit-jupiter-params - 6.1.2 + 6.1.3 test @@ -54,7 +54,7 @@ org.snakeyaml snakeyaml-engine - 3.0.1 + 3.1.1 org.tomlj @@ -74,12 +74,12 @@ org.xerial sqlite-jdbc - 3.53.2.0 + 3.53.2.1 org.bouncycastle bcprov-jdk18on - 1.85 + 1.85.2 org.bouncycastle @@ -89,7 +89,7 @@ io.netty netty-codec-http - 4.2.16.Final + 4.2.17.Final diff --git a/src/main/perl/lib/Pod/Man.pm b/src/main/perl/lib/Pod/Man.pm index bfa2f74b51..f0fea739fa 100644 --- a/src/main/perl/lib/Pod/Man.pm +++ b/src/main/perl/lib/Pod/Man.pm @@ -12,7 +12,7 @@ # Modules and declarations ############################################################################## -package Pod::Man v6.0.2; +package Pod::Man v6.1.0; use 5.012; use parent qw(Pod::Simple); @@ -294,7 +294,7 @@ sub init_fonts { # implementations what fixed bold-italic may be called (if it's even # available), so default to just bold. #<<< - $self->{opt_fixed} ||= 'CW'; + $self->{opt_fixed} ||= 'CR'; $self->{opt_fixedbold} ||= 'CB'; $self->{opt_fixeditalic} ||= 'CI'; $self->{opt_fixedbolditalic} ||= 'CB'; @@ -548,6 +548,8 @@ sub quote_literal { ^\s* (?: ( [\'\"] ) .* \1 # already quoted + | \x{201C} .* \x{201D} # already quoted (Unicode) + | . \" # one character and double quote | \\\*\(Aq .* \\\*\(Aq # quoted and escaped | \\?\` .* ( \' | \\?\` | \\\*\(Aq ) # `quoted' or `quoted` | $extra @@ -1085,11 +1087,15 @@ $preamble .\\" .IX Title $index .TH $name $section $date $release $center -.\\" For nroff, turn off justification. Always turn off hyphenation; it makes -.\\" way too many mistakes in technical documents. +.\\" For nroff, turn off justification. Always turn off hyphenation. String +.\\" and register settings are required by groff 1.23.0 and later. Changing +.\\" tag separation back to 1n is required by groff 1.24.0 and later. +.if n .ds AD l .if n .ad l +.nr HY 0 .nh ----END OF HEADER---- +#"# unconfuse Emacs cperl-mode # If the language was specified, output the language configuration. if ($self->{opt_language}) { @@ -1462,7 +1468,12 @@ sub item_common { # Now, output the item tag itself. $item = $self->mapfonts($item, '\fR'); - $self->output($self->switchquotes('.IP', $item, $$self{INDENT})); + if ($type eq 'bullet' || $type eq 'number') { + $self->output($self->switchquotes('.IP', $item, $$self{INDENT})); + } else { + $self->output(".TP $$self{INDENT}\n"); + $self->output($self->protect("$item\n")); + } $$self{NEEDSPACE} = 0; $$self{ITEMS}++; $$self{SHIFTWAIT} = 0; @@ -1620,9 +1631,6 @@ sub preamble_template { . \} .\} .rr rF -.\" -.\" Required to disable full justification in groff 1.23.0. -.if n .ds AD l ----END OF PREAMBLE---- if ($$self{ENCODING} eq 'roff') { @@ -1707,8 +1715,9 @@ __END__ =for stopwords en em ALLCAPS teeny fixedbold fixeditalic fixedbolditalic stderr utf8 UTF-8 Allbery Sean Burke Ossanna Solaris formatters troff uppercased Christiansen -nourls parsers Kernighan lquote rquote unrepresentable mandoc NetBSD PostScript -SMP macOS EBCDIC fallbacks manref reflowed reflowing FH overridable +nourls parsers Kernighan lquote rquote unrepresentable mandoc NetBSD +PostScript SMP macOS EBCDIC fallbacks manref reflowed reflowing FH overridable +intersentence =head1 NAME @@ -1742,7 +1751,7 @@ backward-compatible output mangling on such systems, set the C option to C (the default in earlier Pod::Man versions). See the C option and L for more details. -See L for the versions of Pod::Man with significant +See L for the versions of Pod::Man with significant backward-incompatible changes (other than constructor options, whose versions are documented below), and the versions of Perl that included them. @@ -1765,15 +1774,18 @@ this option is not specified, is C. =item date -[4.00] Sets the left-hand footer for the C<.TH> macro. If this option is not -set, the contents of the environment variable POD_MAN_DATE, if set, will be -used. Failing that, the value of SOURCE_DATE_EPOCH, the modification date of -the input file, or the current time if stat() can't find that file (which will -be the case if the input is from C) will be used. If taken from any -source other than POD_MAN_DATE (which is used verbatim), the date will be +[4.00] Sets the centered page footer for the C<.TH> macro. If this option is +not set, the contents of the environment variable POD_MAN_DATE, if set, will +be used. Failing that, the value of SOURCE_DATE_EPOCH, the modification date +of the input file, or the current time if stat() can't find that file (which +will be the case if the input is from C) will be used. If taken from +any source other than POD_MAN_DATE (which is used verbatim), the date will be formatted as C and will be based on UTC (so that the output will be reproducible regardless of local time zone). +Note that some system C macro sets assume that the centered footer will be +a modification date and will prepend something like C. + =item encoding [5.00] Specifies the encoding of the output. The value must be an encoding @@ -1826,8 +1838,9 @@ The default is C. =item fixed -[1.00] The fixed-width font to use for verbatim text and code. Defaults to -C. Some systems prefer C instead. Only matters for B output. +[6.1.0] The fixed-width font to use for verbatim text and code. Defaults to +C. Solaris systems historically preferred C instead. Only matters +for B output. =item fixedbold @@ -1976,14 +1989,10 @@ options is set, C or C overrides C. =item release -[1.00] Set the centered footer for the C<.TH> macro. By default, this is set -to the version of Perl you run Pod::Man under. Setting this to the empty -string will cause some *roff implementations to use the system default value. - -Note that some system C macro sets assume that the centered footer will be -a modification date and will prepend something like C. If -this is the case for your target system, you may want to set C to the -last modified date and C to the version number. +[1.12] Set the left-hand page footer for the C<.TH> macro. By default, this +is set to the version of Perl you run Pod::Man under. Setting this to the +empty string will cause some *roff implementations to use the system default +value. =item section @@ -2201,7 +2210,7 @@ B, it's behavior is probably the same as the BSD hosts. Notes: -=over 4 +=over 5 =item [1] @@ -2331,13 +2340,17 @@ also dropped attempts to add subtle formatting corrections in the output that would only be visible when typeset with B, which had previously been a significant source of bugs. -Pod::Man v6.0.0 and later unconditionally convert C<-> to the C<\-> *roff -escape, representing an ASCII hyphen-minus. Earlier versions attempted to use -heuristics to decide when a given C<-> character should translate to a -hyphen-minus or a true hyphen, but these heuristics were buggy and fragile. -v6.0.0 and later also unconditionally convert C<`> and C<'> to ASCII grave -accent and apostrophe marks instead of the default *roff behavior of -interpreting them as paired quotes. +Pod::Man v6.0.0 and later, included in Perl 5.41.2, unconditionally convert +C<-> to the C<\-> *roff escape, representing an ASCII hyphen-minus. Earlier +versions attempted to use heuristics to decide when a given C<-> character +should translate to a hyphen-minus or a true hyphen, but these heuristics were +buggy and fragile. v6.0.0 and later also unconditionally convert C<`> and +C<'> to ASCII grave accent and apostrophe marks instead of the default *roff +behavior of interpreting them as paired quotes. + +Pod::Man v6.1.0 and later use C as the default fixed-width font instead of +C, as was used in previous versions. This should only matter for B +output. =head1 BUGS @@ -2355,32 +2368,60 @@ nice to support as an option for those who want to use it. =head2 Sentence spacing +It is difficult to write POD documents such that the resulting *roff output +has consistent intersentence spacing. For most documents, writing the POD +using whatever conventions you prefer and letting the *roff output be +inconsistent is probably the best trade-off to make. But if you want to dive +into the details, read on. + Pod::Man copies the input spacing verbatim to the output *roff document. This -means your output will be affected by how B generally handles sentence -spacing. +means your output will be affected by how *roff handles sentence spacing. -B dates from an era in which it was standard to use two spaces after +*roff dates from an era in which it was standard to use two spaces after sentences, and will always add two spaces after a line-ending period (or -similar punctuation) when reflowing text. For example, the following input: +similar punctuation) when reflowing text, with one exception mentioned below. +For example, the following input: =pod One sentence. Another sentence. -will result in two spaces after the period when the text is reflowed. If you -use two spaces after sentences anyway, this will be consistent, although you -will have to be careful to not end a line with an abbreviation such as C -or C. Output will also be consistent if you use the *roff style guide -(and L) recommendation of putting a line -break after each sentence, although that will consistently produce two spaces -after each sentence, which may not be what you want. - -If you prefer one space after sentences (which is the more modern style), you -will unfortunately need to ensure that no line in the middle of a paragraph -ends in a period or similar sentence-ending paragraph. Otherwise, B -will add a two spaces after that sentence when reflowing, and your output -document will have inconsistent spacing. +will result in two spaces after the period in B output when the text is +reflowed. + +One significant exception, however, is that different versions of groff vary +in their interpretation of C<."> (a sentence ending with an ASCII double +quote). Versions of groff prior to 1.24.0 treat this as the end of a sentence +if there are two spaces after the closing quote, or if it comes at the end of +a line. Later versions will never treat this as the end of a sentence and +will collapse any following spaces down to a single space. For consistent +behavior for documents written in POD, you must use Unicode double quotes +(C<“”>, U+201C and U+201D) and declare UTF-8 encoding (or some other Unicode +encoding). The Unicode closing double-quote, when preceded by a period and +followed by two spaces or the end of the line, will always be interpreted as +the end of a sentence in modern versions of groff. + +Therefore, if you want two spaces after sentences in the B output, you +can achieve this by using Unicode double quotes and using two spaces after +periods that end a sentence. You will have to be careful to not end a line +with an abbreviation such as C or C. Alternately, you can use the +*roff style guide (and L) recommendation of +putting a line break after each sentence, but you will still need to use +Unicode double quotes. + +If you prefer one space after sentences (which is the more modern style), your +best option is to configure your local *roff installation to always format man +pages that way, rather than attempt to force this result via your POD source. +For example, for groff, L documents putting: + + .\" Put only one space after the end of a sentence. + .ss 12 0 \" See groff(7). + +in F (on Debian-derived systems, +F is used instead). This will affect all man pages +formatted with groff on that system, regardless of how their source is +formatted. =head2 Hyphens and quotes @@ -2422,7 +2463,7 @@ recognition and all bugs are mine. =head1 COPYRIGHT AND LICENSE -Copyright 1999-2020, 2022-2024 Russ Allbery +Copyright 1999-2020, 2022-2026 Russ Allbery Substantial contributions by Sean Burke . diff --git a/src/main/perl/lib/Pod/ParseLink.pm b/src/main/perl/lib/Pod/ParseLink.pm index 7b0fda34cc..325802becc 100644 --- a/src/main/perl/lib/Pod/ParseLink.pm +++ b/src/main/perl/lib/Pod/ParseLink.pm @@ -11,7 +11,7 @@ # Modules and declarations ############################################################################## -package Pod::ParseLink v6.0.2; +package Pod::ParseLink v6.1.0; use 5.012; use warnings; diff --git a/src/main/perl/lib/Pod/Text.pm b/src/main/perl/lib/Pod/Text.pm index e89b01d262..0b08fe6884 100644 --- a/src/main/perl/lib/Pod/Text.pm +++ b/src/main/perl/lib/Pod/Text.pm @@ -12,7 +12,7 @@ # Modules and declarations ############################################################################## -package Pod::Text v6.0.2; +package Pod::Text v6.1.0; use 5.012; use parent qw(Pod::Simple); @@ -313,7 +313,7 @@ sub output { $$self{ENCODING} = $encoding; } } - if ($encoding) { + if ($encoding && $encoding ne 'none') { my $check = sub { my ($char) = @_; my $display = '"\x{' . hex($char) . '}"'; @@ -651,10 +651,12 @@ sub cmd_c { }xms; } $text =~ m{ - ^\s* + \A\s* (?: ( [\'\`\"] ) .* \1 # already quoted | \` .* \' # `quoted' + | \x{201C} .* \x{201D} # already quoted (Unicode) + | . \" # one character and double quote | $extra ) \s*\z @@ -921,18 +923,25 @@ with the POD rendered and the code left intact. =item encoding -[5.00] Specifies the encoding of the output. The value must be an encoding -recognized by the L module (see L). If the output -contains characters that cannot be represented in this encoding, that is an -error that will be reported as configured by the C option. If error -handling is other than C, the unrepresentable character will be replaced -with the Encode substitution character (normally C). +[6.1.0] Specifies the encoding of the output. The value must be an encoding +recognized by the L module (see L) or the special +value C. If the output contains characters that cannot be represented +in this encoding, that is an error that will be reported as configured by the +C option. If error handling is other than C, the unrepresentable +character will be replaced with the Encode substitution character (normally +C). If the output file handle has a PerlIO encoding layer set, this parameter will be ignored and no encoding will be done by Pod::Man. It will instead rely on the encoding layer to make whatever output encoding transformations are desired. +As a special case, if the encoding is set to C, no encoding will be done +and characters will be output in Perl's internal representation. This option +only makes sense in combination with output_string(). It is intended for +special cases when the results of formatting are kept in memory and will be +encoded for output at some later step. + WARNING: The input encoding of the POD source is independent from the output encoding, and setting this option does not affect the interpretation of the POD input. Unless your POD source is US-ASCII, its encoding should be @@ -1078,7 +1087,7 @@ to the scalar variable pointed to by REF, rather than C. For example: $man->parse_file('/some/input/file'); Be aware that the output in that variable will already be encoded (see -L). +L) unless the C option to Pod::Text is set to C. =item parse_file(PATH) @@ -1211,6 +1220,8 @@ encoding changes. The L module is now used for all output encoding rather than PerlIO layers, which fixes earlier problems with output to scalars. +Pod::Text 6.1.0 added support for the C option to C. + =head1 CAVEATS Line wrapping is done only at ASCII spaces and tabs, rather than using a @@ -1226,15 +1237,15 @@ Pod::Simple. =head1 COPYRIGHT AND LICENSE -Copyright 1999-2002, 2004, 2006, 2008-2009, 2012-2016, 2018-2019, 2022 Russ -Allbery +Copyright 1999-2002, 2004, 2006, 2008-2009, 2012-2016, 2018-2019, 2022, +2024-2026 Russ Allbery This program is free software; you may redistribute it and/or modify it under the same terms as Perl itself. =head1 SEE ALSO -L, L, L, +L, L, L, L, L, L The current version of this module is always available from its web site at diff --git a/src/main/perl/lib/Pod/Text/Color.pm b/src/main/perl/lib/Pod/Text/Color.pm index 5212763293..f06b4d8803 100644 --- a/src/main/perl/lib/Pod/Text/Color.pm +++ b/src/main/perl/lib/Pod/Text/Color.pm @@ -10,13 +10,13 @@ # Modules and declarations ############################################################################## -package Pod::Text::Color v6.0.2; +package Pod::Text::Color v6.1.0; use 5.012; use parent qw(Pod::Text); use warnings; -use Term::ANSIColor qw(color colored); +use Term::ANSIColor qw(color colored colorstrip); ############################################################################## # Overrides @@ -25,30 +25,32 @@ use Term::ANSIColor qw(color colored); # Make level one headings bold. sub cmd_head1 { my ($self, $attrs, $text) = @_; - $text =~ s/\s+$//; + $text =~ s{ \s+ \z }{}xms; local $Term::ANSIColor::EACHLINE = "\n"; - $self->SUPER::cmd_head1 ($attrs, colored ($text, 'bold')); + $self->SUPER::cmd_head1($attrs, colored($text, 'bold')); + return; } # Make level two headings bold. sub cmd_head2 { my ($self, $attrs, $text) = @_; - $text =~ s/\s+$//; - $self->SUPER::cmd_head2 ($attrs, colored ($text, 'bold')); + $text =~ s{ \s+ \z }{}xms; + $self->SUPER::cmd_head2($attrs, colored($text, 'bold')); + return; } # Fix the various formatting codes. -sub cmd_b { return colored ($_[2], 'bold') } -sub cmd_f { return colored ($_[2], 'cyan') } -sub cmd_i { return colored ($_[2], 'yellow') } +sub cmd_b { my (undef, undef, $text) = @_; return colored($text, 'bold') } +sub cmd_f { my (undef, undef, $text) = @_; return colored($text, 'cyan') } +sub cmd_i { my (undef, undef, $text) = @_; return colored($text, 'yellow') } # Analyze a single line and return any formatting codes in effect at the end # of that line. sub end_format { my ($self, $line) = @_; - my $reset = color ('reset'); + my $reset = color('reset'); my $current; - while ($line =~ /(\e\[[\d;]+m)/g) { + while ($line =~ m{ ( \e\[ [\d;]+ m ) }xmsg) { my $code = $1; if ($code eq $reset) { undef $current; @@ -63,69 +65,80 @@ sub end_format { sub output_code { my ($self, $code) = @_; local $Term::ANSIColor::EACHLINE = "\n"; - $code = colored ($code, 'green'); - $self->output ($code); + $code = colored($code, 'green'); + $self->output($code); + return; } # Strip all of the formatting from a provided string, returning the stripped -# version. We will eventually want to use colorstrip() from Term::ANSIColor, -# but it's fairly new so avoid the tight dependency. +# version. sub strip_format { my ($self, $text) = @_; - $text =~ s/\e\[[\d;]*m//g; - return $text; + return colorstrip($text); } # We unfortunately have to override the wrapping code here, since the normal # wrapping code gets really confused by all the escape sequences. sub wrap { - my $self = shift; - local $_ = shift; - my $output = ''; - my $spaces = ' ' x $$self{MARGIN}; - my $width = $$self{opt_width} - $$self{MARGIN}; - - # $codes matches a single special sequence. $char matches any number of - # special sequences preceding a single character other than a newline. - # $shortchar matches some sequence of $char ending in codes followed by - # whitespace or the end of the string. $longchar matches exactly $width - # $chars, used when we have to truncate and hard wrap. - my $code = '(?:\e\[[\d;]+m)'; - my $char = "(?>$code*[^\\n])"; - my $shortchar = '^(' . $char . "{0,$width}(?>$code*)" . ')(?:[ \t\n]+|\z)'; - my $longchar = '^(' . $char . "{$width})"; - while (length > $width) { - if (s/$shortchar// || s/$longchar//) { + my ($self, $text) = @_; + my $output = q{}; + my $spaces = q{ } x $self->{MARGIN}; + my $width = $self->{opt_width} - $self->{MARGIN}; + + # Matches a single escape sequence. + my $code = qr{ (?: \e\[ [\d;]+ m ) }xms; + + # Matches any number of escape sequences preceding a single character + # other than a newline. Prevent backtracking to optimize the final + # regular expression matching since $code is complex. + my $char = qr{ (?> $code* [^\n] ) }xms; + + # Matches some sequence of $char up to $width characters, ending in codes + # followed by whitespace or the end of the string. This detects a valid + # break point. The extracted text is placed in $1. + my $shortchar = qr{ + \A + ( ${char}{0,$width} (?> $code* ) ) + (?: [ \t\n]+ | \z ) + }xms; + + # Matches exactly $width $chars, used when we have to hard wrap in the + # middle of an unbroken string. The extracted text is placed in $1. + my $longchar = qr{ \A ( ${char}{$width} ) }xms; + + # Extract one line at a time from $text and wrap it. + while (length($text) > $width) { + if ($text =~ s{$shortchar}{}xms || $text =~ s{$longchar}{}xms) { $output .= $spaces . $1 . "\n"; } else { last; } } - $output .= $spaces . $_; + $output .= $spaces . $text; # less -R always resets terminal attributes at the end of each line, so we # need to clear attributes at the end of lines and then set them again at # the start of the next line. This requires a second pass through the # wrapped string, accumulating any attributes we see, remembering them, # and then inserting the appropriate sequences at the newline. - if ($output =~ /\n/) { - my @lines = split (/\n/, $output); + if ($output =~ m{\n}xms) { + my @lines = split(m{\n}xms, $output); my $start_format; for my $line (@lines) { - if ($start_format && $line =~ /\S/) { - $line =~ s/^(\s*)(\S)/$1$start_format$2/; + if ($start_format && $line =~ m{\S}xms) { + $line =~ s{ \A (\s*) (\S) }{$1$start_format$2}xms; } - $start_format = $self->end_format ($line); + $start_format = $self->end_format($line); if ($start_format) { - $line .= color ('reset'); + $line .= color('reset'); } } - $output = join ("\n", @lines); + $output = join("\n", @lines); } # Fix up trailing whitespace and return the results. - $output =~ s/\s+$/\n\n/; - $output; + $output =~ s{ \s+ \z }{\n\n}xms; + return $output; } ############################################################################## diff --git a/src/main/perl/lib/Pod/Text/Overstrike.pm b/src/main/perl/lib/Pod/Text/Overstrike.pm index 8982c42e31..6b5384af3b 100644 --- a/src/main/perl/lib/Pod/Text/Overstrike.pm +++ b/src/main/perl/lib/Pod/Text/Overstrike.pm @@ -17,7 +17,7 @@ # Modules and declarations ############################################################################## -package Pod::Text::Overstrike v6.0.2; +package Pod::Text::Overstrike v6.1.0; use 5.012; use parent qw(Pod::Text); diff --git a/src/main/perl/lib/Pod/Text/Termcap.pm b/src/main/perl/lib/Pod/Text/Termcap.pm index b628d7a8b8..3ca6101207 100644 --- a/src/main/perl/lib/Pod/Text/Termcap.pm +++ b/src/main/perl/lib/Pod/Text/Termcap.pm @@ -10,7 +10,7 @@ # Modules and declarations ############################################################################## -package Pod::Text::Termcap v6.0.2; +package Pod::Text::Termcap v6.1.0; use 5.012; use parent qw(Pod::Text); diff --git a/src/main/perl/lib/Pod/perl.pod b/src/main/perl/lib/Pod/perl.pod index d13b04cede..55f95cde84 100644 --- a/src/main/perl/lib/Pod/perl.pod +++ b/src/main/perl/lib/Pod/perl.pod @@ -182,10 +182,13 @@ aux h2ph h2xs perlbug pl2pm pod2html pod2man splain xsubpp perlhist Perl history records perldelta Perl changes since previous version + perl5450delta Perl changes in version 5.45.0 perl5440delta Perl changes in version 5.44.0 + perl5423delta Perl changes in version 5.42.3 perl5422delta Perl changes in version 5.42.2 perl5421delta Perl changes in version 5.42.1 perl5420delta Perl changes in version 5.42.0 + perl5405delta Perl changes in version 5.40.5 perl5404delta Perl changes in version 5.40.4 perl5403delta Perl changes in version 5.40.3 perl5402delta Perl changes in version 5.40.2 diff --git a/src/main/perl/lib/Pod/perl5405delta.pod b/src/main/perl/lib/Pod/perl5405delta.pod new file mode 100644 index 0000000000..b5de354890 --- /dev/null +++ b/src/main/perl/lib/Pod/perl5405delta.pod @@ -0,0 +1,188 @@ +=encoding utf8 + +=head1 NAME + +perl5405delta - what is new for perl v5.40.5 + +=head1 DESCRIPTION + +This document describes differences between the 5.40.4 release and the 5.40.5 +release. + +If you are upgrading from an earlier release such as 5.40.3, first read +L, which describes differences between 5.40.3 and 5.40.4. + +=head1 Security + +=head2 CVE-2026-8376 - Buffer overflow in Perl_study_chunk + +Perl_study_chunk in regcomp_study.c checked the size of the joined substring +buffer in characters rather than bytes. On 32-bit builds, this can lead to an +integer overflow of the size of the buffer leading to out-of-bounds writes. + +=head2 CVE-2026-57432 - Buffer overflow in S_measure_struct + +If you call C or C to operate on a structure whose computed size +is too large to fit in memory, an integer overflow could happen that would +result in a buffer overflow. This usually happens as a result of embedding a +large number as the repeat count for an item. + +=head2 CVE-2026-13221 - Regex trie 16-bit field overflow + +The trie optimization in the regex engine could overflow in an alternation with +more than ~65k branches. This could cause both false positives and false +negatives on such regular expressions. + +=head1 Incompatible Changes + +There are no changes intentionally incompatible with 5.40.4. If any exist, +they are bugs, and we request that you submit a report. See L +below. + +=head1 Modules and Pragmata + +=head2 Updated Modules and Pragmata + +=over 4 + +=item * + +L has been upgraded from version 3.02_001 to 3.12. + +This fixes CVE-2026-9538, CVE-2026-42496, and CVE-2026-42497. + +=item * + +L has been upgraded from version 2.212 to 2.218. + +=item * + +L has been upgraded from version 0.088 to 0.096. + +This fixes CVE-2026-7010 and CVE-2026-7017. + +=item * + +L has been upgraded from version 2.212 to 2.223. + +This fixes CVE-2025-15649, CVE-2026-48961, CVE-2026-48962, and CVE-2026-48959. + +=item * + +L has been upgraded from version 5.20260329_40 to 5.20260802_40. + +=item * + +L has been upgraded from version 2.038 to 2.041. + +This fixes CVE-2026-12087. + +=item * + +L has been upgraded from version 3.32 to 3.32_01. + +This fixes CVE-2026-57433. + +=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. + +=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. + +=head2 New Diagnostics + +=head3 New Errors + +=over 4 + +=item * + +L + +(F) You called C or C to operate on a structure, whose computed +size is too large to fit in memory. This usually happens as a result of +embedding a large number as the repeat count for an item. + +=back + +=head1 Testing + +Tests were added and changed to reflect the other additions and changes in this +release. + +=head1 Acknowledgements + +Perl 5.40.5 represents approximately 4 months of development since Perl 5.40.4 +and contains approximately 4,200 lines of changes across 130 files from 15 +authors. + +Excluding auto-generated files, documentation and release tools, there were +approximately 2,000 lines of changes to 64 .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.40.5: + +Aristotle Pagaltzis, Chris 'BinGOs' Williams, David Mitchell, E. Choroba, Eric +Herman, Karen Etheridge, Karl Williamson, Leon Timmermans, Paul Evans, Paul +Marquess, Philippe Bruhat (BooK), Richard Leach, Steve Hay, Thibault +Duponchelle, 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 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. There may also be information at +L, the Perl Home Page. + +If you believe you have an unreported bug, please open an issue at +L. 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 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 program: + + perlthanks + +This will send an email to the Perl 5 Porters list with your show of thanks. + +=head1 SEE ALSO + +The F file for an explanation of how to view exhaustive details on +what changed. + +The F file for how to build Perl. + +The F file for general stuff. + +The F and F files for copyright information. + +=cut diff --git a/src/main/perl/lib/Pod/perl5423delta.pod b/src/main/perl/lib/Pod/perl5423delta.pod new file mode 100644 index 0000000000..f295d39dbb --- /dev/null +++ b/src/main/perl/lib/Pod/perl5423delta.pod @@ -0,0 +1,188 @@ +=encoding utf8 + +=head1 NAME + +perl5423delta - what is new for perl v5.42.3 + +=head1 DESCRIPTION + +This document describes differences between the 5.42.2 release and the 5.42.3 +release. + +If you are upgrading from an earlier release such as 5.42.1, first read +L, which describes differences between 5.42.1 and 5.42.2. + +=head1 Security + +=head2 CVE-2026-8376 - Buffer overflow in Perl_study_chunk + +Perl_study_chunk in regcomp_study.c checked the size of the joined substring +buffer in characters rather than bytes. On 32-bit builds, this can lead to an +integer overflow of the size of the buffer leading to out-of-bounds writes. + +=head2 CVE-2026-57432 - Buffer overflow in S_measure_struct + +If you call C or C to operate on a structure whose computed size +is too large to fit in memory, an integer overflow could happen that would +result in a buffer overflow. This usually happens as a result of embedding a +large number as the repeat count for an item. + +=head2 CVE-2026-13221 - Regex trie 16-bit field overflow + +The trie optimization in the regex engine could overflow in an alternation with +more than ~65k branches. This could cause both false positives and false +negatives on such regular expressions. + +=head1 Incompatible Changes + +There are no changes intentionally incompatible with 5.42.2. If any exist, +they are bugs, and we request that you submit a report. See L +below. + +=head1 Modules and Pragmata + +=head2 Updated Modules and Pragmata + +=over 4 + +=item * + +L has been upgraded from version 3.04 to 3.12. + +This fixes CVE-2026-9538, CVE-2026-42496, and CVE-2026-42497. + +=item * + +L has been upgraded from version 2.213 to 2.218. + +=item * + +L has been upgraded from version 0.090 to 0.096. + +This fixes CVE-2026-7010 and CVE-2026-7017. + +=item * + +L has been upgraded from version 2.213 to 2.223. + +This fixes CVE-2025-15649, CVE-2026-48961, CVE-2026-48962, and CVE-2026-48959. + +=item * + +L has been upgraded from version 5.20260329_42 to 5.20260802_42. + +=item * + +L has been upgraded from version 2.038 to 2.041. + +This fixes CVE-2026-12087. + +=item * + +L has been upgraded from version 3.37 to 3.37_01. + +This fixes CVE-2026-57433. + +=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. + +=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. + +=head2 New Diagnostics + +=head3 New Errors + +=over 4 + +=item * + +L + +(F) You called C or C to operate on a structure, whose computed +size is too large to fit in memory. This usually happens as a result of +embedding a large number as the repeat count for an item. + +=back + +=head1 Testing + +Tests were added and changed to reflect the other additions and changes in this +release. + +=head1 Acknowledgements + +Perl 5.42.3 represents approximately 4 months of development since Perl 5.42.2 +and contains approximately 4,000 lines of changes across 120 files from 14 +authors. + +Excluding auto-generated files, documentation and release tools, there were +approximately 1,700 lines of changes to 59 .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.42.3: + +Aristotle Pagaltzis, Chris 'BinGOs' Williams, E. Choroba, Eric Herman, Karen +Etheridge, Karl Williamson, Leon Timmermans, Paul Evans, Paul Marquess, +Philippe Bruhat (BooK), Richard Leach, Steve Hay, Thibault Duponchelle, 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 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. There may also be information at +L, the Perl Home Page. + +If you believe you have an unreported bug, please open an issue at +L. 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 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 program: + + perlthanks + +This will send an email to the Perl 5 Porters list with your show of thanks. + +=head1 SEE ALSO + +The F file for an explanation of how to view exhaustive details on +what changed. + +The F file for how to build Perl. + +The F file for general stuff. + +The F and F files for copyright information. + +=cut diff --git a/src/main/perl/lib/Pod/perl5440delta.pod b/src/main/perl/lib/Pod/perl5440delta.pod index 45eacdf6b2..3d9ffc9fc1 100644 --- a/src/main/perl/lib/Pod/perl5440delta.pod +++ b/src/main/perl/lib/Pod/perl5440delta.pod @@ -371,7 +371,7 @@ L has been upgraded from version 2.005002 to 2.005003. =item * -L has been upgraded from version 5.20250702 to 5.20260708. +L has been upgraded from version 5.20250702 to 5.20260715. =item * @@ -658,6 +658,14 @@ this throws an exception. =item * +L + +(F) You called C or C to operate on a structure, whose +computed size is too large to fit in memory. This usually happens as a +result of embedding a large number as the repeat count for an item. + +=item * + L<\x{%X} is a \w char that isn't valid in a name "%s" |perldiag/\x{%X} is a \w char that isn't valid in a name "%s"> diff --git a/src/main/perl/lib/Pod/perl5450delta.pod b/src/main/perl/lib/Pod/perl5450delta.pod new file mode 100644 index 0000000000..8edcaca4cc --- /dev/null +++ b/src/main/perl/lib/Pod/perl5450delta.pod @@ -0,0 +1,235 @@ +=encoding utf8 + +=head1 NAME + +perl5450delta - what is new for perl v5.45.0 + +=head1 DESCRIPTION + +This document describes differences between the 5.44.0 release and the 5.45.0 +release. + +If you are upgrading from an earlier release such as 5.43.0, first read +L, which describes differences between 5.43.0 and 5.44.0. + +=head1 Incompatible Changes + +=head2 Mutex locks for C and C are removed + +The macros C and C macros are +removed, along with their unlocking counterparts. These macros, though +never documented, were intended to create thread safety when using their +corresponding functions in a threaded-perl. But they didn't actually +furnish that, so using them would give a false sense of security. +Another thread simultaneously accessing the database could move the +pointers, so these would act unpredictably. + +=head1 Performance Enhancements + +=over 4 + +=item * + +Some pattern matches against long strings are now faster: in particular +where the pattern: is anchored; contains a short fixed substring; and +contains a floating substring which is as long or longer than than the +fixed substring; but where the fixed substring isn't present in the +target string. For example this match will be rejected much faster now: + + "-" x 10_000_000 =~ /^abc.*def/ + +=back + +=head1 Modules and Pragmata + +=head2 Updated Modules and Pragmata + +=over 4 + +=item * + +L has been upgraded from version 1.11 to 1.12. + +=item * + +L has been upgraded from version 3.63 to 3.64. + +=item * + +L has been upgraded from version 3.63 to 3.64. + +=item * + +L has been upgraded from version 1.20 to 1.21. + +=item * + +L has been upgraded from version 2.02 to 2.03. + +=item * + +L has been upgraded from version 4.16 to 4.18. + +=item * + +L has been upgraded from version 5.20260715 to 5.20260720. + +=item * + +L has been upgraded from version v6.0.2 to v6.1.0. + +=item * + +L has been upgraded from version 1.29 to 1.30. + +=item * + +L has been upgraded from version 1.302219 to 1.302222. + +=item * + +L has been upgraded from version 2.45 to 2.46. + +=item * + +L has been upgraded from version 1.73 to 1.74. + +=item * + +L has been upgraded from version 1.50 to 1.51. + +=back + +=head1 Platform Support + +=head2 Platform-Specific Notes + +=over 4 + +=item VMS + +Socket support is no longer a configure-time option on OpenVMS; sockets will +always be available in Perl and are based on the universal socket support in the +CRTL. + +=back + +=head1 Internal Changes + +=over 4 + +=item * + +Added new API function C which does the same lexical export +that the L function does. + +=back + +=head1 Selected Bug Fixes + +=over 4 + +=item * + +Allow field lookups within methods in nested scopes to succeed, +previously they could complain that C. + +This was most confusingly broken with a use: + + class A { + field $fieldname; + use overload '""' => method (@) { $fieldname }; + } + +since the syntax hides the C sub. + +[L] + +=item * + +Many potential threads-related race conditions have been fixed in the perl +core and the two L and L modules. + +=item * + +Line numbers reported by C and diagnostic messages are now more +accurate when the relevant COP has been optimized out (occurring often +when the line is the first in an C block, or when the line is +inside a loop condition (such as within a C). +[L] +[L] + +Note that (i) these changes could break any tests that hardcode the +less-accurate line numbers (ii) further improvements to line number +accuracy will hopefully follow within this development cycle. + +=back + +=head1 Acknowledgements + +Perl 5.45.1 represents approximately 1 week of development since Perl 5.44.0 +and contains approximately 36,000 lines of changes across 470 files from 19 +authors. + +Excluding auto-generated files, documentation and release tools, there were +approximately 12,000 lines of changes to 310 .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.45.1: + +Andrew Fresh, Chad Granum, Chris 'BinGOs' Williams, Craig A. Berry, Dagfinn +Ilmari Mannsåker, David Mitchell, Georgij Tsarin, Graham Knop, James E +Keenan, Karl Williamson, Leon Timmermans, Lukas Mai, Paul Evans, Philippe +Bruhat (BooK), Richard Leach, Russ Allbery, Steve Hay, Tony Cook, Yves +Orton. + +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 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. There may also be information at +L, the Perl Home Page. + +If you believe you have an unreported bug, please open an issue at +L. 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 +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 program: + + perlthanks + +This will send an email to the Perl 5 Porters list with your show of thanks. + +=head1 SEE ALSO + +The F file for an explanation of how to view exhaustive details on +what changed. + +The F file for how to build Perl. + +The F file for general stuff. + +The F and F files for copyright information. + +=cut diff --git a/src/main/perl/lib/Pod/perlclib.pod b/src/main/perl/lib/Pod/perlclib.pod index d95ebde124..065773dced 100644 --- a/src/main/perl/lib/Pod/perlclib.pod +++ b/src/main/perl/lib/Pod/perlclib.pod @@ -45,6 +45,11 @@ a way of being adapted beyond our initial expectations. If it is just as easy to use something that can be used under threads, it's better to use that now, just in case. +Perl furnishes macros that can "cure" many cases of multi-thread +problems. The functions they are generated for are listed in +L. The macros themselves are listed +alphabetically in F. + =item * In functions that deal with strings, complications may arise because the @@ -874,42 +879,98 @@ All the uses listed above are function calls, except for these: daylight MB_CUR_MAX timezone tzname -There are three main approaches to coping with issues involving these +There are various approaches to coping with issues involving these constructs, each suitable for different circumstances: =over =item * -Don't use them. Some of them have preferred alternatives. Use the list -above in L to replace your uses with ones -that are thread-friendly. For example I/O, should be done via -L. +Don't use them. + +Some of them are obsolete. For example, most functions listed above that +deal with randomness or cryptography have been superceded by other +functions that are more secure, and tend to be thread-safe. C, +for example has even been removed from some distributions. + +Others have preferred alternatives. Use the list above in L to replace your uses with ones that are +thread-friendly. For example I/O, should be done via L. + +Still others are implemented in the L module, and can be called +from XS code using the mechanisms described in L. See the +next item. + +=item * + +Use them with mutexes. + +Since v5.46, perl furnishes wrapper macros to make many of the above calls +thread-safe. If you surround a function call with the macros designed +for it that are found in F, you automatically +make it thread-safe, as long as all other executing threads have done +the same. + +Note that if the function returns results in global storage, you will +need to save it to a per-instance area before unlocking. Then you can +work on it at your leisure. This might be an automatic C variable for +non-pointers, or something as described in C>. + +(If you're writing a module, you can't guarantee the behavior of other +modules in other threads, but you can advertise that your module is +thread-safe when used with any other thread-safe module(s).) + +For example F defines the C and +C macros to wrap C with, making it +thread-safe. + +There are a few functions that are callable from Perl code that use +mutexes somewhat prior to v5.46. You can call them to get thread-safety +a little further back if you use L to access them. An example +is C. + +Otherwise, you can say that your module is thread-safe when used with +perls 5.46 or later. + +=item * + +C<#define PERL_REENTRANT> -If you must use them, many, but not all, of them will be ok as long as -their use is confined to a single thread that has no interaction with -conflicting uses in other threads. You will need to closely examine -their man pages for this, and be aware that vendor documentation is -often imprecise. +Some functions have reentrant versions on some or all systems and which don't +have races, or have fewer races than their base counterpart. You gain +automatic conversion to use these when you define this symbol prior to +including F. +See L below for details. =item * -Do all your business before any other code can change things. If you -make changes, change back before returning. +If the above items don't work for you, many, but certainly not all, of +the functions will be ok as long as their use is confined to a single +thread that has no interaction with conflicting uses in other threads. +You will need to closely examine their man pages for this, and be aware +that vendor documentation is often imprecise. + +An example of this case is the C set of functions. Perl does not +generate locking macros for functions that are used atomically in +conjunction with other functions. In the case of databases with +iterators, the open, traversal, and close must be done without +interference from other threads. As long as just a single thread +accesses a given database, there is no need for locking. If that cannot +be guaranteed, you'll have to carefully craft your own mutexes, and be +very worried about deadlock. =item * -Save the result of a query of global information to a per-instance area -before allowing another instance to execute. Then you can work on it at -your leisure. This might be an automatic C variable for non-pointers, -or something as described above in -C>. +Do all your business at initialization, before any other code can change +things. =back Without threading, you don't have to worry about being interrupted by the system giving control to another thread. With threading, you will -have to uses mutexes, and be concerned with the possibility of deadlock. +have to use mutexes, and, if not using the automatically furnished ones, +be concerned with the possibility of deadlock. =head2 Functions always unsuitable for use under multi-threads @@ -931,7 +992,7 @@ multi-thread use. Some functions perform initialization on their first call that must be done while still in a single-thread environment, but subsequent calls are -thread-safe when executed in a critical section. +thread-safe when executed in a critical section controlled by mutexes. Therefore, they must be called at least once before switching to multi-threads: @@ -971,9 +1032,9 @@ does, even if the database is not changed. For example, typically there is a global iterator for such a data base and that iterator is maintained by libc, so that each new read from any instance advances it, meaning that no instance will see all the entries. The only way to make these thread-safe -is to have an exclusive lock on a mutex from the open call through the -close. You are advised to not use such databases from more than one -instance at a time. +is to have an exclusive lock on a mutex from the open call all the way +through the close. You are advised to not use such databases from more +than one instance at a time. Other examples of functions that use a global state include pseudo-random number generators. Some libc implementations of 'rand()', for example, may @@ -1023,6 +1084,21 @@ the platform, nor if threads aren't enabled. You just write as if there weren't threads, and you get the better behavior without having to think about it. +An example is C. It has various potential races with other +threads executing related functions. POSIX 2008 added a C +reentrant version which doesn't have such races (but it does require +that the environment not change during its execution, nor the locale if +it isn't executing in a per-thread locale). If your code has defined +C, all calls to C will automatically be +converted to C on systems that implement POSIX 2008. +Further, if you have wrapped calls to C with +C/C macros, it will be +thread-safe, as long as the returned struct is copied to a safe place +before the unlock. Further, on systems with C, the calls +will have been converted to use that, and the calls to the locking +macros will be converted to use the locking macros for that function, +which have fewer things that need to be locked. + On some platforms the safer library functions may fail if the result buffer is too small (for example the user group databases may be rather large, and the reentrant functions may have to carry around a full @@ -1091,6 +1167,12 @@ alternative.) *tmpnam() ~tmpnam_r() ttyname() ttyname_r() +(There are other functions that could be added to have this behavior, +but nobody has. Patches Welcome! For example, some systems (but not +the POSIX Standard) have an C that doesn't change the global +C that plain C does. It would be fairly easy to add +that function.) + The Perl-furnished items are documented in perlapi. The bottom line is: @@ -1112,7 +1194,10 @@ If you really need to use these functions, you have two choices: Use the function in the first column as-is, and let perl do the work of substituting the function in the right column if available on the -platform, and it is deemed suitable for use. +platform, and it is deemed suitable for use. If there are locking +macros defined for it in F, wrap your calls with +them. Perl will automatically substitute whatever locking mechanism is +needed for the replacement function. You should look at the man pages for both versions to find any other gotchas. @@ -1123,7 +1208,8 @@ You should examine the application's code to determine if the column 1 function presents a real problem under threads given the circumstances it is used in. You can go directly to the column 2 replacement, but beware of the ones that are marked. Some of those may be nonexistent or -flaky on some platforms. +flaky on some platforms. If there are macros defined for the +replacement in F, wrap your calls with them. =back @@ -1136,8 +1222,11 @@ it. One instance changing the environment affects all the other instances. Under threads, any libc call that expects the environment to not change for the duration of its execution will have undefined results if another thread interrupts it at just the wrong time and changes it. -These are the functions that the man pages list as being sensitive to -that. + +Any locking macros for the functions in the list below, in +F, automatically cause the environment to be held +constant while locked, so you don't otherwise need to be concerned about +them. catopen() gethostbyname2() newlocale() ctime() gethostbyname2_r() regerror() @@ -1162,11 +1251,6 @@ that. Many of these functions are problematic under threads for other reasons as well. See the man pages for any you use. -Perl defines mutexes C and C with which -to wrap calls to these functions. You need to consider the possibility -of deadlock. It is expected that a different mechanism will be in place -and preferred for Perl v5.42. - =head2 Locale-specific issues C language programs originally had a single locale global to the entire @@ -1185,6 +1269,10 @@ the global locale are affected. Almost all the locale-related functions in the list directly under L have undefined behavior if another thread interrupts their execution and changes the locale. Under threads, another thread could do exactly that. +Starting in v5.46, if all threads wrap those function calls with the +locking macros designed for each and found in F, +that interruption doesn't happen. But, the thread may still find itself +executing in an unexpected locale, with bad results. But, on systems that have per-thread locales, starting with Perl v5.28, perl uses them after initialization; the global locale is not used @@ -1201,7 +1289,8 @@ possibility of using them. The converse is that on systems with only a global locale, having different threads using different locales is not likely to work well; -and changing the locale is dangerous, often leading to crashes. +and changing the locale is dangerous, and without use of the locking +macros, often leads to crashes. Perl has extensive code to work as well as possible on both types of systems. You should always use C to change and query diff --git a/src/main/perl/lib/Pod/perldebguts.pod b/src/main/perl/lib/Pod/perldebguts.pod index 6b715935a4..4a08e71704 100644 --- a/src/main/perl/lib/Pod/perldebguts.pod +++ b/src/main/perl/lib/Pod/perldebguts.pod @@ -560,327 +560,8 @@ C< >I: I I (I) =head2 Types of Nodes -Here are the current possible types, with short descriptions: - -=for comment -This table is generated by regen/regcomp.pl. Any changes made here -will be lost. - -=for regcomp.pl begin - - # TYPE arg-description [regnode-struct-suffix] [longjump-len] DESCRIPTION - - # Exit points - - END no End of program. - SUCCEED no Return from a subroutine, basically. - - # Line Start Anchors: - SBOL no Match "" at beginning of line: /^/, /\A/ - MBOL no Same, assuming multiline: /^/m - - # Line End Anchors: - SEOL no Match "" at end of line: /$/ - MEOL no Same, assuming multiline: /$/m - EOS no Match "" at end of string: /\z/ - - # Match Start Anchors: - GPOS no Matches where last m//g left off. - - # Word Boundary Opcodes: - BOUND no Like BOUNDA for non-utf8, otherwise like - BOUNDU - BOUNDL no Like BOUND/BOUNDU, but \w and \W are - defined by current locale - BOUNDU no Match "" at any boundary of a given type - using /u rules. - BOUNDA no Match "" at any boundary between \w\W or - \W\w, where \w is [_a-zA-Z0-9] - NBOUND no Like NBOUNDA for non-utf8, otherwise like - BOUNDU - NBOUNDL no Like NBOUND/NBOUNDU, but \w and \W are - defined by current locale - NBOUNDU no Match "" at any non-boundary of a given - type using /u rules. - NBOUNDA no Match "" between any \w\w or \W\W, where \w - is [_a-zA-Z0-9] - - # [Special] alternatives: - REG_ANY no Match any one character (except newline). - SANY no Match any one character. - ANYOF sv Match character in (or not in) this class, - charclass single char match only - ANYOFD sv Like ANYOF, but /d is in effect - charclass - ANYOFL sv Like ANYOF, but /l is in effect - charclass - ANYOFPOSIXL sv Like ANYOFL, but matches [[:posix:]] - charclass_ classes - posixl - - ANYOFH sv 1 Like ANYOF, but only has "High" matches, - none in the bitmap; the flags field - contains the lowest matchable UTF-8 start - byte - ANYOFHb sv 1 Like ANYOFH, but all matches share the same - UTF-8 start byte, given in the flags field - ANYOFHr sv 1 Like ANYOFH, but the flags field contains - packed bounds for all matchable UTF-8 start - bytes. - ANYOFHs sv:str 1 Like ANYOFHb, but has a string field that - gives the leading matchable UTF-8 bytes; - flags field is len - ANYOFR packed 1 Matches any character in the range given by - its packed args: upper 12 bits is the max - delta from the base lower 20; the flags - field contains the lowest matchable UTF-8 - start byte - ANYOFRb packed 1 Like ANYOFR, but all matches share the same - UTF-8 start byte, given in the flags field - - ANYOFHbbm none bbm Like ANYOFHb, but only for 2-byte UTF-8 - characters; uses a bitmap to match the - continuation byte - - ANYOFM byte 1 Like ANYOF, but matches an invariant byte - as determined by the mask and arg - NANYOFM byte 1 complement of ANYOFM - - # POSIX Character Classes: - POSIXD none Some [[:class:]] under /d; the FLAGS field - gives which one - POSIXL none Some [[:class:]] under /l; the FLAGS field - gives which one - POSIXU none Some [[:class:]] under /u; the FLAGS field - gives which one - POSIXA none Some [[:class:]] under /a; the FLAGS field - gives which one - NPOSIXD none complement of POSIXD, [[:^class:]] - NPOSIXL none complement of POSIXL, [[:^class:]] - NPOSIXU none complement of POSIXU, [[:^class:]] - NPOSIXA none complement of POSIXA, [[:^class:]] - - CLUMP no Match any extended grapheme cluster - sequence - - # Alternation - - # BRANCH The set of branches constituting a single choice are - # hooked together with their "next" pointers, since - # precedence prevents anything being concatenated to - # any individual branch. The "next" pointer of the last - # BRANCH in a choice points to the thing following the - # whole choice. This is also where the final "next" - # pointer of each individual branch points; each branch - # starts with the operand node of a BRANCH node. - # - BRANCH node 1 Match this alternative, or the next... - - # Literals - - EXACT str Match this string (flags field is the - length). - - # In a long string node, the U32 argument is the length, and is - # immediately followed by the string. - LEXACT len:str 1 Match this long string (preceded by length; - flags unused). - EXACTL str Like EXACT, but /l is in effect (used so - locale-related warnings can be checked for) - EXACTF str Like EXACT, but match using /id rules; - (string not UTF-8, ASCII folded; non-ASCII - not) - EXACTFL str Like EXACT, but match using /il rules; - (string not likely to be folded) - EXACTFU str Like EXACT, but match using /iu rules; - (string folded) - - EXACTFAA str 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) - EXACTFAA_NO_TRIE str Like EXACTFAA, (string not UTF-8, folded - except: MICRO, SHARP S; folded length <= - unfolded, not currently trie-able) - - EXACTFUP str Like EXACT, but match using /iu rules; - (string not UTF-8, folded except MICRO: - hence Problematic) - - EXACTFLU8 str Like EXACTFU, but use /il, UTF-8, (string - is folded, and everything in it is above - 255 - EXACT_REQ8 str Like EXACT, but only UTF-8 encoded targets - can match - LEXACT_REQ8 len:str 1 Like LEXACT, but only UTF-8 encoded targets - can match - EXACTFU_REQ8 str Like EXACTFU, but only UTF-8 encoded - targets can match - - EXACTFU_S_EDGE str /di rules, but nothing in it precludes /ui, - except begins and/or ends with [Ss]; - (string not UTF-8; compile-time only) - - # New charclass like patterns - LNBREAK none generic newline pattern - - # Trie Related - - # Behave the same as A|LIST|OF|WORDS would. The '..C' variants - # have inline charclass data (ascii only), the 'C' store it in the - # structure. - - TRIE trie 1 Match many EXACT(F[ALU]?)? at once. - flags==type - TRIEC trie Same as TRIE, but with embedded charclass - charclass data - - AHOCORASICK trie 1 Aho Corasick stclass. flags==type - AHOCORASICKC trie Same as AHOCORASICK, but with embedded - charclass charclass data - - # Do nothing types - - NOTHING no Match empty string. - # A variant of above which delimits a group, thus stops optimizations - TAIL no Match empty string. Can jump here from - outside. - - # Loops - - # STAR,PLUS '?', and complex '*' and '+', are implemented as - # circular BRANCH structures. Simple cases - # (one character per match) are implemented with STAR - # and PLUS for speed and to minimize recursive plunges. - # - STAR node Match this (simple) thing 0 or more times: - /A{0,}B/ where A is width 1 char - PLUS node Match this (simple) thing 1 or more times: - /A{1,}B/ where A is width 1 char - - CURLY sv 3 Match this (simple) thing {n,m} times: - /A{m,n}B/ where A is width 1 char - CURLYN no 3 Capture next-after-this simple thing: - /(A){m,n}B/ where A is width 1 char - CURLYM no 3 Capture this medium-complex thing {n,m} - times: /(A){m,n}B/ where A is fixed-length - CURLYX sv 3 Match/Capture this complex thing {n,m} - times. - - # This terminator creates a loop structure for CURLYX - WHILEM no Do curly processing and see if rest - matches. - - # Buffer related - - # OPEN,CLOSE,GROUPP ...are numbered at compile time. - OPEN num 1 Mark this point in input as start of #n. - CLOSE num 1 Close corresponding OPEN of #n. - SROPEN none Same as OPEN, but for script run - SRCLOSE none Close preceding SROPEN - - REF num 2 Match some already matched string - REFF num 2 Match already matched string, using /di - rules. - REFFL num 2 Match already matched string, using /li - rules. - REFFU num 2 Match already matched string, using /ui. - REFFA num 2 Match already matched string, using /aai - rules. - - # Named references. Code in regcomp.c assumes that these all are after - # the numbered references - REFN no-sv 2 Match some already matched string - REFFN no-sv 2 Match already matched string, using /di - rules. - REFFLN no-sv 2 Match already matched string, using /li - rules. - REFFUN num 2 Match already matched string, using /ui - rules. - REFFAN num 2 Match already matched string, using /aai - rules. - - # Support for long RE - LONGJMP off 1 1 Jump far away. - BRANCHJ off 2 1 BRANCH with long offset. - - # Special Case Regops - IFMATCH off 1 1 Succeeds if the following matches; non-zero - flags "f", next_off "o" means lookbehind - assertion starting "f..(f-o)" characters - before current - UNLESSM off 1 1 Fails if the following matches; non-zero - flags "f", next_off "o" means lookbehind - assertion starting "f..(f-o)" characters - before current - SUSPEND off 1 1 "Independent" sub-RE. - IFTHEN off 1 1 Switch, should be preceded by switcher. - GROUPP num 1 Whether the group matched. - - # The heavy worker - - EVAL evl/flags Execute some Perl code. - 2 - - # Modifiers - - MINMOD no Next operator is not greedy. - LOGICAL no Next opcode should set the flag only. - - # This is not used yet - RENUM off 1 1 Group with independently numbered parens. - - # Regex Subroutines - GOSUB num/ofs 2 recurse to paren arg1 at (signed) ofs arg2 - - # Special conditionals - GROUPPN no-sv 1 Whether the group matched. - INSUBP num 1 Whether we are in a specific recurse. - DEFINEP none 1 Never execute directly. - - # Backtracking Verbs - ENDLIKE none Used only for the type field of verbs - OPFAIL no-sv 1 Same as (?!), but with verb arg - ACCEPT no-sv/num Accepts the current matched string, with - 2 verbar - - # Verbs With Arguments - VERB no-sv 1 Used only for the type field of verbs - PRUNE no-sv 1 Pattern fails at this startpoint if no- - backtracking through this - MARKPOINT no-sv 1 Push the current location for rollback by - cut. - SKIP no-sv 1 On failure skip forward (to the mark) - before retrying - COMMIT no-sv 1 Pattern fails outright if backtracking - through this - CUTGROUP no-sv 1 On failure go to the next alternation in - the group - - # Control what to keep in $&. - KEEPS no $& begins here. - - # Validate that lookbehind IFMATCH and UNLESSM end at the right place - LOOKBEHIND_END no Return from lookbehind (IFMATCH/UNLESSM) - and validate position - - # SPECIAL REGOPS - - # This is not really a node, but an optimized away piece of a "long" - # node. To simplify debugging output, we mark it as if it were a node - OPTIMIZED off Placeholder for dump. - - # Special opcode with the property that no opcode in a compiled program - # will ever be of this type. Thus it can be used as a flag value that - # no other opcode has been seen. END is used similarly, in that an END - # node can't be optimized. So END implies "unoptimizable" and PSEUDO - # mean "not seen anything to optimize yet". - PSEUDO off Pseudo opcode for internal use. - - REGEX_SET depth p Regex set, temporary node used in pre- - optimization compilation - -=for regcomp.pl end +The current regop definitions are documented in L. + =for unprinted-credits Next section M-J. Dominus (mjd-perl-patch+@plover.com) 20010421 diff --git a/src/main/perl/lib/Pod/perldelta.pod b/src/main/perl/lib/Pod/perldelta.pod index bcff1cd571..1ca60e6a7d 100644 --- a/src/main/perl/lib/Pod/perldelta.pod +++ b/src/main/perl/lib/Pod/perldelta.pod @@ -5,15 +5,15 @@ [ this is a template for a new perldelta file. Any text flagged as XXX needs to be processed before release. ] -perldelta - what is new for perl v5.45.0 +perldelta - what is new for perl v5.45.1 =head1 DESCRIPTION -This document describes differences between the 5.44.0 release and the 5.45.0 +This document describes differences between the 5.45.0 release and the 5.45.1 release. -If you are upgrading from an earlier release such as 5.43.0, first read -L, which describes differences between 5.43.0 and 5.44.0. +If you are upgrading from an earlier release such as 5.44.0, first read +L, which describes differences between 5.44.0 and 5.45.0. =head1 Notice @@ -27,6 +27,22 @@ here, but most should go in the L section. [ List each enhancement as a =head2 entry ] +=head2 Magic v2 + +This version introduces a whole new set of API functions, data structures, and +related items that provides a new kind of variable magic; providing the +ability to attach user-supplied trigger functions to behaviours on existing +variables. + +The eventual intention of this new version is to extend magic with new trigger +functions that can apply at different times to those currently supported, and +to allow magic to be attached to new kinds of items than are currently +permitted. Right now as of this iteration, it does not offer any new abilities +but simply changes the shape and structure of existing things to allow space +for those extensions to be made at a later date. + +For more details, see L. + =head1 Security XXX Any security-related notices go here. In particular, any security @@ -89,6 +105,26 @@ There may well be none in a stable release. =item * +C has been added to streamline expressions such as +C<(ref $x eq 'SCALAR')> where (i) the first operator is C or +C, (ii) the comparison is C or C, and (iii) the value +being compared against is one of the internal reftype strings mentioned +in L, is C, or is the empty string C<''>. + +=item * + +Counting the number of matches within a string using the following common +idiom is now more streamlined. + + C + +Instead of pushing all matches to the stack as mortal SVs, just so that +the list assignment can count them, C maintains an internal +count during matching and pushes just that upon completion. +[GH #24558] + +=item * + XXX =back @@ -350,6 +386,48 @@ well. XXX +=item * + +Mutex locks for C and C are removed + +The macros C and C macros are +removed, along with their unlocking counterparts. These macros, though +never documented, were intended to create thread safety when using their +corresponding functions in a threaded-perl. But they didn't actually +furnish that, so using them would give a false sense of security. +Another thread simultaneously accessing the database could move the +pointers, so these would act unpredictably. + +=item * + +New macros created for thread-safety in libc calls + +Many C library functions are not thread safe, but can be made so by +using mutexes around them to lock out other threads from interrupting +their execution. Many macros have now been created for this purpose. +Guidance for using them, and the functions they protect are listed in +L; their actual definitions are found in +F. If you call a libc function, look in +L to see if we have created locking macros for it. The macros +are based on man pages (especially Linux ones), and our experience. We +also know from experience that man pages can be wrong or incomplete, and +the behavior of any given function may be platform dependent. Patches +to update our knowledge base are welcome. + +More detail can be found in +L. + +=item * + +During compiletime of a named subroutine, the name of the new sub +currently being compiled is now accessible via C. + +=item * + +A new internal function, C attaches an SV onto a +PADNAME instance, which is used to store the name string of that padname. +This SV can be used by code that wishes to attach magic onto the padname. + =back =head1 Selected Bug Fixes @@ -366,20 +444,26 @@ manager will later use a regex to expand these into links. =item * -Allow field lookups within methods in nested scopes to succeed, -previously they could complain that C. +Cleanup of field initialization ops for an incomplete class now +happens within the correct CV. Previously, if an error was thrown +with an incomplete class this would release pad entries on the wrong +CV and eventually crash. [GH #24616] -This was most confusingly broken with a use: +=item * + +sv_set_undef() no longer blindly clears the C flag. This +could break code that expected to detect mortal SVs, like constant +folding. [GH #24661] - class A { - field $fieldname; - use overload '""' => method (@) { $fieldname }; - } +=item * -since the syntax hides the C sub. +The regular expression engine's "super-linear cache" wasn't 64-bit clean +and so could in principle overflow on huge (>256Mb) strings, resulting in +incorrect matches and potential memory corruption. (The cache engages on +nested variable-width patterns such as C, to avoid exponential +backtracking.) -[GH #24464] +[GH security issue #149] =back @@ -419,7 +503,7 @@ died, add a short obituary here. XXX Generate this with: - perl Porting/acknowledgements.pl v5.44.0..HEAD + perl Porting/acknowledgements.pl v5.45.1..HEAD =head1 Reporting Bugs diff --git a/src/main/perl/lib/Pod/perldiag.pod b/src/main/perl/lib/Pod/perldiag.pod index 65d00c4ba9..fef39ad173 100644 --- a/src/main/perl/lib/Pod/perldiag.pod +++ b/src/main/perl/lib/Pod/perldiag.pod @@ -737,6 +737,11 @@ not a scalar (i.e. an array or hash). At the present version, these are only permitted on scalar fields. You will have to manually create a writer accessor method yourself. +=item Cannot apply magicfuncs shape %d to SV type %d + +(F) An XS module attempted to attach a Magic v2 structure to an SV, but the +value of its C field is not compatible with the type of the SV. + =item Cannot assign :param(%s) to field %s because that name is already in use (F) An attempt was made to apply a parameter name to a field, when the name @@ -7617,6 +7622,12 @@ whereabouts in the regular expression the escape was discovered. (F) You attempted to add a named attribute to a C definition, but perl does not recognise the name of the requested attribute. +=item Unrecognized magicfuncs->shape value %d + +(F) An XS module attempted to attach a Magic v2 structure to an SV, but the +value of its C field is not one of the recognised constants. This must +take one of the C values listed in L. + =item Unrecognized named parameter '%s' to subroutine '%s' =item Unrecognized named parameters '%s' to subroutine '%s' @@ -7670,6 +7681,16 @@ Note that under some systems, like OS/2, there may be different flavors of Perl executables, some of which may support fork, some not. Try changing the name you call Perl by to C, C, and so on. +=item Unsupported MagicFunctions->ver value of %u + +(F) An XS module attempted to attach a Magic v2 structure to an SV, but the +value of its C field is not supported as a valid version. + +If the reported value is zero, it is likely the author forgot to initialise +that field of the structure. If the number is larger than 2, it likely means +the XS module is written for a later version of Magic than this version of +perl can support. + =item Unsupported script encoding %s (F) Your program file begins with a Unicode Byte Order Mark (BOM) which diff --git a/src/main/perl/lib/Pod/perlembed.pod b/src/main/perl/lib/Pod/perlembed.pod index 66c20de3e9..435c75fffe 100644 --- a/src/main/perl/lib/Pod/perlembed.pod +++ b/src/main/perl/lib/Pod/perlembed.pod @@ -153,13 +153,13 @@ change the path following the C<-I>. You may have to add extra libraries as well. Which ones? Perhaps those printed by - perl -MConfig -e 'print $Config{libs}' + perl -MConfig -e 'print $Config{libs}' Provided your perl binary was properly configured and installed the B module will determine all of this information for you: - % cc -o interp interp.c `perl -MExtUtils::Embed -e ccopts -e ldopts` + % cc -o interp interp.c `perl -MExtUtils::Embed -e ccopts -e ldopts` If the B module isn't part of your Perl distribution, you can retrieve it from @@ -185,16 +185,16 @@ version of I containing the essentials of embedding: int main(int argc, char **argv, char **env) { - PERL_SYS_INIT3(&argc,&argv,&env); - my_perl = perl_alloc(); - perl_construct(my_perl); - PL_exit_flags |= PERL_EXIT_DESTRUCT_END; - perl_parse(my_perl, NULL, argc, argv, (char **)NULL); - perl_run(my_perl); - perl_destruct(my_perl); - perl_free(my_perl); - PERL_SYS_TERM(); - exit(EXIT_SUCCESS); + PERL_SYS_INIT3(&argc,&argv,&env); + my_perl = perl_alloc(); + perl_construct(my_perl); + PL_exit_flags |= PERL_EXIT_DESTRUCT_END; + perl_parse(my_perl, NULL, argc, argv, (char **)NULL); + perl_run(my_perl); + perl_destruct(my_perl); + perl_free(my_perl); + PERL_SYS_TERM(); + exit(EXIT_SUCCESS); } Notice that we don't use the C pointer. Normally handed to @@ -248,30 +248,30 @@ In this example we'll use C. That's shown below, in a program I'll call I. - #include - #include + #include + #include - static PerlInterpreter *my_perl; + static PerlInterpreter *my_perl; - int main(int argc, char **argv, char **env) - { - char *args[] = { NULL }; - PERL_SYS_INIT3(&argc,&argv,&env); - my_perl = perl_alloc(); - perl_construct(my_perl); + int main(int argc, char **argv, char **env) + { + char *args[] = { NULL }; + PERL_SYS_INIT3(&argc,&argv,&env); + my_perl = perl_alloc(); + perl_construct(my_perl); - perl_parse(my_perl, NULL, argc, argv, NULL); - PL_exit_flags |= PERL_EXIT_DESTRUCT_END; + perl_parse(my_perl, NULL, argc, argv, NULL); + PL_exit_flags |= PERL_EXIT_DESTRUCT_END; - /*** skipping perl_run() ***/ + /*** skipping perl_run() ***/ - call_argv("showtime", G_DISCARD | G_NOARGS, args); + call_argv("showtime", G_DISCARD | G_NOARGS, args); - perl_destruct(my_perl); - perl_free(my_perl); - PERL_SYS_TERM(); - exit(EXIT_SUCCESS); - } + perl_destruct(my_perl); + perl_free(my_perl); + PERL_SYS_TERM(); + exit(EXIT_SUCCESS); + } where I is a Perl subroutine that takes no arguments (that's the I) and for which I'll ignore the return value (that's the @@ -279,18 +279,18 @@ I). Those flags, and others, are discussed in L. I'll define the I subroutine in a file called I: - print "I shan't be printed."; + print "I shan't be printed."; - sub showtime { - print time; - } + sub showtime { + print time; + } Simple enough. Now compile and run: - % cc -o showtime showtime.c \ - `perl -MExtUtils::Embed -e ccopts -e ldopts` - % showtime showtime.pl - 818284590 + % cc -o showtime showtime.c \ + `perl -MExtUtils::Embed -e ccopts -e ldopts` + % showtime showtime.pl + 818284590 yielding the number of seconds that elapsed between January 1, 1970 (the beginning of the Unix epoch), and the moment I began writing this @@ -364,19 +364,19 @@ If you compile and run I, you'll see the results of using I to create an C, I to create a C, and I to create a string: - a = 9 - a = 9.859600 - a = Just Another Perl Hacker + a = 9 + a = 9.859600 + a = Just Another Perl Hacker In the example above, we've created a global variable to temporarily store the computed value of our eval'ed expression. It is also possible and in most cases a better strategy to fetch the return value from I instead. Example: - ... - SV *val = eval_pv("reverse 'rekcaH lreP rehtonA tsuJ'", TRUE); - printf("%s\n", SvPV_nolen(val)); - ... + ... + SV *val = eval_pv("reverse 'rekcaH lreP rehtonA tsuJ'", TRUE); + printf("%s\n", SvPV_nolen(val)); + ... This way, we avoid namespace pollution by not creating global variables and we've simplified our code as well. @@ -387,20 +387,20 @@ The I function lets us evaluate strings of Perl code, so we can define some functions that use it to "specialize" in matches and substitutions: I, I, and I. - I32 match(SV *string, char *pattern); + I32 match(SV *string, char *pattern); Given a string and a pattern (e.g., C or C, which in your C program might appear as "/\\b\\w*\\b/"), match() returns 1 if the string matches the pattern and 0 otherwise. - int substitute(SV **string, char *pattern); + int substitute(SV **string, char *pattern); Given a pointer to an C and an C<=~> operation (e.g., C or C), substitute() modifies the string within the C as according to the operation, returning the number of substitutions made. - SSize_t matches(SV *string, char *pattern, AV **matches); + SSize_t matches(SV *string, char *pattern, AV **matches); Given an C, a pattern, and a pointer to an empty C, matches() evaluates C<$string =~ $pattern> in a list context, and @@ -450,7 +450,7 @@ been wrapped here): SV *command = newSV(0), *retval; sv_setpvf(command, "my $string = '%s'; $string =~ %s", - SvPV_nolen(string), pattern); + SvPV_nolen(string), pattern); retval = my_eval_sv(command, TRUE); SvREFCNT_dec(command); @@ -472,7 +472,7 @@ been wrapped here): SV *command = newSV(0), *retval; sv_setpvf(command, "$string = '%s'; ($string =~ %s)", - SvPV_nolen(*string), pattern); + SvPV_nolen(*string), pattern); retval = my_eval_sv(command, TRUE); SvREFCNT_dec(command); @@ -495,7 +495,7 @@ been wrapped here): SSize_t num_matches; sv_setpvf(command, "my $string = '%s'; @array = ($string =~ %s)", - SvPV_nolen(string), pattern); + SvPV_nolen(string), pattern); my_eval_sv(command, TRUE); SvREFCNT_dec(command); @@ -521,25 +521,25 @@ been wrapped here): text = newSV(0); sv_setpv(text, "When he is at a convenience store and the " - "bill comes to some amount like 76 cents, Maynard is " - "aware that there is something he *should* do, something " - "that will enable him to get back a quarter, but he has " - "no idea *what*. He fumbles through his red squeezey " - "changepurse and gives the boy three extra pennies with " - "his dollar, hoping that he might luck into the correct " - "amount. The boy gives him back two of his own pennies " - "and then the big shiny quarter that is his prize. " - "-RICHH"); + "bill comes to some amount like 76 cents, Maynard is " + "aware that there is something he *should* do, something " + "that will enable him to get back a quarter, but he has " + "no idea *what*. He fumbles through his red squeezey " + "changepurse and gives the boy three extra pennies with " + "his dollar, hoping that he might luck into the correct " + "amount. The boy gives him back two of his own pennies " + "and then the big shiny quarter that is his prize. " + "-RICHH"); if (match(text, "m/quarter/")) /** Does text contain 'quarter'? **/ - printf("match: Text contains the word 'quarter'.\n\n"); + printf("match: Text contains the word 'quarter'.\n\n"); else - printf("match: Text doesn't contain the word 'quarter'.\n\n"); + printf("match: Text doesn't contain the word 'quarter'.\n\n"); if (match(text, "m/eighth/")) /** Does text contain 'eighth'? **/ - printf("match: Text contains the word 'eighth'.\n\n"); + printf("match: Text contains the word 'eighth'.\n\n"); else - printf("match: Text doesn't contain the word 'eighth'.\n\n"); + printf("match: Text doesn't contain the word 'eighth'.\n\n"); /** Match all occurrences of /wi../ **/ num_matches = matches(text, "m/(wi..)/g", &match_list); @@ -553,14 +553,14 @@ been wrapped here): /** Remove all vowels from text **/ num_matches = substitute(&text, "s/[aeiou]//gi"); if (num_matches) { - printf("substitute: s/[aeiou]//gi...%lu substitutions made.\n", - (unsigned long)num_matches); - printf("Now text is: %s\n\n", SvPV_nolen(text)); + printf("substitute: s/[aeiou]//gi...%lu substitutions made.\n", + (unsigned long)num_matches); + printf("Now text is: %s\n\n", SvPV_nolen(text)); } /** Attempt a substitution **/ if (!substitute(&text, "s/Perl/C/")) { - printf("substitute: s/Perl/C...No substitution made.\n\n"); + printf("substitute: s/Perl/C...No substitution made.\n\n"); } SvREFCNT_dec(text); @@ -572,23 +572,23 @@ been wrapped here): which produces the output (again, long lines have been wrapped here) - match: Text contains the word 'quarter'. + match: Text contains the word 'quarter'. - match: Text doesn't contain the word 'eighth'. + match: Text doesn't contain the word 'eighth'. - matches: m/(wi..)/g found 2 matches... - match: will - match: with + matches: m/(wi..)/g found 2 matches... + match: will + match: with - substitute: s/[aeiou]//gi...139 substitutions made. - Now text is: Whn h s t cnvnnc str nd th bll cms t sm mnt lk 76 cnts, - Mynrd s wr tht thr s smthng h *shld* d, smthng tht wll nbl hm t gt - bck qrtr, bt h hs n d *wht*. H fmbls thrgh hs rd sqzy chngprs nd - gvs th by thr xtr pnns wth hs dllr, hpng tht h mght lck nt th crrct - mnt. Th by gvs hm bck tw f hs wn pnns nd thn th bg shny qrtr tht s - hs prz. -RCHH + substitute: s/[aeiou]//gi...139 substitutions made. + Now text is: Whn h s t cnvnnc str nd th bll cms t sm mnt lk 76 cnts, + Mynrd s wr tht thr s smthng h *shld* d, smthng tht wll nbl hm t gt + bck qrtr, bt h hs n d *wht*. H fmbls thrgh hs rd sqzy chngprs nd + gvs th by thr xtr pnns wth hs dllr, hpng tht h mght lck nt th crrct + mnt. Th by gvs hm bck tw f hs wn pnns nd thn th bg shny qrtr tht s + hs prz. -RCHH - substitute: s/Perl/C...No substitution made. + substitute: s/Perl/C...No substitution made. =head2 Fiddling with the Perl stack from your C program @@ -631,40 +631,45 @@ deep breath... static void PerlPower(int a, int b) { - dSP; /* initialize stack pointer */ - ENTER; /* everything created after here */ - SAVETMPS; /* ...is a temporary variable. */ - PUSHMARK(SP); /* remember the stack pointer */ - XPUSHs(sv_2mortal(newSViv(a))); /* push the base onto the stack */ - XPUSHs(sv_2mortal(newSViv(b))); /* push the exponent onto stack */ - PUTBACK; /* make local stack pointer global */ - call_pv("expo", G_SCALAR); /* call the function */ - SPAGAIN; /* refresh stack pointer */ - /* pop the return value from stack */ - printf ("%d to the %dth power is %d.\n", a, b, POPi); - PUTBACK; - FREETMPS; /* free that return value */ - LEAVE; /* ...and the XPUSHed "mortal" args.*/ + dSP; /* initialize stack pointer */ + ENTER; /* everything created after here */ + SAVETMPS; /* ...is a temporary variable. */ + PUSHMARK(SP); /* remember the stack pointer */ + + /* push the base (a) and the exponent (b) onto the stack */ + XPUSHs(sv_2mortal(newSViv(a))); + XPUSHs(sv_2mortal(newSViv(b))); + + PUTBACK; /* make local stack pointer global */ + call_pv("expo", G_SCALAR); /* call the function */ + SPAGAIN; /* refresh stack pointer */ + + /* pop the return value from stack */ + printf ("%d to the %dth power is %d.\n", a, b, POPi); + + PUTBACK; + FREETMPS; /* free that return value */ + LEAVE; /* ...and the XPUSHed "mortal" args.*/ } int main (int argc, char **argv, char **env) { - char *my_argv[] = { "", "power.pl", NULL }; + char *my_argv[] = { "", "power.pl", NULL }; - PERL_SYS_INIT3(&argc,&argv,&env); - my_perl = perl_alloc(); - perl_construct( my_perl ); + PERL_SYS_INIT3(&argc,&argv,&env); + my_perl = perl_alloc(); + perl_construct( my_perl ); - perl_parse(my_perl, NULL, 2, my_argv, (char **)NULL); - PL_exit_flags |= PERL_EXIT_DESTRUCT_END; - perl_run(my_perl); + perl_parse(my_perl, NULL, 2, my_argv, (char **)NULL); + PL_exit_flags |= PERL_EXIT_DESTRUCT_END; + perl_run(my_perl); - PerlPower(3, 4); /*** Compute 3 ** 4 ***/ + PerlPower(3, 4); /*** Compute 3 ** 4 ***/ - perl_destruct(my_perl); - perl_free(my_perl); - PERL_SYS_TERM(); - exit(EXIT_SUCCESS); + perl_destruct(my_perl); + perl_free(my_perl); + PERL_SYS_TERM(); + exit(EXIT_SUCCESS); } @@ -717,71 +722,75 @@ itself after a certain number of requests, to ensure that memory consumption is minimized. You'll also want to scope your variables with L whenever possible. +To illustrate this, we create a file C: package Embed::Persistent; - #persistent.pl use strict; our %Cache; use Symbol qw(delete_package); sub valid_package_name { - my($string) = @_; - $string =~ s/([^A-Za-z0-9\/])/sprintf("_%2x",unpack("C",$1))/eg; + my ($string) = @_; + + # replace special characters (other than '/') with their hex codes + $string =~ s{ ( [^[:alnum:]/] ) }{ sprintf('_%2x', ord $1) }xeg; + # second pass only for words starting with a digit - $string =~ s|/(\d)|sprintf("/_%2x",unpack("C",$1))|eg; + $string =~ s{ / (\d) }{ sprintf('/_%2x', ord $1) }xeg; # Dress it up as a real package name - $string =~ s|/|::|g; - return "Embed" . $string; + $string =~ s{/}{::}g; + + return "Embed$string"; } sub eval_file { - my($filename, $delete) = @_; + my ($filename, $delete) = @_; my $package = valid_package_name($filename); my $mtime = -M $filename; - if(defined $Cache{$package}{mtime} - && - $Cache{$package}{mtime} <= $mtime) - { - # we have compiled this subroutine already, - # it has not been updated on disk, nothing left to do - print STDERR "already compiled $package->handler\n"; + my $cached_mtime = $Cache{$package}{mtime}; + + if(defined $cached_mtime && $cached_mtime <= $mtime) { + # we have compiled this subroutine already, + # it has not been updated on disk, nothing left to do + print STDERR "already compiled $package->handler\n"; } else { - local *FH; - open FH, $filename or die "open '$filename' $!"; - local($/) = undef; - my $sub = ; - close FH; - - #wrap the code into a subroutine inside our unique package - my $eval = qq{package $package; sub handler { $sub; }}; - { - # hide our variables within this block - my($filename,$mtime,$package,$sub); - eval $eval; - } - die $@ if $@; - - #cache it unless we're cleaning out each time - $Cache{$package}{mtime} = $mtime unless $delete; + # slurp all the file contents at once + my $sub = do { + open my $fh, '<', $filename or die "open '$filename' $!"; + local $/; + <$fh>; + }; + + # wrap the code into a subroutine inside our unique package + my $eval = qq{package $package; sub handler { $sub; }}; + { + # hide our variables within this block + my($filename, $mtime, $package, $sub); + eval $eval; + } + die $@ if $@; + + # cache it unless we're cleaning out each time + $Cache{$package}{mtime} = $mtime unless $delete; } - eval {$package->handler;}; + eval { $package->handler }; die $@ if $@; delete_package($package) if $delete; - #take a look if you want - #print Devel::Symdump->rnew($package)->as_string, $/; + # take a look if you want + # print Devel::Symdump->rnew($package)->as_string, $/; } 1; - __END__ +This file will be hardcoded to be loaded in our C program, whose code is +located in C: - /* persistent.c */ #include #include @@ -806,8 +815,8 @@ with L whenever possible. PERL_SYS_INIT3(&argc,&argv,&env); if((my_perl = perl_alloc()) == NULL) { - fprintf(stderr, "no memory!"); - exit(EXIT_FAILURE); + fprintf(stderr, "no memory!"); + exit(EXIT_FAILURE); } perl_construct(my_perl); @@ -816,21 +825,22 @@ with L whenever possible. failing = perl_parse(my_perl, NULL, 2, embedding, NULL); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; if(!failing) - failing = perl_run(my_perl); + failing = perl_run(my_perl); if(!failing) { - while(printf("Enter file name: ") && - fgets(filename, BUFFER_SIZE, stdin)) { - - filename[strlen(filename)-1] = '\0'; /* strip \n */ - /* call the subroutine, - passing it the filename as an argument */ - args[0] = filename; - call_argv("Embed::Persistent::eval_file", - G_DISCARD | G_EVAL, args); - - /* check $@ */ - if(SvTRUE(ERRSV)) - fprintf(stderr, "eval error: %s\n", SvPV_nolen(ERRSV)); + while(printf("Enter file name: ") && + fgets(filename, BUFFER_SIZE, stdin)) { + + filename[strlen(filename)-1] = '\0'; /* strip \n */ + /* call the subroutine, + passing it the filename as an argument */ + args[0] = filename; + call_argv("Embed::Persistent::eval_file", + G_DISCARD | G_EVAL, args); + + /* check $@ */ + if(SvTRUE(ERRSV)) + fprintf(stderr, "eval error: %s\n", + SvPV_nolen(ERRSV)); } } @@ -843,28 +853,28 @@ with L whenever possible. Now compile: - % cc -o persistent persistent.c \ - `perl -MExtUtils::Embed -e ccopts -e ldopts` + % cc -o persistent persistent.c \ + `perl -MExtUtils::Embed -e ccopts -e ldopts` Here's an example script file: - #test.pl - my $string = "hello"; - foo($string); + # test.pl + my $string = "hello"; + foo($string); - sub foo { - print "foo says: @_\n"; - } + sub foo { + print "foo says: @_\n"; + } Now run: - % persistent - Enter file name: test.pl - foo says: hello - Enter file name: test.pl - already compiled Embed::test_2epl->handler - foo says: hello - Enter file name: ^C + % persistent + Enter file name: test.pl + foo says: hello + Enter file name: test.pl + already compiled Embed::test_2epl->handler + foo says: hello + Enter file name: ^C =head2 Execution of END blocks @@ -1016,14 +1026,14 @@ the more esoteric perl_clone()). Compile as usual: - % cc -o multiplicity multiplicity.c \ - `perl -MExtUtils::Embed -e ccopts -e ldopts` + % cc -o multiplicity multiplicity.c \ + `perl -MExtUtils::Embed -e ccopts -e ldopts` Run it, Run it: - % multiplicity - Hi, I'm one_perl - Hi, I'm two_perl + % multiplicity + Hi, I'm one_perl + Hi, I'm two_perl =head2 Using Perl modules, which themselves use C libraries, from your C program @@ -1044,7 +1054,7 @@ Your interpreter doesn't know how to communicate with these extensions on its own. A little glue will help. Up until now you've been calling I, handing it NULL for the second argument: - perl_parse(my_perl, NULL, argc, my_argv, NULL); + perl_parse(my_perl, NULL, argc, my_argv, NULL); That's where the glue code can be inserted to create the initial contact between Perl and linked C/C++ routines. Let's take a look some pieces of @@ -1059,10 +1069,10 @@ I to see how Perl does this: EXTERN_C void xs_init(pTHX) { - char *file = __FILE__; - /* DynaLoader is a special case */ - newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); - newXS("Socket::bootstrap", boot_Socket, file); + char *file = __FILE__; + /* DynaLoader is a special case */ + newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); + newXS("Socket::bootstrap", boot_Socket, file); } Simply put: for each extension linked with your Perl executable @@ -1082,7 +1092,7 @@ is rarely any need to link in any other extensions statically. Once you have this code, slap it into the second argument of I: - perl_parse(my_perl, xs_init, argc, my_argv, NULL); + perl_parse(my_perl, xs_init, argc, my_argv, NULL); Then compile: @@ -1177,3 +1187,4 @@ Copyright (C) 1995, 1996, 1997, 1998 Doug MacEachern and Jon Orwant. All Rights Reserved. This document may be distributed under the same terms as Perl itself. + diff --git a/src/main/perl/lib/Pod/perlguts.pod b/src/main/perl/lib/Pod/perlguts.pod index bc3c64786b..658ce80aa4 100644 --- a/src/main/perl/lib/Pod/perlguts.pod +++ b/src/main/perl/lib/Pod/perlguts.pod @@ -1437,6 +1437,18 @@ macro C would need to be called instead of C. =head2 Magic Variables +Perl version 5.43.8 added a new set of structures, functions, and related +infrastructure currently called "Magic v2", intended as an overhaul of the +original MAGIC system that had been in place beforehand. This section of +the document is now split into two parts, one for each version. + +Firstly we'll describe the original system, partly for historical interest +and to explain how existing code works. Afterwards, we will introduce the +newer "Magic v2" by contrasting with the original and explaining what is new +and why it was added, as well as how to use it. + +=head2 Original MAGIC + [This section still under construction. Ignore everything here. Post no bills. Everything not permitted is forbidden.] @@ -1457,7 +1469,7 @@ linked list of C's, typedef'ed to C. Note this is current as of patchlevel 0, and could change at any time. -=head2 Assigning Magic +=head3 Assigning Magic Perl adds magic to an SV using the sv_magic function: @@ -1522,7 +1534,7 @@ virtual table, use C instead: int sv_unmagicext(SV *sv, int type, MGVTBL *vtbl); -=head2 Magic Virtual Tables +=head3 Magic Virtual Tables The C field in the C structure is a pointer to an C, which is a structure of function pointers and stands for @@ -1805,7 +1817,7 @@ For example, calls to the C functions typically need to be followed by C, but they don't need a prior C since their implementation handles 'get' magic. -=head2 Finding Magic +=head3 Finding Magic MAGIC *mg_find(SV *sv, int type); /* Finds the magic pointer of that * type */ @@ -1829,7 +1841,7 @@ This routine checks to see what types of magic C has. If the mg_type field is an uppercase letter, then the mg_obj is copied to C, but the mg_type field is changed to be the lowercase letter. -=head2 Understanding the Magic of Tied Hashes and Arrays +=head3 Understanding the Magic of Tied Hashes and Arrays Tied hashes and arrays are magical beasts of the C magic type. @@ -1917,6 +1929,263 @@ This overhead will be comparatively small if the TIE methods are themselves substantial, but if they are only a few statements long, the overhead will not be insignificant. +=head2 Magic v2 + +The entire section above has explained the "historic" original MAGIC system, +so now we will move on to the newer "Magic v2". + +"Magic v2" follows a broadly similar design to original MAGIC, in that it +permits specific I of behaviour to be specified in terms of trigger +functions that are invoked at various times. Pointers to these functions are +stored in a structure, this time called C, and it is +this structure which is pointed to by attachments made on individual target +SVs. Like with original MAGIC, these attachments can also store additional +data that the magic trigger functions can make use of alongside that target +SV. + +The C structure can be thought of as being like a +class definition, in that it describes a set of behaviours in general. It +should be declared C in a module that provides it, as it won't +need to be visible to any other code, and it won't be modified during +runtime. + +Owing to its development history, original MAGIC has a two-level arrangement +for identifying different kinds of magic, with many internally-defined tables +having API-level visible identities that can be identified by the I +field of the MAGIC structure or the I parameter to several of the API +functions. If that type is C or similar, the additional +virtual functions pointer identifies the particular magic involved. Magic v2 +is much simpler here, lacking that first-level "type" distinction. Various +kinds of v2 magic are entirely identified by a pointer to the functions +structure, and generally even most internally-defined structures are not +exposed as API-level names. + +The central design of the original MGVTBL did not leave any room for +versioning or metadata, or any way to be able to extend the structure in +future. The C, C and C flags already illustrate +the limitation of that approach. Therefore, the C +structure begins with two fields, called I and I, that between +them aim to describe exactly what sort of structure it is, as well as provide +ability to extend and change that structure in future versions of perl, when +new abilities are added. + +=head3 Attaching Magic + +Magic v2 is attached to an SV using a similar function than original MAGIC: + + MAGIC *sv_magicv2_add(SV *sv, struct MagicFunctions *funcs, + U32 flags, SV *auxsv); + +This creates a new instance of a magic structure associated with the given +functions structure and stores it in the SV. For a more detailed description +of the arguments and flags to this function see its entry in L. + +Often the behaviour added by magic requires storing extra data in the +attachment to each SV. The Magic v2 mechanism provides four ways this can be +achieved, offering various tradeoffs of simplicity of use vs flexibility. +Magic can store data in an SV pointer in C, the storage provided +by either C or C, the storage provided by C and +C, and and the extra storage offered by C and +C. These four features are not alternatives to each other; +each can be used independently of the others, or in combination, to achieve +the desired effect. + +=head3 Storing an SV in C + +The simplest way to store extra data in a magic attachment on an SV is to put +that data into another SV, and store that second SV in the "aux SV" area. +This is initially set by using the C parameter to the +C function, and thereafter accessed by the C macro +on the Magic structure. Any kind of SV can be used for this purpose. + + SV *more_data = newSVpvs("here is my extra data"); + MAGIC *mg = sv_magicv2_add(target_sv, &my_magic_funcs, 0, more_data); + + warn("The extra data is %" SVf, SVfARG(MgAUXSV(mg))); + +When cloning the interpreter for a new thread, Perl will automatically clone +the aux SV as well, storing the updated pointer in the magic structure in the +new thread. When destroying the magic attachment it will automatically +decrement the reference count in the referred SV, reclaiming it if necessary. +This usually means the user code does not need to take any additional steps +when using this method of storing data. + +=head3 Using the C or C + +If the magic attachment relates to a specific element of an AV or HV, it can +be necessary or useful to additionally store the index or key of that element +with the magic structure. This is the intended purpose of the C and +C macros, and their corresponding C and C +mutators. + +To use these, the C or C flag needs to be +present, either passed to the C function call, or set in the +C field of the C structure. Once the magic +attachment structure is created, the relevant field access macro can be used +as an lvalue to set it, or the corresponding C<_set> variant can be passed a +new value. + + MAGIC *mg = sv_magicv2_add(target_sv, &my_magic_funcs, + MGv2f_WITH_KEYIV, NULL); + /* the following two lines are equivalent; you may use either style */ + MgKEYIV(mg) = idx; + MgKEYIV_set(mg, idx); + + warn("The element index is %" IVdf, MgKEYIV(mg)); + +When using a SV pointer as a key argument, remember that the key is shared by +any C'ized copies of the containing variable, so it should not be +modified once created. As it is intended to set this field initially when the +magic is created and then leave it unmodified, using the C macro as +an lvalue to set its value will I decrement the reference count of a +previous SV referred there. If you are replacing the SV pointer, you must +remember to do this manually. + + if(MgKEYSV(mg)) + SvREFCNT_dec(MgKEYSV(mg)); + + MgKEYSV(mg) = newSVsv(newkey); + +Alternatively, this is made simpler by using the C macro, which +handles this for you. + + MgKEYSV_set(mg, newSVsv(newkey)); + +=head3 Using the C and C + +Each of these first two methods of storing extra data allow one additional +value to be stored in the magic structure - either in the C pointer, +or one of the C or C fields. If the user code needs to store +more different fields of data than this, it has a number of options. It could +use some sort of aggregate data structure at the SV level (such as an AV or +HV) to store multiple elements, but this consumes more memory and requires +more indirect pointer accesses, impacting its performance. There are two +further ways to add extra data in the form of an arbitrary C-level data +structure; which could contain a C of the user's design. + +The C and C macros can be used together to set the +pointer and corresponding length values in the magic structure itself, to +manage an allocated buffer: + + struct MyExtraData { + int x; + UV y; + size_t len; + char **many_ptrs; + }; + + MAGIC *mg = sv_magicv2_add(target_sv, &my_magic_funcs, 0, NULL); + + struct MyExtraData *dat; + Newx(dat, struct MyExtraData, 1); + *dat = ...; + + MgPTR_set(mg, dat); + MgPTRLEN_set(mg, sizeof(*dat)); + + ((struct MyExtraData *)MgPTR(mg))->y = 1234; + +Alternatively, the C function will allocate a buffer of +arbitrary size and place its pointer and length into the structure. The user +code can then use C, suitably cast, to access this buffer for its own +purposes. Passing in a NULL pointer to C causes it to allocate a +new uninitialised buffer without copying existing data into it. + + struct MyExtraData { + int x; + UV y; + size_t len; + char **many_ptrs; + }; + + MAGIC *mg = sv_magicv2_add(target_sv, &my_magic_funcs, 0, NULL); + mg_ptr_store(mg, NULL, sizeof(struct MyExtraData)); + + ((struct MyExtraData *)MgPTR(mg))->y = 1234; + +=head3 Using C<.user_size> and C + +While the C area is a useful place to store some arbitrary C-level +pointer in the magic attachment, it is not in fact ideal if the user code is +simply using this as a buffer to store its own structural data. It involves +an additional level of pointer access, which affects CPU performance and cache +efficiency. It also involves making two separate memory allocations, doubling +the C overhead involved. + +Instead of this, the user code can ask the magic system to over-allocate its +own structure and dedicate those spare bytes of storage to the user code, +keeping the entire thing in one place in memory. + +When the C field of the magic functions structure is given a +non-zero value, any time the magic internals needs to allocate a structure, it +will add this number of extra bytes. Being a structure of a size given by the +user code means it can be sized sufficiently for whatever the user code wishes +to store there (provided that is a single fixed size). + +Note however, that due to possible alignment limitations, the user code must +not use any type in this structure which requires an alignment of larger +granularity than a regular data pointer, as perl may not be able to guarantee +correct alignment. If that is required, the user code must allocate its own +structures and store pointers using the C technique above. + + struct MyExtraData { + int x; + UV y; + size_t len; + char **many_ptrs; + }; + struct MagicFunctions my_magic_funcs = { + ... + .user_size = sizeof(struct MyExtraData), + }; + + MAGIC *mg = sv_magicv2_add(target_sv, &my_magic_funcs, 0, NULL); + + MgUSERSTRUCT(mg, struct MyExtraData)->y = 1234; + +When freeing the structure or cloning it for a new interpreter thread, this +extra storage area is accounted for and copied if necessary, so user code may +not be required to handle basic structures that do not refer to other +allocated memory. If other memory is allocated and stored in the structure, +make sure to handle it correctly by providing the C and C +trigger functions. + +=head3 Handling Localization In Magic + +By default, Perl will not perform any extra work when C is applied to a +variable with magic annotations on it. Behaviour can be added by use of the +C trigger function on the C, +C and C structures. + +In many cases, it is entirely sufficient for localisation purposes to call the +the L function. You can use this function +directly in your magic functions structure by setting its address as that of +the C trigger. Remember that it needs to point to the actual +function and not the API compatibility wrapper macro, so remember to include +the leading C prefix on its name: + + const struct ScalarVarMagicFunctions magic_funcs = { + ..., + .localize_mg = &Perl_magicv2_localize_copy, + }; + +If your magic makes use of the pointer area or the C area to +store additional pointers that require further memory management, you will +have to account for these yourself. However, you can still call this function +at the start of your own handler function, before performing any extra work +yourself that may be required, such as calling C on your own +stored pointers. + + static MAGIC * + S_magic_localize(pTHX_ SV *nsv, SV *osv, MAGIC *omg) + { + MAGIC *nmg = magicv2_localize_copy(nsv, osv, omg); + + SvREFCNT_inc(MgUSERSTRUCT(mg, struct MyExtraData)->othersv); + + return nmg; + } + =head2 Localizing changes Perl has a very handy construction diff --git a/src/main/perl/lib/Pod/perlhack.pod b/src/main/perl/lib/Pod/perlhack.pod index 6a4d198035..210d3e7e01 100644 --- a/src/main/perl/lib/Pod/perlhack.pod +++ b/src/main/perl/lib/Pod/perlhack.pod @@ -36,6 +36,7 @@ In case the advice in this guide has been updated recently, read the latest version directly from the perl source: % perldoc pod/perlhack.pod + % perldoc pod/perlhacktips.pod =item * Create a branch for your change diff --git a/src/main/perl/lib/Pod/perlhacktips.pod b/src/main/perl/lib/Pod/perlhacktips.pod index ce18de951d..7b5365e577 100644 --- a/src/main/perl/lib/Pod/perlhacktips.pod +++ b/src/main/perl/lib/Pod/perlhacktips.pod @@ -388,27 +388,71 @@ POSIX also reserves many symbols. See Section 2.2.2 in L. Perl also has conflicts with that. -Perl reserves for its use any symbol beginning with C, C, -or C. Any time you introduce a macro into a header file that -doesn't follow that convention, you are creating the possibility of a -namespace clash with an existing XS module, unless you restrict it by, -say, - - #ifdef PERL_CORE - # define my_symbol - #endif - -There are many symbols in header files that aren't of this form, and -which are accessible from XS namespace, intentionally or not, just -about anything in F, for example. - -Having to use one of these prefixes detracts from the readability of -the code, and hasn't been an actual issue for non-trivial names. Things -like perl defining its own C macro have been problematic, but they -were quickly discovered, and a S> guard added. - -So there's no rule imposed about using such symbols, just be aware of -the issues. +Perl reserves for its use any symbol whose name matches the pattern +C<$names_reserved_for_perl_use_re> found in F. The +details are complicated, but, simplified, come down to things beginning +with C, C, or C, or ending with C<_pl_>. + +=head3 Symbol visibility + +For most of its life, Perl made little or no effort to hide its internal +symbols or functions. This has led to programmers using Perl to use +functionality that was dependent on Perl internal implementation +details, breaking when we unknowingly tried to change our +implementation, and thus hindering progress. + +That has been changing in recent releases, and as of v5.44, the +visibility of new symbols is restricted to just the perl core, unless an +explicit declaration is made otherwise. (Except symbol names which +match the pattern C<$names_reserved_for_perl_use_re> found in +F are made visible everywhere.) This means you can add +symbols with whatever C-compliant spelling you want, without fear that +they will be misused by someone. + +Note that symbols not placed in header files have never been visible to +outside code. + +You should consider several things before making a new symbol visible. +The bottom line is "Who really needs to see it?" + +The best method is to document the symbol. How to do this is described +near the top of F, and that file can be used to mark a +symbol's visibility. But the main documentation remains using +C<=for apidoc> lines in the source and various pods. There are several +advantages to doing this + +=over + +=item 1 + +People will know how to use your symbol without having to puzzle it out +from the code. That might even be you 6 months from now. + +=item 2 + +Various services are automatically generated for symbols naming +functions, such as Cs for parameter input conditions. + +One service is that specifying the visibility with one of the flags for +the purpose automatically makes sure the symbol has that visibility +without you having to do anything else. + +=item 3 + +Simple test cases can be automatically generated. + +=back + +Some symbols need to be visible everywhere even though they aren't +supposed to be used directly by outside code. These typically are +helper functions or flag values, I, used in a public macro. +Strictly, those names should be ones that are of the form reserved for +Perl's use, but those names are clumsy, and as long as the names aren't +likely to clash with ones an author might choose, problems don't arise. + +If you choose to not document a new symbol that needs to be visible +everywhere, add it to the array C<@undocumented_always_visible> in +F. =head3 Choosing good symbol names diff --git a/src/main/perl/lib/Pod/perlhist.pod b/src/main/perl/lib/Pod/perlhist.pod index 42848315ac..a6413e4427 100644 --- a/src/main/perl/lib/Pod/perlhist.pod +++ b/src/main/perl/lib/Pod/perlhist.pod @@ -806,6 +806,8 @@ the strings?). 5.40.3 2025-Aug-03 5.40.4-RC1 2026-Mar-22 5.40.4 2026-Mar-29 + 5.40.5-RC1 2026-Jul-22 + 5.40.5 2026-Aug-02 Graham K 5.41.0 2024-Jun-10 The 5.41 development track Philippe 5.41.1 2024-Jul-02 @@ -831,6 +833,8 @@ the strings?). 5.42.1 2026-Mar-08 5.42.2-RC1 2026-Mar-22 5.42.2 2026-Mar-29 + 5.42.3-RC1 2026-Jul-22 + 5.42.3 2026-Aug-02 Philippe 5.43.0 2025-Jul-03 The 5.43 development track Richard L 5.43.1 2025-Jul-20 @@ -848,7 +852,8 @@ the strings?). Leon T 5.44.0-RC2 2026-Jul-08 Leon T 5.44.0 2026-Jul-15 - Leon T 5.45.0 2026-Jul-16 + Leon T 5.45.0 2026-Jul-16 The 5.45 development track + Paul E 5.45.1 2026-Jul-21 =head2 SELECTED RELEASE SIZES diff --git a/src/main/perl/lib/Pod/perlop.pod b/src/main/perl/lib/Pod/perlop.pod index 3a14676f73..30a421de30 100644 --- a/src/main/perl/lib/Pod/perlop.pod +++ b/src/main/perl/lib/Pod/perlop.pod @@ -2184,10 +2184,8 @@ Options (specified by the following modifiers) are: d Use Unicode or native charset, as in 5.12 and earlier. n Non-capture mode. Don't let () fill in $1, $2, etc... -If a precompiled pattern is embedded in a larger pattern then the effect -of C<"msixpluadn"> will be propagated appropriately. The effect that the -C modifier has is not propagated, being restricted to those patterns -explicitly using it. +Embedding a precompiled pattern in a larger pattern does not change it +nor its settings. The C, C, C, and C modifiers (added in Perl 5.14) control the character set rules, but C is the only one you are likely diff --git a/src/main/perl/lib/Pod/perlpodstyle.pod b/src/main/perl/lib/Pod/perlpodstyle.pod index 4039af569e..7a5749cc6e 100644 --- a/src/main/perl/lib/Pod/perlpodstyle.pod +++ b/src/main/perl/lib/Pod/perlpodstyle.pod @@ -1,3 +1,5 @@ +=for stopwords Allbery Christiansen FSFAP SPDX perlpodstyle + =head1 NAME perlpodstyle - Perl POD style guide @@ -222,7 +224,7 @@ For licensing the easiest way is to use the same licensing as Perl itself: modify it under the same terms as Perl itself. This makes it easy for people to use your module with Perl. Note that -this licensing example is neither an endorsement nor a requirement, you are +this licensing example is neither an endorsement or a requirement, you are of course free to choose any licensing. =item SEE ALSO diff --git a/src/main/perl/lib/Pod/perlpolicy.pod b/src/main/perl/lib/Pod/perlpolicy.pod index a314cefde9..c128060949 100644 --- a/src/main/perl/lib/Pod/perlpolicy.pod +++ b/src/main/perl/lib/Pod/perlpolicy.pod @@ -98,7 +98,7 @@ A new stable release series is typically produced once a year. =head1 MAINTENANCE AND SUPPORT These are the "officially" supported perl versions -as of the release of Perl 5.42: +as of the release of Perl 5.44: Version track Start date Support status ------------- ----------- -------------- diff --git a/src/main/perl/lib/Pod/perlreapi.pod b/src/main/perl/lib/Pod/perlreapi.pod index 8d2f134a7e..a19a54fb8a 100644 --- a/src/main/perl/lib/Pod/perlreapi.pod +++ b/src/main/perl/lib/Pod/perlreapi.pod @@ -688,6 +688,8 @@ values. U32 lastparen; /* highest close paren matched ($+) */ U32 lastcloseparen; /* last close paren matched ($^N) */ regexp_paren_pair *offs; /* Array of offsets for (@-) and (@+) */ + regexp_paren_pair *offs_spare; /* To minimise allocation churn when this + * regex was the last successful match */ char **recurse_locinput; /* used to detect infinite recursion, XXX: move to internal */ @@ -700,6 +702,9 @@ values. * extflags in various ways */ PERL_BITFIELD32 compflags:9; + /* Is offs_spare already in use? */ + PERL_BITFIELD32 offs_spare_used:1; + /*---------------------------------------------------------------------- */ char *subbeg; /* saved or original string so \digit works forever. */ diff --git a/src/main/perl/lib/Pod/perlreguts.pod b/src/main/perl/lib/Pod/perlreguts.pod index 890bc68372..c5521440d8 100644 --- a/src/main/perl/lib/Pod/perlreguts.pod +++ b/src/main/perl/lib/Pod/perlreguts.pod @@ -214,6 +214,313 @@ and equivalents for reading and setting the arguments; and C, C and C for manipulating strings and regop bearing types. +=head3 Regop Definitions + +The following table is generated by F from F. +It documents the regop types, their operands, and their implementation +structures. The numeric dispatch variants are defined in F +relative to the base regop numbers. + +=for comment +This table is generated by regen/regcomp.pl. Any changes made here +will be lost. + +=for regcomp.pl begin + +# TYPE arg-description [regnode-struct-suffix] [longjump-len] DESCRIPTION + +# Exit points +END no End of program. +SUCCEED no Return from a subroutine, basically. +LOOKBEHIND_END no Return from lookbehind (IFMATCH/UNLESSM) + and validate position when they do + +# Line Start Anchors: +SBOL no Match "" at beginning of line: /^/, /\A/ +MBOL no Same, assuming multiline: /^/m + +# Line End Anchors: +SEOL no Match "" at end of line: /$/ +MEOL no Same, assuming multiline: /$/m +EOS no Match "" at end of string: /\z/ + +# Match Start Anchors: +GPOS no Matches where last m//g left off. + +# Word Boundary Opcodes: +BOUND no Like BOUNDA for non-utf8, otherwise like + BOUNDU +BOUNDL no Like BOUND/BOUNDU, but \w and \W are + defined by current locale +BOUNDU no Match "" at any boundary of a given type + using /u rules. +BOUNDA no Match "" at any boundary between \w\W or + \W\w, where \w is [_a-zA-Z0-9] +NBOUND no Like NBOUNDA for non-utf8, otherwise like + BOUNDU +NBOUNDL no Like NBOUND/NBOUNDU, but \w and \W are + defined by current locale +NBOUNDU no Match "" at any non-boundary of a given + type using /u rules. +NBOUNDA no Match "" between any \w\w or \W\W, where \w + is [_a-zA-Z0-9] + +# [Special] alternatives: +REG_ANY no Match any one character (except newline). +SANY no Match any one character. +ANYOF sv Match character in (or not in) this class, + charclass single char match only +ANYOFD sv Like ANYOF, but /d is in effect + charclass +ANYOFL sv Like ANYOF, but /l is in effect + charclass +ANYOFPOSIXL sv Like ANYOFL, but matches [[:posix:]] + charclass_ classes + posixl +ANYOFH sv 1 Like ANYOF, but only has "High" matches, + none in the bitmap; the flags field + contains the lowest matchable UTF-8 start + byte +ANYOFHb sv 1 Like ANYOFH, but all matches share the same + UTF-8 start byte, given in the flags field +ANYOFHr sv 1 Like ANYOFH, but the flags field contains + packed bounds for all matchable UTF-8 start + bytes. +ANYOFHs sv:str 1 Like ANYOFHb, but has a string field that + gives the leading matchable UTF-8 bytes; + flags field is len +ANYOFR packed 1 Matches any character in the range given by + its packed args: upper 12 bits is the max + delta from the base lower 20; the flags + field contains the lowest matchable UTF-8 + start byte +ANYOFRb packed 1 Like ANYOFR, but all matches share the same + UTF-8 start byte, given in the flags field +ANYOFHbbm none bbm Like ANYOFHb, but only for 2-byte UTF-8 + characters; uses a bitmap to match the + continuation byte +ANYOFM byte 1 Like ANYOF, but matches an invariant byte + as determined by the mask and arg +NANYOFM byte 1 complement of ANYOFM + +# POSIX Character Classes: +POSIXD none Some [[:class:]] under /d; the FLAGS field + gives which one +POSIXL none Some [[:class:]] under /l; the FLAGS field + gives which one +POSIXU none Some [[:class:]] under /u; the FLAGS field + gives which one +POSIXA none Some [[:class:]] under /a; the FLAGS field + gives which one +NPOSIXD none complement of POSIXD, [[:^class:]] +NPOSIXL none complement of POSIXL, [[:^class:]] +NPOSIXU none complement of POSIXU, [[:^class:]] +NPOSIXA none complement of POSIXA, [[:^class:]] +CLUMP no Match any extended grapheme cluster + sequence + +# Alternation +# +# BRANCH The set of branches constituting a single choice are hooked +# together with their "next" pointers, since precedence prevents anything +# being concatenated to any individual branch. The "next" pointer of the +# last BRANCH in a choice points to the thing following the whole choice. +# This is also where the final "next" pointer of each individual branch +# points; each branch starts with the operand node of a BRANCH node. +BRANCH node 1 Match this alternative, or the next... + +# Literals +EXACT str Match this string (flags field is the + length). + +# In a long string node, the U32 argument is the length, and is immediately +# followed by the string. +LEXACT len:str 1 Match this long string (preceded by length; + flags unused). +EXACTL str Like EXACT, but /l is in effect (used so + locale-related warnings can be checked for) +EXACTF str Like EXACT, but match using /id rules; + (string not UTF-8, ASCII folded; non-ASCII + not) +EXACTFL str Like EXACT, but match using /il rules; + (string not likely to be folded) +EXACTFU str Like EXACT, but match using /iu rules; + (string folded) +EXACTFAA str 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) +EXACTFAA_NO_TRIE str Like EXACTFAA, (string not UTF-8, folded + except: MICRO, SHARP S; folded length <= + unfolded, not currently trie-able) +EXACTFUP str Like EXACT, but match using /iu rules; + (string not UTF-8, folded except MICRO: + hence Problematic) +EXACTFLU8 str Like EXACTFU, but use /il, UTF-8, (string + is folded, and everything in it is above + 255 +EXACT_REQ8 str Like EXACT, but only UTF-8 encoded targets + can match +LEXACT_REQ8 len:str 1 Like LEXACT, but only UTF-8 encoded targets + can match +EXACTFU_REQ8 str Like EXACTFU, but only UTF-8 encoded + targets can match +EXACTFU_S_EDGE str /di rules, but nothing in it precludes /ui, + except begins and/or ends with [Ss]; + (string not UTF-8; compile-time only) + +# New charclass like patterns +LNBREAK none generic newline pattern + +# Trie Related +# +# Behave the same as A|LIST|OF|WORDS would. The '..C' variants have inline +# charclass data (ascii only), the 'C' store it in the structure. +TRIE trie 1 Match many EXACT(F[ALU]?)? at once. + flags==type +TRIEC trie Same as TRIE, but with embedded charclass + charclass data +AHOCORASICK trie 1 Aho Corasick stclass. flags==type +AHOCORASICKC trie Same as AHOCORASICK, but with embedded + charclass charclass data +LTRIE trie 2 Same as TRIE, but with longjump support +LTRIEC trie Same as TRIEC, but with longjump support + charclass_ + trie + +# Do nothing types +NOTHING no Match empty string. + +# A variant of above which delimits a group, thus stops optimizations +TAIL no Match empty string. Can jump here from + outside. +OPTIMIZED no This is not really a node, but an optimized + away piece of a "long" node. To simplify + debugging output, we mark it as if it were + a node + +# Loops +# +# STAR,PLUS '?', and complex '*' and '+', are implemented as circular +# BRANCH structures. Simple cases (one character per match) are +# implemented with STAR and PLUS for speed and to minimize recursive +# plunges. +STAR node Match this (simple) thing 0 or more times: + /A{0,}B/ where A is width 1 char +PLUS node Match this (simple) thing 1 or more times: + /A{1,}B/ where A is width 1 char +CURLY sv 3 Match this (simple) thing {n,m} times: + /A{m,n}B/ where A is width 1 char +CURLYN no 3 Capture next-after-this simple thing: + /(A){m,n}B/ where A is width 1 char +CURLYM no 3 Capture this medium-complex thing {n,m} + times: /(A){m,n}B/ where A is fixed-length +CURLYX sv 3 Match/Capture this complex thing {n,m} + times. +WHILEM no Do curly processing and see if rest + matches. + +# Buffer related +# +# OPEN,CLOSE,GROUPP ...are numbered at compile time. +OPEN num 1 Mark this point in input as start of #n. +CLOSE num 1 Close corresponding OPEN of #n. + +# Script Run +SROPEN none Start a script run +SRCLOSE End a + script run +REF num 2 Match some already matched string +REFF num 2 Match already matched string, using /di + rules. +REFFL num 2 Match already matched string, using /li + rules. +REFFU num 2 Match already matched string, using /ui. +REFFA num 2 Match already matched string, using /aai + rules. + +# Named references. Code in regcomp.c assumes that these all are after the +# numbered references +REFN no-sv 2 Match some already matched string +REFFN no-sv 2 Match already matched string, using /di + rules. +REFFLN no-sv 2 Match already matched string, using /li + rules. +REFFUN num 2 Match already matched string, using /ui + rules. +REFFAN num 2 Match already matched string, using /aai + rules. + +# Support for long RE +BRANCHJ off 2 1 BRANCH with long offset. + +# Special Case Regops +IFMATCH off 1 1 Succeeds if the following matches; non-zero + flags "f", next_off "o" means lookbehind + assertion starting "f..(f-o)" characters + before current +UNLESSM off 1 1 Fails if the following matches; non-zero + flags "f", next_off "o" means lookbehind + assertion starting "f..(f-o)" characters + before current +SUSPEND off 1 1 "Independent" sub-RE. +IFTHEN off 1 1 Switch, should be preceded by switcher. +RENUM off 1 1 Group with independently numbered parens. + Not used yet. +LONGJMP off 1 1 Jump far away. + +# Modifiers +MINMOD no Next operator is not greedy. +LOGICAL no Next opcode should set the flag only. + +# Regex Code And Subroutines +EVAL evl/flags Execute some Perl code. Used by other + 2 opcodes in some cases +GOSUB num/ofs 2 recurse to paren arg1 at (signed) ofs arg2 + +# Special conditionals used in (?(COND)YES|NO) constructs +GROUPP num 1 Whether the group matched. +GROUPPN no-sv 1 Whether the named group matched. +INSUBP num 1 Whether we are in a specific recurse. +DEFINEP none 1 Define regex subroutines. Contents never + executed directly, disallows 'no' branch in + conditional. + +# Backtracking Verbs that are similar to an END opcode +ENDLIKE none Used only for the type field of verbs +OPFAIL no-sv 1 Same as (?!), but with verb arg +ACCEPT no-sv/num Accepts the current matched string, with + 2 verbar + +# Verbs With Arguments +VERB no-sv 1 Used only for the type field of verbs +PRUNE no-sv 1 Pattern fails at this startpoint if no- + backtracking through this +MARKPOINT no-sv 1 Push the current location for rollback by + cut. +SKIP no-sv 1 On failure skip forward (to the mark) + before retrying +COMMIT no-sv 1 Pattern fails outright if backtracking + through this +CUTGROUP no-sv 1 On failure go to the next alternation in + the group + +# Control what to keep in $&. +KEEPS no $& begins here. + +# Special opcode with the property that no opcode in a compiled program +# will ever be of this type. Thus it can be used as a flag value that no +# other opcode has been seen. +# +# END is used similarly, in that an END node can't be optimized. So END +# implies "unoptimizable" and PSEUDO means "not seen anything to optimize +# yet". +PSEUDO off Pseudo opcode for internal use. +REGEX_SET depth p Regex set, temporary node used in pre- + optimization compilation + +=for regcomp.pl end + =head3 What regnode is next? There are two distinct concepts of "next regnode" in the regex engine, diff --git a/src/main/perl/lib/Pod/perlrun.pod b/src/main/perl/lib/Pod/perlrun.pod index 93bb97ee89..22dd208a5c 100644 --- a/src/main/perl/lib/Pod/perlrun.pod +++ b/src/main/perl/lib/Pod/perlrun.pod @@ -453,6 +453,8 @@ B<-D14> is equivalent to B<-Dtls>): 134217728 i trace PerlIO layer processing. Set PERLIO_DEBUG to the filename to trace to. 268435456 y trace y///, tr/// compilation and execution + 536870912 K Mutex locking/unlocking; enabled only when Configure + was passed -Accflags=-DPERL_DEBUG_MUTEXES All these flags require B<-DDEBUGGING> when you compile the Perl executable (but see C<:opd> in L or L diff --git a/src/main/perl/lib/Test/Podlators.pm b/src/main/perl/lib/Test/Podlators.pm index c9787eb4bb..02eccb56c3 100644 --- a/src/main/perl/lib/Test/Podlators.pm +++ b/src/main/perl/lib/Test/Podlators.pm @@ -84,12 +84,12 @@ sub _stderr_restore { # exception - Text of exception (with file and line stripped) sub read_snippet { my ($path) = @_; - $path = File::Spec->catfile('t', 'data', 'snippets', $path); + my $fullpath = File::Spec->catfile('t', 'data', 'snippets', $path); my %data; # Read the sections and store them in the %data hash. my ($line, $section); - open(my $fh, '<', $path) or BAIL_OUT("cannot open $path: $!"); + open(my $fh, '<', $fullpath) or BAIL_OUT("cannot open $fullpath: $!"); while (defined($line = <$fh>)) { if ($line =~ m{ \A \s* \[ (\S+) \] \s* \z }xms) { $section = $1; @@ -98,18 +98,22 @@ sub read_snippet { $data{$section} .= $line; } } - close($fh) or BAIL_OUT("cannot close $path: $!"); + close($fh) or BAIL_OUT("cannot close $fullpath: $!"); # Strip trailing blank lines from all sections. for my $section (keys %data) { $data{$section} =~ s{ \n\s+ \z }{\n}xms; } - # Clean up the name section by removing newlines and extra space. + # Clean up the name section by removing newlines and extra space and add + # the filename. if ($data{name}) { $data{name} =~ s{ \A \s+ }{}xms; $data{name} =~ s{ \s+ \z }{}xms; $data{name} =~ s{ \s+ }{ }xmsg; + $data{name} = $path . ': ' . $data{name}; + } else { + $data{name} = $path; } # Turn the options section into a hash. @@ -576,7 +580,7 @@ Russ Allbery =head1 COPYRIGHT AND LICENSE -Copyright 2015-2016, 2018-2020, 2022, 2024 Russ Allbery +Copyright 2015-2016, 2018-2020, 2022, 2024, 2026 Russ Allbery This program is free software; you may redistribute it and/or modify it under the same terms as Perl itself.