diff options
author | Peter Martini <PeterCMartini@GMail.com> | 2013-06-25 04:47:56 -0400 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2013-07-10 20:41:38 -0700 |
commit | f791a21a201869623475139b9a596b9cff272a03 (patch) | |
tree | a74703e69891f2c053f31ef683a3e55165bfc8be | |
parent | 9c8008621f0729831a4b338ab439f4006a70326f (diff) | |
download | perl-f791a21a201869623475139b9a596b9cff272a03.tar.gz |
Split the handling for "Illegal character" and "Illegal character after '_'"
After applying this patch, both can now be triggered at once, whereas
previously any use of '_' would trigger the "after '_'" variant. Since
the two warnings warn for different reasons, there's no reason to
conflate the two. Also updated perldiag with a clearer explanation
of the tighter restrictions after an underscore.
(In the tests, the change of uniproto12 to uniproto13 is merely correcting
an error from a previous patch, reusing the name would conflate
two kinds of tests in one statement).
-rw-r--r-- | pod/perldiag.pod | 4 | ||||
-rw-r--r-- | t/comp/proto.t | 39 | ||||
-rw-r--r-- | toke.c | 23 |
3 files changed, 48 insertions, 18 deletions
diff --git a/pod/perldiag.pod b/pod/perldiag.pod index fa9d7f2744..6552f67206 100644 --- a/pod/perldiag.pod +++ b/pod/perldiag.pod @@ -2231,7 +2231,9 @@ offending digit. =item Illegal character after '_' in prototype for %s : %s (W illegalproto) An illegal character was found in a prototype declaration. -Legal characters in prototypes are $, @, %, *, ;, [, ], &, \, and +. +The '_' in a prototype must be followed by a ';', indicating the rest of +the parameters are optional, or one of '@' or '%', since those two will +accept 0 or more final parameters. =item Illegal character \%o (carriage return) diff --git a/t/comp/proto.t b/t/comp/proto.t index d472cd3fba..213ae3a543 100644 --- a/t/comp/proto.t +++ b/t/comp/proto.t @@ -18,7 +18,7 @@ BEGIN { # strict use strict; -print "1..187\n"; +print "1..196\n"; my $i = 1; @@ -669,19 +669,43 @@ for my $p ( "", qw{ () ($) ($@) ($%) ($;$) (&) (&\@) (&@) (%) (\%) (\@) } ) { eval 'sub badproto (@bar) { 1; }'; print "not " unless $warn =~ /Illegal character in prototype for main::badproto : \@bar/; - print "ok ", $i++, "\n"; + print "ok ", $i++, " checking badproto - (\@bar)\n"; eval 'sub badproto2 (bar) { 1; }'; print "not " unless $warn =~ /Illegal character in prototype for main::badproto2 : bar/; - print "ok ", $i++, "\n"; + print "ok ", $i++, " checking badproto2 - (bar)\n"; eval 'sub badproto3 (&$bar$@) { 1; }'; print "not " unless $warn =~ /Illegal character in prototype for main::badproto3 : &\$bar\$\@/; - print "ok ", $i++, "\n"; + print "ok ", $i++, " checking badproto3 - (&\$bar\$\@)\n"; eval 'sub badproto4 (@ $b ar) { 1; }'; + # This one emits two warnings print "not " unless $warn =~ /Illegal character in prototype for main::badproto4 : \@ \$b ar/; - print "ok ", $i++, "\n"; + print "ok ", $i++, " checking badproto4 - (\@ \$b ar) - illegal character\n"; + print "not " unless $warn =~ /Prototype after '\@' for main::badproto4 : \@ \$b ar/; + print "ok ", $i++, " checking badproto4 - (\@ \$b ar) - prototype after '\@'\n"; + + eval 'sub badproto5 ($_$) { 1; }'; + print "not " unless $warn =~ /Illegal character after '_' in prototype for main::badproto5 : \$_\$/; + print "ok ", $i++, " checking badproto5 - (\$_\$) - illegal character after '_'\n"; + print "not " if $warn =~ /Illegal character in prototype for main::badproto5 : \$_\$/; + print "ok ", $i++, " checking badproto5 - (\$_\$) - but not just illegal character\n"; + eval 'sub badproto6 (bar_) { 1; }'; + print "not " unless $warn =~ /Illegal character in prototype for main::badproto6 : bar_/; + print "ok ", $i++, " checking badproto6 - (bar_) - illegal character\n"; + print "not " if $warn =~ /Illegal character after '_' in prototype for main::badproto6 : bar_/; + print "ok ", $i++, " checking badproto6 - (bar_) - shouldn't add \"after '_'\"\n"; + eval 'sub badproto7 (_;bar) { 1; }'; + print "not " unless $warn =~ /Illegal character in prototype for main::badproto7 : _;bar/; + print "ok ", $i++, " checking badproto7 - (_;bar) - illegal character\n"; + print "not " if $warn =~ /Illegal character after '_' in prototype for main::badproto7 : _;bar/; + print "ok ", $i++, " checking badproto7 - (_;bar) - shouldn't add \"after '_'\"\n"; + eval 'sub badproto8 (_b) { 1; }'; + print "not " unless $warn =~ /Illegal character after '_' in prototype for main::badproto8 : _b/; + print "ok ", $i++, " checking badproto8 - (_b) - illegal character after '_'\n"; + print "not " unless $warn =~ /Illegal character in prototype for main::badproto8 : _b/; + print "ok ", $i++, " checking badproto8 - (_b) - just illegal character\n"; } # make sure whitespace in prototypes works @@ -745,8 +769,9 @@ print "not " unless eval 'sub uniproto12 (;;;+) {} uniproto12 $_, 1' or warn $@; print "ok ", $i++, " - uniproto12 (;;;*)\n"; print "not " - unless eval 'sub uniproto12 ( ; ; ; + ) {} uniproto12 $_, 1' or warn $@; -print "ok ", $i++, " - uniproto12 ( ; ; ; * )\n"; + unless eval 'sub uniproto13 ( ; ; ; + ) {} uniproto13 $_, 1' or warn $@; +print "ok ", $i++, " - uniproto13 ( ; ; ; * )\n"; + # Test that a trailing semicolon makes a sub have listop precedence sub unilist ($;) { $_[0]+1 } @@ -1608,7 +1608,7 @@ Perl_validate_proto(pTHX_ SV *name, SV *proto, bool warn) bool proto_after_greedy_proto = FALSE; bool must_be_last = FALSE; bool underscore = FALSE; - bool seen_underscore = FALSE; + bool bad_proto_after_underscore = FALSE; PERL_ARGS_ASSERT_VALIDATE_PROTO; @@ -1620,16 +1620,15 @@ Perl_validate_proto(pTHX_ SV *name, SV *proto, bool warn) if (!isSPACE(*p)) { if (must_be_last) proto_after_greedy_proto = TRUE; + if (underscore) { + if (!strchr(";@%", *p)) + bad_proto_after_underscore = TRUE; + underscore = FALSE; + } if (!strchr("$@%*;[]&\\_+", *p) || *p == '\0') { bad_proto = TRUE; } else { - if (underscore) { - if(!strchr(";@%", *p)) - bad_proto = TRUE; - underscore = FALSE; - } - if (*p == '[') in_brackets = TRUE; else if (*p == ']') @@ -1641,7 +1640,7 @@ Perl_validate_proto(pTHX_ SV *name, SV *proto, bool warn) greedy_proto = *p; } else if (*p == '_') - underscore = seen_underscore = TRUE; + underscore = TRUE; } if (*p == '\\') after_slash = TRUE; @@ -1664,8 +1663,12 @@ Perl_validate_proto(pTHX_ SV *name, SV *proto, bool warn) greedy_proto, SVfARG(name), p); if (bad_proto) Perl_warner(aTHX_ packWARN(WARN_ILLEGALPROTO), - "Illegal character %sin prototype for %"SVf" : %s", - seen_underscore ? "after '_' " : "", SVfARG(name), p); + "Illegal character in prototype for %"SVf" : %s", + SVfARG(name), p); + if (bad_proto_after_underscore) + Perl_warner(aTHX_ packWARN(WARN_ILLEGALPROTO), + "Illegal character after '_' in prototype for %"SVf" : %s", + SVfARG(name), p); } return (! (proto_after_greedy_proto || bad_proto) ); |