]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Scripts/ConvertFceToStructurePcd.py
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / BaseTools / Scripts / ConvertFceToStructurePcd.py
CommitLineData
ef529e6a
LG
1#!/usr/bin/python\r
2## @file\r
3# Firmware Configuration Editor (FCE) from https://firmware.intel.com/develop\r
4# can parse BIOS image and generate Firmware Configuration file.\r
5# This script bases on Firmware Configuration file, and generate the structure\r
6# PCD setting in DEC/DSC/INF files.\r
7#\r
8# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>\r
2e351cbe 9# SPDX-License-Identifier: BSD-2-Clause-Patent\r
ef529e6a
LG
10#\r
11\r
12'''\r
13ConvertFceToStructurePcd\r
14'''\r
15\r
16import re\r
17import os\r
18import datetime\r
19import argparse\r
20\r
21#\r
22# Globals for help information\r
23#\r
24__prog__ = 'ConvertFceToStructurePcd'\r
25__version__ = '%s Version %s' % (__prog__, '0.1 ')\r
26__copyright__ = 'Copyright (c) 2018, Intel Corporation. All rights reserved.'\r
27__description__ = 'Generate Structure PCD in DEC/DSC/INF based on Firmware Configuration.\n'\r
28\r
29\r
30dscstatement='''[Defines]\r
31 VPD_TOOL_GUID = 8C3D856A-9BE6-468E-850A-24F7A8D38E08\r
32\r
33[SkuIds]\r
34 0|DEFAULT # The entry: 0|DEFAULT is reserved and always required.\r
35\r
36[DefaultStores]\r
37 0|STANDARD # UEFI Standard default 0|STANDARD is reserved.\r
38 1|MANUFACTURING # UEFI Manufacturing default 1|MANUFACTURING is reserved.\r
39\r
40[PcdsDynamicExVpd.common.DEFAULT]\r
41 gEfiMdeModulePkgTokenSpaceGuid.PcdNvStoreDefaultValueBuffer|*\r
42'''\r
43\r
44decstatement = '''[Guids]\r
45 gStructPcdTokenSpaceGuid = {0x3f1406f4, 0x2b, 0x487a, {0x8b, 0x69, 0x74, 0x29, 0x1b, 0x36, 0x16, 0xf4}}\r
46\r
47[PcdsFixedAtBuild,PcdsPatchableInModule,PcdsDynamic,PcdsDynamicEx]\r
48'''\r
49\r
50infstatement = '''[Pcd]\r
51'''\r
52\r
53SECTION='PcdsDynamicHii'\r
54PCD_NAME='gStructPcdTokenSpaceGuid.Pcd'\r
532f907b 55Max_Pcd_Len = 100\r
ef529e6a
LG
56\r
57WARNING=[]\r
58ERRORMSG=[]\r
59\r
60class parser_lst(object):\r
61\r
62 def __init__(self,filelist):\r
63 self._ignore=['BOOLEAN', 'UINT8', 'UINT16', 'UINT32', 'UINT64']\r
64 self.file=filelist\r
65 self.text=self.megre_lst()[0]\r
66 self.content=self.megre_lst()[1]\r
67\r
68 def megre_lst(self):\r
69 alltext=''\r
70 content={}\r
71 for file in self.file:\r
72 with open(file,'r') as f:\r
73 read =f.read()\r
74 alltext += read\r
75 content[file]=read\r
76 return alltext,content\r
77\r
78 def struct_lst(self):#{struct:lst file}\r
79 structs_file={}\r
80 name_format = re.compile(r'(?<!typedef)\s+struct (\w+) {.*?;', re.S)\r
81 for i in list(self.content.keys()):\r
82 structs= name_format.findall(self.content[i])\r
83 if structs:\r
84 for j in structs:\r
85 if j not in self._ignore:\r
86 structs_file[j]=i\r
87 else:\r
88 print("%s"%structs)\r
89 return structs_file\r
90\r
91 def struct(self):#struct:{offset:name}\r
92 unit_num = re.compile('(\d+)')\r
93 offset1_re = re.compile('(\d+)\[')\r
94 pcdname_num_re = re.compile('\w+\[(\S+)\]')\r
95 pcdname_re = re.compile('\](.*)\<')\r
96 pcdname2_re = re.compile('(\w+)\[')\r
97 uint_re = re.compile('\<(\S+)\>')\r
98 name_format = re.compile(r'(?<!typedef)\s+struct (\w+) {.*?;', re.S)\r
99 name=name_format.findall(self.text)\r
100 info={}\r
101 unparse=[]\r
102 if name:\r
103 tmp_n = [n for n in name if n not in self._ignore]\r
104 name = list(set(tmp_n))\r
105 name.sort(key = tmp_n.index)\r
106 name.reverse()\r
107 #name=list(set(name).difference(set(self._ignore)))\r
108 for struct in name:\r
109 s_re = re.compile(r'struct %s :(.*?)};'% struct, re.S)\r
110 content = s_re.search(self.text)\r
111 if content:\r
112 tmp_dict = {}\r
113 text = content.group().split('+')\r
114 for line in text[1:]:\r
115 offset = offset1_re.findall(line)\r
116 t_name = pcdname_re.findall(line)\r
117 uint = uint_re.findall(line)\r
118 if offset and uint:\r
119 offset = offset[0]\r
120 uint = uint[0]\r
121 if t_name:\r
122 t_name = t_name[0].strip()\r
123 if (' ' in t_name) or ("=" in t_name) or (";" in t_name) or("\\" in name) or (t_name ==''):\r
124 WARNING.append("Warning:Invalid Pcd name '%s' for Offset %s in struct %s" % (t_name,offset, struct))\r
125 else:\r
126 if '[' in t_name:\r
127 if uint in ['UINT8', 'UINT16', 'UINT32', 'UINT64']:\r
128 offset = int(offset, 10)\r
129 tmp_name = pcdname2_re.findall(t_name)[0] + '[0]'\r
130 tmp_dict[offset] = tmp_name\r
131 pcdname_num = int(pcdname_num_re.findall(t_name)[0],10)\r
132 uint = int(unit_num.findall(uint)[0],10)\r
7cc7e054 133 bit = uint // 8\r
ef529e6a
LG
134 for i in range(1, pcdname_num):\r
135 offset += bit\r
136 tmp_name = pcdname2_re.findall(t_name)[0] + '[%s]' % i\r
137 tmp_dict[offset] = tmp_name\r
138 else:\r
139 tmp_name = pcdname2_re.findall(t_name)[0]\r
140 pcdname_num = pcdname_num_re.findall(t_name)[0]\r
141 line = [offset,tmp_name,pcdname_num,uint]\r
142 line.append(struct)\r
143 unparse.append(line)\r
144 else:\r
d79df34b 145 if uint not in ['UINT8', 'UINT16', 'UINT32', 'UINT64', 'BOOLEAN']:\r
ef529e6a
LG
146 line = [offset, t_name, 0, uint]\r
147 line.append(struct)\r
148 unparse.append(line)\r
149 else:\r
150 offset = int(offset,10)\r
151 tmp_dict[offset] = t_name\r
152 info[struct] = tmp_dict\r
153 if len(unparse) != 0:\r
154 for u in unparse:\r
155 if u[3] in list(info.keys()):\r
156 unpar = self.nameISstruct(u,info[u[3]])\r
157 info[u[4]]= dict(list(info[u[4]].items())+list(unpar[u[4]].items()))\r
158 else:\r
159 print("ERROR: No struct name found in %s" % self.file)\r
160 ERRORMSG.append("ERROR: No struct name found in %s" % self.file)\r
161 return info\r
162\r
163\r
164 def nameISstruct(self,line,key_dict):\r
165 dict={}\r
166 dict2={}\r
167 s_re = re.compile(r'struct %s :(.*?)};' % line[3], re.S)\r
168 size_re = re.compile(r'mTotalSize \[(\S+)\]')\r
169 content = s_re.search(self.text)\r
170 if content:\r
171 s_size = size_re.findall(content.group())[0]\r
172 else:\r
173 s_size = '0'\r
174 print("ERROR: Struct %s not define mTotalSize in lst file" %line[3])\r
175 ERRORMSG.append("ERROR: Struct %s not define mTotalSize in lst file" %line[3])\r
176 size = int(line[0], 10)\r
177 if line[2] != 0:\r
178 for j in range(0, int(line[2], 10)):\r
179 for k in list(key_dict.keys()):\r
180 offset = size + k\r
181 name ='%s.%s' %((line[1]+'[%s]'%j),key_dict[k])\r
182 dict[offset] = name\r
183 size = int(s_size,16)+size\r
184 elif line[2] == 0:\r
185 for k in list(key_dict.keys()):\r
186 offset = size + k\r
187 name = '%s.%s' % (line[1], key_dict[k])\r
188 dict[offset] = name\r
189 dict2[line[4]] = dict\r
190 return dict2\r
191\r
192 def efivarstore_parser(self):\r
193 efivarstore_format = re.compile(r'efivarstore.*?;', re.S)\r
194 struct_re = re.compile(r'efivarstore(.*?),',re.S)\r
195 name_re = re.compile(r'name=(\w+)')\r
196 efivarstore_dict={}\r
197 efitxt = efivarstore_format.findall(self.text)\r
198 for i in efitxt:\r
199 struct = struct_re.findall(i.replace(' ',''))\r
d28a6815
YC
200 if struct[0] in self._ignore:\r
201 continue\r
ef529e6a
LG
202 name = name_re.findall(i.replace(' ',''))\r
203 if struct and name:\r
204 efivarstore_dict[name[0]]=struct[0]\r
205 else:\r
206 print("ERROR: Can't find Struct or name in lst file, please check have this format:efivarstore XXXX, name=xxxx")\r
207 ERRORMSG.append("ERROR: Can't find Struct or name in lst file, please check have this format:efivarstore XXXX, name=xxxx")\r
208 return efivarstore_dict\r
209\r
210class Config(object):\r
211\r
212 def __init__(self,Config):\r
213 self.config=Config\r
214\r
215 #Parser .config file,return list[offset,name,guid,value,help]\r
216 def config_parser(self):\r
217 ids_re =re.compile('_ID:(\d+)',re.S)\r
218 id_re= re.compile('\s+')\r
219 info = []\r
220 info_dict={}\r
221 with open(self.config, 'r') as text:\r
222 read = text.read()\r
223 if 'DEFAULT_ID:' in read:\r
224 all_txt = read.split('FCEKEY DEFAULT')\r
225 for i in all_txt[1:]:\r
226 part = [] #save all infomation for DEFAULT_ID\r
227 str_id=''\r
228 ids = ids_re.findall(i.replace(' ',''))\r
229 for m in ids:\r
230 str_id +=m+'_'\r
231 str_id=str_id[:-1]\r
232 part.append(ids)\r
233 section = i.split('\nQ') #split with '\nQ ' to get every block\r
234 part +=self.section_parser(section)\r
235 info_dict[str_id] = self.section_parser(section)\r
236 info.append(part)\r
237 else:\r
238 part = []\r
239 id=('0','0')\r
240 str_id='0_0'\r
241 part.append(id)\r
242 section = read.split('\nQ')\r
243 part +=self.section_parser(section)\r
244 info_dict[str_id] = self.section_parser(section)\r
245 info.append(part)\r
246 return info_dict\r
247\r
248 def eval_id(self,id):\r
249 id = id.split("_")\r
250 default_id=id[0:len(id)//2]\r
251 platform_id=id[len(id)//2:]\r
252 text=''\r
253 for i in range(len(default_id)):\r
254 text +="%s.common.%s.%s,"%(SECTION,self.id_name(platform_id[i],'PLATFORM'),self.id_name(default_id[i],'DEFAULT'))\r
255 return '\n[%s]\n'%text[:-1]\r
256\r
257 def id_name(self,ID, flag):\r
258 platform_dict = {'0': 'DEFAULT'}\r
259 default_dict = {'0': 'STANDARD', '1': 'MANUFACTURING'}\r
260 if flag == "PLATFORM":\r
261 try:\r
262 value = platform_dict[ID]\r
263 except KeyError:\r
264 value = 'SKUID%s' % ID\r
265 elif flag == 'DEFAULT':\r
266 try:\r
267 value = default_dict[ID]\r
268 except KeyError:\r
269 value = 'DEFAULTID%s' % ID\r
270 else:\r
271 value = None\r
272 return value\r
273\r
274 def section_parser(self,section):\r
275 offset_re = re.compile(r'offset=(\w+)')\r
276 name_re = re.compile(r'name=(\S+)')\r
277 guid_re = re.compile(r'guid=(\S+)')\r
278 # help_re = re.compile(r'help = (.*)')\r
279 attribute_re=re.compile(r'attribute=(\w+)')\r
280 value_re = re.compile(r'(//.*)')\r
281 part = []\r
dd6c0a0b 282 part_without_comment = []\r
ef529e6a
LG
283 for x in section[1:]:\r
284 line=x.split('\n')[0]\r
532f907b
CC
285 comment_list = value_re.findall(line) # the string \\... in "Q...." line\r
286 comment_list[0] = comment_list[0].replace('//', '')\r
3de3c247
CC
287 comment_ori = comment_list[0].strip()\r
288 comment = ""\r
289 for each in comment_ori:\r
290 if each != " " and "\x21" > each or each > "\x7E":\r
291 if bytes(each, 'utf-16') == b'\xff\xfe\xae\x00':\r
292 each = '(R)'\r
293 else:\r
294 each = ""\r
295 comment += each\r
ef529e6a
LG
296 line=value_re.sub('',line) #delete \\... in "Q...." line\r
297 list1=line.split(' ')\r
298 value=self.value_parser(list1)\r
299 offset = offset_re.findall(x.replace(' ',''))\r
300 name = name_re.findall(x.replace(' ',''))\r
301 guid = guid_re.findall(x.replace(' ',''))\r
302 attribute =attribute_re.findall(x.replace(' ',''))\r
303 if offset and name and guid and value and attribute:\r
304 if attribute[0] in ['0x3','0x7']:\r
305 offset = int(offset[0], 16)\r
306 #help = help_re.findall(x)\r
dd6c0a0b
CC
307 text_without_comment = offset, name[0], guid[0], value, attribute[0]\r
308 if text_without_comment in part_without_comment:\r
309 # check if exists same Pcd with different comments, add different comments in one line with "|".\r
310 dupl_index = part_without_comment.index(text_without_comment)\r
311 part[dupl_index] = list(part[dupl_index])\r
312 if comment not in part[dupl_index][-1]:\r
313 part[dupl_index][-1] += " | " + comment\r
314 part[dupl_index] = tuple(part[dupl_index])\r
315 else:\r
316 text = offset, name[0], guid[0], value, attribute[0], comment\r
317 part_without_comment.append(text_without_comment)\r
318 part.append(text)\r
ef529e6a
LG
319 return(part)\r
320\r
321 def value_parser(self, list1):\r
322 list1 = [t for t in list1 if t != ''] # remove '' form list\r
323 first_num = int(list1[0], 16)\r
324 if list1[first_num + 1] == 'STRING': # parser STRING\r
ce283fd6
LG
325 if list1[-1] == '""':\r
326 value = "{0x0, 0x0}"\r
327 else:\r
328 value = 'L%s' % list1[-1]\r
ef529e6a
LG
329 elif list1[first_num + 1] == 'ORDERED_LIST': # parser ORDERED_LIST\r
330 value_total = int(list1[first_num + 2])\r
331 list2 = list1[-value_total:]\r
332 tmp = []\r
333 line = ''\r
334 for i in list2:\r
335 if len(i) % 2 == 0 and len(i) != 2:\r
336 for m in range(0, len(i) // 2):\r
337 tmp.append('0x%02x' % (int('0x%s' % i, 16) >> m * 8 & 0xff))\r
338 else:\r
339 tmp.append('0x%s' % i)\r
340 for i in tmp:\r
341 line += '%s,' % i\r
342 value = '{%s}' % line[:-1]\r
343 else:\r
344 value = "0x%01x" % int(list1[-1], 16)\r
345 return value\r
346\r
347\r
348#parser Guid file, get guid name form guid value\r
349class GUID(object):\r
350\r
351 def __init__(self,path):\r
352 self.path = path\r
353 self.guidfile = self.gfile()\r
354 self.guiddict = self.guid_dict()\r
355\r
356 def gfile(self):\r
357 for root, dir, file in os.walk(self.path, topdown=True, followlinks=False):\r
358 if 'FV' in dir:\r
359 gfile = os.path.join(root,'Fv','Guid.xref')\r
360 if os.path.isfile(gfile):\r
361 return gfile\r
362 else:\r
363 print("ERROR: Guid.xref file not found")\r
364 ERRORMSG.append("ERROR: Guid.xref file not found")\r
365 exit()\r
366\r
367 def guid_dict(self):\r
368 guiddict={}\r
369 with open(self.guidfile,'r') as file:\r
370 lines = file.readlines()\r
371 guidinfo=lines\r
372 for line in guidinfo:\r
373 list=line.strip().split(' ')\r
374 if list:\r
375 if len(list)>1:\r
376 guiddict[list[0].upper()]=list[1]\r
377 elif list[0] != ''and len(list)==1:\r
378 print("Error: line %s can't be parser in %s"%(line.strip(),self.guidfile))\r
379 ERRORMSG.append("Error: line %s can't be parser in %s"%(line.strip(),self.guidfile))\r
380 else:\r
381 print("ERROR: No data in %s" %self.guidfile)\r
382 ERRORMSG.append("ERROR: No data in %s" %self.guidfile)\r
383 return guiddict\r
384\r
385 def guid_parser(self,guid):\r
386 if guid.upper() in self.guiddict:\r
387 return self.guiddict[guid.upper()]\r
388 else:\r
389 print("ERROR: GUID %s not found in file %s"%(guid, self.guidfile))\r
390 ERRORMSG.append("ERROR: GUID %s not found in file %s"%(guid, self.guidfile))\r
391 return guid\r
392\r
393class PATH(object):\r
394\r
395 def __init__(self,path):\r
396 self.path=path\r
397 self.rootdir=self.get_root_dir()\r
8501bb0c 398 self.usefuldir=set()\r
ef529e6a
LG
399 self.lstinf = {}\r
400 for path in self.rootdir:\r
401 for o_root, o_dir, o_file in os.walk(os.path.join(path, "OUTPUT"), topdown=True, followlinks=False):\r
402 for INF in o_file:\r
403 if os.path.splitext(INF)[1] == '.inf':\r
404 for l_root, l_dir, l_file in os.walk(os.path.join(path, "DEBUG"), topdown=True,\r
405 followlinks=False):\r
406 for LST in l_file:\r
407 if os.path.splitext(LST)[1] == '.lst':\r
408 self.lstinf[os.path.join(l_root, LST)] = os.path.join(o_root, INF)\r
8501bb0c 409 self.usefuldir.add(path)\r
ef529e6a
LG
410\r
411 def get_root_dir(self):\r
412 rootdir=[]\r
413 for root,dir,file in os.walk(self.path,topdown=True,followlinks=False):\r
414 if "OUTPUT" in root:\r
415 updir=root.split("OUTPUT",1)[0]\r
416 rootdir.append(updir)\r
417 rootdir=list(set(rootdir))\r
418 return rootdir\r
419\r
420 def lst_inf(self):\r
421 return self.lstinf\r
422\r
423 def package(self):\r
424 package={}\r
425 package_re=re.compile(r'Packages\.\w+]\n(.*)',re.S)\r
426 for i in list(self.lstinf.values()):\r
427 with open(i,'r') as inf:\r
428 read=inf.read()\r
429 section=read.split('[')\r
430 for j in section:\r
431 p=package_re.findall(j)\r
432 if p:\r
433 package[i]=p[0].rstrip()\r
434 return package\r
435\r
436 def header(self,struct):\r
437 header={}\r
8501bb0c 438 head_re = re.compile('typedef.*} %s;[\n]+(.*)(?:typedef|formset)'%struct,re.M|re.S)\r
ef529e6a
LG
439 head_re2 = re.compile(r'#line[\s\d]+"(\S+h)"')\r
440 for i in list(self.lstinf.keys()):\r
441 with open(i,'r') as lst:\r
442 read = lst.read()\r
443 h = head_re.findall(read)\r
444 if h:\r
445 head=head_re2.findall(h[0])\r
446 if head:\r
447 format = head[0].replace('\\\\','/').replace('\\','/')\r
448 name =format.split('/')[-1]\r
8501bb0c
CC
449 head = self.headerfileset.get(name)\r
450 if head:\r
451 head = head.replace('\\','/')\r
452 header[struct] = head\r
ef529e6a 453 return header\r
8501bb0c
CC
454 @property\r
455 def headerfileset(self):\r
456 headerset = dict()\r
457 for root,dirs,files in os.walk(self.path):\r
458 for file in files:\r
459 if os.path.basename(file) == 'deps.txt':\r
460 with open(os.path.join(root,file),"r") as fr:\r
461 for line in fr.readlines():\r
462 headerset[os.path.basename(line).strip()] = line.strip()\r
463 return headerset\r
ef529e6a
LG
464\r
465 def makefile(self,filename):\r
466 re_format = re.compile(r'DEBUG_DIR.*(?:\S+Pkg)\\(.*\\%s)'%filename)\r
467 for i in self.usefuldir:\r
468 with open(os.path.join(i,'Makefile'),'r') as make:\r
469 read = make.read()\r
470 dir = re_format.findall(read)\r
471 if dir:\r
472 return dir[0]\r
8501bb0c 473 return None\r
ef529e6a
LG
474\r
475class mainprocess(object):\r
476\r
477 def __init__(self,InputPath,Config,OutputPath):\r
478 self.init = 0xFCD00000\r
479 self.inputpath = os.path.abspath(InputPath)\r
480 self.outputpath = os.path.abspath(OutputPath)\r
481 self.LST = PATH(self.inputpath)\r
482 self.lst_dict = self.LST.lst_inf()\r
483 self.Config = Config\r
484 self.attribute_dict = {'0x3': 'NV, BS', '0x7': 'NV, BS, RT'}\r
485 self.guid = GUID(self.inputpath)\r
486 self.header={}\r
487\r
488 def main(self):\r
489 conf=Config(self.Config)\r
490 config_dict=conf.config_parser() #get {'0_0':[offset,name,guid,value,attribute]...,'1_0':....}\r
491 lst=parser_lst(list(self.lst_dict.keys()))\r
492 efi_dict=lst.efivarstore_parser() #get {name:struct} form lst file\r
493 keys=sorted(config_dict.keys())\r
494 all_struct=lst.struct()\r
495 stru_lst=lst.struct_lst()\r
496 title_list=[]\r
497 info_list=[]\r
498 header_list=[]\r
499 inf_list =[]\r
500 for i in stru_lst:\r
501 tmp = self.LST.header(i)\r
502 self.header.update(tmp)\r
503 for id_key in keys:\r
504 tmp_id=[id_key] #['0_0',[(struct,[name...]),(struct,[name...])]]\r
505 tmp_info={} #{name:struct}\r
506 for section in config_dict[id_key]:\r
532f907b 507 c_offset,c_name,c_guid,c_value,c_attribute,c_comment = section\r
ef529e6a
LG
508 if c_name in efi_dict:\r
509 struct = efi_dict[c_name]\r
510 title='%s%s|L"%s"|%s|0x00||%s\n'%(PCD_NAME,c_name,c_name,self.guid.guid_parser(c_guid),self.attribute_dict[c_attribute])\r
511 if struct in all_struct:\r
512 lstfile = stru_lst[struct]\r
513 struct_dict=all_struct[struct]\r
514 try:\r
515 title2 = '%s%s|{0}|%s|0xFCD00000{\n <HeaderFiles>\n %s\n <Packages>\n%s\n}\n' % (PCD_NAME, c_name, struct, self.header[struct], self.LST.package()[self.lst_dict[lstfile]])\r
516 except KeyError:\r
517 WARNING.append("Warning: No <HeaderFiles> for struct %s"%struct)\r
518 title2 = '%s%s|{0}|%s|0xFCD00000{\n <HeaderFiles>\n %s\n <Packages>\n%s\n}\n' % (PCD_NAME, c_name, struct, '', self.LST.package()[self.lst_dict[lstfile]])\r
519 header_list.append(title2)\r
8501bb0c 520 elif struct not in lst._ignore:\r
ef529e6a
LG
521 struct_dict ={}\r
522 print("ERROR: Struct %s can't found in lst file" %struct)\r
523 ERRORMSG.append("ERROR: Struct %s can't found in lst file" %struct)\r
524 if c_offset in struct_dict:\r
525 offset_name=struct_dict[c_offset]\r
526 info = "%s%s.%s|%s\n"%(PCD_NAME,c_name,offset_name,c_value)\r
532f907b
CC
527 blank_length = Max_Pcd_Len - len(info)\r
528 if blank_length <= 0:\r
529 info_comment = "%s%s.%s|%s%s# %s\n"%(PCD_NAME,c_name,offset_name,c_value," ",c_comment)\r
530 else:\r
531 info_comment = "%s%s.%s|%s%s# %s\n"%(PCD_NAME,c_name,offset_name,c_value,blank_length*" ",c_comment)\r
ef529e6a
LG
532 inf = "%s%s\n"%(PCD_NAME,c_name)\r
533 inf_list.append(inf)\r
532f907b 534 tmp_info[info_comment]=title\r
ef529e6a
LG
535 else:\r
536 print("ERROR: Can't find offset %s with struct name %s"%(c_offset,struct))\r
537 ERRORMSG.append("ERROR: Can't find offset %s with name %s"%(c_offset,struct))\r
538 else:\r
539 print("ERROR: Can't find name %s in lst file"%(c_name))\r
540 ERRORMSG.append("ERROR: Can't find name %s in lst file"%(c_name))\r
541 tmp_id.append(list(self.reverse_dict(tmp_info).items()))\r
542 id,tmp_title_list,tmp_info_list = self.read_list(tmp_id)\r
543 title_list +=tmp_title_list\r
544 info_list.append(tmp_info_list)\r
545 inf_list = self.del_repeat(inf_list)\r
546 header_list = self.plus(self.del_repeat(header_list))\r
547 title_all=list(set(title_list))\r
ce283fd6 548 info_list = self.remove_bracket(self.del_repeat(info_list))\r
ef529e6a
LG
549 for i in range(len(info_list)-1,-1,-1):\r
550 if len(info_list[i]) == 0:\r
551 info_list.remove(info_list[i])\r
d79b63c6
LL
552 for i in (inf_list, title_all, header_list):\r
553 i.sort()\r
ef529e6a
LG
554 return keys,title_all,info_list,header_list,inf_list\r
555\r
dd6c0a0b
CC
556 def correct_sort(self, PcdString):\r
557 # sort the Pcd list with two rules:\r
558 # First sort through Pcd name;\r
559 # Second if the Pcd exists several elements, sort them through index value.\r
560 if ("]|") in PcdString:\r
561 Pcdname = PcdString.split("[")[0]\r
562 Pcdindex = int(PcdString.split("[")[1].split("]")[0])\r
563 else:\r
564 Pcdname = PcdString.split("|")[0]\r
565 Pcdindex = 0\r
566 return Pcdname, Pcdindex\r
567\r
ce283fd6
LG
568 def remove_bracket(self,List):\r
569 for i in List:\r
570 for j in i:\r
571 tmp = j.split("|")\r
d79df34b 572 if (('L"' in j) and ("[" in j)) or (tmp[1].split("#")[0].strip() == '{0x0, 0x0}'):\r
ce283fd6
LG
573 tmp[0] = tmp[0][:tmp[0].index('[')]\r
574 List[List.index(i)][i.index(j)] = "|".join(tmp)\r
575 else:\r
576 List[List.index(i)][i.index(j)] = j\r
d79b63c6
LL
577 for i in List:\r
578 if type(i) == type([0,0]):\r
dd6c0a0b 579 i.sort(key = lambda x:(self.correct_sort(x)[0], self.correct_sort(x)[1]))\r
ce283fd6 580 return List\r
ef529e6a
LG
581\r
582 def write_all(self):\r
583 title_flag=1\r
584 info_flag=1\r
585 if not os.path.isdir(self.outputpath):\r
586 os.makedirs(self.outputpath)\r
587 decwrite = write2file(os.path.join(self.outputpath,'StructurePcd.dec'))\r
588 dscwrite = write2file(os.path.join(self.outputpath,'StructurePcd.dsc'))\r
589 infwrite = write2file(os.path.join(self.outputpath, 'StructurePcd.inf'))\r
590 conf = Config(self.Config)\r
591 ids,title,info,header,inf=self.main()\r
592 decwrite.add2file(decstatement)\r
593 decwrite.add2file(header)\r
594 infwrite.add2file(infstatement)\r
595 infwrite.add2file(inf)\r
596 dscwrite.add2file(dscstatement)\r
597 for id in ids:\r
598 dscwrite.add2file(conf.eval_id(id))\r
599 if title_flag:\r
600 dscwrite.add2file(title)\r
601 title_flag=0\r
602 if len(info) == 1:\r
603 dscwrite.add2file(info)\r
604 elif len(info) == 2:\r
605 if info_flag:\r
606 dscwrite.add2file(info[0])\r
607 info_flag =0\r
608 else:\r
609 dscwrite.add2file(info[1])\r
610\r
611 def del_repeat(self,List):\r
612 if len(List) == 1 or len(List) == 0:\r
613 return List\r
614 else:\r
615 if type(List[0]) != type('xxx'):\r
616 alist=[]\r
617 for i in range(len(List)):\r
618 if i == 0:\r
619 alist.append(List[0])\r
620 else:\r
621 plist = []\r
622 for j in range(i):\r
623 plist += List[j]\r
624 alist.append(self.__del(list(set(plist)), List[i]))\r
625 return alist\r
626 else:\r
627 return list(set(List))\r
628\r
629\r
630 def __del(self,list1,list2):\r
631 return list(set(list2).difference(set(list1)))\r
632\r
633 def reverse_dict(self,dict):\r
634 data={}\r
635 for i in list(dict.items()):\r
636 if i[1] not in list(data.keys()):\r
637 data[i[1]]=[i[0]]\r
638 else:\r
639 data[i[1]].append(i[0])\r
640 return data\r
641\r
642 def read_list(self,list):\r
643 title_list=[]\r
644 info_list=[]\r
645 for i in list[1]:\r
646 title_list.append(i[0])\r
647 for j in i[1]:\r
648 info_list.append(j)\r
649 return list[0],title_list,info_list\r
650\r
651 def plus(self,list):\r
652 nums=[]\r
653 for i in list:\r
654 if type(i) != type([0]):\r
655 self.init += 1\r
656 num = "0x%01x" % self.init\r
657 j=i.replace('0xFCD00000',num.upper())\r
658 nums.append(j)\r
659 return nums\r
660\r
661class write2file(object):\r
662\r
663 def __init__(self,Output):\r
664 self.output=Output\r
665 self.text=''\r
666 if os.path.exists(self.output):\r
667 os.remove(self.output)\r
668\r
669 def add2file(self,content):\r
670 self.text = ''\r
671 with open(self.output,'a+') as file:\r
672 file.write(self.__gen(content))\r
673\r
674 def __gen(self,content):\r
675 if type(content) == type(''):\r
676 return content\r
677 elif type(content) == type([0,0])or type(content) == type((0,0)):\r
678 return self.__readlist(content)\r
679 elif type(content) == type({0:0}):\r
680 return self.__readdict(content)\r
681\r
682 def __readlist(self,list):\r
683 for i in list:\r
684 if type(i) == type([0,0])or type(i) == type((0,0)):\r
685 self.__readlist(i)\r
686 elif type(i) == type('') :\r
687 self.text +=i\r
688 return self.text\r
689\r
690 def __readdict(self,dict):\r
691 content=list(dict.items())\r
692 return self.__readlist(content)\r
693\r
694def stamp():\r
695 return datetime.datetime.now()\r
696\r
697def dtime(start,end,id=None):\r
698 if id:\r
699 pass\r
700 print("%s time:%s" % (id,str(end - start)))\r
701 else:\r
702 print("Total time:%s" %str(end-start)[:-7])\r
703\r
704\r
705def main():\r
706 start = stamp()\r
707 parser = argparse.ArgumentParser(prog = __prog__,\r
708 description = __description__ + __copyright__,\r
709 conflict_handler = 'resolve')\r
710 parser.add_argument('-v', '--version', action = 'version',version = __version__, help="show program's version number and exit")\r
711 parser.add_argument('-p', '--path', metavar='PATH', dest='path', help="platform build output directory")\r
712 parser.add_argument('-c', '--config',metavar='FILENAME', dest='config', help="firmware configuration file")\r
713 parser.add_argument('-o', '--outputdir', metavar='PATH', dest='output', help="output directoy")\r
714 options = parser.parse_args()\r
715 if options.config:\r
716 if options.path:\r
717 if options.output:\r
718 run = mainprocess(options.path, options.config, options.output)\r
719 print("Running...")\r
720 run.write_all()\r
721 if WARNING:\r
722 warning = list(set(WARNING))\r
723 for j in warning:\r
724 print(j)\r
725 if ERRORMSG:\r
726 ERROR = list(set(ERRORMSG))\r
727 with open("ERROR.log", 'w+') as error:\r
728 for i in ERROR:\r
729 error.write(i + '\n')\r
730 print("Some error find, error log in ERROR.log")\r
731 print('Finished, Output files in directory %s'%os.path.abspath(options.output))\r
732 else:\r
733 print('Error command, no output path, use -h for help')\r
734 else:\r
735 print('Error command, no build path input, use -h for help')\r
736 else:\r
737 print('Error command, no output file, use -h for help')\r
738 end = stamp()\r
739 dtime(start, end)\r
740\r
741if __name__ == '__main__':\r
742 main()\r