rjw | 6c1fd8f | 2022-11-30 14:33:01 +0800 | [diff] [blame] | 1 | #!/usr/bin/perl |
| 2 | # |
| 3 | # Copyright Statement: |
| 4 | # -------------------- |
| 5 | # This software is protected by Copyright and the information contained |
| 6 | # herein is confidential. The software may not be copied and the information |
| 7 | # contained herein may not be used or disclosed except with the written |
| 8 | # permission of MediaTek Inc. (C) 2006 |
| 9 | # |
| 10 | # BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES |
| 11 | # THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") |
| 12 | # RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON |
| 13 | # AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, |
| 14 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF |
| 15 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. |
| 16 | # NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE |
| 17 | # SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR |
| 18 | # SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH |
| 19 | # THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO |
| 20 | # NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S |
| 21 | # SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. |
| 22 | # |
| 23 | # BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE |
| 24 | # LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, |
| 25 | # AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, |
| 26 | # OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO |
| 27 | # MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. |
| 28 | # |
| 29 | # THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE |
| 30 | # WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF |
| 31 | # LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND |
| 32 | # RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER |
| 33 | # THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC). |
| 34 | # |
| 35 | #***************************************************************************** |
| 36 | #* |
| 37 | #* Filename: |
| 38 | #* --------- |
| 39 | #* FileInfoParser.pm |
| 40 | #* |
| 41 | #* Project: |
| 42 | #* -------- |
| 43 | #* |
| 44 | #* |
| 45 | #* Description: |
| 46 | #* ------------ |
| 47 | #* This module collects the subroutines for common utility. |
| 48 | #* |
| 49 | #* |
| 50 | #* Author: |
| 51 | #* ------- |
| 52 | #* Carl Kao (mtk08237) |
| 53 | #* |
| 54 | #****************************************************************************/ |
| 55 | use strict; |
| 56 | #use warnings; |
| 57 | BEGIN { push @INC, './pcore/tools/' } # add additional library path |
| 58 | #-------------------------------------------------------------------------------------------------------------- |
| 59 | package BuildOPT; |
| 60 | #**************************************************************************** |
| 61 | # Constant |
| 62 | #**************************************************************************** |
| 63 | use constant CMPL => 0; |
| 64 | use constant REL => 1; |
| 65 | #-------------------------------------------------------------------------------------------------------------- |
| 66 | package FileInfo; |
| 67 | use constant SHARED_REGION_SIZE => "SHARED_REGION_SIZE"; |
| 68 | use constant PCORE_LV_SIZE => "PCORE_LV_SIZE"; |
| 69 | |
| 70 | use sysGenUtility; #pm file name without case sensitivity |
| 71 | use CommonUtility; |
| 72 | #**************************************************************************** |
| 73 | # Constants |
| 74 | #**************************************************************************** |
| 75 | my $FILEINFOPARSER_VERNO = " a0.01"; |
| 76 | # a0.01 , 2016/11/21, Tero, Mode parsing fixed |
| 77 | # u0.18 , 2016/08/01, Tero, L1Core and Copro info removed |
| 78 | # u0.17 , 2016/01/31, Tero, Fix compiler option parsing bug in EvaluateCompileOption() |
| 79 | # u0.16 , 2015/07/03, Carl, Call GetDefaultSharedMemorySize to get default shared memory size |
| 80 | # u0.15 , 2015/06/23, Carl, Refine GetSharedMemorySize. It includes dsp tx/rx section now |
| 81 | # u0.14 , 2015/06/22, Carl, Decrease shared region size (in 1st linking time) from 96 MB to 80 MB |
| 82 | # u0.13 , 2015/06/22, Carl, Decrease shared region size (in 1st linking time) from 112 MB to 96 MB |
| 83 | # u0.12 , 2015/05/19, Carl, Increase shared region size (in 1st linking time) from 80 MB to 112 MB |
| 84 | # u0.11 , 2015/04/17, Carl, Increase shared region size (in 1st linking time) from 48 MB to 80 MB |
| 85 | # u0.10 , 2015/02/06, Carl, disable isSupportedToAdjustLoadView for ESL COSIM |
| 86 | # u0.09 , 2015/01/06, Carl, lds refinement: 1) auto adjust shared region size, 2) reserve pcore, l1core SWLA space |
| 87 | # u0.08 , 2014/22/22, Carl, Support L2SRAM section (in L1CORE) |
| 88 | # u0.07 , 2014/08/20, Carl, refine l1core dump region |
| 89 | # u0.06 , 2014/08/19, Carl, add constant value for l1core rector vector load view |
| 90 | # u0.05 , 2014/07/31, Carl, add constant value for dump l1core region |
| 91 | # ... |
| 92 | # m0.14 , 2013/12/24, Support is_with_AP |
| 93 | # m0.13 , 2013/06/28, Ignore MD5 in MDSYS option |
| 94 | # m0.12 , 2013/06/25, Support Copro related query and combined cmp_option+mkfile parsing and query |
| 95 | # m0.11 , 2013/05/28, Support to evaluate compiler option |
| 96 | # m0.10 , 2012/11/16, Support is_MAIN_CODE_NEED_GFH |
| 97 | # m0.09 , 2013/03/22, Support parsing informake.log |
| 98 | # m0.08 , 2012/01/14, Support basic query functions more flexible |
| 99 | # m0.07 , 2012/10/19, Support is_XBOOTING, is_HostedDongle, is_RNDISDongle |
| 100 | # m0.06 , 2012/09/18, Fix MakeFile mode parsing |
| 101 | # m0.05 , 2012/08/17, Support GetChip() |
| 102 | # m0.04 , 2012/08/06, Add more common functions and ParseDefinition() |
| 103 | # m0.03 , 2012/07/26, Support is_NonSPNOR() |
| 104 | # m0.02 , 2012/05/28, Support path and filename case sensitive on Linux |
| 105 | # v0.07 , 2012/05/13, Move is_NOR from sysgenUtility to here and support general query |
| 106 | # m0.01 , 2012/05/09, Provide GetCompiler() |
| 107 | # v0.06 , 2012/05/08, Copy parseFeatureOptionCondition |
| 108 | # and EvaluateFeatureOptionCondition from objListHelper.pm to here |
| 109 | # v0.05 , 2012/05/08, Query is_SmartPhone |
| 110 | # v0.04 , 2012/01/30, To provide CUSTOMER and MODE in %MAKEFILE_OPTIONS |
| 111 | # v0.03 , 2011/12/17, Fix parsing MakeFile |
| 112 | # v0.02 , 2011/11/01, Remove $$ to support Perl v5.12.* |
| 113 | # v0.01 , 2011/09/21, Initial revision |
| 114 | |
| 115 | #**************************************************************************** |
| 116 | # Global variable |
| 117 | #**************************************************************************** |
| 118 | my $g_MAKEFILE_href = undef; |
| 119 | #**************************************************************************** |
| 120 | # oo >>> Finished |
| 121 | #**************************************************************************** |
| 122 | return 1; |
| 123 | |
| 124 | sub PreProcess |
| 125 | { |
| 126 | my ($MAKE_FILE, $mk_href, $INFOMAKE, $CmplOpt_href, $RelInfo_href, $bDie) = @_; |
| 127 | my $bResult = 1; |
| 128 | if(!BuildInfo::Parse_InfoMakeLog($INFOMAKE, $CmplOpt_href, $RelInfo_href)) |
| 129 | { |
| 130 | $bResult = 0; |
| 131 | FileInfoParser_die("Parse infomake.log failed")if($bDie); |
| 132 | } |
| 133 | if(!FileInfo::Parse_MAKEFILE($MAKE_FILE, $mk_href)) |
| 134 | { |
| 135 | $bResult = 0; |
| 136 | FileInfoParser_die("Parse MakeFile failed")if($bDie); |
| 137 | } |
| 138 | return $bResult; |
| 139 | } |
| 140 | |
| 141 | #**************************************************************************** |
| 142 | # subroutine: Parse_MAKEFILE |
| 143 | # input: 1. MAKEFILE path |
| 144 | # 2. a Hash to contain MAKEFILE information. |
| 145 | # output: 1=Parse successfully, 0 or die= Parse failed. |
| 146 | # sample code: my %MAKEFILE_OPTIONS; |
| 147 | # &FileInfo::Parse_MAKEFILE($MAKEFILE_Path, \%MAKEFILE_OPTIONS); |
| 148 | #**************************************************************************** |
| 149 | |
| 150 | sub Parse_MAKEFILE |
| 151 | { |
| 152 | my ($strMAKEFILE_Path, $Info_href) = @_; |
| 153 | my $bResult = 0; |
| 154 | if(-e $strMAKEFILE_Path) |
| 155 | { |
| 156 | open (FILE_HANDLE, $strMAKEFILE_Path) or &FileInfoParser_die("Cannot open $strMAKEFILE_Path\n", __FILE__, __LINE__); |
| 157 | while (<FILE_HANDLE>) |
| 158 | { |
| 159 | if ((/^([^\#]*)\#?.*/) && ($1 =~ /^(\w+)\s*=\s*(.*\S)\s*$/)) |
| 160 | { |
| 161 | my $keyname = lc($1); |
| 162 | #defined($Info_href->{$keyname}) && warn "$1 redefined in $strMAKEFILE_Path!\n"; |
| 163 | $Info_href->{$keyname} = uc($2); |
| 164 | $keyname = uc($1); |
| 165 | #defined($Info_href->{$keyname}) && warn "$1 redefined in $strMAKEFILE_Path!\n"; |
| 166 | $Info_href->{$keyname} = uc($2); |
| 167 | $bResult = 1; |
| 168 | } |
| 169 | } |
| 170 | close FILE_HANDLE; |
| 171 | if ($strMAKEFILE_Path =~ /(\w+)_(\w+)\((\w+)\).mak/i) |
| 172 | { |
| 173 | $Info_href->{'MODE'} = uc($3); |
| 174 | $Info_href->{'mode'} = uc($3); |
| 175 | } |
| 176 | $g_MAKEFILE_href = $Info_href; |
| 177 | } |
| 178 | else |
| 179 | { |
| 180 | &FileInfoParser_die("$strMAKEFILE_Path: NOT exist!", __FILE__, __LINE__); |
| 181 | } |
| 182 | return $bResult; |
| 183 | } |
| 184 | |
| 185 | sub GetMakeFileRef |
| 186 | { |
| 187 | my ($strMAKEFILE_Path) = @_; |
| 188 | if(!defined $g_MAKEFILE_href) |
| 189 | { |
| 190 | my %MakeFileOption; |
| 191 | &Parse_MAKEFILE($strMAKEFILE_Path, \%MakeFileOption); |
| 192 | } |
| 193 | return $g_MAKEFILE_href; |
| 194 | } |
| 195 | sub is |
| 196 | { |
| 197 | my ($strKey, $strValue, $MakeFile_ref) = @_; |
| 198 | $MakeFile_ref = $g_MAKEFILE_href if (!defined $MakeFile_ref); |
| 199 | &NoMakeFile_die($MakeFile_ref, __FILE__, __LINE__); |
| 200 | my $bEqual = 0; |
| 201 | if(exists $MakeFile_ref->{uc($strKey)} and uc($MakeFile_ref->{uc($strKey)}) eq uc($strValue)) |
| 202 | { |
| 203 | $bEqual = 1; |
| 204 | } |
| 205 | return $bEqual; |
| 206 | } |
| 207 | sub find |
| 208 | { |
| 209 | my ($strKey, $strValue, $MakeFile_ref) = @_; |
| 210 | $MakeFile_ref = $g_MAKEFILE_href if (!defined $MakeFile_ref); |
| 211 | &NoMakeFile_die($MakeFile_ref, __FILE__, __LINE__); |
| 212 | my $bFound = 0; |
| 213 | if(exists $MakeFile_ref->{uc($strKey)} and $MakeFile_ref->{uc($strKey)} =~ /$strValue/) |
| 214 | { |
| 215 | $bFound = 1; |
| 216 | } |
| 217 | return $bFound; |
| 218 | } |
| 219 | sub isnot |
| 220 | { |
| 221 | my ($strKey, $strValue, $MakeFile_ref) = @_; |
| 222 | $MakeFile_ref = $g_MAKEFILE_href if (!defined $MakeFile_ref); |
| 223 | &NoMakeFile_die($MakeFile_ref, __FILE__, __LINE__); |
| 224 | my $bNotEqual = 0; |
| 225 | if(exists $MakeFile_ref->{uc($strKey)} and uc($MakeFile_ref->{uc($strKey)}) ne uc($strValue)) |
| 226 | { #exist but not equal |
| 227 | $bNotEqual = 1; |
| 228 | } |
| 229 | return $bNotEqual; |
| 230 | } |
| 231 | sub get |
| 232 | { |
| 233 | my ($strKey, $MakeFile_ref) = @_; |
| 234 | $MakeFile_ref = $g_MAKEFILE_href if (!defined $MakeFile_ref); |
| 235 | &NoMakeFile_die($MakeFile_ref, __FILE__, __LINE__); |
| 236 | my $Value = undef; |
| 237 | if(exists $MakeFile_ref->{uc($strKey)}) |
| 238 | { |
| 239 | $Value = $MakeFile_ref->{uc($strKey)}; |
| 240 | } |
| 241 | elsif(exists $MakeFile_ref->{$strKey}) |
| 242 | { |
| 243 | $Value = $MakeFile_ref->{$strKey}; |
| 244 | } |
| 245 | return $Value; |
| 246 | } |
| 247 | sub ParseDefinition |
| 248 | { |
| 249 | my ($strFilePath, $Hash_ref, $bAllowDuplicated) = @_; |
| 250 | my $content = &CommonUtil::GetFileContent($strFilePath); |
| 251 | #strip comments |
| 252 | $content =~ s/\/\/(.+)//g; |
| 253 | $content =~s#/\*[^*]*\*+([^/*][^*]*\*+)*/|([^/"']*("[^"\\]*(\\[\d\D][^"\\]*)*"[^/"']*|'[^'\\]*(\\[\d\D][^'\\]*)*'[^/"']*|/+[^*/][^/"']*)*)#$2#g; |
| 254 | |
| 255 | my @lines = split(/\n|\r/, $content); |
| 256 | my $nDuplicatedIndex=0; |
| 257 | foreach my $line (@lines) |
| 258 | { |
| 259 | if ($line =~ /#define\s+(\w+)\s+\((.*)\)\s*$/ || $line =~ /#define\s+(\w+)\s+(\S*)\s*$/) |
| 260 | { |
| 261 | my $option = $1; |
| 262 | my $value = $2; |
| 263 | &FileInfoParser_die("$strFilePath: $option redefined in $strFilePath!", __FILE__, __LINE__) |
| 264 | if (!$bAllowDuplicated and defined($Hash_ref->{$option})); |
| 265 | if (!defined $value) |
| 266 | { |
| 267 | $Hash_ref->{$option} = 'TRUE'; |
| 268 | $Hash_ref->{uc($option)} = 'TRUE'; |
| 269 | $Hash_ref->{lc($option)} = 'TRUE'; |
| 270 | } |
| 271 | else |
| 272 | { |
| 273 | $Hash_ref->{$option} = $value; |
| 274 | $Hash_ref->{uc($option)} = $value; |
| 275 | $Hash_ref->{lc($option)} = $value; |
| 276 | } |
| 277 | } |
| 278 | } |
| 279 | close (FILE_HANDLE); |
| 280 | } |
| 281 | |
| 282 | |
| 283 | #**************************************************************************** |
| 284 | # subroutine: is_SmartPhone - Query if it belongs smart phone project |
| 285 | # Input: x |
| 286 | # Output: 1=it's SmartPhone, others=not SmartPhone |
| 287 | #**************************************************************************** |
| 288 | sub is_SmartPhone |
| 289 | { |
| 290 | my ($MakeFile_ref) = @_; |
| 291 | $MakeFile_ref = $g_MAKEFILE_href if (!defined $MakeFile_ref); |
| 292 | &NoMakeFile_die($MakeFile_ref, __FILE__, __LINE__); |
| 293 | my $bIsSmartPhone = 0; |
| 294 | if( exists $MakeFile_ref->{SMART_PHONE_CORE} and $MakeFile_ref->{SMART_PHONE_CORE} ne "NONE" ) #NONE = feature phone |
| 295 | { |
| 296 | $bIsSmartPhone = 1; |
| 297 | } |
| 298 | return $bIsSmartPhone; |
| 299 | } |
| 300 | |
| 301 | #**************************************************************************** |
| 302 | # subroutine: is_with_AP - Query if it is paired with AP |
| 303 | # Input: x |
| 304 | # Output: 1=it's paired with AP, others=other combination |
| 305 | #**************************************************************************** |
| 306 | sub is_with_AP |
| 307 | { |
| 308 | my ($MakeFile_ref) = @_; |
| 309 | $MakeFile_ref = $g_MAKEFILE_href if (!defined $MakeFile_ref); |
| 310 | &NoMakeFile_die($MakeFile_ref, __FILE__, __LINE__); |
| 311 | my $bIsWithAP = 0; |
| 312 | if( exists $MakeFile_ref->{SMART_PHONE_CORE} and $MakeFile_ref->{SMART_PHONE_CORE} =~/ANDROID_MODEM/i ) |
| 313 | { |
| 314 | $bIsWithAP = 1; |
| 315 | } |
| 316 | return $bIsWithAP; |
| 317 | } |
| 318 | |
| 319 | |
| 320 | #**************************************************************************** |
| 321 | # subroutine: is_NOR - Query if it's NOR flash |
| 322 | # Input: \%MAKEFILE_OPTION |
| 323 | # Output: 0=not NOR, 1=NOR |
| 324 | #**************************************************************************** |
| 325 | sub is_NOR |
| 326 | { |
| 327 | my ($MAKEFILE_ref) = @_; |
| 328 | $MAKEFILE_ref = $g_MAKEFILE_href if (!defined $MAKEFILE_ref); |
| 329 | &NoMakeFile_die($MAKEFILE_ref, __FILE__, __LINE__); |
| 330 | my $bNOR = 1; # 0=not NOR, 1= NOR |
| 331 | if((exists $MAKEFILE_ref->{'nand_flash_booting'} and $MAKEFILE_ref->{'nand_flash_booting'} ne 'NONE') |
| 332 | or (exists $MAKEFILE_ref->{'emmc_booting'} and $MAKEFILE_ref->{'emmc_booting'} ne 'NONE')) |
| 333 | { |
| 334 | $bNOR = 0; |
| 335 | } |
| 336 | return $bNOR; |
| 337 | } |
| 338 | #**************************************************************************** |
| 339 | # subroutine: is_NonSPNOR - Query if it's not nand flash and not smart_phone project |
| 340 | # Input: \%MAKEFILE_OPTION |
| 341 | # Output: 0=not NOR, 1=NOR |
| 342 | #**************************************************************************** |
| 343 | sub is_NonSPNOR |
| 344 | { |
| 345 | my ($MAKEFILE_ref) = @_; |
| 346 | return (&is_NOR($MAKEFILE_ref) and !&is_SmartPhone($MAKEFILE_ref)); |
| 347 | } |
| 348 | |
| 349 | #**************************************************************************** |
| 350 | # subroutine: is_BuiltWithCopro - Query if it's built with copro |
| 351 | # Input: \%MAKEFILE_OPTION, \%Compile_OPTION |
| 352 | # Output: 0=not building with copro, 1=building with containing copro now |
| 353 | #**************************************************************************** |
| 354 | sub is_BuiltWithCopro |
| 355 | { |
| 356 | my ($MAKEFILE_ref, $CMPL_href) = @_; |
| 357 | my $bBuiltWithCopro = 0; |
| 358 | $bBuiltWithCopro = 1 if(is("MD_OFFLOAD_COPRO", "ARM7EJ-S", $MAKEFILE_ref) |
| 359 | and !BuildInfo::exist(BuildOPT::CMPL, "NEED_BUILD_MD_OFFLOAD_COPRO", $CMPL_href)); |
| 360 | return $bBuiltWithCopro; |
| 361 | } |
| 362 | #**************************************************************************** |
| 363 | # subroutine: is_Copro - Query if it's COPRO |
| 364 | # Input: \%MAKEFILE_OPTION, \%Compile_OPTION |
| 365 | # Output: 0=not copro, 1=it's copro |
| 366 | #**************************************************************************** |
| 367 | sub is_Copro |
| 368 | { |
| 369 | my ($MAKEFILE_ref, $CMPL_href) = @_; |
| 370 | my $bCopro = 0; |
| 371 | $bCopro = 1 if(is("MD_OFFLOAD_COPRO", "ARM7EJ-S", $MAKEFILE_ref) |
| 372 | and BuildInfo::exist(BuildOPT::CMPL, "NEED_BUILD_MD_OFFLOAD_COPRO", $CMPL_href)); |
| 373 | return $bCopro; |
| 374 | } |
| 375 | |
| 376 | #**************************************************************************** |
| 377 | # subroutine: is_MAIN_CODE_NEED_GFH - Query if it's MAIN_CODE_NEED_GFH: |
| 378 | # SMART_PHONE_CORE != NONE && X_BOOTING==NONE => MAIN_CODE_NEED_GFH = FALSE |
| 379 | # Input: \%MAKEFILE_OPTION |
| 380 | # Output: 0=no GFH, 1=having GFH |
| 381 | #**************************************************************************** |
| 382 | sub is_MAIN_CODE_NEED_GFH |
| 383 | { |
| 384 | my ($bb, $MAKEFILE_ref) = @_; |
| 385 | $MAKEFILE_ref = $g_MAKEFILE_href if (!defined $MAKEFILE_ref); |
| 386 | &NoMakeFile_die($MAKEFILE_ref, __FILE__, __LINE__); |
| 387 | my $bNEED_GFH = 0; |
| 388 | if(&sysUtil::is_sv5($bb)) |
| 389 | { |
| 390 | $bNEED_GFH = 1; |
| 391 | if(&is_SmartPhone($MAKEFILE_ref) && &is("X_BOOTING", "NONE", $MAKEFILE_ref) ) |
| 392 | { |
| 393 | $bNEED_GFH = 0; |
| 394 | } |
| 395 | } |
| 396 | return $bNEED_GFH; |
| 397 | } |
| 398 | |
| 399 | #**************************************************************************** |
| 400 | # subroutine: is_XBOOTING - Query if it's X_BOOTING: X_BOOTING != NONE |
| 401 | # Input: \%MAKEFILE_OPTION |
| 402 | # Output: 0=not X BOOTING, 1=X BOOTING |
| 403 | #**************************************************************************** |
| 404 | sub is_XBOOTING |
| 405 | { |
| 406 | my ($MAKEFILE_ref) = @_; |
| 407 | $MAKEFILE_ref = $g_MAKEFILE_href if (!defined $MAKEFILE_ref); |
| 408 | &NoMakeFile_die($MAKEFILE_ref, __FILE__, __LINE__); |
| 409 | my $bX = 0; |
| 410 | $bX = 1 if(&isnot("X_BOOTING", "NONE")); |
| 411 | return $bX; |
| 412 | } |
| 413 | |
| 414 | #**************************************************************************** |
| 415 | # subroutine: is_HostedDongle - Query if it's HostedDongle |
| 416 | # SMART_PHONE_CORE=MODEM_HOST and X_BOOTING=NONE |
| 417 | # Input: \%MAKEFILE_OPTION |
| 418 | # Output: 0=not Hosted dongle, 1=Hosted dongle |
| 419 | #**************************************************************************** |
| 420 | sub is_HostedDongle |
| 421 | { |
| 422 | my ($MAKEFILE_ref) = @_; |
| 423 | $MAKEFILE_ref = $g_MAKEFILE_href if (!defined $MAKEFILE_ref); |
| 424 | &NoMakeFile_die($MAKEFILE_ref, __FILE__, __LINE__); |
| 425 | my $bX = 0; |
| 426 | $bX = 1 if(&is("SMART_PHONE_CORE", "MODEM_HOST") and !&is_XBOOTING()); |
| 427 | return $bX; |
| 428 | } |
| 429 | |
| 430 | |
| 431 | #**************************************************************************** |
| 432 | # subroutine: is_RNDISDongle - Query if it's RNDIS Dongle |
| 433 | # (is smartphone but SMART_PHONE_CORE != MODEM_HOST) and X_BOOTING=NONE |
| 434 | # Input: \%MAKEFILE_OPTION |
| 435 | # Output: 0=not RNDIS, 1=RNDIS |
| 436 | #**************************************************************************** |
| 437 | sub is_RNDISDongle |
| 438 | { |
| 439 | my ($MAKEFILE_ref) = @_; |
| 440 | $MAKEFILE_ref = $g_MAKEFILE_href if (!defined $MAKEFILE_ref); |
| 441 | &NoMakeFile_die($MAKEFILE_ref, __FILE__, __LINE__); |
| 442 | my $bX = 0; |
| 443 | $bX = 1 if(&is_SmartPhone() and !&is_XBOOTING() and !is_HostedDongle()); |
| 444 | return $bX; |
| 445 | } |
| 446 | |
| 447 | #**************************************************************************** |
| 448 | # subroutine: GetCompiler() |
| 449 | # Input: \%MAKEFILE_OPTION |
| 450 | # Output: Should be "GCC" or "RVCT" in string |
| 451 | #**************************************************************************** |
| 452 | sub GetCompiler |
| 453 | { |
| 454 | my ($MakeFile_ref) = @_; |
| 455 | $MakeFile_ref = $g_MAKEFILE_href if (!defined $MakeFile_ref); |
| 456 | &NoMakeFile_die($MakeFile_ref, __FILE__, __LINE__); |
| 457 | my $strCompiler = undef; |
| 458 | $strCompiler = uc($MakeFile_ref->{COMPILER}) if(exists $MakeFile_ref->{COMPILER}); |
| 459 | &FileInfoParser_die("Unsupported ToolChain!\n", __FILE__, __LINE__) if(($strCompiler ne "GCC") and ($strCompiler ne "RVCT")); |
| 460 | return $strCompiler; |
| 461 | } |
| 462 | #**************************************************************************** |
| 463 | # subroutine: GetChip() |
| 464 | # Input: \%MAKEFILE_OPTION |
| 465 | # \%COMPILER_OPTION |
| 466 | # Output: string (e.g. MT6280 or MT6280_XX) |
| 467 | #**************************************************************************** |
| 468 | sub GetChip |
| 469 | { |
| 470 | my ($MakeFile_ref, $CMPL_href) = @_; |
| 471 | $MakeFile_ref = $g_MAKEFILE_href if (!defined $MakeFile_ref); |
| 472 | &NoMakeFile_die($MakeFile_ref, __FILE__, __LINE__); |
| 473 | my $strChip = undef; |
| 474 | $strChip = uc($MakeFile_ref->{PLATFORM}) if(exists $MakeFile_ref->{PLATFORM}); |
| 475 | $strChip .= "_".uc($MakeFile_ref->{MDSYS}) if(exists $MakeFile_ref->{MDSYS} and $MakeFile_ref->{MDSYS} !~/none|md5/i); |
| 476 | $strChip .= "_COPRO" if(is_Copro($MakeFile_ref, $CMPL_href)); |
| 477 | return $strChip; |
| 478 | } |
| 479 | |
| 480 | #**************************************************************************** |
| 481 | # subroutine: GetSharedMemorySize |
| 482 | # description: return shared region size |
| 483 | # input: N/A |
| 484 | # output: size of SHARED_REGION_SIZE in ~copro_info.tmp or default value (inculde dsp tx/rx sections) |
| 485 | # need init: No |
| 486 | #**************************************************************************** |
| 487 | sub GetSharedMemorySize |
| 488 | { |
| 489 | my $nSharedRegionEnd = &FileInfo::get(SHARED_REGION_SIZE); |
| 490 | return ( 0==$nSharedRegionEnd ? &sysUtil::GetDefaultSharedMemorySize(&GetChip()) : $nSharedRegionEnd ); |
| 491 | } |
| 492 | |
| 493 | #**************************************************************************** |
| 494 | # subroutine: EvaluateFeatureOptionCondition |
| 495 | # description: Evaluate the feature option condition. |
| 496 | # input: Feature option condition(string), makefile options hash ref |
| 497 | # output: 1: true, 0: false |
| 498 | # need init: No |
| 499 | #**************************************************************************** |
| 500 | sub EvaluateFeatureOptionCondition |
| 501 | { |
| 502 | my $condition = shift; |
| 503 | my $makefileOptionsRef = shift; |
| 504 | |
| 505 | my @expressionTree; |
| 506 | my @stack; |
| 507 | |
| 508 | # Transform the condition to expression tree in postfix form |
| 509 | &parseFeatureOptionCondition($condition, \@expressionTree); |
| 510 | |
| 511 | # Evaluate the expression tree |
| 512 | foreach my $token (@expressionTree) |
| 513 | { |
| 514 | if ($token eq "&&" or $token eq "||") |
| 515 | { |
| 516 | my $second = pop(@stack); |
| 517 | my $first = pop(@stack); |
| 518 | push (@stack, eval "$first $token $second"); |
| 519 | } |
| 520 | elsif ($token eq "=") |
| 521 | { |
| 522 | my $second = pop(@stack); |
| 523 | my $first = pop(@stack); |
| 524 | my $value = $makefileOptionsRef->{$first}; |
| 525 | $value = "" unless defined $value; |
| 526 | if ($value eq $second) |
| 527 | { |
| 528 | push (@stack, 1); |
| 529 | } |
| 530 | else |
| 531 | { |
| 532 | push (@stack, 0); |
| 533 | } |
| 534 | } |
| 535 | elsif ($token eq "!") |
| 536 | { |
| 537 | my $first = pop(@stack); |
| 538 | if ($first == 1) |
| 539 | { |
| 540 | push (@stack, 0); |
| 541 | } |
| 542 | else |
| 543 | { |
| 544 | push (@stack, 1); |
| 545 | } |
| 546 | } |
| 547 | else |
| 548 | { |
| 549 | push @stack, $token; |
| 550 | } |
| 551 | } |
| 552 | &FileInfoParser_die("Incorrect syntax of feature option condition \"$condition\"", __FILE__, __LINE__) |
| 553 | unless (1 == @stack); |
| 554 | |
| 555 | return $stack[0]; |
| 556 | } |
| 557 | |
| 558 | #**************************************************************************** |
| 559 | # subroutine: parseFeatureOptionCondition |
| 560 | # description: Parse the feature option condition to postfix form. |
| 561 | # input: Feature option condition, expression tree ref |
| 562 | # output: Expression tree |
| 563 | # need init: No |
| 564 | #**************************************************************************** |
| 565 | sub parseFeatureOptionCondition |
| 566 | { |
| 567 | my $condition = shift; |
| 568 | my $expressionTreeRef = shift; |
| 569 | my $conditionNoSpace = $condition; |
| 570 | $conditionNoSpace =~ s/ //g; |
| 571 | |
| 572 | my @tokens = split(/(=|\(|\)|&&|\|\||!)/, $conditionNoSpace); |
| 573 | my @stack; |
| 574 | |
| 575 | # For error checking |
| 576 | my $parenthesis = 0; |
| 577 | my $operand = 0; |
| 578 | my $operator = 0; |
| 579 | |
| 580 | foreach my $token (@tokens) |
| 581 | { |
| 582 | if ($token eq "") |
| 583 | { |
| 584 | # Skip empty token |
| 585 | next; |
| 586 | } |
| 587 | elsif ($token eq "(") |
| 588 | { |
| 589 | push @stack, $token; |
| 590 | ++$parenthesis; |
| 591 | } |
| 592 | elsif ($token eq ")") |
| 593 | { |
| 594 | &FileInfoParser_die("Incorrect syntax of feature option condition \"$condition\"", __FILE__, __LINE__) |
| 595 | unless (0 < $parenthesis); |
| 596 | my $temp = pop(@stack); |
| 597 | |
| 598 | &FileInfoParser_die("Incorrect syntax of feature option condition \"$condition\"", __FILE__, __LINE__) |
| 599 | if ($temp eq "("); |
| 600 | |
| 601 | do |
| 602 | { |
| 603 | push @$expressionTreeRef, $temp; |
| 604 | $temp = pop(@stack); |
| 605 | } while ($temp ne "("); |
| 606 | |
| 607 | --$parenthesis; |
| 608 | } |
| 609 | elsif ($token eq "=" or $token eq "&&" or $token eq "||" or $token eq "!") |
| 610 | { |
| 611 | my $needLoop = 0; |
| 612 | |
| 613 | do |
| 614 | { |
| 615 | if (0 == scalar(@stack) or $stack[-1] eq "(") |
| 616 | { |
| 617 | # Stack is empty or stack top eqals to ( |
| 618 | push @stack, $token; |
| 619 | $needLoop = 0; |
| 620 | } |
| 621 | elsif (0 < compareFeatureOptionOperator($stack[-1], $token)) |
| 622 | { |
| 623 | # Stack top has higher priority than current token |
| 624 | push @stack, $token; |
| 625 | $needLoop = 0; |
| 626 | } |
| 627 | else |
| 628 | { |
| 629 | push @$expressionTreeRef, pop(@stack); |
| 630 | $needLoop = 1; |
| 631 | } |
| 632 | } while ($needLoop); |
| 633 | |
| 634 | $operator += 1 unless ($token eq "!"); |
| 635 | } |
| 636 | elsif ($token =~ /\w+/) |
| 637 | { |
| 638 | # Operand |
| 639 | push @$expressionTreeRef, $token; |
| 640 | $operand += 1; |
| 641 | } |
| 642 | else |
| 643 | { |
| 644 | &FileInfoParser_die("Incorrect syntax of feature option condition \"$condition\"", __FILE__, __LINE__); |
| 645 | } |
| 646 | } |
| 647 | |
| 648 | &FileInfoParser_die("Incorrect syntax of feature option condition \"$condition\"", __FILE__, __LINE__) |
| 649 | unless ($operator == ($operand - 1) and 0 == $parenthesis); |
| 650 | |
| 651 | push @$expressionTreeRef, reverse(@stack); |
| 652 | } |
| 653 | |
| 654 | sub compareFeatureOptionOperator |
| 655 | { |
| 656 | my $first = shift; |
| 657 | my $second = shift; |
| 658 | my %operatorToNumber = ("=" => 0, "!" => 1, "&&" => 2, "||" => 2); |
| 659 | |
| 660 | return $operatorToNumber{$first} <=> $operatorToNumber{$second}; |
| 661 | } |
| 662 | |
| 663 | #**************************************************************************** |
| 664 | # subroutine: FileInfoParser_die |
| 665 | # sample code: (message, __FILE__, __LINE__) |
| 666 | # input: $error_msg, $file, $line_no |
| 667 | #**************************************************************************** |
| 668 | sub FileInfoParser_die |
| 669 | { |
| 670 | my ($error_msg, $file, $line_no) = @_; |
| 671 | my $pack_name = undef; |
| 672 | if(!defined $file or !defined $line_no) |
| 673 | { |
| 674 | ($pack_name, $file, $line_no) = caller; |
| 675 | } |
| 676 | &sysUtil::error_handler($error_msg, $file, $line_no, 'ProjectMakeFileParser'); |
| 677 | } |
| 678 | sub NoMakeFile_die |
| 679 | { |
| 680 | my ($MAKEFILE_ref, $file, $line_no) = @_; |
| 681 | &FileInfoParser_die("Please parse project makefile by FileInfo::Parse_MAKEFILE() before using it.", $file, $line_no) |
| 682 | if(!defined $MAKEFILE_ref); |
| 683 | } |
| 684 | |
| 685 | package BuildInfo; |
| 686 | #**************************************************************************** |
| 687 | # Global variable |
| 688 | #**************************************************************************** |
| 689 | my $g_CmplOpt_href = undef; # compiler option |
| 690 | my $g_RelInfo_href = undef; # release info |
| 691 | #**************************************************************************** |
| 692 | # Subroutine |
| 693 | #**************************************************************************** |
| 694 | #**************************************************************************** |
| 695 | # subroutine: Parse_InfoMakeLog |
| 696 | # input: 1. Infomake.log path |
| 697 | # 2. a Hash reference to contain CompilerOption information. |
| 698 | # 3. a Hash reference to contain Release information. |
| 699 | # output: 1=Parse successfully, 0 or die= Parse failed. |
| 700 | # sample code: my %CmplOption; |
| 701 | # my %RelOption; |
| 702 | # BuildInfo::Parse_InfoMakeLog($infomake_path, \%CmplOption, \%RelOption); |
| 703 | #**************************************************************************** |
| 704 | sub Parse_InfoMakeLog |
| 705 | { |
| 706 | my ($strInfomake_Path, $CmplOpt_href, $RelInfo_href) = @_; |
| 707 | my $bResult = 0; |
| 708 | if(-e $strInfomake_Path) |
| 709 | { |
| 710 | open (FILE_HANDLE, $strInfomake_Path) or BuildInfo_die("Cannot open $strInfomake_Path\n", __FILE__, __LINE__); |
| 711 | while (<FILE_HANDLE>) |
| 712 | { |
| 713 | if(/^(\S+)\s*\=\s*(.*)/) |
| 714 | { |
| 715 | my $key = $1; |
| 716 | my $value = $2; |
| 717 | if($key =~ /COM_DEFS/) |
| 718 | { |
| 719 | _ParseCMPLOpt($value, $CmplOpt_href); |
| 720 | } |
| 721 | else |
| 722 | { |
| 723 | $RelInfo_href->{$1} = $2; |
| 724 | $RelInfo_href->{lc($1)} = $2; |
| 725 | } |
| 726 | } |
| 727 | } |
| 728 | close FILE_HANDLE; |
| 729 | $g_CmplOpt_href = $CmplOpt_href; |
| 730 | $g_RelInfo_href = $RelInfo_href; |
| 731 | $bResult = 1; |
| 732 | } |
| 733 | else |
| 734 | { |
| 735 | BuildInfo_die("$strInfomake_Path: NOT exist!", __FILE__, __LINE__); |
| 736 | } |
| 737 | return $bResult; |
| 738 | } |
| 739 | |
| 740 | sub _ParseCMPLOpt |
| 741 | { |
| 742 | my ($strOptions, $CmplOpt_href) = @_; |
| 743 | my @ComlOpt = split(/\s/,$strOptions); |
| 744 | foreach my $Opt(@ComlOpt) |
| 745 | { |
| 746 | $Opt =~ s/\s\n\r//; |
| 747 | next if($Opt eq ""); |
| 748 | my $strkey = $Opt; |
| 749 | my $strvalue = undef; |
| 750 | if($Opt =~ /(.*)=(.*)/) |
| 751 | { |
| 752 | $strkey = $1; |
| 753 | $strvalue = $2; |
| 754 | } |
| 755 | $CmplOpt_href->{$strkey} = $strvalue; |
| 756 | $CmplOpt_href->{lc($strkey)} = $strvalue; |
| 757 | } |
| 758 | } |
| 759 | sub GetCmplOptRef |
| 760 | { |
| 761 | my ($strInfoMake_Path) = @_; |
| 762 | if(!defined $g_CmplOpt_href) |
| 763 | { |
| 764 | my %CmplOption; |
| 765 | my %RelOption; |
| 766 | &Parse_InfoMakeLog($strInfoMake_Path, \%CmplOption, \%RelOption); |
| 767 | } |
| 768 | return $g_CmplOpt_href; |
| 769 | } |
| 770 | sub GetRelOptRef |
| 771 | { |
| 772 | my ($strInfoMake_Path) = @_; |
| 773 | if(!defined $g_RelInfo_href) |
| 774 | { |
| 775 | my %CmplOption; |
| 776 | my %RelOption; |
| 777 | &Parse_InfoMakeLog($strInfoMake_Path, \%CmplOption, \%RelOption); |
| 778 | } |
| 779 | return $g_RelInfo_href; |
| 780 | } |
| 781 | #**************************************************************************** |
| 782 | # subroutine: exist |
| 783 | # Input: $nOption: BuildOPT::CMPL or BuildOPT::REL |
| 784 | # Output: In compiler option, if $strKey exists in compiler option, it will return 1, |
| 785 | # otherwises returns 0 |
| 786 | # In release information, it's usually meaningless to see if $strKey exists |
| 787 | #**************************************************************************** |
| 788 | sub exist |
| 789 | { |
| 790 | my ($nOption, $strKey, $href) = @_; |
| 791 | if (!defined $href) |
| 792 | { |
| 793 | $href = $g_CmplOpt_href if($nOption == BuildOPT::CMPL); |
| 794 | $href = $g_RelInfo_href if($nOption == BuildOPT::REL); |
| 795 | } |
| 796 | &NoInfoMake_die($href, __FILE__, __LINE__); |
| 797 | my $bExist = 0; |
| 798 | if(exists $href->{$strKey}) |
| 799 | { |
| 800 | $bExist = 1; |
| 801 | } |
| 802 | return $bExist; |
| 803 | } |
| 804 | |
| 805 | #**************************************************************************** |
| 806 | # subroutine: EvaluateCompileOption |
| 807 | # description: Evaluate the compile option |
| 808 | # input: Compile option condition(string), compile options hash ref |
| 809 | # output: 1: true, 0: false |
| 810 | # need init: No |
| 811 | #**************************************************************************** |
| 812 | sub EvaluateCompileOption |
| 813 | { |
| 814 | my ($condition, $CmpOption_href) = @_; |
| 815 | $CmpOption_href = $g_CmplOpt_href if(!defined $CmpOption_href); |
| 816 | &NoInfoMake_die($CmpOption_href, __FILE__, __LINE__); |
| 817 | |
| 818 | # Transform the condition to expression tree in postfix form |
| 819 | my @expressionTree; |
| 820 | _parseCompileOptionCondition($condition, \@expressionTree); |
| 821 | |
| 822 | # Evaluate the expression tree |
| 823 | my @stack; |
| 824 | foreach my $token (@expressionTree) |
| 825 | { |
| 826 | if ($token eq "&&" or $token eq "||") |
| 827 | { |
| 828 | my $second = pop(@stack); |
| 829 | my $first = pop(@stack); |
| 830 | $first = exist(BuildOPT::CMPL, $first) if($first =~ /\D+/); |
| 831 | $second = exist(BuildOPT::CMPL, $second) if($second =~ /\D+/); |
| 832 | push (@stack, eval "$first $token $second"); |
| 833 | } |
| 834 | elsif ($token eq "=") |
| 835 | { |
| 836 | my $second = pop(@stack); |
| 837 | my $first = pop(@stack); |
| 838 | my $value = $CmpOption_href->{$first}; |
| 839 | $value = "" unless defined $value; |
| 840 | if ($value eq $second) |
| 841 | { |
| 842 | push (@stack, 1); |
| 843 | } |
| 844 | else |
| 845 | { |
| 846 | push (@stack, 0); |
| 847 | } |
| 848 | } |
| 849 | elsif ($token eq "!") |
| 850 | { |
| 851 | my $first = pop(@stack); |
| 852 | $first = exist(BuildOPT::CMPL, $first) if($first =~ /\D+/); |
| 853 | if ($first == 1) |
| 854 | { |
| 855 | push (@stack, 0); |
| 856 | } |
| 857 | else |
| 858 | { |
| 859 | push (@stack, 1); |
| 860 | } |
| 861 | } |
| 862 | else |
| 863 | { |
| 864 | push @stack, $token; |
| 865 | } |
| 866 | } |
| 867 | |
| 868 | &BuildInfo_die("Incorrect syntax of compile option condition \"$condition\"", __FILE__, __LINE__) |
| 869 | unless (1 == @stack); |
| 870 | # for single compile option |
| 871 | my $ZeroString = "0"; $ZeroString = sprintf("%d", $ZeroString); # convert |
| 872 | my $OneString = "1"; $OneString = sprintf("%d", $OneString); # convert |
| 873 | $stack[0] = (exist(BuildOPT::CMPL, $stack[0])?1:0) if($ZeroString ne $stack[0] && $OneString ne $stack[0]) ; |
| 874 | |
| 875 | #use above safer syntax |
| 876 | #$stack[0] = (exist(BuildOPT::CMPL, $stack[0])?1:0) if("0" ne $stack[0] && "1" ne $stack[0]) ; |
| 877 | |
| 878 | return $stack[0]; |
| 879 | |
| 880 | } |
| 881 | #**************************************************************************** |
| 882 | # subroutine: _parseCompileOptionCondition |
| 883 | # description: Parse the feature option condition to postfix form. |
| 884 | # input: Feature option condition, expression tree ref |
| 885 | # output: Expression tree |
| 886 | # need init: No |
| 887 | #**************************************************************************** |
| 888 | sub _parseCompileOptionCondition |
| 889 | { |
| 890 | my ($condition, $expressionTreeRef) = @_; |
| 891 | my $conditionNoSpace = $condition; |
| 892 | $conditionNoSpace =~ s/ //g; |
| 893 | |
| 894 | my @tokens = split(/(=|\(|\)|&&|\|\||!)/, $conditionNoSpace); |
| 895 | my @stack; |
| 896 | |
| 897 | # For error checking |
| 898 | my $parenthesis = 0; |
| 899 | my $operand = 0; |
| 900 | my $operator = 0; |
| 901 | |
| 902 | foreach my $token (@tokens) |
| 903 | { |
| 904 | if ($token eq "") |
| 905 | { |
| 906 | # Skip empty token |
| 907 | next; |
| 908 | } |
| 909 | elsif ($token eq "(") |
| 910 | { |
| 911 | push @stack, $token; |
| 912 | ++$parenthesis; |
| 913 | } |
| 914 | elsif ($token eq ")") |
| 915 | { |
| 916 | &BuildInfo_die("Incorrect syntax of compile option condition \"$condition\"", __FILE__, __LINE__) |
| 917 | unless (0 < $parenthesis); |
| 918 | my $temp = pop(@stack); |
| 919 | |
| 920 | while ($temp ne "(") |
| 921 | { |
| 922 | push @$expressionTreeRef, $temp; |
| 923 | $temp = pop(@stack); |
| 924 | } |
| 925 | |
| 926 | --$parenthesis; |
| 927 | } |
| 928 | elsif ($token eq "=" or $token eq "&&" or $token eq "||" or $token eq "!") |
| 929 | { |
| 930 | my $needLoop = 0; |
| 931 | |
| 932 | do |
| 933 | { |
| 934 | if (0 == scalar(@stack) or $stack[-1] eq "(") |
| 935 | { |
| 936 | # Stack is empty or stack top eqals to ( |
| 937 | push @stack, $token; |
| 938 | $needLoop = 0; |
| 939 | } |
| 940 | elsif (0 < _compareCompileOptionOperator($stack[-1], $token)) |
| 941 | { |
| 942 | # Stack top has higher priority than current token |
| 943 | push @stack, $token; |
| 944 | $needLoop = 0; |
| 945 | } |
| 946 | else |
| 947 | { |
| 948 | push @$expressionTreeRef, pop(@stack); |
| 949 | $needLoop = 1; |
| 950 | } |
| 951 | } while ($needLoop); |
| 952 | |
| 953 | $operator += 1 unless ($token eq "!"); |
| 954 | } |
| 955 | elsif ($token =~ /\w+/) |
| 956 | { |
| 957 | # Operand |
| 958 | push @$expressionTreeRef, $token; |
| 959 | $operand += 1; |
| 960 | } |
| 961 | else |
| 962 | { |
| 963 | &BuildInfo_die("Incorrect syntax of compile option condition \"$condition\"", __FILE__, __LINE__); |
| 964 | } |
| 965 | } |
| 966 | |
| 967 | &BuildInfo_die("Incorrect syntax of compile option condition \"$condition\"", __FILE__, __LINE__) |
| 968 | unless ($operator == ($operand - 1) and 0 == $parenthesis); |
| 969 | |
| 970 | push @$expressionTreeRef, reverse(@stack); |
| 971 | } |
| 972 | |
| 973 | sub _compareCompileOptionOperator |
| 974 | { |
| 975 | my $first = shift; |
| 976 | my $second = shift; |
| 977 | my %operatorToNumber = ("=" => 0, "!" => 1, "&&" => 2, "||" => 2); |
| 978 | |
| 979 | return $operatorToNumber{$first} <=> $operatorToNumber{$second}; |
| 980 | } |
| 981 | |
| 982 | #**************************************************************************** |
| 983 | # subroutine: get |
| 984 | # Input: $nOption: BuildOPT::CMPL or BuildOPT::REL |
| 985 | # Output: In compiler option, if it's ooo=xxx, it returns xxx |
| 986 | # otherwises, it returns undef |
| 987 | # In release information, it returns value directly |
| 988 | #**************************************************************************** |
| 989 | sub get |
| 990 | { |
| 991 | my ($nOption, $strKey, $href) = @_; |
| 992 | if (!defined $href) |
| 993 | { |
| 994 | $href = $g_CmplOpt_href if($nOption == BuildOPT::CMPL); |
| 995 | $href = $g_RelInfo_href if($nOption == BuildOPT::REL); |
| 996 | } |
| 997 | &NoInfoMake_die($href, __FILE__, __LINE__); |
| 998 | my $strValue = undef; |
| 999 | if(exists $href->{$strKey}) |
| 1000 | { |
| 1001 | $strValue = $href->{$strKey}; |
| 1002 | } |
| 1003 | return $strValue; |
| 1004 | } |
| 1005 | #**************************************************************************** |
| 1006 | # subroutine: is |
| 1007 | # Input: $nOption: BuildOPT::CMPL or BuildOPT::REL |
| 1008 | # Output: 1=$href->{$strKey} equals to $strValue, 0=not equal |
| 1009 | #**************************************************************************** |
| 1010 | sub is |
| 1011 | { |
| 1012 | my ($nOption, $strKey, $strValue, $href) = @_; |
| 1013 | if (!defined $href) |
| 1014 | { |
| 1015 | $href = $g_CmplOpt_href if($nOption == BuildOPT::CMPL); |
| 1016 | $href = $g_RelInfo_href if($nOption == BuildOPT::REL); |
| 1017 | } |
| 1018 | &NoInfoMake_die($href, __FILE__, __LINE__); |
| 1019 | my $bResult = 0; |
| 1020 | if(exists $href->{$strKey}) |
| 1021 | { |
| 1022 | $bResult =1 if(lc($strValue) eq lc($href->{$strKey})); |
| 1023 | } |
| 1024 | return $bResult; |
| 1025 | } |
| 1026 | #**************************************************************************** |
| 1027 | # subroutine: BuildInfo_die |
| 1028 | # sample code: (message, __FILE__, __LINE__) |
| 1029 | # input: $error_msg, $file, $line_no |
| 1030 | #**************************************************************************** |
| 1031 | sub BuildInfo_die |
| 1032 | { |
| 1033 | my ($error_msg, $file, $line_no) = @_; |
| 1034 | &sysUtil::error_handler($error_msg, $file, $line_no, 'BuildInfoParser'); |
| 1035 | } |
| 1036 | |
| 1037 | sub NoInfoMake_die |
| 1038 | { |
| 1039 | my ($temp_ref, $file, $line_no) = @_; |
| 1040 | &BuildInfo_die("Please parse infomake.log by BuildInfo::ParseInfoMakeLog() before using it.", $file, $line_no) |
| 1041 | if(!defined $temp_ref); |
| 1042 | } |