X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FCommon%2FMisc.py;h=d1752d8a624e7087061779fb48e8ff9f292c5a26;hp=549c8791765ffc0c46f381dbda5ce9d7b7ddb61d;hb=5fbb0f9908ded1944aa4bba599ccc4c605987cb7;hpb=520365decb26e5176ec2bb614f11ddeaa495de54
diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py
index 549c879176..d1752d8a62 100644
--- a/BaseTools/Source/Python/Common/Misc.py
+++ b/BaseTools/Source/Python/Common/Misc.py
@@ -1,7 +1,7 @@
## @file
# Common routines used by all tools
#
-# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
@@ -37,7 +37,8 @@ from Parsing import GetSplitValueList
from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.MultipleWorkspace import MultipleWorkspace as mws
import uuid
-
+from CommonDataClass.Exceptions import BadExpression
+import subprocess
## Regular expression used to find out place holders in string template
gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE | re.UNICODE)
@@ -75,7 +76,7 @@ def GetVariableOffset(mapfilepath, efifilepath, varnames):
def _parseForXcode(lines, efifilepath, varnames):
status = 0
ret = []
- for index, line in enumerate(lines):
+ for line in lines:
line = line.strip()
if status == 0 and line == "# Symbols:":
status = 1
@@ -84,7 +85,7 @@ def _parseForXcode(lines, efifilepath, varnames):
for varname in varnames:
if varname in line:
m = re.match('^([\da-fA-FxX]+)([\s\S]*)([_]*%s)$' % varname, line)
- if m != None:
+ if m is not None:
ret.append((varname, m.group(1)))
return ret
@@ -109,27 +110,27 @@ def _parseForGCC(lines, efifilepath, varnames):
# status handler
if status == 3:
m = re.match('^([\w_\.]+) +([\da-fA-Fx]+) +([\da-fA-Fx]+)$', line)
- if m != None:
+ if m is not None:
sections.append(m.groups(0))
for varname in varnames:
Str = ''
m = re.match("^.data.(%s)" % varname, line)
- if m != None:
+ if m is not None:
m = re.match(".data.(%s)$" % varname, line)
- if m != None:
+ if m is not None:
Str = lines[index + 1]
else:
Str = line[len(".data.%s" % varname):]
if Str:
m = re.match('^([\da-fA-Fx]+) +([\da-fA-Fx]+)', Str.strip())
- if m != None:
+ if m is not None:
varoffset.append((varname, int(m.groups(0)[0], 16) , int(sections[-1][1], 16), sections[-1][0]))
if not varoffset:
return []
# get section information from efi file
efisecs = PeImageClass(efifilepath).SectionHeaderList
- if efisecs == None or len(efisecs) == 0:
+ if efisecs is None or len(efisecs) == 0:
return []
#redirection
redirection = 0
@@ -165,19 +166,19 @@ def _parseGeneral(lines, efifilepath, varnames):
continue
if status == 1 and len(line) != 0:
m = secRe.match(line)
- assert m != None, "Fail to parse the section in map file , line is %s" % line
+ assert m is not None, "Fail to parse the section in map file , line is %s" % line
sec_no, sec_start, sec_length, sec_name, sec_class = m.groups(0)
secs.append([int(sec_no, 16), int(sec_start, 16), int(sec_length, 16), sec_name, sec_class])
if status == 2 and len(line) != 0:
for varname in varnames:
m = symRe.match(line)
- assert m != None, "Fail to parse the symbol in map file, line is %s" % line
+ assert m is not None, "Fail to parse the symbol in map file, line is %s" % line
sec_no, sym_offset, sym_name, vir_addr = m.groups(0)
sec_no = int(sec_no, 16)
sym_offset = int(sym_offset, 16)
vir_addr = int(vir_addr, 16)
m2 = re.match('^[_]*(%s)' % varname, sym_name)
- if m2 != None:
+ if m2 is not None:
# fond a binary pcd entry in map file
for sec in secs:
if sec[0] == sec_no and (sym_offset >= sec[1] and sym_offset < sec[1] + sec[2]):
@@ -187,7 +188,7 @@ def _parseGeneral(lines, efifilepath, varnames):
# get section information from efi file
efisecs = PeImageClass(efifilepath).SectionHeaderList
- if efisecs == None or len(efisecs) == 0:
+ if efisecs is None or len(efisecs) == 0:
return []
ret = []
@@ -422,7 +423,7 @@ def GuidStructureStringToGuidValueName(GuidValue):
# @param Directory The directory name
#
def CreateDirectory(Directory):
- if Directory == None or Directory.strip() == "":
+ if Directory is None or Directory.strip() == "":
return True
try:
if not os.access(Directory, os.F_OK):
@@ -436,7 +437,7 @@ def CreateDirectory(Directory):
# @param Directory The directory name
#
def RemoveDirectory(Directory, Recursively=False):
- if Directory == None or Directory.strip() == "" or not os.path.exists(Directory):
+ if Directory is None or Directory.strip() == "" or not os.path.exists(Directory):
return
if Recursively:
CurrentDirectory = os.getcwd()
@@ -539,7 +540,7 @@ def DataDump(Data, File):
except:
EdkLogger.error("", FILE_OPEN_FAILURE, ExtraData=File, RaiseError=False)
finally:
- if Fd != None:
+ if Fd is not None:
Fd.close()
## Restore a Python object from a file
@@ -559,7 +560,7 @@ def DataRestore(File):
EdkLogger.verbose("Failed to load [%s]\n\t%s" % (File, str(e)))
Data = None
finally:
- if Fd != None:
+ if Fd is not None:
Fd.close()
return Data
@@ -667,7 +668,7 @@ def GetFiles(Root, SkipList=None, FullPath=True):
# @retval False if file doesn't exists
#
def ValidFile(File, Ext=None):
- if Ext != None:
+ if Ext is not None:
Dummy, FileExt = os.path.splitext(File)
if FileExt.lower() != Ext.lower():
return False
@@ -714,13 +715,13 @@ def RealPath2(File, Dir='', OverrideDir=''):
#
def ValidFile2(AllFiles, File, Ext=None, Workspace='', EfiSource='', EdkSource='', Dir='.', OverrideDir=''):
NewFile = File
- if Ext != None:
+ if Ext is not None:
Dummy, FileExt = os.path.splitext(File)
if FileExt.lower() != Ext.lower():
return False, File
# Replace the Edk macros
- if OverrideDir != '' and OverrideDir != None:
+ if OverrideDir != '' and OverrideDir is not None:
if OverrideDir.find('$(EFI_SOURCE)') > -1:
OverrideDir = OverrideDir.replace('$(EFI_SOURCE)', EfiSource)
if OverrideDir.find('$(EDK_SOURCE)') > -1:
@@ -736,19 +737,19 @@ def ValidFile2(AllFiles, File, Ext=None, Workspace='', EfiSource='', EdkSource='
NewFile = File.replace('$(EFI_SOURCE)', EfiSource)
NewFile = NewFile.replace('$(EDK_SOURCE)', EdkSource)
NewFile = AllFiles[os.path.normpath(NewFile)]
- if NewFile != None:
+ if NewFile is not None:
return True, NewFile
# Second check the path with override value
- if OverrideDir != '' and OverrideDir != None:
+ if OverrideDir != '' and OverrideDir is not None:
NewFile = AllFiles[os.path.normpath(os.path.join(OverrideDir, File))]
- if NewFile != None:
+ if NewFile is not None:
return True, NewFile
# Last check the path with normal definitions
File = os.path.join(Dir, File)
NewFile = AllFiles[os.path.normpath(File)]
- if NewFile != None:
+ if NewFile is not None:
return True, NewFile
return False, File
@@ -758,7 +759,7 @@ def ValidFile2(AllFiles, File, Ext=None, Workspace='', EfiSource='', EdkSource='
#
def ValidFile3(AllFiles, File, Workspace='', EfiSource='', EdkSource='', Dir='.', OverrideDir=''):
# Replace the Edk macros
- if OverrideDir != '' and OverrideDir != None:
+ if OverrideDir != '' and OverrideDir is not None:
if OverrideDir.find('$(EFI_SOURCE)') > -1:
OverrideDir = OverrideDir.replace('$(EFI_SOURCE)', EfiSource)
if OverrideDir.find('$(EDK_SOURCE)') > -1:
@@ -780,23 +781,23 @@ def ValidFile3(AllFiles, File, Workspace='', EfiSource='', EdkSource='', Dir='.'
File = File.replace('$(EFI_SOURCE)', EfiSource)
File = File.replace('$(EDK_SOURCE)', EdkSource)
NewFile = AllFiles[os.path.normpath(File)]
- if NewFile != None:
+ if NewFile is not None:
NewRelaPath = os.path.dirname(NewFile)
File = os.path.basename(NewFile)
#NewRelaPath = NewFile[:len(NewFile) - len(File.replace("..\\", '').replace("../", '')) - 1]
break
# Second check the path with override value
- if OverrideDir != '' and OverrideDir != None:
+ if OverrideDir != '' and OverrideDir is not None:
NewFile = AllFiles[os.path.normpath(os.path.join(OverrideDir, File))]
- if NewFile != None:
+ if NewFile is not None:
#NewRelaPath = os.path.dirname(NewFile)
NewRelaPath = NewFile[:len(NewFile) - len(File.replace("..\\", '').replace("../", '')) - 1]
break
# Last check the path with normal definitions
NewFile = AllFiles[os.path.normpath(os.path.join(Dir, File))]
- if NewFile != None:
+ if NewFile is not None:
break
# No file found
@@ -1061,7 +1062,7 @@ class Progressor:
self.CodaMessage = CloseMessage
self.ProgressChar = ProgressChar
self.Interval = Interval
- if Progressor._StopFlag == None:
+ if Progressor._StopFlag is None:
Progressor._StopFlag = threading.Event()
## Start to print progress charater
@@ -1069,10 +1070,10 @@ class Progressor:
# @param OpenMessage The string printed before progress charaters
#
def Start(self, OpenMessage=None):
- if OpenMessage != None:
+ if OpenMessage is not None:
self.PromptMessage = OpenMessage
Progressor._StopFlag.clear()
- if Progressor._ProgressThread == None:
+ if Progressor._ProgressThread is None:
Progressor._ProgressThread = threading.Thread(target=self._ProgressThreadEntry)
Progressor._ProgressThread.setDaemon(False)
Progressor._ProgressThread.start()
@@ -1083,7 +1084,7 @@ class Progressor:
#
def Stop(self, CloseMessage=None):
OriginalCodaMessage = self.CodaMessage
- if CloseMessage != None:
+ if CloseMessage is not None:
self.CodaMessage = CloseMessage
self.Abort()
self.CodaMessage = OriginalCodaMessage
@@ -1106,9 +1107,9 @@ class Progressor:
## Abort the progress display
@staticmethod
def Abort():
- if Progressor._StopFlag != None:
+ if Progressor._StopFlag is not None:
Progressor._StopFlag.set()
- if Progressor._ProgressThread != None:
+ if Progressor._ProgressThread is not None:
Progressor._ProgressThread.join()
Progressor._ProgressThread = None
@@ -1227,7 +1228,7 @@ class sdict(IterableUserDict):
return key, value
def update(self, dict=None, **kwargs):
- if dict != None:
+ if dict is not None:
for k, v in dict.items():
self[k] = v
if len(kwargs):
@@ -1300,7 +1301,7 @@ class tdict:
if self._Level_ > 1:
RestKeys = [self._Wildcard for i in range(0, self._Level_ - 1)]
- if FirstKey == None or str(FirstKey).upper() in self._ValidWildcardList:
+ if FirstKey is None or str(FirstKey).upper() in self._ValidWildcardList:
FirstKey = self._Wildcard
if self._Single_:
@@ -1315,24 +1316,24 @@ class tdict:
if FirstKey == self._Wildcard:
if FirstKey in self.data:
Value = self.data[FirstKey][RestKeys]
- if Value == None:
+ if Value is None:
for Key in self.data:
Value = self.data[Key][RestKeys]
- if Value != None: break
+ if Value is not None: break
else:
if FirstKey in self.data:
Value = self.data[FirstKey][RestKeys]
- if Value == None and self._Wildcard in self.data:
+ if Value is None and self._Wildcard in self.data:
#print "Value=None"
Value = self.data[self._Wildcard][RestKeys]
else:
if FirstKey == self._Wildcard:
if FirstKey in self.data:
Value = self.data[FirstKey]
- if Value == None:
+ if Value is None:
for Key in self.data:
Value = self.data[Key]
- if Value != None: break
+ if Value is not None: break
else:
if FirstKey in self.data:
Value = self.data[FirstKey]
@@ -1440,23 +1441,44 @@ def ParseConsoleLog(Filename):
Opr.close()
Opw.close()
+def IsFieldValueAnArray (Value):
+ Value = Value.strip()
+ if Value.startswith('GUID') and Value.endswith(')'):
+ return True
+ if Value.startswith('L"') and Value.endswith('"') and len(list(Value[2:-1])) > 1:
+ return True
+ if Value[0] == '"' and Value[-1] == '"' and len(list(Value[1:-1])) > 1:
+ return True
+ if Value[0] == '{' and Value[-1] == '}':
+ return True
+ if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1:
+ return True
+ if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1:
+ return True
+ return False
+
def AnalyzePcdExpression(Setting):
Setting = Setting.strip()
- # There might be escaped quote in a string: \", \\\"
- Data = Setting.replace('\\\\', '//').replace('\\\"', '\\\'')
+ # There might be escaped quote in a string: \", \\\" , \', \\\'
+ Data = Setting
# There might be '|' in string and in ( ... | ... ), replace it with '-'
NewStr = ''
- InStr = False
+ InSingleQuoteStr = False
+ InDoubleQuoteStr = False
Pair = 0
- for ch in Data:
- if ch == '"':
- InStr = not InStr
- elif ch == '(' and not InStr:
+ for Index, ch in enumerate(Data):
+ if ch == '"' and not InSingleQuoteStr:
+ if Data[Index - 1] != '\\':
+ InDoubleQuoteStr = not InDoubleQuoteStr
+ elif ch == "'" and not InDoubleQuoteStr:
+ if Data[Index - 1] != '\\':
+ InSingleQuoteStr = not InSingleQuoteStr
+ elif ch == '(' and not (InSingleQuoteStr or InDoubleQuoteStr):
Pair += 1
- elif ch == ')' and not InStr:
+ elif ch == ')' and not (InSingleQuoteStr or InDoubleQuoteStr):
Pair -= 1
- if (Pair > 0 or InStr) and ch == TAB_VALUE_SPLIT:
+ if (Pair > 0 or InSingleQuoteStr or InDoubleQuoteStr) and ch == TAB_VALUE_SPLIT:
NewStr += '-'
else:
NewStr += ch
@@ -1472,99 +1494,157 @@ def AnalyzePcdExpression(Setting):
return FieldList
+def ParseDevPathValue (Value):
+ if '\\' in Value:
+ Value.replace('\\', '/').replace(' ', '')
+
+ Cmd = 'DevicePath ' + '"' + Value + '"'
+ try:
+ p = subprocess.Popen(Cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
+ out, err = p.communicate()
+ except Exception, X:
+ raise BadExpression("DevicePath: %s" % (str(X)) )
+ finally:
+ subprocess._cleanup()
+ p.stdout.close()
+ p.stderr.close()
+ if err:
+ raise BadExpression("DevicePath: %s" % str(err))
+ Size = len(out.split())
+ out = ','.join(out.split())
+ return '{' + out + '}', Size
+
def ParseFieldValue (Value):
- if type(Value) == type(0):
- return Value, (Value.bit_length() + 7) / 8
- if type(Value) <> type(''):
- raise ValueError
- Value = Value.strip()
- if Value.startswith('UINT8') and Value.endswith(')'):
- Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
- if Size > 1:
- raise ValueError
+ if type(Value) == type(0):
+ return Value, (Value.bit_length() + 7) / 8
+ if type(Value) <> type(''):
+ raise BadExpression('Type %s is %s' %(Value, type(Value)))
+ Value = Value.strip()
+ if Value.startswith('UINT8') and Value.endswith(')'):
+ Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
+ if Size > 1:
+ raise BadExpression('Value (%s) Size larger than %d' %(Value, Size))
+ return Value, 1
+ if Value.startswith('UINT16') and Value.endswith(')'):
+ Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
+ if Size > 2:
+ raise BadExpression('Value (%s) Size larger than %d' %(Value, Size))
+ return Value, 2
+ if Value.startswith('UINT32') and Value.endswith(')'):
+ Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
+ if Size > 4:
+ raise BadExpression('Value (%s) Size larger than %d' %(Value, Size))
+ return Value, 4
+ if Value.startswith('UINT64') and Value.endswith(')'):
+ Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
+ if Size > 8:
+ raise BadExpression('Value (%s) Size larger than %d' % (Value, Size))
+ return Value, 8
+ if Value.startswith('GUID') and Value.endswith(')'):
+ Value = Value.split('(', 1)[1][:-1].strip()
+ if Value[0] == '{' and Value[-1] == '}':
+ TmpValue = GuidStructureStringToGuidString(Value)
+ if len(TmpValue) == 0:
+ raise BadExpression("Invalid GUID value string %s" % Value)
+ Value = TmpValue
+ if Value[0] == '"' and Value[-1] == '"':
+ Value = Value[1:-1]
+ try:
+ Value = "'" + uuid.UUID(Value).get_bytes_le() + "'"
+ except ValueError, Message:
+ raise BadExpression('%s' % Message)
+ Value, Size = ParseFieldValue(Value)
+ return Value, 16
+ if Value.startswith('L"') and Value.endswith('"'):
+ # Unicode String
+ # translate escape character
+ Value = Value[1:]
+ try:
+ Value = eval(Value)
+ except:
+ Value = Value[1:-1]
+ List = list(Value)
+ List.reverse()
+ Value = 0
+ for Char in List:
+ Value = (Value << 16) | ord(Char)
+ return Value, (len(List) + 1) * 2
+ if Value.startswith('"') and Value.endswith('"'):
+ # ASCII String
+ # translate escape character
+ try:
+ Value = eval(Value)
+ except:
+ Value = Value[1:-1]
+ List = list(Value)
+ List.reverse()
+ Value = 0
+ for Char in List:
+ Value = (Value << 8) | ord(Char)
+ return Value, len(List) + 1
+ if Value.startswith("L'") and Value.endswith("'"):
+ # Unicode Character Constant
+ # translate escape character
+ Value = Value[1:]
+ try:
+ Value = eval(Value)
+ except:
+ Value = Value[1:-1]
+ List = list(Value)
+ if len(List) == 0:
+ raise BadExpression('Length %s is %s' % (Value, len(List)))
+ List.reverse()
+ Value = 0
+ for Char in List:
+ Value = (Value << 16) | ord(Char)
+ return Value, len(List) * 2
+ if Value.startswith("'") and Value.endswith("'"):
+ # Character constant
+ # translate escape character
+ try:
+ Value = eval(Value)
+ except:
+ Value = Value[1:-1]
+ List = list(Value)
+ if len(List) == 0:
+ raise BadExpression('Length %s is %s' % (Value, len(List)))
+ List.reverse()
+ Value = 0
+ for Char in List:
+ Value = (Value << 8) | ord(Char)
+ return Value, len(List)
+ if Value.startswith('{') and Value.endswith('}'):
+ # Byte array
+ Value = Value[1:-1]
+ List = [Item.strip() for Item in Value.split(',')]
+ List.reverse()
+ Value = 0
+ RetSize = 0
+ for Item in List:
+ ItemValue, Size = ParseFieldValue(Item)
+ RetSize += Size
+ for I in range(Size):
+ Value = (Value << 8) | ((ItemValue >> 8 * I) & 0xff)
+ return Value, RetSize
+ if Value.startswith('DEVICE_PATH(') and Value.endswith(')'):
+ Value = Value.replace("DEVICE_PATH(", '').rstrip(')')
+ Value = Value.strip().strip('"')
+ return ParseDevPathValue(Value)
+ if Value.lower().startswith('0x'):
+ Value = int(Value, 16)
+ if Value == 0:
+ return 0, 1
+ return Value, (Value.bit_length() + 7) / 8
+ if Value[0].isdigit():
+ Value = int(Value, 10)
+ if Value == 0:
+ return 0, 1
+ return Value, (Value.bit_length() + 7) / 8
+ if Value.lower() == 'true':
+ return 1, 1
+ if Value.lower() == 'false':
+ return 0, 1
return Value, 1
- if Value.startswith('UINT16') and Value.endswith(')'):
- Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
- if Size > 2:
- raise ValueError
- return Value, 2
- if Value.startswith('UINT32') and Value.endswith(')'):
- Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
- if Size > 4:
- raise ValueError
- return Value, 4
- if Value.startswith('UINT64') and Value.endswith(')'):
- Value, Size = ParseFieldValue(Value.split('(', 1)[1][:-1])
- if Size > 8:
- raise ValueError
- return Value, 8
- if Value.startswith('GUID') and Value.endswith(')'):
- Value = Value.split('(', 1)[1][:-1].strip()
- if Value[0] == '{' and Value[-1] == '}':
- Value = Value[1:-1].strip()
- Value = Value.split('{', 1)
- Value = [Item.strip()[2:] for Item in (Value[0] + Value[1][:-1]).split(',')]
- Value = '-'.join(Value[0:3]) + '-' + ''.join(Value[3:5]) + '-' + ''.join(Value[5:11])
- if Value[0] == '"' and Value[-1] == '"':
- Value = Value[1:-1]
- Value = "'" + uuid.UUID(Value).get_bytes_le() + "'"
- Value, Size = ParseFieldValue(Value)
- return Value, 16
- if Value.startswith('L"') and Value.endswith('"'):
- # Unicode String
- List = list(Value[2:-1])
- List.reverse()
- Value = 0
- for Char in List:
- Value = (Value << 16) | ord(Char)
- return Value, (len(List) + 1) * 2
- if Value.startswith('"') and Value.endswith('"'):
- # ASCII String
- List = list(Value[1:-1])
- List.reverse()
- Value = 0
- for Char in List:
- Value = (Value << 8) | ord(Char)
- return Value, len(List) + 1
- if Value.startswith("L'") and Value.endswith("'"):
- # Unicode Character Constant
- List = list(Value[2:-1])
- List.reverse()
- Value = 0
- for Char in List:
- Value = (Value << 16) | ord(Char)
- return Value, len(List) * 2
- if Value.startswith("'") and Value.endswith("'"):
- # Character constant
- List = list(Value[1:-1])
- List.reverse()
- Value = 0
- for Char in List:
- Value = (Value << 8) | ord(Char)
- return Value, len(List)
- if Value.startswith('{') and Value.endswith('}'):
- # Byte array
- Value = Value[1:-1]
- List = [Item.strip() for Item in Value.split(',')]
- List.reverse()
- Value = 0
- for Item in List:
- ItemValue, Size = ParseFieldValue(Item)
- if Size > 1:
- raise ValueError
- Value = (Value << 8) | ItemValue
- return Value, len(List)
- if Value.lower().startswith('0x'):
- Value = int(Value, 16)
- return Value, (Value.bit_length() + 7) / 8
- if Value[0].isdigit():
- Value = int(Value, 10)
- return Value, (Value.bit_length() + 7) / 8
- if Value.lower() == 'true':
- return 1, 1
- if Value.lower() == 'false':
- return 0, 1
- return Value, 1
## AnalyzeDscPcd
#
@@ -1627,14 +1707,6 @@ def AnalyzeDscPcd(Setting, PcdType, DataType=''):
Type = DataType
if len(FieldList) > 2:
Size = FieldList[2]
- else:
- if Type == 'VOID*':
- if Value.startswith("L"):
- Size = str((len(Value)- 3 + 1) * 2)
- elif Value.startswith("{"):
- Size = str(len(Value.split(",")))
- else:
- Size = str(len(Value) -2 + 1 )
if DataType == "":
IsValid = (len(FieldList) <= 1)
else:
@@ -1767,10 +1839,10 @@ def CheckPcdDatum(Type, Value):
if Type == "VOID*":
ValueRe = re.compile(r'\s*L?\".*\"\s*$')
if not (((Value.startswith('L"') or Value.startswith('"')) and Value.endswith('"'))
- or (Value.startswith('{') and Value.endswith('}'))
+ or (Value.startswith('{') and Value.endswith('}')) or (Value.startswith("L'") or Value.startswith("'") and Value.endswith("'"))
):
return False, "Invalid value [%s] of type [%s]; must be in the form of {...} for array"\
- ", or \"...\" for string, or L\"...\" for unicode string" % (Value, Type)
+ ", \"...\" or \'...\' for string, L\"...\" or L\'...\' for unicode string" % (Value, Type)
elif ValueRe.match(Value):
# Check the chars in UnicodeString or CString is printable
if Value.startswith("L"):
@@ -1981,7 +2053,7 @@ class PathClass(object):
return hash(self.Path)
def _GetFileKey(self):
- if self._Key == None:
+ if self._Key is None:
self._Key = self.Path.upper() # + self.ToolChainFamily + self.TagName + self.ToolCode + self.Target
return self._Key
@@ -2145,12 +2217,21 @@ class SkuClass():
def __init__(self,SkuIdentifier='', SkuIds=None):
if SkuIds is None:
SkuIds = {}
+
+ for SkuName in SkuIds:
+ SkuId = SkuIds[SkuName][0]
+ skuid_num = int(SkuId,16) if SkuId.upper().startswith("0X") else int(SkuId)
+ if skuid_num > 0xFFFFFFFFFFFFFFFF:
+ EdkLogger.error("build", PARAMETER_INVALID,
+ ExtraData = "SKU-ID [%s] value %s exceeds the max value of UINT64"
+ % (SkuName, SkuId))
self.AvailableSkuIds = sdict()
self.SkuIdSet = []
self.SkuIdNumberSet = []
self.SkuData = SkuIds
self.__SkuInherit = {}
+ self.__SkuIdentifier = SkuIdentifier
if SkuIdentifier == '' or SkuIdentifier is None:
self.SkuIdSet = ['DEFAULT']
self.SkuIdNumberSet = ['0U']
@@ -2180,6 +2261,10 @@ class SkuClass():
GlobalData.gSkuids = (self.SkuIdSet)
if 'COMMON' in GlobalData.gSkuids:
GlobalData.gSkuids.remove('COMMON')
+ if self.SkuUsageType == self.SINGLE:
+ if len(GlobalData.gSkuids) != 1:
+ if 'DEFAULT' in GlobalData.gSkuids:
+ GlobalData.gSkuids.remove('DEFAULT')
if GlobalData.gSkuids:
GlobalData.gSkuids.sort()
@@ -2189,14 +2274,50 @@ class SkuClass():
for item in self.SkuData.values():
self.__SkuInherit[item[1]]=item[2] if item[2] else "DEFAULT"
return self.__SkuInherit.get(skuname,"DEFAULT")
+
+ def GetSkuChain(self,sku):
+ if sku == "DEFAULT":
+ return ["DEFAULT"]
+ skulist = [sku]
+ nextsku = sku
+ while 1:
+ nextsku = self.GetNextSkuId(nextsku)
+ skulist.append(nextsku)
+ if nextsku == "DEFAULT":
+ break
+ skulist.reverse()
+ return skulist
+ def SkuOverrideOrder(self):
+ skuorderset = []
+ for skuname in self.SkuIdSet:
+ skuorderset.append(self.GetSkuChain(skuname))
+ skuorder = []
+ for index in range(max([len(item) for item in skuorderset])):
+ for subset in skuorderset:
+ if index > len(subset)-1:
+ continue
+ if subset[index] in skuorder:
+ continue
+ skuorder.append(subset[index])
+
+ return skuorder
+
def __SkuUsageType(self):
+ if self.__SkuIdentifier.upper() == "ALL":
+ return SkuClass.MULTIPLE
+
if len(self.SkuIdSet) == 1:
if self.SkuIdSet[0] == 'DEFAULT':
return SkuClass.DEFAULT
else:
return SkuClass.SINGLE
+ elif len(self.SkuIdSet) == 2:
+ if 'DEFAULT' in self.SkuIdSet:
+ return SkuClass.SINGLE
+ else:
+ return SkuClass.MULTIPLE
else:
return SkuClass.MULTIPLE
def DumpSkuIdArrary(self):
@@ -2219,7 +2340,10 @@ class SkuClass():
def __GetSystemSkuID(self):
if self.__SkuUsageType() == SkuClass.SINGLE:
- return self.SkuIdSet[0]
+ if len(self.SkuIdSet) == 1:
+ return self.SkuIdSet[0]
+ else:
+ return self.SkuIdSet[0] if self.SkuIdSet[0] != 'DEFAULT' else self.SkuIdSet[1]
else:
return 'DEFAULT'
def __GetAvailableSkuIdNumber(self):
@@ -2248,31 +2372,6 @@ def PackRegistryFormatGuid(Guid):
int(Guid[4][-2:], 16)
)
-def BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, Value):
- if PcdDatumType == 'VOID*':
- if Value.startswith('L'):
- if not Value[1]:
- EdkLogger.error("build", FORMAT_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", H"{...}"')
- Value = Value[0] + '"' + Value[1:] + '"'
- elif Value.startswith('H'):
- if not Value[1]:
- EdkLogger.error("build", FORMAT_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", H"{...}"')
- Value = Value[1:]
- else:
- if not Value[0]:
- EdkLogger.error("build", FORMAT_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", H"{...}"')
- Value = '"' + Value + '"'
-
- IsValid, Cause = CheckPcdDatum(PcdDatumType, Value)
- if not IsValid:
- EdkLogger.error("build", FORMAT_INVALID, Cause, ExtraData="%s.%s" % (TokenSpaceGuidCName, TokenCName))
- if PcdDatumType == 'BOOLEAN':
- Value = Value.upper()
- if Value == 'TRUE' or Value == '1':
- Value = '1'
- elif Value == 'FALSE' or Value == '0':
- Value = '0'
- return Value
## Get the integer value from string like "14U" or integer like 2
#
# @param Input The object that may be either a integer value or a string