744 lines
34 KiB
Python
744 lines
34 KiB
Python
# -*- coding: utf-8 -*-
|
|
import argparse
|
|
import traceback
|
|
import sys
|
|
import os
|
|
import re
|
|
import xml.etree.ElementTree as ET
|
|
|
|
|
|
class ParserBase(object):
|
|
def __init__(self):
|
|
self.result = True
|
|
|
|
def __del__(self):
|
|
pass
|
|
|
|
def get_result(self):
|
|
return self.result
|
|
|
|
|
|
class ParserBaseEx(ParserBase):
|
|
def __init__(self, ssdk_dir, project):
|
|
super().__init__()
|
|
self.prj_dir, _ = os.path.split(project)
|
|
self.prj_dir = self.prj_dir.replace("\\", '/')
|
|
self.board_map = {
|
|
"e3_gateway": "E3640",
|
|
"e3_324_dev_kit": "E3640",
|
|
"e3_display": "E3340",
|
|
"e3_324_ref_display": "E3340",
|
|
"d3_gateway": "D3248",
|
|
"d3_display": "D3248",
|
|
"e3_176_ref": "E3110",
|
|
"e3_144_ref": "E3205",
|
|
}
|
|
|
|
self.skip_boards = ["e3_master_slave"]
|
|
|
|
self.boards_dir = ssdk_dir.replace('\\', '/')
|
|
if not self.boards_dir.endswith('/'):
|
|
self.boards_dir += '/'
|
|
self.boards_dir += 'boards/'
|
|
self.board_name = self.prj_dir.replace(self.boards_dir, '').split('/')[0]
|
|
|
|
def __del__(self):
|
|
pass
|
|
|
|
def is_skip_board(self):
|
|
if self.board_name.lower() in self.skip_boards:
|
|
return True
|
|
return False
|
|
|
|
|
|
class CustomArgvarsParser(ParserBaseEx):
|
|
def __init__(self, ssdk_dir, custom_argvars):
|
|
super().__init__(ssdk_dir, custom_argvars)
|
|
self.custom_argvars = custom_argvars.replace("\\", '/')
|
|
self.project_name = self.prj_dir.replace(self.boards_dir, '').split('/')[-2]
|
|
self._load_xml()
|
|
# print("project_name", self.project_name)
|
|
# print("board_name=", self.board_name)
|
|
|
|
def __del__(self):
|
|
pass
|
|
|
|
def check_part_id(self):
|
|
part_id = self.get_part_id()
|
|
if len(part_id) == 0:
|
|
print(" [Error] '%s' : PART_ID macro is undefined" % self.custom_argvars)
|
|
self.result = False
|
|
elif self.board_name in self.board_map.keys()and not (part_id == self.board_map[self.board_name]):
|
|
print(" [Error] '%s' : PART ID [%s] is invalid, it must be configured as '%s'" %
|
|
(self.custom_argvars, part_id, self.board_map[self.board_name]))
|
|
self.result = False
|
|
return True
|
|
|
|
def _load_xml(self):
|
|
data = open(self.custom_argvars).read()
|
|
index = data.find('<?xml')
|
|
if not index == -1:
|
|
data = data[index:]
|
|
self.root = ET.fromstring(data)
|
|
# self.tree = ET.parse(custom_argvars)
|
|
# self.root = self.tree.getroot()
|
|
|
|
def get_part_id(self):
|
|
for variable in self.root.find("group"):
|
|
# print(variable.find('name').text)
|
|
# print(variable.find('value').text)
|
|
if variable.find('name').text == 'PART_ID':
|
|
return variable.find('value').text
|
|
return ""
|
|
|
|
def get_board_name(self):
|
|
return self.board_name
|
|
|
|
def get_cord_name(self):
|
|
return self.project_name
|
|
|
|
|
|
class EwpParser(ParserBase):
|
|
def __init__(self, ewp, board, core, part_id):
|
|
super().__init__()
|
|
self.ewp = ewp.replace("\\", '/')
|
|
self.board = board
|
|
self.core = core
|
|
self.part_id = part_id
|
|
self.prj_dir, _ = os.path.split(self.ewp)
|
|
self.tree = ET.parse(ewp)
|
|
self.root = self.tree.getroot()
|
|
self.sfs_map = {
|
|
"e3_gateway": "sfs_s26h-hyperflash.img",
|
|
"e3_324_dev_kit": "sfs_s26h-hyperflash.img",
|
|
"e3_display": "sfs_mt35-1-1-1.img",
|
|
"e3_324_ref_display": "sfs_mt35-1-1-1.img",
|
|
"d3_display": "sfs_mt35-1-1-1.img",
|
|
"d3_gateway": "sfs_mt35-1-1-1.img",
|
|
"e3_176_ref": "sfs_mt35-1-1-1.img",
|
|
"e3_144_ref": "sfs_mt35-1-1-1.img",
|
|
}
|
|
self.out_map = {
|
|
'bootloader': 'bootloader.bin',
|
|
"sf": "sf.bin",
|
|
"sp0": "sp0.bin",
|
|
"sp1": "sp1.bin",
|
|
"sx0": "sx0.bin",
|
|
"sx1": "sx1.bin",
|
|
}
|
|
|
|
self.nor_flash_boards = [
|
|
"d3_display",
|
|
"d3_gateway",
|
|
"e3_display",
|
|
"e3_144_ref"
|
|
]
|
|
|
|
def __del__(self):
|
|
pass
|
|
|
|
def _is_sf_core(self):
|
|
if self.core not in ["sp0", "sp1", "sx0", "sx1"]:
|
|
return True
|
|
return False
|
|
|
|
def _is_xip_hyper_flash(self):
|
|
if not -1 == self.ewp.lower().find('xip/') and -1 == self.ewp.lower().find('iar_norflash'):
|
|
return True
|
|
return False
|
|
|
|
def _is_hyper_flash_driver(self):
|
|
if not -1 == self.ewp.lower().find('hyperbus/'):
|
|
return True
|
|
return False
|
|
|
|
def _is_nor_flash_driver(self):
|
|
if not -1 == self.ewp.lower().find('spi_nor/'):
|
|
return True
|
|
return False
|
|
|
|
def _is_xip_nor_flash(self):
|
|
if not -1 == self.ewp.lower().find('xip/') and not -1 == self.ewp.lower().find('iar_norflash'):
|
|
return True
|
|
return False
|
|
|
|
def check_options(self):
|
|
# project/configuration/name
|
|
_conditions = {
|
|
'IlinkAutoLibEnable': '1',
|
|
'GenLowLevelInterface': '0'
|
|
}
|
|
# 'OOCObjCopyEnable': 1 # debug
|
|
# 'OOCObjCopyEnable': 0 # flashdebug
|
|
for config in self.root.findall("configuration"):
|
|
_config = config.find('name').text
|
|
print(config.find('name').text, 'version')
|
|
for setting in config.findall("settings"):
|
|
# print(" ", setting.find('name').text)
|
|
if setting.find('name').text.upper() == 'ILINK':
|
|
for option in setting.findall("data/option"):
|
|
if option.find('name').text == 'IlinkAutoLibEnable':
|
|
'''
|
|
<option>
|
|
<name>IlinkAutoLibEnable</name>
|
|
<state>1</state>
|
|
</option>
|
|
'''
|
|
# print(" ", option.find('name').text)
|
|
# print(" ", option.find('state').text)
|
|
if not option.find('state').text == '1':
|
|
print(" [Error] '%s' : IlinkAutoLibEnable is %s, it must be configured as 1" % (self.ewp, option.find('state').text))
|
|
self.result = False
|
|
|
|
elif option.find('name').text == 'IlinkExtraOptions':
|
|
'''
|
|
<option>
|
|
<name>IlinkExtraOptions</name>
|
|
<state>--image_input $PROJ_DIR$\..\..\..\..\..\tools\sdtools\sfs\sfs_s26h-hyperflash.img,SFS_BIN,SFS_BIN,8</state>
|
|
<state>--keep SFS_BIN</state>
|
|
</option>
|
|
'''
|
|
error_des = ""
|
|
if _config.lower() == 'flashdebug':
|
|
if self.board not in self.sfs_map:
|
|
sfs_result = True # skip undefined sfs map
|
|
continue
|
|
error_des = " [Error] '%s' : IlinkExtraOptions (sfs) is invalid, it must be configured as %s" % (self.ewp, self.sfs_map[self.board])
|
|
sfs_result = False
|
|
for state in option.findall('state'):
|
|
# print(" ", state.text)
|
|
if self._is_sf_core():
|
|
if self._is_hyper_flash_driver():
|
|
error_des = " [Error] '%s' : IlinkExtraOptions (sfs) is invalid, it must be configured as sfs_s26h-hyperflash.img" % self.ewp
|
|
if state.text and len(state.text) and not -1 == state.text.find('sfs_s26h-hyperflash.img'):
|
|
sfs_result = True
|
|
error_des = ""
|
|
break
|
|
elif self._is_nor_flash_driver():
|
|
error_des = " [Error] '%s' : IlinkExtraOptions (sfs) is invalid, it must be configured as sfs_mt35-1-1-1.img" % self.ewp
|
|
if state.text and len(state.text) and not -1 == state.text.find('sfs_mt35-1-1-1.img'):
|
|
sfs_result = True
|
|
error_des = ""
|
|
break
|
|
elif self.board in self.nor_flash_boards:
|
|
error_des = " [Error] '%s' : IlinkExtraOptions (sfs) is invalid, it must be configured as sfs_mt35-1-1-1.img" % self.ewp
|
|
if state.text and len(state.text) and not -1 == state.text.find('sfs_mt35-1-1-1.img'):
|
|
sfs_result = True
|
|
error_des = ""
|
|
break
|
|
elif self._is_xip_hyper_flash():
|
|
error_des = " [Error] '%s' : IlinkExtraOptions (sfs) is invalid, it must be configured as sfs_s26h-hyperflash.img" % self.ewp
|
|
if state.text and len(state.text) and not -1 == state.text.find('sfs_s26h-hyperflash.img'):
|
|
sfs_result = True
|
|
error_des = ""
|
|
break
|
|
elif self._is_xip_nor_flash():
|
|
error_des = " [Error] '%s' : IlinkExtraOptions (sfs) is invalid, it must be configured as sfs_mt35-1-1-1.img" % self.ewp
|
|
if state.text and len(state.text) and not -1 == state.text.find('sfs_mt35-1-1-1.img'):
|
|
sfs_result = True
|
|
error_des = ""
|
|
break
|
|
else:
|
|
if state.text and len(state.text) and not -1 == state.text.find(self.sfs_map[self.board]):
|
|
sfs_result = True
|
|
error_des = ""
|
|
break
|
|
else:
|
|
sfs_result = True
|
|
if state.text and len(state.text) and not (-1 == state.text.find('SFS_BIN,')):
|
|
sfs_result = False
|
|
error_des = " [Error] '%s' : IlinkExtraOptions (sfs) is invalid, does not need to configure sfs for %s core" % (self.ewp, self.core)
|
|
break
|
|
|
|
else: # debug verison
|
|
sfs_result = True
|
|
for state in option.findall('state'):
|
|
if state.text and len(state.text) and not (-1 == state.text.find('SFS_BIN,')):
|
|
sfs_result = False
|
|
error_des = " [Error] '%s' : IlinkExtraOptions (sfs) is invalid, does not need to configure sfs for debug version" % self.ewp
|
|
break
|
|
|
|
if not sfs_result:
|
|
print(" ", option.find('name').text)
|
|
for state in option.findall('state'):
|
|
print(" ", state.text)
|
|
print(error_des)
|
|
self.result = False
|
|
elif setting.find('name').text == 'General':
|
|
for option in setting.findall("data/option"):
|
|
if option.find('name').text == 'GenLowLevelInterface':
|
|
'''
|
|
<option>
|
|
<name>GenLowLevelInterface</name>
|
|
<state>0</state>
|
|
</option>
|
|
'''
|
|
# print(" ", option.find('name').text)
|
|
# print(" ", option.find('state').text)
|
|
if not option.find('state').text == '0':
|
|
print(" [Error] '%s' : GenLowLevelInterface is %s, it must be configured as 0" % (self.ewp, option.find('state').text))
|
|
self.result = False
|
|
elif setting.find('name').text == 'OBJCOPY':
|
|
for option in setting.findall("data/option"):
|
|
if option.find('name').text == 'OOCObjCopyEnable' and _config.lower() == 'debug':
|
|
'''
|
|
<option>
|
|
<name>OOCObjCopyEnable</name>
|
|
<state>1</state>
|
|
</option>
|
|
'''
|
|
# print(" ", option.find('name').text)
|
|
# print(" ", option.find('state').text)
|
|
if not option.find('state').text == '1':
|
|
print(" [Error] '%s' : OOCObjCopyEnable is %s, it must be configured as 1 for Debug version" % (self.ewp, option.find('state').text))
|
|
self.result = False
|
|
|
|
elif option.find('name').text == 'OOCOutputFile':
|
|
'''
|
|
<option>
|
|
<name>OOCOutputFile</name>
|
|
<state>sf.bin</state>
|
|
</option>
|
|
'''
|
|
# print(" ", option.find('name').text)
|
|
# print(" ", option.find('state').text)
|
|
if not _config.lower() == 'flashdebug' and \
|
|
option.find('state').text:
|
|
if self.core in self.out_map.keys() and not option.find('state').text == self.out_map[self.core]:
|
|
print(" [Error] '%s' : OOCOutputFile is %s, it must be configured as %s" %
|
|
(self.ewp, option.find('state').text, self.out_map[self.core]))
|
|
self.result = False
|
|
elif self.core not in self.out_map.keys() and not option.find('state').text == self.out_map['sf']:
|
|
print(" [Error] '%s' : OOCOutputFile is %s, it must be configured as %s" %
|
|
(self.ewp, option.find('state').text, self.out_map['sf']))
|
|
self.result = False
|
|
|
|
def check_files(self):
|
|
for group in self.root.findall("group"):
|
|
# print(group.find('name').text)
|
|
self._enum_group(group)
|
|
|
|
def _check_file(self, file):
|
|
if -1 == file.find('$PROJ_DIR$'):
|
|
print(" [Error] \'%s\' is not a relative path" % file)
|
|
self.result = False
|
|
return False
|
|
_file = file.replace('$PROJ_DIR$', self.prj_dir)
|
|
_file = _file.replace('$PART_ID$', self.part_id)
|
|
_file = _file.replace("\\", '/')
|
|
if not os.path.exists(_file):
|
|
print(" [Error] \'%s\' : \'%s\' don't exist" % (self.ewp, file))
|
|
self.result = False
|
|
return False
|
|
match = re.search('^.+/devices/([DE]\d+)/.+$', file.replace("\\", '/'), re.I)
|
|
if match:
|
|
print(" [Error] \'%s\' - \'%s\' : The part id can not use fixed value [%s], must be used macro definition" %
|
|
(self.ewp, file, match.group(1)))
|
|
self.result = False
|
|
return False
|
|
return True
|
|
|
|
def _enum_group(self, parent):
|
|
# print(">>>", parent.find('name').text)
|
|
for file in parent.findall("file"):
|
|
# print(" ", file.find('name').text)
|
|
_file = file.find('name').text
|
|
self._check_file(_file)
|
|
for sub_group in parent.findall("group"):
|
|
self._enum_group(sub_group)
|
|
|
|
|
|
class EclipsePrjParser(ParserBaseEx):
|
|
def __init__(self, ssdk_dir, project):
|
|
super().__init__(ssdk_dir, project)
|
|
self.project = project.replace("\\", '/')
|
|
self.prj_dir, _ = os.path.split(self.project)
|
|
self.tree = ET.parse(self.project)
|
|
self.root = self.tree.getroot()
|
|
self.PART_PATH = ""
|
|
self.part_id = ""
|
|
self.macro_map = {}
|
|
|
|
def __del__(self):
|
|
pass
|
|
|
|
def check_project_name(self):
|
|
# print(self.prj_dir.split('/'))
|
|
if not self.prj_dir.split('/')[-2] == self.root.find('name').text:
|
|
print(" [Error] '%s' : Project name is incorrect, please modify '%s' to '%s'" %
|
|
(self.project, self.root.find('name').text, self.prj_dir.split('/')[-2]))
|
|
self.result = False
|
|
return False
|
|
return True
|
|
|
|
def check_part_id(self):
|
|
if self.root.find('variableList/variable') is None:
|
|
print(" [Error] '%s' : Undefined PART_ID macro" % self.project)
|
|
self.result = False
|
|
return False
|
|
has_part_id_macro = False
|
|
has_part_path_macro = False
|
|
for variable in self.root.findall("variableList/variable"):
|
|
# print(variable.find('name').text)
|
|
self.macro_map[variable.find('name').text] = variable.find('value').text
|
|
if variable.find('name').text == 'PART_ID':
|
|
has_part_id_macro = True
|
|
self.part_id = variable.find('value').text
|
|
elif variable.find('name').text == 'PART_PATH':
|
|
self.PART_PATH = variable.find('value').text
|
|
if not (-1 == variable.find('value').text.find('$%7BPART_ID%7D')):
|
|
has_part_path_macro = True
|
|
# print(self.macro_map)
|
|
if not has_part_id_macro:
|
|
print(" [Error] '%s' : PART_ID macro is undefined" % self.project)
|
|
self.result = False
|
|
return False
|
|
|
|
if not has_part_path_macro:
|
|
print(" [Error] '%s' : PART_PATH macro is undefined" % self.project)
|
|
self.result = False
|
|
return False
|
|
if len(self.part_id) == 0:
|
|
print(" [Error] '%s' : PART_ID macro is undefined" % self.project)
|
|
self.result = False
|
|
return False
|
|
elif self.board_name in self.board_map.keys() and not (self.part_id == self.board_map[self.board_name]):
|
|
print(" [Error] '%s' : PART ID [%s] is invalid, it must be configured as '%s'" %
|
|
(self.project, self.part_id, self.board_map[self.board_name]))
|
|
self.result = False
|
|
return False
|
|
return True
|
|
|
|
def get_part_id(self):
|
|
return self.part_id
|
|
|
|
def get_depth(self):
|
|
return self.PART_PATH
|
|
|
|
def check_files(self):
|
|
for link_src in self.root.findall("linkedResources/link"):
|
|
if link_src.find('type').text == '1':
|
|
# print(link_src.find('name').text)
|
|
# print(link_src.find('type').text)
|
|
if link_src.find('locationURI') is None:
|
|
# print('location', link_src.find('location').text)
|
|
self._check_file(link_src.find('location').text)
|
|
elif link_src.find('location') is None:
|
|
# print('locationURI', link_src.find('locationURI').text)
|
|
self._check_file(link_src.find('locationURI').text)
|
|
|
|
def _check_file(self, file):
|
|
match = re.search('^.+/devices/([DE]\d+)/.+$', file.replace("\\", '/'), re.I)
|
|
if match:
|
|
print(" [Error] \'%s\' - \'%s\' : The part id can not use fixed value [%s], must be used macro definition" %
|
|
(self.project, file, match.group(1)))
|
|
self.result = False
|
|
return False
|
|
return True
|
|
|
|
|
|
class EclipseCprjParser(ParserBaseEx):
|
|
def __init__(self, ssdk_dir, project):
|
|
super().__init__(ssdk_dir, project)
|
|
self.project = project.replace("\\", '/')
|
|
self.prj_dir, _ = os.path.split(self.project)
|
|
self.tree = ET.parse(self.project)
|
|
self.root = self.tree.getroot()
|
|
self.part_id = ""
|
|
self.out_map = {
|
|
'bootloader': 'bootloader',
|
|
"sf": "sf",
|
|
"sp0": "sp0",
|
|
"sp1": "sp1",
|
|
"sx0": "sx0",
|
|
"sx1": "sx1",
|
|
}
|
|
|
|
def __del__(self):
|
|
pass
|
|
|
|
def check_macro(self):
|
|
find = False
|
|
for macro in self.root.findall("storageModule/cconfiguration/storageModule/macros"):
|
|
# print(macro.find('stringMacro').attrib['name'])
|
|
# print(macro.find('stringMacro').attrib['value'])
|
|
self.part_id = macro.find('stringMacro').attrib['value']
|
|
find = True
|
|
if not find:
|
|
self.result = False
|
|
print(" [Error] '%s' : PART_ID macro is undefined" % self.project)
|
|
return False
|
|
if len(self.part_id) == 0:
|
|
print(" [Error] '%s' : PART_ID macro is undefined" % self.project)
|
|
self.result = False
|
|
return False
|
|
elif self.board_name in self.board_map.keys() and not (self.part_id == self.board_map[self.board_name]):
|
|
print(" [Error] '%s' : PART ID [%s] is invalid, it must be configured as '%s'" %
|
|
(self.project, self.part_id, self.board_map[self.board_name]))
|
|
self.result = False
|
|
return False
|
|
return True
|
|
|
|
def check_includes(self):
|
|
Assembler_tag = "GNU Arm Cross Assembler".lower()
|
|
CC_tag = "GNU Arm Cross C Compiler".lower()
|
|
CPP_tag = "GNU Arm Cross C++ Compiler".lower()
|
|
Include_tag = "Include paths (-I)".lower()
|
|
|
|
Linker_tag = "GNU Arm Cross C Linker".lower()
|
|
LD_tag = "Script files (-T)".lower()
|
|
|
|
Image_tag = "GNU Arm Cross Create Flash Image".lower()
|
|
Type_tag = "Output file format (-O)".lower()
|
|
superClass = "ilg.gnuarmeclipse.managedbuild.cross.tool.createflash".lower()
|
|
Bin_tag = 'ilg.gnuarmeclipse.managedbuild.cross.option.createflash.choice.binary'.lower()
|
|
|
|
for tool in self.root.findall("storageModule/cconfiguration/storageModule/configuration/folderInfo/toolChain/"):
|
|
if "name" not in tool.attrib.keys():
|
|
continue
|
|
if tool.attrib['name'].lower() in [Assembler_tag, CC_tag, CPP_tag, Linker_tag, Image_tag]:
|
|
_tool_name = tool.attrib['name'].lower()
|
|
if _tool_name == Image_tag:
|
|
if 'superClass' in tool.attrib.keys() and tool.attrib['superClass'].lower() == superClass:
|
|
_result = False
|
|
_error = " [Error] '%s' : artifactName is empty, it must be configured as %s" % \
|
|
(self.project, Bin_tag)
|
|
for option_item in list(tool): # tool.getchildren():
|
|
if "value" not in option_item.attrib.keys():
|
|
continue
|
|
if option_item.attrib['value'].lower() == Bin_tag:
|
|
_result = True
|
|
_error = ""
|
|
break
|
|
else:
|
|
# print("_attr_name", option_item.attrib['value'])
|
|
_error = " [Error] '%s' : artifactName is %s, it must be configured as %s" % \
|
|
(self.project, option_item.attrib['value'], Bin_tag)
|
|
_result = False
|
|
if not _result and len(_error):
|
|
print(_error)
|
|
self.result = False
|
|
continue
|
|
for option_item in list(tool): # tool.getchildren():
|
|
if "name" not in option_item.attrib.keys():
|
|
continue
|
|
_attr_name = option_item.attrib['name']
|
|
if _attr_name.lower() in [Include_tag, LD_tag]:
|
|
# print("_attr_name", _attr_name)
|
|
for listOptionValue in list(option_item): # option_item.getchildren():
|
|
# print(listOptionValue.attrib['value'])
|
|
self._check_file(listOptionValue.attrib['value'])
|
|
|
|
def check_output(self):
|
|
prj_name = self.prj_dir.split('/')[-2]
|
|
for config in self.root.findall("storageModule/cconfiguration/storageModule/configuration"):
|
|
if "artifactName" in config.attrib.keys():
|
|
if prj_name in self.out_map.keys() and not config.attrib['artifactName'] == self.out_map[prj_name] and \
|
|
not config.attrib['artifactName'] == '${ProjName}':
|
|
print(" [Error] '%s' : artifactName is %s, it must be configured as %s" %
|
|
(self.project, config.attrib['artifactName'], self.out_map[prj_name]))
|
|
self.result = False
|
|
elif prj_name not in self.out_map.keys() and not config.attrib['artifactName'] == self.out_map['sf'] and \
|
|
not config.attrib['artifactName'] == '${ProjName}':
|
|
print(" [Error] '%s' : artifactName is %s, it must be configured as %s" %
|
|
(self.project, config.attrib['artifactName'], self.out_map['sf']))
|
|
self.result = False
|
|
elif config.attrib['artifactName'] == '${ProjName}' and prj_name not in self.out_map.keys():
|
|
print(" [Error] '%s' : artifactName is %s, it must be configured as %s" %
|
|
(self.project, config.attrib['artifactName'], self.out_map['sf']))
|
|
self.result = False
|
|
|
|
def _check_file(self, file):
|
|
match = re.search('^.+/devices/([DE]\d+)/.+$', file.replace("\\", '/'), re.I)
|
|
if match:
|
|
print(" [Error] \'%s\' - \'%s\' : The part id can not use fixed value [%s], must be used macro definition" %
|
|
(self.project, file, match.group(1)))
|
|
self.result = False
|
|
return False
|
|
return True
|
|
|
|
|
|
class VerifyBase(object):
|
|
def __init__(self, ssdk_dir, board_dir=''):
|
|
self.ssdk_dir = ssdk_dir.replace("\\", '/')
|
|
self.board_dir = board_dir.replace("\\", '/')
|
|
self.ssdk_dir = self._rm_slash(self.ssdk_dir)
|
|
self.board_dir = self._rm_slash(self.board_dir)
|
|
if 0 == len(self.board_dir):
|
|
self.board_dir = self.ssdk_dir + '/boards'
|
|
self.result = True
|
|
|
|
def __del__(self):
|
|
pass
|
|
|
|
def _rm_slash(self, src): # remove /slash
|
|
if src.endswith('/'):
|
|
return src[:-1]
|
|
return src
|
|
|
|
def get_projects(self, project_type):
|
|
# project_type in ['IAR', 'IAR_Norflash', 'Eclipse', 'Eclipse_Norflash']
|
|
project_dir = []
|
|
for path, subdirs, files in os.walk(self.board_dir):
|
|
for sub_dir in subdirs:
|
|
if sub_dir in project_type:
|
|
_project = os.path.join(path, sub_dir)
|
|
_project = _project.replace("\\", '/')
|
|
project_dir.append(_project)
|
|
return project_dir
|
|
|
|
def get_result(self):
|
|
return self.result
|
|
|
|
|
|
class IarVerify(VerifyBase):
|
|
_iar_ext = [
|
|
'custom_argvars',
|
|
'ewd',
|
|
'ewp',
|
|
'eww'
|
|
]
|
|
|
|
def verify(self):
|
|
print("Start scanning and checking iar project ...")
|
|
_projects = self.get_projects(['IAR', 'IAR_Norflash'])
|
|
for proj in _projects:
|
|
_project_name = proj.split('/')[-2]
|
|
# print(proj, _project_name)
|
|
_tmp_prj_files = []
|
|
board = ""
|
|
core = ""
|
|
part_id = ""
|
|
|
|
# check *.custom_argvars
|
|
skip_check = False
|
|
for file in os.listdir(proj):
|
|
if file.endswith('custom_argvars'):
|
|
obj = CustomArgvarsParser(self.ssdk_dir, os.path.join(proj, file).replace("\\", '/'))
|
|
if obj.is_skip_board():
|
|
skip_check = True
|
|
continue
|
|
print("Check the custom_argvars file :", os.path.join(proj, file).replace("/", '\\'))
|
|
obj.check_part_id()
|
|
board = obj.get_board_name()
|
|
core = obj.get_cord_name()
|
|
part_id = obj.get_part_id()
|
|
if self.result:
|
|
self.result = obj.get_result()
|
|
|
|
# check *.ewp
|
|
# print("board = ", board)
|
|
# print("core = ", core)
|
|
# print("part_id = ", part_id)
|
|
if skip_check:
|
|
continue
|
|
for file in os.listdir(proj):
|
|
_tmp_prj_files.append(file.split('.')[-1])
|
|
if file.endswith('ewp'):
|
|
print("Check the ewp file :", os.path.join(proj, file).replace("/", '\\'))
|
|
obj = EwpParser(os.path.join(proj, file).replace("\\", '/'), board, core, part_id)
|
|
obj.check_options()
|
|
obj.check_files()
|
|
if self.result:
|
|
self.result = obj.get_result()
|
|
|
|
for item in self._iar_ext:
|
|
if item not in _tmp_prj_files:
|
|
print(" [Error] '%s' : Not find '%s' file" % (proj, item))
|
|
self.result = False
|
|
print('\n')
|
|
print("Finished scanning and checking iar project")
|
|
return self.result
|
|
|
|
|
|
class EclipseVerify(VerifyBase):
|
|
def verify(self):
|
|
print("Start scanning and checking eclipse project ...")
|
|
_projects = self.get_projects(['Eclipse', 'Eclipse_Norflash'])
|
|
for proj in _projects:
|
|
_project_name = proj.split('/')[-2]
|
|
# print(proj, _project_name)
|
|
|
|
obj = EclipsePrjParser(self.ssdk_dir, os.path.join(proj, '.project'))
|
|
if obj.is_skip_board():
|
|
continue
|
|
print("Check the .project file :", os.path.join(proj, '.project').replace("/", '\\'))
|
|
obj.check_project_name()
|
|
obj.check_part_id()
|
|
obj.check_files()
|
|
if self.result:
|
|
self.result = obj.get_result()
|
|
|
|
print("Check the .cproject file :", os.path.join(proj, '.cproject').replace("/", '\\'))
|
|
c_obj = EclipseCprjParser(self.ssdk_dir, os.path.join(proj, '.cproject'))
|
|
c_obj.check_macro()
|
|
c_obj.check_includes()
|
|
c_obj.check_output()
|
|
if self.result:
|
|
self.result = c_obj.get_result()
|
|
print("Finished scanning and checking eclipse project")
|
|
return self.result
|
|
|
|
|
|
class VerifyIdeProject(object):
|
|
"""Object for command-line tool."""
|
|
|
|
def __init__(self):
|
|
"""Initializer method."""
|
|
pass
|
|
|
|
def version(self, _):
|
|
"""Implements the 'version' sub-command."""
|
|
print('1.23.1.1')
|
|
|
|
def verify(self, args):
|
|
result = False
|
|
try:
|
|
iar = IarVerify(args.ssdk_dir, args.project_dir)
|
|
eclipse = EclipseVerify(args.ssdk_dir, args.project_dir)
|
|
result = iar.verify()
|
|
eclipse_result = eclipse.verify()
|
|
if result:
|
|
result = eclipse_result
|
|
except Exception:
|
|
result = False
|
|
print("[Error] %s" % traceback.format_exc())
|
|
finally:
|
|
if result:
|
|
print('Successfully verified project files.')
|
|
else:
|
|
print('[Error] Invalid project configuration found.')
|
|
sys.exit(1)
|
|
return result
|
|
|
|
def run(self, argv):
|
|
parser = argparse.ArgumentParser()
|
|
subparsers = parser.add_subparsers(title='subcommands')
|
|
sub_parser = subparsers.add_parser('version', help='Prints version of VerifyIdeProject.')
|
|
sub_parser.set_defaults(func=self.version)
|
|
|
|
sub_parser = subparsers.add_parser('verify', help="Verify IDE project for ssdk's boards.")
|
|
sub_parser.add_argument('--ssdk_dir',
|
|
help='Path to ssdk project root directory.',
|
|
type=str,
|
|
required=True)
|
|
sub_parser.add_argument('--project_dir',
|
|
help='Path to ide project directory.',
|
|
type=str,
|
|
default="")
|
|
sub_parser.set_defaults(func=self.verify)
|
|
|
|
args = parser.parse_args(argv[1:])
|
|
try:
|
|
func = args.func
|
|
except AttributeError:
|
|
parser.error("invalid arguments")
|
|
return func(args)
|
|
|
|
|
|
# python project_verify.py verify --ssdk_dir D:\SDRapidStudio\ide\workspace\2.1
|
|
# python project_verify.py verify --ssdk_dir D:\SDRapidStudio\ide\workspace\2.1 --project_dir D:\SDRapidStudio\ide\workspace\2.1\boards\e3_gateway
|
|
if __name__ == '__main__':
|
|
tool = VerifyIdeProject()
|
|
tool.run(sys.argv)
|