tweak "0x123.456" deprecation
Zefram [Fri, 30 Apr 2010 19:23:59 +0000 (20:23 +0100)]
Some improvements to the deprecation added in commit
6fb472bab4fadd0ae2ca9624b74596afab4fb8cb:

- warning message includes the word "deprecated"
- warning is in "syntax" category as well as "deprecated"
- more systematic tests
- dot detected more efficiently by incorporation into existing switch
- small doc rewording
- avoid the warning in t/op/taint.t

MANIFEST
pod/perldiag.pod
t/comp/binary_num.t [new file with mode: 0644]
t/lib/warnings/toke
t/op/taint.t
toke.c

index f3827c8..ad842f7 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -4188,6 +4188,7 @@ t/cmd/mod.t                       See if statement modifiers work
 t/cmd/subval.t                 See if subroutine values work
 t/cmd/switch.t                 See if switch optimizations work
 t/cmd/while.t                  See if while loops work
+t/comp/binary_num.t            See if bin/oct/hex numbers are parsed right
 t/comp/bproto.t                        See if builtins conform to their prototypes
 t/comp/cmdopt.t                        See if command optimization works
 t/comp/colon.t                 See if colons are parsed correctly
index 6d6322a..1d3b55c 100644 (file)
@@ -1534,12 +1534,13 @@ you called it with no args and both C<$@> and C<$_> were empty.
 
 See Server error.
 
-=item Dot after %s literal is concatenation
+=item Dot after %s literal is deprecated concatenation
 
-(D) You had something like 0x123.456 in your code.  This is currently
+(D deprecated, syntax) You had something like 0x123.456 in your code.
+This is currently
 parsed as the hexadecimal number 0x123 concatenated with the decimal
-number 456, not 0x123 + 0x456/0x1000 -- we only support decimal
-decimal points.  If you meant it to be a fraction, you'll need to use
+number 456, not the fraction 0x123 + 0x456/0x1000 -- we only support decimal
+fractions.  If you meant it to be a fraction, you'll need to use
 Math::BigFloat's from_hex (or friends).  If you meant it to be
 concatenation, just put spaces around the dot to make it clearer.  In
 5.14.0, we expect to change this to mean a hex fraction.  (Of course,
diff --git a/t/comp/binary_num.t b/t/comp/binary_num.t
new file mode 100644 (file)
index 0000000..91fb001
--- /dev/null
@@ -0,0 +1,36 @@
+#!./perl
+
+print "1..30\n";
+my $test_num = 0;
+sub ok {
+       print $_[0] ? "" : "not ", "ok ", ++$test_num, "\n";
+}
+
+sub do_test {
+    my($src, $expect_value, $match_warning) = @_;
+    my($value, $warning);
+    local $SIG{__WARN__} = sub { $warning .= $_[0] };
+    $value = eval($src);
+    ok defined($expect_value) ? $value == $expect_value : !defined($value);
+    ok $warning =~ $match_warning;
+}
+
+do_test "0x123", 291, qr/\A\z/;
+do_test "0x123.8", 2918, qr/\ADot after hexadecimal literal is deprecated /;
+do_test "0x123 .8", 2918, qr/\A\z/;
+do_test "0x123. 8", 2918, qr/\ADot after hexadecimal literal is deprecated /;
+do_test "[0x123..8] && 5", 5, qr/\A\z/;
+
+do_test "0123", 83, qr/\A\z/;
+do_test "0123.4", 834, qr/\ADot after octal literal is deprecated /;
+do_test "0123 .4", 834, qr/\A\z/;
+do_test "0123. 4", 834, qr/\ADot after octal literal is deprecated /;
+do_test "[0123..4] && 5", 5, qr/\A\z/;
+
+do_test "0b101", 5, qr/\A\z/;
+do_test "0b101.1", 51, qr/\ADot after binary literal is deprecated /;
+do_test "0b101 .1", 51, qr/\A\z/;
+do_test "0b101. 1", 51, qr/\ADot after binary literal is deprecated /;
+do_test "[0b101..1] && 5", 5, qr/\A\z/;
+
+1;
index 81cf246..ae097de 100644 (file)
@@ -970,9 +970,9 @@ my $d = 0123 . 456;
 no warnings 'deprecated';
 my $e = 0765.432;
 EXPECT
-Dot after octal literal is concatenation at - line 3.
-Dot after hexadecimal literal is concatenation at - line 4.
-Dot after binary literal is concatenation at - line 5.
+Dot after octal literal is deprecated concatenation at - line 3.
+Dot after hexadecimal literal is deprecated concatenation at - line 4.
+Dot after binary literal is deprecated concatenation at - line 5.
 ########
 # toke.c
 use warnings;
index e3a5712..8aeaea1 100644 (file)
@@ -393,7 +393,7 @@ SKIP: {
 
 # Operations which affect directories can't use tainted data.
 {
-    test !eval { mkdir "foo".$TAINT, 0755.$TAINT0 }, 'mkdir';
+    test !eval { mkdir "foo".$TAINT, (0755).$TAINT0 }, 'mkdir';
     test $@ =~ /^Insecure dependency/, $@;
 
     test !eval { rmdir $TAINT }, 'rmdir';
diff --git a/toke.c b/toke.c
index 21b69cb..faa1664 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -13014,6 +13014,18 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
 
                switch (*s) {
 
+               case '.':
+                   /* Dot here is historically concat, not a radix point.
+                      Deprecate that; it's confusing, and gets in the way of
+                      hex(ish) fractions... but '..' is OK. */
+                   if (s[1] != '.') {
+                       Perl_ck_warner_d(aTHX_
+                           packWARN2(WARN_DEPRECATED, WARN_SYNTAX),
+                           "Dot after %s literal is deprecated concatenation",
+                           base);
+                   }
+                   /* FALL THROUGH */
+
                /* if we don't mention it, we're done */
                default:
                    goto out;
@@ -13096,15 +13108,6 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
                Perl_ck_warner(aTHX_ packWARN(WARN_SYNTAX), "Misplaced _ in number");
            }
 
-           /* Dot here is historically concat, not a radix point.
-              Deprecate that; it's confusing, and gets in the way of
-              hex(ish) fractions... but '..' is OK. */
-           if (s[0] == '.' &&
-               s[1] != '.') {
-               Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),
-                       "Dot after %s literal is concatenation", base);
-           }
-
            sv = newSV(0);
            if (overflowed) {
                if (n > 4294967295.0)