본문 바로가기

Language/python

python-clang : 인클루드 파일 파싱 하기 예제

cindex-includes.py


#===- cindex-includes.py - cindex/Python Inclusion Graph -----*- python -*--===#
#
#                     The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
#===------------------------------------------------------------------------===#

"""
A simple command line tool for dumping a Graphviz description (dot) that
describes include dependencies.
"""

def main():
    import sys
    from clang.cindex import Index

    from optparse import OptionParser, OptionGroup

    parser = OptionParser("usage: %prog [options] {filename} [clang-args*]")
    parser.disable_interspersed_args()
    (opts, args) = parser.parse_args()
    if len(args) == 0:
        parser.error('invalid number arguments')

    # FIXME: Add an output file option
    out = sys.stdout

    index = Index.create()
    tu = index.parse(None, args)
    if not tu:
        parser.error("unable to load input")

    # A helper function for generating the node name.
    def name(f):
        if f:
            return "\"" + f.name + "\""

    # Generate the include graph
    out.write("digraph G {\n")
    for i in tu.get_includes():
        line = "  ";
        if i.is_input_file:
            # Always write the input file as a node just in case it doesn't
            # actually include anything. This would generate a 1 node graph.
            line += name(i.include)
        else:
            line += '%s->%s' % (name(i.source), name(i.include))
        line += "\n";
        out.write(line)
    out.write("}\n")

if __name__ == '__main__':
    main()



sample.cpp


class MyClass{
public:
    void init(int a, int b);
    int loopAlot();
private:
    int var1, var2;
};

sample.h


#include "sample.h"
#include "test.h"
#include 

void MyClass::init(int a, int b){
    var1 = a;
    var2 = b;
}

int MyClass::loopAlot(){
    int res = this->var1 + var2;
    for(int i=0; ivar1; ++i){
        res = res + this->var2;
    }
    return res;
}


결과물

ppiazi@ppiazi-VirtualBox:~/work/clang-example$ python3 cindex-includes.py sample.cpp


digraph G {
  "sample.cpp"->"./sample.h"
  "sample.cpp"->"/usr/include/stdio.h"
  "/usr/include/stdio.h"->"/usr/include/x86_64-linux-gnu/bits/libc-header-start.h"
  "/usr/include/x86_64-linux-gnu/bits/libc-header-start.h"->"/usr/include/features.h"
  "/usr/include/features.h"->"/usr/include/stdc-predef.h"
  "/usr/include/features.h"->"/usr/include/x86_64-linux-gnu/sys/cdefs.h"
  "/usr/include/x86_64-linux-gnu/sys/cdefs.h"->"/usr/include/x86_64-linux-gnu/bits/wordsize.h"
  "/usr/include/x86_64-linux-gnu/sys/cdefs.h"->"/usr/include/x86_64-linux-gnu/bits/long-double.h"
  "/usr/include/features.h"->"/usr/include/x86_64-linux-gnu/gnu/stubs.h"
  "/usr/include/x86_64-linux-gnu/gnu/stubs.h"->"/usr/include/x86_64-linux-gnu/gnu/stubs-64.h"
  "/usr/include/stdio.h"->"/usr/include/clang/6.0.0/include/stddef.h"
  "/usr/include/stdio.h"->"/usr/include/x86_64-linux-gnu/bits/types.h"
  "/usr/include/x86_64-linux-gnu/bits/types.h"->"/usr/include/x86_64-linux-gnu/bits/wordsize.h"
  "/usr/include/x86_64-linux-gnu/bits/types.h"->"/usr/include/x86_64-linux-gnu/bits/typesizes.h"
  "/usr/include/stdio.h"->"/usr/include/x86_64-linux-gnu/bits/types/__FILE.h"
  "/usr/include/stdio.h"->"/usr/include/x86_64-linux-gnu/bits/types/FILE.h"
  "/usr/include/stdio.h"->"/usr/include/x86_64-linux-gnu/bits/libio.h"
  "/usr/include/x86_64-linux-gnu/bits/libio.h"->"/usr/include/x86_64-linux-gnu/bits/_G_config.h"
  "/usr/include/x86_64-linux-gnu/bits/_G_config.h"->"/usr/include/clang/6.0.0/include/stddef.h"
  "/usr/include/x86_64-linux-gnu/bits/_G_config.h"->"/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h"
  "/usr/include/x86_64-linux-gnu/bits/libio.h"->"/usr/include/clang/6.0.0/include/stdarg.h"
  "/usr/include/stdio.h"->"/usr/include/x86_64-linux-gnu/bits/stdio_lim.h"
  "/usr/include/stdio.h"->"/usr/include/x86_64-linux-gnu/bits/sys_errlist.h"
}


  •  총 세개의 헤더를 포함하였음.
  • 실제 파일이 없는 "test.h" 는 포함되지 않음.
  • <stdio.h> 의 경우 하부에서 포함하는 모든 헤더들이 포함됨.