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