summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/ConvertFceToStructurePcd.py
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
commitf215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch)
tree6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/ConvertFceToStructurePcd.py
parentInitial commit. (diff)
downloadvirtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz
virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/ConvertFceToStructurePcd.py')
-rwxr-xr-xsrc/VBox/Devices/EFI/Firmware/BaseTools/Scripts/ConvertFceToStructurePcd.py734
1 files changed, 734 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/ConvertFceToStructurePcd.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/ConvertFceToStructurePcd.py
new file mode 100755
index 00000000..995fcfce
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Scripts/ConvertFceToStructurePcd.py
@@ -0,0 +1,734 @@
+#!/usr/bin/python
+## @file
+# Firmware Configuration Editor (FCE) from https://firmware.intel.com/develop
+# can parse BIOS image and generate Firmware Configuration file.
+# This script bases on Firmware Configuration file, and generate the structure
+# PCD setting in DEC/DSC/INF files.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+'''
+ConvertFceToStructurePcd
+'''
+
+import re
+import os
+import datetime
+import argparse
+
+#
+# Globals for help information
+#
+__prog__ = 'ConvertFceToStructurePcd'
+__version__ = '%s Version %s' % (__prog__, '0.1 ')
+__copyright__ = 'Copyright (c) 2018, Intel Corporation. All rights reserved.'
+__description__ = 'Generate Structure PCD in DEC/DSC/INF based on Firmware Configuration.\n'
+
+
+dscstatement='''[Defines]
+ VPD_TOOL_GUID = 8C3D856A-9BE6-468E-850A-24F7A8D38E08
+
+[SkuIds]
+ 0|DEFAULT # The entry: 0|DEFAULT is reserved and always required.
+
+[DefaultStores]
+ 0|STANDARD # UEFI Standard default 0|STANDARD is reserved.
+ 1|MANUFACTURING # UEFI Manufacturing default 1|MANUFACTURING is reserved.
+
+[PcdsDynamicExVpd.common.DEFAULT]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdNvStoreDefaultValueBuffer|*
+'''
+
+decstatement = '''[Guids]
+ gStructPcdTokenSpaceGuid = {0x3f1406f4, 0x2b, 0x487a, {0x8b, 0x69, 0x74, 0x29, 0x1b, 0x36, 0x16, 0xf4}}
+
+[PcdsFixedAtBuild,PcdsPatchableInModule,PcdsDynamic,PcdsDynamicEx]
+'''
+
+infstatement = '''[Pcd]
+'''
+
+SECTION='PcdsDynamicHii'
+PCD_NAME='gStructPcdTokenSpaceGuid.Pcd'
+Max_Pcd_Len = 100
+
+WARNING=[]
+ERRORMSG=[]
+
+class parser_lst(object):
+
+ def __init__(self,filelist):
+ self._ignore=['BOOLEAN', 'UINT8', 'UINT16', 'UINT32', 'UINT64']
+ self.file=filelist
+ self.text=self.megre_lst()[0]
+ self.content=self.megre_lst()[1]
+
+ def megre_lst(self):
+ alltext=''
+ content={}
+ for file in self.file:
+ with open(file,'r') as f:
+ read =f.read()
+ alltext += read
+ content[file]=read
+ return alltext,content
+
+ def struct_lst(self):#{struct:lst file}
+ structs_file={}
+ name_format = re.compile(r'(?<!typedef)\s+struct (\w+) {.*?;', re.S)
+ for i in list(self.content.keys()):
+ structs= name_format.findall(self.content[i])
+ if structs:
+ for j in structs:
+ if j not in self._ignore:
+ structs_file[j]=i
+ else:
+ print("%s"%structs)
+ return structs_file
+
+ def struct(self):#struct:{offset:name}
+ unit_num = re.compile('(\d+)')
+ offset1_re = re.compile('(\d+)\[')
+ pcdname_num_re = re.compile('\w+\[(\S+)\]')
+ pcdname_re = re.compile('\](.*)\<')
+ pcdname2_re = re.compile('(\w+)\[')
+ uint_re = re.compile('\<(\S+)\>')
+ name_format = re.compile(r'(?<!typedef)\s+struct (\w+) {.*?;', re.S)
+ name=name_format.findall(self.text)
+ info={}
+ unparse=[]
+ if name:
+ tmp_n = [n for n in name if n not in self._ignore]
+ name = list(set(tmp_n))
+ name.sort(key = tmp_n.index)
+ name.reverse()
+ #name=list(set(name).difference(set(self._ignore)))
+ for struct in name:
+ s_re = re.compile(r'struct %s :(.*?)};'% struct, re.S)
+ content = s_re.search(self.text)
+ if content:
+ tmp_dict = {}
+ text = content.group().split('+')
+ for line in text[1:]:
+ offset = offset1_re.findall(line)
+ t_name = pcdname_re.findall(line)
+ uint = uint_re.findall(line)
+ if offset and uint:
+ offset = offset[0]
+ uint = uint[0]
+ if t_name:
+ t_name = t_name[0].strip()
+ if (' ' in t_name) or ("=" in t_name) or (";" in t_name) or("\\" in name) or (t_name ==''):
+ WARNING.append("Warning:Invalid Pcd name '%s' for Offset %s in struct %s" % (t_name,offset, struct))
+ else:
+ if '[' in t_name:
+ if uint in ['UINT8', 'UINT16', 'UINT32', 'UINT64']:
+ offset = int(offset, 10)
+ tmp_name = pcdname2_re.findall(t_name)[0] + '[0]'
+ tmp_dict[offset] = tmp_name
+ pcdname_num = int(pcdname_num_re.findall(t_name)[0],10)
+ uint = int(unit_num.findall(uint)[0],10)
+ bit = uint // 8
+ for i in range(1, pcdname_num):
+ offset += bit
+ tmp_name = pcdname2_re.findall(t_name)[0] + '[%s]' % i
+ tmp_dict[offset] = tmp_name
+ else:
+ tmp_name = pcdname2_re.findall(t_name)[0]
+ pcdname_num = pcdname_num_re.findall(t_name)[0]
+ line = [offset,tmp_name,pcdname_num,uint]
+ line.append(struct)
+ unparse.append(line)
+ else:
+ if uint not in ['UINT8', 'UINT16', 'UINT32', 'UINT64']:
+ line = [offset, t_name, 0, uint]
+ line.append(struct)
+ unparse.append(line)
+ else:
+ offset = int(offset,10)
+ tmp_dict[offset] = t_name
+ info[struct] = tmp_dict
+ if len(unparse) != 0:
+ for u in unparse:
+ if u[3] in list(info.keys()):
+ unpar = self.nameISstruct(u,info[u[3]])
+ info[u[4]]= dict(list(info[u[4]].items())+list(unpar[u[4]].items()))
+ else:
+ print("ERROR: No struct name found in %s" % self.file)
+ ERRORMSG.append("ERROR: No struct name found in %s" % self.file)
+ return info
+
+
+ def nameISstruct(self,line,key_dict):
+ dict={}
+ dict2={}
+ s_re = re.compile(r'struct %s :(.*?)};' % line[3], re.S)
+ size_re = re.compile(r'mTotalSize \[(\S+)\]')
+ content = s_re.search(self.text)
+ if content:
+ s_size = size_re.findall(content.group())[0]
+ else:
+ s_size = '0'
+ print("ERROR: Struct %s not define mTotalSize in lst file" %line[3])
+ ERRORMSG.append("ERROR: Struct %s not define mTotalSize in lst file" %line[3])
+ size = int(line[0], 10)
+ if line[2] != 0:
+ for j in range(0, int(line[2], 10)):
+ for k in list(key_dict.keys()):
+ offset = size + k
+ name ='%s.%s' %((line[1]+'[%s]'%j),key_dict[k])
+ dict[offset] = name
+ size = int(s_size,16)+size
+ elif line[2] == 0:
+ for k in list(key_dict.keys()):
+ offset = size + k
+ name = '%s.%s' % (line[1], key_dict[k])
+ dict[offset] = name
+ dict2[line[4]] = dict
+ return dict2
+
+ def efivarstore_parser(self):
+ efivarstore_format = re.compile(r'efivarstore.*?;', re.S)
+ struct_re = re.compile(r'efivarstore(.*?),',re.S)
+ name_re = re.compile(r'name=(\w+)')
+ efivarstore_dict={}
+ efitxt = efivarstore_format.findall(self.text)
+ for i in efitxt:
+ struct = struct_re.findall(i.replace(' ',''))
+ if struct[0] in self._ignore:
+ continue
+ name = name_re.findall(i.replace(' ',''))
+ if struct and name:
+ efivarstore_dict[name[0]]=struct[0]
+ else:
+ print("ERROR: Can't find Struct or name in lst file, please check have this format:efivarstore XXXX, name=xxxx")
+ ERRORMSG.append("ERROR: Can't find Struct or name in lst file, please check have this format:efivarstore XXXX, name=xxxx")
+ return efivarstore_dict
+
+class Config(object):
+
+ def __init__(self,Config):
+ self.config=Config
+
+ #Parser .config file,return list[offset,name,guid,value,help]
+ def config_parser(self):
+ ids_re =re.compile('_ID:(\d+)',re.S)
+ id_re= re.compile('\s+')
+ info = []
+ info_dict={}
+ with open(self.config, 'r') as text:
+ read = text.read()
+ if 'DEFAULT_ID:' in read:
+ all_txt = read.split('FCEKEY DEFAULT')
+ for i in all_txt[1:]:
+ part = [] #save all infomation for DEFAULT_ID
+ str_id=''
+ ids = ids_re.findall(i.replace(' ',''))
+ for m in ids:
+ str_id +=m+'_'
+ str_id=str_id[:-1]
+ part.append(ids)
+ section = i.split('\nQ') #split with '\nQ ' to get every block
+ part +=self.section_parser(section)
+ info_dict[str_id] = self.section_parser(section)
+ info.append(part)
+ else:
+ part = []
+ id=('0','0')
+ str_id='0_0'
+ part.append(id)
+ section = read.split('\nQ')
+ part +=self.section_parser(section)
+ info_dict[str_id] = self.section_parser(section)
+ info.append(part)
+ return info_dict
+
+ def eval_id(self,id):
+ id = id.split("_")
+ default_id=id[0:len(id)//2]
+ platform_id=id[len(id)//2:]
+ text=''
+ for i in range(len(default_id)):
+ text +="%s.common.%s.%s,"%(SECTION,self.id_name(platform_id[i],'PLATFORM'),self.id_name(default_id[i],'DEFAULT'))
+ return '\n[%s]\n'%text[:-1]
+
+ def id_name(self,ID, flag):
+ platform_dict = {'0': 'DEFAULT'}
+ default_dict = {'0': 'STANDARD', '1': 'MANUFACTURING'}
+ if flag == "PLATFORM":
+ try:
+ value = platform_dict[ID]
+ except KeyError:
+ value = 'SKUID%s' % ID
+ elif flag == 'DEFAULT':
+ try:
+ value = default_dict[ID]
+ except KeyError:
+ value = 'DEFAULTID%s' % ID
+ else:
+ value = None
+ return value
+
+ def section_parser(self,section):
+ offset_re = re.compile(r'offset=(\w+)')
+ name_re = re.compile(r'name=(\S+)')
+ guid_re = re.compile(r'guid=(\S+)')
+ # help_re = re.compile(r'help = (.*)')
+ attribute_re=re.compile(r'attribute=(\w+)')
+ value_re = re.compile(r'(//.*)')
+ part = []
+ part_without_comment = []
+ for x in section[1:]:
+ line=x.split('\n')[0]
+ comment_list = value_re.findall(line) # the string \\... in "Q...." line
+ comment_list[0] = comment_list[0].replace('//', '')
+ comment = comment_list[0].strip()
+ line=value_re.sub('',line) #delete \\... in "Q...." line
+ list1=line.split(' ')
+ value=self.value_parser(list1)
+ offset = offset_re.findall(x.replace(' ',''))
+ name = name_re.findall(x.replace(' ',''))
+ guid = guid_re.findall(x.replace(' ',''))
+ attribute =attribute_re.findall(x.replace(' ',''))
+ if offset and name and guid and value and attribute:
+ if attribute[0] in ['0x3','0x7']:
+ offset = int(offset[0], 16)
+ #help = help_re.findall(x)
+ text_without_comment = offset, name[0], guid[0], value, attribute[0]
+ if text_without_comment in part_without_comment:
+ # check if exists same Pcd with different comments, add different comments in one line with "|".
+ dupl_index = part_without_comment.index(text_without_comment)
+ part[dupl_index] = list(part[dupl_index])
+ if comment not in part[dupl_index][-1]:
+ part[dupl_index][-1] += " | " + comment
+ part[dupl_index] = tuple(part[dupl_index])
+ else:
+ text = offset, name[0], guid[0], value, attribute[0], comment
+ part_without_comment.append(text_without_comment)
+ part.append(text)
+ return(part)
+
+ def value_parser(self, list1):
+ list1 = [t for t in list1 if t != ''] # remove '' form list
+ first_num = int(list1[0], 16)
+ if list1[first_num + 1] == 'STRING': # parser STRING
+ if list1[-1] == '""':
+ value = "{0x0, 0x0}"
+ else:
+ value = 'L%s' % list1[-1]
+ elif list1[first_num + 1] == 'ORDERED_LIST': # parser ORDERED_LIST
+ value_total = int(list1[first_num + 2])
+ list2 = list1[-value_total:]
+ tmp = []
+ line = ''
+ for i in list2:
+ if len(i) % 2 == 0 and len(i) != 2:
+ for m in range(0, len(i) // 2):
+ tmp.append('0x%02x' % (int('0x%s' % i, 16) >> m * 8 & 0xff))
+ else:
+ tmp.append('0x%s' % i)
+ for i in tmp:
+ line += '%s,' % i
+ value = '{%s}' % line[:-1]
+ else:
+ value = "0x%01x" % int(list1[-1], 16)
+ return value
+
+
+#parser Guid file, get guid name form guid value
+class GUID(object):
+
+ def __init__(self,path):
+ self.path = path
+ self.guidfile = self.gfile()
+ self.guiddict = self.guid_dict()
+
+ def gfile(self):
+ for root, dir, file in os.walk(self.path, topdown=True, followlinks=False):
+ if 'FV' in dir:
+ gfile = os.path.join(root,'Fv','Guid.xref')
+ if os.path.isfile(gfile):
+ return gfile
+ else:
+ print("ERROR: Guid.xref file not found")
+ ERRORMSG.append("ERROR: Guid.xref file not found")
+ exit()
+
+ def guid_dict(self):
+ guiddict={}
+ with open(self.guidfile,'r') as file:
+ lines = file.readlines()
+ guidinfo=lines
+ for line in guidinfo:
+ list=line.strip().split(' ')
+ if list:
+ if len(list)>1:
+ guiddict[list[0].upper()]=list[1]
+ elif list[0] != ''and len(list)==1:
+ print("Error: line %s can't be parser in %s"%(line.strip(),self.guidfile))
+ ERRORMSG.append("Error: line %s can't be parser in %s"%(line.strip(),self.guidfile))
+ else:
+ print("ERROR: No data in %s" %self.guidfile)
+ ERRORMSG.append("ERROR: No data in %s" %self.guidfile)
+ return guiddict
+
+ def guid_parser(self,guid):
+ if guid.upper() in self.guiddict:
+ return self.guiddict[guid.upper()]
+ else:
+ print("ERROR: GUID %s not found in file %s"%(guid, self.guidfile))
+ ERRORMSG.append("ERROR: GUID %s not found in file %s"%(guid, self.guidfile))
+ return guid
+
+class PATH(object):
+
+ def __init__(self,path):
+ self.path=path
+ self.rootdir=self.get_root_dir()
+ self.usefuldir=set()
+ self.lstinf = {}
+ for path in self.rootdir:
+ for o_root, o_dir, o_file in os.walk(os.path.join(path, "OUTPUT"), topdown=True, followlinks=False):
+ for INF in o_file:
+ if os.path.splitext(INF)[1] == '.inf':
+ for l_root, l_dir, l_file in os.walk(os.path.join(path, "DEBUG"), topdown=True,
+ followlinks=False):
+ for LST in l_file:
+ if os.path.splitext(LST)[1] == '.lst':
+ self.lstinf[os.path.join(l_root, LST)] = os.path.join(o_root, INF)
+ self.usefuldir.add(path)
+
+ def get_root_dir(self):
+ rootdir=[]
+ for root,dir,file in os.walk(self.path,topdown=True,followlinks=False):
+ if "OUTPUT" in root:
+ updir=root.split("OUTPUT",1)[0]
+ rootdir.append(updir)
+ rootdir=list(set(rootdir))
+ return rootdir
+
+ def lst_inf(self):
+ return self.lstinf
+
+ def package(self):
+ package={}
+ package_re=re.compile(r'Packages\.\w+]\n(.*)',re.S)
+ for i in list(self.lstinf.values()):
+ with open(i,'r') as inf:
+ read=inf.read()
+ section=read.split('[')
+ for j in section:
+ p=package_re.findall(j)
+ if p:
+ package[i]=p[0].rstrip()
+ return package
+
+ def header(self,struct):
+ header={}
+ head_re = re.compile('typedef.*} %s;[\n]+(.*)(?:typedef|formset)'%struct,re.M|re.S)
+ head_re2 = re.compile(r'#line[\s\d]+"(\S+h)"')
+ for i in list(self.lstinf.keys()):
+ with open(i,'r') as lst:
+ read = lst.read()
+ h = head_re.findall(read)
+ if h:
+ head=head_re2.findall(h[0])
+ if head:
+ format = head[0].replace('\\\\','/').replace('\\','/')
+ name =format.split('/')[-1]
+ head = self.headerfileset.get(name)
+ if head:
+ head = head.replace('\\','/')
+ header[struct] = head
+ return header
+ @property
+ def headerfileset(self):
+ headerset = dict()
+ for root,dirs,files in os.walk(self.path):
+ for file in files:
+ if os.path.basename(file) == 'deps.txt':
+ with open(os.path.join(root,file),"r") as fr:
+ for line in fr.readlines():
+ headerset[os.path.basename(line).strip()] = line.strip()
+ return headerset
+
+ def makefile(self,filename):
+ re_format = re.compile(r'DEBUG_DIR.*(?:\S+Pkg)\\(.*\\%s)'%filename)
+ for i in self.usefuldir:
+ with open(os.path.join(i,'Makefile'),'r') as make:
+ read = make.read()
+ dir = re_format.findall(read)
+ if dir:
+ return dir[0]
+ return None
+
+class mainprocess(object):
+
+ def __init__(self,InputPath,Config,OutputPath):
+ self.init = 0xFCD00000
+ self.inputpath = os.path.abspath(InputPath)
+ self.outputpath = os.path.abspath(OutputPath)
+ self.LST = PATH(self.inputpath)
+ self.lst_dict = self.LST.lst_inf()
+ self.Config = Config
+ self.attribute_dict = {'0x3': 'NV, BS', '0x7': 'NV, BS, RT'}
+ self.guid = GUID(self.inputpath)
+ self.header={}
+
+ def main(self):
+ conf=Config(self.Config)
+ config_dict=conf.config_parser() #get {'0_0':[offset,name,guid,value,attribute]...,'1_0':....}
+ lst=parser_lst(list(self.lst_dict.keys()))
+ efi_dict=lst.efivarstore_parser() #get {name:struct} form lst file
+ keys=sorted(config_dict.keys())
+ all_struct=lst.struct()
+ stru_lst=lst.struct_lst()
+ title_list=[]
+ info_list=[]
+ header_list=[]
+ inf_list =[]
+ for i in stru_lst:
+ tmp = self.LST.header(i)
+ self.header.update(tmp)
+ for id_key in keys:
+ tmp_id=[id_key] #['0_0',[(struct,[name...]),(struct,[name...])]]
+ tmp_info={} #{name:struct}
+ for section in config_dict[id_key]:
+ c_offset,c_name,c_guid,c_value,c_attribute,c_comment = section
+ if c_name in efi_dict:
+ struct = efi_dict[c_name]
+ 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])
+ if struct in all_struct:
+ lstfile = stru_lst[struct]
+ struct_dict=all_struct[struct]
+ try:
+ 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]])
+ except KeyError:
+ WARNING.append("Warning: No <HeaderFiles> for struct %s"%struct)
+ 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]])
+ header_list.append(title2)
+ elif struct not in lst._ignore:
+ struct_dict ={}
+ print("ERROR: Struct %s can't found in lst file" %struct)
+ ERRORMSG.append("ERROR: Struct %s can't found in lst file" %struct)
+ if c_offset in struct_dict:
+ offset_name=struct_dict[c_offset]
+ info = "%s%s.%s|%s\n"%(PCD_NAME,c_name,offset_name,c_value)
+ blank_length = Max_Pcd_Len - len(info)
+ if blank_length <= 0:
+ info_comment = "%s%s.%s|%s%s# %s\n"%(PCD_NAME,c_name,offset_name,c_value," ",c_comment)
+ else:
+ info_comment = "%s%s.%s|%s%s# %s\n"%(PCD_NAME,c_name,offset_name,c_value,blank_length*" ",c_comment)
+ inf = "%s%s\n"%(PCD_NAME,c_name)
+ inf_list.append(inf)
+ tmp_info[info_comment]=title
+ else:
+ print("ERROR: Can't find offset %s with struct name %s"%(c_offset,struct))
+ ERRORMSG.append("ERROR: Can't find offset %s with name %s"%(c_offset,struct))
+ else:
+ print("ERROR: Can't find name %s in lst file"%(c_name))
+ ERRORMSG.append("ERROR: Can't find name %s in lst file"%(c_name))
+ tmp_id.append(list(self.reverse_dict(tmp_info).items()))
+ id,tmp_title_list,tmp_info_list = self.read_list(tmp_id)
+ title_list +=tmp_title_list
+ info_list.append(tmp_info_list)
+ inf_list = self.del_repeat(inf_list)
+ header_list = self.plus(self.del_repeat(header_list))
+ title_all=list(set(title_list))
+ info_list = self.remove_bracket(self.del_repeat(info_list))
+ for i in range(len(info_list)-1,-1,-1):
+ if len(info_list[i]) == 0:
+ info_list.remove(info_list[i])
+ for i in (inf_list, title_all, header_list):
+ i.sort()
+ return keys,title_all,info_list,header_list,inf_list
+
+ def correct_sort(self, PcdString):
+ # sort the Pcd list with two rules:
+ # First sort through Pcd name;
+ # Second if the Pcd exists several elements, sort them through index value.
+ if ("]|") in PcdString:
+ Pcdname = PcdString.split("[")[0]
+ Pcdindex = int(PcdString.split("[")[1].split("]")[0])
+ else:
+ Pcdname = PcdString.split("|")[0]
+ Pcdindex = 0
+ return Pcdname, Pcdindex
+
+ def remove_bracket(self,List):
+ for i in List:
+ for j in i:
+ tmp = j.split("|")
+ if (('L"' in j) and ("[" in j)) or (tmp[1].strip() == '{0x0, 0x0}'):
+ tmp[0] = tmp[0][:tmp[0].index('[')]
+ List[List.index(i)][i.index(j)] = "|".join(tmp)
+ else:
+ List[List.index(i)][i.index(j)] = j
+ for i in List:
+ if type(i) == type([0,0]):
+ i.sort(key = lambda x:(self.correct_sort(x)[0], self.correct_sort(x)[1]))
+ return List
+
+ def write_all(self):
+ title_flag=1
+ info_flag=1
+ if not os.path.isdir(self.outputpath):
+ os.makedirs(self.outputpath)
+ decwrite = write2file(os.path.join(self.outputpath,'StructurePcd.dec'))
+ dscwrite = write2file(os.path.join(self.outputpath,'StructurePcd.dsc'))
+ infwrite = write2file(os.path.join(self.outputpath, 'StructurePcd.inf'))
+ conf = Config(self.Config)
+ ids,title,info,header,inf=self.main()
+ decwrite.add2file(decstatement)
+ decwrite.add2file(header)
+ infwrite.add2file(infstatement)
+ infwrite.add2file(inf)
+ dscwrite.add2file(dscstatement)
+ for id in ids:
+ dscwrite.add2file(conf.eval_id(id))
+ if title_flag:
+ dscwrite.add2file(title)
+ title_flag=0
+ if len(info) == 1:
+ dscwrite.add2file(info)
+ elif len(info) == 2:
+ if info_flag:
+ dscwrite.add2file(info[0])
+ info_flag =0
+ else:
+ dscwrite.add2file(info[1])
+
+ def del_repeat(self,List):
+ if len(List) == 1 or len(List) == 0:
+ return List
+ else:
+ if type(List[0]) != type('xxx'):
+ alist=[]
+ for i in range(len(List)):
+ if i == 0:
+ alist.append(List[0])
+ else:
+ plist = []
+ for j in range(i):
+ plist += List[j]
+ alist.append(self.__del(list(set(plist)), List[i]))
+ return alist
+ else:
+ return list(set(List))
+
+
+ def __del(self,list1,list2):
+ return list(set(list2).difference(set(list1)))
+
+ def reverse_dict(self,dict):
+ data={}
+ for i in list(dict.items()):
+ if i[1] not in list(data.keys()):
+ data[i[1]]=[i[0]]
+ else:
+ data[i[1]].append(i[0])
+ return data
+
+ def read_list(self,list):
+ title_list=[]
+ info_list=[]
+ for i in list[1]:
+ title_list.append(i[0])
+ for j in i[1]:
+ info_list.append(j)
+ return list[0],title_list,info_list
+
+ def plus(self,list):
+ nums=[]
+ for i in list:
+ if type(i) != type([0]):
+ self.init += 1
+ num = "0x%01x" % self.init
+ j=i.replace('0xFCD00000',num.upper())
+ nums.append(j)
+ return nums
+
+class write2file(object):
+
+ def __init__(self,Output):
+ self.output=Output
+ self.text=''
+ if os.path.exists(self.output):
+ os.remove(self.output)
+
+ def add2file(self,content):
+ self.text = ''
+ with open(self.output,'a+') as file:
+ file.write(self.__gen(content))
+
+ def __gen(self,content):
+ if type(content) == type(''):
+ return content
+ elif type(content) == type([0,0])or type(content) == type((0,0)):
+ return self.__readlist(content)
+ elif type(content) == type({0:0}):
+ return self.__readdict(content)
+
+ def __readlist(self,list):
+ for i in list:
+ if type(i) == type([0,0])or type(i) == type((0,0)):
+ self.__readlist(i)
+ elif type(i) == type('') :
+ self.text +=i
+ return self.text
+
+ def __readdict(self,dict):
+ content=list(dict.items())
+ return self.__readlist(content)
+
+def stamp():
+ return datetime.datetime.now()
+
+def dtime(start,end,id=None):
+ if id:
+ pass
+ print("%s time:%s" % (id,str(end - start)))
+ else:
+ print("Total time:%s" %str(end-start)[:-7])
+
+
+def main():
+ start = stamp()
+ parser = argparse.ArgumentParser(prog = __prog__,
+ description = __description__ + __copyright__,
+ conflict_handler = 'resolve')
+ parser.add_argument('-v', '--version', action = 'version',version = __version__, help="show program's version number and exit")
+ parser.add_argument('-p', '--path', metavar='PATH', dest='path', help="platform build output directory")
+ parser.add_argument('-c', '--config',metavar='FILENAME', dest='config', help="firmware configuration file")
+ parser.add_argument('-o', '--outputdir', metavar='PATH', dest='output', help="output directoy")
+ options = parser.parse_args()
+ if options.config:
+ if options.path:
+ if options.output:
+ run = mainprocess(options.path, options.config, options.output)
+ print("Running...")
+ run.write_all()
+ if WARNING:
+ warning = list(set(WARNING))
+ for j in warning:
+ print(j)
+ if ERRORMSG:
+ ERROR = list(set(ERRORMSG))
+ with open("ERROR.log", 'w+') as error:
+ for i in ERROR:
+ error.write(i + '\n')
+ print("Some error find, error log in ERROR.log")
+ print('Finished, Output files in directory %s'%os.path.abspath(options.output))
+ else:
+ print('Error command, no output path, use -h for help')
+ else:
+ print('Error command, no build path input, use -h for help')
+ else:
+ print('Error command, no output file, use -h for help')
+ end = stamp()
+ dtime(start, end)
+
+if __name__ == '__main__':
+ main()