diff options
author | David Mitchell <davem@iabyn.com> | 2011-05-29 19:54:58 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2011-05-29 20:21:54 +0100 |
commit | 76912796531d6c0d25da0a8a285be9c7ba45b1bf (patch) | |
tree | 3c6a31dd34bd82e168f4b7dd6f8bbaa2b21ca377 | |
parent | 26e935cfa6e70de1bd5258e0cb0f22ee976909f3 (diff) | |
download | perl-76912796531d6c0d25da0a8a285be9c7ba45b1bf.tar.gz |
Allow formats with lines >64K
Back in 2003, the format bytecode was changed to allow 32-bit offsets,
but all the stored offsets were still being cast to U16. So for example
only the first char of a 65537 char literal would be output.
This commit removes all the U16 casts.
-rw-r--r-- | pp_ctl.c | 14 | ||||
-rw-r--r-- | t/op/write.t | 10 |
2 files changed, 16 insertions, 8 deletions
@@ -4986,14 +4986,14 @@ S_doparseform(pTHX_ SV *sv) if (postspace) *fpc++ = FF_SPACE; *fpc++ = FF_LITERAL; - *fpc++ = (U16)arg; + *fpc++ = (U32)arg; } postspace = FALSE; if (s <= send) skipspaces--; if (skipspaces) { *fpc++ = FF_SKIP; - *fpc++ = (U16)skipspaces; + *fpc++ = (U32)skipspaces; } skipspaces = 0; if (s <= send) @@ -5004,7 +5004,7 @@ S_doparseform(pTHX_ SV *sv) arg = fpc - linepc + 1; else arg = 0; - *fpc++ = (U16)arg; + *fpc++ = (U32)arg; } if (s < send) { linepc = fpc; @@ -5027,7 +5027,7 @@ S_doparseform(pTHX_ SV *sv) arg = (s - base) - 1; if (arg) { *fpc++ = FF_LITERAL; - *fpc++ = (U16)arg; + *fpc++ = (U32)arg; } base = s - 1; @@ -5054,7 +5054,7 @@ S_doparseform(pTHX_ SV *sv) } *fpc++ = s - base; /* fieldsize for FETCH */ *fpc++ = FF_DECIMAL; - *fpc++ = (U16)arg; + *fpc++ = (U32)arg; unchopnum |= ! ischop; } else if (*s == '0' && s[1] == '#') { /* Zero padded decimals */ @@ -5071,7 +5071,7 @@ S_doparseform(pTHX_ SV *sv) } *fpc++ = s - base; /* fieldsize for FETCH */ *fpc++ = FF_0DECIMAL; - *fpc++ = (U16)arg; + *fpc++ = (U32)arg; unchopnum |= ! ischop; } else { /* text field */ @@ -5101,7 +5101,7 @@ S_doparseform(pTHX_ SV *sv) *fpc++ = ischop ? FF_CHECKCHOP : FF_CHECKNL; if (prespace) - *fpc++ = (U16)prespace; /* add SPACE or HALFSPACE */ + *fpc++ = (U32)prespace; /* add SPACE or HALFSPACE */ *fpc++ = FF_ITEM; if (ismore) *fpc++ = FF_MORE; diff --git a/t/op/write.t b/t/op/write.t index c2e3399305..d30c9d77ef 100644 --- a/t/op/write.t +++ b/t/op/write.t @@ -61,7 +61,7 @@ for my $tref ( @NumTests ){ my $bas_tests = 20; # number of tests in section 3 -my $bug_tests = 4 + 3 * 3 * 5 * 2 * 3 + 2 + 66 + 3 + 2 + 1 + 1; +my $bug_tests = 4 + 3 * 3 * 5 * 2 * 3 + 2 + 66 + 4 + 2 + 1 + 1; # number of tests in section 4 my $hmb_tests = 35; @@ -712,6 +712,14 @@ ok defined *{$::{CmT}}{FORMAT}, "glob assign"; $orig = "x" x 100 . "\n"; formline $format, $orig, 12345; is $^A, ("x" x 100) . " 12345\n", "\@* doesn't overflow"; + + # make sure it can cope with formats > 64k + + $format = 'x' x 65537; + $^A = ''; + formline $format; + # don't use 'is' here, as the diag output will be too long! + ok $^A eq $format, ">64K"; } |