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();