在libclang中如何从stdio.h中排除函数

时间:2014-01-30 19:15:27

标签: python header-files libclang

使用libclang时,如何从stdio.h中排除函数?

当我使用下面的源只收集函数定义时,我最终也从stdio.h获取所有函数。

我读过我们可以在创建索引时传递'-x c-header'类型的参数。但这种方式是否适用于libclang。

tu = index.parse(self.filename, "-x c-header")

在包含'c-header'参数后,它还要我填写'unsaved_files'数组,根据'cindex.py'中'解析'函数的定义。

def parse(self, path, args = [], unsaved_files = [], options = 0):

我不知道这样做的正确方法是什么。

def funcdefn_visitor(self, node, parent, userdata):
    if node.kind == clang.cindex.CursorKind.FUNCTION_DECL: #gives function definitions
        self.func_defn.append(clang.cindex.Cursor_displayname(node))
        self.func_defn_line_no.append(node.location.line)
        self.func_defn_col_no.append(node.location.column)
    print 'Found %s [line=%s, col=%s]' % (
        clang.cindex.Cursor_displayname(node),
        node.location.line,
        node.location.column)
    return 2 # means continue visiting recursively

index = clang.cindex.Index.create()

tu = index.parse(self.filename)
#-- link cursor visitor to call back to give function definitions
clang.cindex.Cursor_visit(
    tu.cursor,
    clang.cindex.Cursor_visit_callback(self.funcdefn_visitor),
    None)

1 个答案:

答案 0 :(得分:1)

-x c-header命令行开关用于生成precompiled headers,而不是从翻译单元中排除标题。

我认为从特定文件中排除函数的正确方法是在访问AST时跳过位于其中的所有节点。为了详细说明您的示例,我们的想法是在访问者中进行第一次测试,以尽早跳过该文件并避免访问其所有子节点。

def funcdefn_visitor(self, node, parent, userdata):

    # You might want to change the test here
    if node.location.file.endswith("/stdio.h"):
        print "Skipping 'stdio.h'"
        # Continue with next sibling
        return 1

    if node.kind == clang.cindex.CursorKind.FUNCTION_DECL: #gives function definitions
        self.func_defn.append(clang.cindex.Cursor_displayname(node))
        self.func_defn_line_no.append(node.location.line)
        self.func_defn_col_no.append(node.location.column)

    print 'Found %s [line=%s, col=%s]' % (
        clang.cindex.Cursor_displayname(node),
        node.location.line,
        node.location.column)

    # Continue visiting recursively
    return 2

index = clang.cindex.Index.create()

tu = index.parse(self.filename)
#-- link cursor visitor to call back to give function definitions
clang.cindex.Cursor_visit(
    tu.cursor,
    clang.cindex.Cursor_visit_callback(self.funcdefn_visitor),
    None)

现在我不是cindex.pylibclang的python API)的专家,但我认为你的例子遵循C API概念而不是python概念。引用文档(强调我的):

  

此模块提供Clang索引库的接口。它是一个   索引库的低级接口,它尝试匹配Clang   API直接同时也是“pythonic”。与C API有显着差异   是:

     
      
  • 字符串结果以Python字符串形式返回,而不是CXString对象。

  •   
  • null游标已转换为None。

  •   
  • 访问子游标是通过迭代而不是访问来完成的。

  •   

虽然cindex.pyCursor_visit绑定到clang_visitChildren,但它甚至不会导出CXChildVisitResult枚举,这意味着您需要对Break的值进行硬编码, ContinueRecurse。 pythonic的做事方式包括迭代子节点,由Cursor.get_children()方法返回。这些SO答案(12)中给出了一个示例,您可以根据源文件过滤掉节点。