2014-01-30 3 views
1

При использовании libclang, как исключить функцию из stdio.h?В libclang как исключить функции из stdio.h

Когда я использую источник ниже, чтобы собирать только определения функций, тогда я получаю все функции от stdio.h.

Я читал, что мы можем передавать аргументы типа -x c-header при создании индекса. Но делает ли этот способ аргументов, применимых в libclang.

tu = index.parse(self.filename, "-x 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

-x c-header переключатель командной строки используется для генерации precompiled headers, чтобы не исключать заголовки из блока перевода.

Я думаю, что правильным способом исключения функций из определенного файла было бы пропустить все узлы, находящиеся в нем во время посещения АСТ. Чтобы подробно остановиться на вашем примере, идея делает первый тест у посетителя, чтобы как можно скорее пропустить файл и не посещать все его подносы.

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.py (libclang «s питона API), но я думаю, что ваш пример следующим образом понятия C API, а не те, питона. Цитата из документации (выделено мной):

Этот модуль обеспечивает интерфейс к библиотеке индексирования Клана. Это низкоуровневый интерфейс к библиотеке индексирования, которая пытается напрямую сопоставить API Clang , будучи также «pythonic». Заметные отличия от C API являются: результаты

  • строки возвращаются в виде строки Python, не CXString объектов.

  • нулевые курсоры переведены на None.

  • Доступ к детским курсорам осуществляется через итерацию, а не посещение.

Хотя cindex.py связывает Cursor_visit к clang_visitChildren, она даже и не экспортировать CXChildVisitResult перечисления, а это означает, что вам нужно жёстко значения Break, Continue и Recurse. Питонический способ делать вещи состоит в итерации на дочерних узлах, возвращаемых методом Cursor.get_children(). Пример приведен в этих ответах SO (1, 2), которые вы можете адаптировать для фильтрации узлов на основе исходного файла.

Смежные вопросы