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
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