def _get_cf_struct(self, automaton, params): """ Provides declaration of structure to pack all control function (or maybe other) parameters as a single argument with help of it. :param automaton: Automaton object. :param params: Declaration objects list. :return: Declaration object. """ # todo: ensure proper ordering of structure parameters especially arrays, bit fields and so on. cache_identifier = '' for param in params: cache_identifier += str(param) if cache_identifier not in self._structures: struct_name = 'emg_struct_{}_{}'.format(automaton.process.name, str(automaton)) if struct_name in self._structures: raise KeyError('Structure name is not unique') decl = import_declaration('struct {} a'.format(struct_name)) for index in range(len(params)): decl.fields['arg{}'.format(index)] = params[index] decl.fields['signal_pending'] = import_declaration('int a') self._structures[cache_identifier] = [automaton.process.file, decl] else: decl = self._structures[cache_identifier][1] return decl
def new_method(*args, **kwargs): for test in method(*args, **kwargs): obj = import_declaration(test) # Test that it is parsed assert obj # Test that it is the same new_obj = import_declaration(obj.to_string('name')) # todo: Pretty names are different but I am not sure whether it correct or not assert obj == new_obj
def intf_collection(): collection = InterfaceCollection(logging, sortedcontainers.SortedDict()) usb_driver = Container('usb', 'driver') usb_driver.declaration = import_declaration('struct usb_driver driver') collection.set_intf(usb_driver) return collection
def intf_collection(): collection = InterfaceCollection() usb_driver = Container('usb', 'driver') usb_driver.declaration = import_declaration('struct usb_driver driver') collection.set_intf(usb_driver) return collection
def get_clean_declaration(c, desc, i): if "declaration" in desc: decl = import_declaration(desc["declaration"]) else: raise ValueError( "Provide declaration at the interface specification of '{}.{}'" .format(c, i)) return decl
def test_equality(): tests = [ 'int x', 'int *x', 'void x(void)', 'void *x(void)', 'void *x(void *)' ] for test in tests: obj = import_declaration(test) # Test that it is parsed assert obj assert obj.to_string('x') == test
def _import_label(self, name, dic): label = self.LABEL_CONSTRUCTOR(name) for att in (att for att in self.LABEL_ATTRIBUTES if att in dic): if self.LABEL_ATTRIBUTES[att]: attname = self.LABEL_ATTRIBUTES[att] else: attname = att setattr(label, attname, dic[att]) if label.declaration: label.declaration = import_declaration(label.declaration) return label
def __init__(self, name, declaration): self._name = name self._declaration = None self.use = 0 self.value = None self.declaration_files = sortedcontainers.SortedSet() self.initialization_file = None if not declaration: declaration = 'void f(void)' if isinstance(declaration, str): self._declaration = import_declaration(declaration) elif issubclass(type(declaration), Declaration): self._declaration = declaration else: raise ValueError( "Attempt to add variable {!r} without signature".format(name))
def _entry_point(self): self._logger.info( "Finally generate an entry point function {!r}".format( self._cmodel.entry_name)) cf = self._control_function(self._entry_fsa) if self._conf.get("self parallel model"): cf.declaration = import_declaration( "void *(*start_routine)(void *)") body = [ "pthread_t **thread;", "pthread_create_N(thread, 0, {}, 0);".format(cf.name), "pthread_join_N(thread, {});".format(cf.name) ] else: body = ['{}(0);'.format(cf.name)] if self._entry_fsa.process.file != self._cmodel.entry_file: self._cmodel.add_function_declaration(self._cmodel.entry_file, cf, extern=True) return self._cmodel.compose_entry_point(body)
def __init__(self, name, declaration=None): self._name = name self._declaration = None self.body = list() self.header_files = list() self.definition_file = None self.calls = sortedcontainers.SortedDict() self.called_at = sortedcontainers.SortedDict() self.declaration_files = sortedcontainers.SortedSet() if not declaration: declaration = 'void f(void)' if isinstance(declaration, str): self._declaration = import_declaration(declaration) elif isinstance(declaration, Declaration): self._declaration = declaration else: raise ValueError( "Attempt to add function {!r} without signature".format(name))
def __generate_insmod_process(self, source, inits, exits, kernel_initializations): self.logger.info( "Generate artificial process description to call Init and Exit module functions 'insmod'" ) ep = Process("insmod") ep.comment = "Initialize or exit module." ep.self_parallelism = False # Add subprocesses finally process = '' for i, pair in enumerate(inits): process += "<{0}>.(<init_failed_{1}>".format(pair[1], i) for j, pair2 in enumerate(exits[::-1]): if pair2[0] == pair[0]: break j = 1 for _, exit_name in exits[:j - 1:-1]: process += ".<{}>".format(exit_name) process += "|<init_success_{}>.".format(i) for _, exit_name in exits: process += "<{}>.".format(exit_name) # Remove the last dot process = process[:-1] process += ")" * len(inits) if kernel_initializations and inits: process += "<kernel_initialization>." \ "(<kerninit_success> | <kerninit_failed>.(" + process + "))" elif kernel_initializations and not inits: process += "<kernel_initialization>.(<kernel_initialization_success> | <kernel_initialization_fail>)" elif not inits and not kernel_initializations: raise NotImplementedError( "There is no both kernel initialization functions and module initialization " "functions") # This populates all actions parse_process(ep, process) ep.actions.populate_with_empty_descriptions() if len(kernel_initializations) > 0: body = ["int ret;"] label_name = 'emg_kernel_initialization_exit' # Generate kernel initializations for name, calls in kernel_initializations: for filename, func_name in calls: func = source.get_source_function(func_name, filename) if func: retval = not func.declaration.return_value == 'void' else: raise RuntimeError( "Cannot resolve function {!r} in file {!r}".format( name, filename)) new_name = self.__generate_alias(ep, func_name, filename, retval) statements = [] if retval: statements.extend([ "ret = {}();".format(new_name), "ret = ldv_post_init(ret);", "if (ret)", "\tgoto {};".format(label_name) ]) else: statements.append("{}();".format(new_name)) body.extend(statements) body.extend(["{}:".format(label_name), "return ret;"]) func = Function('emg_kernel_init', 'int emg_kernel_init(void)') func.body = body addon = func.define() ep.add_definition('environment model', 'emg_kernel_init', addon) ki_subprocess = ep.actions['kernel initialization'] ki_subprocess.statements = ["%ret% = emg_kernel_init();"] ki_subprocess.comment = 'Kernel initialization stage.' ki_subprocess.trace_relevant = True ki_success = ep.actions['ki_success'] ki_success.condition = ["%ret% == 0"] ki_success.comment = "Kernel initialization is successful." ki_failed = ep.actions['kerninit_failed'] ki_failed.condition = ["%ret% != 0"] ki_failed.comment = "Kernel initialization is unsuccessful." if len(inits) > 0: # Generate init subprocess for filename, init_name in inits: self.logger.debug("Found init function {!r}".format(init_name)) new_name = self.__generate_alias(ep, init_name, filename, True) init_subprocess = ep.actions[init_name] init_subprocess.comment = 'Initialize the module after insmod with {!r} function.'.format( init_name) init_subprocess.statements = [ "%ret% = {}();".format(new_name), "%ret% = ldv_post_init(%ret%);" ] init_subprocess.trace_relevant = True # Add ret label ep.add_label('ret', import_declaration("int label")) # Generate exit subprocess if len(exits) == 0: self.logger.debug("There is no exit function found") else: for filename, exit_name in exits: self.logger.debug("Found exit function {!r}".format(exit_name)) new_name = self.__generate_alias(ep, exit_name, filename, False) exit_subprocess = ep.actions[exit_name] exit_subprocess.comment = 'Exit the module before its unloading with {!r} function.'.format( exit_name) exit_subprocess.statements = ["{}();".format(new_name)] exit_subprocess.trace_relevant = True # Generate successful conditions for action in (a for a in ep.actions.filter(include={Block}) if str(a).startswith('init_success')): action.condition = ["%ret% == 0"] action.comment = "Module has been initialized." # Generate else branch for action in (a for a in ep.actions.filter(include={Block}) if str(a).startswith('init_failed')): action.condition = ["%ret% != 0"] action.comment = "Failed to initialize the module." return ep
def __import_entities(collection, sa, entities): def determine_category(e, decl): c = None if 'category' in e: c = e['category'] else: resolved = collection.resolve_interface_weakly(decl) if len(resolved) == 1: c = resolved[0].category return c while entities: entity = entities.pop() bt = entity["type"] if "value" in entity["description"] and isinstance( entity["description"]['value'], str): if is_not_null_function(bt, entity["description"]["value"]): category = entity["category"] if "category" in entity else None intfs = list( check_relevant_interface(collection, entity["type"], category, entity["root sequence"][-1])) if not intfs and isinstance( entity["type"], Pointer) and isinstance( entity["type"].points, Function): containers = collection.resolve_interface_weakly( entity['parent type'], category) for container in (c for c in containers if isinstance(c, StructureContainer)): if "{}.{}".format(container.category, entity["root sequence"] [-1]) not in collection.interfaces: identifier = entity["root sequence"][-1] elif "{}.{}".format(container.category, entity["type"].pretty_name ) not in collection.interfaces: identifier = entity["type"].pretty_name else: raise RuntimeError( "Cannot yield identifier for callback {!r} of category {!r}" .format(str(entity["type"]), container.category)) interface = Callback(container.category, identifier) interface.declaration = entity["type"] collection.set_intf(interface) container.field_interfaces[entity["root sequence"] [-1]] = interface intfs.append(interface) break for intf in intfs: intf.add_implementation(entity["description"]["value"], entity['type'], entity['path'], entity["root type"], entity["root value"], entity["root sequence"]) elif "value" in entity["description"] and isinstance( entity["description"]['value'], list): if isinstance(bt, Array): bt.size = len(entity["description"]['value']) for entry in entity["description"]['value']: if not entity["root type"]: new_root_type = bt else: new_root_type = entity["root type"] e_bt = bt.element new_sequence = list(entity["root sequence"]) new_sequence.append(entry['index']) new_desc = { "type": e_bt, "description": entry, "path": entity["path"], "parent type": bt, "root type": new_root_type, "root value": entity["root value"], "root sequence": new_sequence } category = determine_category(entity, e_bt) if category: new_desc["category"] = category entities.append(new_desc) elif isinstance(bt, Structure) or isinstance(bt, Union): for entry in entity["description"]['value']: if not entity["root type"] and not entity["root value"]: new_root_type = bt new_root_value = entity["description"]["value"] else: new_root_type = entity["root type"] new_root_value = entity["root value"] field = extract_name(entry['field']) # Ignore actually unions and structures without a name if field: e_bt = import_declaration(entry['field'], None) e_bt.add_parent(bt) new_sequence = list(entity["root sequence"]) new_sequence.append(field) new_desc = { "type": e_bt, "description": entry, "path": entity["path"], "parent type": bt, "root type": new_root_type, "root value": new_root_value, "root sequence": new_sequence } category = determine_category(entity, e_bt) if category: new_desc["category"] = category bt.fields[field] = e_bt entities.append(new_desc) else: raise NotImplementedError else: raise TypeError('Expect list or string')
def check_ast(given_ast, declarator, iint): try: probe_ast = copy.deepcopy(given_ast) cl = import_declaration(None, probe_ast) expr = cl.to_string(declarator) return expr, None except KeyError: if 'specifiers' in given_ast and 'category' in given_ast['specifiers'] and \ 'identifier' in given_ast['specifiers']: n = given_ast['specifiers']['identifier'] category = given_ast['specifiers']['category'] i = collection.get_intf("{}.{}".format(category, n)) if 'pointer' in given_ast['specifiers'] and given_ast[ 'specifiers']['pointer']: d = i.declaration.take_pointer.to_string(declarator) else: d = i.declaration.to_string(declarator) return d, i else: if check_function(given_ast) and 'specifiers' not in given_ast: parameter_declarations = [] for index, p in enumerate( given_ast['declarator'][0]['function arguments']): if isinstance(p, str): parameter_declarations.append(p) else: expr, i = check_ast(p, 'a', None) if iint and i: iint.set_param_interface(index, i) parameter_declarations.append(expr) if len(parameter_declarations) == 0: declarator += '(void)' else: declarator += '(' + ', '.join( parameter_declarations) + ')' declarator, i = check_ast(given_ast['return value type'], declarator, None) if iint and i: iint.rv_interface = i return declarator, None elif check_array(given_ast): array = given_ast['declarator'][-1]['arrays'].pop() size = array['size'] given_ast = reduce_level(given_ast) if not size: size = '' declarator += '[{}]'.format(size) return check_ast(given_ast, declarator, iint) elif 'pointer' in given_ast['declarator'][ -1] and given_ast['declarator'][-1]['pointer'] > 0: given_ast['declarator'][-1]['pointer'] -= 1 given_ast = reduce_level(given_ast) if check_array(given_ast) or check_function(given_ast): declarator = '(*' + declarator + ')' else: declarator = '*' + declarator return check_ast(given_ast, declarator, iint) else: raise NotImplementedError