Ejemplo n.º 1
0
def get_undefined_vars(nodes, resolved):
    """Get undefined variable.
    :param nodes: a list of dom nodes
    :param resolved: a set of names as strings that is assumed to be defined
    :return a set of names
    """
    result = set()
    for node in nodes:
        if domutil.is_element(node):
            if node.tagName == 'decl_stmt':
                _,var_name,_ = syntaxutil.parse_decl_stmt(node)
                resolved.add(var_name)
            elif node.tagName == 'expr':
                # in #ifdef, there may be `#elif defined(__sun)`
                if domutil.in_node(node, 'cpp:ifdef', level=2) or\
                    domutil.in_node(node, 'cpp:elif', level=2) or\
                    domutil.in_node(node, 'cpp:ifndef', level=2):
                    continue
                name_set = syntaxutil.parse_expr(node)
                for name in name_set:
                    # uint8_t, false, true, NULL
                    if sys.resolve_single(name):
                        continue
                    # here we find the undefined variable
                    if name not in resolved and name not in result:
                        result.add(name)
            elif node.tagName == 'for':
                init_node = domutil.get_first_child_by_tagname(node, 'init')
                if init_node:
                    _, var = syntaxutil.parse_for_init(init_node)
                    if var:
                        resolved.add(var)
            elif node.tagName == 'parameter_list':
                params = syntaxutil.parse_parameter_list(node)
                for _,name in params:
                    resolved.add(name)
            elif node.tagName == 'cpp:define':
                value_node = domutil.get_first_child_by_tagname(node, 'cpp:value')
                text = domutil.get_text_content(value_node)
                match = re.findall(r'([A-Z_]{2,})', text)
                for m in match:
                    if m not in resolved:
                        result.add(m)
            new_result = get_undefined_vars(node.childNodes, resolved | result)
            result.update(new_result)
    return result
Ejemplo n.º 2
0
def resolve_undefined_vars(nodes, resolved):
    """Get undefined variable. Resolve its type.
    :param nodes: a list of dom nodes
    :param resolved: a set of names as strings that is assumed to be defined
    :return {var: type, ...}
    """
    result = {}
    for node in nodes:
        if domutil.is_element(node):
            if node.tagName == 'decl_stmt':
                _,var_name,_ = syntaxutil.parse_decl_stmt(node)
                resolved.add(var_name)
            elif node.tagName == 'expr':
                # in #ifdef, there may be `#elif defined(__sun)`
                if domutil.in_node(node, 'cpp:ifdef', level=2) or\
                    domutil.in_node(node, 'cpp:elif', level=2) or\
                    domutil.in_node(node, 'cpp:ifndef', level=2):
                    continue
                name_set = syntaxutil.parse_expr(node)
                for name in name_set:
                    # uint8_t, false, true, NULL
                    if sys.resolve_single(name):
                        continue
                    # here we find the undefined variable
                    if name not in resolved and name not in result:
                        type_name = resolve_local_type(name, node)
                        if type_name:
                            result[name] = type_name
                        # if it is a global variable, do not print warning
                        elif not local.check_global_variable(name):
                            logger.warning('undefind variable ' + name + ' not resovled for local type.')
            elif node.tagName == 'for':
                init_node = domutil.get_first_child_by_tagname(node, 'init')
                if init_node:
                    _, var = syntaxutil.parse_for_init(init_node)
                    if var:
                        resolved.add(var)
            new_result = resolve_undefined_vars(node.childNodes, resolved | result.keys())
            result.update(new_result)
    return result