This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Make the length overrun checking and stack extension table driven.
[perl5.git] / genpacksizetables.pl
CommitLineData
78d46eaa
NC
1#!/usr/bin/perl -w
2# I'm assuming that you're running this on some kind of ASCII system, but
3# it will generate EDCDIC too. (TODO)
4use strict;
5use Encode;
6
7my @lines = grep {!/^#/} <DATA>;
8
9sub addline {
10 my ($arrays, $chrmap, $letter, $arrayname, $noone, $nocsum, $size) = @_;
11 my $line = "/* $letter */ $size";
12 $line .= " | PACK_SIZE_CANNOT_ONLY_ONE" if $noone;
13 $line .= " | PACK_SIZE_CANNOT_CSUM" if $nocsum;
14 $line .= ",";
15 $arrays->{$arrayname}->[ord $chrmap->{$letter}] = $line;
16 # print ord $chrmap->{$letter}, " $line\n";
17}
18
19sub output_tables {
20 my %arrays;
21
22 my $chrmap = shift;
23 foreach (@_) {
24 my ($letter, $shriek, $noone, $nocsum, $size)
25 = /^([A-Za-z])(!?)\t(\S*)\t(\S*)\t(.*)/;
26 die "Can't parse '$_'" unless $size;
27
28 unless ($size =~ s/^=//) {
29 $size = "sizeof($size)";
30 }
31
32 addline (\%arrays, $chrmap, $letter, $shriek ? 'shrieking' : 'normal',
33 $noone, $nocsum, $size);
34 }
35
36 my %earliest;
37 foreach my $arrayname (sort keys %arrays) {
38 my $array = $arrays{$arrayname};
39 die "No defined entries in $arrayname" unless $array->[$#$array];
40 # Find the first used entry
41 my $earliest = 0;
42 $earliest++ while (!$array->[$earliest]);
43 # Remove all the empty elements.
44 splice @$array, 0, $earliest;
45 print "unsigned char size_${arrayname}[", scalar @$array, "] = {\n";
46 my @lines = map {$_ || "0,"} @$array;
47 # remove the last, annoying, comma
48 chop $lines[$#lines];
49 print " $_\n" foreach @lines;
50 print "};\n";
51 $earliest{$arrayname} = $earliest;
52 }
53
54 print "struct packsize_t packsize[2] = {\n";
55
56 my @lines;
57 foreach (qw(normal shrieking)) {
58 my $array = $arrays{$_};
59 push @lines, " {size_$_, $earliest{$_}, " . (scalar @$array) . "},";
60 }
61 # remove the last, annoying, comma
62 chop $lines[$#lines];
63 print "$_\n" foreach @lines;
64 print "};\n";
65}
66
67my %asciimap = (map {chr $_, chr $_} 0..255);
68my %ebcdicmap = (map {chr $_, Encode::encode ("posix-bc", chr $_)} 0..255);
69
70print <<'EOC';
71#if 'J'-'I' == 1
72/* ASCII */
73EOC
74output_tables (\%asciimap, @lines);
75print <<'EOC';
76#else
77/* EBCDIC (or bust) */
78EOC
79output_tables (\%ebcdicmap, @lines);
80print "#endif\n";
81
82__DATA__
83#Symbol nooone nocsum size
84c char
85C unsigned char
86U char
87s! short
88s =SIZE16
89S! unsigned short
90v =SIZE16
91n =SIZE16
92S =SIZE16
93v! =SIZE16
94n! =SIZE16
95i int
96i! int
97I unsigned int
98I! unsigned int
99j =IVSIZE
100J =UVSIZE
101l! long
102l =SIZE32
103L! unsigned long
104V =SIZE32
105N =SIZE32
106V! =SIZE32
107N! =SIZE32
108L =SIZE32
109p * * char *
110w * char
111q Quad_t
112Q Uquad_t
113f float
114d double
115F =NVSIZE
116D =LONG_DOUBLESIZE