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