592e276fd145fc76c2e929245eea271e71b35371
[people/mcb30/basetools.git] / Source / Python / Common / ToolDefClassObject.py
1 # Copyright (c) 2007, Intel Corporation\r
2 # All rights reserved. This program and the accompanying materials\r
3 # are licensed and made available under the terms and conditions of the BSD License\r
4 # which accompanies this distribution.    The full text of the license may be found at\r
5 # http://opensource.org/licenses/bsd-license.php\r
6 #\r
7 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
8 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
9 \r
10 #\r
11 #This file is used to define each component of tools_def.txt file\r
12 #\r
13 \r
14 import os\r
15 import re\r
16 import EdkLogger\r
17 \r
18 from Dictionary import *\r
19 from BuildToolError import *\r
20 from TargetTxtClassObject import *\r
21 \r
22 gMacroRefPattern = re.compile('(DEF\([^\(\)]+\))')\r
23 gEnvRefPattern = re.compile('(ENV\([^\(\)]+\))')\r
24 gMacroDefPattern = re.compile("DEFINE\s+([^\s]+)")\r
25 \r
26 class ToolDefClassObject(object):\r
27     def __init__(self, FileName = None):\r
28         self.ToolsDefTxtDictionary = {}\r
29         self.MacroDictionary = {}\r
30         for Env in os.environ:\r
31             self.MacroDictionary["ENV(%s)" % Env] = os.environ[Env]\r
32 \r
33         if FileName != None:\r
34             self.LoadToolDefFile(FileName)\r
35 \r
36     def LoadToolDefFile(self, FileName):\r
37         FileContent = []\r
38         if os.path.isfile(FileName):\r
39             try:\r
40                 F = open(FileName,'r')\r
41                 FileContent = F.readlines()\r
42             except:\r
43                 EdkLogger.error("tools_def.txt parser", FILE_OPEN_FAILURE, ExtraData=FileName)\r
44         else:\r
45             EdkLogger.error("tools_def.txt parser", FILE_NOT_FOUND, ExtraData=FileName)\r
46 \r
47         self.ToolsDefTxtDatabase = {\r
48             TAB_TOD_DEFINES_TARGET          :   [],\r
49             TAB_TOD_DEFINES_TOOL_CHAIN_TAG  :   [],\r
50             TAB_TOD_DEFINES_TARGET_ARCH     :   [],\r
51             TAB_TOD_DEFINES_COMMAND_TYPE    :   []\r
52         }\r
53 \r
54         for Index in range(len(FileContent)):\r
55             Line = FileContent[Index].strip()\r
56             if Line == "" or Line[0] == '#':\r
57                 continue\r
58             NameValuePair = Line.split("=", 1)\r
59             if len(NameValuePair) != 2:\r
60                 EdkLogger.warn("Line %d: not correct assignment statement, skipped" % (Index + 1))\r
61                 continue\r
62 \r
63             Name = NameValuePair[0].strip()\r
64             Value = NameValuePair[1].strip()\r
65 \r
66             if Name == "IDENTIFIER":\r
67                 EdkLogger.debug(EdkLogger.DEBUG_9, "Line %d: Found identifier statement, skipped: %s" % ((Index + 1), Value))\r
68                 continue\r
69 \r
70             MacroDefinition = gMacroDefPattern.findall(Name)\r
71             if MacroDefinition != []:\r
72                 EnvReference = gEnvRefPattern.findall(Value)\r
73                 for Ref in EnvReference:\r
74                     if Ref not in self.MacroDictionary:\r
75                         EdkLogger.error("tools_def.txt parser", PARSER_ERROR,\r
76                                         "Environment [%s] has not been defined" % Ref,\r
77                                         File=FileName, Line=Index+1)\r
78                     Value = Value.replace(Ref, self.MacroDictionary[Ref])\r
79 \r
80                 Value = self.ExpandMacros(Value)\r
81 \r
82                 MacroName = MacroDefinition[0].strip()\r
83                 self.MacroDictionary["DEF(%s)" % MacroName] = Value\r
84                 EdkLogger.debug(EdkLogger.DEBUG_9, "Line %d: Found macro: %s = %s" % ((Index + 1), MacroName, Value))\r
85                 continue\r
86 \r
87             Value = self.ExpandMacros(Value)\r
88 \r
89             List = Name.split('_')\r
90             if len(List) != 5:\r
91                 EdkLogger.verbose("Line %d: Not a valid name of definition: %s" % ((Index + 1), Name))\r
92                 continue\r
93             elif List[4] == '*':\r
94                 EdkLogger.verbose("Line %d: '*' is not allowed in last field: %s" % ((Index + 1), Name))\r
95                 continue\r
96             else:\r
97                 self.ToolsDefTxtDictionary[Name] = Value\r
98                 if List[0] != '*':\r
99                     self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET] += [List[0]]\r
100                 if List[1] != '*':\r
101                     self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG] += [List[1]]\r
102                 if List[2] != '*':\r
103                     self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH] += [List[2]]\r
104                 if List[3] != '*':\r
105                     self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE] += [List[3]]\r
106 \r
107         self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET]                 = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET]))\r
108         self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG]))\r
109         self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH]        = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH]))\r
110         self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE]     = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE]))\r
111 \r
112         self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET].sort()\r
113         self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG].sort()\r
114         self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH].sort()\r
115         self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE].sort()\r
116 \r
117         KeyList = [TAB_TOD_DEFINES_TARGET, TAB_TOD_DEFINES_TOOL_CHAIN_TAG, TAB_TOD_DEFINES_TARGET_ARCH, TAB_TOD_DEFINES_COMMAND_TYPE]\r
118         for Index in range(3,-1,-1):\r
119             for Key in dict(self.ToolsDefTxtDictionary):\r
120                 List = Key.split('_')\r
121                 if List[Index] == '*':\r
122                     for String in self.ToolsDefTxtDatabase[KeyList[Index]]:\r
123                         List[Index] = String\r
124                         NewKey = '%s_%s_%s_%s_%s' % tuple(List)\r
125                         if NewKey not in self.ToolsDefTxtDictionary:\r
126                             self.ToolsDefTxtDictionary[NewKey] = self.ToolsDefTxtDictionary[Key]\r
127                         continue\r
128                     del self.ToolsDefTxtDictionary[Key]\r
129                 elif List[Index] not in self.ToolsDefTxtDatabase[KeyList[Index]]:\r
130                     del self.ToolsDefTxtDictionary[Key]\r
131 \r
132     def ExpandMacros(self, Value):\r
133 \r
134         MacroReference = gMacroRefPattern.findall(Value)\r
135         for Ref in MacroReference:\r
136             if Ref not in self.MacroDictionary:\r
137                 EdkLogger.error("tools_def.txt parser", PARSER_ERROR,\r
138                                 "Macro [%s] has not been defined" % Ref,\r
139                                 File=FileName, Line=Index+1)\r
140             Value = Value.replace(Ref, self.MacroDictionary[Ref])\r
141 \r
142         return Value\r
143 \r
144 def ToolDefDict(WorkSpace):\r
145     Target = TargetTxtClassObject()\r
146     Target.LoadTargetTxtFile(WorkSpace + '\\Conf\\target.txt')\r
147     ToolDef = ToolDefClassObject()\r
148     ToolDef.LoadToolDefFile(WorkSpace + '\\' + Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF])\r
149     return ToolDef\r
150 \r
151 if __name__ == '__main__':\r
152 ##    td = ToolDefClassObject('tool_def.txt')\r
153 ##    print td.ToolsDefTxtDatabase\r
154 \r
155     ToolDef = ToolDefDict(os.getenv("WORKSPACE"))\r
156     pass\r