BaseTools: Refactor python except statements
[mirror_edk2.git] / BaseTools / Source / Python / TargetTool / TargetTool.py
CommitLineData
97fa0ee9
YL
1## @file\r
2# Target Tool Parser\r
30fdf114 3#\r
9eb87141 4# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
30fdf114 5#\r
40d841f6 6# This program and the accompanying materials\r
30fdf114
LG
7# are licensed and made available under the terms and conditions of the BSD License\r
8# which accompanies this distribution. The full text of the license may be found at\r
9# http://opensource.org/licenses/bsd-license.php\r
10#\r
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13#\r
14\r
1be2ed90 15import Common.LongFilePathOs as os\r
30fdf114
LG
16import sys\r
17import traceback\r
18from optparse import OptionParser\r
19\r
20import Common.EdkLogger as EdkLogger\r
21import Common.BuildToolError as BuildToolError\r
22from Common.DataType import *\r
b36d134f 23from Common.BuildVersion import gBUILD_VERSION\r
1be2ed90 24from Common.LongFilePathSupport import OpenLongFilePath as open\r
30fdf114
LG
25\r
26# To Do 1.set clean, 2. add item, if the line is disabled.\r
27\r
28class TargetTool():\r
29 def __init__(self, opt, args):\r
30 self.WorkSpace = os.path.normpath(os.getenv('WORKSPACE'))\r
31 self.Opt = opt\r
32 self.Arg = args[0]\r
33 self.FileName = os.path.normpath(os.path.join(self.WorkSpace, 'Conf', 'target.txt'))\r
34 if os.path.isfile(self.FileName) == False:\r
35 print "%s does not exist." % self.FileName\r
36 sys.exit(1)\r
37 self.TargetTxtDictionary = {\r
38 TAB_TAT_DEFINES_ACTIVE_PLATFORM : None,\r
39 TAB_TAT_DEFINES_TOOL_CHAIN_CONF : None,\r
30fdf114
LG
40 TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER : None,\r
41 TAB_TAT_DEFINES_TARGET : None,\r
42 TAB_TAT_DEFINES_TOOL_CHAIN_TAG : None,\r
43 TAB_TAT_DEFINES_TARGET_ARCH : None,\r
44 TAB_TAT_DEFINES_BUILD_RULE_CONF : None,\r
45 }\r
46 self.LoadTargetTxtFile(self.FileName)\r
47\r
48 def LoadTargetTxtFile(self, filename):\r
49 if os.path.exists(filename) and os.path.isfile(filename):\r
08dd311f 50 return self.ConvertTextFileToDict(filename, '#', '=')\r
30fdf114
LG
51 else:\r
52 raise ParseError('LoadTargetTxtFile() : No Target.txt file exists.')\r
53 return 1\r
54\r
55#\r
56# Convert a text file to a dictionary\r
57#\r
58 def ConvertTextFileToDict(self, FileName, CommentCharacter, KeySplitCharacter):\r
59 """Convert a text file to a dictionary of (name:value) pairs."""\r
60 try:\r
61 f = open(FileName,'r')\r
62 for Line in f:\r
63 if Line.startswith(CommentCharacter) or Line.strip() == '':\r
64 continue\r
65 LineList = Line.split(KeySplitCharacter,1)\r
66 if len(LineList) >= 2:\r
67 Key = LineList[0].strip()\r
9eb87141 68 if Key.startswith(CommentCharacter) == False and Key in self.TargetTxtDictionary:\r
30fdf114 69 if Key == TAB_TAT_DEFINES_ACTIVE_PLATFORM or Key == TAB_TAT_DEFINES_TOOL_CHAIN_CONF \\r
08dd311f 70 or Key == TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER \\r
30fdf114
LG
71 or Key == TAB_TAT_DEFINES_ACTIVE_MODULE:\r
72 self.TargetTxtDictionary[Key] = LineList[1].replace('\\', '/').strip()\r
73 elif Key == TAB_TAT_DEFINES_TARGET or Key == TAB_TAT_DEFINES_TARGET_ARCH \\r
74 or Key == TAB_TAT_DEFINES_TOOL_CHAIN_TAG or Key == TAB_TAT_DEFINES_BUILD_RULE_CONF:\r
75 self.TargetTxtDictionary[Key] = LineList[1].split()\r
76 f.close()\r
77 return 0\r
78 except:\r
79 last_type, last_value, last_tb = sys.exc_info()\r
80 traceback.print_exception(last_type, last_value, last_tb)\r
81\r
82 def Print(self):\r
30fdf114 83 errMsg = ''\r
98120f5f 84 for Key in self.TargetTxtDictionary:\r
30fdf114
LG
85 if type(self.TargetTxtDictionary[Key]) == type([]):\r
86 print "%-30s = %s" % (Key, ''.join(elem + ' ' for elem in self.TargetTxtDictionary[Key]))\r
4231a819 87 elif self.TargetTxtDictionary[Key] is None:\r
30fdf114
LG
88 errMsg += " Missing %s configuration information, please use TargetTool to set value!" % Key + os.linesep \r
89 else:\r
90 print "%-30s = %s" % (Key, self.TargetTxtDictionary[Key])\r
91 \r
92 if errMsg != '':\r
93 print os.linesep + 'Warning:' + os.linesep + errMsg\r
94 \r
95 def RWFile(self, CommentCharacter, KeySplitCharacter, Num):\r
96 try:\r
97 fr = open(self.FileName, 'r')\r
98 fw = open(os.path.normpath(os.path.join(self.WorkSpace, 'Conf\\targetnew.txt')), 'w')\r
99\r
100 existKeys = []\r
101 for Line in fr:\r
102 if Line.startswith(CommentCharacter) or Line.strip() == '':\r
103 fw.write(Line)\r
104 else:\r
105 LineList = Line.split(KeySplitCharacter,1)\r
106 if len(LineList) >= 2:\r
107 Key = LineList[0].strip()\r
9eb87141 108 if Key.startswith(CommentCharacter) == False and Key in self.TargetTxtDictionary:\r
30fdf114
LG
109 if Key not in existKeys:\r
110 existKeys.append(Key)\r
111 else:\r
112 print "Warning: Found duplicate key item in original configuration files!"\r
113 \r
114 if Num == 0:\r
115 Line = "%-30s = \n" % Key\r
116 else:\r
117 ret = GetConfigureKeyValue(self, Key)\r
4231a819 118 if ret is not None:\r
30fdf114
LG
119 Line = ret\r
120 fw.write(Line)\r
9eb87141 121 for key in self.TargetTxtDictionary:\r
30fdf114
LG
122 if key not in existKeys:\r
123 print "Warning: %s does not exist in original configuration file" % key\r
124 Line = GetConfigureKeyValue(self, key)\r
4231a819 125 if Line is None:\r
30fdf114
LG
126 Line = "%-30s = " % key\r
127 fw.write(Line)\r
128 \r
129 fr.close()\r
130 fw.close()\r
131 os.remove(self.FileName)\r
132 os.rename(os.path.normpath(os.path.join(self.WorkSpace, 'Conf\\targetnew.txt')), self.FileName)\r
133 \r
134 except:\r
135 last_type, last_value, last_tb = sys.exc_info()\r
136 traceback.print_exception(last_type, last_value, last_tb)\r
137\r
138def GetConfigureKeyValue(self, Key):\r
139 Line = None\r
4231a819 140 if Key == TAB_TAT_DEFINES_ACTIVE_PLATFORM and self.Opt.DSCFILE is not None:\r
30fdf114
LG
141 dscFullPath = os.path.join(self.WorkSpace, self.Opt.DSCFILE)\r
142 if os.path.exists(dscFullPath):\r
143 Line = "%-30s = %s\n" % (Key, self.Opt.DSCFILE)\r
144 else:\r
145 EdkLogger.error("TagetTool", BuildToolError.FILE_NOT_FOUND, \r
146 "DSC file %s does not exist!" % self.Opt.DSCFILE, RaiseError=False)\r
4231a819 147 elif Key == TAB_TAT_DEFINES_TOOL_CHAIN_CONF and self.Opt.TOOL_DEFINITION_FILE is not None:\r
30fdf114
LG
148 tooldefFullPath = os.path.join(self.WorkSpace, self.Opt.TOOL_DEFINITION_FILE)\r
149 if os.path.exists(tooldefFullPath):\r
150 Line = "%-30s = %s\n" % (Key, self.Opt.TOOL_DEFINITION_FILE)\r
151 else:\r
152 EdkLogger.error("TagetTool", BuildToolError.FILE_NOT_FOUND, \r
153 "Tooldef file %s does not exist!" % self.Opt.TOOL_DEFINITION_FILE, RaiseError=False)\r
08dd311f
LG
154\r
155 elif self.Opt.NUM >= 2:\r
156 Line = "%-30s = %s\n" % (Key, 'Enable')\r
157 elif self.Opt.NUM <= 1:\r
158 Line = "%-30s = %s\n" % (Key, 'Disable') \r
4231a819 159 elif Key == TAB_TAT_DEFINES_MAX_CONCURRENT_THREAD_NUMBER and self.Opt.NUM is not None:\r
30fdf114 160 Line = "%-30s = %s\n" % (Key, str(self.Opt.NUM))\r
4231a819 161 elif Key == TAB_TAT_DEFINES_TARGET and self.Opt.TARGET is not None:\r
30fdf114 162 Line = "%-30s = %s\n" % (Key, ''.join(elem + ' ' for elem in self.Opt.TARGET))\r
4231a819 163 elif Key == TAB_TAT_DEFINES_TARGET_ARCH and self.Opt.TARGET_ARCH is not None:\r
30fdf114 164 Line = "%-30s = %s\n" % (Key, ''.join(elem + ' ' for elem in self.Opt.TARGET_ARCH))\r
4231a819 165 elif Key == TAB_TAT_DEFINES_TOOL_CHAIN_TAG and self.Opt.TOOL_CHAIN_TAG is not None:\r
30fdf114 166 Line = "%-30s = %s\n" % (Key, self.Opt.TOOL_CHAIN_TAG)\r
4231a819 167 elif Key == TAB_TAT_DEFINES_BUILD_RULE_CONF and self.Opt.BUILD_RULE_FILE is not None:\r
30fdf114
LG
168 buildruleFullPath = os.path.join(self.WorkSpace, self.Opt.BUILD_RULE_FILE)\r
169 if os.path.exists(buildruleFullPath):\r
170 Line = "%-30s = %s\n" % (Key, self.Opt.BUILD_RULE_FILE)\r
171 else:\r
172 EdkLogger.error("TagetTool", BuildToolError.FILE_NOT_FOUND, \r
173 "Build rule file %s does not exist!" % self.Opt.BUILD_RULE_FILE, RaiseError=False)\r
174 return Line\r
175\r
b36d134f 176VersionNumber = ("0.01" + " " + gBUILD_VERSION)\r
30fdf114 177__version__ = "%prog Version " + VersionNumber\r
52302d4d 178__copyright__ = "Copyright (c) 2007 - 2010, Intel Corporation All rights reserved."\r
30fdf114
LG
179__usage__ = "%prog [options] {args} \\r
180\nArgs: \\r
181\n Clean clean the all default configuration of target.txt. \\r
182\n Print print the all default configuration of target.txt. \\r
183\n Set replace the default configuration with expected value specified by option."\r
184\r
185gParamCheck = []\r
186def SingleCheckCallback(option, opt_str, value, parser):\r
187 if option not in gParamCheck:\r
188 setattr(parser.values, option.dest, value)\r
189 gParamCheck.append(option)\r
190 else:\r
191 parser.error("Option %s only allows one instance in command line!" % option)\r
192\r
193def RangeCheckCallback(option, opt_str, value, parser):\r
194 if option not in gParamCheck:\r
195 gParamCheck.append(option)\r
196 if value < 1 or value > 8:\r
197 parser.error("The count of multi-thread is not in valid range of 1 ~ 8.")\r
198 else:\r
199 setattr(parser.values, option.dest, value)\r
200 else:\r
201 parser.error("Option %s only allows one instance in command line!" % option)\r
202 \r
203def MyOptionParser():\r
204 parser = OptionParser(version=__version__,prog="TargetTool.exe",usage=__usage__,description=__copyright__)\r
4afd3d04
LG
205 parser.add_option("-a", "--arch", action="append", type="choice", choices=['IA32','X64','IPF','EBC', 'ARM', 'AARCH64','0'], dest="TARGET_ARCH",\r
206 help="ARCHS is one of list: IA32, X64, IPF, ARM, AARCH64 or EBC, which replaces target.txt's TARGET_ARCH definition. To specify more archs, please repeat this option. 0 will clear this setting in target.txt and can't combine with other value.")\r
30fdf114
LG
207 parser.add_option("-p", "--platform", action="callback", type="string", dest="DSCFILE", callback=SingleCheckCallback,\r
208 help="Specify a DSC file, which replace target.txt's ACTIVE_PLATFORM definition. 0 will clear this setting in target.txt and can't combine with other value.")\r
209 parser.add_option("-c", "--tooldef", action="callback", type="string", dest="TOOL_DEFINITION_FILE", callback=SingleCheckCallback,\r
210 help="Specify the WORKSPACE relative path of tool_def.txt file, which replace target.txt's TOOL_CHAIN_CONF definition. 0 will clear this setting in target.txt and can't combine with other value.")\r
211 parser.add_option("-t", "--target", action="append", type="choice", choices=['DEBUG','RELEASE','0'], dest="TARGET",\r
212 help="TARGET is one of list: DEBUG, RELEASE, which replaces target.txt's TARGET definition. To specify more TARGET, please repeat this option. 0 will clear this setting in target.txt and can't combine with other value.")\r
213 parser.add_option("-n", "--tagname", action="callback", type="string", dest="TOOL_CHAIN_TAG", callback=SingleCheckCallback,\r
214 help="Specify the Tool Chain Tagname, which replaces target.txt's TOOL_CHAIN_TAG definition. 0 will clear this setting in target.txt and can't combine with other value.")\r
215 parser.add_option("-r", "--buildrule", action="callback", type="string", dest="BUILD_RULE_FILE", callback=SingleCheckCallback,\r
216 help="Specify the build rule configure file, which replaces target.txt's BUILD_RULE_CONF definition. If not specified, the default value Conf/build_rule.txt will be set.")\r
217 parser.add_option("-m", "--multithreadnum", action="callback", type="int", dest="NUM", callback=RangeCheckCallback,\r
218 help="Specify the multi-thread number which replace target.txt's MAX_CONCURRENT_THREAD_NUMBER. If the value is less than 2, MULTIPLE_THREAD will be disabled. If the value is larger than 1, MULTIPLE_THREAD will be enabled.")\r
30fdf114
LG
219 (opt, args)=parser.parse_args()\r
220 return (opt, args)\r
221\r
222if __name__ == '__main__':\r
223 EdkLogger.Initialize()\r
224 EdkLogger.SetLevel(EdkLogger.QUIET)\r
4231a819 225 if os.getenv('WORKSPACE') is None:\r
30fdf114
LG
226 print "ERROR: WORKSPACE should be specified or edksetup script should be executed before run TargetTool"\r
227 sys.exit(1)\r
228 \r
229 (opt, args) = MyOptionParser()\r
230 if len(args) != 1 or (args[0].lower() != 'print' and args[0].lower() != 'clean' and args[0].lower() != 'set'):\r
231 print "The number of args isn't 1 or the value of args is invalid."\r
232 sys.exit(1)\r
4231a819 233 if opt.NUM is not None and opt.NUM < 1:\r
30fdf114
LG
234 print "The MAX_CONCURRENT_THREAD_NUMBER must be larger than 0."\r
235 sys.exit(1)\r
4231a819 236 if opt.TARGET is not None and len(opt.TARGET) > 1:\r
30fdf114
LG
237 for elem in opt.TARGET:\r
238 if elem == '0':\r
239 print "0 will clear the TARGET setting in target.txt and can't combine with other value."\r
240 sys.exit(1)\r
4231a819 241 if opt.TARGET_ARCH is not None and len(opt.TARGET_ARCH) > 1:\r
30fdf114
LG
242 for elem in opt.TARGET_ARCH:\r
243 if elem == '0':\r
244 print "0 will clear the TARGET_ARCH setting in target.txt and can't combine with other value."\r
245 sys.exit(1)\r
246\r
247 try:\r
248 FileHandle = TargetTool(opt, args)\r
249 if FileHandle.Arg.lower() == 'print':\r
250 FileHandle.Print()\r
251 sys.exit(0)\r
252 elif FileHandle.Arg.lower() == 'clean':\r
253 FileHandle.RWFile('#', '=', 0)\r
254 else:\r
255 FileHandle.RWFile('#', '=', 1)\r
5b0671c1 256 except Exception as e:\r
30fdf114
LG
257 last_type, last_value, last_tb = sys.exc_info()\r
258 traceback.print_exception(last_type, last_value, last_tb)\r
259\r