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