]>
Commit | Line | Data |
---|---|---|
4234283c LG |
1 | ## @file\r |
2 | # This file is for converting package information data file to xml file.\r | |
3 | #\r | |
64285f15 | 4 | # Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r |
4234283c | 5 | #\r |
2e351cbe | 6 | # SPDX-License-Identifier: BSD-2-Clause-Patent\r |
4234283c LG |
7 | #\r |
8 | \r | |
9 | '''\r | |
10 | IniToXml\r | |
11 | '''\r | |
12 | \r | |
13 | import os.path\r | |
14 | import re\r | |
15 | from time import strftime\r | |
16 | from time import localtime\r | |
17 | \r | |
18 | import Logger.Log as Logger\r | |
19 | from Logger.ToolError import UPT_INI_PARSE_ERROR\r | |
20 | from Logger.ToolError import FILE_NOT_FOUND\r | |
21 | from Library.Xml.XmlRoutines import CreateXmlElement\r | |
22 | from Library.DataType import TAB_VALUE_SPLIT\r | |
23 | from Library.DataType import TAB_EQUAL_SPLIT\r | |
24 | from Library.DataType import TAB_SECTION_START\r | |
25 | from Library.DataType import TAB_SECTION_END\r | |
26 | from Logger import StringTable as ST\r | |
64285f15 | 27 | from Library.StringUtils import ConvertSpecialChar\r |
4234283c | 28 | from Library.ParserValidate import IsValidPath\r |
421ccda3 | 29 | from Library import GlobalData\r |
4234283c LG |
30 | \r |
31 | ## log error:\r | |
32 | #\r | |
33 | # @param error: error\r | |
34 | # @param File: File\r | |
35 | # @param Line: Line\r | |
36 | #\r | |
37 | def IniParseError(Error, File, Line):\r | |
38 | Logger.Error("UPT", UPT_INI_PARSE_ERROR, File=File,\r | |
39 | Line=Line, ExtraData=Error)\r | |
40 | \r | |
41 | ## __ValidatePath\r | |
42 | #\r | |
43 | # @param Path: Path to be checked\r | |
44 | #\r | |
45 | def __ValidatePath(Path, Root):\r | |
46 | Path = Path.strip()\r | |
47 | if os.path.isabs(Path) or not IsValidPath(Path, Root):\r | |
48 | return False, ST.ERR_FILELIST_LOCATION % (Root, Path)\r | |
49 | return True, ''\r | |
50 | \r | |
51 | ## ValidateMiscFile\r | |
52 | #\r | |
53 | # @param Filename: File to be checked\r | |
54 | #\r | |
55 | def ValidateMiscFile(Filename):\r | |
421ccda3 | 56 | Root = GlobalData.gWORKSPACE\r |
4234283c LG |
57 | return __ValidatePath(Filename, Root)\r |
58 | \r | |
59 | ## ValidateToolsFile\r | |
60 | #\r | |
61 | # @param Filename: File to be checked\r | |
62 | #\r | |
63 | def ValidateToolsFile(Filename):\r | |
64 | Valid, Cause = False, ''\r | |
65 | if not Valid and 'EDK_TOOLS_PATH' in os.environ:\r | |
66 | Valid, Cause = __ValidatePath(Filename, os.environ['EDK_TOOLS_PATH'])\r | |
421ccda3 HC |
67 | if not Valid:\r |
68 | Valid, Cause = __ValidatePath(Filename, GlobalData.gWORKSPACE)\r | |
4234283c LG |
69 | return Valid, Cause\r |
70 | \r | |
71 | ## ParseFileList\r | |
72 | #\r | |
73 | # @param Line: Line\r | |
74 | # @param Map: Map\r | |
75 | # @param CurrentKey: CurrentKey\r | |
76 | # @param PathFunc: Path validate function\r | |
77 | #\r | |
78 | def ParseFileList(Line, Map, CurrentKey, PathFunc):\r | |
79 | FileList = ["", {}]\r | |
80 | TokenList = Line.split(TAB_VALUE_SPLIT)\r | |
81 | if len(TokenList) > 0:\r | |
82 | Path = TokenList[0].strip().replace('\\', '/')\r | |
83 | if not Path:\r | |
84 | return False, ST.ERR_WRONG_FILELIST_FORMAT\r | |
85 | Valid, Cause = PathFunc(Path)\r | |
86 | if not Valid:\r | |
87 | return Valid, Cause\r | |
88 | FileList[0] = TokenList[0].strip()\r | |
89 | for Token in TokenList[1:]:\r | |
90 | Attr = Token.split(TAB_EQUAL_SPLIT)\r | |
91 | if len(Attr) != 2 or not Attr[0].strip() or not Attr[1].strip():\r | |
92 | return False, ST.ERR_WRONG_FILELIST_FORMAT\r | |
f7496d71 | 93 | \r |
4234283c LG |
94 | Key = Attr[0].strip()\r |
95 | Val = Attr[1].strip()\r | |
96 | if Key not in ['OS', 'Executable']:\r | |
97 | return False, ST.ERR_UNKNOWN_FILELIST_ATTR % Key\r | |
f7496d71 LG |
98 | \r |
99 | if Key == 'OS' and Val not in ["Win32", "Win64", "Linux32",\r | |
100 | "Linux64", "OS/X32", "OS/X64",\r | |
4234283c LG |
101 | "GenericWin", "GenericNix"]:\r |
102 | return False, ST.ERR_FILELIST_ATTR % 'OS'\r | |
103 | elif Key == 'Executable' and Val not in ['true', 'false']:\r | |
104 | return False, ST.ERR_FILELIST_ATTR % 'Executable'\r | |
105 | FileList[1][Key] = Val\r | |
f7496d71 | 106 | \r |
4234283c LG |
107 | Map[CurrentKey].append(FileList)\r |
108 | return True, ''\r | |
109 | \r | |
110 | ## Create header XML file\r | |
111 | #\r | |
112 | # @param DistMap: DistMap\r | |
113 | # @param Root: Root\r | |
114 | #\r | |
115 | def CreateHeaderXml(DistMap, Root):\r | |
116 | Element1 = CreateXmlElement('Name', DistMap['Name'],\r | |
117 | [], [['BaseName', DistMap['BaseName']]])\r | |
118 | Element2 = CreateXmlElement('GUID', DistMap['GUID'],\r | |
119 | [], [['Version', DistMap['Version']]])\r | |
120 | AttributeList = [['ReadOnly', DistMap['ReadOnly']],\r | |
121 | ['RePackage', DistMap['RePackage']]]\r | |
122 | NodeList = [Element1,\r | |
123 | Element2,\r | |
124 | ['Vendor', DistMap['Vendor']],\r | |
125 | ['Date', DistMap['Date']],\r | |
126 | ['Copyright', DistMap['Copyright']],\r | |
127 | ['License', DistMap['License']],\r | |
128 | ['Abstract', DistMap['Abstract']],\r | |
129 | ['Description', DistMap['Description']],\r | |
130 | ['Signature', DistMap['Signature']],\r | |
131 | ['XmlSpecification', DistMap['XmlSpecification']],\r | |
132 | ]\r | |
133 | Root.appendChild(CreateXmlElement('DistributionHeader', '',\r | |
134 | NodeList, AttributeList))\r | |
135 | \r | |
136 | ## Create tools XML file\r | |
137 | #\r | |
138 | # @param Map: Map\r | |
139 | # @param Root: Root\r | |
f7496d71 | 140 | # @param Tag: Tag\r |
4234283c LG |
141 | #\r |
142 | def CreateToolsXml(Map, Root, Tag):\r | |
143 | #\r | |
144 | # Check if all elements in this section are empty\r | |
145 | #\r | |
146 | for Key in Map:\r | |
147 | if len(Map[Key]) > 0:\r | |
148 | break\r | |
149 | else:\r | |
150 | return\r | |
151 | \r | |
152 | NodeList = [['Name', Map['Name']],\r | |
153 | ['Copyright', Map['Copyright']],\r | |
154 | ['License', Map['License']],\r | |
155 | ['Abstract', Map['Abstract']],\r | |
156 | ['Description', Map['Description']],\r | |
157 | ]\r | |
158 | HeaderNode = CreateXmlElement('Header', '', NodeList, [])\r | |
159 | NodeList = [HeaderNode]\r | |
160 | \r | |
161 | for File in Map['FileList']:\r | |
162 | AttrList = []\r | |
163 | for Key in File[1]:\r | |
164 | AttrList.append([Key, File[1][Key]])\r | |
165 | NodeList.append(CreateXmlElement('Filename', File[0], [], AttrList))\r | |
166 | Root.appendChild(CreateXmlElement(Tag, '', NodeList, []))\r | |
167 | \r | |
168 | ## ValidateValues\r | |
169 | #\r | |
170 | # @param Key: Key\r | |
171 | # @param Value: Value\r | |
172 | # @param SectionName: SectionName\r | |
173 | #\r | |
174 | def ValidateValues(Key, Value, SectionName):\r | |
175 | if SectionName == 'DistributionHeader':\r | |
176 | Valid, Cause = ValidateRegValues(Key, Value)\r | |
177 | if not Valid:\r | |
178 | return Valid, Cause\r | |
179 | Valid = __ValidateDistHeader(Key, Value)\r | |
180 | if not Valid:\r | |
181 | return Valid, ST.ERR_VALUE_INVALID % (Key, SectionName)\r | |
182 | else:\r | |
183 | Valid = __ValidateOtherHeader(Key, Value)\r | |
184 | if not Valid:\r | |
185 | return Valid, ST.ERR_VALUE_INVALID % (Key, SectionName)\r | |
186 | return True, ''\r | |
187 | \r | |
188 | ## ValidateRegValues\r | |
189 | #\r | |
190 | # @param Key: Key\r | |
191 | # @param Value: Value\r | |
192 | #\r | |
193 | def ValidateRegValues(Key, Value):\r | |
194 | ValidateMap = {\r | |
195 | 'ReadOnly' :\r | |
196 | ('true|false', ST.ERR_BOOLEAN_VALUE % (Key, Value)),\r | |
197 | 'RePackage' :\r | |
198 | ('true|false', ST.ERR_BOOLEAN_VALUE % (Key, Value)),\r | |
199 | 'GUID' :\r | |
200 | ('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}'\r | |
201 | '-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}',\r | |
202 | ST.ERR_GUID_VALUE % Value),\r | |
203 | 'Version' : ('[0-9]+(\.[0-9]+)?', ST.ERR_VERSION_VALUE % \\r | |
204 | (Key, Value)),\r | |
205 | 'XmlSpecification' : ('1\.1', ST.ERR_VERSION_XMLSPEC % Value)\r | |
206 | }\r | |
207 | if Key not in ValidateMap:\r | |
208 | return True, ''\r | |
209 | Elem = ValidateMap[Key]\r | |
210 | Match = re.compile(Elem[0]).match(Value)\r | |
211 | if Match and Match.start() == 0 and Match.end() == len(Value):\r | |
212 | return True, ''\r | |
213 | return False, Elem[1]\r | |
214 | \r | |
215 | ## __ValidateDistHeaderName\r | |
216 | #\r | |
217 | # @param Name: Name\r | |
218 | #\r | |
219 | def __ValidateDistHeaderName(Name):\r | |
220 | if len(Name) < 1:\r | |
221 | return False\r | |
f7496d71 | 222 | \r |
4234283c LG |
223 | for Char in Name:\r |
224 | if ord(Char) < 0x20 or ord(Char) >= 0x7f:\r | |
225 | return False\r | |
226 | return True\r | |
227 | \r | |
228 | ## __ValidateDistHeaderBaseName\r | |
229 | #\r | |
230 | # @param BaseName: BaseName\r | |
231 | #\r | |
232 | def __ValidateDistHeaderBaseName(BaseName):\r | |
233 | if not BaseName:\r | |
234 | return False\r | |
235 | # if CheckLen and len(BaseName) < 2:\r | |
236 | # return False\r | |
237 | if not BaseName[0].isalnum() and BaseName[0] != '_':\r | |
238 | return False\r | |
239 | for Char in BaseName[1:]:\r | |
240 | if not Char.isalnum() and Char not in '-_':\r | |
241 | return False\r | |
242 | return True\r | |
243 | \r | |
244 | ## __ValidateDistHeaderAbstract\r | |
245 | #\r | |
246 | # @param Abstract: Abstract\r | |
247 | #\r | |
248 | def __ValidateDistHeaderAbstract(Abstract):\r | |
249 | return '\t' not in Abstract and len(Abstract.splitlines()) == 1\r | |
250 | \r | |
251 | ## __ValidateOtherHeaderAbstract\r | |
252 | #\r | |
253 | # @param Abstract: Abstract\r | |
254 | #\r | |
255 | def __ValidateOtherHeaderAbstract(Abstract):\r | |
256 | return __ValidateDistHeaderAbstract(Abstract)\r | |
257 | \r | |
258 | ## __ValidateDistHeader\r | |
259 | #\r | |
260 | # @param Key: Key\r | |
261 | # @param Value: Value\r | |
262 | #\r | |
263 | def __ValidateDistHeader(Key, Value):\r | |
264 | ValidateMap = {\r | |
265 | 'Name' : __ValidateDistHeaderName,\r | |
266 | 'BaseName' : __ValidateDistHeaderBaseName,\r | |
267 | 'Abstract' : __ValidateDistHeaderAbstract,\r | |
268 | 'Vendor' : __ValidateDistHeaderAbstract\r | |
269 | }\r | |
270 | return not (Value and Key in ValidateMap and not ValidateMap[Key](Value))\r | |
271 | \r | |
272 | ## __ValidateOtherHeader\r | |
273 | #\r | |
274 | # @param Key: Key\r | |
275 | # @param Value: Value\r | |
276 | #\r | |
277 | def __ValidateOtherHeader(Key, Value):\r | |
278 | ValidateMap = {\r | |
279 | 'Name' : __ValidateDistHeaderName,\r | |
280 | 'Abstract' : __ValidateOtherHeaderAbstract\r | |
281 | }\r | |
282 | return not (Value and Key in ValidateMap and not ValidateMap[Key](Value))\r | |
283 | \r | |
284 | ## Convert ini file to xml file\r | |
285 | #\r | |
286 | # @param IniFile\r | |
287 | #\r | |
288 | def IniToXml(IniFile):\r | |
289 | if not os.path.exists(IniFile):\r | |
290 | Logger.Error("UPT", FILE_NOT_FOUND, ST.ERR_TEMPLATE_NOTFOUND % IniFile)\r | |
291 | \r | |
292 | DistMap = {'ReadOnly' : '', 'RePackage' : '', 'Name' : '',\r | |
293 | 'BaseName' : '', 'GUID' : '', 'Version' : '', 'Vendor' : '',\r | |
294 | 'Date' : '', 'Copyright' : '', 'License' : '', 'Abstract' : '',\r | |
295 | 'Description' : '', 'Signature' : '', 'XmlSpecification' : ''\r | |
296 | }\r | |
297 | \r | |
298 | ToolsMap = {'Name' : '', 'Copyright' : '', 'License' : '',\r | |
299 | 'Abstract' : '', 'Description' : '', 'FileList' : []}\r | |
300 | #\r | |
301 | # Only FileList is a list: [['file1', {}], ['file2', {}], ...]\r | |
302 | #\r | |
303 | MiscMap = {'Name' : '', 'Copyright' : '', 'License' : '',\r | |
304 | 'Abstract' : '', 'Description' : '', 'FileList' : []}\r | |
305 | \r | |
306 | SectionMap = {\r | |
307 | 'DistributionHeader' : DistMap,\r | |
308 | 'ToolsHeader' : ToolsMap,\r | |
309 | 'MiscellaneousFilesHeader' : MiscMap\r | |
310 | }\r | |
f7496d71 | 311 | \r |
4234283c LG |
312 | PathValidator = {\r |
313 | 'ToolsHeader' : ValidateToolsFile,\r | |
314 | 'MiscellaneousFilesHeader' : ValidateMiscFile\r | |
315 | }\r | |
f7496d71 | 316 | \r |
4234283c LG |
317 | ParsedSection = []\r |
318 | \r | |
319 | SectionName = ''\r | |
320 | CurrentKey = ''\r | |
321 | PreMap = None\r | |
322 | Map = None\r | |
174a9d3c | 323 | FileContent = ConvertSpecialChar(open(IniFile, 'r').readlines())\r |
4234283c LG |
324 | LastIndex = 0\r |
325 | for Index in range(0, len(FileContent)):\r | |
326 | LastIndex = Index\r | |
327 | Line = FileContent[Index].strip()\r | |
421ccda3 | 328 | if Line == '' or Line.startswith(';'):\r |
4234283c LG |
329 | continue\r |
330 | if Line[0] == TAB_SECTION_START and Line[-1] == TAB_SECTION_END:\r | |
331 | CurrentKey = ''\r | |
332 | SectionName = Line[1:-1].strip()\r | |
333 | if SectionName not in SectionMap:\r | |
334 | IniParseError(ST.ERR_SECTION_NAME_INVALID % SectionName,\r | |
335 | IniFile, Index+1)\r | |
f7496d71 | 336 | \r |
4234283c LG |
337 | if SectionName in ParsedSection:\r |
338 | IniParseError(ST.ERR_SECTION_REDEFINE % SectionName,\r | |
339 | IniFile, Index+1)\r | |
340 | else:\r | |
341 | ParsedSection.append(SectionName)\r | |
f7496d71 | 342 | \r |
4234283c LG |
343 | Map = SectionMap[SectionName]\r |
344 | continue\r | |
345 | if not Map:\r | |
346 | IniParseError(ST.ERR_SECTION_NAME_NONE, IniFile, Index+1)\r | |
347 | TokenList = Line.split(TAB_EQUAL_SPLIT, 1)\r | |
348 | TempKey = TokenList[0].strip()\r | |
349 | #\r | |
350 | # Value spanned multiple or same keyword appears more than one time\r | |
351 | #\r | |
352 | if len(TokenList) < 2 or TempKey not in Map:\r | |
353 | if CurrentKey == '':\r | |
354 | IniParseError(ST.ERR_KEYWORD_INVALID % TempKey,\r | |
355 | IniFile, Index+1)\r | |
356 | elif CurrentKey == 'FileList':\r | |
357 | #\r | |
358 | # Special for FileList\r | |
359 | #\r | |
f7496d71 | 360 | Valid, Cause = ParseFileList(Line, Map, CurrentKey,\r |
4234283c LG |
361 | PathValidator[SectionName])\r |
362 | if not Valid:\r | |
363 | IniParseError(Cause, IniFile, Index+1)\r | |
364 | \r | |
365 | else:\r | |
366 | #\r | |
367 | # Multiple lines for one key such as license\r | |
368 | # Or if string on the left side of '=' is not a keyword\r | |
369 | #\r | |
370 | Map[CurrentKey] = ''.join([Map[CurrentKey], '\n', Line])\r | |
f7496d71 | 371 | Valid, Cause = ValidateValues(CurrentKey,\r |
4234283c LG |
372 | Map[CurrentKey], SectionName)\r |
373 | if not Valid:\r | |
374 | IniParseError(Cause, IniFile, Index+1)\r | |
375 | continue\r | |
376 | \r | |
377 | if (TokenList[1].strip() == ''):\r | |
378 | IniParseError(ST.ERR_EMPTY_VALUE, IniFile, Index+1)\r | |
379 | \r | |
380 | #\r | |
381 | # A keyword found\r | |
382 | #\r | |
383 | CurrentKey = TempKey\r | |
384 | if Map[CurrentKey]:\r | |
385 | IniParseError(ST.ERR_KEYWORD_REDEFINE % CurrentKey,\r | |
386 | IniFile, Index+1)\r | |
f7496d71 | 387 | \r |
4234283c LG |
388 | if id(Map) != id(PreMap) and Map['Copyright']:\r |
389 | PreMap = Map\r | |
390 | Copyright = Map['Copyright'].lower()\r | |
391 | Pos = Copyright.find('copyright')\r | |
392 | if Pos == -1:\r | |
393 | IniParseError(ST.ERR_COPYRIGHT_CONTENT, IniFile, Index)\r | |
394 | if not Copyright[Pos + len('copyright'):].lstrip(' ').startswith('('):\r | |
395 | IniParseError(ST.ERR_COPYRIGHT_CONTENT, IniFile, Index)\r | |
f7496d71 | 396 | \r |
4234283c | 397 | if CurrentKey == 'FileList':\r |
f7496d71 | 398 | Valid, Cause = ParseFileList(TokenList[1], Map, CurrentKey,\r |
4234283c LG |
399 | PathValidator[SectionName])\r |
400 | if not Valid:\r | |
401 | IniParseError(Cause, IniFile, Index+1)\r | |
402 | else:\r | |
403 | Map[CurrentKey] = TokenList[1].strip()\r | |
404 | Valid, Cause = ValidateValues(CurrentKey,\r | |
405 | Map[CurrentKey], SectionName)\r | |
406 | if not Valid:\r | |
407 | IniParseError(Cause, IniFile, Index+1)\r | |
f7496d71 | 408 | \r |
4234283c LG |
409 | if id(Map) != id(PreMap) and Map['Copyright'] and 'copyright' not in Map['Copyright'].lower():\r |
410 | IniParseError(ST.ERR_COPYRIGHT_CONTENT, IniFile, LastIndex)\r | |
411 | \r | |
412 | #\r | |
413 | # Check mandatory keys\r | |
f7496d71 LG |
414 | #\r |
415 | CheckMdtKeys(DistMap, IniFile, LastIndex,\r | |
4234283c LG |
416 | (('ToolsHeader', ToolsMap), ('MiscellaneousFilesHeader', MiscMap))\r |
417 | )\r | |
f7496d71 | 418 | \r |
4234283c LG |
419 | return CreateXml(DistMap, ToolsMap, MiscMap, IniFile)\r |
420 | \r | |
421 | \r | |
422 | ## CheckMdtKeys\r | |
423 | #\r | |
424 | # @param MdtDistKeys: All mandatory keys\r | |
425 | # @param DistMap: Dist content\r | |
426 | # @param IniFile: Ini file\r | |
427 | # @param LastIndex: Last index of Ini file\r | |
428 | # @param Maps: Tools and Misc section name and map. (('section_name', map),*)\r | |
429 | #\r | |
f7496d71 | 430 | def CheckMdtKeys(DistMap, IniFile, LastIndex, Maps):\r |
4234283c LG |
431 | MdtDistKeys = ['Name', 'GUID', 'Version', 'Vendor', 'Copyright', 'License', 'Abstract', 'XmlSpecification']\r |
432 | for Key in MdtDistKeys:\r | |
433 | if Key not in DistMap or DistMap[Key] == '':\r | |
434 | IniParseError(ST.ERR_KEYWORD_MANDATORY % Key, IniFile, LastIndex+1)\r | |
f7496d71 | 435 | \r |
4234283c LG |
436 | if '.' not in DistMap['Version']:\r |
437 | DistMap['Version'] = DistMap['Version'] + '.0'\r | |
f7496d71 | 438 | \r |
4234283c LG |
439 | DistMap['Date'] = str(strftime("%Y-%m-%dT%H:%M:%S", localtime()))\r |
440 | \r | |
441 | #\r | |
442 | # Check Tools Surface Area according to UPT Spec\r | |
443 | # <Tools> {0,}\r | |
444 | # <Header> ... </Header> {0,1}\r | |
445 | # <Filename> ... </Filename> {1,}\r | |
446 | # </Tools>\r | |
447 | # <Header>\r | |
448 | # <Name> xs:normalizedString </Name> {1}\r | |
449 | # <Copyright> xs:string </Copyright> {0,1}\r | |
450 | # <License> xs:string </License> {0,1}\r | |
451 | # <Abstract> xs:normalizedString </Abstract> {0,1}\r | |
452 | # <Description> xs:string </Description> {0,1}\r | |
453 | # </Header>\r | |
454 | #\r | |
455 | for Item in Maps:\r | |
456 | Map = Item[1]\r | |
457 | NonEmptyKey = 0\r | |
458 | for Key in Map:\r | |
459 | if Map[Key]:\r | |
460 | NonEmptyKey += 1\r | |
f7496d71 | 461 | \r |
4234283c LG |
462 | if NonEmptyKey > 0 and not Map['FileList']:\r |
463 | IniParseError(ST.ERR_KEYWORD_MANDATORY % (Item[0] + '.FileList'), IniFile, LastIndex+1)\r | |
f7496d71 | 464 | \r |
4234283c LG |
465 | if NonEmptyKey > 0 and not Map['Name']:\r |
466 | IniParseError(ST.ERR_KEYWORD_MANDATORY % (Item[0] + '.Name'), IniFile, LastIndex+1)\r | |
467 | \r | |
468 | ## CreateXml\r | |
469 | #\r | |
470 | # @param DistMap: Dist Content\r | |
471 | # @param ToolsMap: Tools Content\r | |
472 | # @param MiscMap: Misc Content\r | |
473 | # @param IniFile: Ini File\r | |
474 | #\r | |
f7496d71 | 475 | def CreateXml(DistMap, ToolsMap, MiscMap, IniFile):\r |
4234283c LG |
476 | Attrs = [['xmlns', 'http://www.uefi.org/2011/1.1'],\r |
477 | ['xmlns:xsi', 'http:/www.w3.org/2001/XMLSchema-instance'],\r | |
478 | ]\r | |
479 | Root = CreateXmlElement('DistributionPackage', '', [], Attrs)\r | |
480 | CreateHeaderXml(DistMap, Root)\r | |
481 | CreateToolsXml(ToolsMap, Root, 'Tools')\r | |
482 | CreateToolsXml(MiscMap, Root, 'MiscellaneousFiles')\r | |
483 | \r | |
484 | FileAndExt = IniFile.rsplit('.', 1)\r | |
485 | if len(FileAndExt) > 1:\r | |
486 | FileName = FileAndExt[0] + '.xml'\r | |
487 | else:\r | |
488 | FileName = IniFile + '.xml'\r | |
489 | File = open(FileName, 'w')\r | |
f7496d71 | 490 | \r |
4234283c LG |
491 | try:\r |
492 | File.write(Root.toprettyxml(indent = ' '))\r | |
493 | finally:\r | |
494 | File.close()\r | |
495 | return FileName\r | |
496 | \r |