## @file
# Common routines used by all tools
#
# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
# 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
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
# Import Modules
#
import os
import sys
import string
import thread
import threading
import time
import re
import cPickle
import array
from DataType import *
from BuildToolError import *
## Regular expression used to find out place holders in string template
## Dictionary used to store file time stamp for quick re-access
## Dictionary used to store dependencies of files
## callback routine for processing variable option
#
# This function can be used to process variable number of option values. The
# typical usage of it is specify architecure list on command line.
# (e.g. <tool> -a IA32 X64 IPF)
#
# @param Option Standard callback function parameter
# @param OptionString Standard callback function parameter
# @param Value Standard callback function parameter
# @param Parser Standard callback function parameter
#
# @retval
#
assert Value is None
Value = []
while RawArgs:
break
del RawArgs[0]
## Convert GUID string in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx style to C structure style
#
# @param Guid The GUID string
#
# @retval string The GUID string in C structure style
#
Result = '{'
Result += '}}'
return Result
## Convert GUID structure in byte array to xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
#
# @param GuidValue The GUID value in byte array
#
# @retval string The GUID value in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format
#
guidValueString = GuidValue.lower().replace("{", "").replace("}", "").replace(" ", "").replace(";", "")
return ''
#EdkLogger.error(None, None, "Invalid GUID value string %s" % GuidValue)
try:
return "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" % (
)
except:
return ''
## Convert GUID string in C structure style to xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
#
# @param GuidValue The GUID value in C structure format
#
# @retval string The GUID value in xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx format
#
guidValueString = GuidValue.lower().replace("{", "").replace("}", "").replace(" ", "").replace(";", "")
return ''
#EdkLogger.error(None, None, "Invalid GUID value string %s" % GuidValue)
try:
return "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x" % (
)
except:
return ''
## Convert GUID string in C structure style to xxxxxxxx_xxxx_xxxx_xxxx_xxxxxxxxxxxx
#
# @param GuidValue The GUID value in C structure format
#
# @retval string The GUID value in xxxxxxxx_xxxx_xxxx_xxxx_xxxxxxxxxxxx format
#
return "%08x_%04x_%04x_%02x%02x_%02x%02x%02x%02x%02x%02x" % (
)
## Create directories
#
# @param Directory The directory name
#
return True
try:
except:
return False
return True
## Remove directories, including files and sub-directories in it
#
# @param Directory The directory name
#
return
if Recursively:
else:
## Check if given file is changed or not
#
# This method is used to check if a file is changed or not between two build
# actions. It makes use a cache to store files timestamp.
#
# @param File The path of file
#
# @retval True If the given file is changed, doesn't exist, or can't be
# found in timestamp cache
# @retval False If the given file is changed
#
return True
else:
return FileChanged
## Store content in file
#
# This method is used to save file only when its content is changed. This is
# quite useful for "make" system to decide what will be re-built and what won't.
#
# @param File The path of file
# @param Content The new content of the file
# @param IsBinaryFile The flag indicating if the file is binary file or not
#
# @retval True If the file content is changed and the file is renewed
# @retval False If the file content is the same
#
if not IsBinaryFile:
try:
return False
except:
if not CreateDirectory(DirName):
else:
if DirName == '':
try:
if False: # VBox: Don't want python25.dll dependencies, original: if GlobalData.gIsWindows:
try:
except:
else:
except IOError, X:
return True
## Make a Python object persistent on file system
#
# @param Data The object to be stored in file
# @param File The path of file to store the object
#
Fd = None
try:
except:
finally:
if Fd != None:
## Restore a Python object from a file
#
# @param File The path of file stored the object
#
# @retval object A python object
# @retval None If failure in file operation
#
Data = None
Fd = None
try:
except Exception, e:
Data = None
finally:
if Fd != None:
return Data
## Retrieve and cache the real path name in file system
#
# @param Root The root directory of path relative to
#
# @retval str The path string if the path exists
# @retval None If path doesn't exist
#
class DirCache:
_UPPER_CACHE_ = {}
# =[] operator
if not Path:
IndexList = []
LastSepIndex = -1
while SepIndex > -1:
break
if LastSepIndex == -1:
return None
while SepIndex > -1:
return None
else:
return None
## Get all files of a directory
#
# @param Root: Root dir
# @param SkipList : The files need be skipped
#
# @retval A list of all files
#
FileList = []
if SkipList:
if not FullPath:
return FileList
## Check if gvien file exists or not
#
# @param File File name or path to be checked
# @param Dir The directory the file is relative to
#
# @retval True if file exists
# @retval False if file doesn't exists
#
if Ext != None:
return False
return False
return True
if not NewFile and OverrideDir:
return NewFile
if OverrideDir:
if NewFile:
else:
if GlobalData.gAllFiles:
# VBox hack begin - Required for RAW reset vectors and logo bmps files outside the workspace.
# VBox hack end.
else:
if NewFile:
if Dir:
else:
else:
return NewFile, ''
return None, None
## Check if gvien file exists or not
#
#
def ValidFile2(AllFiles, File, Ext=None, Workspace='', EfiSource='', EdkSource='', Dir='.', OverrideDir=''):
if Ext != None:
# Replace the Edk macros
# Replace the default dir to current dir
if Dir == '.':
# First check if File has Edk definition itself
if NewFile != None:
# Second check the path with override value
if NewFile != None:
# Last check the path with normal definitions
if NewFile != None:
## Check if gvien file exists or not
#
#
# Replace the Edk macros
# Replace the default dir to current dir
# Dir is current module dir related to workspace
if Dir == '.':
while(True):
# First check if File has Edk definition itself
if NewFile != None:
#NewRelaPath = NewFile[:len(NewFile) - len(File.replace("..\\", '').replace("../", '')) - 1]
break
# Second check the path with override value
if NewFile != None:
#NewRelaPath = os.path.dirname(NewFile)
break
# Last check the path with normal definitions
if NewFile != None:
break
# No file found
break
break
## Get GUID value from given packages
#
# @param CName The CName of the GUID
# @param PackageList List of packages looking-up in
#
# @retval GuidValue if the CName is found in any given package
# @retval None if the CName is not found in all given packages
#
for P in PackageList:
return None
## Get Protocol value from given packages
#
# @param CName The CName of the GUID
# @param PackageList List of packages looking-up in
#
# @retval GuidValue if the CName is found in any given package
# @retval None if the CName is not found in all given packages
#
for P in PackageList:
return None
## Get PPI value from given packages
#
# @param CName The CName of the GUID
# @param PackageList List of packages looking-up in
#
# @retval GuidValue if the CName is found in any given package
# @retval None if the CName is not found in all given packages
#
for P in PackageList:
return None
## A string template class
#
# This class implements a template for string replacement. A string template
# looks like following
#
# ${BEGIN} other_string ${placeholder_name} other_string ${END}
#
# The string between ${BEGIN} and ${END} will be repeated as many times as the
# length of "placeholder_name", which is a list passed through a dict. The
# "placeholder_name" is the key name of the dict. The ${BEGIN} and ${END} can
# be not used and, in this case, the "placeholder_name" must not a list and it
# will just be replaced once.
#
self._PlaceHolderList = []
# Split the section into sub-sections according to the position of placeholders
if PlaceHolderList:
self._SubSectionList = []
SubSectionStart = 0
#
# The placeholders passed in must be in the format of
#
# PlaceHolderName, PlaceHolderStartPoint, PlaceHolderEndPoint
#
else:
RepeatTime = -1
RepeatPlaceHolders = {}
if PlaceHolder not in PlaceHolderValues:
continue
if RepeatTime < 0:
"TemplateString",
"${%s} has different repeat time from others!" % PlaceHolder,
)
else:
StringList = []
for S in self._SubSectionList:
if S not in NonRepeatPlaceHolders:
StringList.append(S)
else:
else:
TempStringList = []
for S in StringList:
if S not in RepeatPlaceHolders:
else:
## Constructor
## str() operator
#
# @retval string The string replaced
#
## Split the template string into fragments per the ${BEGIN} and ${END} flags
#
# @retval list A list of TemplateString.Section objects
#
SectionStart = 0
SearchFrom = 0
MatchEnd = 0
PlaceHolderList = []
TemplateSectionList = []
while Template:
if not MatchObj:
break
if MatchStart > SectionStart:
PlaceHolderList = []
PlaceHolderList = []
else:
return TemplateSectionList
## Replace the string template with dictionary of placeholders and append it to previous one
#
# @param AppendString The string template to append
# @param Dictionary The placeholder dictionaries
#
if Dictionary:
else:
## Replace the string template with dictionary of placeholders
#
# @param Dictionary The placeholder dictionaries
#
# @retval str The string replaced with placeholder values
#
## Progress indicator class
#
# This class makes use of thread to print progress on console.
#
class Progressor:
# for avoiding deadloop
_StopFlag = None
_ProgressThread = None
## Constructor
#
# @param OpenMessage The string printed before progress charaters
# @param CloseMessage The string printed after progress charaters
# @param ProgressChar The charater used to indicate the progress
# @param Interval The interval in seconds between two progress charaters
#
if Progressor._StopFlag == None:
## Start to print progress charater
#
# @param OpenMessage The string printed before progress charaters
#
if OpenMessage != None:
if Progressor._ProgressThread == None:
## Stop printing progress charater
#
# @param CloseMessage The string printed after progress charaters
#
if CloseMessage != None:
## Thread entry method
TimeUp = 0.0
if TimeUp <= 0.0:
## Abort the progress display
def Abort():
if Progressor._StopFlag != None:
if Progressor._ProgressThread != None:
Progressor._ProgressThread = None
#
# The class implements a new kind of dict which its keys or values can be
# accessed in the order they are added into the dict. It guarantees the order
# by making use of an internal list to keep a copy of keys.
#
## Constructor
## [] operator
## del operator
## used in "for k in dict" loop to ensure the correct order
## len() support
## "in" test support
## indexof support
## insert support
if order == 'BEFORE':
elif order == 'AFTER':
## append support
## Empty the dict
## Return a copy of keys
keys = []
return keys
## Return a copy of values
values = []
return values
## Return a copy of (key, value) list
items = []
return items
## Iteration support
## Keys interation support
## Values interation support
## Return value related to a key, and remove the (key, value) from the dict
value = None
return value
## Return (key, value) pair, and remove the (key, value) from the dict
if dict != None:
self[k] = v
self[k] = v
## Dictionary with restricted keys
#
## Constructor
## []= operator
## =[] operator
return ""
## del operator
## Empty the dict
## Return value related to a key, and remove the (key, value) from the dict
## Return (key, value) pair, and remove the (key, value) from the dict
## Dictionary using prioritized list as key
#
class tdict:
# =[] operator
RestKeys = None
else:
else:
Value = None
#print "%s-%s" % (FirstKey, self._Level_) ,
if Value == None:
if Value != None: break
else:
#print "Value=None"
else:
if Value == None:
if Value != None: break
else:
return Value
Value = []
else:
else:
else:
return Value
## []= operator
RestKeys = None
else:
else:
else:
assert KeyIndex >= 0
if KeyIndex == 0:
else:
return keys
## Boolean chain list
#
if item == 0:
else:
return Value
## AnalyzePcdData
#
# Analyze the pcd Value, Datum type and TokenNumber.
# Used to avoid split issue while the value string contain "|" character
#
#
# @retval ValueList: A List contain value, datum type and toke number.
#
if ValueUpdateFlag:
return ValueList
## AnalyzeHiiPcdData
#
# Analyze the pcd Value, variable name, variable Guid and variable offset.
# Used to avoid split issue while the value string contain "|" character
#
# @param[in] Setting: A String contain VariableName, VariableGuid, VariableOffset, DefaultValue information;
#
# @retval ValueList: A List contaian VariableName, VariableGuid, VariableOffset, DefaultValue.
#
if ValueUpdateFlag:
return ValueList
## AnalyzeVpdPcdData
#
# Analyze the vpd pcd Value, Datum type and TokenNumber.
# Used to avoid split issue while the value string contain "|" character
#
#
# @retval ValueList: A List contain value, datum type and toke number.
#
if ValueUpdateFlag:
return ValueList
## check format of PCD value against its the datum type
#
# For PCD value setting
#
if Type == "VOID*":
):
return False, "Invalid value [%s] of type [%s]; must be in the form of {...} for array"\
elif Type == 'BOOLEAN':
if Value not in ['TRUE', 'True', 'true', '0x1', '0x01', '1', 'FALSE', 'False', 'false', '0x0', '0x00', '0']:
return False, "Invalid value [%s] of type [%s]; must be one of TRUE, True, true, 0x1, 0x01, 1"\
try:
except:
return False, "Invalid value [%s] of type [%s];"\
" must be a hexadecimal, decimal or octal in C language format."\
return True, ""
## Split command line option string to list
#
# subprocess.Popen needs the args to be a sequence. Otherwise there's problem
# in non-windows platform to launch command
#
OptionList = []
LastChar = " "
OptionStart = 0
QuotationMark = ""
if QuotationMark == CurrentChar:
QuotationMark = ""
elif QuotationMark == "":
continue
elif QuotationMark:
continue
if Index > OptionStart:
return OptionList
else:
# Remove any '.' and '..' in path
# eliminate the side-effect of 'C:'
# file path should not start with path separator
else:
else:
else:
else:
if IsBinary:
else:
## Convert the object of this class to a string
#
# Convert member Path of the class to a string
#
# @retval string Formatted String
#
## Override __eq__ function
#
# Check whether PathClass are the same
#
# @retval False The two PathClass are different
# @retval True The two PathClass are the same
#
else:
## Override __cmp__ function
#
# Customize the comparsion operation of two PathClass
#
# @retval 0 The two PathClass are different
# @retval -1 The first PathClass is less than the second PathClass
# @retval 1 The first PathClass is Bigger than the second PathClass
else:
return 0
return 1
else:
return -1
## Override __hash__ function
#
# Use Path as key in hash table
#
# @retval string Key for hash table
#
ErrorCode = 0
ErrorInfo = ''
if CaseSensitive and (RealFile != self.File or (RealRoot != self.Root and RealRoot != self.AlterRoot)):
else:
## Parse PE image to get the required PE informaion.
#
class PeImageClass():
## Constructor
#
# @param File FilePath of PeImage
#
self.SectionHeaderList = []
try:
except:
return
# Read DOS header
# DOS signature should be 'MZ'
return
# Read 4 byte PE Signature
# PE signature should be 'PE\0\0'
return
# Read PE file header
if SecNumber == 0:
return
# Read PE optional header
# Read each Section Header
String = ''
break
return String
Value = 0
return Value
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
pass