1#!/usr/bin/perl -w 2 3use strict; 4use warnings; 5use bigint; 6use DBI; 7use Data::Dumper; 8 9my $project = shift; 10my $warns = shift; 11my $db_file = shift; 12my $db = DBI->connect("dbi:SQLite:$db_file", "", "", {AutoCommit => 0}); 13 14my $raw_line; 15 16sub 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 49sub 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 97sub print_num($) 98{ 99 my $num = shift; 100 101 if ($num < 0) { 102 return "(" . $num . ")"; 103 } else { 104 return $num; 105 } 106} 107 108sub 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 119sub 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 144my ($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 = ""; 151while (@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} 180if ($skip == 0) { 181 print_info($cur_type, $union_array); 182} 183 184$db->commit(); 185$db->disconnect(); 186