ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/staticperl/perl/genpacksizetables.pl
Revision: 1.1
Committed: Thu Jun 30 14:26:41 2005 UTC (19 years ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: PERL-5-8-7, HEAD
Branch point for: PERL
Log Message:
*** empty log message ***

File Contents

# Content
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)
4 use strict;
5 use Encode;
6
7 my @lines = grep {!/^#/} <DATA>;
8
9 sub addline {
10 my ($arrays, $chrmap, $letter, $arrayname, $spare, $nocsum, $size,
11 $condition) = @_;
12 my $line = "/* $letter */ $size";
13 $line .= " | PACK_SIZE_SPARE" if $spare;
14 $line .= " | PACK_SIZE_CANNOT_CSUM" if $nocsum;
15 $line .= ",";
16 # And then the hack
17 $line = [$condition, $line] if $condition;
18 $arrays->{$arrayname}->[ord $chrmap->{$letter}] = $line;
19 # print ord $chrmap->{$letter}, " $line\n";
20 }
21
22 sub output_tables {
23 my %arrays;
24
25 my $chrmap = shift;
26 foreach (@_) {
27 my ($letter, $shriek, $spare, $nocsum, $size, $condition)
28 = /^([A-Za-z])(!?)\t(\S*)\t(\S*)\t([^\t\n]+)(?:\t+(.*))?$/;
29 die "Can't parse '$_'" unless $size;
30
31 if (defined $condition) {
32 $condition = join " && ", map {"defined($_)"} split ' ', $condition;
33 }
34 unless ($size =~ s/^=//) {
35 $size = "sizeof($size)";
36 }
37
38 addline (\%arrays, $chrmap, $letter, $shriek ? 'shrieking' : 'normal',
39 $spare, $nocsum, $size, $condition);
40 }
41
42 my %earliest;
43 foreach my $arrayname (sort keys %arrays) {
44 my $array = $arrays{$arrayname};
45 die "No defined entries in $arrayname" unless $array->[$#$array];
46 # Find the first used entry
47 my $earliest = 0;
48 $earliest++ while (!$array->[$earliest]);
49 # Remove all the empty elements.
50 splice @$array, 0, $earliest;
51 print "unsigned char size_${arrayname}[", scalar @$array, "] = {\n";
52 my @lines;
53 foreach (@$array) {
54 # Remove the assumption here that the last entry isn't conditonal
55 if (ref $_) {
56 push @lines,
57 ["#if $_->[0]", " $_->[1]", "#else", " 0,", "#endif"];
58 } else {
59 push @lines, $_ ? " $_" : " 0,";
60 }
61 }
62 # remove the last, annoying, comma
63 my $last = $lines[$#lines];
64 my $got;
65 foreach (ref $last ? @$last : $last) {
66 $got += s/,$//;
67 }
68 die "Last entry had no commas" unless $got;
69 print map {"$_\n"} ref $_ ? @$_ : $_ foreach @lines;
70 print "};\n";
71 $earliest{$arrayname} = $earliest;
72 }
73
74 print "struct packsize_t packsize[2] = {\n";
75
76 my @lines;
77 foreach (qw(normal shrieking)) {
78 my $array = $arrays{$_};
79 push @lines, " {size_$_, $earliest{$_}, " . (scalar @$array) . "},";
80 }
81 # remove the last, annoying, comma
82 chop $lines[$#lines];
83 print "$_\n" foreach @lines;
84 print "};\n";
85 }
86
87 my %asciimap = (map {chr $_, chr $_} 0..255);
88 my %ebcdicmap = (map {chr $_, Encode::encode ("posix-bc", chr $_)} 0..255);
89
90 print <<'EOC';
91 #if 'J'-'I' == 1
92 /* ASCII */
93 EOC
94 output_tables (\%asciimap, @lines);
95 print <<'EOC';
96 #else
97 /* EBCDIC (or bust) */
98 EOC
99 output_tables (\%ebcdicmap, @lines);
100 print "#endif\n";
101
102 __DATA__
103 #Symbol spare nocsum size
104 c char
105 C unsigned char
106 U char
107 s! short
108 s =SIZE16
109 S! unsigned short
110 v =SIZE16
111 n =SIZE16
112 S =SIZE16
113 v! =SIZE16 PERL_PACK_CAN_SHRIEKSIGN
114 n! =SIZE16 PERL_PACK_CAN_SHRIEKSIGN
115 i int
116 i! int
117 I unsigned int
118 I! unsigned int
119 j =IVSIZE
120 J =UVSIZE
121 l! long
122 l =SIZE32
123 L! unsigned long
124 V =SIZE32
125 N =SIZE32
126 V! =SIZE32 PERL_PACK_CAN_SHRIEKSIGN
127 N! =SIZE32 PERL_PACK_CAN_SHRIEKSIGN
128 L =SIZE32
129 p * char *
130 w * char
131 q Quad_t HAS_QUAD
132 Q Uquad_t HAS_QUAD
133 f float
134 d double
135 F =NVSIZE
136 D =LONG_DOUBLESIZE HAS_LONG_DOUBLE USE_LONG_DOUBLE