1*1f5207b7SJohn Levon#!/usr/bin/perl -w
2*1f5207b7SJohn Levon
3*1f5207b7SJohn Levonuse strict;
4*1f5207b7SJohn Levonuse warnings;
5*1f5207b7SJohn Levonuse bigint;
6*1f5207b7SJohn Levonuse DBI;
7*1f5207b7SJohn Levonuse Data::Dumper;
8*1f5207b7SJohn Levon
9*1f5207b7SJohn Levon
10*1f5207b7SJohn Levonmy $project = shift;
11*1f5207b7SJohn Levonmy $warns = shift;
12*1f5207b7SJohn Levonmy $db_file = shift;
13*1f5207b7SJohn Levonmy $db = DBI->connect("dbi:SQLite:$db_file", "", "", {AutoCommit => 0});
14*1f5207b7SJohn Levon
15*1f5207b7SJohn Levonsub text_to_int($)
16*1f5207b7SJohn Levon{
17*1f5207b7SJohn Levon    my $text = shift;
18*1f5207b7SJohn Levon
19*1f5207b7SJohn Levon    if ($text =~ /s64min/) {
20*1f5207b7SJohn Levon        return -(2**63);
21*1f5207b7SJohn Levon    } elsif ($text =~/s32min/) {
22*1f5207b7SJohn Levon        return -(2**31);
23*1f5207b7SJohn Levon    } elsif ($text =~ /s16min/) {
24*1f5207b7SJohn Levon        return -(2**15);
25*1f5207b7SJohn Levon    } elsif ($text =~ /s64max/) {
26*1f5207b7SJohn Levon        return 2**63 - 1;
27*1f5207b7SJohn Levon    } elsif ($text =~ /s32max/) {
28*1f5207b7SJohn Levon        return 2**31 - 1;
29*1f5207b7SJohn Levon    } elsif ($text =~ /s16max/) {
30*1f5207b7SJohn Levon        return 2**15 - 1;
31*1f5207b7SJohn Levon    } elsif ($text =~ /u64max/) {
32*1f5207b7SJohn Levon        return 2**64 - 1;
33*1f5207b7SJohn Levon    } elsif ($text =~ /u32max/) {
34*1f5207b7SJohn Levon        return 2**32 - 1;
35*1f5207b7SJohn Levon    } elsif ($text =~ /u16max/) {
36*1f5207b7SJohn Levon        return 2**16 - 1;
37*1f5207b7SJohn Levon    }
38*1f5207b7SJohn Levon    if ($text =~ /\((.*?)\)/) {
39*1f5207b7SJohn Levon        $text = $1;
40*1f5207b7SJohn Levon    }
41*1f5207b7SJohn Levon    if (!($text =~ /^[-0123456789]/)) {
42*1f5207b7SJohn Levon        return "NaN";
43*1f5207b7SJohn Levon    }
44*1f5207b7SJohn Levon
45*1f5207b7SJohn Levon    return int($text);
46*1f5207b7SJohn Levon}
47*1f5207b7SJohn Levon
48*1f5207b7SJohn Levonsub add_range($$$)
49*1f5207b7SJohn Levon{
50*1f5207b7SJohn Levon    my $union = shift;
51*1f5207b7SJohn Levon    my $min = shift;
52*1f5207b7SJohn Levon    my $max = shift;
53*1f5207b7SJohn Levon    my %range;
54*1f5207b7SJohn Levon    my @return_union;
55*1f5207b7SJohn Levon    my $added = 0;
56*1f5207b7SJohn Levon    my $check_next = 0;
57*1f5207b7SJohn Levon
58*1f5207b7SJohn Levon    $range{min} = $min;
59*1f5207b7SJohn Levon    $range{max} = $max;
60*1f5207b7SJohn Levon
61*1f5207b7SJohn Levon    foreach my $tmp (@$union) {
62*1f5207b7SJohn Levon        if ($added) {
63*1f5207b7SJohn Levon            push @return_union, $tmp;
64*1f5207b7SJohn Levon            next;
65*1f5207b7SJohn Levon        }
66*1f5207b7SJohn Levon
67*1f5207b7SJohn Levon        if ($range{max} < $tmp->{min}) {
68*1f5207b7SJohn Levon            push @return_union, \%range;
69*1f5207b7SJohn Levon            push @return_union, $tmp;
70*1f5207b7SJohn Levon            $added = 1;
71*1f5207b7SJohn Levon        } elsif ($range{min} <= $tmp->{min}) {
72*1f5207b7SJohn Levon            if ($range{max} <= $tmp->{max}) {
73*1f5207b7SJohn Levon                $range{max} = $tmp->{max};
74*1f5207b7SJohn Levon                push @return_union, \%range;
75*1f5207b7SJohn Levon                $added = 1;
76*1f5207b7SJohn Levon            }
77*1f5207b7SJohn Levon        } elsif ($range{min} <= $tmp->{max}) {
78*1f5207b7SJohn Levon            if ($range{max} <= $tmp->{max}) {
79*1f5207b7SJohn Levon                push @return_union, $tmp;
80*1f5207b7SJohn Levon                $added = 1;
81*1f5207b7SJohn Levon            } else {
82*1f5207b7SJohn Levon                $range{min} = $tmp->{min};
83*1f5207b7SJohn Levon            }
84*1f5207b7SJohn Levon        } else {
85*1f5207b7SJohn Levon            push @return_union, $tmp;
86*1f5207b7SJohn Levon        }
87*1f5207b7SJohn Levon    }
88*1f5207b7SJohn Levon
89*1f5207b7SJohn Levon    if (!$added) {
90*1f5207b7SJohn Levon        push @return_union, \%range;
91*1f5207b7SJohn Levon    }
92*1f5207b7SJohn Levon
93*1f5207b7SJohn Levon    return \@return_union;
94*1f5207b7SJohn Levon}
95*1f5207b7SJohn Levon
96*1f5207b7SJohn Levonsub print_num($)
97*1f5207b7SJohn Levon{
98*1f5207b7SJohn Levon    my $num = shift;
99*1f5207b7SJohn Levon
100*1f5207b7SJohn Levon    if ($num < 0) {
101*1f5207b7SJohn Levon        return "(" . $num . ")";
102*1f5207b7SJohn Levon    } else {
103*1f5207b7SJohn Levon        return $num;
104*1f5207b7SJohn Levon    }
105*1f5207b7SJohn Levon}
106*1f5207b7SJohn Levon
107*1f5207b7SJohn Levonsub print_range($)
108*1f5207b7SJohn Levon{
109*1f5207b7SJohn Levon    my $range = shift;
110*1f5207b7SJohn Levon
111*1f5207b7SJohn Levon    if ($range->{min} == $range->{max}) {
112*1f5207b7SJohn Levon        return print_num($range->{min});
113*1f5207b7SJohn Levon    } else {
114*1f5207b7SJohn Levon        return print_num($range->{min}) . "-" .  print_num($range->{max});
115*1f5207b7SJohn Levon    }
116*1f5207b7SJohn Levon}
117*1f5207b7SJohn Levon
118*1f5207b7SJohn Levonsub print_info($$)
119*1f5207b7SJohn Levon{
120*1f5207b7SJohn Levon    my $type = shift;
121*1f5207b7SJohn Levon    my $union = shift;
122*1f5207b7SJohn Levon    my $printed_range = "";
123*1f5207b7SJohn Levon    my $i = 0;
124*1f5207b7SJohn Levon
125*1f5207b7SJohn Levon    if ($#$union > 100) {
126*1f5207b7SJohn Levon        print "$type " . scalar @$union . "\n";
127*1f5207b7SJohn Levon        return;
128*1f5207b7SJohn Levon    }
129*1f5207b7SJohn Levon
130*1f5207b7SJohn Levon    foreach my $range (@$union) {
131*1f5207b7SJohn Levon        if ($i) {
132*1f5207b7SJohn Levon            $printed_range = $printed_range . ",";
133*1f5207b7SJohn Levon        }
134*1f5207b7SJohn Levon        $i++;
135*1f5207b7SJohn Levon        $printed_range = $printed_range . print_range($range);
136*1f5207b7SJohn Levon    }
137*1f5207b7SJohn Levon    my $sql = "insert into type_value values ('$type', '$printed_range');";
138*1f5207b7SJohn Levon    $db->do($sql);
139*1f5207b7SJohn Levon}
140*1f5207b7SJohn Levon
141*1f5207b7SJohn Levon
142*1f5207b7SJohn Levon$db->do("PRAGMA cache_size = 800000");
143*1f5207b7SJohn Levon$db->do("PRAGMA journal_mode = OFF");
144*1f5207b7SJohn Levon$db->do("PRAGMA count_changes = OFF");
145*1f5207b7SJohn Levon$db->do("PRAGMA temp_store = MEMORY");
146*1f5207b7SJohn Levon$db->do("PRAGMA locking = EXCLUSIVE");
147*1f5207b7SJohn Levon
148*1f5207b7SJohn Levonmy ($sth, @row, $cur_type, $type, @ranges, $range_txt, %range, $min, $max, $union_array, $skip);
149*1f5207b7SJohn Levon
150*1f5207b7SJohn Levon$sth = $db->prepare('select type, value from function_type_value order by type');
151*1f5207b7SJohn Levon$sth->execute();
152*1f5207b7SJohn Levon
153*1f5207b7SJohn Levon$skip = 0;
154*1f5207b7SJohn Levon$cur_type = "";
155*1f5207b7SJohn Levonwhile (@row = $sth->fetchrow_array()) {
156*1f5207b7SJohn Levon    $type = $row[0];
157*1f5207b7SJohn Levon
158*1f5207b7SJohn Levon    if ($cur_type ne "$type") {
159*1f5207b7SJohn Levon        if ($cur_type ne "" && $skip == 0) {
160*1f5207b7SJohn Levon            print_info($cur_type, $union_array);
161*1f5207b7SJohn Levon        }
162*1f5207b7SJohn Levon        $cur_type = $type;
163*1f5207b7SJohn Levon        $union_array = ();
164*1f5207b7SJohn Levon        $skip = 0;
165*1f5207b7SJohn Levon    }
166*1f5207b7SJohn Levon
167*1f5207b7SJohn Levon    if ($skip == 1) {
168*1f5207b7SJohn Levon        next;
169*1f5207b7SJohn Levon    }
170*1f5207b7SJohn Levon
171*1f5207b7SJohn Levon    @ranges = split(/,/, $row[1]);
172*1f5207b7SJohn Levon    foreach $range_txt (@ranges) {
173*1f5207b7SJohn Levon        if ($range_txt =~ /ignore/) {
174*1f5207b7SJohn Levon            next;
175*1f5207b7SJohn Levon        }
176*1f5207b7SJohn Levon        if ($range_txt =~ /(.*[^(])-(.*)/) {
177*1f5207b7SJohn Levon            $min = text_to_int($1);
178*1f5207b7SJohn Levon            $max = text_to_int($2);
179*1f5207b7SJohn Levon        } else {
180*1f5207b7SJohn Levon            $min = text_to_int($range_txt);
181*1f5207b7SJohn Levon            $max = $min;
182*1f5207b7SJohn Levon        }
183*1f5207b7SJohn Levon        if ($min =~ /NaN/ || $max =~ /NaN/) {
184*1f5207b7SJohn Levon            $skip = 1;
185*1f5207b7SJohn Levon            last;
186*1f5207b7SJohn Levon        }
187*1f5207b7SJohn Levon        $union_array = add_range($union_array, $min, $max);
188*1f5207b7SJohn Levon    }
189*1f5207b7SJohn Levon}
190*1f5207b7SJohn Levonif ($skip == 0) {
191*1f5207b7SJohn Levon    print_info($cur_type, $union_array);
192*1f5207b7SJohn Levon}
193*1f5207b7SJohn Levon
194*1f5207b7SJohn Levon$db->commit();
195*1f5207b7SJohn Levon$db->disconnect();
196