From 0da72d5e623b55d88fb3772b9c91e8f2d1ea7c40 Mon Sep 17 00:00:00 2001 From: Karl Williamson Date: Mon, 11 Jun 2012 11:48:04 -0600 Subject: [PATCH] Require space between regex and following alnum operator Not having such space has been deprecated since v5.14.0. --- pod/perldelta.pod | 15 +++++++++++++++ pod/perldiag.pod | 50 +++++++++++++++----------------------------------- pod/perlop.pod | 8 -------- t/lib/warnings/toke | 19 ++++++++++++------- t/re/pat.t | 47 +---------------------------------------------- toke.c | 50 ++++---------------------------------------------- 6 files changed, 47 insertions(+), 142 deletions(-) diff --git a/pod/perldelta.pod b/pod/perldelta.pod index 7980515..fe157fd 100644 --- a/pod/perldelta.pod +++ b/pod/perldelta.pod @@ -64,6 +64,21 @@ referred to U+0007, but would raise a deprecated warning. Now, "BELL" refers to U+1F514, and the name for U+0007 is "ALERT". All the functions in L have been correspondingly updated. +=head2 Alphanumeric operators must now be separated from the closing +delimter of regular expressions + +You may no longer write something like: + + m/a/and 1 + +Instead you must write + + m/a/ and 1 + +with whitespace separating the operator from the closing delimiter of +the regular expression. Not having whitespace has resulted in a +deprecated warning since Perl v5.14.0. + =head1 Deprecations XXX Any deprecated features, syntax, modules etc. should be listed here. diff --git a/pod/perldiag.pod b/pod/perldiag.pod index 2a486bb..5b5bbdb 100644 --- a/pod/perldiag.pod +++ b/pod/perldiag.pod @@ -135,20 +135,6 @@ string C<"-foo">, or a call to the function C, negated. If you meant the string, just write C<"-foo">. If you meant the function call, write C<-foo()>. -=item Ambiguous use of 's//le...' resolved as 's// le...'; Rewrite as 's//el' if you meant 'use locale rules and evaluate rhs as an expression'. In Perl 5.18, it will be resolved the other way - -(W deprecated, ambiguous) You wrote a pattern match with substitution -immediately followed by "le". In Perl 5.16 and earlier, this is -resolved as meaning to take the result of the substitution, and see if -it is stringwise less-than-or-equal-to what follows in the expression. -Having the "le" immediately following a pattern is deprecated behavior, -so in Perl 5.18, this expression will be resolved as meaning to do the -pattern match using the rules of the current locale, and evaluate the -rhs as an expression when doing the substitution. In 5.14, and 5.16 if -you want the latter interpretation, you can simply write "el" instead. -But note that the C modifier should not be used explicitly anyway; -you should use C instead. See L. - =item '|' and '<' may not both be specified on command line (F) An error peculiar to VMS. Perl does its own command line @@ -2111,27 +2097,6 @@ spots. This is now heavily deprecated. (F) The parser has given up trying to parse the program after 10 errors. Further error messages would likely be uninformative. -=item Having no space between pattern and following word is deprecated - -(D syntax) - -You had a word that isn't a regex modifier immediately following -a pattern without an intervening space. If you are trying to use -the C flags on a substitution, use C instead. Otherwise, add -white space between the pattern and following word to eliminate -the warning. As an example of the latter, the two constructs: - - - $a =~ m/$foo/sand $bar - $a =~ m/$foo/s and $bar - -both currently mean the same thing, but it is planned to disallow -the first form in Perl 5.18. And, - - $a =~ m/$foo/and $bar - -will be disallowed too. - =item Hexadecimal number > 0xffffffff non-portable (W portable) The hexadecimal number you specified is larger than 2**32-1 @@ -4999,6 +4964,21 @@ subvert Perl's population of %ENV for nefarious purposes. (W) You tried to use an unknown subpragma of the "re" pragma. +=item Unknown regex modifier "%s" + +(F) Alphanumerics immediately following the closing delimiter +of a regular expression pattern are interpreted by Perl as modifier +flags for the regex. One of the ones you specified is invalid. One way +this can happen is if you didn't put in white space between the end of +the regex and a following alphanumeric operator: + + if ($a =~ /foo/and $bar == 3) { ... } + +The C<"a"> is a valid modifier flag, but the C<"n"> is not, and raises +this error. Likely what was meant instead was: + + if ($a =~ /foo/ and $bar == 3) { ... } + =item Unknown switch condition (?(%s in regex; marked by <-- HERE in m/%s/ (F) The condition part of a (?(condition)if-clause|else-clause) construct diff --git a/pod/perlop.pod b/pod/perlop.pod index 7b2d0a3..a53f869 100644 --- a/pod/perlop.pod +++ b/pod/perlop.pod @@ -2068,14 +2068,6 @@ to occur that you might want. Here are two common cases: # expand tabs to 8-column spacing 1 while s/\t+/' ' x (length($&)*8 - length($`)%8)/e; -C is treated as a substitution followed by the C operator, not -the C flags. This may change in a future version of Perl. It -produces a warning if warnings are enabled. To disambiguate, use a space -or change the order of the flags: - - s/foo/bar/ le 5; # "le" infix operator - s/foo/bar/el; # "e" and "l" flags - =back =head2 Quote-Like Operators diff --git a/t/lib/warnings/toke b/t/lib/warnings/toke index a9106fb..db4bbee 100644 --- a/t/lib/warnings/toke +++ b/t/lib/warnings/toke @@ -143,19 +143,24 @@ Use of comma-less variable list is deprecated at - line 4. Use of comma-less variable list is deprecated at - line 4. ######## # toke.c -$a =~ m/$foo/sand $bar; -$a =~ s/$foo/fool/sand $bar; $a = <<; no warnings 'deprecated' ; -$a =~ m/$foo/sand $bar; -$a =~ s/$foo/fool/sand $bar; $a = <<; EXPECT -Having no space between pattern and following word is deprecated at - line 2. -Having no space between pattern and following word is deprecated at - line 3. -Use of bare << to mean <<"" is deprecated at - line 4. +Use of bare << to mean <<"" is deprecated at - line 2. +######## +# toke.c +$a =~ m/$foo/eq; +$a =~ s/$foo/fool/seq; + +EXPECT +OPTION fatal +Unknown regexp modifier "/e" at - line 2, near "=~ " +Unknown regexp modifier "/q" at - line 2, near "=~ " +Unknown regexp modifier "/q" at - line 3, near "=~ " +Execution of - aborted due to compilation errors. ######## # toke.c use warnings 'syntax' ; diff --git a/t/re/pat.t b/t/re/pat.t index 9c29c95..e03f5ca 100644 --- a/t/re/pat.t +++ b/t/re/pat.t @@ -19,7 +19,7 @@ BEGIN { require './test.pl'; } -plan tests => 474; # Update this when adding/deleting tests. +plan tests => 436; # Update this when adding/deleting tests. run_tests() unless caller; @@ -1069,51 +1069,6 @@ sub run_tests { } { - # Test that a regex followed by an operator and/or a statement modifier work - # These tests use string-eval so that it reports a clean error when it fails - # (without the string eval the test script might be unparseable) - - # Note: these test check the behaviour that currently is valid syntax - # If a new regex modifier is added and a test fails then there is a backwards-compatibility issue - # Note-2: a new deprecate warning was added for this with commit e6897b1a5db0410e387ccbf677e89fc4a1d8c97a - # which indicate that this syntax will be removed in 5.16. - # When this happens the tests can be removed - - foreach (['my $r = "a" =~ m/a/lt 2', 'm', 'lt'], - ['my $r = "a" =~ m/a/le 1', 'm', 'le'], - ['my $r = "a" =~ m/a/eq 1', 'm', 'eq'], - ['my $r = "a" =~ m/a/ne 0', 'm', 'ne'], - ['my $r = "a" =~ m/a/and 1', 'm', 'and'], - ['my $r = "a" =~ m/a/unless 0', 'm', 'unless'], - ['my $c = 1; my $r; $r = "a" =~ m/a/while $c--', 'm', 'while'], - ['my $c = 0; my $r; $r = "a" =~ m/a/until $c++', 'm', 'until'], - ['my $r; $r = "a" =~ m/a/for 1', 'm', 'for'], - ['my $r; $r = "a" =~ m/a/foreach 1', 'm', 'foreach'], - - ['my $t = "a"; my $r = $t =~ s/a//lt 2', 's', 'lt'], - ['my $t = "a"; my $r = $t =~ s/a//le 1', 's', 'le'], - ['my $t = "a"; my $r = $t =~ s/a//ne 0', 's', 'ne'], - ['my $t = "a"; my $r = $t =~ s/a//and 1', 's', 'and'], - ['my $t = "a"; my $r = $t =~ s/a//unless 0', 's', 'unless'], - - ['my $c = 1; my $r; my $t = "a"; $r = $t =~ s/a//while $c--', 's', 'while'], - ['my $c = 0; my $r; my $t = "a"; $r = $t =~ s/a//until $c++', 's', 'until'], - ['my $r; my $t = "a"; $r = $t =~ s/a//for 1', 's', 'for'], - ['my $r; my $t = "a"; $r = $t =~ s/a//for 1', 's', 'foreach'], - ) { - my $message = sprintf 'regex (%s) followed by $_->[2]', - $_->[1] eq 'm' ? 'm//' : 's///'; - my $code = "$_->[0]; 'eval_ok ' . \$r"; - my $result = do { - no warnings 'syntax'; - eval $code; - }; - is($@, '', $message); - is($result, 'eval_ok 1', $message); - } - } - - { my $str= "\x{100}"; chop $str; my $qr= qr/$str/; diff --git a/toke.c b/toke.c index 0d5e321..6079817 100644 --- a/toke.c +++ b/toke.c @@ -9014,13 +9014,15 @@ S_pmflag(pTHX_ const char* const valid_flags, U32 * pmfl, char** s, char* charse * current regex. This routine will set it to any charset modifier found. * The caller shouldn't change it. This way, another charset modifier * encountered in the parse can be detected as an error, as we have decided - * allow only one */ + * to allow only one */ const char c = **s; if (! strchr(valid_flags, c)) { if (isALNUM(c)) { - goto deprecate; + yyerror(Perl_form(aTHX_ "Unknown regexp modifier \"/%c\"", c)); + (*s)++; + return TRUE; } return FALSE; } @@ -9034,34 +9036,6 @@ S_pmflag(pTHX_ const char* const valid_flags, U32 * pmfl, char** s, char* charse case KEEPCOPY_PAT_MOD: *pmfl |= RXf_PMf_KEEPCOPY; break; case NONDESTRUCT_PAT_MOD: *pmfl |= PMf_NONDESTRUCT; break; case LOCALE_PAT_MOD: - - /* In 5.14, qr//lt is legal but deprecated; the 't' means they - * can't be regex modifiers. - * In 5.14, s///le is legal and ambiguous. Try to disambiguate as - * much as easily done. s///lei, for example, has to mean regex - * modifiers if it's not an error (as does any word character - * following the 'e'). Otherwise, we resolve to the backwards- - * compatible, but less likely 's/// le ...', i.e. as meaning - * less-than-or-equal. The reason it's not likely is that s// - * returns a number for code in the field (/r returns a string, but - * that wasn't added until the 5.13 series), and so '<=' should be - * used for comparing, not 'le'. */ - if (*((*s) + 1) == 't') { - goto deprecate; - } - else if (*((*s) + 1) == 'e' && ! isALNUM(*((*s) + 2))) { - - /* 'e' is valid only for substitutes, s///e. If it is not - * valid in the current context, then 'm//le' must mean the - * comparison operator, so use the regular deprecation message. - */ - if (! strchr(valid_flags, 'e')) { - goto deprecate; - } - Perl_ck_warner_d(aTHX_ packWARN(WARN_AMBIGUOUS), - "Ambiguous use of 's//le...' resolved as 's// le...'; Rewrite as 's//el' if you meant 'use locale rules and evaluate rhs as an expression'. In Perl 5.18, it will be resolved the other way"); - return FALSE; - } if (*charset) { goto multiple_charsets; } @@ -9069,11 +9043,6 @@ S_pmflag(pTHX_ const char* const valid_flags, U32 * pmfl, char** s, char* charse *charset = c; break; case UNICODE_PAT_MOD: - /* In 5.14, qr//unless and qr//until are legal but deprecated; the - * 'n' means they can't be regex modifiers */ - if (*((*s) + 1) == 'n') { - goto deprecate; - } if (*charset) { goto multiple_charsets; } @@ -9081,12 +9050,6 @@ S_pmflag(pTHX_ const char* const valid_flags, U32 * pmfl, char** s, char* charse *charset = c; break; case ASCII_RESTRICT_PAT_MOD: - /* In 5.14, qr//and is legal but deprecated; the 'n' means they - * can't be regex modifiers */ - if (*((*s) + 1) == 'n') { - goto deprecate; - } - if (! *charset) { set_regex_charset(pmfl, REGEX_ASCII_RESTRICTED_CHARSET); } @@ -9116,11 +9079,6 @@ S_pmflag(pTHX_ const char* const valid_flags, U32 * pmfl, char** s, char* charse (*s)++; return TRUE; - deprecate: - Perl_ck_warner_d(aTHX_ packWARN(WARN_SYNTAX), - "Having no space between pattern and following word is deprecated"); - return FALSE; - multiple_charsets: if (*charset != c) { yyerror(Perl_form(aTHX_ "Regexp modifiers \"/%c\" and \"/%c\" are mutually exclusive", *charset, c)); -- 1.8.3.1