=item * Make your change
-Hack, hack, hack.
+Hack, hack, hack. Keep in mind that Perl runs on many different
+platforms, with different operating systems that have different
+capabilities, different filesystem organizations, and even different
+character sets. L<perlhacktips> gives advice on this.
=item * Test your change
via email.
If your changes are in a single git commit, run the following commands
-to write the file as a MIME attachment and send it with a meaningful
-subject:
+to generate the patch file and attach it to your bug report:
- % git format-patch -1 --attach
- % ./perl -Ilib utils/perlbug -s "[PATCH] $(
- git log -1 --oneline HEAD)" -f 0001-*.patch
+ % git format-patch -1
+ % ./perl -Ilib utils/perlbug -p 0001-*.patch
The perlbug program will ask you a few questions about your email
address and the patch you're submitting. Once you've answered them it
will submit your patch via email.
-If your changes are in multiple commits, generate a patch file
-containing them all, and attach that:
+If your changes are in multiple commits, generate a patch file for each
+one and provide them to perlbug's C<-p> option separated by commas:
- % git format-patch origin/blead --attach --stdout > patches
- % ./perl -Ilib utils/perlbug -f patches
+ % git format-patch -3
+ % ./perl -Ilib utils/perlbug -p 0001-fix1.patch,0002-fix2.patch,\
+ > 0003-fix3.patch
-When prompted, pick a subject that summarizes your changes overall and
-has "[PATCH]" at the beginning.
+When prompted, pick a subject that summarizes your changes.
=item * Thank you
"porters".
A searchable archive of the list is available at
-L<http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/>. There is
-also another archive at
+L<http://markmail.org/search/?q=perl5-porters>. There is also an archive at
L<http://archive.develooper.com/perl5-porters@perl.org/>.
=head2 perl-changes mailing list
the tree, see recent commits, subscribe to RSS feeds for the changes,
search for particular commits and more. You may access it at
L<http://perl5.git.perl.org/perl.git>. A mirror of the repository is
-found at L<http://github.com/mirrors/perl>.
+found at L<https://github.com/Perl/perl5>.
=head2 Read access via rsync
=item *
-8-wide tabs (no exceptions!)
+4-wide indents for code, 2-wide indents for nested CPP C<#define>s,
+with 8-wide tabstops.
=item *
-4-wide indents for code, 2-wide indents for nested CPP #defines
+Use spaces for indentation, not tab characters.
+
+The codebase is a mixture of tabs and spaces for indentation, and we
+are moving to spaces only. Converting lines you're patching from 8-wide
+tabs to spaces will help this migration.
=item *
=item *
-In function definitions, name starts in column 0 (return value is on
+In function definitions, name starts in column 0 (return value-type is on
previous line)
=item *
=item * F<t/base>, F<t/comp> and F<t/opbasic>
-Since we don't know if require works, or even subroutines, use ad hoc
+Since we don't know if C<require> works, or even subroutines, use ad hoc
tests for these three. Step carefully to avoid using the feature being
tested. Tests in F<t/opbasic>, for instance, have been placed there
rather than in F<t/op> because they test functionality which
F<lib/>, so here's some opportunity for some patching.
You must be triply conscious of cross-platform concerns. This usually
-boils down to using L<File::Spec> and avoiding things like C<fork()>
-and C<system()> unless absolutely necessary.
+boils down to using L<File::Spec>, avoiding things like C<fork()>
+and C<system()> unless absolutely necessary, and not assuming that a
+given character has a particular ordinal value (code point) or that its
+UTF-8 representation is composed of particular bytes.
+
+There are several functions available to specify characters and code
+points portably in tests. The always-preloaded functions
+C<utf8::unicode_to_native()> and its inverse
+C<utf8::native_to_unicode()> take code points and translate
+appropriately. The file F<t/charset_tools.pl> has several functions
+that can be useful. It has versions of the previous two functions
+that take strings as inputs -- not single numeric code points:
+C<uni_to_native()> and C<native_to_uni()>. If you must look at the
+individual bytes comprising a UTF-8 encoded string,
+C<byte_utf8a_to_utf8n()> takes as input a string of those bytes encoded
+for an ASCII platform, and returns the equivalent string in the native
+platform. For example, C<byte_utf8a_to_utf8n("\xC2\xA0")> returns the
+byte sequence on the current platform that form the UTF-8 for C<U+00A0>,
+since C<"\xC2\xA0"> are the UTF-8 bytes on an ASCII platform for that
+code point. This function returns C<"\xC2\xA0"> on an ASCII platform, and
+C<"\x80\x41"> on an EBCDIC 1047 one.
+
+But easiest is, if the character is specifiable as a literal, like
+C<"A"> or C<"%">, to use that; if not so specificable, you can use use
+C<\N{}> , if the side effects aren't troublesome. Simply specify all
+your characters in hex, using C<\N{U+ZZ}> instead of C<\xZZ>. C<\N{}>
+is the Unicode name, and so it
+always gives you the Unicode character. C<\N{U+41}> is the character
+whose Unicode code point is C<0x41>, hence is C<'A'> on all platforms.
+The side effects are:
+
+=over 4
+
+=item *
+
+These select Unicode rules. That means that in double-quotish strings,
+the string is always converted to UTF-8 to force a Unicode
+interpretation (you can C<utf8::downgrade()> afterwards to convert back
+to non-UTF8, if possible). In regular expression patterns, the
+conversion isn't done, but if the character set modifier would
+otherwise be C</d>, it is changed to C</u>.
+
+=item *
+
+If you use the form C<\N{I<character name>}>, the L<charnames> module
+gets automatically loaded. This may not be suitable for the test level
+you are doing.
+
+=back
+
+If you are testing locales (see L<perllocale>), there are helper
+functions in F<t/loc_tools.pl> to enable you to see what locales there
+are on the current platform.
=head2 Special C<make test> targets
to C<make> utilities to interact with their job schedulers.
Note that currently some test scripts may fail when run in parallel
-(most notably F<ext/IO/t/io_dir.t>). If necessary, run just the
+(most notably F<dist/IO/t/io_dir.t>). If necessary, run just the
failing scripts again sequentially and see if the failures go away.
=head2 Running tests by hand
See also the documentation for the Test and Test::Harness modules, for
more environment variables that affect testing.
+=head2 Performance testing
+
+The file F<t/perf/benchmarks> contains snippets of perl code which are
+intended to be benchmarked across a range of perls by the
+F<Porting/bench.pl> tool. If you fix or enhance a performance issue, you
+may want to add a representative code sample to the file, then run
+F<bench.pl> against the previous and current perls to see what difference
+it has made, and whether anything else has slowed down as a consequence.
+
+The file F<t/perf/opcount.t> is designed to test whether a particular
+code snippet has been compiled into an optree containing specified
+numbers of particular op types. This is good for testing whether
+optimisations which alter ops, such as converting an C<aelem> op into an
+C<aelemfast> op, are really doing that.
+
+The files F<t/perf/speed.t> and F<t/re/speed.t> are designed to test
+things that run thousands of times slower if a particular optimisation
+is broken (for example, the utf8 length cache on long utf8 strings).
+Add a test that will take a fraction of a second normally, and minutes
+otherwise, causing the test file to time out on failure.
+
+=head2 Building perl at older commits
+
+In the course of hacking on the Perl core distribution, you may have occasion
+to configure, build and test perl at an old commit. Sometimes C<make> will
+fail during this process. If that happens, you may be able to salvage the
+situation by using the Devel::PatchPerl library from CPAN (not included in the
+core) to bring the source code at that commit to a buildable state.
+
+Here's a real world example, taken from work done to resolve
+L<perl #72414|https://rt.perl.org/Ticket/Display.html?id=72414>.
+Use of F<Porting/bisect.pl> had identified commit
+C<ba77e4cc9d1ceebf472c9c5c18b2377ee47062e6> as the commit in which a bug was
+corrected. To confirm, a P5P developer wanted to configure and build perl at
+commit C<ba77e4c^> (presumably "bad") and then at C<ba77e4c> (presumably
+"good"). Normal configuration and build was attempted:
+
+ $ sh ./Configure -des -Dusedevel
+ $ make test_prep
+
+C<make>, however, failed with output (excerpted) like this:
+
+ cc -fstack-protector -L/usr/local/lib -o miniperl \
+ gv.o toke.o perly.o pad.o regcomp.o dump.o util.o \
+ mg.o reentr.o mro.o hv.o av.o run.o pp_hot.o sv.o \
+ pp.o scope.o pp_ctl.o pp_sys.o doop.o doio.o regexec.o \
+ utf8.o taint.o deb.o universal.o globals.o perlio.o \
+ perlapi.o numeric.o mathoms.o locale.o pp_pack.o pp_sort.o \
+ miniperlmain.o opmini.o perlmini.o
+ pp.o: In function `Perl_pp_pow':
+ pp.c:(.text+0x2db9): undefined reference to `pow'
+ ...
+ collect2: error: ld returned 1 exit status
+ makefile:348: recipe for target 'miniperl' failed
+ make: *** [miniperl] Error 1
+
+Another P5P contributor recommended installation and use of Devel::PatchPerl
+for this situation, first to determine the version of perl at the commit in
+question, then to patch the source code at that point to facilitate a build.
+
+ $ perl -MDevel::PatchPerl -e \
+ 'print Devel::PatchPerl->determine_version("/path/to/sourcecode"), "\n";'
+ 5.11.1
+ $ perl -MDevel::PatchPerl -e \
+ 'Devel::PatchPerl->patch_source("5.11.1", "/path/to/sourcecode");'
+
+Once the source was patched, C<./Configure> and C<make test_prep> were called
+and completed successfully, enabling confirmation of the findings in RT
+#72414.
+
=head1 MORE READING FOR GUTS HACKERS
To hack on the Perl guts, you'll need to read the following things:
=head1 CPAN TESTERS AND PERL SMOKERS
-The CPAN testers ( http://testers.cpan.org/ ) are a group of volunteers
+The CPAN testers ( L<http://testers.cpan.org/> ) are a group of volunteers
who test CPAN modules on a variety of platforms.
-Perl Smokers ( http://www.nntp.perl.org/group/perl.daily-build/ and
-http://www.nntp.perl.org/group/perl.daily-build.reports/ )
+Perl Smokers ( L<http://www.nntp.perl.org/group/perl.daily-build/> and
+L<http://www.nntp.perl.org/group/perl.daily-build.reports/> )
automatically test Perl source releases on platforms with various
configurations.
This document was originally written by Nathan Torkington, and is
maintained by the perl5-porters mailing list.
-