def p_connector_defn(t): '''connector_defn : from connector_end_type ID SEMI to connector_end_type ID SEMI | from connector_end_type ID template STRING SEMI to connector_end_type ID SEMI | from connector_end_type ID SEMI to connector_end_type ID template STRING SEMI | from connector_end_type ID template STRING SEMI to connector_end_type ID template STRING SEMI''' from_template = None to_template = None from_type = t[2] if len(t) == 9: to_type = t[6] elif len(t) == 11: if t[4] == 'template': from_template = t[5] to_type = t[8] else: to_type = t[6] to_template = t[9] else: assert len(t) == 13 from_template = t[5] to_type = t[8] to_template = t[11] t[0] = Connector(name=None, from_type=from_type, to_type=to_type, from_template=from_template, to_template=to_template, filename=t.lexer.filename, lineno=t.lexer.lineno)
def test_inclusion(self): ''' Test whether we can add a template that includes another template. ''' # Setup some custom templates. tmp = self.mkdtemp() with open(os.path.join(tmp, 'parent'), 'wt') as f: f.write('/*- include "child" -*/\n') with open(os.path.join(tmp, 'child'), 'wt') as f: f.write('/* nothing */\n') # Create template store and add a custom path. templates = Templates('seL4') templates.add_root(tmp) # Invent a fake connector and connection. This is necessary for adding # the template. c = Connector('foo', 'Event', 'Event', from_template='parent') c1 = Connection(c, 'bar', [], []) # Add the custom template. included = templates.add(c, c1) # Now we should have noted the included files. self.assertSetEqual( set([os.path.join(tmp, 'child'), os.path.join(tmp, 'parent')]), included)
def test_mutual_recursion(self): ''' We should trigger an exception when including ourselves, even when it is via an intermediary. ''' # Setup some custom templates. tmp = self.mkdtemp() with open(os.path.join(tmp, 'greatgrandparent'), 'wt') as f: f.write('/*- include "grandparent" -*/\n') with open(os.path.join(tmp, 'grandparent'), 'wt') as f: f.write('/*- include "parent" -*/\n') with open(os.path.join(tmp, 'parent'), 'wt') as f: f.write('/*- include "child" -*/\n') with open(os.path.join(tmp, 'child'), 'wt') as f: f.write('/*- include "greatgrandparent" -*/\n') # Create template store and add a custom path. templates = Templates('seL4') templates.add_root(tmp) # Invent a fake connector and connection. This is necessary for adding # the template. c = Connector('foo', 'Event', 'Event', from_template='greatgrandparent') c1 = Connection(c, 'bar', [], []) # Add the custom template. with self.assertRaises(TemplateError): templates.add(c, c1)
def _lift_connector_defn(location, *args): # Defaults from_template = None to_template = None from_threads = 1 to_threads = 1 from_hardware = False to_hardware = False def thread_count(value): ''' Validate a number of threads for a connector end. ''' try: v = int(value) if v < 0 or v != value: raise ValueError except ValueError: raise ParseError('illegal thread value \'%s\'' % value, location) return v if args[0] == 'hardware': from_hardware = True args = args[1:] from_type, args = args[0], args[1:] # The loops in this function are a little ad hoc, but are justified by # 'template' arguments appearing as raw strings and 'threads' arguments as # raw numbers. The motivation is to allow these two arguments to appear in # either order. See the grammar for more details. while isinstance(args[0], numbers.Number) or args[0].startswith('"'): if isinstance(args[0], numbers.Number): from_threads, args = thread_count(args[0]), args[1:] else: assert args[0].startswith('"') from_template, args = args[0][1:-1], args[1:] if args[0] == 'hardware': to_hardware = True args = args[1:] to_type, args = args[0], args[1:] while len(args) > 0: if isinstance(args[0], numbers.Number): to_threads, args= thread_count(args[0]), args[1:] else: assert args[0].startswith('"'), 'unexpected child of ' \ 'connector definition (bug in grammar?)' to_template, args = args[0][1:-1], args[1:] return Connector(from_type=from_type, to_type=to_type, from_template=from_template, to_template=to_template, from_threads=from_threads, to_threads=to_threads, from_hardware=from_hardware, to_hardware=to_hardware, location=location)
def _lift_connector_decl(location, *args): if len(args) == 1: return args[0] id, connector_defn = args if connector_defn.from_multiple: from_type = '%ss' % connector_defn.from_type else: from_type = connector_defn.from_type if connector_defn.to_multiple: to_type = '%ss' % connector_defn.to_type else: to_type = connector_defn.to_type return Connector(id, from_type, to_type, connector_defn.from_template, connector_defn.to_template, connector_defn.from_threads, connector_defn.to_threads, connector_defn.from_hardware, connector_defn.to_hardware, location=location)
def test_self_inclusion(self): ''' Test that a template that includes itself triggers an exception. ''' # Setup some custom templates. tmp = self.mkdtemp() with open(os.path.join(tmp, 'parent'), 'wt') as f: f.write('/*- include "parent" -*/\n') # Create template store and add a custom path. templates = Templates('seL4') templates.add_root(tmp) # Invent a fake connector and connection. This is necessary for adding # the template. c = Connector('foo', 'Event', 'Event', from_template='parent') c1 = Connection(c, 'bar', [], []) # Add the custom template. with self.assertRaises(TemplateError): templates.add(c, c1)
def test_double_inclusion(self): ''' We should be able to include the same template twice without triggering an exception. ''' # Setup some custom templates. tmp = self.mkdtemp() with open(os.path.join(tmp, 'parent'), 'wt') as f: f.write('/*- include "child" -*/\n' '/*- include "child" -*/\n') with open(os.path.join(tmp, 'child'), 'wt') as f: f.write('/* nothing */\n') # Create template store and add a custom path. templates = Templates('seL4') templates.add_root(tmp) # Invent a fake connector and connection. This is necessary for adding # the template. c = Connector('foo', 'Event', 'Event', from_template='parent') c1 = Connection(c, 'bar', [], []) # Add the custom template. templates.add(c, c1)