Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
 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
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
    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))
Ejemplo n.º 9
0
 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)
Ejemplo n.º 10
0
    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))
Ejemplo n.º 11
0
    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
Ejemplo n.º 12
0
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')
Ejemplo n.º 13
0
    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