def test_is_agm1_agent(self): component = DSLFactory().from_file( os.path.join(CURRENT_DIR, "resources", "camerasimple.cdsl")) self.assertFalse(parsing_utils.is_agm1_agent(component)) component = DSLFactory().from_file( os.path.join(CURRENT_DIR, "resources", "humanAgent.cdsl")) self.assertTrue(parsing_utils.is_agm1_agent(component)) self.assertRaises(AssertionError, parsing_utils.is_agm1_agent, "CameraSimple")
def test_dsl_factory(self): factory = DSLFactory() factory2 = DSLFactory() # test of singleton factory behavior self.assertIs(factory, factory2) a = factory.from_file( "/home/robolab/robocomp/components/euroage-tv/components/tvGames/gamestatemachine.smdsl" ) # test for cached query b = factory.from_file( "/home/robolab/robocomp/components/euroage-tv/components/tvGames/gamestatemachine.smdsl" ) self.assertIs(a, b) c = factory.from_file( "/home/robolab/robocomp/interfaces/IDSLs/JointMotor.idsl") # test for cached query d = factory.from_file( "/home/robolab/robocomp/interfaces/IDSLs/JointMotor.idsl") self.assertIs(c, d) e = factory.from_file( "/home/robolab/robocomp/tools/robocompdsl/component_generation_test/customStateMachinePython/test.cdsl" ) # test for cached query f = factory.from_file( "/home/robolab/robocomp/tools/robocompdsl/component_generation_test/customStateMachinePython/test.cdsl" ) self.assertIs(e, f)
def gimmeIDSL(name, files='', includeDirectories=None): if not '.idsl' in name: name += '.idsl' name = os.path.basename(name) pathList = [] if includeDirectories != None: pathList += [x for x in includeDirectories] fileList = [] for p in [f for f in files.split('#') if len(f) > 0]: if p.startswith("-I"): pathList.append(p[2:]) else: fileList.append(p) pathList.append('/opt/robocomp/interfaces/IDSLs/') pathList.append(os.path.expanduser('~/robocomp/interfaces/IDSLs/')) filename = name.split('.')[0] for p in pathList: try: path = os.path.join(p, name) # WARN: import is here to avoid problem with recursive import on startup from dsl_parsers.dsl_factory import DSLFactory return DSLFactory().from_file(path) except IOError as e: pass print(('Couldn\'t locate ', name)) sys.exit(-1)
def includeInPool(self, files, module_pool, include_directories): """ Recursively add the loaded modules to the pool. """ # look for the files in the includeDirectories for f in files: filename = f.split('.')[0] if filename not in module_pool: for p in include_directories: try: path = os.path.join(p, f) # if found, load the module from the file # WARN: import is here to avoid problem with recursive import on startup from dsl_parsers.dsl_factory import DSLFactory module = DSLFactory().from_file(path) # store the module module_pool[filename] = module # try to add the modules that this one imports self.includeInPool( module['imports'] + module['recursive_imports'], module_pool, include_directories) break except IOError: pass if filename not in self: raise ValueError('Couldn\'t locate %s ' % f)
def load_slice_and_create_imports(self, includeDirectories=None): result = "" import os for imp in sorted(set(self.component.recursiveImports + self.component.imports)): file_name = os.path.basename(imp) name = os.path.splitext(file_name)[0] result += Template(SLICE_LOAD_STR).substitute(interface_name=name) module = DSLFactory().from_file(file_name, includeDirectories=includeDirectories) result += f"import {module['name']}\n" return result
def get_interface_name_for_idsl(self, idsl_filename): """ Extract the name of the interface for a idsl file. :param idsl_filename: .idsl file name :return: name of the interface defined inside the .idsl file. """ try: interface_name = DSLFactory().from_file(idsl_filename)['interfaces'][0]['name'] except: # There's some .idsl files without interfaces defined on it, just data structures definitions raise ValueError("Couldn't get the interface name for idsl file: %s" % idsl_filename) else: return interface_name
def generate_recursive_imports(initial_idsls, include_directories=[]): assert isinstance( initial_idsls, list), "initial_idsl, parameter must be a list, not %s" % str( type(initial_idsls)) new_idsls = [] for idsl_path in initial_idsls: importedModule = None idsl_basename = os.path.basename(idsl_path) iD = include_directories + [ '/opt/robocomp/interfaces/IDSLs/', os.path.expanduser('~/robocomp/interfaces/IDSLs/') ] # TODO: Replace by idsl_robocomp_path try: for directory in iD: attempt = directory + '/' + idsl_basename # print 'Check', attempt if os.path.isfile(attempt): # WARN: import is here to avoid problem with recursive import on startup from dsl_parsers.dsl_factory import DSLFactory importedModule = DSLFactory().from_file( attempt) # IDSLParsing.gimmeIDSL(attempt) break except: print(('Error reading IMPORT', idsl_basename)) traceback.print_exc() print(('Error reading IMPORT', idsl_basename)) os._exit(1) if importedModule == None: print(('Counldn\'t locate', idsl_basename)) os._exit(1) # if importedModule['imports'] have a # at the end an emtpy '' is generated idsl_imports = importedModule['imports'].split('#') # we remove all the '' ocurrences and existing imports aux_imports = [] for i_import in idsl_imports: if i_import != '' and i_import not in initial_idsls: if communication_is_ice(i_import): aux_imports.append(i_import) idsl_imports = aux_imports if len(idsl_imports) > 0 and idsl_imports[0] != '': new_idsls += idsl_imports + generate_recursive_imports( idsl_imports, include_directories) return list(set(new_idsls))
def generate_recursive_imports(initial_idsls, include_directories=None): assert isinstance( initial_idsls, list), "initial_idsl, parameter must be a list, not %s" % str( type(initial_idsls)) if include_directories is None: include_directories = [] new_idsls = [] for idsl_path in initial_idsls: idsl_basename = os.path.basename(idsl_path) include_directories = include_directories + IDSLPool.get_common_interface_dirs( ) # TODO: Replace by idsl_robocomp_path new_idsl_path = idsl_robocomp_path(idsl_basename, include_directories) from dsl_parsers.dsl_factory import DSLFactory try: imported_module = DSLFactory().from_file( new_idsl_path) # IDSLParsing.gimmeIDSL(attempt) except pyparsing.ParseException as e: console.log( f"Parsing error in file {Text(new_idsl_path, style='red')} while generating recursive imports." ) console.log( f"Exception info: {Text(e.args[2], style='red')} in line {e.lineno} of:\n{Text(e.args[0].rstrip(), styled='magenta')}" ) raise if imported_module is None: raise FileNotFoundError( 'generate_recursive_imports: Couldn\'t locate %s' % idsl_basename) # if importedModule['imports'] have a # at the end an emtpy '' is generated idsl_imports = imported_module['imports'] # we remove all the '' ocurrences and existing imports aux_imports = [] for i_import in idsl_imports: if i_import != '' and i_import not in initial_idsls: if communication_is_ice(i_import): aux_imports.append(i_import) idsl_imports = aux_imports if len(idsl_imports) > 0 and idsl_imports[0] != '': new_idsls += idsl_imports + generate_recursive_imports( idsl_imports, include_directories) return list(set(new_idsls))
def includeInPool(self, files, modulePool, includeDirectories): """ Recursively add the loaded modules to the pool. """ fileList = [] # Extracting files names from string argument "-I filename.idsl#filename2.idsl" for p in [f for f in files.split('#') if len(f) > 0]: if p.startswith("-I"): pass else: fileList.append(p) # look for the files in the includeDirectories for f in fileList: filename = f.split('.')[0] if not filename in modulePool: for p in includeDirectories: try: path = os.path.join(p, f) # if found, load the module from the file # WARN: import is here to avoid problem with recursive import on startup from dsl_parsers.dsl_factory import DSLFactory module = DSLFactory().from_file(path) # store the module modulePool[filename] = module # try to add the modules that this one imports self.includeInPool( module['imports'] + module['recursive_imports'], modulePool, includeDirectories) break except IOError as e: pass if not filename in self.modulePool: print(('Couldn\'t locate ', f)) # TODO: replace with an exception sys.exit(-1)
def test_factory_singleton(self): factory2 = DSLFactory() self.assertIs(self.factory, factory2)
def setUp(self): self.maxDiff = None self.factory = DSLFactory()
class DSLFactoryTestCase(unittest.TestCase): def setUp(self): self.maxDiff = None self.factory = DSLFactory() def assertNestedDictEqual(self, first, second, ignored_keys=None, msg=None): if ignored_keys is not None: first = copy.deepcopy(first) second = copy.deepcopy(second) for key in ignored_keys: if key in first: del first[key] if key in second: del second[key] j1 = json.dumps(first, sort_keys=True, indent=4) j2 = json.dumps(second, sort_keys=True, indent=4) self.maxDiff = None # with open('last_json1.txt', 'w') as outfile: # json.dump(first, outfile, sort_keys=True, indent=4) # with open('last_json2.txt', 'w') as outfile: # json.dump(second, outfile, sort_keys=True, indent=4) self.assertEqual(j1, j2, msg) def test_factory_singleton(self): factory2 = DSLFactory() self.assertIs(self.factory, factory2) def test_factory_smdsl(self): a = self.factory.from_file(os.path.join(RESOURCES_DIR, "gamestatemachine.smdsl")) self.assertDictEqual(a, { 'machine': { 'name': 'application_machine', 'default': False, 'contents': { 'states': None, 'finalstate': 'app_end', 'initialstate': 'game_machine', 'transitions': [ {'src': 'game_machine', 'dests': ['app_end']}] } }, 'substates': [ { 'parallel': False, 'parent': 'game_machine', 'contents': { 'states': [ 'session_init', 'game_start_wait', 'game_init', 'game_loop', 'game_pause', 'game_resume', 'game_reset', 'game_end', 'game_won', 'game_lost', 'session_end'], 'finalstate': None, 'initialstate': 'session_start_wait', 'transitions': [ {'src': 'session_start_wait', 'dests': ['session_init']}, {'src': 'session_init', 'dests': ['game_start_wait']}, {'src': 'game_start_wait', 'dests': ['game_start_wait']}, {'src': 'game_start_wait', 'dests': ['game_init']}, {'src': 'game_start_wait', 'dests': ['session_end']}, {'src': 'session_end', 'dests': ['session_start_wait']}, {'src': 'game_init', 'dests': ['game_loop']}, {'src': 'game_loop', 'dests': ['game_loop', 'game_pause', 'game_won', 'game_lost', 'game_end']}, {'src': 'game_pause', 'dests': ['game_loop']}, {'src': 'game_pause', 'dests': ['game_reset']}, {'src': 'game_pause', 'dests': ['game_resume']}, {'src': 'game_pause', 'dests': ['game_end']}, {'src': 'game_resume', 'dests': ['game_loop']}, {'src': 'game_end', 'dests': ['game_lost']}, {'src': 'game_end', 'dests': ['game_won']}, {'src': 'game_lost', 'dests': ['game_start_wait']}, {'src': 'game_won', 'dests': ['game_start_wait']}, {'src': 'game_reset', 'dests': ['game_start_wait']} ] } }, { 'parallel': False, 'parent': 'session_init', 'contents': { 'states': [ 'player_acquisition_loop'], 'finalstate': 'player_acquisition_ended', 'initialstate': 'player_acquisition_init', 'transitions': [ {'src': 'player_acquisition_init', 'dests': ['player_acquisition_loop']}, {'src': 'player_acquisition_loop', 'dests': ['player_acquisition_loop']}, {'src': 'player_acquisition_loop', 'dests': ['player_acquisition_ended']} ] } } ], 'filename': os.path.join(RESOURCES_DIR, "gamestatemachine.smdsl") }) # Test for cached query b = self.factory.from_file(os.path.join(RESOURCES_DIR, "gamestatemachine.smdsl")) self.assertIs(a, b) def test_factory_idsl(self): c = self.factory.from_file("JointMotor.idsl") ref = OrderedDict({ 'name': 'RoboCompJointMotor', 'imports': [], 'recursive_imports': [], 'interfaces':[ {'name': 'JointMotor', 'methods': OrderedDict([ ('getAllMotorParams',{'name': 'getAllMotorParams', 'decorator': '', 'return': 'MotorParamsList', 'params': [], 'throws': 'nothing'}), ('getAllMotorState', {'name': 'getAllMotorState', 'decorator': '', 'return': 'void', 'params': [{'decorator': 'out', 'type': 'MotorStateMap', 'name': 'mstateMap'}], 'throws': ['UnknownMotorException']}), ('getBusParams', {'name': 'getBusParams', 'decorator': '', 'return': 'BusParams', 'params': [], 'throws': 'nothing'}), ('getMotorParams', {'name': 'getMotorParams', 'decorator': '', 'return': 'MotorParams', 'params': [{'decorator': 'none', 'type': 'string', 'name': 'motor'}], 'throws': ['UnknownMotorException']}), ('getMotorState', {'name': 'getMotorState', 'decorator': '', 'return': 'MotorState', 'params': [{'decorator': 'none', 'type': 'string', 'name': 'motor'}], 'throws': ['UnknownMotorException']}), ('getMotorStateMap', {'name': 'getMotorStateMap', 'decorator': '', 'return': 'MotorStateMap', 'params': [{'decorator': 'none', 'type': 'MotorList', 'name': 'mList'}], 'throws': ['UnknownMotorException']}), ('setPosition', {'name': 'setPosition', 'decorator': '', 'return': 'void', 'params': [{'decorator': 'none', 'type': 'MotorGoalPosition', 'name': 'goal'}], 'throws': ['UnknownMotorException', ',', 'HardwareFailedException', ',', 'CollisionException']}), ('setSyncPosition', {'name': 'setSyncPosition', 'decorator': '', 'return': 'void', 'params': [{'decorator': 'none', 'type': 'MotorGoalPositionList', 'name': 'listGoals'}], 'throws': ['UnknownMotorException', ',', 'HardwareFailedException']}), ('setSyncVelocity', {'name': 'setSyncVelocity', 'decorator': '', 'return': 'void', 'params': [{'decorator': 'none', 'type': 'MotorGoalVelocityList', 'name': 'listGoals'}], 'throws': ['UnknownMotorException', ',', 'HardwareFailedException']}), ('setSyncZeroPos', {'name': 'setSyncZeroPos', 'decorator': '', 'return': 'void', 'params': [], 'throws': ['UnknownMotorException', ',', 'HardwareFailedException']}), ('setVelocity', {'name': 'setVelocity', 'decorator': '', 'return': 'void', 'params': [{'decorator': 'none', 'type': 'MotorGoalVelocity', 'name': 'goal'}], 'throws': ['UnknownMotorException', ',', 'HardwareFailedException']}), ('setZeroPos', {'name': 'setZeroPos', 'decorator': '', 'return': 'void', 'params': [{'decorator': 'none', 'type': 'string', 'name': 'name'}], 'throws': ['UnknownMotorException', ',', 'HardwareFailedException']})])}, {'name': 'JointMotorPublish', 'methods': OrderedDict([ ('motorStates', {'name': 'motorStates', 'decorator': '', 'return': 'void', 'params': [ {'decorator': 'none', 'type': 'MotorStateMap', 'name': 'mstateMap'} ], 'throws': 'nothing' }) ]) } ], 'types': [ {'type': 'exception', 'name': 'HardwareFailedException', 'content': '\n string what;\n '}, {'type': 'exception', 'name': 'OutOfRangeException', 'content': '\n string what;\n '}, {'type': 'exception', 'name': 'UnknownMotorException', 'content': '\n string what;\n '}, {'type': 'exception', 'name': 'CollisionException', 'content': '\n string what;\n '}, {'type': 'struct', 'name': 'MotorState', 'structIdentifiers': [{'type': 'float', 'identifier': 'pos'}, {'type': 'float', 'identifier': 'vel'}, {'type': 'float', 'identifier': 'power'}, {'type': 'string', 'identifier': 'timeStamp'}, {'type': 'int', 'identifier': 'p'}, {'type': 'int', 'identifier': 'v'}, {'type': 'bool', 'identifier': 'isMoving'}, {'type': 'int', 'identifier': 'temperature'}]}, {'type': 'dictionary', 'content': 'string,MotorState', 'name': 'MotorStateMap'}, {'type': 'struct', 'name': 'MotorParams', 'structIdentifiers': [{'type': 'string', 'identifier': 'name'}, {'type': 'byte', 'identifier': 'busId'}, {'type': 'float', 'identifier': 'minPos'}, {'type': 'float', 'identifier': 'maxPos'}, {'type': 'float', 'identifier': 'maxVelocity'}, {'type': 'float', 'identifier': 'zeroPos'}, {'type': 'float', 'identifier': 'stepsRange'}, {'type': 'float', 'identifier': 'maxDegrees'}, {'type': 'bool', 'identifier': 'invertedSign'}, {'type': 'float', 'identifier': 'offset'}, {'type': 'float', 'identifier': 'unitsRange'}]}, {'type': 'sequence', 'typeSequence': 'MotorParams', 'name': 'MotorParamsList'}, {'type': 'struct', 'name': 'BusParams', 'structIdentifiers': [{'type': 'string', 'identifier': 'handler'}, {'type': 'string', 'identifier': 'device'}, {'type': 'int', 'identifier': 'numMotors'}, {'type': 'int', 'identifier': 'baudRate'}, {'type': 'int', 'identifier': 'basicPeriod'}]}, {'type': 'struct', 'name': 'MotorGoalPosition', 'structIdentifiers': [{'type': 'string', 'identifier': 'name'}, {'type': 'float', 'identifier': 'position'}, {'type': 'float', 'identifier': 'maxSpeed'}]}, {'type': 'sequence', 'typeSequence': 'MotorGoalPosition', 'name': 'MotorGoalPositionList'}, {'type': 'struct', 'name': 'MotorGoalVelocity', 'structIdentifiers': [{'type': 'string', 'identifier': 'name'}, {'type': 'float', 'identifier': 'velocity'}, {'type': 'float', 'identifier': 'maxAcc'}]}, {'type': 'sequence', 'typeSequence': 'MotorGoalVelocity', 'name': 'MotorGoalVelocityList'}, {'type': 'sequence', 'typeSequence': 'string', 'name': 'MotorList'}], 'sequences': [ {'name': 'RoboCompJointMotor/MotorParamsList', 'type': 'sequence', 'typeSequence': 'MotorParams'}, {'name': 'RoboCompJointMotor/MotorGoalPositionList', 'type': 'sequence', 'typeSequence': 'MotorGoalPosition'}, {'name': 'RoboCompJointMotor/MotorGoalVelocityList', 'type': 'sequence', 'typeSequence': 'MotorGoalVelocity'}, {'name': 'RoboCompJointMotor/MotorList', 'type': 'sequence', 'typeSequence': 'string'} ], 'simpleSequences': [ {'name': 'RoboCompJointMotor', 'strName': 'MotorParamsList'}, {'name': 'RoboCompJointMotor', 'strName': 'MotorGoalPositionList'}, {'name': 'RoboCompJointMotor', 'strName': 'MotorGoalVelocityList'}, {'name': 'RoboCompJointMotor', 'strName': 'MotorList'} ], 'structs': [ {'name': 'RoboCompJointMotor/MotorState', 'type': 'struct', 'structIdentifiers': [ ['float', 'pos'], ['float', 'vel'], ['float', 'power'], ['string', 'timeStamp'], ['int', 'p'], ['int', 'v'], ['bool', 'isMoving'], ['int', 'temperature'] ] }, {'name': 'RoboCompJointMotor/MotorParams', 'type': 'struct', 'structIdentifiers': [ ['string', 'name'], ['byte', 'busId'], ['float', 'minPos'], ['float', 'maxPos'], ['float', 'maxVelocity'], ['float', 'zeroPos'], ['float', 'stepsRange'], ['float', 'maxDegrees'], ['bool', 'invertedSign'], ['float', 'offset'], ['float', 'unitsRange'] ] }, {'name': 'RoboCompJointMotor/BusParams', 'type': 'struct', 'structIdentifiers': [ ['string', 'handler'], ['string', 'device'], ['int', 'numMotors'], ['int', 'baudRate'], ['int', 'basicPeriod'] ] }, {'name': 'RoboCompJointMotor/MotorGoalPosition', 'type': 'struct', 'structIdentifiers': [ ['string', 'name'], ['float', 'position'], ['float', 'maxSpeed'] ] }, {'name': 'RoboCompJointMotor/MotorGoalVelocity', 'type': 'struct', 'structIdentifiers': [ ['string', 'name'], ['float', 'velocity'], ['float', 'maxAcc'] ] } ], 'simpleStructs': [ {'name': 'RoboCompJointMotor', 'strName': 'MotorState'}, {'name': 'RoboCompJointMotor', 'strName': 'MotorParams'}, {'name': 'RoboCompJointMotor', 'strName': 'BusParams'}, {'name': 'RoboCompJointMotor', 'strName': 'MotorGoalPosition'}, {'name': 'RoboCompJointMotor', 'strName': 'MotorGoalVelocity'} ], 'filename': '/opt/robocomp/interfaces/IDSLs/JointMotor.idsl' }) self.assertNestedDictEqual(c, ref, ignored_keys=['filename']) # test for cached query d = self.factory.from_file("JointMotor.idsl") self.assertIs(c, d) def test_factory_cdsl(self): # TODO: Use a better cdsl example than this g = self.factory.from_file(os.path.join(RESOURCES_DIR, "customstatemachinecpp.cdsl")) ref = cf.ComponentFacade({ 'options': [], 'name': 'testcomp', 'imports': [], 'recursiveImports': [], 'language': 'cpp', 'statemachine_path': 'gamestatemachine.smdsl', 'statemachine_visual': False, 'innermodelviewer': False, 'gui': ['Qt', 'QWidget'], 'rosInterfaces': [], 'iceInterfaces': [], 'implements': [], 'requires': [], 'publishes': [], 'subscribesTo': [], 'usingROS': False, 'dsr': False, 'filename': os.path.join(RESOURCES_DIR, "customstatemachinecpp.cdsl")}) self.assertEqual(g, ref) # test for cached query h = self.factory.from_file(os.path.join(RESOURCES_DIR, "customstatemachinecpp.cdsl")) self.assertIs(g, h) def test_factory_cdsl_with_options(self): # TODO: Use a better cdsl example than this g = self.factory.from_file(os.path.join(RESOURCES_DIR, "componentwithoptions.cdsl")) ref = cf.ComponentFacade({ 'options': ['agmagent', 'innermodelviewer'], 'name': 'testcomp', 'imports': ['AGMCommonBehavior.idsl', 'AGMExecutive.idsl', 'AGMExecutiveTopic.idsl', 'AGMWorldModel.idsl'], 'recursiveImports': ['Planning.idsl'], 'language': 'cpp', 'statemachine_path': None, 'statemachine_visual': False, 'innermodelviewer': True, 'gui': ['Qt', 'QWidget'], 'rosInterfaces': [], 'iceInterfaces': [['AGMCommonBehavior', 'ice'], ['AGMExecutive', 'ice'], ['AGMExecutiveTopic', 'ice'], ['AGMWorldModel', 'ice']], 'implements': [['AGMCommonBehavior','ice']], 'requires': [['AGMExecutive', 'ice']], 'publishes': [], 'subscribesTo': [['AGMExecutiveTopic', 'ice']], 'usingROS': False, 'dsr': False, 'filename': os.path.join(RESOURCES_DIR, "componentwithoptions.cdsl")}) self.assertEqual(g, ref) # test for cached query h = self.factory.from_file(os.path.join(RESOURCES_DIR, "componentwithoptions.cdsl")) self.assertIs(g, h) # def test_factory_jcdsl(self): # # TODO: Use a better cdsl example than this # g = self.factory.from_file(os.path.join(RESOURCES_DIR, "jsoncomp.jcdsl")) # self.assertCountEqual(g, { # 'options': ['agmagent', 'innermodelviewer'], # 'name': 'testcomp', # 'imports': ['AGMCommonBehavior.idsl', # 'AGMExecutive.idsl', # 'AGMExecutiveTopic.idsl', # 'AGMWorldModel.idsl'], # 'recursiveImports': ['Planning.idsl'], # 'language': 'cpp', # 'statemachine': None, # 'statemachine_visual': False, # 'innermodelviewer': True, # 'gui': ['Qt', 'QWidget'], # 'rosInterfaces': [], # 'iceInterfaces': ['AGMCommonBehavior', # 'AGMExecutive', # 'AGMExecutiveTopic', # 'AGMWorldModel'], # 'implements': ['AGMCommonBehavior'], # 'requires': ['AGMExecutive'], # 'publishes': [], # 'subscribesTo': ['AGMExecutiveTopic'], # 'usingROS': False, # 'filename': os.path.join(RESOURCES_DIR, "jsoncomp.jcdsl")}) # # test for cached query # h = self.factory.from_file(os.path.join(RESOURCES_DIR, "jsoncomp.jcdsl")) # self.assertIs(g, h) def test_factory_special_cases(self): # valid idsl without path a = self.factory.from_file("JointMotor.idsl") b = self.factory.from_file("JointMotor.idsl") self.assertEqual(a,b) # Not valid idsl without path self.assertRaises(IOError, self.factory.from_file,"NotAnIdsl.idsl") # None as path self.assertEqual(self.factory.from_file(None), None) # invalid dsl type from file extension self.assertRaises(ValueError, self.factory.from_string,"asdafafsdfasfsdfasdff", "ppsl") # invalid dsl type from file extension self.assertRaises(ParseException, self.factory.from_string, "this is not a valid string for the parser", "idsl") def assertFilesSame(self, sFName1, sFName2): text1 = open(os.path.join(self.tempdir, sFName1), 'rb').read() text2 = open(os.path.join(self.tempdir, sFName2), 'rb').read() self.assertEqual(text1, text2)
import sys sys.path.append('/opt/robocomp/python') import cog def A(): cog.out('<@@<') def Z(): cog.out('>@@>') def TAB(): cog.out('<TABHERE>') from dsl_parsers.dsl_factory import DSLFactory from dsl_parsers.parsing_utils import getNameNumber, gimmeIDSL, communicationIsIce, IDSLPool includeDirectories = theIDSLPaths.split('#') component = DSLFactory().from_file(theCDSL, include_directories=includeDirectories) sm = DSLFactory().from_file(component['statemachine']) if component == None: print('Can\'t locate', theCDSLs) sys.exit(1) pool = IDSLPool(theIDSLs, includeDirectories) def replaceTypeCPP2Python(t): t = t.replace('::','.') t = t.replace('string', 'str') return t ]]] [[[end]]]
import sys sys.path.append('/opt/robocomp/python') import cog def A(): cog.out('<@@<') def Z(): cog.out('>@@>') def TAB(): cog.out('<TABHERE>') from dsl_parsers.dsl_factory import DSLFactory from dsl_parsers.parsing_utils import getNameNumber, IDSLPool, communicationIsIce includeDirectories = theIDSLPaths.split('#') component = DSLFactory().from_file(theCDSL, include_directories=includeDirectories) pool = IDSLPool(theIDSLs, includeDirectories) REQUIRE_STR = """ <TABHERE># Remote object connection for <NORMAL> <TABHERE>try: <TABHERE><TABHERE>proxyString = ic.getProperties().getProperty('<NORMAL><NUM>Proxy') <TABHERE><TABHERE>try: <TABHERE><TABHERE><TABHERE>basePrx = ic.stringToProxy(proxyString) <TABHERE><TABHERE><TABHERE><LOWER><NUM>_proxy = <NORMAL>Prx.uncheckedCast(basePrx) <TABHERE><TABHERE><TABHERE>mprx["<NORMAL>Proxy<NUM>"] = <LOWER><NUM>_proxy <TABHERE><TABHERE>except Ice.Exception: <TABHERE><TABHERE><TABHERE>print('Cannot connect to the remote object (<NORMAL>)', proxyString) <TABHERE><TABHERE><TABHERE>#traceback.print_exc()
def main(): parser = MyParser( description= 'This application create components files from cdsl files or .ice from idsl\n' '\ta) to generate code from a CDSL file: ' + sys.argv[0].split('/')[-1] + ' INPUT_FILE.CDSL OUTPUT_PATH\n' + '\tb) to generate a new CDSL file: ' + sys.argv[0].split('/')[-1] + ' NEW_COMPONENT_DESCRIPTOR.CDSL', formatter_class=argparse.RawTextHelpFormatter) parser.add_argument("-I", "--include_dirs", nargs='*', help="Include directories", action=FullPaths, default=[]) parser.add_argument("-d", '--diff', dest='diff', choices=DIFF_TOOLS, action='store') parser.add_argument("input_file", help="The input dsl file") parser.add_argument("output_path", nargs='?', help="The path to put the files") args = parser.parse_args() if args.output_path is None: if args.input_file.endswith(".cdsl"): generateDummyCDSL(args.input_file) generateDummySMDSL("statemachine.smdsl") sys.exit(0) else: print(args.output_path, args.input_file) print(parser.error("No output path with non .cdsl file")) sys.exit(-1) inputFile = args.input_file outputPath = args.output_path sys.path.append('/opt/robocomp/python') new_existing_files = {} if inputFile.endswith(".cdsl"): component = DSLFactory().from_file( inputFile, includeDirectories=args.include_dirs) imports = ''.join([imp + '#' for imp in component['imports']]) # verification pool = IDSLPool(imports, args.include_dirs) interface_list = component['requires'] + component[ 'implements'] + component['subscribesTo'] + component['publishes'] for interface_required in interface_list: interface_required = interface_required if isinstance( interface_required, str) else interface_required[0] if not pool.moduleProviding(interface_required): raise rcExceptions.InterfaceNotFound(interface_required, pool.interfaces()) if component['language'].lower( ) == 'cpp' or component['language'].lower() == 'cpp11': # # Check output directory # if not os.path.exists(outputPath): create_directory(outputPath) # Create directories within the output directory try: create_directory(outputPath + "/bin") create_directory(outputPath + "/etc") create_directory(outputPath + "/src") except: print('There was a problem creating a directory') sys.exit(1) pass # # Generate regular files # files = [ 'CMakeLists.txt', 'DoxyFile', 'README-STORM.txt', 'README.md', 'etc/config', 'src/main.cpp', 'src/CMakeLists.txt', 'src/CMakeListsSpecific.txt', 'src/commonbehaviorI.h', 'src/commonbehaviorI.cpp', 'src/genericmonitor.h', 'src/genericmonitor.cpp', 'src/config.h', 'src/specificmonitor.h', 'src/specificmonitor.cpp', 'src/genericworker.h', 'src/genericworker.cpp', 'src/specificworker.h', 'src/specificworker.cpp', 'src/mainUI.ui' ] specificFiles = [ 'src/specificworker.h', 'src/specificworker.cpp', 'src/CMakeListsSpecific.txt', 'src/mainUI.ui', 'src/specificmonitor.h', 'src/specificmonitor.cpp', 'README.md', 'etc/config' ] for f in files: ofile = outputPath + '/' + f if f in specificFiles and os.path.exists(ofile): print('Not overwriting specific file "' + ofile + '", saving it to ' + ofile + '.new') new_existing_files[os.path.abspath( ofile)] = os.path.abspath(ofile) + '.new' ofile += '.new' ifile = "/opt/robocomp/share/robocompdsl/templateCPP/" + f if f != 'src/mainUI.ui' or component['gui'] is not None: print('Generating', ofile) run = "cog.py -z -d -D theCDSL=" + inputFile + " -D theIDSLs=" + imports + ' -D theIDSLPaths=' + '#'.join( args.include_dirs) + " -o " + ofile + " " + ifile run = run.split(' ') ret = Cog().main(run) if ret != 0: print('ERROR') sys.exit(-1) replaceTagsInFile(ofile) # # Generate interface-dependent files # for ima in component['implements']: im = ima if type(im) != type(''): im = im[0] if communicationIsIce(ima): for f in ["SERVANT.H", "SERVANT.CPP"]: ofile = outputPath + '/src/' + im.lower( ) + 'I.' + f.split('.')[-1].lower() print('Generating ', ofile, ' (servant for', im + ')') # Call cog run = "cog.py -z -d -D theCDSL=" + inputFile + " -D theIDSLs=" + imports + ' -D theIDSLPaths=' + '#'.join( args.include_dirs ) + " -D theInterface=" + im + " -o " + ofile + " " + "/opt/robocomp/share/robocompdsl/templateCPP/" + f run = run.split(' ') ret = Cog().main(run) if ret != 0: print('ERROR') sys.exit(-1) replaceTagsInFile(ofile) for imp in component['subscribesTo']: im = imp if type(im) != type(''): im = im[0] if communicationIsIce(imp): for f in ["SERVANT.H", "SERVANT.CPP"]: ofile = outputPath + '/src/' + im.lower( ) + 'I.' + f.split('.')[-1].lower() print('Generating ', ofile, ' (servant for', im + ')') # Call cog theInterfaceStr = im if type(theInterfaceStr) == type([]): theInterfaceStr = str(';'.join(im)) run = "cog.py -z -d -D theCDSL=" + inputFile + " -D theIDSLs=" + imports + ' -D theIDSLPaths=' + '#'.join( args.include_dirs ) + " -D theInterface=" + theInterfaceStr + " -o " + ofile + " " + "/opt/robocomp/share/robocompdsl/templateCPP/" + f #print(run run = run.split(' ') ret = Cog().main(run) if ret != 0: print('ERROR') sys.exit(-1) replaceTagsInFile(ofile) elif component['language'].lower() == 'python': # # Check output directory # if not os.path.exists(outputPath): create_directory(outputPath) # Create directories within the output directory try: create_directory(outputPath + "/etc") create_directory(outputPath + "/src") except: print('There was a problem creating a directory') sys.exit(1) pass needStorm = False for pub in component['publishes']: if communicationIsIce(pub): needStorm = True for sub in component['subscribesTo']: if communicationIsIce(sub): needStorm = True # # Generate regular files # files = [ 'CMakeLists.txt', 'DoxyFile', 'README-STORM.txt', 'README.md', 'etc/config', 'src/main.py', 'src/genericworker.py', 'src/specificworker.py', 'src/mainUI.ui' ] specificFiles = [ 'src/specificworker.py', 'src/mainUI.ui', 'README.md', 'etc/config' ] for f in files: if f == 'src/main.py': ofile = outputPath + '/src/' + component['name'] + '.py' else: ofile = outputPath + '/' + f if f in specificFiles and os.path.exists(ofile): print('Not overwriting specific file "' + ofile + '", saving it to ' + ofile + '.new') new_existing_files[os.path.abspath( ofile)] = os.path.abspath(ofile) + '.new' ofile += '.new' ifile = "/opt/robocomp/share/robocompdsl/templatePython/" + f ignoreFile = False if f == 'src/mainUI.ui' and component['gui'] is None: ignoreFile = True if f == 'CMakeLists.txt' and component['gui'] is None: ignoreFile = True if f == 'README-STORM.txt' and needStorm == False: ignoreFile = True if not ignoreFile: print('Generating', ofile) run = "cog.py -z -d -D theCDSL=" + inputFile + " -D theIDSLs=" + imports + ' -D theIDSLPaths=' + '#'.join( args.include_dirs) + " -o " + ofile + " " + ifile run = run.split(' ') ret = Cog().main(run) if ret != 0: print('ERROR') sys.exit(-1) replaceTagsInFile(ofile) if f == 'src/main.py': os.chmod(ofile, os.stat(ofile).st_mode | 0o111) # # Generate interface-dependent files # for imp in component['implements'] + component['subscribesTo']: if type(imp) != type(''): im = imp[0] else: im = imp if communicationIsIce(imp): for f in ["SERVANT.PY"]: ofile = outputPath + '/src/' + im.lower( ) + 'I.' + f.split('.')[-1].lower() print('Generating', ofile, ' (servant for', im + ')') # Call cog run = "cog.py -z -d -D theCDSL=" + inputFile + " -D theIDSLs=" + imports + ' -D theIDSLPaths=' + '#'.join( args.include_dirs ) + " -D theInterface=" + im + " -o " + ofile + " " + "/opt/robocomp/share/robocompdsl/templatePython/" + f run = run.split(' ') ret = Cog().main(run) if ret != 0: print('ERROR') sys.exit(-1) replaceTagsInFile(ofile) else: print('Unsupported language', component['language']) if component['usingROS'] == True: for imp in component['imports']: generateROSHeaders(imp, outputPath + "/src", component, args.include_dirs) # Code to launch diff tool on .new files to be compared with their old version if args.diff is not None: diff_tool, _ = get_diff_tool(prefered=args.diff) print( "Executing diff tool for existing files. Close if no change is needed." ) for o_file, n_file in new_existing_files.items(): if not filecmp.cmp(o_file, n_file): print([diff_tool, o_file, n_file]) try: subprocess.call([diff_tool, o_file, n_file]) except KeyboardInterrupt as e: print( "Comparasion interrupted. All files have been generated. Check this .new files manually:" ) for o_file2, n_file2 in new_existing_files.items(): if not filecmp.cmp(o_file2, n_file2): print("%s %s" % (o_file2, n_file2)) break except Exception as e: print("Exception trying to execute %s" % (diff_tool)) print(e.message) else: print("Binary equal files %s and %s" % (o_file, n_file)) elif inputFile.endswith(".idsl"): # idsl = IDSLParsing.fromFileIDSL(inputFile) print('Generating ICE file ', outputPath) # Call cog run = "cog.py -z -d" + " -D theIDSL=" + inputFile + ' -D theIDSLPaths=' + '#'.join( args.include_dirs ) + " -o " + outputPath + " /opt/robocomp/share/robocompdsl/TEMPLATE.ICE" run = run.split(' ') ret = Cog().main(run) if ret != 0: print('ERROR') sys.exit(-1) replaceTagsInFile(outputPath)
def generarH(idslFile, imported): idsl = DSLFactory().from_file(idslFile) try: os.system("rm -f " + output_path + "/" + idsl['module']['name'] + "ROS/msg/__init__.py") os.system("rm -f " + output_path + "/" + idsl['module']['name'] + "ROS/srv/__init__.py") except KeyError: print("No module found in %s"%idsl_file) for imp in idsl['structs']+idsl['sequences']: if imp['type'] in ['struct','sequence']: for f in [ "SERVANT.MSG"]: ofile = output_path + "/" + imp['name'] + "." + f.split('.')[-1].lower() print('Generating', ofile, ' (servant for', idslFile.split('.')[0].lower() + ')') ofile_dir = os.path.dirname(ofile) if not os.path.exists(ofile_dir): os.makedirs(ofile_dir) # Call cog run = "cog.py -z -d" + ' -D theIDSLPaths=' + '#'.join(include_directories) + " -D structName=" + imp['name'] + " -D theIDSL=" + idslFile + " -o " + ofile + " " + "/opt/robocomp/share/robocompdsl/templateCPP/" + f run = run.split(' ') ret = Cog().main(run) if ret != 0: print('ERROR') sys.exit(-1) replaceTagsInFile(ofile) commandCPP = "/opt/ros/melodic/lib/gencpp/gen_cpp.py " + ofile + " -Istd_msgs:/opt/ros/melodic/share/std_msgs/msg -I" + idsl['name'] + "ROS:" + output_path commandPY = "/opt/ros/melodic/lib/genpy/genmsg_py.py " + ofile + " -Istd_msgs:/opt/ros/melodic/share/std_msgs/msg -I" + idsl['name'] + "ROS:" + output_path for impo in imported: if not impo == idsl['module']['name']+"ROS": commandCPP = commandCPP + " -I" + impo + ":" + output_path commandPY = commandPY + " -I" + impo + ":" + output_path if not os.path.exists(output_path): create_directory(output_path) commandCPP = commandCPP + " -p " + idsl['name'] + "ROS -o " + output_path + "/" + idsl['name'] + "ROS -e /opt/ros/melodic/share/gencpp" commandPY = commandPY + " -p " + idsl['name'] + "ROS -o " + output_path + "/" + idsl['name'] + "ROS/msg" if comp['language'].lower() == 'cpp': os.system(commandCPP) else: os.system(commandPY) try: fileInit = open(output_path + "/" + idsl['name'] + "ROS/msg/__init__.py", 'a') fileInit.write("from ._"+imp['name']+" import *\n") fileInit.close() except: pass for imp in idsl['interfaces']: for ima in [comp['implements']+comp['requires']]: im = ima if type(im) != type(''): im = im[0] if not communication_is_ice(ima) and im == imp['name']: for method in imp['methods'].values(): if 'params' in method: if len(method['params']) == 2: for f in [ "SERVANT.SRV"]: ofile = output_path + "/" + method['name'] + "." + f.split('.')[-1].lower() print('Generating', ofile, ' (servant for', idslFile.split('.')[0].lower() + ')') # Call cog run = "cog.py -z -d" + ' -D theIDSLPaths=' + '#'.join(include_directories) + " -D methodName=" + method['name'] + " -D theIDSL=" + idslFile + " -o " + ofile + " " + "/opt/robocomp/share/robocompdsl/templateCPP/" + f run = run.split(' ') ret = Cog().main(run) if ret != 0: print('ERROR') sys.exit(-1) replaceTagsInFile(ofile) commandCPP = "/opt/ros/melodic/lib/gencpp/gen_cpp.py " + ofile + " -Istd_msgs:/opt/ros/melodic/share/std_msgs/msg -Istd_srvs:/opt/ros/melodic/share/std_srv/cmake/../srv -I" + idsl['module']['name'] + "ROS:" + output_path commandPY = "/opt/ros/melodic/lib/genpy/gensrv_py.py " + ofile + " -Istd_msgs:/opt/ros/melodic/share/std_msgs/msg -Istd_srvs:/opt/ros/kinetic/share/std_srv/cmake/../srv -I" + idsl['module']['name'] + "ROS:" + output_path for impo in imported: if not impo == idsl['module']['name']+"ROS": commandCPP = commandCPP + " -I" + impo + ":" + output_path commandPY = commandPY + " -I" + impo + ":" + output_path if not os.path.exists(output_path): create_directory(output_path) commandCPP = commandCPP + " -p " + idsl['module']['name'] + "ROS -o " + output_path + "/" + idsl['module']['name'] + "ROS -e /opt/ros/melodic/share/gencpp/cmake/.." commandPY = commandPY + " -p " + idsl['module']['name'] + "ROS -o " + output_path + "/" + idsl['module']['name'] + "ROS/srv" if comp['language'].lower() == 'cpp': os.system(commandCPP) else: os.system(commandPY) try: fileInit = open(output_path + "/" + idsl['module']['name'] + "ROS/srv/__init__.py", 'a') fileInit.write("from ._"+method['name']+" import *\n") fileInit.close() except: pass else: print("error: ROS service with incorrect number of parameters. ROS only supports remote procedure calls of the form: void method(type inVar, out type outVar);") for param in enumerate(method['params']): print(param[0], '-->', param[1]) sys.exit(-1) else: print("error: service without params. Form is: void method(type inVar, out type outVar);") sys.exit(-1) os.system("touch " + output_path + "/" + idsl['module']['name'] + "ROS/__init__.py") return idsl['module']['name']+"ROS"