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