2 # Common routines used by all tools
4 # Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 import Common
.LongFilePathOs
as os
27 from struct
import pack
28 from UserDict
import IterableUserDict
29 from UserList
import UserList
31 from Common
import EdkLogger
as EdkLogger
32 from Common
import GlobalData
as GlobalData
33 from DataType
import *
34 from BuildToolError
import *
35 from CommonDataClass
.DataClass
import *
36 from Parsing
import GetSplitValueList
37 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
38 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
41 ## Regular expression used to find out place holders in string template
42 gPlaceholderPattern
= re
.compile("\$\{([^$()\s]+)\}", re
.MULTILINE | re
.UNICODE
)
44 ## Dictionary used to store file time stamp for quick re-access
45 gFileTimeStampCache
= {} # {file path : file time stamp}
47 ## Dictionary used to store dependencies of files
48 gDependencyDatabase
= {} # arch : {file path : [dependent files list]}
50 def GetVariableOffset(mapfilepath
, efifilepath
, varnames
):
51 """ Parse map file to get variable offset in current EFI file
52 @param mapfilepath Map file absolution path
53 @param efifilepath: EFI binary file full path
54 @param varnames iteratable container whose elements are variable names to be searched
56 @return List whos elements are tuple with variable name and raw offset
60 f
= open(mapfilepath
, 'r')
66 if len(lines
) == 0: return None
67 firstline
= lines
[0].strip()
68 if (firstline
.startswith("Archive member included ") and
69 firstline
.endswith(" file (symbol)")):
70 return _parseForGCC(lines
, efifilepath
, varnames
)
71 if firstline
.startswith("# Path:"):
72 return _parseForXcode(lines
, efifilepath
, varnames
)
73 return _parseGeneral(lines
, efifilepath
, varnames
)
75 def _parseForXcode(lines
, efifilepath
, varnames
):
78 for index
, line
in enumerate(lines
):
80 if status
== 0 and line
== "# Symbols:":
83 if status
== 1 and len(line
) != 0:
84 for varname
in varnames
:
86 m
= re
.match('^([\da-fA-FxX]+)([\s\S]*)([_]*%s)$' % varname
, line
)
88 ret
.append((varname
, m
.group(1)))
91 def _parseForGCC(lines
, efifilepath
, varnames
):
92 """ Parse map file generated by GCC linker """
96 for index
, line
in enumerate(lines
):
98 # status machine transection
99 if status
== 0 and line
== "Memory Configuration":
102 elif status
== 1 and line
== 'Linker script and memory map':
105 elif status
==2 and line
== 'START GROUP':
111 m
= re
.match('^([\w_\.]+) +([\da-fA-Fx]+) +([\da-fA-Fx]+)$', line
)
113 sections
.append(m
.groups(0))
114 for varname
in varnames
:
116 m
= re
.match("^.data.(%s)" % varname
, line
)
118 m
= re
.match(".data.(%s)$" % varname
, line
)
120 Str
= lines
[index
+ 1]
122 Str
= line
[len(".data.%s" % varname
):]
124 m
= re
.match('^([\da-fA-Fx]+) +([\da-fA-Fx]+)', Str
.strip())
126 varoffset
.append((varname
, int(m
.groups(0)[0], 16) , int(sections
[-1][1], 16), sections
[-1][0]))
130 # get section information from efi file
131 efisecs
= PeImageClass(efifilepath
).SectionHeaderList
132 if efisecs
== None or len(efisecs
) == 0:
136 for efisec
in efisecs
:
137 for section
in sections
:
138 if section
[0].strip() == efisec
[0].strip() and section
[0].strip() == '.text':
139 redirection
= int(section
[1], 16) - efisec
[1]
142 for var
in varoffset
:
143 for efisec
in efisecs
:
144 if var
[1] >= efisec
[1] and var
[1] < efisec
[1]+efisec
[3]:
145 ret
.append((var
[0], hex(efisec
[2] + var
[1] - efisec
[1] - redirection
)))
148 def _parseGeneral(lines
, efifilepath
, varnames
):
149 status
= 0 #0 - beginning of file; 1 - PE section definition; 2 - symbol table
150 secs
= [] # key = section name
152 secRe
= re
.compile('^([\da-fA-F]+):([\da-fA-F]+) +([\da-fA-F]+)[Hh]? +([.\w\$]+) +(\w+)', re
.UNICODE
)
153 symRe
= re
.compile('^([\da-fA-F]+):([\da-fA-F]+) +([\.:\\\\\w\?@\$]+) +([\da-fA-F]+)', re
.UNICODE
)
157 if re
.match("^Start[' ']+Length[' ']+Name[' ']+Class", line
):
160 if re
.match("^Address[' ']+Publics by Value[' ']+Rva\+Base", line
):
163 if re
.match("^entry point at", line
):
166 if status
== 1 and len(line
) != 0:
167 m
= secRe
.match(line
)
168 assert m
!= None, "Fail to parse the section in map file , line is %s" % line
169 sec_no
, sec_start
, sec_length
, sec_name
, sec_class
= m
.groups(0)
170 secs
.append([int(sec_no
, 16), int(sec_start
, 16), int(sec_length
, 16), sec_name
, sec_class
])
171 if status
== 2 and len(line
) != 0:
172 for varname
in varnames
:
173 m
= symRe
.match(line
)
174 assert m
!= None, "Fail to parse the symbol in map file, line is %s" % line
175 sec_no
, sym_offset
, sym_name
, vir_addr
= m
.groups(0)
176 sec_no
= int(sec_no
, 16)
177 sym_offset
= int(sym_offset
, 16)
178 vir_addr
= int(vir_addr
, 16)
179 m2
= re
.match('^[_]*(%s)' % varname
, sym_name
)
181 # fond a binary pcd entry in map file
183 if sec
[0] == sec_no
and (sym_offset
>= sec
[1] and sym_offset
< sec
[1] + sec
[2]):
184 varoffset
.append([varname
, sec
[3], sym_offset
, vir_addr
, sec_no
])
186 if not varoffset
: return []
188 # get section information from efi file
189 efisecs
= PeImageClass(efifilepath
).SectionHeaderList
190 if efisecs
== None or len(efisecs
) == 0:
194 for var
in varoffset
:
196 for efisec
in efisecs
:
198 if var
[1].strip() == efisec
[0].strip():
199 ret
.append((var
[0], hex(efisec
[2] + var
[2])))
200 elif var
[4] == index
:
201 ret
.append((var
[0], hex(efisec
[2] + var
[2])))
205 ## Routine to process duplicated INF
207 # This function is called by following two cases:
210 # Pkg/module/module.inf
211 # Pkg/module/module.inf {
213 # FILE_GUID = 0D1B936F-68F3-4589-AFCC-FB8B7AEBC836
216 # INF Pkg/module/module.inf
217 # INF FILE_GUID = 0D1B936F-68F3-4589-AFCC-FB8B7AEBC836 Pkg/module/module.inf
219 # This function copies Pkg/module/module.inf to
220 # Conf/.cache/0D1B936F-68F3-4589-AFCC-FB8B7AEBC836module.inf
222 # @param Path Original PathClass object
223 # @param BaseName New file base name
225 # @retval return the new PathClass object
227 def ProcessDuplicatedInf(Path
, BaseName
, Workspace
):
228 Filename
= os
.path
.split(Path
.File
)[1]
230 Filename
= BaseName
+ Path
.BaseName
+ Filename
[Filename
.rfind('.'):]
232 Filename
= BaseName
+ Path
.BaseName
235 # If -N is specified on command line, cache is disabled
236 # The directory has to be created
238 DbDir
= os
.path
.split(GlobalData
.gDatabasePath
)[0]
239 if not os
.path
.exists(DbDir
):
242 # A temporary INF is copied to database path which must have write permission
243 # The temporary will be removed at the end of build
244 # In case of name conflict, the file name is
245 # FILE_GUIDBaseName (0D1B936F-68F3-4589-AFCC-FB8B7AEBC836module.inf)
247 TempFullPath
= os
.path
.join(DbDir
,
249 RtPath
= PathClass(Path
.File
, Workspace
)
251 # Modify the full path to temporary path, keep other unchanged
253 # To build same module more than once, the module path with FILE_GUID overridden has
254 # the file name FILE_GUIDmodule.inf, but the relative path (self.MetaFile.File) is the real path
255 # in DSC which is used as relative path by C files and other files in INF.
256 # A trick was used: all module paths are PathClass instances, after the initialization
257 # of PathClass, the PathClass.Path is overridden by the temporary INF path.
259 # The reason for creating a temporary INF is:
260 # Platform.Modules which is the base to create ModuleAutoGen objects is a dictionary,
261 # the key is the full path of INF, the value is an object to save overridden library instances, PCDs.
262 # A different key for the same module is needed to create different output directory,
263 # retrieve overridden PCDs, library instances.
265 # The BaseName is the FILE_GUID which is also the output directory name.
268 RtPath
.Path
= TempFullPath
269 RtPath
.BaseName
= BaseName
271 # If file exists, compare contents
273 if os
.path
.exists(TempFullPath
):
274 with
open(str(Path
), 'rb') as f1
: Src
= f1
.read()
275 with
open(TempFullPath
, 'rb') as f2
: Dst
= f2
.read()
278 GlobalData
.gTempInfs
.append(TempFullPath
)
279 shutil
.copy2(str(Path
), TempFullPath
)
282 ## Remove temporary created INFs whose paths were saved in gTempInfs
284 def ClearDuplicatedInf():
285 for File
in GlobalData
.gTempInfs
:
286 if os
.path
.exists(File
):
289 ## callback routine for processing variable option
291 # This function can be used to process variable number of option values. The
292 # typical usage of it is specify architecure list on command line.
293 # (e.g. <tool> -a IA32 X64 IPF)
295 # @param Option Standard callback function parameter
296 # @param OptionString Standard callback function parameter
297 # @param Value Standard callback function parameter
298 # @param Parser Standard callback function parameter
302 def ProcessVariableArgument(Option
, OptionString
, Value
, Parser
):
305 RawArgs
= Parser
.rargs
308 if (Arg
[:2] == "--" and len(Arg
) > 2) or \
309 (Arg
[:1] == "-" and len(Arg
) > 1 and Arg
[1] != "-"):
313 setattr(Parser
.values
, Option
.dest
, Value
)
315 ## Convert GUID string in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx style to C structure style
317 # @param Guid The GUID string
319 # @retval string The GUID string in C structure style
321 def GuidStringToGuidStructureString(Guid
):
322 GuidList
= Guid
.split('-')
324 for Index
in range(0, 3, 1):
325 Result
= Result
+ '0x' + GuidList
[Index
] + ', '
326 Result
= Result
+ '{0x' + GuidList
[3][0:2] + ', 0x' + GuidList
[3][2:4]
327 for Index
in range(0, 12, 2):
328 Result
= Result
+ ', 0x' + GuidList
[4][Index
:Index
+ 2]
332 ## Convert GUID structure in byte array to xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
334 # @param GuidValue The GUID value in byte array
336 # @retval string The GUID value in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format
338 def GuidStructureByteArrayToGuidString(GuidValue
):
339 guidValueString
= GuidValue
.lower().replace("{", "").replace("}", "").replace(" ", "").replace(";", "")
340 guidValueList
= guidValueString
.split(",")
341 if len(guidValueList
) != 16:
343 #EdkLogger.error(None, None, "Invalid GUID value string %s" % GuidValue)
345 return "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" % (
346 int(guidValueList
[3], 16),
347 int(guidValueList
[2], 16),
348 int(guidValueList
[1], 16),
349 int(guidValueList
[0], 16),
350 int(guidValueList
[5], 16),
351 int(guidValueList
[4], 16),
352 int(guidValueList
[7], 16),
353 int(guidValueList
[6], 16),
354 int(guidValueList
[8], 16),
355 int(guidValueList
[9], 16),
356 int(guidValueList
[10], 16),
357 int(guidValueList
[11], 16),
358 int(guidValueList
[12], 16),
359 int(guidValueList
[13], 16),
360 int(guidValueList
[14], 16),
361 int(guidValueList
[15], 16)
366 ## Convert GUID string in C structure style to xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
368 # @param GuidValue The GUID value in C structure format
370 # @retval string The GUID value in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format
372 def GuidStructureStringToGuidString(GuidValue
):
373 guidValueString
= GuidValue
.lower().replace("{", "").replace("}", "").replace(" ", "").replace(";", "")
374 guidValueList
= guidValueString
.split(",")
375 if len(guidValueList
) != 11:
377 #EdkLogger.error(None, None, "Invalid GUID value string %s" % GuidValue)
379 return "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x" % (
380 int(guidValueList
[0], 16),
381 int(guidValueList
[1], 16),
382 int(guidValueList
[2], 16),
383 int(guidValueList
[3], 16),
384 int(guidValueList
[4], 16),
385 int(guidValueList
[5], 16),
386 int(guidValueList
[6], 16),
387 int(guidValueList
[7], 16),
388 int(guidValueList
[8], 16),
389 int(guidValueList
[9], 16),
390 int(guidValueList
[10], 16)
395 ## Convert GUID string in C structure style to xxxxxxxx_xxxx_xxxx_xxxx_xxxxxxxxxxxx
397 # @param GuidValue The GUID value in C structure format
399 # @retval string The GUID value in xxxxxxxx_xxxx_xxxx_xxxx_xxxxxxxxxxxx format
401 def GuidStructureStringToGuidValueName(GuidValue
):
402 guidValueString
= GuidValue
.lower().replace("{", "").replace("}", "").replace(" ", "")
403 guidValueList
= guidValueString
.split(",")
404 if len(guidValueList
) != 11:
405 EdkLogger
.error(None, FORMAT_INVALID
, "Invalid GUID value string [%s]" % GuidValue
)
406 return "%08x_%04x_%04x_%02x%02x_%02x%02x%02x%02x%02x%02x" % (
407 int(guidValueList
[0], 16),
408 int(guidValueList
[1], 16),
409 int(guidValueList
[2], 16),
410 int(guidValueList
[3], 16),
411 int(guidValueList
[4], 16),
412 int(guidValueList
[5], 16),
413 int(guidValueList
[6], 16),
414 int(guidValueList
[7], 16),
415 int(guidValueList
[8], 16),
416 int(guidValueList
[9], 16),
417 int(guidValueList
[10], 16)
420 ## Create directories
422 # @param Directory The directory name
424 def CreateDirectory(Directory
):
425 if Directory
== None or Directory
.strip() == "":
428 if not os
.access(Directory
, os
.F_OK
):
429 os
.makedirs(Directory
)
434 ## Remove directories, including files and sub-directories in it
436 # @param Directory The directory name
438 def RemoveDirectory(Directory
, Recursively
=False):
439 if Directory
== None or Directory
.strip() == "" or not os
.path
.exists(Directory
):
442 CurrentDirectory
= os
.getcwd()
444 for File
in os
.listdir("."):
445 if os
.path
.isdir(File
):
446 RemoveDirectory(File
, Recursively
)
449 os
.chdir(CurrentDirectory
)
452 ## Check if given file is changed or not
454 # This method is used to check if a file is changed or not between two build
455 # actions. It makes use a cache to store files timestamp.
457 # @param File The path of file
459 # @retval True If the given file is changed, doesn't exist, or can't be
460 # found in timestamp cache
461 # @retval False If the given file is changed
464 if not os
.path
.exists(File
):
467 FileState
= os
.stat(File
)
468 TimeStamp
= FileState
[-2]
470 if File
in gFileTimeStampCache
and TimeStamp
== gFileTimeStampCache
[File
]:
474 gFileTimeStampCache
[File
] = TimeStamp
478 ## Store content in file
480 # This method is used to save file only when its content is changed. This is
481 # quite useful for "make" system to decide what will be re-built and what won't.
483 # @param File The path of file
484 # @param Content The new content of the file
485 # @param IsBinaryFile The flag indicating if the file is binary file or not
487 # @retval True If the file content is changed and the file is renewed
488 # @retval False If the file content is the same
490 def SaveFileOnChange(File
, Content
, IsBinaryFile
=True):
492 Content
= Content
.replace("\n", os
.linesep
)
494 if os
.path
.exists(File
):
496 if Content
== open(File
, "rb").read():
499 EdkLogger
.error(None, FILE_OPEN_FAILURE
, ExtraData
=File
)
501 DirName
= os
.path
.dirname(File
)
502 if not CreateDirectory(DirName
):
503 EdkLogger
.error(None, FILE_CREATE_FAILURE
, "Could not create directory %s" % DirName
)
506 DirName
= os
.getcwd()
507 if not os
.access(DirName
, os
.W_OK
):
508 EdkLogger
.error(None, PERMISSION_FAILURE
, "Do not have write permission on directory %s" % DirName
)
511 if GlobalData
.gIsWindows
:
513 from PyUtility
import SaveFileToDisk
514 if not SaveFileToDisk(File
, Content
):
515 EdkLogger
.error(None, FILE_CREATE_FAILURE
, ExtraData
=File
)
517 Fd
= open(File
, "wb")
521 Fd
= open(File
, "wb")
525 EdkLogger
.error(None, FILE_CREATE_FAILURE
, ExtraData
='IOError %s' % X
)
529 ## Make a Python object persistent on file system
531 # @param Data The object to be stored in file
532 # @param File The path of file to store the object
534 def DataDump(Data
, File
):
537 Fd
= open(File
, 'wb')
538 cPickle
.dump(Data
, Fd
, cPickle
.HIGHEST_PROTOCOL
)
540 EdkLogger
.error("", FILE_OPEN_FAILURE
, ExtraData
=File
, RaiseError
=False)
545 ## Restore a Python object from a file
547 # @param File The path of file stored the object
549 # @retval object A python object
550 # @retval None If failure in file operation
552 def DataRestore(File
):
556 Fd
= open(File
, 'rb')
557 Data
= cPickle
.load(Fd
)
559 EdkLogger
.verbose("Failed to load [%s]\n\t%s" % (File
, str(e
)))
566 ## Retrieve and cache the real path name in file system
568 # @param Root The root directory of path relative to
570 # @retval str The path string if the path exists
571 # @retval None If path doesn't exist
577 def __init__(self
, Root
):
579 for F
in os
.listdir(Root
):
581 self
._UPPER
_CACHE
_[F
.upper()] = F
584 def __getitem__(self
, Path
):
585 Path
= Path
[len(os
.path
.commonprefix([Path
, self
._Root
])):]
588 if Path
and Path
[0] == os
.path
.sep
:
590 if Path
in self
._CACHE
_:
591 return os
.path
.join(self
._Root
, Path
)
592 UpperPath
= Path
.upper()
593 if UpperPath
in self
._UPPER
_CACHE
_:
594 return os
.path
.join(self
._Root
, self
._UPPER
_CACHE
_[UpperPath
])
598 SepIndex
= Path
.find(os
.path
.sep
)
600 Parent
= UpperPath
[:SepIndex
]
601 if Parent
not in self
._UPPER
_CACHE
_:
603 LastSepIndex
= SepIndex
604 SepIndex
= Path
.find(os
.path
.sep
, LastSepIndex
+ 1)
606 if LastSepIndex
== -1:
611 SepIndex
= LastSepIndex
613 Parent
= Path
[:SepIndex
]
614 ParentKey
= UpperPath
[:SepIndex
]
615 if ParentKey
not in self
._UPPER
_CACHE
_:
619 if Parent
in self
._CACHE
_:
622 ParentDir
= self
._UPPER
_CACHE
_[ParentKey
]
623 for F
in os
.listdir(ParentDir
):
624 Dir
= os
.path
.join(ParentDir
, F
)
625 self
._CACHE
_.add(Dir
)
626 self
._UPPER
_CACHE
_[Dir
.upper()] = Dir
628 SepIndex
= Path
.find(os
.path
.sep
, SepIndex
+ 1)
631 if Path
in self
._CACHE
_:
632 return os
.path
.join(self
._Root
, Path
)
633 elif UpperPath
in self
._UPPER
_CACHE
_:
634 return os
.path
.join(self
._Root
, self
._UPPER
_CACHE
_[UpperPath
])
637 ## Get all files of a directory
639 # @param Root: Root dir
640 # @param SkipList : The files need be skipped
642 # @retval A list of all files
644 def GetFiles(Root
, SkipList
=None, FullPath
=True):
647 for Root
, Dirs
, Files
in os
.walk(Root
):
649 for Item
in SkipList
:
654 File
= os
.path
.normpath(os
.path
.join(Root
, File
))
656 File
= File
[len(OriPath
) + 1:]
657 FileList
.append(File
)
661 ## Check if gvien file exists or not
663 # @param File File name or path to be checked
664 # @param Dir The directory the file is relative to
666 # @retval True if file exists
667 # @retval False if file doesn't exists
669 def ValidFile(File
, Ext
=None):
671 Dummy
, FileExt
= os
.path
.splitext(File
)
672 if FileExt
.lower() != Ext
.lower():
674 if not os
.path
.exists(File
):
678 def RealPath(File
, Dir
='', OverrideDir
=''):
679 NewFile
= os
.path
.normpath(os
.path
.join(Dir
, File
))
680 NewFile
= GlobalData
.gAllFiles
[NewFile
]
681 if not NewFile
and OverrideDir
:
682 NewFile
= os
.path
.normpath(os
.path
.join(OverrideDir
, File
))
683 NewFile
= GlobalData
.gAllFiles
[NewFile
]
686 def RealPath2(File
, Dir
='', OverrideDir
=''):
689 NewFile
= GlobalData
.gAllFiles
[os
.path
.normpath(os
.path
.join(OverrideDir
, File
))]
691 if OverrideDir
[-1] == os
.path
.sep
:
692 return NewFile
[len(OverrideDir
):], NewFile
[0:len(OverrideDir
)]
694 return NewFile
[len(OverrideDir
) + 1:], NewFile
[0:len(OverrideDir
)]
695 if GlobalData
.gAllFiles
:
696 NewFile
= GlobalData
.gAllFiles
[os
.path
.normpath(os
.path
.join(Dir
, File
))]
698 NewFile
= os
.path
.normpath(os
.path
.join(Dir
, File
))
699 if not os
.path
.exists(NewFile
):
703 if Dir
[-1] == os
.path
.sep
:
704 return NewFile
[len(Dir
):], NewFile
[0:len(Dir
)]
706 return NewFile
[len(Dir
) + 1:], NewFile
[0:len(Dir
)]
712 ## Check if gvien file exists or not
715 def ValidFile2(AllFiles
, File
, Ext
=None, Workspace
='', EfiSource
='', EdkSource
='', Dir
='.', OverrideDir
=''):
718 Dummy
, FileExt
= os
.path
.splitext(File
)
719 if FileExt
.lower() != Ext
.lower():
722 # Replace the Edk macros
723 if OverrideDir
!= '' and OverrideDir
!= None:
724 if OverrideDir
.find('$(EFI_SOURCE)') > -1:
725 OverrideDir
= OverrideDir
.replace('$(EFI_SOURCE)', EfiSource
)
726 if OverrideDir
.find('$(EDK_SOURCE)') > -1:
727 OverrideDir
= OverrideDir
.replace('$(EDK_SOURCE)', EdkSource
)
729 # Replace the default dir to current dir
732 Dir
= Dir
[len(Workspace
) + 1:]
734 # First check if File has Edk definition itself
735 if File
.find('$(EFI_SOURCE)') > -1 or File
.find('$(EDK_SOURCE)') > -1:
736 NewFile
= File
.replace('$(EFI_SOURCE)', EfiSource
)
737 NewFile
= NewFile
.replace('$(EDK_SOURCE)', EdkSource
)
738 NewFile
= AllFiles
[os
.path
.normpath(NewFile
)]
742 # Second check the path with override value
743 if OverrideDir
!= '' and OverrideDir
!= None:
744 NewFile
= AllFiles
[os
.path
.normpath(os
.path
.join(OverrideDir
, File
))]
748 # Last check the path with normal definitions
749 File
= os
.path
.join(Dir
, File
)
750 NewFile
= AllFiles
[os
.path
.normpath(File
)]
756 ## Check if gvien file exists or not
759 def ValidFile3(AllFiles
, File
, Workspace
='', EfiSource
='', EdkSource
='', Dir
='.', OverrideDir
=''):
760 # Replace the Edk macros
761 if OverrideDir
!= '' and OverrideDir
!= None:
762 if OverrideDir
.find('$(EFI_SOURCE)') > -1:
763 OverrideDir
= OverrideDir
.replace('$(EFI_SOURCE)', EfiSource
)
764 if OverrideDir
.find('$(EDK_SOURCE)') > -1:
765 OverrideDir
= OverrideDir
.replace('$(EDK_SOURCE)', EdkSource
)
767 # Replace the default dir to current dir
768 # Dir is current module dir related to workspace
771 Dir
= Dir
[len(Workspace
) + 1:]
774 RelaPath
= AllFiles
[os
.path
.normpath(Dir
)]
775 NewRelaPath
= RelaPath
778 # First check if File has Edk definition itself
779 if File
.find('$(EFI_SOURCE)') > -1 or File
.find('$(EDK_SOURCE)') > -1:
780 File
= File
.replace('$(EFI_SOURCE)', EfiSource
)
781 File
= File
.replace('$(EDK_SOURCE)', EdkSource
)
782 NewFile
= AllFiles
[os
.path
.normpath(File
)]
784 NewRelaPath
= os
.path
.dirname(NewFile
)
785 File
= os
.path
.basename(NewFile
)
786 #NewRelaPath = NewFile[:len(NewFile) - len(File.replace("..\\", '').replace("../", '')) - 1]
789 # Second check the path with override value
790 if OverrideDir
!= '' and OverrideDir
!= None:
791 NewFile
= AllFiles
[os
.path
.normpath(os
.path
.join(OverrideDir
, File
))]
793 #NewRelaPath = os.path.dirname(NewFile)
794 NewRelaPath
= NewFile
[:len(NewFile
) - len(File
.replace("..\\", '').replace("../", '')) - 1]
797 # Last check the path with normal definitions
798 NewFile
= AllFiles
[os
.path
.normpath(os
.path
.join(Dir
, File
))]
805 return NewRelaPath
, RelaPath
, File
808 def GetRelPath(Path1
, Path2
):
809 FileName
= os
.path
.basename(Path2
)
810 L1
= os
.path
.normpath(Path1
).split(os
.path
.normpath('/'))
811 L2
= os
.path
.normpath(Path2
).split(os
.path
.normpath('/'))
812 for Index
in range(0, len(L1
)):
813 if L1
[Index
] != L2
[Index
]:
814 FileName
= '../' * (len(L1
) - Index
)
815 for Index2
in range(Index
, len(L2
)):
816 FileName
= os
.path
.join(FileName
, L2
[Index2
])
818 return os
.path
.normpath(FileName
)
821 ## Get GUID value from given packages
823 # @param CName The CName of the GUID
824 # @param PackageList List of packages looking-up in
825 # @param Inffile The driver file
827 # @retval GuidValue if the CName is found in any given package
828 # @retval None if the CName is not found in all given packages
830 def GuidValue(CName
, PackageList
, Inffile
= None):
831 for P
in PackageList
:
832 GuidKeys
= P
.Guids
.keys()
833 if Inffile
and P
._PrivateGuids
:
834 if not Inffile
.startswith(P
.MetaFile
.Dir
):
835 GuidKeys
= (dict.fromkeys(x
for x
in P
.Guids
if x
not in P
._PrivateGuids
)).keys()
836 if CName
in GuidKeys
:
837 return P
.Guids
[CName
]
840 ## Get Protocol value from given packages
842 # @param CName The CName of the GUID
843 # @param PackageList List of packages looking-up in
844 # @param Inffile The driver file
846 # @retval GuidValue if the CName is found in any given package
847 # @retval None if the CName is not found in all given packages
849 def ProtocolValue(CName
, PackageList
, Inffile
= None):
850 for P
in PackageList
:
851 ProtocolKeys
= P
.Protocols
.keys()
852 if Inffile
and P
._PrivateProtocols
:
853 if not Inffile
.startswith(P
.MetaFile
.Dir
):
854 ProtocolKeys
= (dict.fromkeys(x
for x
in P
.Protocols
if x
not in P
._PrivateProtocols
)).keys()
855 if CName
in ProtocolKeys
:
856 return P
.Protocols
[CName
]
859 ## Get PPI value from given packages
861 # @param CName The CName of the GUID
862 # @param PackageList List of packages looking-up in
863 # @param Inffile The driver file
865 # @retval GuidValue if the CName is found in any given package
866 # @retval None if the CName is not found in all given packages
868 def PpiValue(CName
, PackageList
, Inffile
= None):
869 for P
in PackageList
:
870 PpiKeys
= P
.Ppis
.keys()
871 if Inffile
and P
._PrivatePpis
:
872 if not Inffile
.startswith(P
.MetaFile
.Dir
):
873 PpiKeys
= (dict.fromkeys(x
for x
in P
.Ppis
if x
not in P
._PrivatePpis
)).keys()
878 ## A string template class
880 # This class implements a template for string replacement. A string template
881 # looks like following
883 # ${BEGIN} other_string ${placeholder_name} other_string ${END}
885 # The string between ${BEGIN} and ${END} will be repeated as many times as the
886 # length of "placeholder_name", which is a list passed through a dict. The
887 # "placeholder_name" is the key name of the dict. The ${BEGIN} and ${END} can
888 # be not used and, in this case, the "placeholder_name" must not a list and it
889 # will just be replaced once.
891 class TemplateString(object):
892 _REPEAT_START_FLAG
= "BEGIN"
893 _REPEAT_END_FLAG
= "END"
895 class Section(object):
896 _LIST_TYPES
= [type([]), type(set()), type((0,))]
898 def __init__(self
, TemplateSection
, PlaceHolderList
):
899 self
._Template
= TemplateSection
900 self
._PlaceHolderList
= []
902 # Split the section into sub-sections according to the position of placeholders
904 self
._SubSectionList
= []
907 # The placeholders passed in must be in the format of
909 # PlaceHolderName, PlaceHolderStartPoint, PlaceHolderEndPoint
911 for PlaceHolder
, Start
, End
in PlaceHolderList
:
912 self
._SubSectionList
.append(TemplateSection
[SubSectionStart
:Start
])
913 self
._SubSectionList
.append(TemplateSection
[Start
:End
])
914 self
._PlaceHolderList
.append(PlaceHolder
)
915 SubSectionStart
= End
916 if SubSectionStart
< len(TemplateSection
):
917 self
._SubSectionList
.append(TemplateSection
[SubSectionStart
:])
919 self
._SubSectionList
= [TemplateSection
]
922 return self
._Template
+ " : " + str(self
._PlaceHolderList
)
924 def Instantiate(self
, PlaceHolderValues
):
926 RepeatPlaceHolders
= {}
927 NonRepeatPlaceHolders
= {}
929 for PlaceHolder
in self
._PlaceHolderList
:
930 if PlaceHolder
not in PlaceHolderValues
:
932 Value
= PlaceHolderValues
[PlaceHolder
]
933 if type(Value
) in self
._LIST
_TYPES
:
935 RepeatTime
= len(Value
)
936 elif RepeatTime
!= len(Value
):
940 "${%s} has different repeat time from others!" % PlaceHolder
,
941 ExtraData
=str(self
._Template
)
943 RepeatPlaceHolders
["${%s}" % PlaceHolder
] = Value
945 NonRepeatPlaceHolders
["${%s}" % PlaceHolder
] = Value
947 if NonRepeatPlaceHolders
:
949 for S
in self
._SubSectionList
:
950 if S
not in NonRepeatPlaceHolders
:
953 StringList
.append(str(NonRepeatPlaceHolders
[S
]))
955 StringList
= self
._SubSectionList
957 if RepeatPlaceHolders
:
959 for Index
in range(RepeatTime
):
961 if S
not in RepeatPlaceHolders
:
962 TempStringList
.append(S
)
964 TempStringList
.append(str(RepeatPlaceHolders
[S
][Index
]))
965 StringList
= TempStringList
967 return "".join(StringList
)
970 def __init__(self
, Template
=None):
972 self
.IsBinary
= False
973 self
._Template
= Template
974 self
._TemplateSectionList
= self
._Parse
(Template
)
978 # @retval string The string replaced
983 ## Split the template string into fragments per the ${BEGIN} and ${END} flags
985 # @retval list A list of TemplateString.Section objects
987 def _Parse(self
, Template
):
992 TemplateSectionList
= []
994 MatchObj
= gPlaceholderPattern
.search(Template
, SearchFrom
)
996 if MatchEnd
<= len(Template
):
997 TemplateSection
= TemplateString
.Section(Template
[SectionStart
:], PlaceHolderList
)
998 TemplateSectionList
.append(TemplateSection
)
1001 MatchString
= MatchObj
.group(1)
1002 MatchStart
= MatchObj
.start()
1003 MatchEnd
= MatchObj
.end()
1005 if MatchString
== self
._REPEAT
_START
_FLAG
:
1006 if MatchStart
> SectionStart
:
1007 TemplateSection
= TemplateString
.Section(Template
[SectionStart
:MatchStart
], PlaceHolderList
)
1008 TemplateSectionList
.append(TemplateSection
)
1009 SectionStart
= MatchEnd
1010 PlaceHolderList
= []
1011 elif MatchString
== self
._REPEAT
_END
_FLAG
:
1012 TemplateSection
= TemplateString
.Section(Template
[SectionStart
:MatchStart
], PlaceHolderList
)
1013 TemplateSectionList
.append(TemplateSection
)
1014 SectionStart
= MatchEnd
1015 PlaceHolderList
= []
1017 PlaceHolderList
.append((MatchString
, MatchStart
- SectionStart
, MatchEnd
- SectionStart
))
1018 SearchFrom
= MatchEnd
1019 return TemplateSectionList
1021 ## Replace the string template with dictionary of placeholders and append it to previous one
1023 # @param AppendString The string template to append
1024 # @param Dictionary The placeholder dictionaries
1026 def Append(self
, AppendString
, Dictionary
=None):
1028 SectionList
= self
._Parse
(AppendString
)
1029 self
.String
+= "".join([S
.Instantiate(Dictionary
) for S
in SectionList
])
1031 self
.String
+= AppendString
1033 ## Replace the string template with dictionary of placeholders
1035 # @param Dictionary The placeholder dictionaries
1037 # @retval str The string replaced with placeholder values
1039 def Replace(self
, Dictionary
=None):
1040 return "".join([S
.Instantiate(Dictionary
) for S
in self
._TemplateSectionList
])
1042 ## Progress indicator class
1044 # This class makes use of thread to print progress on console.
1047 # for avoiding deadloop
1049 _ProgressThread
= None
1050 _CheckInterval
= 0.25
1054 # @param OpenMessage The string printed before progress charaters
1055 # @param CloseMessage The string printed after progress charaters
1056 # @param ProgressChar The charater used to indicate the progress
1057 # @param Interval The interval in seconds between two progress charaters
1059 def __init__(self
, OpenMessage
="", CloseMessage
="", ProgressChar
='.', Interval
=1.0):
1060 self
.PromptMessage
= OpenMessage
1061 self
.CodaMessage
= CloseMessage
1062 self
.ProgressChar
= ProgressChar
1063 self
.Interval
= Interval
1064 if Progressor
._StopFlag
== None:
1065 Progressor
._StopFlag
= threading
.Event()
1067 ## Start to print progress charater
1069 # @param OpenMessage The string printed before progress charaters
1071 def Start(self
, OpenMessage
=None):
1072 if OpenMessage
!= None:
1073 self
.PromptMessage
= OpenMessage
1074 Progressor
._StopFlag
.clear()
1075 if Progressor
._ProgressThread
== None:
1076 Progressor
._ProgressThread
= threading
.Thread(target
=self
._ProgressThreadEntry
)
1077 Progressor
._ProgressThread
.setDaemon(False)
1078 Progressor
._ProgressThread
.start()
1080 ## Stop printing progress charater
1082 # @param CloseMessage The string printed after progress charaters
1084 def Stop(self
, CloseMessage
=None):
1085 OriginalCodaMessage
= self
.CodaMessage
1086 if CloseMessage
!= None:
1087 self
.CodaMessage
= CloseMessage
1089 self
.CodaMessage
= OriginalCodaMessage
1091 ## Thread entry method
1092 def _ProgressThreadEntry(self
):
1093 sys
.stdout
.write(self
.PromptMessage
+ " ")
1096 while not Progressor
._StopFlag
.isSet():
1098 sys
.stdout
.write(self
.ProgressChar
)
1100 TimeUp
= self
.Interval
1101 time
.sleep(self
._CheckInterval
)
1102 TimeUp
-= self
._CheckInterval
1103 sys
.stdout
.write(" " + self
.CodaMessage
+ "\n")
1106 ## Abort the progress display
1109 if Progressor
._StopFlag
!= None:
1110 Progressor
._StopFlag
.set()
1111 if Progressor
._ProgressThread
!= None:
1112 Progressor
._ProgressThread
.join()
1113 Progressor
._ProgressThread
= None
1115 ## A dict which can access its keys and/or values orderly
1117 # The class implements a new kind of dict which its keys or values can be
1118 # accessed in the order they are added into the dict. It guarantees the order
1119 # by making use of an internal list to keep a copy of keys.
1121 class sdict(IterableUserDict
):
1124 IterableUserDict
.__init
__(self
)
1128 def __setitem__(self
, key
, value
):
1129 if key
not in self
._key
_list
:
1130 self
._key
_list
.append(key
)
1131 IterableUserDict
.__setitem
__(self
, key
, value
)
1134 def __delitem__(self
, key
):
1135 self
._key
_list
.remove(key
)
1136 IterableUserDict
.__delitem
__(self
, key
)
1138 ## used in "for k in dict" loop to ensure the correct order
1140 return self
.iterkeys()
1144 return len(self
._key
_list
)
1146 ## "in" test support
1147 def __contains__(self
, key
):
1148 return key
in self
._key
_list
1151 def index(self
, key
):
1152 return self
._key
_list
.index(key
)
1155 def insert(self
, key
, newkey
, newvalue
, order
):
1156 index
= self
._key
_list
.index(key
)
1157 if order
== 'BEFORE':
1158 self
._key
_list
.insert(index
, newkey
)
1159 IterableUserDict
.__setitem
__(self
, newkey
, newvalue
)
1160 elif order
== 'AFTER':
1161 self
._key
_list
.insert(index
+ 1, newkey
)
1162 IterableUserDict
.__setitem
__(self
, newkey
, newvalue
)
1165 def append(self
, sdict
):
1167 if key
not in self
._key
_list
:
1168 self
._key
_list
.append(key
)
1169 IterableUserDict
.__setitem
__(self
, key
, sdict
[key
])
1171 def has_key(self
, key
):
1172 return key
in self
._key
_list
1177 IterableUserDict
.clear(self
)
1179 ## Return a copy of keys
1182 for key
in self
._key
_list
:
1186 ## Return a copy of values
1189 for key
in self
._key
_list
:
1190 values
.append(self
[key
])
1193 ## Return a copy of (key, value) list
1196 for key
in self
._key
_list
:
1197 items
.append((key
, self
[key
]))
1200 ## Iteration support
1201 def iteritems(self
):
1202 return iter(self
.items())
1204 ## Keys interation support
1206 return iter(self
.keys())
1208 ## Values interation support
1209 def itervalues(self
):
1210 return iter(self
.values())
1212 ## Return value related to a key, and remove the (key, value) from the dict
1213 def pop(self
, key
, *dv
):
1215 if key
in self
._key
_list
:
1217 self
.__delitem
__(key
)
1222 ## Return (key, value) pair, and remove the (key, value) from the dict
1224 key
= self
._key
_list
[-1]
1226 self
.__delitem
__(key
)
1229 def update(self
, dict=None, **kwargs
):
1231 for k
, v
in dict.items():
1234 for k
, v
in kwargs
.items():
1237 ## Dictionary with restricted keys
1241 def __init__(self
, KeyList
):
1243 dict.__setitem
__(self
, Key
, "")
1246 def __setitem__(self
, key
, value
):
1248 EdkLogger
.error("RestrictedDict", ATTRIBUTE_SET_FAILURE
, "Key [%s] is not allowed" % key
,
1249 ExtraData
=", ".join(dict.keys(self
)))
1250 dict.__setitem
__(self
, key
, value
)
1253 def __getitem__(self
, key
):
1256 return dict.__getitem
__(self
, key
)
1259 def __delitem__(self
, key
):
1260 EdkLogger
.error("RestrictedDict", ATTRIBUTE_ACCESS_DENIED
, ExtraData
="del")
1265 self
.__setitem
__(Key
, "")
1267 ## Return value related to a key, and remove the (key, value) from the dict
1268 def pop(self
, key
, *dv
):
1269 EdkLogger
.error("RestrictedDict", ATTRIBUTE_ACCESS_DENIED
, ExtraData
="pop")
1271 ## Return (key, value) pair, and remove the (key, value) from the dict
1273 EdkLogger
.error("RestrictedDict", ATTRIBUTE_ACCESS_DENIED
, ExtraData
="popitem")
1275 ## Dictionary using prioritized list as key
1278 _ListType
= type([])
1279 _TupleType
= type(())
1280 _Wildcard
= 'COMMON'
1281 _ValidWildcardList
= ['COMMON', 'DEFAULT', 'ALL', '*', 'PLATFORM']
1283 def __init__(self
, _Single_
=False, _Level_
=2):
1284 self
._Level
_ = _Level_
1286 self
._Single
_ = _Single_
1289 def __getitem__(self
, key
):
1292 if KeyType
== self
._ListType
or KeyType
== self
._TupleType
:
1296 elif self
._Level
_ > 1:
1297 RestKeys
= [self
._Wildcard
for i
in range(0, self
._Level
_ - 1)]
1300 if self
._Level
_ > 1:
1301 RestKeys
= [self
._Wildcard
for i
in range(0, self
._Level
_ - 1)]
1303 if FirstKey
== None or str(FirstKey
).upper() in self
._ValidWildcardList
:
1304 FirstKey
= self
._Wildcard
1307 return self
._GetSingleValue
(FirstKey
, RestKeys
)
1309 return self
._GetAllValues
(FirstKey
, RestKeys
)
1311 def _GetSingleValue(self
, FirstKey
, RestKeys
):
1313 #print "%s-%s" % (FirstKey, self._Level_) ,
1314 if self
._Level
_ > 1:
1315 if FirstKey
== self
._Wildcard
:
1316 if FirstKey
in self
.data
:
1317 Value
= self
.data
[FirstKey
][RestKeys
]
1319 for Key
in self
.data
:
1320 Value
= self
.data
[Key
][RestKeys
]
1321 if Value
!= None: break
1323 if FirstKey
in self
.data
:
1324 Value
= self
.data
[FirstKey
][RestKeys
]
1325 if Value
== None and self
._Wildcard
in self
.data
:
1327 Value
= self
.data
[self
._Wildcard
][RestKeys
]
1329 if FirstKey
== self
._Wildcard
:
1330 if FirstKey
in self
.data
:
1331 Value
= self
.data
[FirstKey
]
1333 for Key
in self
.data
:
1334 Value
= self
.data
[Key
]
1335 if Value
!= None: break
1337 if FirstKey
in self
.data
:
1338 Value
= self
.data
[FirstKey
]
1339 elif self
._Wildcard
in self
.data
:
1340 Value
= self
.data
[self
._Wildcard
]
1343 def _GetAllValues(self
, FirstKey
, RestKeys
):
1345 if self
._Level
_ > 1:
1346 if FirstKey
== self
._Wildcard
:
1347 for Key
in self
.data
:
1348 Value
+= self
.data
[Key
][RestKeys
]
1350 if FirstKey
in self
.data
:
1351 Value
+= self
.data
[FirstKey
][RestKeys
]
1352 if self
._Wildcard
in self
.data
:
1353 Value
+= self
.data
[self
._Wildcard
][RestKeys
]
1355 if FirstKey
== self
._Wildcard
:
1356 for Key
in self
.data
:
1357 Value
.append(self
.data
[Key
])
1359 if FirstKey
in self
.data
:
1360 Value
.append(self
.data
[FirstKey
])
1361 if self
._Wildcard
in self
.data
:
1362 Value
.append(self
.data
[self
._Wildcard
])
1366 def __setitem__(self
, key
, value
):
1369 if KeyType
== self
._ListType
or KeyType
== self
._TupleType
:
1374 RestKeys
= [self
._Wildcard
for i
in range(0, self
._Level
_ - 1)]
1377 if self
._Level
_ > 1:
1378 RestKeys
= [self
._Wildcard
for i
in range(0, self
._Level
_ - 1)]
1380 if FirstKey
in self
._ValidWildcardList
:
1381 FirstKey
= self
._Wildcard
1383 if FirstKey
not in self
.data
and self
._Level
_ > 0:
1384 self
.data
[FirstKey
] = tdict(self
._Single
_, self
._Level
_ - 1)
1386 if self
._Level
_ > 1:
1387 self
.data
[FirstKey
][RestKeys
] = value
1389 self
.data
[FirstKey
] = value
1391 def SetGreedyMode(self
):
1392 self
._Single
_ = False
1393 if self
._Level
_ > 1:
1394 for Key
in self
.data
:
1395 self
.data
[Key
].SetGreedyMode()
1397 def SetSingleMode(self
):
1398 self
._Single
_ = True
1399 if self
._Level
_ > 1:
1400 for Key
in self
.data
:
1401 self
.data
[Key
].SetSingleMode()
1403 def GetKeys(self
, KeyIndex
=0):
1404 assert KeyIndex
>= 0
1406 return set(self
.data
.keys())
1409 for Key
in self
.data
:
1410 keys |
= self
.data
[Key
].GetKeys(KeyIndex
- 1)
1413 ## Boolean chain list
1415 class Blist(UserList
):
1416 def __init__(self
, initlist
=None):
1417 UserList
.__init
__(self
, initlist
)
1418 def __setitem__(self
, i
, item
):
1419 if item
not in [True, False]:
1425 def _GetResult(self
):
1427 for item
in self
.data
:
1430 Result
= property(_GetResult
)
1432 def ParseConsoleLog(Filename
):
1433 Opr
= open(os
.path
.normpath(Filename
), 'r')
1434 Opw
= open(os
.path
.normpath(Filename
+ '.New'), 'w+')
1435 for Line
in Opr
.readlines():
1436 if Line
.find('.efi') > -1:
1437 Line
= Line
[Line
.rfind(' ') : Line
.rfind('.efi')].strip()
1438 Opw
.write('%s\n' % Line
)
1443 def AnalyzePcdExpression(Setting
):
1444 Setting
= Setting
.strip()
1445 # There might be escaped quote in a string: \", \\\"
1446 Data
= Setting
.replace('\\\\', '//').replace('\\\"', '\\\'')
1447 # There might be '|' in string and in ( ... | ... ), replace it with '-'
1454 elif ch
== '(' and not InStr
:
1456 elif ch
== ')' and not InStr
:
1459 if (Pair
> 0 or InStr
) and ch
== TAB_VALUE_SPLIT
:
1466 Pos
= NewStr
.find(TAB_VALUE_SPLIT
, StartPos
)
1468 FieldList
.append(Setting
[StartPos
:].strip())
1470 FieldList
.append(Setting
[StartPos
:Pos
].strip())
1475 def ParseFieldValue (Value
):
1476 if type(Value
) == type(0):
1477 return Value
, (Value
.bit_length() + 7) / 8
1478 if type(Value
) <> type(''):
1480 Value
= Value
.strip()
1481 if Value
.startswith('UINT8') and Value
.endswith(')'):
1482 Value
, Size
= ParseFieldValue(Value
.split('(', 1)[1][:-1])
1486 if Value
.startswith('UINT16') and Value
.endswith(')'):
1487 Value
, Size
= ParseFieldValue(Value
.split('(', 1)[1][:-1])
1491 if Value
.startswith('UINT32') and Value
.endswith(')'):
1492 Value
, Size
= ParseFieldValue(Value
.split('(', 1)[1][:-1])
1496 if Value
.startswith('UINT64') and Value
.endswith(')'):
1497 Value
, Size
= ParseFieldValue(Value
.split('(', 1)[1][:-1])
1501 if Value
.startswith('GUID') and Value
.endswith(')'):
1502 Value
= Value
.split('(', 1)[1][:-1].strip()
1503 if Value
[0] == '{' and Value
[-1] == '}':
1504 Value
= Value
[1:-1].strip()
1505 Value
= Value
.split('{', 1)
1506 Value
= [Item
.strip()[2:] for Item
in (Value
[0] + Value
[1][:-1]).split(',')]
1507 Value
= '-'.join(Value
[0:3]) + '-' + ''.join(Value
[3:5]) + '-' + ''.join(Value
[5:11])
1508 if Value
[0] == '"' and Value
[-1] == '"':
1510 Value
= "'" + uuid
.UUID(Value
).get_bytes_le() + "'"
1511 Value
, Size
= ParseFieldValue(Value
)
1513 if Value
.startswith('L"') and Value
.endswith('"'):
1515 List
= list(Value
[2:-1])
1519 Value
= (Value
<< 16) |
ord(Char
)
1520 return Value
, (len(List
) + 1) * 2
1521 if Value
.startswith('"') and Value
.endswith('"'):
1523 List
= list(Value
[1:-1])
1527 Value
= (Value
<< 8) |
ord(Char
)
1528 return Value
, len(List
) + 1
1529 if Value
.startswith("L'") and Value
.endswith("'"):
1530 # Unicode Character Constant
1531 List
= list(Value
[2:-1])
1535 Value
= (Value
<< 16) |
ord(Char
)
1536 return Value
, len(List
) * 2
1537 if Value
.startswith("'") and Value
.endswith("'"):
1538 # Character constant
1539 List
= list(Value
[1:-1])
1543 Value
= (Value
<< 8) |
ord(Char
)
1544 return Value
, len(List
)
1545 if Value
.startswith('{') and Value
.endswith('}'):
1548 List
= [Item
.strip() for Item
in Value
.split(',')]
1552 ItemValue
, Size
= ParseFieldValue(Item
)
1555 Value
= (Value
<< 8) | ItemValue
1556 return Value
, len(List
)
1557 if Value
.lower().startswith('0x'):
1558 Value
= int(Value
, 16)
1559 return Value
, (Value
.bit_length() + 7) / 8
1560 if Value
[0].isdigit():
1561 Value
= int(Value
, 10)
1562 return Value
, (Value
.bit_length() + 7) / 8
1563 if Value
.lower() == 'true':
1565 if Value
.lower() == 'false':
1571 # Analyze DSC PCD value, since there is no data type info in DSC
1572 # This fuction is used to match functions (AnalyzePcdData, AnalyzeHiiPcdData, AnalyzeVpdPcdData) used for retrieving PCD value from database
1573 # 1. Feature flag: TokenSpace.PcdCName|PcdValue
1574 # 2. Fix and Patch:TokenSpace.PcdCName|PcdValue[|MaxSize]
1575 # 3. Dynamic default:
1576 # TokenSpace.PcdCName|PcdValue[|VOID*[|MaxSize]]
1577 # TokenSpace.PcdCName|PcdValue
1579 # TokenSpace.PcdCName|VpdOffset[|VpdValue]
1580 # TokenSpace.PcdCName|VpdOffset[|MaxSize[|VpdValue]]
1582 # TokenSpace.PcdCName|HiiString|VaiableGuid|VariableOffset[|HiiValue]
1583 # PCD value needs to be located in such kind of string, and the PCD value might be an expression in which
1584 # there might have "|" operator, also in string value.
1586 # @param Setting: String contain information described above with "TokenSpace.PcdCName|" stripped
1587 # @param PcdType: PCD type: feature, fixed, dynamic default VPD HII
1588 # @param DataType: The datum type of PCD: VOID*, UNIT, BOOL
1590 # ValueList: A List contain fields described above
1591 # IsValid: True if conforming EBNF, otherwise False
1592 # Index: The index where PcdValue is in ValueList
1594 def AnalyzeDscPcd(Setting
, PcdType
, DataType
=''):
1595 FieldList
= AnalyzePcdExpression(Setting
)
1598 if PcdType
in (MODEL_PCD_FIXED_AT_BUILD
, MODEL_PCD_PATCHABLE_IN_MODULE
, MODEL_PCD_FEATURE_FLAG
):
1599 Value
= FieldList
[0]
1601 if len(FieldList
) > 1:
1602 if FieldList
[1].upper().startswith("0X") or FieldList
[1].isdigit():
1605 DataType
= FieldList
[1]
1607 if len(FieldList
) > 2:
1610 IsValid
= (len(FieldList
) <= 1)
1612 IsValid
= (len(FieldList
) <= 3)
1613 # Value, Size = ParseFieldValue(Value)
1614 return [str(Value
), '', str(Size
)], IsValid
, 0
1615 elif PcdType
in (MODEL_PCD_DYNAMIC_DEFAULT
, MODEL_PCD_DYNAMIC_EX_DEFAULT
):
1616 Value
= FieldList
[0]
1618 if len(FieldList
) > 1:
1622 if len(FieldList
) > 2:
1626 if Value
.startswith("L"):
1627 Size
= str((len(Value
)- 3 + 1) * 2)
1628 elif Value
.startswith("{"):
1629 Size
= str(len(Value
.split(",")))
1631 Size
= str(len(Value
) -2 + 1 )
1633 IsValid
= (len(FieldList
) <= 1)
1635 IsValid
= (len(FieldList
) <= 3)
1636 return [Value
, Type
, Size
], IsValid
, 0
1637 elif PcdType
in (MODEL_PCD_DYNAMIC_VPD
, MODEL_PCD_DYNAMIC_EX_VPD
):
1638 VpdOffset
= FieldList
[0]
1640 if not DataType
== 'VOID*':
1641 if len(FieldList
) > 1:
1642 Value
= FieldList
[1]
1644 if len(FieldList
) > 1:
1646 if len(FieldList
) > 2:
1647 Value
= FieldList
[2]
1649 IsValid
= (len(FieldList
) <= 1)
1651 IsValid
= (len(FieldList
) <= 3)
1653 return [VpdOffset
, Size
, Value
], IsValid
, 2
1654 elif PcdType
in (MODEL_PCD_DYNAMIC_HII
, MODEL_PCD_DYNAMIC_EX_HII
):
1655 HiiString
= FieldList
[0]
1656 Guid
= Offset
= Value
= Attribute
= ''
1657 if len(FieldList
) > 1:
1659 if len(FieldList
) > 2:
1660 Offset
= FieldList
[2]
1661 if len(FieldList
) > 3:
1662 Value
= FieldList
[3]
1663 if len(FieldList
) > 4:
1664 Attribute
= FieldList
[4]
1665 IsValid
= (3 <= len(FieldList
) <= 5)
1666 return [HiiString
, Guid
, Offset
, Value
, Attribute
], IsValid
, 3
1671 # Analyze the pcd Value, Datum type and TokenNumber.
1672 # Used to avoid split issue while the value string contain "|" character
1674 # @param[in] Setting: A String contain value/datum type/token number information;
1676 # @retval ValueList: A List contain value, datum type and toke number.
1678 def AnalyzePcdData(Setting
):
1679 ValueList
= ['', '', '']
1681 ValueRe
= re
.compile(r
'^\s*L?\".*\|.*\"')
1682 PtrValue
= ValueRe
.findall(Setting
)
1684 ValueUpdateFlag
= False
1686 if len(PtrValue
) >= 1:
1687 Setting
= re
.sub(ValueRe
, '', Setting
)
1688 ValueUpdateFlag
= True
1690 TokenList
= Setting
.split(TAB_VALUE_SPLIT
)
1691 ValueList
[0:len(TokenList
)] = TokenList
1694 ValueList
[0] = PtrValue
[0]
1698 ## AnalyzeHiiPcdData
1700 # Analyze the pcd Value, variable name, variable Guid and variable offset.
1701 # Used to avoid split issue while the value string contain "|" character
1703 # @param[in] Setting: A String contain VariableName, VariableGuid, VariableOffset, DefaultValue information;
1705 # @retval ValueList: A List contaian VariableName, VariableGuid, VariableOffset, DefaultValue.
1707 def AnalyzeHiiPcdData(Setting
):
1708 ValueList
= ['', '', '', '']
1710 TokenList
= GetSplitValueList(Setting
)
1711 ValueList
[0:len(TokenList
)] = TokenList
1715 ## AnalyzeVpdPcdData
1717 # Analyze the vpd pcd VpdOffset, MaxDatumSize and InitialValue.
1718 # Used to avoid split issue while the value string contain "|" character
1720 # @param[in] Setting: A String contain VpdOffset/MaxDatumSize/InitialValue information;
1722 # @retval ValueList: A List contain VpdOffset, MaxDatumSize and InitialValue.
1724 def AnalyzeVpdPcdData(Setting
):
1725 ValueList
= ['', '', '']
1727 ValueRe
= re
.compile(r
'\s*L?\".*\|.*\"\s*$')
1728 PtrValue
= ValueRe
.findall(Setting
)
1730 ValueUpdateFlag
= False
1732 if len(PtrValue
) >= 1:
1733 Setting
= re
.sub(ValueRe
, '', Setting
)
1734 ValueUpdateFlag
= True
1736 TokenList
= Setting
.split(TAB_VALUE_SPLIT
)
1737 ValueList
[0:len(TokenList
)] = TokenList
1740 ValueList
[2] = PtrValue
[0]
1744 ## check format of PCD value against its the datum type
1746 # For PCD value setting
1748 def CheckPcdDatum(Type
, Value
):
1750 ValueRe
= re
.compile(r
'\s*L?\".*\"\s*$')
1751 if not (((Value
.startswith('L"') or Value
.startswith('"')) and Value
.endswith('"'))
1752 or (Value
.startswith('{') and Value
.endswith('}'))
1754 return False, "Invalid value [%s] of type [%s]; must be in the form of {...} for array"\
1755 ", or \"...\" for string, or L\"...\" for unicode string" % (Value
, Type
)
1756 elif ValueRe
.match(Value
):
1757 # Check the chars in UnicodeString or CString is printable
1758 if Value
.startswith("L"):
1762 Printset
= set(string
.printable
)
1763 Printset
.remove(TAB_PRINTCHAR_VT
)
1764 Printset
.add(TAB_PRINTCHAR_BS
)
1765 Printset
.add(TAB_PRINTCHAR_NUL
)
1766 if not set(Value
).issubset(Printset
):
1767 PrintList
= list(Printset
)
1769 return False, "Invalid PCD string value of type [%s]; must be printable chars %s." % (Type
, PrintList
)
1770 elif Type
== 'BOOLEAN':
1771 if Value
not in ['TRUE', 'True', 'true', '0x1', '0x01', '1', 'FALSE', 'False', 'false', '0x0', '0x00', '0']:
1772 return False, "Invalid value [%s] of type [%s]; must be one of TRUE, True, true, 0x1, 0x01, 1"\
1773 ", FALSE, False, false, 0x0, 0x00, 0" % (Value
, Type
)
1774 elif Type
in [TAB_UINT8
, TAB_UINT16
, TAB_UINT32
, TAB_UINT64
]:
1776 Value
= long(Value
, 0)
1778 return False, "Invalid value [%s] of type [%s];"\
1779 " must be a hexadecimal, decimal or octal in C language format." % (Value
, Type
)
1781 return True, "StructurePcd"
1785 ## Split command line option string to list
1787 # subprocess.Popen needs the args to be a sequence. Otherwise there's problem
1788 # in non-windows platform to launch command
1790 def SplitOption(OptionString
):
1795 for Index
in range(0, len(OptionString
)):
1796 CurrentChar
= OptionString
[Index
]
1797 if CurrentChar
in ['"', "'"]:
1798 if QuotationMark
== CurrentChar
:
1800 elif QuotationMark
== "":
1801 QuotationMark
= CurrentChar
1806 if CurrentChar
in ["/", "-"] and LastChar
in [" ", "\t", "\r", "\n"]:
1807 if Index
> OptionStart
:
1808 OptionList
.append(OptionString
[OptionStart
:Index
- 1])
1810 LastChar
= CurrentChar
1811 OptionList
.append(OptionString
[OptionStart
:])
1814 def CommonPath(PathList
):
1815 P1
= min(PathList
).split(os
.path
.sep
)
1816 P2
= max(PathList
).split(os
.path
.sep
)
1817 for Index
in xrange(min(len(P1
), len(P2
))):
1818 if P1
[Index
] != P2
[Index
]:
1819 return os
.path
.sep
.join(P1
[:Index
])
1820 return os
.path
.sep
.join(P1
)
1823 # Convert string to C format array
1825 def ConvertStringToByteArray(Value
):
1826 Value
= Value
.strip()
1830 if not Value
.endswith('}'):
1832 Value
= Value
.replace(' ', '').replace('{', '').replace('}', '')
1833 ValFields
= Value
.split(',')
1835 for Index
in range(len(ValFields
)):
1836 ValFields
[Index
] = str(int(ValFields
[Index
], 0))
1839 Value
= '{' + ','.join(ValFields
) + '}'
1843 if Value
.startswith('L"'):
1844 if not Value
.endswith('"'):
1848 elif not Value
.startswith('"') or not Value
.endswith('"'):
1851 Value
= eval(Value
) # translate escape character
1853 for Index
in range(0,len(Value
)):
1855 NewValue
= NewValue
+ str(ord(Value
[Index
]) % 0x10000) + ','
1857 NewValue
= NewValue
+ str(ord(Value
[Index
]) % 0x100) + ','
1858 Value
= NewValue
+ '0}'
1861 class PathClass(object):
1862 def __init__(self
, File
='', Root
='', AlterRoot
='', Type
='', IsBinary
=False,
1863 Arch
='COMMON', ToolChainFamily
='', Target
='', TagName
='', ToolCode
=''):
1865 self
.File
= str(File
)
1866 if os
.path
.isabs(self
.File
):
1870 self
.Root
= str(Root
)
1871 self
.AlterRoot
= str(AlterRoot
)
1873 # Remove any '.' and '..' in path
1875 self
.Root
= mws
.getWs(self
.Root
, self
.File
)
1876 self
.Path
= os
.path
.normpath(os
.path
.join(self
.Root
, self
.File
))
1877 self
.Root
= os
.path
.normpath(CommonPath([self
.Root
, self
.Path
]))
1878 # eliminate the side-effect of 'C:'
1879 if self
.Root
[-1] == ':':
1880 self
.Root
+= os
.path
.sep
1881 # file path should not start with path separator
1882 if self
.Root
[-1] == os
.path
.sep
:
1883 self
.File
= self
.Path
[len(self
.Root
):]
1885 self
.File
= self
.Path
[len(self
.Root
) + 1:]
1887 self
.Path
= os
.path
.normpath(self
.File
)
1889 self
.SubDir
, self
.Name
= os
.path
.split(self
.File
)
1890 self
.BaseName
, self
.Ext
= os
.path
.splitext(self
.Name
)
1894 self
.Dir
= os
.path
.join(self
.Root
, self
.SubDir
)
1896 self
.Dir
= self
.Root
1898 self
.Dir
= self
.SubDir
1903 self
.Type
= self
.Ext
.lower()
1905 self
.IsBinary
= IsBinary
1906 self
.Target
= Target
1907 self
.TagName
= TagName
1908 self
.ToolCode
= ToolCode
1909 self
.ToolChainFamily
= ToolChainFamily
1913 ## Convert the object of this class to a string
1915 # Convert member Path of the class to a string
1917 # @retval string Formatted String
1922 ## Override __eq__ function
1924 # Check whether PathClass are the same
1926 # @retval False The two PathClass are different
1927 # @retval True The two PathClass are the same
1929 def __eq__(self
, Other
):
1930 if type(Other
) == type(self
):
1931 return self
.Path
== Other
.Path
1933 return self
.Path
== str(Other
)
1935 ## Override __cmp__ function
1937 # Customize the comparsion operation of two PathClass
1939 # @retval 0 The two PathClass are different
1940 # @retval -1 The first PathClass is less than the second PathClass
1941 # @retval 1 The first PathClass is Bigger than the second PathClass
1942 def __cmp__(self
, Other
):
1943 if type(Other
) == type(self
):
1944 OtherKey
= Other
.Path
1946 OtherKey
= str(Other
)
1949 if SelfKey
== OtherKey
:
1951 elif SelfKey
> OtherKey
:
1956 ## Override __hash__ function
1958 # Use Path as key in hash table
1960 # @retval string Key for hash table
1963 return hash(self
.Path
)
1965 def _GetFileKey(self
):
1966 if self
._Key
== None:
1967 self
._Key
= self
.Path
.upper() # + self.ToolChainFamily + self.TagName + self.ToolCode + self.Target
1970 def _GetTimeStamp(self
):
1971 return os
.stat(self
.Path
)[8]
1973 def Validate(self
, Type
='', CaseSensitive
=True):
1974 if GlobalData
.gCaseInsensitive
:
1975 CaseSensitive
= False
1976 if Type
and Type
.lower() != self
.Type
:
1977 return FILE_TYPE_MISMATCH
, '%s (expect %s but got %s)' % (self
.File
, Type
, self
.Type
)
1979 RealFile
, RealRoot
= RealPath2(self
.File
, self
.Root
, self
.AlterRoot
)
1980 if not RealRoot
and not RealFile
:
1981 RealFile
= self
.File
1983 RealFile
= os
.path
.join(self
.AlterRoot
, self
.File
)
1985 RealFile
= os
.path
.join(self
.Root
, self
.File
)
1986 if len (mws
.getPkgPath()) == 0:
1987 return FILE_NOT_FOUND
, os
.path
.join(self
.AlterRoot
, RealFile
)
1989 return FILE_NOT_FOUND
, "%s is not found in packages path:\n\t%s" % (self
.File
, '\n\t'.join(mws
.getPkgPath()))
1993 if RealRoot
!= self
.Root
or RealFile
!= self
.File
:
1994 if CaseSensitive
and (RealFile
!= self
.File
or (RealRoot
!= self
.Root
and RealRoot
!= self
.AlterRoot
)):
1995 ErrorCode
= FILE_CASE_MISMATCH
1996 ErrorInfo
= self
.File
+ '\n\t' + RealFile
+ " [in file system]"
1998 self
.SubDir
, self
.Name
= os
.path
.split(RealFile
)
1999 self
.BaseName
, self
.Ext
= os
.path
.splitext(self
.Name
)
2001 self
.Dir
= os
.path
.join(RealRoot
, self
.SubDir
)
2004 self
.File
= RealFile
2005 self
.Root
= RealRoot
2006 self
.Path
= os
.path
.join(RealRoot
, RealFile
)
2007 return ErrorCode
, ErrorInfo
2009 Key
= property(_GetFileKey
)
2010 TimeStamp
= property(_GetTimeStamp
)
2012 ## Parse PE image to get the required PE informaion.
2014 class PeImageClass():
2017 # @param File FilePath of PeImage
2019 def __init__(self
, PeFile
):
2020 self
.FileName
= PeFile
2021 self
.IsValid
= False
2024 self
.SectionAlignment
= 0
2025 self
.SectionHeaderList
= []
2028 PeObject
= open(PeFile
, 'rb')
2030 self
.ErrorInfo
= self
.FileName
+ ' can not be found\n'
2033 ByteArray
= array
.array('B')
2034 ByteArray
.fromfile(PeObject
, 0x3E)
2035 ByteList
= ByteArray
.tolist()
2036 # DOS signature should be 'MZ'
2037 if self
._ByteListToStr
(ByteList
[0x0:0x2]) != 'MZ':
2038 self
.ErrorInfo
= self
.FileName
+ ' has no valid DOS signature MZ'
2041 # Read 4 byte PE Signature
2042 PeOffset
= self
._ByteListToInt
(ByteList
[0x3C:0x3E])
2043 PeObject
.seek(PeOffset
)
2044 ByteArray
= array
.array('B')
2045 ByteArray
.fromfile(PeObject
, 4)
2046 # PE signature should be 'PE\0\0'
2047 if ByteArray
.tostring() != 'PE\0\0':
2048 self
.ErrorInfo
= self
.FileName
+ ' has no valid PE signature PE00'
2051 # Read PE file header
2052 ByteArray
= array
.array('B')
2053 ByteArray
.fromfile(PeObject
, 0x14)
2054 ByteList
= ByteArray
.tolist()
2055 SecNumber
= self
._ByteListToInt
(ByteList
[0x2:0x4])
2057 self
.ErrorInfo
= self
.FileName
+ ' has no section header'
2060 # Read PE optional header
2061 OptionalHeaderSize
= self
._ByteListToInt
(ByteArray
[0x10:0x12])
2062 ByteArray
= array
.array('B')
2063 ByteArray
.fromfile(PeObject
, OptionalHeaderSize
)
2064 ByteList
= ByteArray
.tolist()
2065 self
.EntryPoint
= self
._ByteListToInt
(ByteList
[0x10:0x14])
2066 self
.SectionAlignment
= self
._ByteListToInt
(ByteList
[0x20:0x24])
2067 self
.Size
= self
._ByteListToInt
(ByteList
[0x38:0x3C])
2069 # Read each Section Header
2070 for Index
in range(SecNumber
):
2071 ByteArray
= array
.array('B')
2072 ByteArray
.fromfile(PeObject
, 0x28)
2073 ByteList
= ByteArray
.tolist()
2074 SecName
= self
._ByteListToStr
(ByteList
[0:8])
2075 SecVirtualSize
= self
._ByteListToInt
(ByteList
[8:12])
2076 SecRawAddress
= self
._ByteListToInt
(ByteList
[20:24])
2077 SecVirtualAddress
= self
._ByteListToInt
(ByteList
[12:16])
2078 self
.SectionHeaderList
.append((SecName
, SecVirtualAddress
, SecRawAddress
, SecVirtualSize
))
2082 def _ByteListToStr(self
, ByteList
):
2084 for index
in range(len(ByteList
)):
2085 if ByteList
[index
] == 0:
2087 String
+= chr(ByteList
[index
])
2090 def _ByteListToInt(self
, ByteList
):
2092 for index
in range(len(ByteList
) - 1, -1, -1):
2093 Value
= (Value
<< 8) |
int(ByteList
[index
])
2103 def __init__(self
,SkuIdentifier
='', SkuIds
={}):
2105 self
.AvailableSkuIds
= sdict()
2107 self
.SkuIdNumberSet
= []
2108 if SkuIdentifier
== '' or SkuIdentifier
is None:
2109 self
.SkuIdSet
= ['DEFAULT']
2110 self
.SkuIdNumberSet
= ['0U']
2111 elif SkuIdentifier
== 'ALL':
2112 self
.SkuIdSet
= SkuIds
.keys()
2113 self
.SkuIdNumberSet
= [num
.strip() + 'U' for num
in SkuIds
.values()]
2115 r
= SkuIdentifier
.split('|')
2116 self
.SkuIdSet
=[r
[k
].strip() for k
in range(len(r
))]
2119 self
.SkuIdNumberSet
= [SkuIds
[k
].strip() + 'U' for k
in self
.SkuIdSet
]
2121 EdkLogger
.error("build", PARAMETER_INVALID
,
2122 ExtraData
= "SKU-ID [%s] is not supported by the platform. [Valid SKU-ID: %s]"
2123 % (k
, " | ".join(SkuIds
.keys())))
2124 if len(self
.SkuIdSet
) == 2 and 'DEFAULT' in self
.SkuIdSet
and SkuIdentifier
!= 'ALL':
2125 self
.SkuIdSet
.remove('DEFAULT')
2126 self
.SkuIdNumberSet
.remove('0U')
2127 for each
in self
.SkuIdSet
:
2129 self
.AvailableSkuIds
[each
] = SkuIds
[each
]
2131 EdkLogger
.error("build", PARAMETER_INVALID
,
2132 ExtraData
="SKU-ID [%s] is not supported by the platform. [Valid SKU-ID: %s]"
2133 % (each
, " | ".join(SkuIds
.keys())))
2135 def __SkuUsageType(self
):
2137 if len(self
.SkuIdSet
) == 1:
2138 if self
.SkuIdSet
[0] == 'DEFAULT':
2139 return SkuClass
.DEFAULT
2141 return SkuClass
.SINGLE
2143 return SkuClass
.MULTIPLE
2145 def __GetAvailableSkuIds(self
):
2146 return self
.AvailableSkuIds
2148 def __GetSystemSkuID(self
):
2149 if self
.__SkuUsageType
() == SkuClass
.SINGLE
:
2150 return self
.SkuIdSet
[0]
2153 def __GetAvailableSkuIdNumber(self
):
2154 return self
.SkuIdNumberSet
2155 SystemSkuId
= property(__GetSystemSkuID
)
2156 AvailableSkuIdSet
= property(__GetAvailableSkuIds
)
2157 SkuUsageType
= property(__SkuUsageType
)
2158 AvailableSkuIdNumSet
= property(__GetAvailableSkuIdNumber
)
2161 # Pack a registry format GUID
2163 def PackRegistryFormatGuid(Guid
):
2164 Guid
= Guid
.split('-')
2165 return pack('=LHHBBBBBBBB',
2169 int(Guid
[3][-4:-2], 16),
2170 int(Guid
[3][-2:], 16),
2171 int(Guid
[4][-12:-10], 16),
2172 int(Guid
[4][-10:-8], 16),
2173 int(Guid
[4][-8:-6], 16),
2174 int(Guid
[4][-6:-4], 16),
2175 int(Guid
[4][-4:-2], 16),
2176 int(Guid
[4][-2:], 16)
2179 def BuildOptionPcdValueFormat(TokenSpaceGuidCName
, TokenCName
, PcdDatumType
, Value
):
2180 if PcdDatumType
== 'VOID*':
2181 if Value
.startswith('L'):
2183 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"{...}"')
2184 Value
= Value
[0] + '"' + Value
[1:] + '"'
2185 elif Value
.startswith('H'):
2187 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"{...}"')
2191 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"{...}"')
2192 Value
= '"' + Value
+ '"'
2194 IsValid
, Cause
= CheckPcdDatum(PcdDatumType
, Value
)
2196 EdkLogger
.error("build", FORMAT_INVALID
, Cause
, ExtraData
="%s.%s" % (TokenSpaceGuidCName
, TokenCName
))
2197 if PcdDatumType
== 'BOOLEAN':
2198 Value
= Value
.upper()
2199 if Value
== 'TRUE' or Value
== '1':
2201 elif Value
== 'FALSE' or Value
== '0':
2204 ## Get the integer value from string like "14U" or integer like 2
2206 # @param Input The object that may be either a integer value or a string
2208 # @retval Value The integer value that the input represents
2210 def GetIntegerValue(Input
):
2211 if type(Input
) in (int, long):
2214 if String
.endswith("U"):
2215 String
= String
[:-1]
2216 if String
.endswith("ULL"):
2217 String
= String
[:-3]
2218 if String
.endswith("LL"):
2219 String
= String
[:-2]
2221 if String
.startswith("0x") or String
.startswith("0X"):
2222 return int(String
, 16)
2230 # This acts like the main() function for the script, unless it is 'import'ed into another
2233 if __name__
== '__main__':