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