Lukas Mai 67972cbed5 porting/diag.t: fix some corner cases
Before this patch
=================

The porting/diag.t test tries to make sure every error message emitted
by perl is documented in pod/perldiag.pod. The way it does this is as
follows:

1. Collect list of diagnostic functions by taking all known functions
   whose name contains warn, err, die, croak, or deprecate. Add Perl_mess
   and anything that starts with PERL_DIAG_. Add the special
   (v)FAIL(2,3,4) macros used in regcomp.c.
2. For every input file, scan it line by line.
3. If the line starts with "#", skip it (so we don't find macro
   definitions like "#define croak(...) ..." themselves).
4. If the line contains the name of a diagnostic function, collect the
   line.
5. If the function name is followed by a simple argument list (basically
   "(...)" with at most one level of nested parentheses within), stop.
   Otherwise keep collecting lines until we find a line that ends with
   ");", which we take to be the end of the statement.
6. Join all collected lines into one blob of text and rescan it for the
   diagnostic message.
7. Read the next line and repeat (step 3).

There are some issues with this approach. For example, step 5 may end up
eating large chunks of the input file until a ");" line is encountered.
If we're in a header that "#define"s many macros in a row, all of them
will be swallowed here.

Also, while "#define" lines themselves are skipped, the body of the
macro may not be: If the "#define" line ends with a backslash, the rest
of the macro definition (placed on the following lines) will be scanned
as normal.

Finally, there is a bug in the "simple argument list" check in step 5:
It doesn't handle a completely empty argument list (as in
"croak_memory_wrap()", for example), so it starts collecting lines until
it finds the next ");".

After this patch
================

Extend step 3: If the line is a definition of one of the regcomp error
macros (e.g. "#define FAIL2(...)"), skip the entire definition,
including backslash continuation lines. These macros are just wrappers
around croak; they don't emit any particular diagnostics of their own.

Extend step 5: Handle empty argument lists so "croak_memory_wrap()" does
not start a runaway scan for ");".

Extend step 5: When collecting lines, don't just stop at ");", but also
at (or rather just before) lines starting with "#", so we don't blindly
swallow preprocessor directives.

If an error message is not found in perldiag, report the source location
where it is emitted with the number of the first line of its collected
chunk (i.e. the location of the diagnostic function name), not (as
before) the last line of the chunk (i.e. the location of the next ");",
which may be a long ways off).

This exposes one new message in regcomp_internal.h, which has been added
to perldiag.
2025-09-16 07:10:34 +02:00
..
2025-09-02 18:20:20 -06:00
2025-09-02 18:20:20 -06:00
2025-09-02 18:20:20 -06:00
2025-05-15 06:51:06 -06:00

This is the perl test library.  To run the test suite, just type './TEST'
or 'make test' from the build directory above t/.  See also the section
"Special Make Test Targets" in pod/perlhack.pod to learn about other
specific test commands.

To add new tests, just look at the current tests and do likewise.
The library t/test.pl provides some utility functions that you can use
in most tests, except in the most basic ones.

If a test fails, run it by itself to see if it prints any informative
diagnostics.  If not, modify the test to print informative diagnostics.
If you put out extra lines with a '#' character on the front, you don't
have to worry about removing the extra print statements later since TEST
ignores lines beginning with '#'.

If you know that Perl is basically working but expect that some tests
will fail, you may want to use Test::Harness thusly:
        cd t
        ./perl harness
This method pinpoints failed tests automatically.

If you come up with new tests, please submit them to
https://github.com/Perl/perl5/issues.

Tests in the t/base/ directory must be runnable with plain miniperl alone.
That is, they should not assume that require works, let alone that they can
require Config.pm, strict or warnings.  This constraint is frustrating, but
necessary as they exist to sanity test the rest of the test framework.
TEST will abort if any tests in the t/base/ directory fail.

Tests in the t/comp/, t/cmd/, t/run/, t/io/, t/op/ and t/uni/ directories
should also be runnable by miniperl and not require Config.pm, but
failures to comply will not cause TEST to abort like for t/base/.

The comment in TEST explains the test bootstrapping order:

* base first, as TEST bails out if that can't run
* then comp, to validate that require works
* then run, to validate that -M works
* then we know we can -MTestInit for everything else, making life simpler

Tests in t/perf/ are designed to test performance and optimisations,
and also contain additional tools and files designed to run outside
of the test suite