gpt4 book ai didi

python - get_includes 找不到标准库头文件

转载 作者:行者123 更新时间:2023-12-03 06:50:23 45 4
gpt4 key购买 nike

我正在玩弄 libclang 的 Python 绑定(bind)。目前,我正在尝试执行一些非常简单的任务,例如查找 C++ 文件中包含的所有 header 。我使用的代码如下:

from clang.cindex import Index

index = Index.create()
tu = index.parse("hello.cpp", args=["-std=c++14"])
for it in tu.get_includes():
print(it.include.name)
文件 hello.cpp如下:
#include <iostream>
#include <stdio.h>
#include "hello.h"

int main()
{
std::cout << "Hello world\n";
}
和文件 hello.h如下:
#include <list>
我以为上面的代码会打印 iostream , stdio.hhello.h ,也许 list如果考虑到传递包含,也许更多。但是,它只打印 ./hello.h ,公然忽略标准库头文件。
我在文档中找不到任何关于它是否是设计的东西。是设计使然吗?如果是这样,有什么方法可以实际获取文件中包含的所有标题 clang.cindex ,包括标准库的?

最佳答案

对于那些仍在寻找答案的人:

import sys
import os
from enum import Enum
from clang.cindex import Config, Index, CursorKind


Config.set_library_path(os.environ['CLANG_LIBRARY_PATH'])


# clang.cindex.TranslationUnit does not have all latest flags
# see: https://clang.llvm.org/doxygen/group__CINDEX__TRANSLATION__UNIT.html#gab1e4965c1ebe8e41d71e90203a723fe9
CXTranslationUnit_None = 0x0
CXTranslationUnit_DetailedPreprocessingRecord = 0x01
CXTranslationUnit_Incomplete = 0x02
CXTranslationUnit_PrecompiledPreamble = 0x04
CXTranslationUnit_CacheCompletionResults = 0x08
CXTranslationUnit_ForSerialization = 0x10
CXTranslationUnit_CXXChainedPCH = 0x20
CXTranslationUnit_SkipFunctionBodies = 0x40
CXTranslationUnit_IncludeBriefCommentsInCodeCompletion = 0x80
CXTranslationUnit_CreatePreambleOnFirstParse = 0x100
CXTranslationUnit_KeepGoing = 0x200
CXTranslationUnit_SingleFileParse = 0x400
CXTranslationUnit_LimitSkipFunctionBodiesToPreamble = 0x800
CXTranslationUnit_IncludeAttributedTypes = 0x1000
CXTranslationUnit_VisitImplicitAttributes = 0x2000
CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles = 0x4000
CXTranslationUnit_RetainExcludedConditionalBlocks = 0x8000


class IncludeForm(Enum):
Quoted = 0
AngleBracket = 1


class IncludeInfo:
def __init__(self, path, form, file=None):
self.path = path
self.form = form
self.file = file

def __str__(self):
open_bracket, close_bracket = ('<', '>') if self.form == IncludeForm.AngleBracket else ('"', '"')
return f'#include {open_bracket}{self.path}{close_bracket} // {self.file}'


default_parser_options = (
CXTranslationUnit_DetailedPreprocessingRecord | # needed for preprocessing parsing
CXTranslationUnit_SkipFunctionBodies | # for faster parsing
CXTranslationUnit_SingleFileParse | # don't parse include files recursively
CXTranslationUnit_RetainExcludedConditionalBlocks | # keep includes inside ifdef blocks
CXTranslationUnit_KeepGoing # don't stop on errors
)


def create_include_parser(options=default_parser_options):
def try_get_included_file(node):
try:
return node.get_included_file()
except:
return None

def parse_includes(file, args=None):
tu = index.parse(file, args=args, options=options)

for node in tu.cursor.get_children():
if node.kind == CursorKind.INCLUSION_DIRECTIVE:
yield IncludeInfo(
node.displayname,
IncludeForm.AngleBracket if list(node.get_tokens())[-1].spelling == '>' else IncludeForm.Quoted,
try_get_included_file(node)
)

index = Index.create()

return parse_includes


if __name__ == "__main__":
parse_includes = create_include_parser()

for file in sys.argv[1:]:
for include_info in parse_includes(file):
print(include_info)
对于这样的 C++ 文件:
#include <iostream>
// #include <vector>

#include "foo.h"

#ifdef _BAR
# include "bar.h"
#endif

#include "3rdparty/buzz.h"

int main() {
std::cout << "Hello, World!" << std::endl;
}
它将打印如下内容:
#include <iostream> // C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Tools\MSVC\14.16.27023\include\iostream
#include "foo.h" // data/example/app/foo.h
#include "bar.h" // None
#include "3rdparty/buzz.h" // None
您可以使用 args 传递其他编译器选项参数,例如传递额外的包含目录:
for include_info in parse_includes(file, args=['-Idata/example']):

关于python - get_includes 找不到标准库头文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33103684/

45 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com