#!/usr/bin/perl -w | |
#------------------------------------------------------------------- | |
#Tool version | |
$tool_version = '20170719'; | |
#------------------------------------------------------------------- | |
#Parameters Configuration | |
$imm_file = $ARGV[0]; | |
$list_file = $ARGV[1]; | |
$symbol_file = $ARGV[2]; | |
$log_file = $ARGV[3]; | |
#------------------------------------------------------------------- | |
# Replace '\' with '/' | |
$imm_file =~ s/\\/\//g; | |
$list_file =~ s/\\/\//g; | |
$symbol_file =~ s/\\/\//g; | |
$log_file =~ s/\\/\//g; | |
#------------------------------------------------------------------- | |
$debug_mode = 0; # 0 or 1 | |
$error_prefix = 'AutoAMMS Error:'; | |
$nolist_keyword = 'NO_LIST'; | |
$attribute_line_number = 0; | |
#------------------------------------------------------------------- | |
# Open log file | |
open (FILE_LOG, ">>$log_file" ) or die (print "$error_prefix Can't open Auto-AMMS-Attribute log file $log_file!\n"); | |
print FILE_LOG "Auto AMMS Attribute Tool $tool_version\n"; | |
#------------------------------------------------------------------- | |
#Construct C file name | |
$c_file = $imm_file; | |
$c_file =~ s/.*\///; # remove path part | |
print FILE_LOG "Source C File : $c_file\n"; | |
print FILE_LOG "Immediated File : $imm_file\n"; | |
#------------------------------------------------------------------- | |
# Intialize some list as empty | |
%special_symbol_list = (); | |
%added_code = (); | |
%attribute_list = (); | |
$attribute = ''; | |
$find_file = 0; | |
$special_symbol_list_num = 0; | |
Extract_DRDI_attribute($list_file,$c_file); | |
if($find_file == 1) | |
{ | |
$special_symbol_list_num = Extrace_DRDI_symbol($symbol_file,$c_file); | |
print FILE_LOG "special symbol list num : $special_symbol_list_num\n"; | |
&Find_DRDI_List($imm_file, $attribute); | |
} | |
#Add __attribute__ code in source code | |
if( scalar(keys %added_code) > 0 ) | |
{ | |
my $backup = &Add_Attribute_Code( $debug_mode, $imm_file ); | |
print FILE_LOG "Backup Imm File : $backup\n"; | |
}else | |
{ | |
print FILE_LOG "\t$c_file is not in AMMS symbol lists.\n"; | |
} | |
#------------------------------------------------------------------- | |
#Close log file handle | |
print FILE_LOG "Done!\n"; | |
print FILE_LOG "-----------------------------------------------------------\n"; | |
close FILE_LOG; | |
#------------------------------------------------------------------- | |
#Parsing Done. | |
exit 0; #return 0 if it is successful | |
#------------------------------------------------------------------- | |
sub Extract_DRDI_attribute | |
{ | |
my $list = $_[0]; | |
return 0 if( $list eq $nolist_keyword ); | |
my $search_file_1 = $_[1]; | |
my $search_file_2 = $search_file_1; | |
my $section = ''; | |
$search_file_2 =~ s/\.c$/\.obj/; | |
# Open TCM fucntions list file | |
open (FILE_ITCM, "<$list" ) or &print_error_info_die("$error_prefix Can't open AMMS 3GFDD list file $list!\n"); | |
while (<FILE_ITCM>) | |
{ | |
if( /^__attribute__/) | |
{ | |
$section = $_; | |
}elsif( /^\s*($search_file_1|$search_file_2)\b/ ) | |
{ | |
$find_file = 1; | |
print FILE_LOG "find file: $search_file_2\n"; | |
last; | |
} | |
} | |
$section =~ s/\r\n//g; | |
$attribute = $section; | |
close FILE_ITCM; | |
} | |
sub Extrace_DRDI_symbol | |
{ | |
my $list = $_[0]; | |
return 0 if( $list eq $nolist_keyword ); | |
my $search_file_1 = $_[1]; | |
my $search_file_2 = $search_file_1; | |
my $section = ''; | |
$search_file_2 =~ s/\.c$/\.obj/; | |
# Open TCM fucntions list file | |
open (FILE_ITCM, "<$list" ) or &print_error_info_die("$error_prefix Can't open AMMS 3GFDD list file $list!\n"); | |
while (<FILE_ITCM>) | |
{ | |
if( /^\s*(\S+)\s*,?\s*($search_file_1|$search_file_2)\b/ ) | |
{ | |
my $search_symbol = $1; | |
my $symbol_name = $search_symbol; | |
$symbol_name =~ s/_SetX/_Set/; | |
$special_symbol_list{$symbol_name} = 0; | |
} | |
} | |
close FILE_ITCM; | |
return scalar(keys %special_symbol_list); | |
} | |
#------------------------------------------------------------------- | |
#------------------------------------------------------------------- | |
sub Find_DRDI_List | |
{ | |
my $imm = $_[0]; #Input is immediated | |
my $attribute_section = $_[1]; #Input attribute | |
# Open imm file, which is output of pre-processor | |
open (FILE_IMM, "<$imm" ) or &print_error_info_die("$error_prefix Can't open immediated file $imm!\n"); | |
my $line_in = ''; | |
my $line_number = 0; | |
my $brace_l_sum = 0; # left brace { conter | |
my $brace_r_sum = 0; # right brace } conter | |
my $setx = 'SetX'; | |
foreach my $i (0..63) | |
{ | |
my $attribute = $attribute_section; | |
my $setnum = $setx; | |
$attribute =~ s/SETX/SET$i/; | |
$setnum =~ s/X/$i/; | |
$attribute_list{$setnum} = $attribute; | |
} | |
while( <FILE_IMM> ) | |
{ | |
$line_in = $_; | |
$line_number++; | |
next if($line_in =~ /^\#line/); # speed up parsing | |
next unless ( $line_in =~ /\S/ ); # speed up parsing | |
# Update {} counters | |
my $brace_l_cnt = $line_in =~ tr/{//; #count { number | |
my $brace_r_cnt = $line_in =~ tr/}//; #count } number | |
my $brace_tick_ori = $brace_l_sum - $brace_r_sum; | |
my $brace_tick_new = $brace_tick_ori + ($brace_l_cnt - $brace_r_cnt); | |
my $run_special_symbol_list = 1; | |
$brace_l_sum += $brace_l_cnt; | |
$brace_r_sum += $brace_r_cnt; | |
if( $brace_tick_ori == 0 && !($line_in =~ /^\s*{/) ) # Only search global variable | |
{ | |
unless( ( $line_in =~ /\bextern\b/ ) || !($line_in =~ /\bconst\b/ ) ) # || ($line_in =~ /\*/) | |
{ | |
if(($line_in =~ /\*+\s*\b(\S+)_Set(\d+)\b/i) || ($line_in =~ /\*+\s*\b(\S+)_Type(\d+)\b/i)) | |
{ | |
if(($line_in =~ /\*+\s*\bconst\b\s*\b(\S+)_Set(\d+)\b.*[=;,]/i) || ($line_in =~ /\*+\s*\bconst\b\s*\b(\S+)_TYPE(\d+)\b.*[=;,]/)) | |
{ | |
my $num = $2; | |
my $setnum = $setx; | |
$setnum =~ s/X/$num/; | |
$added_code{ $line_number } = $attribute_list{$setnum}; | |
$run_special_symbol_list = 0; | |
} | |
} | |
elsif(( $line_in =~ /(^|,)[^=]*\b(\S+)_Set(\d+)\b.*[=;,]/i ) || ( $line_in =~ /(^|,)[^=]*\b(\S+)_TYPE(\d+)\b.*[=;,]/ )) | |
{ | |
my $num = $3; | |
my $setnum = $setx; | |
$setnum =~ s/X/$num/; | |
$added_code{ $line_number } = $attribute_list{$setnum}; | |
$run_special_symbol_list = 0; | |
} | |
} | |
if( ($special_symbol_list_num > 0) && ($run_special_symbol_list == 1) ) | |
{ | |
foreach( keys %special_symbol_list ) | |
{ | |
my $target = $_; | |
if($target =~ /\s*(\S+)\*(\S+)\*(\S+)/) | |
{ | |
my $pre = $1; | |
my $middle = $2; | |
my $post = $3; | |
if( $line_in =~ /(^|,)[^=]*\b$pre\w+$middle\w+$post(\d+)\b.*[=;,]/ ) | |
{ | |
my $num = $2; | |
my $setnum = $setx; | |
$setnum =~ s/X/$num/; | |
$special_symbol_list{ $target }++; # hit and increase hit counter | |
$added_code{ $line_number } = $attribute_list{$setnum}; | |
} | |
} | |
elsif($target =~ /\s*(\S+)\*(\S+)/) | |
{ | |
my $pre = $1; | |
my $post = $2; | |
if( $line_in =~ /(^|,)[^=]*\b$pre\w+$post(\d+)\b.*[=;,]/ ) | |
{ | |
my $num = $2; | |
my $setnum = $setx; | |
$setnum =~ s/X/$num/; | |
$special_symbol_list{ $target }++; # hit and increase hit counter | |
$added_code{ $line_number } = $attribute_list{$setnum}; | |
} | |
} | |
else | |
{ | |
if( $line_in =~ /(^|,)[^=]*\b$target(\d+)\b.*[=;,]/ ) # variable name is matched but assignment is excluded | |
{ | |
my $num = $2; | |
my $setnum = $setx; | |
$setnum =~ s/X/$num/; | |
$special_symbol_list{ $target }++; # hit and increase hit counter | |
$added_code{ $line_number } = $attribute_list{$setnum}; | |
} | |
}#End of if() | |
} | |
} | |
} | |
} | |
close FILE_IMM; | |
} | |
#------------------------------------------------------------------- | |
sub Add_Attribute_Code | |
{ | |
my $debug = $_[0]; | |
my $file_ori = $_[1]; | |
my $file_new = $file_ori; | |
my $file_bak = $file_ori; | |
$file_bak =~ s/\.c$/\.i/; | |
rename $file_ori, $file_bak or &print_error_info_die("$error_prefix Can't rename $file_ori to $file_bak\n"); | |
open (FILE_IN, "<$file_bak" ) or &print_error_info_die("$error_prefix Can't open immediated file $file_bak!\n"); | |
open (FILE_OUT, ">$file_new" ) or &print_error_info_die("$error_prefix Can't open output file $file_new!\n"); | |
my $line_number = 0; | |
my $line_in = ''; | |
my $log_on = 0; | |
while( <FILE_IN> ) | |
{ | |
$line_in = $_; | |
$line_number++; | |
if( exists $added_code{$line_number} ) | |
{ | |
my $added = $added_code{$line_number}; | |
$attribute_line_number++; | |
$added =~ s/LINE/$attribute_line_number/; | |
print FILE_OUT "$added\n "; | |
if( $debug == 1 ) | |
{ | |
print FILE_LOG "$added "; | |
$log_on = 1; | |
} | |
} | |
print FILE_OUT $line_in; | |
if($log_on==1) | |
{ | |
print FILE_LOG $line_in; | |
if( $line_in =~ /[={\;]/ ) | |
{ | |
$log_on= 0; | |
print FILE_LOG "\n"; | |
} | |
} | |
} | |
close FILE_IN; | |
close FILE_OUT; | |
return $file_bak; | |
} | |
#------------------------------------------------------------------- | |
sub print_error_info_die | |
{ | |
my $error_info = $_[0]; | |
print FILE_LOG $error_info; | |
print STDERR $error_info; | |
exit(1); | |
} | |
#------------------------------------------------------------------- |