pp_pack.c, simplifying genpacksizetables

Message-Id: <d11kvt$1k7$1@post.home.lunix>

p4raw-id: //depot/perl@24038
This commit is contained in:
Ton Hospel 2005-03-13 15:07:41 +00:00 committed by H.Merijn Brand
parent 35a4481cfd
commit a7a3cfaaf4
2 changed files with 283 additions and 287 deletions

View File

@ -4,103 +4,85 @@
use strict;
use Encode;
sub make_text {
my ($chrmap, $letter, $unpredictable, $nocsum, $size, $condition) = @_;
my $text = " /* $letter */ $size";
$text .= " | PACK_SIZE_UNPREDICTABLE" if $unpredictable;
$text .= " | PACK_SIZE_CANNOT_CSUM" if $nocsum;
$text .= ",";
if ($condition) {
$condition = join " && ", map {"defined($_)"} split ' ', $condition;
$text = "#if $condition
$text
#else
0,
#endif";
}
return $text;
}
sub make_tables {
my %arrays;
my $chrmap = shift;
foreach (@_) {
my ($letter, $shriek, $unpredictable, $nocsum, $size, $condition) =
/^([A-Za-z])(!?)\t(\S*)\t(\S*)\t([^\t\n]+)(?:\t+(.*))?$/ or
die "Can't parse '$_'";
$size = "sizeof($size)" unless $size =~ s/^=//;
$arrays{$shriek ? 'shrieking' : 'normal'}{ord $chrmap->{$letter}} =
make_text($chrmap, $letter,
$unpredictable, $nocsum, $size, $condition);
}
my $text = "const packprops_t packprops[512] = {\n";
foreach my $arrayname (qw(normal shrieking)) {
my $array = $arrays{$arrayname} ||
die "No defined entries in $arrayname";
$text .= " /* $arrayname */\n";
for my $ch (0..255) {
$text .= $array->{$ch} || " 0,";
$text .= "\n";
}
}
# Join "0," entries together
1 while $text =~ s/\b0,\s*\n\s*0,/0, 0,/g;
# But split them up again if the sequence gets too long
$text =~ s/((?:\b0, ){15}0,) /$1\n /g;
# Clean up final ,
$text =~ s/,$//;
$text .= "};";
return $text;
}
my @lines = grep {
s/#.*//;
/\S/;
} <DATA>;
sub addline {
my ($arrays, $chrmap, $letter, $arrayname, $unpredictable, $nocsum, $size,
$condition) = @_;
my $line = "/* $letter */ $size";
$line .= " | PACK_SIZE_UNPREDICTABLE" if $unpredictable;
$line .= " | PACK_SIZE_CANNOT_CSUM" if $nocsum;
$line .= ",";
# And then the hack
$line = [$condition, $line] if $condition;
$arrays->{$arrayname}->[ord $chrmap->{$letter}] = $line;
# print ord $chrmap->{$letter}, " $line\n";
}
my %asciimap = map {chr $_, chr $_} 0..255;
my %ebcdicmap = map {chr $_, Encode::encode("posix-bc", chr $_)} 0..255;
sub output_tables {
my %arrays;
print <<"EOC";
/* These tables are regenerated by genpacksizetables.pl (and then hand pasted
in). You're unlikely ever to need to regenerate them. */
my $chrmap = shift;
foreach (@_) {
my ($letter, $shriek, $unpredictable, $nocsum, $size, $condition)
= /^([A-Za-z])(!?)\t(\S*)\t(\S*)\t([^\t\n]+)(?:\t+(.*))?$/;
die "Can't parse '$_'" unless $size;
#if TYPE_IS_SHRIEKING != 0x100
++++shriek offset should be 256
#endif
if (defined $condition) {
$condition = join " && ", map {"defined($_)"} split ' ', $condition;
}
unless ($size =~ s/^=//) {
$size = "sizeof($size)";
}
addline (\%arrays, $chrmap, $letter, $shriek ? 'shrieking' : 'normal',
$unpredictable, $nocsum, $size, $condition);
}
my %earliest;
foreach my $arrayname (sort keys %arrays) {
my $array = $arrays{$arrayname};
die "No defined entries in $arrayname" unless $array->[$#$array];
# Find the first used entry
my $earliest = 0;
$earliest++ while (!$array->[$earliest]);
# Remove all the empty elements.
splice @$array, 0, $earliest;
print "unsigned char size_${arrayname}[", scalar @$array, "] = {\n";
my @lines;
foreach (@$array) {
# Remove the assumption here that the last entry isn't conditonal
if (ref $_) {
push @lines,
["#if $_->[0]", " $_->[1]", "#else", " 0,", "#endif"];
} else {
push @lines, $_ ? " $_" : " 0,";
}
}
# remove the last, annoying, comma
my $last = $lines[$#lines];
my $got;
foreach (ref $last ? @$last : $last) {
$got += s/,$//;
}
die "Last entry had no commas" unless $got;
print map {"$_\n"} ref $_ ? @$_ : $_ foreach @lines;
print "};\n";
$earliest{$arrayname} = $earliest;
}
print "struct packsize_t packsize[2] = {\n";
my @lines;
foreach (qw(normal shrieking)) {
my $array = $arrays{$_};
push @lines, " {size_$_, $earliest{$_}, " . (scalar @$array) . "},";
}
# remove the last, annoying, comma
chop $lines[$#lines];
print "$_\n" foreach @lines;
print "};\n";
}
my %asciimap = (map {chr $_, chr $_} 0..255);
my %ebcdicmap = (map {chr $_, Encode::encode ("posix-bc", chr $_)} 0..255);
print <<'EOC';
typedef U8 packprops_t;
#if 'J'-'I' == 1
/* ASCII */
EOC
output_tables (\%asciimap, @lines);
print <<'EOC';
@{[make_tables (\%asciimap, @lines)]}
#else
/* EBCDIC (or bust) */
@{[make_tables (\%ebcdicmap, @lines)]}
#endif
EOC
output_tables (\%ebcdicmap, @lines);
print "#endif\n";
__DATA__
#Symbol unpredictable

420
pp_pack.c
View File

@ -314,213 +314,253 @@ S_mul128(pTHX_ SV *sv, U8 m)
#define PACK_SIZE_UNPREDICTABLE 0x40 /* Not a fixed size element */
#define PACK_SIZE_MASK 0x3F
struct packsize_t {
const unsigned char *array;
int first;
int size;
};
#define PACK_SIZE_NORMAL 0
#define PACK_SIZE_SHRIEKING 1
/* These tables are regenerated by genpacksizetables.pl (and then hand pasted
in). You're unlikely ever to need to regenerate them. */
#if TYPE_IS_SHRIEKING != 0x100
++++shriek offset should be 256
#endif
typedef U8 packprops_t;
#if 'J'-'I' == 1
/* ASCII */
unsigned char size_normal[53] = {
/* C */ sizeof(unsigned char),
const packprops_t packprops[512] = {
/* normal */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0,
/* C */ sizeof(unsigned char) | PACK_SIZE_UNPREDICTABLE,
#if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
/* D */ LONG_DOUBLESIZE,
/* D */ LONG_DOUBLESIZE,
#else
0,
0,
#endif
0,
/* F */ NVSIZE,
0, 0,
/* I */ sizeof(unsigned int),
/* J */ UVSIZE,
0,
/* L */ SIZE32,
0,
/* N */ SIZE32,
0, 0,
0,
/* F */ NVSIZE,
0, 0,
/* I */ sizeof(unsigned int),
/* J */ UVSIZE,
0,
/* L */ SIZE32,
0,
/* N */ SIZE32,
0, 0,
#if defined(HAS_QUAD)
/* Q */ sizeof(Uquad_t),
/* Q */ sizeof(Uquad_t),
#else
0,
0,
#endif
0,
/* S */ SIZE16,
0,
/* U */ sizeof(char) | PACK_SIZE_UNPREDICTABLE,
/* V */ SIZE32,
/* W */ sizeof(unsigned char) | PACK_SIZE_UNPREDICTABLE,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* c */ sizeof(char),
/* d */ sizeof(double),
0,
/* f */ sizeof(float),
0, 0,
/* i */ sizeof(int),
/* j */ IVSIZE,
0,
/* l */ SIZE32,
0,
/* n */ SIZE16,
0,
/* p */ sizeof(char *) | PACK_SIZE_CANNOT_CSUM,
0,
/* S */ SIZE16,
0,
/* U */ sizeof(char) | PACK_SIZE_UNPREDICTABLE,
/* V */ SIZE32,
/* W */ sizeof(unsigned char) | PACK_SIZE_UNPREDICTABLE,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* c */ sizeof(char),
/* d */ sizeof(double),
0,
/* f */ sizeof(float),
0, 0,
/* i */ sizeof(int),
/* j */ IVSIZE,
0,
/* l */ SIZE32,
0,
/* n */ SIZE16,
0,
/* p */ sizeof(char *) | PACK_SIZE_CANNOT_CSUM,
#if defined(HAS_QUAD)
/* q */ sizeof(Quad_t),
/* q */ sizeof(Quad_t),
#else
0,
0,
#endif
0,
/* s */ SIZE16,
0, 0,
/* v */ SIZE16,
/* w */ sizeof(char) | PACK_SIZE_UNPREDICTABLE | PACK_SIZE_CANNOT_CSUM,
};
unsigned char size_shrieking[46] = {
/* I */ sizeof(unsigned int),
0, 0,
/* L */ sizeof(unsigned long),
0,
0,
/* s */ SIZE16,
0, 0,
/* v */ SIZE16,
/* w */ sizeof(char) | PACK_SIZE_UNPREDICTABLE | PACK_SIZE_CANNOT_CSUM,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
/* shrieking */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
/* I */ sizeof(unsigned int),
0, 0,
/* L */ sizeof(unsigned long),
0,
#if defined(PERL_PACK_CAN_SHRIEKSIGN)
/* N */ SIZE32,
/* N */ SIZE32,
#else
0,
0,
#endif
0, 0, 0, 0,
/* S */ sizeof(unsigned short),
0, 0,
0, 0, 0, 0,
/* S */ sizeof(unsigned short),
0, 0,
#if defined(PERL_PACK_CAN_SHRIEKSIGN)
/* V */ SIZE32,
/* V */ SIZE32,
#else
0,
0,
#endif
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* i */ sizeof(int),
0, 0,
/* l */ sizeof(long),
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
/* i */ sizeof(int),
0, 0,
/* l */ sizeof(long),
0,
#if defined(PERL_PACK_CAN_SHRIEKSIGN)
/* n */ SIZE16,
/* n */ SIZE16,
#else
0,
0,
#endif
0, 0, 0, 0,
/* s */ sizeof(short),
0, 0,
0, 0, 0, 0,
/* s */ sizeof(short),
0, 0,
#if defined(PERL_PACK_CAN_SHRIEKSIGN)
/* v */ SIZE16
/* v */ SIZE16,
#else
0
0,
#endif
};
struct packsize_t packsize[2] = {
{size_normal, 67, 53},
{size_shrieking, 73, 46}
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0
};
#else
/* EBCDIC (or bust) */
unsigned char size_normal[100] = {
/* c */ sizeof(char),
/* d */ sizeof(double),
0,
/* f */ sizeof(float),
0, 0,
/* i */ sizeof(int),
0, 0, 0, 0, 0, 0, 0,
/* j */ IVSIZE,
0,
/* l */ SIZE32,
0,
/* n */ SIZE16,
0,
/* p */ sizeof(char *) | PACK_SIZE_CANNOT_CSUM,
const packprops_t packprops[512] = {
/* normal */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0,
/* c */ sizeof(char),
/* d */ sizeof(double),
0,
/* f */ sizeof(float),
0, 0,
/* i */ sizeof(int),
0, 0, 0, 0, 0, 0, 0,
/* j */ IVSIZE,
0,
/* l */ SIZE32,
0,
/* n */ SIZE16,
0,
/* p */ sizeof(char *) | PACK_SIZE_CANNOT_CSUM,
#if defined(HAS_QUAD)
/* q */ sizeof(Quad_t),
/* q */ sizeof(Quad_t),
#else
0,
0,
#endif
0, 0, 0, 0, 0, 0, 0, 0, 0,
/* s */ SIZE16,
0, 0,
/* v */ SIZE16,
/* w */ sizeof(char) | PACK_SIZE_UNPREDICTABLE | PACK_SIZE_CANNOT_CSUM,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
/* C */ sizeof(unsigned char),
0, 0, 0, 0, 0, 0, 0, 0, 0,
/* s */ SIZE16,
0, 0,
/* v */ SIZE16,
/* w */ sizeof(char) | PACK_SIZE_UNPREDICTABLE | PACK_SIZE_CANNOT_CSUM,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* C */ sizeof(unsigned char) | PACK_SIZE_UNPREDICTABLE,
#if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
/* D */ LONG_DOUBLESIZE,
/* D */ LONG_DOUBLESIZE,
#else
0,
0,
#endif
0,
/* F */ NVSIZE,
0, 0,
/* I */ sizeof(unsigned int),
0, 0, 0, 0, 0, 0, 0,
/* J */ UVSIZE,
0,
/* L */ SIZE32,
0,
/* N */ SIZE32,
0, 0,
0,
/* F */ NVSIZE,
0, 0,
/* I */ sizeof(unsigned int),
0, 0, 0, 0, 0, 0, 0,
/* J */ UVSIZE,
0,
/* L */ SIZE32,
0,
/* N */ SIZE32,
0, 0,
#if defined(HAS_QUAD)
/* Q */ sizeof(Uquad_t),
/* Q */ sizeof(Uquad_t),
#else
0,
0,
#endif
0, 0, 0, 0, 0, 0, 0, 0, 0,
/* S */ SIZE16,
0,
/* U */ sizeof(char) | PACK_SIZE_UNPREDICTABLE,
/* V */ SIZE32,
/* W */ sizeof(unsigned char) | PACK_SIZE_UNPREDICTABLE,
};
unsigned char size_shrieking[93] = {
/* i */ sizeof(int),
0, 0, 0, 0, 0, 0, 0, 0, 0,
/* l */ sizeof(long),
0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
/* S */ SIZE16,
0,
/* U */ sizeof(char) | PACK_SIZE_UNPREDICTABLE,
/* V */ SIZE32,
/* W */ sizeof(unsigned char) | PACK_SIZE_UNPREDICTABLE,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
/* shrieking */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
/* i */ sizeof(int),
0, 0, 0, 0, 0, 0, 0, 0, 0,
/* l */ sizeof(long),
0,
#if defined(PERL_PACK_CAN_SHRIEKSIGN)
/* n */ SIZE16,
/* n */ SIZE16,
#else
0,
0,
#endif
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* s */ sizeof(short),
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* s */ sizeof(short),
0, 0,
#if defined(PERL_PACK_CAN_SHRIEKSIGN)
/* v */ SIZE16,
/* v */ SIZE16,
#else
0,
0,
#endif
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
/* I */ sizeof(unsigned int),
0, 0, 0, 0, 0, 0, 0, 0, 0,
/* L */ sizeof(unsigned long),
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0,
/* I */ sizeof(unsigned int),
0, 0, 0, 0, 0, 0, 0, 0, 0,
/* L */ sizeof(unsigned long),
0,
#if defined(PERL_PACK_CAN_SHRIEKSIGN)
/* N */ SIZE32,
/* N */ SIZE32,
#else
0,
0,
#endif
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* S */ sizeof(unsigned short),
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* S */ sizeof(unsigned short),
0, 0,
#if defined(PERL_PACK_CAN_SHRIEKSIGN)
/* V */ SIZE32
/* V */ SIZE32,
#else
0
0,
#endif
};
struct packsize_t packsize[2] = {
{size_normal, 131, 100},
{size_shrieking, 137, 93}
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
#endif
@ -701,9 +741,6 @@ S_measure_struct(pTHX_ tempsym_t* symptr)
while (next_symbol(symptr)) {
I32 len;
int star, size;
int which = (symptr->code & TYPE_IS_SHRIEKING) ?
PACK_SIZE_SHRIEKING : PACK_SIZE_NORMAL;
int offset = TYPE_NO_MODIFIERS(symptr->code) - packsize[which].first;
switch (symptr->howlen) {
case e_star:
@ -716,11 +753,7 @@ S_measure_struct(pTHX_ tempsym_t* symptr)
break;
}
if ((offset >= 0) && (offset < packsize[which].size))
size = packsize[which].array[offset] & PACK_SIZE_MASK;
else
size = 0;
size = packprops[TYPE_NO_ENDIANNESS(symptr->code)] & PACK_SIZE_MASK;
if (!size) {
/* endianness doesn't influence the size of a type */
switch(TYPE_NO_ENDIANNESS(symptr->code)) {
@ -1151,6 +1184,7 @@ S_unpack_rec(pTHX_ tempsym_t* symptr, char *s, char *strbeg, char *strend, char
bool utf8 = (symptr->flags & FLAG_PARSE_UTF8) ? 1 : 0;
while (next_symbol(symptr)) {
packprops_t props;
I32 len, ai32;
I32 datumtype = symptr->code;
/* do first one only unless in list context
@ -1174,32 +1208,22 @@ S_unpack_rec(pTHX_ tempsym_t* symptr, char *s, char *strbeg, char *strend, char
explicit_length = TRUE;
redo_switch:
beyond = s >= strend;
{
struct packsize_t *pack_props =
&packsize[(symptr->code & TYPE_IS_SHRIEKING) ?
PACK_SIZE_SHRIEKING : PACK_SIZE_NORMAL];
const int rawtype = TYPE_NO_MODIFIERS(datumtype);
int offset = rawtype - pack_props->first;
if (offset >= 0 && offset < pack_props->size) {
/* Data about this template letter */
unsigned char data = pack_props->array[offset];
props = packprops[TYPE_NO_ENDIANNESS(datumtype)];
if (props) {
/* props nonzero means we can process this letter. */
long size = props & PACK_SIZE_MASK;
long howmany = (strend - s) / size;
if (len > howmany)
len = howmany;
if (data) {
/* data nonzero means we can process this letter. */
long size = data & PACK_SIZE_MASK;
long howmany = (strend - s) / size;
if (len > howmany)
len = howmany;
if (!checksum || (data & PACK_SIZE_CANNOT_CSUM)) {
if (len && unpack_only_one) len = 1;
EXTEND(SP, len);
EXTEND_MORTAL(len);
}
}
if (!checksum || (props & PACK_SIZE_CANNOT_CSUM)) {
if (len && unpack_only_one) len = 1;
EXTEND(SP, len);
EXTEND_MORTAL(len);
}
}
switch(TYPE_NO_ENDIANNESS(datumtype)) {
default:
Perl_croak(aTHX_ "Invalid type '%c' in unpack", (int)TYPE_NO_MODIFIERS(datumtype) );
@ -2435,23 +2459,13 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist )
}
if (len) {
struct packsize_t *pack_props =
&packsize[(symptr->code & TYPE_IS_SHRIEKING) ?
PACK_SIZE_SHRIEKING : PACK_SIZE_NORMAL];
const int rawtype = TYPE_NO_MODIFIERS(datumtype);
int offset = rawtype - pack_props->first;
packprops_t props = packprops[TYPE_NO_ENDIANNESS(datumtype)];
if (offset >= 0 && offset < pack_props->size) {
/* Data about this template letter */
unsigned char data = pack_props->array[offset];
if (data && !(data & PACK_SIZE_UNPREDICTABLE)) {
/* We can process this letter. */
STRLEN size = data & PACK_SIZE_MASK;
GROWING(utf8, cat, start, cur, (STRLEN) len * size);
}
if (props && !(props & PACK_SIZE_UNPREDICTABLE)) {
/* We can process this letter. */
STRLEN size = props & PACK_SIZE_MASK;
GROWING(utf8, cat, start, cur, (STRLEN) len * size);
}
}
/* Look ahead for next symbol. Do we have code/code? */