| #!/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; | |
| } |