blob: e4046d107e58f8c8d166202cd2ebc7f6e6d26f44 [file] [log] [blame]
#!/usr/bin/perl
#
# Copyright Statement:
# --------------------
# This software is protected by Copyright and the information contained
# herein is confidential. The software may not be copied and the information
# contained herein may not be used or disclosed except with the written
# permission of MediaTek Inc. (C) 2006
#
# BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
# NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
# SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
#
# BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
# LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
#
# THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
# WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
# LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
# RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
# THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
#
#*****************************************************************************
#*
#* Filename:
#* ---------
#* auto_adjust_mem.pm
#*
#* Project:
#* --------
#*
#*
#* Description:
#* ------------
#* This module collects the subroutines for common utility.
#*
#*
#* Author:
#* -------
#* Qmei Yang (mtk03726)
#*
#****************************************************************************/
#****************************************************************************
# Included Modules
#****************************************************************************
use strict;
#****************************************************************************
# Constants
#****************************************************************************
my $AAPMC_VERNO = " m0.02";
# m0.02, Support load view size insufficient error code
# m0.01, Support folder on Linux
# v0.03, Add AAPMC::Copyer to support theone architecture
# v0.02, 20120425 by mei, add one error code
# v0.01, initial version
return 1;
#****************************************************************************
# Package : ERR
#****************************************************************************
package ERR;
use constant NO_MODIFY => 0;
use constant MODIFY_SUCCESS => 1;
use constant CANNOT_ADJUST => 2;
use constant AAPMCLOG_SUCCESS => 3;
use constant AUTOCONFIG_SELF_MODIFY_SUCCESS => 4;
use constant NO_NEED_TO_UPDATE => 5;
use constant ERR_MODIFYFAIL => 101;
use constant ERR_UNEXPECTED => 102; #default exit
use constant ERR_MODIFYDUPLICATED => 103;
use constant ERR_LOADVIEWSIZE_INSUFFICIENT => 104;
sub QueryErrMeaning
{
my ($ERR) = @_;
return "[$ERR]NO_MODIFY, PASS" if($ERR == NO_MODIFY);
return "[$ERR]MODIFY_SUCCESS, PASS" if($ERR == MODIFY_SUCCESS);
return "[$ERR]CANNOT_ADJUST, FAIL" if($ERR == CANNOT_ADJUST);
return "[$ERR]AAPMCLOG_SUCCESS, PASS" if($ERR == AAPMCLOG_SUCCESS);
return "[$ERR]AUTOCONFIG_SELF_MODIFY_SUCCESS, PASS" if($ERR == AUTOCONFIG_SELF_MODIFY_SUCCESS);
return "[$ERR]NO_NEED_TO_UPDATE, PASS" if($ERR == NO_NEED_TO_UPDATE);
return "[$ERR]MODIFYFAIL, FAIL" if($ERR == ERR_MODIFYFAIL);
return "[$ERR]UNEXPECTED, FAIL" if($ERR == ERR_UNEXPECTED);
return "[$ERR]MODIFY DUPLICATED, FAIL" if($ERR == ERR_MODIFYDUPLICATED);
return "[$ERR]LOADVIEWSIZE_INSUFFICIENT, FAIL" if($ERR == ERR_LOADVIEWSIZE_INSUFFICIENT);
}
#****************************************************************************
# Package : AUTO_ADJUST
#****************************************************************************
package AUTO_ADJUST;
#****************************************************************************
# subroutine: AUTO_ADJUST::ChangeDefineValue
# aim to change #define value
# input: $strFilePath: file path
# %ChangeListHash={$strName, $strValue}
# After changing, it should look like: #define $strName $strValue
# output: $bModified: ERR::NO_MODIFY= no change, ERR::MODIFY_SUCCESS=modified
# SampleCode:
# my %ChangeList;
# $ChangeList{'name1'} = "value1";
# $ChangeList{'name2'} = "value2";
# &AUTO_ADJUST::ChangeDefineValue($CUSTOM_FEATURE_CONFIG_H, \%ChangeList);
# or &AUTO_ADJUST::ChangeDefineValue($CUSTOM_FEATURE_CONFIG_H, {'name1'=>'value1',});
#****************************************************************************
sub ChangeDefineValue
{
my ($strFilePath, $ChangeListHash_href) = @_;
open (FILE_HANDLE, $strFilePath) or &autoadjust_die("Cannot open $strFilePath\n", __FILE__, __LINE__);
my $reading = "";
my $bModified = ERR::ERR_MODIFYFAIL;
while (<FILE_HANDLE>)
{
my $strLine = $_;
foreach my $strName (keys %$ChangeListHash_href)
{
my $strValue = $ChangeListHash_href->{$strName};
if($strLine =~ /^#define\s+($strName)\s+(\S+)/ or
$strLine =~ /\/\/\s*#define\s+($strName)\s+/ or
$strLine =~ /\/\/\s*#define\s+($strName)$/)
{
next if(hex($strValue) == hex($2));
$strLine = "#define $strName $strValue\n";
$bModified = ERR::MODIFY_SUCCESS;
}
}
$reading .= $strLine;
}
close FILE_HANDLE;
open (FILE_HANDLE, ">$strFilePath") or &autoadjust_die("Cannot open $strFilePath\n", __FILE__, __LINE__);
print FILE_HANDLE $reading;
close FILE_HANDLE;
#print $bModified == 0 ? "No change\n" : "Modified\n";
return $bModified;
}
#****************************************************************************
# subroutine: AUTO_ADJUST::ModifyByChangeRecord
# input: $strFolderPath: folder path before mcu\
# Reference of @ChangeRecord = [$strFilePath, %ChangeListHash, %P4Info]
# $bNeedBackup: 0=no need backup, 1=need backup
# output: $err: ERR::NO_MODIFY= no change, ERR::MODIFY_SUCCESS=modified
# Note: Backup the file before modifying. If no change, delete backup file.
# Backup file name=File.beforeAutoAdj.timestamp.[rand=3 digits]
# eg. ABC.h.beforeAutoAdj.1322408801.282
#****************************************************************************
sub ModifyByChangeRecord
{
my ($strFolderPath, $ChangeRecord_ref, $bNeedBackup) = @_;
my $strFileName = $ChangeRecord_ref->[0];
my $TheOneBackupPath = AAPMC_COPYER::TheOneBackup($strFolderPath, $strFileName);
my $BackupPath = AAPMC_COPYER::AAPMCBackup($strFolderPath, $strFileName) if ($bNeedBackup ==1);
my $filepath = $strFolderPath . $strFileName;
my $err = &ChangeDefineValue($filepath, $ChangeRecord_ref->[1]);
unlink $BackupPath if($bNeedBackup ==1 and $err == ERR::NO_MODIFY);
unlink $TheOneBackupPath if($err == ERR::NO_MODIFY);
return $err;
}
#****************************************************************************
# subroutine: AUTO_ADJUST::CreateP4InfoTemplate
# input: $strOwner_ID: P4 ID
# $strProject: Project Name
# $strPurpose: CR Purpose
# $strAdjustmentResult: Change List
# output: Reference of %P4Info
#****************************************************************************
sub CreateP4InfoTemplate
{
my ($strOwner_ID, $strProject, $strPurpose, $strAdjustmentResult) = @_;
my %P4Info = ( "OWNER_ID" => $strOwner_ID,
"CR_DESCRIPTION" => "[$strProject]$strPurpose\n$strAdjustmentResult" );
return \%P4Info;
}
#****************************************************************************
# subroutine: AUTO_ADJUST::GetP4Info
# input: Reference of %P4Info
# output: $strOwner_ID: P4 Owner ID
# $strCR_Description: CR description for 1 modification
#****************************************************************************
sub GetP4Info
{
my ($P4Info_ref) = @_;
my ($strOwner_ID, $strCR_Description);
if($P4Info_ref)
{
$strOwner_ID = $P4Info_ref->{OWNER_ID};
$strCR_Description = $P4Info_ref->{CR_DESCRIPTION};
}
return ($strOwner_ID, $strCR_Description);
}
#****************************************************************************
# subroutine: error_handler
# input: $error_msg: error message
#****************************************************************************
sub error_handler
{
my ($error_msg, $file, $line_no, $strTitle) = @_;
my $final_error_msg = "$strTitle ERROR: $error_msg at $file line $line_no : $!\n";
print $final_error_msg;
die $final_error_msg;
}
sub autoadjust_die
{
my ($error_msg, $file, $line_no) = @_;
&error_handler($error_msg, $file, $line_no, 'AUTO ADJUST MEM');
}
#****************************************************************************
# Package : AAPMCLogParser
#****************************************************************************
package AAPMCLogParser;
use Storable qw/lock_retrieve lock_nstore/;
my $g_FileArchieve = undef;
my $g_DBInfo_ref = undef; # %DBInfoTable
#****************************************************************************
# subroutine: AAPMCLogParser::Open
# input: $strLogPath: AAPMC.log's path
# output: $err: ERR::ERR_UNEXPECTED= Load failed
# ERR::AAPMCLOG_SUCCESS=Load successfully
#****************************************************************************
sub Open
{
my ($strLogPath) = @_;
my $err = ERR::ERR_UNEXPECTED;
if(!-e $strLogPath)
{
my %Empty = ('AAPMCLog' => ());
lock_nstore \%Empty, $strLogPath;
}
my $g_FileArchieve = lock_retrieve $strLogPath;
if($g_FileArchieve)
{
$g_DBInfo_ref = $g_FileArchieve->{'AAPMCLog'};
$err = ERR::AAPMCLOG_SUCCESS;
}
return $err;
}
#****************************************************************************
# subroutine: AAPMCLogParser::Close
# input: $strLogPath: AAPMC.log's path
# output: $err: ERR::ERR_UNEXPECTED= Load failed
# ERR::AAPMCLOG_SUCCESS=Load successfully
#****************************************************************************
sub Close
{
my ($strLogPath) = @_;
my $err = ERR::ERR_UNEXPECTED;
if(-e $strLogPath)
{
my %Temp = ('AAPMCLog' => $g_DBInfo_ref);
lock_nstore \%Temp, $strLogPath;
$err = ERR::AAPMCLOG_SUCCESS;
}
return $err;
}
#****************************************************************************
# subroutine: AAPMCLogParser::AddOneChangeRecord
# input: $ChangeFilePath: The file is going to be modified. (store its path by mcu\... without folder information)
# $ChangeList_ref: Reference of %ChangeListHash={$strName, $strValue}
# $P4Info_ref: Reference of %P4Info = {$OwnerID, $CR_Description} => You can create by &AUTO_ADJUST::CreateP4InfoTemplate
# output: $err: ERR::ERR_MODIFYDUPLICATED : Can't add the same key ChangeList more than twice
# ERR::AAPMCLOG_SUCCESS : Add successfully
#****************************************************************************
sub AddOneChangeRecord
{
my ($ChangeFilePath, $ChangeList_ref, $P4Info_ref) = @_;
my $err = ERR::ERR_UNEXPECTED;
#Trim the string before mcu\ in which mcu should be the last mcu
if($ChangeFilePath =~ /\S+(mcu\S+)/)
{
$ChangeFilePath = $1;
}
if(0 == &isModified($ChangeFilePath, $ChangeList_ref))
{
#Key=TimeStamp, Value=0: $ChangeFilePath
# 1: %ChangeList
# 2: %P4Info
$g_DBInfo_ref->{&GetTimeStamp()} = [ $ChangeFilePath, $ChangeList_ref, \%$P4Info_ref ];
$err = ERR::AAPMCLOG_SUCCESS;
}
else
{
$err = ERR::ERR_MODIFYDUPLICATED;
}
return $err;
}
#****************************************************************************
# subroutine: AAPMCLogParser::isModified : Called by AddOneChangeRecord()
# input: $strChangeFilePath: The file is going to be modified. (store its path by mcu\... without folder information)
# $ChangeList_ref: Reference of %ChangeListHash={$strName, $strValue}
# output: $isModified: 0=never modified before, 1= it has been modified
# comment: in the same file, if ChangeList's option existed, then return duplicated modification.
#****************************************************************************
sub isModified
{
my ($strChangeFilePath, $ChangeList_ref) = @_;
my $isModified = 0; # 0=no, 1=yes;
if($g_DBInfo_ref)
{
while (my ($timestamp, $aChange) = each (%$g_DBInfo_ref))
{
if(($aChange->[0] eq $strChangeFilePath))
{
foreach my $option (keys %$ChangeList_ref)
{
if(exists $aChange->[1]{$option})
{
$isModified = 1;
last;
}
}
}
}
}
#print $isModified==0 ? "never modified\n" : "has been modified\n";
return $isModified;
}
#****************************************************************************
# subroutine: AAPMCLogParser::GetAllRecordsIndex
# input: x
# output: $err: ERR::ERR_UNEXPECTED: no records in DBInfo.
# ERR::AAPMCLOG_SUCCESS
# Reference of @ChangeRecords: an array of all timestamps
#****************************************************************************
sub GetAllRecordsIndex
{
my @ChangeRecords;
my $err = ERR::ERR_UNEXPECTED;
if($g_DBInfo_ref)
{
map {push (@ChangeRecords, $_);} keys %$g_DBInfo_ref;
$err = ERR::AAPMCLOG_SUCCESS;
}
return ($err, \@ChangeRecords);
}
#****************************************************************************
# subroutine: AAPMCLogParser::GetByIndex
# input: $Index: timestamp
# $Type: AAPMCLogParser::FILEPATH
# AAPMCLogParser::CHANGELIST
# AAPMCLogParser::P4Info
# AAPMCLogParser::RECORD
# output: 1. $err=ERR::ERR_UNEXPECTED=no data in DBInfo
# ERR::AAPMCLOG_SUCCESS
# 2. if $Type=AAPMCLogParser::FILEPATH, return strChangeFilePath
# $Type=AAPMCLogParser::CHANGELIST, return Reference of %ChangeList
# $Type=AAPMCLogParser::P4INFO, return Reference of %P4Info,
# you may use AUTO_ADJUST::GetP4Info to get P4Info
# $Type=AAPMCLogParser::RECORD, return Reference of %ChangeRecord
# else, return undef with ERR::ERR_UNEXPECTED
#****************************************************************************
use constant FILEPATH => 0;
use constant CHANGELIST => 1;
use constant P4INFO => 2;
use constant RECORD => 3;
sub GetByIndex
{
my ($Index, $Type) = @_;
if($g_DBInfo_ref)
{
if($Type < RECORD)
{
return ($g_DBInfo_ref->{$Index}[$Type]);
}
elsif($Type == RECORD)
{
return ($g_DBInfo_ref->{$Index}); # @ChangeRecord
}
}
return undef;
}
#****************************************************************************
# subroutine: AAPMCLogParser::GetTimeStamp
# input: x
# output: string of timestamp with rand(1000)
# eg. 1322408801.282
#****************************************************************************
sub GetTimeStamp
{
return time().".".int(rand(1000));
}
#****************************************************************************
# Package : AAPMC_COPYER
#****************************************************************************
package AAPMC_COPYER;
use constant THEONE => "theone";
use constant CONFIG => "conf";
use File::Copy;
#****************************************************************************
# subroutine: AAPMC_COPYER::AAPMCBackup
# input:
# output:
#****************************************************************************
sub AAPMCBackup
{
my ($strBuildFolder, $strFileName) = @_;
#Backup for AutoAdj
$strBuildFolder .= '/' if($strBuildFolder !~ /\/$/);
my $OrgFilePath = $strBuildFolder.$strFileName;
my $BackupPath = $OrgFilePath.".beforeAutoAdj".&AAPMCLogParser::GetTimeStamp();
copy($OrgFilePath, $BackupPath);
return $BackupPath;
}
sub TheOneBackup
{
my ($strBuildFolder, $strFileName) = @_;
#Backup for the one
$strBuildFolder .= '/' if($strBuildFolder !~ /\/$/);
my $OrgFilePath = $strBuildFolder.$strFileName;
my $BackupPath = $OrgFilePath.".".THEONE;
if(!-e $BackupPath)
{
copy($OrgFilePath, $BackupPath);
}
return $BackupPath;
}
#****************************************************************************
# subroutine: AAPMC_COPYER::IsNeededToCopy
# purpose: before m sysgen, build flow needs to know if it needs to copy the files
# from custom\system\[BB]\
# input: 1. $strBuild_FolderPath : build folder for custom\system
# 2. $strBB_FolderPath : custom\system\[BB]
# 3. $strFileName : filename without .conf or .theone for querying if it is needed to copy
# output: undef = no need to copy
# 1 = needed to copy
#****************************************************************************
sub IsNeededToCopy
{
my ($strBuild_FolderPath, $strBB_FolderPath, $strFileName) = @_;
my $bNeededToCopy = undef;
$strBuild_FolderPath .= '/' if($strBuild_FolderPath !~ /\/$/);
$strBB_FolderPath .= '/' if($strBB_FolderPath !~ /\/$/);
my $strBuildFile = $strBuild_FolderPath . $strFileName;
my $strBBFile = $strBB_FolderPath . $strFileName ."." .CONFIG;
my $strTheOneFile = $strBuild_FolderPath . $strFileName . "." . THEONE;
if(-e $strBuildFile)
{
if(-e $strTheOneFile)
{
$bNeededToCopy = &CompareFile($strBBFile, $strTheOneFile);
}
else
{
$bNeededToCopy = 1;
}
}
else
{
$bNeededToCopy = 1;
}
return $bNeededToCopy;
}
#****************************************************************************
# subroutine: AAPMC_COPYER::CompareFile
# input: 1. strSrcPath
# 2. strDestPath
# output: undef = no different
# 1 = have some difference
#****************************************************************************
sub CompareFile
{
my ($strSrcPath, $strDestPath) = @_;
my $bDeff = undef;
my $strSrcContent = &GetFileContent($strSrcPath);
my $strDestContent = &GetFileContent($strDestPath);
$bDeff = 1 if($strSrcContent ne $strDestContent);
return $bDeff;
}
#****************************************************************************
# subroutine: AAPMC_COPYER::GetFileContent
# input: strFilePath
# output: strFileContent after chomp
#****************************************************************************
sub GetFileContent
{
my ($strFilePath) = @_;
my $content;
open FILE, "<$strFilePath" or &AUTO_ADJUST::error_handler("$strFilePath: open file error!", __FILE__, __LINE__, 'AAPMC_COPYER::GetFileContent');
{
local $/;
$content = <FILE>;
}
close FILE;
chomp($content);
return $content;
}