[Feature]Upload Modem source code
Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/tools/FileInfoParser.pm b/mcu/tools/FileInfoParser.pm
new file mode 100644
index 0000000..d88da72
--- /dev/null
+++ b/mcu/tools/FileInfoParser.pm
@@ -0,0 +1,1042 @@
+#!/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:
+#* ---------
+#* FileInfoParser.pm
+#*
+#* Project:
+#* --------
+#*
+#*
+#* Description:
+#* ------------
+#* This module collects the subroutines for common utility.
+#*
+#*
+#* Author:
+#* -------
+#* Carl Kao (mtk08237)
+#*
+#****************************************************************************/
+use strict;
+#use warnings;
+BEGIN { push @INC, './pcore/tools/' } # add additional library path
+#--------------------------------------------------------------------------------------------------------------
+package BuildOPT;
+#****************************************************************************
+# Constant
+#****************************************************************************
+use constant CMPL => 0;
+use constant REL => 1;
+#--------------------------------------------------------------------------------------------------------------
+package FileInfo;
+use constant SHARED_REGION_SIZE => "SHARED_REGION_SIZE";
+use constant PCORE_LV_SIZE => "PCORE_LV_SIZE";
+
+use sysGenUtility; #pm file name without case sensitivity
+use CommonUtility;
+#****************************************************************************
+# Constants
+#****************************************************************************
+my $FILEINFOPARSER_VERNO = " a0.01";
+ # a0.01 , 2016/11/21, Tero, Mode parsing fixed
+ # u0.18 , 2016/08/01, Tero, L1Core and Copro info removed
+ # u0.17 , 2016/01/31, Tero, Fix compiler option parsing bug in EvaluateCompileOption()
+ # u0.16 , 2015/07/03, Carl, Call GetDefaultSharedMemorySize to get default shared memory size
+ # u0.15 , 2015/06/23, Carl, Refine GetSharedMemorySize. It includes dsp tx/rx section now
+ # u0.14 , 2015/06/22, Carl, Decrease shared region size (in 1st linking time) from 96 MB to 80 MB
+ # u0.13 , 2015/06/22, Carl, Decrease shared region size (in 1st linking time) from 112 MB to 96 MB
+ # u0.12 , 2015/05/19, Carl, Increase shared region size (in 1st linking time) from 80 MB to 112 MB
+ # u0.11 , 2015/04/17, Carl, Increase shared region size (in 1st linking time) from 48 MB to 80 MB
+ # u0.10 , 2015/02/06, Carl, disable isSupportedToAdjustLoadView for ESL COSIM
+ # u0.09 , 2015/01/06, Carl, lds refinement: 1) auto adjust shared region size, 2) reserve pcore, l1core SWLA space
+ # u0.08 , 2014/22/22, Carl, Support L2SRAM section (in L1CORE)
+ # u0.07 , 2014/08/20, Carl, refine l1core dump region
+ # u0.06 , 2014/08/19, Carl, add constant value for l1core rector vector load view
+ # u0.05 , 2014/07/31, Carl, add constant value for dump l1core region
+ # ...
+ # m0.14 , 2013/12/24, Support is_with_AP
+ # m0.13 , 2013/06/28, Ignore MD5 in MDSYS option
+ # m0.12 , 2013/06/25, Support Copro related query and combined cmp_option+mkfile parsing and query
+ # m0.11 , 2013/05/28, Support to evaluate compiler option
+ # m0.10 , 2012/11/16, Support is_MAIN_CODE_NEED_GFH
+ # m0.09 , 2013/03/22, Support parsing informake.log
+ # m0.08 , 2012/01/14, Support basic query functions more flexible
+ # m0.07 , 2012/10/19, Support is_XBOOTING, is_HostedDongle, is_RNDISDongle
+ # m0.06 , 2012/09/18, Fix MakeFile mode parsing
+ # m0.05 , 2012/08/17, Support GetChip()
+ # m0.04 , 2012/08/06, Add more common functions and ParseDefinition()
+ # m0.03 , 2012/07/26, Support is_NonSPNOR()
+ # m0.02 , 2012/05/28, Support path and filename case sensitive on Linux
+ # v0.07 , 2012/05/13, Move is_NOR from sysgenUtility to here and support general query
+ # m0.01 , 2012/05/09, Provide GetCompiler()
+ # v0.06 , 2012/05/08, Copy parseFeatureOptionCondition
+ # and EvaluateFeatureOptionCondition from objListHelper.pm to here
+ # v0.05 , 2012/05/08, Query is_SmartPhone
+ # v0.04 , 2012/01/30, To provide CUSTOMER and MODE in %MAKEFILE_OPTIONS
+ # v0.03 , 2011/12/17, Fix parsing MakeFile
+ # v0.02 , 2011/11/01, Remove $$ to support Perl v5.12.*
+ # v0.01 , 2011/09/21, Initial revision
+
+#****************************************************************************
+# Global variable
+#****************************************************************************
+my $g_MAKEFILE_href = undef;
+#****************************************************************************
+# oo >>> Finished
+#****************************************************************************
+return 1;
+
+sub PreProcess
+{
+ my ($MAKE_FILE, $mk_href, $INFOMAKE, $CmplOpt_href, $RelInfo_href, $bDie) = @_;
+ my $bResult = 1;
+ if(!BuildInfo::Parse_InfoMakeLog($INFOMAKE, $CmplOpt_href, $RelInfo_href))
+ {
+ $bResult = 0;
+ FileInfoParser_die("Parse infomake.log failed")if($bDie);
+ }
+ if(!FileInfo::Parse_MAKEFILE($MAKE_FILE, $mk_href))
+ {
+ $bResult = 0;
+ FileInfoParser_die("Parse MakeFile failed")if($bDie);
+ }
+ return $bResult;
+}
+
+#****************************************************************************
+# subroutine: Parse_MAKEFILE
+# input: 1. MAKEFILE path
+# 2. a Hash to contain MAKEFILE information.
+# output: 1=Parse successfully, 0 or die= Parse failed.
+# sample code: my %MAKEFILE_OPTIONS;
+# &FileInfo::Parse_MAKEFILE($MAKEFILE_Path, \%MAKEFILE_OPTIONS);
+#****************************************************************************
+
+sub Parse_MAKEFILE
+{
+ my ($strMAKEFILE_Path, $Info_href) = @_;
+ my $bResult = 0;
+ if(-e $strMAKEFILE_Path)
+ {
+ open (FILE_HANDLE, $strMAKEFILE_Path) or &FileInfoParser_die("Cannot open $strMAKEFILE_Path\n", __FILE__, __LINE__);
+ while (<FILE_HANDLE>)
+ {
+ if ((/^([^\#]*)\#?.*/) && ($1 =~ /^(\w+)\s*=\s*(.*\S)\s*$/))
+ {
+ my $keyname = lc($1);
+ #defined($Info_href->{$keyname}) && warn "$1 redefined in $strMAKEFILE_Path!\n";
+ $Info_href->{$keyname} = uc($2);
+ $keyname = uc($1);
+ #defined($Info_href->{$keyname}) && warn "$1 redefined in $strMAKEFILE_Path!\n";
+ $Info_href->{$keyname} = uc($2);
+ $bResult = 1;
+ }
+ }
+ close FILE_HANDLE;
+ if ($strMAKEFILE_Path =~ /(\w+)_(\w+)\((\w+)\).mak/i)
+ {
+ $Info_href->{'MODE'} = uc($3);
+ $Info_href->{'mode'} = uc($3);
+ }
+ $g_MAKEFILE_href = $Info_href;
+ }
+ else
+ {
+ &FileInfoParser_die("$strMAKEFILE_Path: NOT exist!", __FILE__, __LINE__);
+ }
+ return $bResult;
+}
+
+sub GetMakeFileRef
+{
+ my ($strMAKEFILE_Path) = @_;
+ if(!defined $g_MAKEFILE_href)
+ {
+ my %MakeFileOption;
+ &Parse_MAKEFILE($strMAKEFILE_Path, \%MakeFileOption);
+ }
+ return $g_MAKEFILE_href;
+}
+sub is
+{
+ my ($strKey, $strValue, $MakeFile_ref) = @_;
+ $MakeFile_ref = $g_MAKEFILE_href if (!defined $MakeFile_ref);
+ &NoMakeFile_die($MakeFile_ref, __FILE__, __LINE__);
+ my $bEqual = 0;
+ if(exists $MakeFile_ref->{uc($strKey)} and uc($MakeFile_ref->{uc($strKey)}) eq uc($strValue))
+ {
+ $bEqual = 1;
+ }
+ return $bEqual;
+}
+sub find
+{
+ my ($strKey, $strValue, $MakeFile_ref) = @_;
+ $MakeFile_ref = $g_MAKEFILE_href if (!defined $MakeFile_ref);
+ &NoMakeFile_die($MakeFile_ref, __FILE__, __LINE__);
+ my $bFound = 0;
+ if(exists $MakeFile_ref->{uc($strKey)} and $MakeFile_ref->{uc($strKey)} =~ /$strValue/)
+ {
+ $bFound = 1;
+ }
+ return $bFound;
+}
+sub isnot
+{
+ my ($strKey, $strValue, $MakeFile_ref) = @_;
+ $MakeFile_ref = $g_MAKEFILE_href if (!defined $MakeFile_ref);
+ &NoMakeFile_die($MakeFile_ref, __FILE__, __LINE__);
+ my $bNotEqual = 0;
+ if(exists $MakeFile_ref->{uc($strKey)} and uc($MakeFile_ref->{uc($strKey)}) ne uc($strValue))
+ { #exist but not equal
+ $bNotEqual = 1;
+ }
+ return $bNotEqual;
+}
+sub get
+{
+ my ($strKey, $MakeFile_ref) = @_;
+ $MakeFile_ref = $g_MAKEFILE_href if (!defined $MakeFile_ref);
+ &NoMakeFile_die($MakeFile_ref, __FILE__, __LINE__);
+ my $Value = undef;
+ if(exists $MakeFile_ref->{uc($strKey)})
+ {
+ $Value = $MakeFile_ref->{uc($strKey)};
+ }
+ elsif(exists $MakeFile_ref->{$strKey})
+ {
+ $Value = $MakeFile_ref->{$strKey};
+ }
+ return $Value;
+}
+sub ParseDefinition
+{
+ my ($strFilePath, $Hash_ref, $bAllowDuplicated) = @_;
+ my $content = &CommonUtil::GetFileContent($strFilePath);
+ #strip comments
+ $content =~ s/\/\/(.+)//g;
+ $content =~s#/\*[^*]*\*+([^/*][^*]*\*+)*/|([^/"']*("[^"\\]*(\\[\d\D][^"\\]*)*"[^/"']*|'[^'\\]*(\\[\d\D][^'\\]*)*'[^/"']*|/+[^*/][^/"']*)*)#$2#g;
+
+ my @lines = split(/\n|\r/, $content);
+ my $nDuplicatedIndex=0;
+ foreach my $line (@lines)
+ {
+ if ($line =~ /#define\s+(\w+)\s+\((.*)\)\s*$/ || $line =~ /#define\s+(\w+)\s+(\S*)\s*$/)
+ {
+ my $option = $1;
+ my $value = $2;
+ &FileInfoParser_die("$strFilePath: $option redefined in $strFilePath!", __FILE__, __LINE__)
+ if (!$bAllowDuplicated and defined($Hash_ref->{$option}));
+ if (!defined $value)
+ {
+ $Hash_ref->{$option} = 'TRUE';
+ $Hash_ref->{uc($option)} = 'TRUE';
+ $Hash_ref->{lc($option)} = 'TRUE';
+ }
+ else
+ {
+ $Hash_ref->{$option} = $value;
+ $Hash_ref->{uc($option)} = $value;
+ $Hash_ref->{lc($option)} = $value;
+ }
+ }
+ }
+ close (FILE_HANDLE);
+}
+
+
+#****************************************************************************
+# subroutine: is_SmartPhone - Query if it belongs smart phone project
+# Input: x
+# Output: 1=it's SmartPhone, others=not SmartPhone
+#****************************************************************************
+sub is_SmartPhone
+{
+ my ($MakeFile_ref) = @_;
+ $MakeFile_ref = $g_MAKEFILE_href if (!defined $MakeFile_ref);
+ &NoMakeFile_die($MakeFile_ref, __FILE__, __LINE__);
+ my $bIsSmartPhone = 0;
+ if( exists $MakeFile_ref->{SMART_PHONE_CORE} and $MakeFile_ref->{SMART_PHONE_CORE} ne "NONE" ) #NONE = feature phone
+ {
+ $bIsSmartPhone = 1;
+ }
+ return $bIsSmartPhone;
+}
+
+#****************************************************************************
+# subroutine: is_with_AP - Query if it is paired with AP
+# Input: x
+# Output: 1=it's paired with AP, others=other combination
+#****************************************************************************
+sub is_with_AP
+{
+ my ($MakeFile_ref) = @_;
+ $MakeFile_ref = $g_MAKEFILE_href if (!defined $MakeFile_ref);
+ &NoMakeFile_die($MakeFile_ref, __FILE__, __LINE__);
+ my $bIsWithAP = 0;
+ if( exists $MakeFile_ref->{SMART_PHONE_CORE} and $MakeFile_ref->{SMART_PHONE_CORE} =~/ANDROID_MODEM/i )
+ {
+ $bIsWithAP = 1;
+ }
+ return $bIsWithAP;
+}
+
+
+#****************************************************************************
+# subroutine: is_NOR - Query if it's NOR flash
+# Input: \%MAKEFILE_OPTION
+# Output: 0=not NOR, 1=NOR
+#****************************************************************************
+sub is_NOR
+{
+ my ($MAKEFILE_ref) = @_;
+ $MAKEFILE_ref = $g_MAKEFILE_href if (!defined $MAKEFILE_ref);
+ &NoMakeFile_die($MAKEFILE_ref, __FILE__, __LINE__);
+ my $bNOR = 1; # 0=not NOR, 1= NOR
+ if((exists $MAKEFILE_ref->{'nand_flash_booting'} and $MAKEFILE_ref->{'nand_flash_booting'} ne 'NONE')
+ or (exists $MAKEFILE_ref->{'emmc_booting'} and $MAKEFILE_ref->{'emmc_booting'} ne 'NONE'))
+ {
+ $bNOR = 0;
+ }
+ return $bNOR;
+}
+#****************************************************************************
+# subroutine: is_NonSPNOR - Query if it's not nand flash and not smart_phone project
+# Input: \%MAKEFILE_OPTION
+# Output: 0=not NOR, 1=NOR
+#****************************************************************************
+sub is_NonSPNOR
+{
+ my ($MAKEFILE_ref) = @_;
+ return (&is_NOR($MAKEFILE_ref) and !&is_SmartPhone($MAKEFILE_ref));
+}
+
+#****************************************************************************
+# subroutine: is_BuiltWithCopro - Query if it's built with copro
+# Input: \%MAKEFILE_OPTION, \%Compile_OPTION
+# Output: 0=not building with copro, 1=building with containing copro now
+#****************************************************************************
+sub is_BuiltWithCopro
+{
+ my ($MAKEFILE_ref, $CMPL_href) = @_;
+ my $bBuiltWithCopro = 0;
+ $bBuiltWithCopro = 1 if(is("MD_OFFLOAD_COPRO", "ARM7EJ-S", $MAKEFILE_ref)
+ and !BuildInfo::exist(BuildOPT::CMPL, "NEED_BUILD_MD_OFFLOAD_COPRO", $CMPL_href));
+ return $bBuiltWithCopro;
+}
+#****************************************************************************
+# subroutine: is_Copro - Query if it's COPRO
+# Input: \%MAKEFILE_OPTION, \%Compile_OPTION
+# Output: 0=not copro, 1=it's copro
+#****************************************************************************
+sub is_Copro
+{
+ my ($MAKEFILE_ref, $CMPL_href) = @_;
+ my $bCopro = 0;
+ $bCopro = 1 if(is("MD_OFFLOAD_COPRO", "ARM7EJ-S", $MAKEFILE_ref)
+ and BuildInfo::exist(BuildOPT::CMPL, "NEED_BUILD_MD_OFFLOAD_COPRO", $CMPL_href));
+ return $bCopro;
+}
+
+#****************************************************************************
+# subroutine: is_MAIN_CODE_NEED_GFH - Query if it's MAIN_CODE_NEED_GFH:
+# SMART_PHONE_CORE != NONE && X_BOOTING==NONE => MAIN_CODE_NEED_GFH = FALSE
+# Input: \%MAKEFILE_OPTION
+# Output: 0=no GFH, 1=having GFH
+#****************************************************************************
+sub is_MAIN_CODE_NEED_GFH
+{
+ my ($bb, $MAKEFILE_ref) = @_;
+ $MAKEFILE_ref = $g_MAKEFILE_href if (!defined $MAKEFILE_ref);
+ &NoMakeFile_die($MAKEFILE_ref, __FILE__, __LINE__);
+ my $bNEED_GFH = 0;
+ if(&sysUtil::is_sv5($bb))
+ {
+ $bNEED_GFH = 1;
+ if(&is_SmartPhone($MAKEFILE_ref) && &is("X_BOOTING", "NONE", $MAKEFILE_ref) )
+ {
+ $bNEED_GFH = 0;
+ }
+ }
+ return $bNEED_GFH;
+}
+
+#****************************************************************************
+# subroutine: is_XBOOTING - Query if it's X_BOOTING: X_BOOTING != NONE
+# Input: \%MAKEFILE_OPTION
+# Output: 0=not X BOOTING, 1=X BOOTING
+#****************************************************************************
+sub is_XBOOTING
+{
+ my ($MAKEFILE_ref) = @_;
+ $MAKEFILE_ref = $g_MAKEFILE_href if (!defined $MAKEFILE_ref);
+ &NoMakeFile_die($MAKEFILE_ref, __FILE__, __LINE__);
+ my $bX = 0;
+ $bX = 1 if(&isnot("X_BOOTING", "NONE"));
+ return $bX;
+}
+
+#****************************************************************************
+# subroutine: is_HostedDongle - Query if it's HostedDongle
+# SMART_PHONE_CORE=MODEM_HOST and X_BOOTING=NONE
+# Input: \%MAKEFILE_OPTION
+# Output: 0=not Hosted dongle, 1=Hosted dongle
+#****************************************************************************
+sub is_HostedDongle
+{
+ my ($MAKEFILE_ref) = @_;
+ $MAKEFILE_ref = $g_MAKEFILE_href if (!defined $MAKEFILE_ref);
+ &NoMakeFile_die($MAKEFILE_ref, __FILE__, __LINE__);
+ my $bX = 0;
+ $bX = 1 if(&is("SMART_PHONE_CORE", "MODEM_HOST") and !&is_XBOOTING());
+ return $bX;
+}
+
+
+#****************************************************************************
+# subroutine: is_RNDISDongle - Query if it's RNDIS Dongle
+# (is smartphone but SMART_PHONE_CORE != MODEM_HOST) and X_BOOTING=NONE
+# Input: \%MAKEFILE_OPTION
+# Output: 0=not RNDIS, 1=RNDIS
+#****************************************************************************
+sub is_RNDISDongle
+{
+ my ($MAKEFILE_ref) = @_;
+ $MAKEFILE_ref = $g_MAKEFILE_href if (!defined $MAKEFILE_ref);
+ &NoMakeFile_die($MAKEFILE_ref, __FILE__, __LINE__);
+ my $bX = 0;
+ $bX = 1 if(&is_SmartPhone() and !&is_XBOOTING() and !is_HostedDongle());
+ return $bX;
+}
+
+#****************************************************************************
+# subroutine: GetCompiler()
+# Input: \%MAKEFILE_OPTION
+# Output: Should be "GCC" or "RVCT" in string
+#****************************************************************************
+sub GetCompiler
+{
+ my ($MakeFile_ref) = @_;
+ $MakeFile_ref = $g_MAKEFILE_href if (!defined $MakeFile_ref);
+ &NoMakeFile_die($MakeFile_ref, __FILE__, __LINE__);
+ my $strCompiler = undef;
+ $strCompiler = uc($MakeFile_ref->{COMPILER}) if(exists $MakeFile_ref->{COMPILER});
+ &FileInfoParser_die("Unsupported ToolChain!\n", __FILE__, __LINE__) if(($strCompiler ne "GCC") and ($strCompiler ne "RVCT"));
+ return $strCompiler;
+}
+#****************************************************************************
+# subroutine: GetChip()
+# Input: \%MAKEFILE_OPTION
+# \%COMPILER_OPTION
+# Output: string (e.g. MT6280 or MT6280_XX)
+#****************************************************************************
+sub GetChip
+{
+ my ($MakeFile_ref, $CMPL_href) = @_;
+ $MakeFile_ref = $g_MAKEFILE_href if (!defined $MakeFile_ref);
+ &NoMakeFile_die($MakeFile_ref, __FILE__, __LINE__);
+ my $strChip = undef;
+ $strChip = uc($MakeFile_ref->{PLATFORM}) if(exists $MakeFile_ref->{PLATFORM});
+ $strChip .= "_".uc($MakeFile_ref->{MDSYS}) if(exists $MakeFile_ref->{MDSYS} and $MakeFile_ref->{MDSYS} !~/none|md5/i);
+ $strChip .= "_COPRO" if(is_Copro($MakeFile_ref, $CMPL_href));
+ return $strChip;
+}
+
+#****************************************************************************
+# subroutine: GetSharedMemorySize
+# description: return shared region size
+# input: N/A
+# output: size of SHARED_REGION_SIZE in ~copro_info.tmp or default value (inculde dsp tx/rx sections)
+# need init: No
+#****************************************************************************
+sub GetSharedMemorySize
+{
+ my $nSharedRegionEnd = &FileInfo::get(SHARED_REGION_SIZE);
+ return ( 0==$nSharedRegionEnd ? &sysUtil::GetDefaultSharedMemorySize(&GetChip()) : $nSharedRegionEnd );
+}
+
+#****************************************************************************
+# subroutine: EvaluateFeatureOptionCondition
+# description: Evaluate the feature option condition.
+# input: Feature option condition(string), makefile options hash ref
+# output: 1: true, 0: false
+# need init: No
+#****************************************************************************
+sub EvaluateFeatureOptionCondition
+{
+ my $condition = shift;
+ my $makefileOptionsRef = shift;
+
+ my @expressionTree;
+ my @stack;
+
+ # Transform the condition to expression tree in postfix form
+ &parseFeatureOptionCondition($condition, \@expressionTree);
+
+ # Evaluate the expression tree
+ foreach my $token (@expressionTree)
+ {
+ if ($token eq "&&" or $token eq "||")
+ {
+ my $second = pop(@stack);
+ my $first = pop(@stack);
+ push (@stack, eval "$first $token $second");
+ }
+ elsif ($token eq "=")
+ {
+ my $second = pop(@stack);
+ my $first = pop(@stack);
+ my $value = $makefileOptionsRef->{$first};
+ $value = "" unless defined $value;
+ if ($value eq $second)
+ {
+ push (@stack, 1);
+ }
+ else
+ {
+ push (@stack, 0);
+ }
+ }
+ elsif ($token eq "!")
+ {
+ my $first = pop(@stack);
+ if ($first == 1)
+ {
+ push (@stack, 0);
+ }
+ else
+ {
+ push (@stack, 1);
+ }
+ }
+ else
+ {
+ push @stack, $token;
+ }
+ }
+ &FileInfoParser_die("Incorrect syntax of feature option condition \"$condition\"", __FILE__, __LINE__)
+ unless (1 == @stack);
+
+ return $stack[0];
+}
+
+#****************************************************************************
+# subroutine: parseFeatureOptionCondition
+# description: Parse the feature option condition to postfix form.
+# input: Feature option condition, expression tree ref
+# output: Expression tree
+# need init: No
+#****************************************************************************
+sub parseFeatureOptionCondition
+{
+ my $condition = shift;
+ my $expressionTreeRef = shift;
+ my $conditionNoSpace = $condition;
+ $conditionNoSpace =~ s/ //g;
+
+ my @tokens = split(/(=|\(|\)|&&|\|\||!)/, $conditionNoSpace);
+ my @stack;
+
+ # For error checking
+ my $parenthesis = 0;
+ my $operand = 0;
+ my $operator = 0;
+
+ foreach my $token (@tokens)
+ {
+ if ($token eq "")
+ {
+ # Skip empty token
+ next;
+ }
+ elsif ($token eq "(")
+ {
+ push @stack, $token;
+ ++$parenthesis;
+ }
+ elsif ($token eq ")")
+ {
+ &FileInfoParser_die("Incorrect syntax of feature option condition \"$condition\"", __FILE__, __LINE__)
+ unless (0 < $parenthesis);
+ my $temp = pop(@stack);
+
+ &FileInfoParser_die("Incorrect syntax of feature option condition \"$condition\"", __FILE__, __LINE__)
+ if ($temp eq "(");
+
+ do
+ {
+ push @$expressionTreeRef, $temp;
+ $temp = pop(@stack);
+ } while ($temp ne "(");
+
+ --$parenthesis;
+ }
+ elsif ($token eq "=" or $token eq "&&" or $token eq "||" or $token eq "!")
+ {
+ my $needLoop = 0;
+
+ do
+ {
+ if (0 == scalar(@stack) or $stack[-1] eq "(")
+ {
+ # Stack is empty or stack top eqals to (
+ push @stack, $token;
+ $needLoop = 0;
+ }
+ elsif (0 < compareFeatureOptionOperator($stack[-1], $token))
+ {
+ # Stack top has higher priority than current token
+ push @stack, $token;
+ $needLoop = 0;
+ }
+ else
+ {
+ push @$expressionTreeRef, pop(@stack);
+ $needLoop = 1;
+ }
+ } while ($needLoop);
+
+ $operator += 1 unless ($token eq "!");
+ }
+ elsif ($token =~ /\w+/)
+ {
+ # Operand
+ push @$expressionTreeRef, $token;
+ $operand += 1;
+ }
+ else
+ {
+ &FileInfoParser_die("Incorrect syntax of feature option condition \"$condition\"", __FILE__, __LINE__);
+ }
+ }
+
+ &FileInfoParser_die("Incorrect syntax of feature option condition \"$condition\"", __FILE__, __LINE__)
+ unless ($operator == ($operand - 1) and 0 == $parenthesis);
+
+ push @$expressionTreeRef, reverse(@stack);
+}
+
+sub compareFeatureOptionOperator
+{
+ my $first = shift;
+ my $second = shift;
+ my %operatorToNumber = ("=" => 0, "!" => 1, "&&" => 2, "||" => 2);
+
+ return $operatorToNumber{$first} <=> $operatorToNumber{$second};
+}
+
+#****************************************************************************
+# subroutine: FileInfoParser_die
+# sample code: (message, __FILE__, __LINE__)
+# input: $error_msg, $file, $line_no
+#****************************************************************************
+sub FileInfoParser_die
+{
+ my ($error_msg, $file, $line_no) = @_;
+ my $pack_name = undef;
+ if(!defined $file or !defined $line_no)
+ {
+ ($pack_name, $file, $line_no) = caller;
+ }
+ &sysUtil::error_handler($error_msg, $file, $line_no, 'ProjectMakeFileParser');
+}
+sub NoMakeFile_die
+{
+ my ($MAKEFILE_ref, $file, $line_no) = @_;
+ &FileInfoParser_die("Please parse project makefile by FileInfo::Parse_MAKEFILE() before using it.", $file, $line_no)
+ if(!defined $MAKEFILE_ref);
+}
+
+package BuildInfo;
+#****************************************************************************
+# Global variable
+#****************************************************************************
+my $g_CmplOpt_href = undef; # compiler option
+my $g_RelInfo_href = undef; # release info
+#****************************************************************************
+# Subroutine
+#****************************************************************************
+#****************************************************************************
+# subroutine: Parse_InfoMakeLog
+# input: 1. Infomake.log path
+# 2. a Hash reference to contain CompilerOption information.
+# 3. a Hash reference to contain Release information.
+# output: 1=Parse successfully, 0 or die= Parse failed.
+# sample code: my %CmplOption;
+# my %RelOption;
+# BuildInfo::Parse_InfoMakeLog($infomake_path, \%CmplOption, \%RelOption);
+#****************************************************************************
+sub Parse_InfoMakeLog
+{
+ my ($strInfomake_Path, $CmplOpt_href, $RelInfo_href) = @_;
+ my $bResult = 0;
+ if(-e $strInfomake_Path)
+ {
+ open (FILE_HANDLE, $strInfomake_Path) or BuildInfo_die("Cannot open $strInfomake_Path\n", __FILE__, __LINE__);
+ while (<FILE_HANDLE>)
+ {
+ if(/^(\S+)\s*\=\s*(.*)/)
+ {
+ my $key = $1;
+ my $value = $2;
+ if($key =~ /COM_DEFS/)
+ {
+ _ParseCMPLOpt($value, $CmplOpt_href);
+ }
+ else
+ {
+ $RelInfo_href->{$1} = $2;
+ $RelInfo_href->{lc($1)} = $2;
+ }
+ }
+ }
+ close FILE_HANDLE;
+ $g_CmplOpt_href = $CmplOpt_href;
+ $g_RelInfo_href = $RelInfo_href;
+ $bResult = 1;
+ }
+ else
+ {
+ BuildInfo_die("$strInfomake_Path: NOT exist!", __FILE__, __LINE__);
+ }
+ return $bResult;
+}
+
+sub _ParseCMPLOpt
+{
+ my ($strOptions, $CmplOpt_href) = @_;
+ my @ComlOpt = split(/\s/,$strOptions);
+ foreach my $Opt(@ComlOpt)
+ {
+ $Opt =~ s/\s\n\r//;
+ next if($Opt eq "");
+ my $strkey = $Opt;
+ my $strvalue = undef;
+ if($Opt =~ /(.*)=(.*)/)
+ {
+ $strkey = $1;
+ $strvalue = $2;
+ }
+ $CmplOpt_href->{$strkey} = $strvalue;
+ $CmplOpt_href->{lc($strkey)} = $strvalue;
+ }
+}
+sub GetCmplOptRef
+{
+ my ($strInfoMake_Path) = @_;
+ if(!defined $g_CmplOpt_href)
+ {
+ my %CmplOption;
+ my %RelOption;
+ &Parse_InfoMakeLog($strInfoMake_Path, \%CmplOption, \%RelOption);
+ }
+ return $g_CmplOpt_href;
+}
+sub GetRelOptRef
+{
+ my ($strInfoMake_Path) = @_;
+ if(!defined $g_RelInfo_href)
+ {
+ my %CmplOption;
+ my %RelOption;
+ &Parse_InfoMakeLog($strInfoMake_Path, \%CmplOption, \%RelOption);
+ }
+ return $g_RelInfo_href;
+}
+#****************************************************************************
+# subroutine: exist
+# Input: $nOption: BuildOPT::CMPL or BuildOPT::REL
+# Output: In compiler option, if $strKey exists in compiler option, it will return 1,
+# otherwises returns 0
+# In release information, it's usually meaningless to see if $strKey exists
+#****************************************************************************
+sub exist
+{
+ my ($nOption, $strKey, $href) = @_;
+ if (!defined $href)
+ {
+ $href = $g_CmplOpt_href if($nOption == BuildOPT::CMPL);
+ $href = $g_RelInfo_href if($nOption == BuildOPT::REL);
+ }
+ &NoInfoMake_die($href, __FILE__, __LINE__);
+ my $bExist = 0;
+ if(exists $href->{$strKey})
+ {
+ $bExist = 1;
+ }
+ return $bExist;
+}
+
+#****************************************************************************
+# subroutine: EvaluateCompileOption
+# description: Evaluate the compile option
+# input: Compile option condition(string), compile options hash ref
+# output: 1: true, 0: false
+# need init: No
+#****************************************************************************
+sub EvaluateCompileOption
+{
+ my ($condition, $CmpOption_href) = @_;
+ $CmpOption_href = $g_CmplOpt_href if(!defined $CmpOption_href);
+ &NoInfoMake_die($CmpOption_href, __FILE__, __LINE__);
+
+ # Transform the condition to expression tree in postfix form
+ my @expressionTree;
+ _parseCompileOptionCondition($condition, \@expressionTree);
+
+ # Evaluate the expression tree
+ my @stack;
+ foreach my $token (@expressionTree)
+ {
+ if ($token eq "&&" or $token eq "||")
+ {
+ my $second = pop(@stack);
+ my $first = pop(@stack);
+ $first = exist(BuildOPT::CMPL, $first) if($first =~ /\D+/);
+ $second = exist(BuildOPT::CMPL, $second) if($second =~ /\D+/);
+ push (@stack, eval "$first $token $second");
+ }
+ elsif ($token eq "=")
+ {
+ my $second = pop(@stack);
+ my $first = pop(@stack);
+ my $value = $CmpOption_href->{$first};
+ $value = "" unless defined $value;
+ if ($value eq $second)
+ {
+ push (@stack, 1);
+ }
+ else
+ {
+ push (@stack, 0);
+ }
+ }
+ elsif ($token eq "!")
+ {
+ my $first = pop(@stack);
+ $first = exist(BuildOPT::CMPL, $first) if($first =~ /\D+/);
+ if ($first == 1)
+ {
+ push (@stack, 0);
+ }
+ else
+ {
+ push (@stack, 1);
+ }
+ }
+ else
+ {
+ push @stack, $token;
+ }
+ }
+
+ &BuildInfo_die("Incorrect syntax of compile option condition \"$condition\"", __FILE__, __LINE__)
+ unless (1 == @stack);
+ # for single compile option
+ my $ZeroString = "0"; $ZeroString = sprintf("%d", $ZeroString); # convert
+ my $OneString = "1"; $OneString = sprintf("%d", $OneString); # convert
+ $stack[0] = (exist(BuildOPT::CMPL, $stack[0])?1:0) if($ZeroString ne $stack[0] && $OneString ne $stack[0]) ;
+
+ #use above safer syntax
+ #$stack[0] = (exist(BuildOPT::CMPL, $stack[0])?1:0) if("0" ne $stack[0] && "1" ne $stack[0]) ;
+
+ return $stack[0];
+
+}
+#****************************************************************************
+# subroutine: _parseCompileOptionCondition
+# description: Parse the feature option condition to postfix form.
+# input: Feature option condition, expression tree ref
+# output: Expression tree
+# need init: No
+#****************************************************************************
+sub _parseCompileOptionCondition
+{
+ my ($condition, $expressionTreeRef) = @_;
+ my $conditionNoSpace = $condition;
+ $conditionNoSpace =~ s/ //g;
+
+ my @tokens = split(/(=|\(|\)|&&|\|\||!)/, $conditionNoSpace);
+ my @stack;
+
+ # For error checking
+ my $parenthesis = 0;
+ my $operand = 0;
+ my $operator = 0;
+
+ foreach my $token (@tokens)
+ {
+ if ($token eq "")
+ {
+ # Skip empty token
+ next;
+ }
+ elsif ($token eq "(")
+ {
+ push @stack, $token;
+ ++$parenthesis;
+ }
+ elsif ($token eq ")")
+ {
+ &BuildInfo_die("Incorrect syntax of compile option condition \"$condition\"", __FILE__, __LINE__)
+ unless (0 < $parenthesis);
+ my $temp = pop(@stack);
+
+ while ($temp ne "(")
+ {
+ push @$expressionTreeRef, $temp;
+ $temp = pop(@stack);
+ }
+
+ --$parenthesis;
+ }
+ elsif ($token eq "=" or $token eq "&&" or $token eq "||" or $token eq "!")
+ {
+ my $needLoop = 0;
+
+ do
+ {
+ if (0 == scalar(@stack) or $stack[-1] eq "(")
+ {
+ # Stack is empty or stack top eqals to (
+ push @stack, $token;
+ $needLoop = 0;
+ }
+ elsif (0 < _compareCompileOptionOperator($stack[-1], $token))
+ {
+ # Stack top has higher priority than current token
+ push @stack, $token;
+ $needLoop = 0;
+ }
+ else
+ {
+ push @$expressionTreeRef, pop(@stack);
+ $needLoop = 1;
+ }
+ } while ($needLoop);
+
+ $operator += 1 unless ($token eq "!");
+ }
+ elsif ($token =~ /\w+/)
+ {
+ # Operand
+ push @$expressionTreeRef, $token;
+ $operand += 1;
+ }
+ else
+ {
+ &BuildInfo_die("Incorrect syntax of compile option condition \"$condition\"", __FILE__, __LINE__);
+ }
+ }
+
+ &BuildInfo_die("Incorrect syntax of compile option condition \"$condition\"", __FILE__, __LINE__)
+ unless ($operator == ($operand - 1) and 0 == $parenthesis);
+
+ push @$expressionTreeRef, reverse(@stack);
+}
+
+sub _compareCompileOptionOperator
+{
+ my $first = shift;
+ my $second = shift;
+ my %operatorToNumber = ("=" => 0, "!" => 1, "&&" => 2, "||" => 2);
+
+ return $operatorToNumber{$first} <=> $operatorToNumber{$second};
+}
+
+#****************************************************************************
+# subroutine: get
+# Input: $nOption: BuildOPT::CMPL or BuildOPT::REL
+# Output: In compiler option, if it's ooo=xxx, it returns xxx
+# otherwises, it returns undef
+# In release information, it returns value directly
+#****************************************************************************
+sub get
+{
+ my ($nOption, $strKey, $href) = @_;
+ if (!defined $href)
+ {
+ $href = $g_CmplOpt_href if($nOption == BuildOPT::CMPL);
+ $href = $g_RelInfo_href if($nOption == BuildOPT::REL);
+ }
+ &NoInfoMake_die($href, __FILE__, __LINE__);
+ my $strValue = undef;
+ if(exists $href->{$strKey})
+ {
+ $strValue = $href->{$strKey};
+ }
+ return $strValue;
+}
+#****************************************************************************
+# subroutine: is
+# Input: $nOption: BuildOPT::CMPL or BuildOPT::REL
+# Output: 1=$href->{$strKey} equals to $strValue, 0=not equal
+#****************************************************************************
+sub is
+{
+ my ($nOption, $strKey, $strValue, $href) = @_;
+ if (!defined $href)
+ {
+ $href = $g_CmplOpt_href if($nOption == BuildOPT::CMPL);
+ $href = $g_RelInfo_href if($nOption == BuildOPT::REL);
+ }
+ &NoInfoMake_die($href, __FILE__, __LINE__);
+ my $bResult = 0;
+ if(exists $href->{$strKey})
+ {
+ $bResult =1 if(lc($strValue) eq lc($href->{$strKey}));
+ }
+ return $bResult;
+}
+#****************************************************************************
+# subroutine: BuildInfo_die
+# sample code: (message, __FILE__, __LINE__)
+# input: $error_msg, $file, $line_no
+#****************************************************************************
+sub BuildInfo_die
+{
+ my ($error_msg, $file, $line_no) = @_;
+ &sysUtil::error_handler($error_msg, $file, $line_no, 'BuildInfoParser');
+}
+
+sub NoInfoMake_die
+{
+ my ($temp_ref, $file, $line_no) = @_;
+ &BuildInfo_die("Please parse infomake.log by BuildInfo::ParseInfoMakeLog() before using it.", $file, $line_no)
+ if(!defined $temp_ref);
+}