blob: da9af7a1b2def68aac842cf4e251ef4c76554d77 [file] [log] [blame]
#!/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);
}
#-------------------------------------------------------------------