rjw | 6c1fd8f | 2022-11-30 14:33:01 +0800 | [diff] [blame] | 1 | use strict; |
| 2 | use warnings; |
| 3 | use XML::Parser; |
| 4 | use XML::Simple; |
| 5 | |
| 6 | package CSIF_Structure_Check; |
| 7 | use File::Find; |
| 8 | return 1; |
| 9 | |
| 10 | # File list |
| 11 | my @all_list = (); |
| 12 | my $max_depth = 0; |
| 13 | # XML parsing result |
| 14 | my @data_tree = (); |
| 15 | ################################################################################## |
| 16 | # Subroutine: xml_parser() |
| 17 | # |
| 18 | # |
| 19 | ################################################################################## |
| 20 | sub xml_parser { |
| 21 | my ($user, $xml_file) = @_; |
| 22 | my @ret_list = (); |
| 23 | my $simple = XML::Simple->new(); |
| 24 | my $data_tree = $simple->XMLin($xml_file); |
| 25 | my $row_idx = 0; |
| 26 | while ($data_tree->{'path'}->[$row_idx]) { |
| 27 | if (ref($data_tree->{'path'}->[$row_idx]) eq "HASH") { |
| 28 | if ($user =~ $data_tree->{'path'}->[$row_idx]->{'group'}) { |
| 29 | push @ret_list, $data_tree->{'path'}->[$row_idx]->{'r_path'}; # if ($data_tree->{'path'}->[$row_idx]->{'r_path'} =~ /\.h$/); |
| 30 | } |
| 31 | } |
| 32 | $row_idx++; |
| 33 | } |
| 34 | |
| 35 | return @ret_list; |
| 36 | } |
| 37 | |
| 38 | ################################################################################## |
| 39 | # Subroutine: xml_format_checker() |
| 40 | # |
| 41 | # |
| 42 | ################################################################################## |
| 43 | sub xml_format_checker { |
| 44 | my ($xml_file) = @_; |
| 45 | my $parser = XML::Parser->new(ErrorContext => 2); |
| 46 | eval {$parser->parsefile($xml_file);}; |
| 47 | |
| 48 | if ($@) { |
| 49 | $@ =~ s/at \/.*?S//s; # Remove module line number |
| 50 | #print STDERR . "\nERROR in " . $xml_file . ":\n$@\n"; |
| 51 | return 0; |
| 52 | } else { |
| 53 | #print STDERR . " " . $xml_file . " is well-formed:\n"; |
| 54 | return 1; |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | ################################################################################## |
| 59 | # Subroutine: crc32() |
| 60 | # - ARGUMENT: $input, $init_value, $polynomial |
| 61 | # - RETURN: $crc |
| 62 | ################################################################################## |
| 63 | sub crc32 { |
| 64 | my ($input, $init_value, $polynomial) = @_; |
| 65 | $init_value = 0 unless (defined $init_value); |
| 66 | $polynomial = 0xedb88320 unless (defined $polynomial); |
| 67 | |
| 68 | my @lookup_table; |
| 69 | |
| 70 | for (my $i = 0; $i < 256; $i++) { |
| 71 | my $x = $i; |
| 72 | for (my $j = 0; $j < 8; $j++) { |
| 73 | if ($x & 1) { |
| 74 | $x = ($x >> 1) ^ $polynomial; |
| 75 | } else { |
| 76 | $x = $x >> 1; |
| 77 | } |
| 78 | } |
| 79 | push @lookup_table, $x; |
| 80 | } |
| 81 | |
| 82 | my $crc = $init_value ^ 0xffffffff; |
| 83 | |
| 84 | foreach my $x (unpack ('C*', $input)) { |
| 85 | $crc = (($crc >> 8) & 0xffffff) ^ $lookup_table[ ($crc ^ $x) & 0xff ]; |
| 86 | } |
| 87 | |
| 88 | $crc = $crc ^ 0xffffffff; |
| 89 | |
| 90 | return $crc; |
| 91 | } |
| 92 | |
| 93 | |
| 94 | ################################################################################## |
| 95 | # Subroutine: file_checksum_input() |
| 96 | # - ARGUMENT: $filename (e.g., ../common/interface/modem/mt6297/CSIF/xxx.h) |
| 97 | # - RETURN: $str |
| 98 | ################################################################################## |
| 99 | sub file_checksum_input { |
| 100 | my ($filename) = @_; |
| 101 | open(FILE, $filename) or die "Could not open $filename, $!"; |
| 102 | my $str = ""; |
| 103 | my @keyword = <FILE>; |
| 104 | close(FILE); |
| 105 | $str = join("", @keyword); |
| 106 | |
| 107 | return $str; |
| 108 | } |
| 109 | |
| 110 | ################################################################################## |
| 111 | # Subroutine: folder_checksum_input() |
| 112 | # - ARGUMENT: $folder_name (e.g., ../common/interface/modem/mt6297/CSIF/) |
| 113 | # - RETURN: $total_str |
| 114 | ################################################################################## |
| 115 | sub folder_checksum_input { |
| 116 | my ($folder_name) = @_; |
| 117 | find({ |
| 118 | wanted => \&wanted |
| 119 | }, $folder_name); |
| 120 | my $str = ""; |
| 121 | my $total_str = ""; |
| 122 | foreach (sort{crc32($a)<=>crc32($b)}@all_list) |
| 123 | { |
| 124 | open(FILE, $_); |
| 125 | my @keyword = <FILE>; |
| 126 | close(FILE); |
| 127 | $str = join("", @keyword); |
| 128 | $total_str = join($total_str, "", $str); |
| 129 | } |
| 130 | @all_list = (); |
| 131 | |
| 132 | return $total_str; |
| 133 | } |
| 134 | |
| 135 | ################################################################################## |
| 136 | # Subroutine: merge_checksum_input() |
| 137 | # - ARGUMENT: @path_list |
| 138 | # - RETURN: $checksum_input |
| 139 | ################################################################################## |
| 140 | sub merge_checksum_input{ |
| 141 | my (@path_list) = @_; |
| 142 | my $checksum_input = ""; |
| 143 | my $checksum_str = ""; |
| 144 | foreach (@path_list) |
| 145 | { |
| 146 | print $_ . "\n"; |
| 147 | if($_ =~ /\.h$/) { |
| 148 | # Read out file contents |
| 149 | $checksum_str = file_checksum_input($_); |
| 150 | # Merge file contents |
| 151 | $checksum_input = join($checksum_input, "", $checksum_str); |
| 152 | } else { |
| 153 | $checksum_str = folder_checksum_input($_); |
| 154 | $checksum_input = join($checksum_input, "", $checksum_str); |
| 155 | } |
| 156 | } |
| 157 | |
| 158 | return $checksum_input; |
| 159 | } |
| 160 | |
| 161 | ################################################################################## |
| 162 | # Subroutine: calc_folder_depth() |
| 163 | # - ARGUMENT: $folder_path |
| 164 | # - RETURN: $depth |
| 165 | ################################################################################## |
| 166 | sub calc_folder_depth { |
| 167 | my ($folder_path) = @_; |
| 168 | my $depth = $folder_path =~ tr /\///; # Contain the number of substitutions made |
| 169 | |
| 170 | return $depth; |
| 171 | } |
| 172 | |
| 173 | ################################################################################## |
| 174 | # Subroutine: preprocess_depth() |
| 175 | # - ARGUMENT: |
| 176 | # - RETURN: |
| 177 | ################################################################################## |
| 178 | sub preprocess_depth { |
| 179 | my $depth = calc_folder_depth($File::Find::dir); # Contain the number of substitutions made |
| 180 | return @_ if $depth < $max_depth; |
| 181 | |
| 182 | return; |
| 183 | } |
| 184 | |
| 185 | ################################################################################## |
| 186 | # Subroutine: wanted() |
| 187 | # - ARGUMENT: |
| 188 | # - RETURN: |
| 189 | ################################################################################## |
| 190 | sub wanted { |
| 191 | push @all_list, $File::Find::name if ($_ =~ /\.h$/); |
| 192 | } |
| 193 | |
| 194 | ################################################################################## |
| 195 | # Subroutine: get_csif_checksum_value() |
| 196 | # - ARGUMENT: |
| 197 | # $user: 0 => CSIF; |
| 198 | # 1 => SLM; |
| 199 | # 2 => ST; |
| 200 | # 3 => other; |
| 201 | # $csif_folder_path: ../common/interface/modem/mt6297/CSIF |
| 202 | # - RETURN: $checksum_value |
| 203 | ################################################################################## |
| 204 | sub get_csif_checksum_value { |
| 205 | my ($user, $csif_folder_path, $xml_file) = @_; |
| 206 | |
| 207 | # Initialize global variables |
| 208 | @all_list = (); |
| 209 | $max_depth = 0; |
| 210 | |
| 211 | #my $method = 0; |
| 212 | |
| 213 | if($user == 0) { |
| 214 | print "User 0: $csif_folder_path\n"; |
| 215 | #if ($method) { |
| 216 | # print "Method " . $method . "\n"; |
| 217 | # my $universal_comm_csif_depth = &calc_folder_depth($csif_folder_path); |
| 218 | # # Modify global variable |
| 219 | # $max_depth = $universal_comm_csif_depth + 1; |
| 220 | # # Preprocess CSIF folder w/ depth 1 and aggregate files into @all_list |
| 221 | # find({ |
| 222 | # preprocess => \&preprocess_depth, |
| 223 | # wanted => \&wanted, |
| 224 | # }, $csif_folder_path); |
| 225 | #} else { |
| 226 | @all_list = xml_parser($user, $xml_file); |
| 227 | #} |
| 228 | my $checksum_value = sprintf("%u", &crc32(&merge_checksum_input(@all_list))); |
| 229 | $checksum_value = join($checksum_value, "", "u"); |
| 230 | return $checksum_value; |
| 231 | } elsif ($user == 1) { |
| 232 | my @CSIF_SLM = (); |
| 233 | #if ($method) { |
| 234 | # print "User 1: @CSIF_SLM\n"; |
| 235 | # print "Method " . $method . "\n"; |
| 236 | # my $CSIF_SLM_PATH = join($csif_folder_path, "", "/slm/"); |
| 237 | # @CSIF_SLM = ($csif_folder_path, $CSIF_SLM_PATH); |
| 238 | #} else { |
| 239 | # @CSIF_SLM = ($csif_folder_path, xml_parser($user, $xml_file)); |
| 240 | @CSIF_SLM = xml_parser($user, $xml_file); |
| 241 | #} |
| 242 | my $checksum_value = sprintf("%u", &crc32(&merge_checksum_input(@CSIF_SLM))); |
| 243 | $checksum_value = join($checksum_value, "", "u"); |
| 244 | return $checksum_value; |
| 245 | } elsif ($user == 2) { |
| 246 | my @CSIF_NL1FWK = (); |
| 247 | #if ($method) { |
| 248 | # print "User 1: @CSIF_NL1FWK\n"; |
| 249 | # print "Method " . $method . "\n"; |
| 250 | # my $CSIF_NL1FWK_PATH = join($csif_folder_path, "", "/slm/"); |
| 251 | # @CSIF_NL1FWK = ($csif_folder_path, $CSIF_NL1FWK_PATH); |
| 252 | #} else { |
| 253 | # @CSIF_NL1FWK = ($csif_folder_path, xml_parser($user, $xml_file)); |
| 254 | @CSIF_NL1FWK = xml_parser($user, $xml_file); |
| 255 | #} |
| 256 | my $checksum_value = sprintf("%u", &crc32(&merge_checksum_input(@CSIF_NL1FWK))); |
| 257 | $checksum_value = join($checksum_value, "", "u"); |
| 258 | return $checksum_value; |
| 259 | }elsif ($user == 3) { |
| 260 | #my $universal_comm_csif_depth = &calc_folder_depth($csif_folder_path); |
| 261 | # Modify global variable |
| 262 | #$max_depth = $universal_comm_csif_depth + 1; |
| 263 | # Preprocess CSIF folder w/ depth 1 and aggregate files into @all_list |
| 264 | #find({ |
| 265 | # preprocess => \&preprocess_depth, |
| 266 | # wanted => \&wanted, |
| 267 | #}, $csif_folder_path); |
| 268 | @all_list = (@all_list, xml_parser($user, $xml_file)); |
| 269 | #foreach (@all_list) { |
| 270 | # print $_ . "\n"; |
| 271 | #} |
| 272 | my $checksum_value = sprintf("%u", &crc32(&merge_checksum_input(@all_list))); |
| 273 | $checksum_value = join($checksum_value, "", "u"); |
| 274 | return $checksum_value; |
| 275 | } elsif ($user == 4) { |
| 276 | #my $universal_comm_csif_depth = &calc_folder_depth($csif_folder_path); |
| 277 | # Modify global variable |
| 278 | #$max_depth = $universal_comm_csif_depth + 1; |
| 279 | # Preprocess CSIF folder w/ depth 1 and aggregate files into @all_list |
| 280 | #find({ |
| 281 | # preprocess => \&preprocess_depth, |
| 282 | # wanted => \&wanted, |
| 283 | #}, $csif_folder_path); |
| 284 | @all_list = (@all_list, xml_parser($user, $xml_file)); |
| 285 | #foreach (@all_list) { |
| 286 | # print $_ . "\n"; |
| 287 | #} |
| 288 | my $checksum_value = sprintf("%u", &crc32(&merge_checksum_input(@all_list))); |
| 289 | $checksum_value = join($checksum_value, "", "u"); |
| 290 | return $checksum_value; |
| 291 | } else { |
| 292 | return 0; |
| 293 | } |
| 294 | } |
| 295 | |
| 296 | ############################## |
| 297 | # test code |
| 298 | ############################## |
| 299 | #my $FILENAME= ($ARGV[0]); |
| 300 | #printf "%s",get_cuif_checksum_value(0,$FILENAME); |
| 301 | #print "\n"; |