my @lines = grep {!/^#/} <DATA>;
sub addline {
- my ($arrays, $chrmap, $letter, $arrayname, $noone, $nocsum, $size,
+ my ($arrays, $chrmap, $letter, $arrayname, $spare, $nocsum, $size,
$condition) = @_;
my $line = "/* $letter */ $size";
- $line .= " | PACK_SIZE_CANNOT_ONLY_ONE" if $noone;
+ $line .= " | PACK_SIZE_SPARE" if $spare;
$line .= " | PACK_SIZE_CANNOT_CSUM" if $nocsum;
$line .= ",";
# And then the hack
my $chrmap = shift;
foreach (@_) {
- my ($letter, $shriek, $noone, $nocsum, $size, $condition)
+ my ($letter, $shriek, $spare, $nocsum, $size, $condition)
= /^([A-Za-z])(!?)\t(\S*)\t(\S*)\t([^\t\n]+)(?:\t+(.*))?$/;
die "Can't parse '$_'" unless $size;
}
addline (\%arrays, $chrmap, $letter, $shriek ? 'shrieking' : 'normal',
- $noone, $nocsum, $size, $condition);
+ $spare, $nocsum, $size, $condition);
}
my %earliest;
print "#endif\n";
__DATA__
-#Symbol nooone nocsum size
+#Symbol spare nocsum size
c char
C unsigned char
U char
V! =SIZE32 PERL_PACK_CAN_SHRIEKSIGN
N! =SIZE32 PERL_PACK_CAN_SHRIEKSIGN
L =SIZE32
-p * * char *
+p * char *
w * char
q Quad_t HAS_QUAD
Q Uquad_t HAS_QUAD
#endif
#define PACK_SIZE_CANNOT_CSUM 0x80
-#define PACK_SIZE_CANNOT_ONLY_ONE 0x40
+#define PACK_SIZE_SPARE 0x40
#define PACK_SIZE_MASK 0x3F
0,
/* n */ SIZE16,
0,
- /* p */ sizeof(char *) | PACK_SIZE_CANNOT_ONLY_ONE | PACK_SIZE_CANNOT_CSUM,
+ /* p */ sizeof(char *) | PACK_SIZE_CANNOT_CSUM,
#if defined(HAS_QUAD)
/* q */ sizeof(Quad_t),
#else
0,
/* n */ SIZE16,
0,
- /* p */ sizeof(char *) | PACK_SIZE_CANNOT_ONLY_ONE | PACK_SIZE_CANNOT_CSUM,
+ /* p */ sizeof(char *) | PACK_SIZE_CANNOT_CSUM,
#if defined(HAS_QUAD)
/* q */ sizeof(Quad_t),
#else
{
int which = (symptr->code & TYPE_IS_SHRIEKING)
? PACK_SIZE_SHRIEKING : PACK_SIZE_NORMAL;
- int offset = TYPE_NO_MODIFIERS(datumtype) - packsize[which].first;
+ const int rawtype = TYPE_NO_MODIFIERS(datumtype);
+ int offset = rawtype - packsize[which].first;
if (offset >= 0 && offset < packsize[which].size) {
/* Data about this template letter */
if (len > howmany)
len = howmany;
+ /* In the old code, 'p' was the only type without shortcut
+ code to curtail unpacking to only one. As far as I can
+ see the only point of retaining this anomaly is to make
+ code such as $_ = unpack "p2", pack "pI", "Hi", 2
+ continue to segfault. ie, it probably should be
+ construed as a bug.
+ */
+
if (!checksum || (data & PACK_SIZE_CANNOT_CSUM)) {
if (len && unpack_only_one &&
- !(data & PACK_SIZE_CANNOT_ONLY_ONE))
+ rawtype != 'p')
len = 1;
EXTEND(SP, len);
EXTEND_MORTAL(len);