This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Add to known_pod_issues.dat following Test-Harness upgrade
[perl5.git] / t / porting / diag.t
1 #!/usr/bin/perl
2
3 BEGIN {
4   @INC = '..' if -f '../TestInit.pm';
5 }
6 use TestInit qw(T); # T is chdir to the top level
7
8 use warnings;
9 use strict;
10
11 require 't/test.pl';
12 plan('no_plan');
13
14 # --make-exceptions-list outputs the list of strings that don't have
15 # perldiag.pod entries to STDERR without TAP formatting, so they can
16 # easily be put in the __DATA__ section of this file.  This was done
17 # initially so as to not create new test failures upon the initial
18 # creation of this test file.  You probably shouldn't do it again.
19 # Just add the documentation instead.
20 my $make_exceptions_list = ($ARGV[0]||'') eq '--make-exceptions-list';
21
22 require 'regen/embed_lib.pl';
23
24 # Look for functions that look like they could be diagnostic ones.
25 my @functions;
26 foreach (@{(setup_embed())[0]}) {
27   next if @$_ < 2;
28   next unless $_->[2]  =~ /warn|err|(\b|_)die|croak/i;
29   # The flag p means that this function may have a 'Perl_' prefix
30   # The flag s means that this function may have a 'S_' prefix
31   push @functions, $_->[2];
32   push @functions, 'Perl_' . $_->[2] if $_->[0] =~ /p/;
33   push @functions, 'S_' . $_->[2] if $_->[0] =~ /s/;
34 };
35
36 my $regcomp_re = "(?<routine>(?:ckWARN(?:\\d+)?reg\\w*|vWARN\\d+))";
37 my $function_re = join '|', @functions;
38 my $regcomp_fail_re = '\b(?:(?:Simple_)?v)?FAIL[2-4]?(?:utf8f)?\b';
39 my $source_msg_re =
40    "(?<routine>\\bDIE\\b|$function_re|$regcomp_fail_re)";
41 my $text_re = '"(?<text>(?:\\\\"|[^"]|"\s*[A-Z_]+\s*")*)"';
42 my $source_msg_call_re = qr/$source_msg_re(?:_nocontext)? \s*
43     \(aTHX_ \s*
44     (?:packWARN\d*\((?<category>.*?)\),)? \s*
45     $text_re /x;
46 my $bad_version_re = qr{BADVERSION\([^"]*$text_re};
47    $regcomp_fail_re = qr/$regcomp_fail_re\([^"]*$text_re/;
48 my $regcomp_call_re = qr/$regcomp_re.*?$text_re/;
49
50 my %entries;
51
52 # Get the ignores that are compiled into this file
53 my $reading_categorical_exceptions;
54 while (<DATA>) {
55   chomp;
56   $entries{$_}{todo} = 1;
57   $reading_categorical_exceptions and $entries{$_}{cattodo}=1;
58   /__CATEGORIES__/ and ++$reading_categorical_exceptions;
59 }
60
61 my $pod = "pod/perldiag.pod";
62 my $cur_entry;
63 open my $diagfh, "<", $pod
64   or die "Can't open $pod: $!";
65
66 my $category_re = qr/ [a-z0-9_:]+?/;    # Note: requires an initial space
67 my $severity_re = qr/ . (?: \| . )* /x; # A severity is a single char, but can
68                                         # be of the form 'S|P|W'
69 my @same_descr;
70 while (<$diagfh>) {
71   if (m/^=item (.*)/) {
72     $cur_entry = $1;
73
74     # Allow multi-line headers
75     while (<$diagfh>) {
76       if (/^\s*$/) {
77         last;
78       }
79
80       $cur_entry .= $_;
81     }
82
83     $cur_entry =~ s/\n/ /gs; # Fix multi-line headers if they have \n's
84     $cur_entry =~ s/\s+\z//;
85
86     if (exists $entries{$cur_entry} &&  $entries{$cur_entry}{todo}
87                                     && !$entries{$cur_entry}{cattodo}) {
88         TODO: {
89             local $::TODO = "Remove the TODO entry \"$cur_entry\" from DATA as it is already in $pod near line $.";
90             ok($cur_entry);
91         }
92     }
93     # Make sure to init this here, so an actual entry in perldiag
94     # overwrites one in DATA.
95     $entries{$cur_entry}{todo} = 0;
96     $entries{$cur_entry}{line_number} = $.;
97   }
98
99   next if ! defined $cur_entry;
100
101   if (! $entries{$cur_entry}{severity}) {
102     if (/^ \( ( $severity_re )
103
104         # Can have multiple categories separated by commas
105         ( $category_re (?: , $category_re)* )? \) /x)
106     {
107       $entries{$cur_entry}{severity} = $1;
108       $entries{$cur_entry}{category} =
109         $2 && join ", ", sort split " ", $2 =~ y/,//dr;
110
111       # Record it also for other messages sharing the same description
112       @$_{qw<severity category>} =
113         @{$entries{$cur_entry}}{qw<severity category>}
114        for @same_descr;
115     }
116     elsif (! $entries{$cur_entry}{first_line} && $_ =~ /\S/) {
117
118       # Keep track of first line of text if doesn't contain a severity, so
119       # that can later examine it to determine if that is ok or not
120       $entries{$cur_entry}{first_line} = $_;
121     }
122     if (/\S/) {
123       @same_descr = ();
124     }
125     else {
126       push @same_descr, $entries{$cur_entry};
127     }
128   }
129 }
130
131 foreach my $cur_entry ( keys %entries) {
132     next if $entries{$cur_entry}{todo}; # If in this file, won't have a severity
133     if (! exists $entries{$cur_entry}{severity}
134
135             # If there is no first line, it was two =items in a row, so the
136             # second one is the one with with text, not this one.
137         && exists $entries{$cur_entry}{first_line}
138
139             # If the first line refers to another message, no need for severity
140         && $entries{$cur_entry}{first_line} !~ /^See/)
141     {
142         fail($cur_entry);
143         diag(
144             "   $pod entry at line $entries{$cur_entry}{line_number}\n"
145           . "       \"$cur_entry\"\n"
146           . "   is missing a severity and/or category"
147         );
148     }
149 }
150
151 # List from perlguts.pod "Formatted Printing of IVs, UVs, and NVs"
152 # Convert from internal formats to ones that the readers will be familiar
153 # with, while removing any format modifiers, such as precision, the
154 # presence of which would just confuse the pod's explanation
155 my %specialformats = (IVdf => 'd',
156                       UVuf => 'd',
157                       UVof => 'o',
158                       UVxf => 'x',
159                       UVXf => 'X',
160                       NVef => 'f',
161                       NVff => 'f',
162                       NVgf => 'f',
163                       HEKf256=>'s',
164                       HEKf => 's',
165                       UTF8f=> 's',
166                       SVf256=>'s',
167                       SVf32=> 's',
168                       SVf  => 's');
169 my $format_modifiers = qr/ [#0\ +-]*              # optional flags
170                           (?: [1-9][0-9]* | \* )? # optional field width
171                           (?: \. \d* )?           # optional precision
172                           (?: h|l )?              # optional length modifier
173                         /x;
174
175 my $specialformats =
176  join '|', sort { length $b cmp length $a } keys %specialformats;
177 my $specialformats_re = qr/%$format_modifiers"\s*($specialformats)(\s*")?/;
178
179 open my $fh, '<', 'MANIFEST' or die "Can't open MANIFEST: $!";
180 while (my $file = <$fh>) {
181     chomp $file;
182     $file =~ s/\s+.*//;
183     next unless $file =~ /\.(?:c|cpp|h|xs|y)\z/ or $file =~ /^perly\./;
184     # OS/2 extensions have never been migrated to ext/, hence the special case:
185     next if $file =~ m!\A(?:ext|dist|cpan|lib|t|os2/OS2)/!
186             && $file !~ m!\Aext/DynaLoader/!;
187     check_file($file);
188 }
189 close $fh or die $!;
190
191 # Standardize messages with variants into the form that appears
192 # in perldiag.pod -- useful for things without a diag_listed_as annotation
193 sub standardize {
194   my ($name) = @_;
195
196   if    ( $name =~ m/^(Invalid strict version format) \([^\)]*\)/ ) {
197     $name = "$1 (\%s)";
198   }
199   elsif ( $name =~ m/^(Invalid version format) \([^\)]*\)/ ) {
200     $name = "$1 (\%s)";
201   }
202   elsif ($name =~ m/^panic: /) {
203     $name = "panic: \%s";
204   }
205
206   return $name;
207 }
208
209 sub check_file {
210   my ($codefn) = @_;
211
212   print "# Checking $codefn\n";
213
214   open my $codefh, "<", $codefn
215     or die "Can't open $codefn: $!";
216
217   my $listed_as;
218   my $listed_as_line;
219   my $sub = 'top of file';
220   while (<$codefh>) {
221     chomp;
222     # Getting too much here isn't a problem; we only use this to skip
223     # errors inside of XS modules, which should get documented in the
224     # docs for the module.
225     if (m<^[^#\s]> and $_ !~ m/^[{}]*$/) {
226       $sub = $_;
227     }
228     next if $sub =~ m/^XS/;
229     if (m</\*\s*diag_listed_as: (.*?)\s*\*/>) {
230       $listed_as = $1;
231       $listed_as_line = $.+1;
232     }
233     next if /^#/;
234
235     my $multiline = 0;
236     # Loop to accumulate the message text all on one line.
237     if (m/(?:$source_msg_re(?:_nocontext)?|$regcomp_re)\s*\(/) {
238       while (not m/\);$/) {
239         my $nextline = <$codefh>;
240         # Means we fell off the end of the file.  Not terribly surprising;
241         # this code tries to merge a lot of things that aren't regular C
242         # code (preprocessor stuff, long comments).  That's OK; we don't
243         # need those anyway.
244         last if not defined $nextline;
245         chomp $nextline;
246         $nextline =~ s/^\s+//;
247         $_ =~ s/\\$//;
248         # Note that we only want to do this where *both* are true.
249         if ($_ =~ m/"\s*$/ and $nextline =~ m/^"/) {
250           $_ =~ s/"\s*$//;
251           $nextline =~ s/^"//;
252         }
253         $_ .= $nextline;
254         ++$multiline;
255       }
256     }
257     # This should happen *after* unwrapping, or we don't reformat the things
258     # in later lines.
259
260     s/$specialformats_re/"%$specialformats{$1}" .  (defined $2 ? '' : '"')/ge;
261
262     # Remove any remaining format modifiers, but not in %%
263     s/ (?<!%) % $format_modifiers ( [dioxXucsfeEgGp] ) /%$1/xg;
264
265     # The %"foo" thing needs to happen *before* this regex.
266     # diag($_);
267     # DIE is just return Perl_die
268     my ($name, $category, $routine);
269     if (/$source_msg_call_re/) {
270       ($name, $category, $routine) = ($+{'text'}, $+{'category'}, $+{'routine'});
271       # Sometimes the regexp will pick up too much for the category
272       # e.g., WARN_UNINITIALIZED), PL_warn_uninit_sv ... up to the next )
273       $category && $category =~ s/\).*//s;
274     }
275     elsif (/$bad_version_re/) {
276       ($name, $category) = ($+{'text'}, undef);
277     }
278     elsif (/$regcomp_fail_re/) {
279       #  FAIL("foo") -> "foo in regex m/%s/"
280       # vFAIL("foo") -> "foo in regex; marked by <-- HERE in m/%s/"
281       ($name, $category) = ($+{'text'}, undef);
282       $name .=
283         " in regex" . ("; marked by <-- HERE in" x /vFAIL/) . " m/%s/";
284     }
285     elsif (/$regcomp_call_re/) {
286       # vWARN/ckWARNreg("foo") -> "foo in regex; marked by <-- HERE in m/%s/
287       ($name, $category, $routine) = ($+{'text'}, undef, $+{'routine'});
288       $name .= " in regex; marked by <-- HERE in m/%s/";
289       $category = 'WARN_REGEXP';
290       if ($routine =~ /dep/) {
291         $category .= ',WARN_DEPRECATED';
292       }
293     }
294     else {
295       next;
296     }
297
298     # Try to guess what the severity should be.  In the case of
299     # Perl_ck_warner and other _ck_ functions, we can tell whether it is
300     # a severe/default warning or no by the _d suffix.  In the case of
301     # other warn functions we cannot tell, because Perl_warner may be pre-
302     # ceded by if(ckWARN) or if(ckWARN_d).
303     my $severity = !$routine                   ? '[PFX]'
304                  :  $routine =~ /warn.*_d\z/   ? '[DS]'
305                  :  $routine =~ /ck_warn/      ?  'W'
306                  :  $routine =~ /warner/       ? '[WDS]'
307                  :  $routine =~ /warn/         ?  'S'
308                  :  $routine =~ /ckWARN.*dep/  ?  'D'
309                  :  $routine =~ /ckWARN\d*reg_d/? 'S'
310                  :  $routine =~ /ckWARN\d*reg/ ?  'W'
311                  :  $routine =~ /vWARN\d/      ? '[WDS]'
312                  :                             '[PFX]';
313     my $categories;
314     if (defined $category) {
315       $category =~ s/__/::/g;
316       $categories =
317         join ", ",
318               sort map {s/^WARN_//; lc $_} split /\s*[|,]\s*/, $category;
319     }
320     if ($listed_as and $listed_as_line == $. - $multiline) {
321       $name = $listed_as;
322     } else {
323       # The form listed in perldiag ignores most sorts of fancy printf
324       # formatting, or makes it more perlish.
325       $name =~ s/%%/%/g;
326       $name =~ s/%l[ud]/%d/g;
327       $name =~ s/%\.(\d+|\*)s/\%s/g;
328       $name =~ s/(?:%s){2,}/%s/g;
329       $name =~ s/(\\")|("\s*[A-Z_]+\s*")/$1 ? '"' : '%s'/egg;
330       $name =~ s/\\t/\t/g;
331       $name =~ s/\\n/\n/g;
332       $name =~ s/\s+$//;
333       $name =~ s/(\\)\\/$1/g;
334     }
335
336     # Extra explanatory info on an already-listed error, doesn't
337     # need it's own listing.
338     next if $name =~ m/^\t/;
339
340     # Happens fairly often with PL_no_modify.
341     next if $name eq '%s';
342
343     # Special syntax for magic comment, allows ignoring the fact
344     # that it isn't listed.  Only use in very special circumstances,
345     # like this script failing to notice that the Perl_croak call is
346     # inside an #if 0 block.
347     next if $name eq 'SKIPME';
348
349     next if $name=~/\[TESTING\]/; # ignore these as they are works in progress
350
351     check_message(standardize($name),$codefn,$severity,$categories);
352   }
353 }
354
355 sub check_message {
356     my($name,$codefn,$severity,$categories,$partial) = @_;
357     my $key = $name =~ y/\n/ /r;
358     my $ret;
359
360     # Try to reduce printf() formats to simplest forms
361     # Really this should be matching %s, etc like diagnostics.pm does
362
363     # Kill flags
364     $key =~ s/%[#0\-+]/%/g;
365
366     # Kill width
367     $key =~ s/\%(\d+|\*)/%/g;
368
369     # Kill precision
370     $key =~ s/\%\.(\d+|\*)/%/g;
371
372     if (exists $entries{$key} and
373           # todo + cattodo means it is not found and it is not in the
374           # regular todo list, either
375           !$entries{$key}{todo} || !$entries{$key}{cattodo}) {
376       $ret = 1;
377       if ( $entries{$key}{seen}++ ) {
378         # no need to repeat entries we've tested
379       } elsif ($entries{$key}{todo}) {
380         TODO: {
381           no warnings 'once';
382           local $::TODO = 'in DATA';
383           # There is no listing, but it is in the list of exceptions.  TODO FAIL.
384           fail($key);
385           diag(
386             "    Message '$name'\n    from $codefn line $. is not listed in $pod\n".
387             "    (but it wasn't documented in 5.10 either, so marking it TODO)."
388           );
389         }
390       } else {
391         # We found an actual valid entry in perldiag.pod for this error.
392         pass($key);
393
394         return $ret
395           if $entries{$key}{cattodo};
396
397         # Now check the category and severity
398
399         # Cache our severity qr thingies
400         use feature 'state';
401         state %qrs;
402         my $qr = $qrs{$severity} ||= qr/$severity/;
403
404         like($entries{$key}{severity}, $qr,
405           $severity =~ /\[/
406             ? "severity is one of $severity for $key"
407             : "severity is $severity for $key");
408
409         is($entries{$key}{category}, $categories,
410            ($categories ? "categories are [$categories]" : "no category")
411              . " for $key");
412       }
413     } elsif ($partial) {
414       # noop
415     } else {
416       my $ok;
417       if ($name =~ /\n/) {
418         $ok = 1;
419         check_message($_,$codefn,$severity,$categories,1) or $ok = 0, last
420           for split /\n/, $name;
421       }
422       if ($ok) {
423         # noop
424       } elsif ($make_exceptions_list) {
425         # We're making an updated version of the exception list, to
426         # stick in the __DATA__ section.  I honestly can't think of
427         # a situation where this is the right thing to do, but I'm
428         # leaving it here, just in case one of my descendents thinks
429         # it's a good idea.
430         print STDERR "$key\n";
431       } else {
432         # No listing found, and no excuse either.
433         # Find the correct place in perldiag.pod, and add a stanza beginning =item $name.
434         fail($name);
435         diag("    Message '$name'\n    from $codefn line $. is not listed in $pod");
436       }
437       # seen it, so only fail once for this message
438       $entries{$name}{seen}++;
439     }
440
441     die if $name =~ /%$/;
442     return $ret;
443 }
444
445 # Lists all missing things as of the inauguration of this script, so we
446 # don't have to go from "meh" to perfect all at once.
447
448 # PLEASE DO NOT ADD TO THIS LIST.  Instead, write an entry in
449 # pod/perldiag.pod for your new (warning|error).  Nevertheless,
450 # listing exceptions here when this script is not smart enough
451 # to recognize the messages is not so bad, as long as there are
452 # entries in perldiag.
453
454 # Entries after __CATEGORIES__ are those that are in perldiag but fail the
455 # severity/category test.
456
457 # Also FIXME this test, as the first entry in TODO *is* covered by the
458 # description: Malformed UTF-8 character (%s)
459 __DATA__
460 Malformed UTF-8 character (unexpected non-continuation byte 0x%x, immediately after start byte 0x%x)
461
462 Cannot apply "%s" in non-PerlIO perl
463 Can't find string terminator %c%s%c anywhere before EOF
464 Can't fix broken locale name "%s"
465 Can't get short module name from a handle
466 Can't locate %s:   %s
467 Can't locate object method "%s" via package "%s" (perhaps you forgot to load "%s"?)
468 Can't pipe "%s": %s
469 Can't spawn: %s
470 Can't spawn "%s": %s
471 Can't %s script `%s' with ARGV[0] being `%s'
472 Can't %s "%s": %s
473 Can't %s `%s' with ARGV[0] being `%s' (looking for executables only, not found)
474 Can't use string ("%s"%s) as a subroutine ref while "strict refs" in use
475 \%c better written as $%c
476 Character(s) in '%c' format wrapped in %s
477 chown not implemented!
478 clear %s
479 Code missing after '/' in pack
480 Code missing after '/' in unpack
481 '%c' outside of string in pack
482 Debug leaking scalars child failed%s with errno %d: %s
483 '/' does not take a repeat count in %s
484 -Dp not implemented on this platform
485 Error reading "%s": %s
486 execl not implemented!
487 EVAL without pos change exceeded limit in regex
488 Filehandle opened only for %sput
489 Filehandle %s opened only for %sput
490 Filehandle STD%s reopened as %s only for input
491 filter_del can only delete in reverse order (currently)
492 YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET! FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!
493 free %s
494 get %s %p %p %p
495 getpwnam returned invalid UIC %o for user "%s"
496 glob failed (can't start child: %s)
497 glob failed (child exited with status %d%s)
498 Goto undefined subroutine
499 Goto undefined subroutine &%s
500 Got signal %d
501 ()-group starts with a count in %s
502 Illegal binary digit '%c' ignored
503 Illegal character %sin prototype for %s : %s
504 Illegal hexadecimal digit '%c' ignored
505 Illegal octal digit '%c' ignored
506 Invalid argument to sv_cat_decode
507 Invalid range "%c-%c" in transliteration operator
508 Invalid separator character %c%c%c in PerlIO layer specification %s
509 Invalid TOKEN object ignored
510 Invalid type '%c' in pack
511 Invalid type '%c' in %s
512 Invalid type '%c' in unpack
513 Invalid type ',' in %s
514 ioctlsocket not implemented!
515 killpg not implemented!
516 List form of pipe open not implemented
517 Malformed integer in [] in %s
518 Malformed UTF-8 character (fatal)
519 Missing (suid) fd script name
520 More than one argument to open
521 More than one argument to open(,':%s')
522 \N{} in character class restricted to one character in regex; marked by <-- HERE in m/%s/
523 No %s allowed while running setgid
524 No %s allowed with (suid) fdscript
525 Not an XSUB reference
526 Operator or semicolon missing before %c%s
527 Out of memory during list extend
528 PerlApp::TextQuery: no arguments, please
529 POSIX syntax [%c %c] is reserved for future extensions in regex; marked by <-- HERE in m/%s/
530 ptr wrong %p != %p fl=%x nl=%p e=%p for %d
531 Recompile perl with -DDEBUGGING to use -D switch (did you mean -d ?)
532 Regexp modifier "%c" may appear a maximum of twice in regex; marked by <-- HERE in m/%s/
533 Regexp modifier "%c" may not appear twice in regex; marked by <-- HERE in m/%s/
534 Regexp modifiers "%c" and "%c" are mutually exclusive in regex; marked by <-- HERE in m/%s/
535 Regexp *+ operand could be empty in regex; marked by <-- HERE in m/%s/
536 Reversed %c= operator
537 %s(%f) failed
538 %sCompilation failed in require
539 Sequence (?%c...) not implemented in regex; marked by <-- HERE in m/%s/
540 Sequence (%s...) not recognized in regex; marked by <-- HERE in m/%s/
541 Sequence %s... not terminated in regex; marked by <-- HERE in m/%s/
542 Sequence (?%c... not terminated in regex; marked by <-- HERE in m/%s/
543 Sequence (?(%c... not terminated in regex; marked by <-- HERE in m/%s/
544 Sequence (?R) not terminated in regex m/%s/
545 set %s %p %p %p
546 %s free() ignored (RMAGIC, PERL_CORE)
547 %s has too many errors.
548 SIG%s handler "%s" not defined.
549 %s in %s
550 Size magic not implemented
551 %s number > %s non-portable
552 %srealloc() %signored
553 %s in regex m/%s/
554 %s on %s %s
555 socketpair not implemented!
556 Starting Full Screen process with flag=%d, mytype=%d
557 Starting PM process with flag=%d, mytype=%d
558 sv_2iv assumed (U_V(fabs((double)SvNVX(sv))) < (UV)IV_MAX) but SvNVX(sv)=%f U_V is 0x%x, IV_MAX is 0x%x
559 switching effective gid is not implemented
560 switching effective uid is not implemented
561 System V IPC is not implemented on this machine
562 -T and -B not implemented on filehandles
563 Terminating on signal SIG%s(%d)
564 The crypt() function is not implemented on NetWare
565 The flock() function is not implemented on NetWare
566 The rewinddir() function is not implemented on NetWare
567 The seekdir() function is not implemented on NetWare
568 The telldir() function is not implemented on NetWare
569 Too deeply nested ()-groups in %s
570 Too many args on %s line of "%s"
571 U0 mode on a byte string
572 unable to find VMSPIPE.COM for i/o piping
573 Unrecognized character %s; marked by <-- HERE after %s<-- HERE near column %d
574 Unstable directory path, current directory changed unexpectedly
575 Unterminated compressed integer in unpack
576 Usage: %s::%s(%s)
577 Usage: File::Copy::rmscopy(from,to[,date_flag])
578 Usage: VMS::Filespec::candelete(spec)
579 Usage: VMS::Filespec::fileify(spec)
580 Usage: VMS::Filespec::pathify(spec)
581 Usage: VMS::Filespec::rmsexpand(spec[,defspec])
582 Usage: VMS::Filespec::unixify(spec)
583 Usage: VMS::Filespec::unixpath(spec)
584 Usage: VMS::Filespec::unixrealpath(spec)
585 Usage: VMS::Filespec::vmsify(spec)
586 Usage: VMS::Filespec::vmspath(spec)
587 Usage: VMS::Filespec::vmsrealpath(spec)
588 Use of inherited AUTOLOAD for non-method %s::%s() is deprecated
589 utf8 "\x%X" does not map to Unicode
590 Value of logical "%s" too long. Truncating to %i bytes
591 waitpid: process %x is not a child of process %x
592 Wide character
593 Wide character in $/
594 Within []-length '*' not allowed in %s
595 Within []-length '%c' not allowed in %s
596 Wrong syntax (suid) fd script name "%s"
597 'X' outside of string in %s
598 'X' outside of string in unpack
599 Zero length \N{} in regex; marked by <-- HERE in m/%s/
600
601 __CATEGORIES__
602 Code point 0x%X is not Unicode, all \p{} matches fail; all \P{} matches succeed
603 Code point 0x%X is not Unicode, may not be portable
604 Illegal character \%o (carriage return)
605 Missing argument in %s
606 Unicode non-character U+%X is illegal for open interchange
607 Operation "%s" returns its argument for non-Unicode code point 0x%X
608 Operation "%s" returns its argument for UTF-16 surrogate U+%X
609 Unicode surrogate U+%X is illegal in UTF-8
610 UTF-16 surrogate U+%X
611 False [] range "%s" in regex; marked by <-- HERE in m/%s/