diff options
| author | kx <kx@radix.pro> | 2024-06-04 06:43:08 +0300 |
|---|---|---|
| committer | kx <kx@radix.pro> | 2024-06-04 06:43:08 +0300 |
| commit | 7e2ccccace24636f29ddc210b94606abd4c7e42b (patch) | |
| tree | 545d43ea12671048956cafeb12303e84d601e571 /BaseTools/Scripts/ConvertFceToStructurePcd.py | |
| parent | 27b044605cd5f6b33a3d231576003850b3fe305b (diff) | |
| download | edk2-trunk.tar.xz | |
Renormalized end-of-lines from master@27b044605cd5f6b33a3d231576003850b3fe305btrunk
Diffstat (limited to 'BaseTools/Scripts/ConvertFceToStructurePcd.py')
| -rw-r--r-- | BaseTools/Scripts/ConvertFceToStructurePcd.py | 1484 |
1 files changed, 742 insertions, 742 deletions
diff --git a/BaseTools/Scripts/ConvertFceToStructurePcd.py b/BaseTools/Scripts/ConvertFceToStructurePcd.py index 9e7fe58768..609eab2c50 100644 --- a/BaseTools/Scripts/ConvertFceToStructurePcd.py +++ b/BaseTools/Scripts/ConvertFceToStructurePcd.py @@ -1,742 +1,742 @@ -#!/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', 'BOOLEAN']:
- 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_ori = comment_list[0].strip()
- comment = ""
- for each in comment_ori:
- if each != " " and "\x21" > each or each > "\x7E":
- if bytes(each, 'utf-16') == b'\xff\xfe\xae\x00':
- each = '(R)'
- else:
- each = ""
- comment += each
- 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].split("#")[0].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()
+#!/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', 'BOOLEAN']: + 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_ori = comment_list[0].strip() + comment = "" + for each in comment_ori: + if each != " " and "\x21" > each or each > "\x7E": + if bytes(each, 'utf-16') == b'\xff\xfe\xae\x00': + each = '(R)' + else: + each = "" + comment += each + 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].split("#")[0].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() |
