import re\r
import cPickle\r
import array\r
+import shutil\r
from UserDict import IterableUserDict\r
from UserList import UserList\r
\r
## Dictionary used to store dependencies of files\r
gDependencyDatabase = {} # arch : {file path : [dependent files list]}\r
\r
+## Routine to process duplicated INF\r
+#\r
+# This function is called by following two cases:\r
+# Case 1 in DSC:\r
+# [components.arch]\r
+# Pkg/module/module.inf\r
+# Pkg/module/module.inf {\r
+# <Defines>\r
+# FILE_GUID = 0D1B936F-68F3-4589-AFCC-FB8B7AEBC836\r
+# }\r
+# Case 2 in FDF:\r
+# INF Pkg/module/module.inf\r
+# INF FILE_GUID = 0D1B936F-68F3-4589-AFCC-FB8B7AEBC836 Pkg/module/module.inf\r
+#\r
+# This function copies Pkg/module/module.inf to\r
+# Conf/.cache/0D1B936F-68F3-4589-AFCC-FB8B7AEBC836module.inf\r
+#\r
+# @param Path Original PathClass object\r
+# @param BaseName New file base name\r
+#\r
+# @retval return the new PathClass object\r
+#\r
+def ProcessDuplicatedInf(Path, BaseName, Workspace):\r
+ Filename = os.path.split(Path.File)[1]\r
+ if '.' in Filename:\r
+ Filename = BaseName + Path.BaseName + Filename[Filename.rfind('.'):]\r
+ else:\r
+ Filename = BaseName + Path.BaseName\r
+\r
+ #\r
+ # If -N is specified on command line, cache is disabled\r
+ # The directory has to be created\r
+ #\r
+ DbDir = os.path.split(GlobalData.gDatabasePath)[0]\r
+ if not os.path.exists(DbDir):\r
+ os.makedirs(DbDir)\r
+ #\r
+ # A temporary INF is copied to database path which must have write permission\r
+ # The temporary will be removed at the end of build\r
+ # In case of name conflict, the file name is \r
+ # FILE_GUIDBaseName (0D1B936F-68F3-4589-AFCC-FB8B7AEBC836module.inf)\r
+ #\r
+ TempFullPath = os.path.join(DbDir,\r
+ Filename)\r
+ RtPath = PathClass(Path.File, Workspace)\r
+ #\r
+ # Modify the full path to temporary path, keep other unchanged\r
+ #\r
+ # To build same module more than once, the module path with FILE_GUID overridden has\r
+ # the file name FILE_GUIDmodule.inf, but the relative path (self.MetaFile.File) is the real path\r
+ # in DSC which is used as relative path by C files and other files in INF. \r
+ # A trick was used: all module paths are PathClass instances, after the initialization\r
+ # of PathClass, the PathClass.Path is overridden by the temporary INF path.\r
+ #\r
+ # The reason for creating a temporary INF is:\r
+ # Platform.Modules which is the base to create ModuleAutoGen objects is a dictionary,\r
+ # the key is the full path of INF, the value is an object to save overridden library instances, PCDs.\r
+ # A different key for the same module is needed to create different output directory,\r
+ # retrieve overridden PCDs, library instances.\r
+ #\r
+ # The BaseName is the FILE_GUID which is also the output directory name.\r
+ #\r
+ #\r
+ RtPath.Path = TempFullPath\r
+ RtPath.BaseName = BaseName\r
+ #\r
+ # If file exists, compare contents\r
+ #\r
+ if os.path.exists(TempFullPath):\r
+ with open(str(Path), 'rb') as f1: Src = f1.read()\r
+ with open(TempFullPath, 'rb') as f2: Dst = f2.read()\r
+ if Src == Dst:\r
+ return RtPath\r
+ GlobalData.gTempInfs.append(TempFullPath)\r
+ shutil.copy2(str(Path), TempFullPath)\r
+ return RtPath\r
+\r
+## Remove temporary created INFs whose paths were saved in gTempInfs\r
+#\r
+def ClearDuplicatedInf():\r
+ for File in GlobalData.gTempInfs:\r
+ if os.path.exists(File):\r
+ os.remove(File)\r
+\r
## callback routine for processing variable option\r
#\r
# This function can be used to process variable number of option values. The\r
return os.path.sep.join(P1[:Index])\r
return os.path.sep.join(P1)\r
\r
+#\r
+# Convert string to C format array\r
+#\r
+def ConvertStringToByteArray(Value):\r
+ Value = Value.strip()\r
+ if not Value:\r
+ return None\r
+ if Value[0] == '{':\r
+ if not Value.endswith('}'):\r
+ return None\r
+ Value = Value.replace(' ', '').replace('{', '').replace('}', '')\r
+ ValFields = Value.split(',')\r
+ try:\r
+ for Index in range(len(ValFields)):\r
+ ValFields[Index] = str(int(ValFields[Index], 0))\r
+ except ValueError:\r
+ return None\r
+ Value = '{' + ','.join(ValFields) + '}'\r
+ return Value\r
+\r
+ Unicode = False\r
+ if Value.startswith('L"'):\r
+ if not Value.endswith('"'):\r
+ return None\r
+ Value = Value[1:]\r
+ Unicode = True\r
+ elif not Value.startswith('"') or not Value.endswith('"'):\r
+ return None\r
+\r
+ Value = eval(Value) # translate escape character\r
+ NewValue = '{'\r
+ for Index in range(0,len(Value)):\r
+ if Unicode:\r
+ NewValue = NewValue + str(ord(Value[Index]) % 0x10000) + ','\r
+ else:\r
+ NewValue = NewValue + str(ord(Value[Index]) % 0x100) + ','\r
+ Value = NewValue + '0}'\r
+ return Value\r
+\r
class PathClass(object):\r
def __init__(self, File='', Root='', AlterRoot='', Type='', IsBinary=False,\r
Arch='COMMON', ToolChainFamily='', Target='', TagName='', ToolCode=''):\r