zoukankan      html  css  js  c++  java
  • 用python实现一个按需生成用于vim跳转的tags文件的小程序

    初学python,找个有用的来练手。选定了一个我早就想做的让vim按需生成tags跳转文件的小程序。

    vim的tags用于跳转的好处自是不用多说,但是如何生成tags确实困扰我的一大问题,用VS的都知道,VS会为每个解决方案生成一个ncb文件用于自动提示,相当于tags的功能,这个ncb文件很智能,它会根据你所包含的头文件来自动处理。这样,你只需包含一个头文件,就可以出现该头文件相关的自动提示了。

    但是vim就没有像VS这么智能了,目前我的做法就是在某个目录下调用ctags,然后加上递归参数,这样的缺点就是会生成一个很大的tags文件,里面很多都是项目根本没用到的头文件的tags。为了改善这种情况,需要有一个按所用到的头文件来生成tags的方法,让ctags按需生成tags。

    ctags本身是支持从一个文件中读入需要生成tags的文件列表的,因此剩下的问题就是如何找到项目所用到的所有相关的C++文件,然后让ctags从这些文件中生成tags。这就是我拿来练手的小程序了。

    python的好处就是不用像C++那样考虑那么多不相关的细节,专注于你想做的。代码如下,应该还算精简吧。有更好的方法不妨评论分享下,:)

    # -*- coding: utf8 -*-  
    # by absolute8511 2010-12-04
    import os,sys
    from os import path
    import string,re
    
    #在系统头文件目录下查找系统头文件,可以自行添加头文件路径
    def findsysinclude(filename,includepath):
        if filename==None:
            return None
        sysincludepath = ['/usr/include/','/usr/include/c++/4.4/',
                '/usr/lib/gcc/i486-linux-gnu/4.4/include/','/usr/include/c++/4.4/i486-linux-gnu/']   #系统头文件目录
        includepath += sysincludepath
        for onepath in includepath:
            if path.isfile(onepath+filename):
                return onepath+filename
        print 'Not found: '+filename
        return None
    
    #读取用户传入的头文件路径参数
    args = sys.argv
    print args
    retest = re.compile(r'\.cpp$|\.c$|\.h$|\.hpp$|\.cc$',re.IGNORECASE)
    cppfiles = []
    #查找用户项目路径下的所有源文件
    for root,dirs,files in os.walk(os.getcwd()):
        oldlen = len(cppfiles)
        cppfiles += filter(lambda x:retest.search(x)<>None,files)        #过滤非C/C++文件
        for index in range(oldlen,len(cppfiles)):
            cppfiles[index] = root + '/' + cppfiles[index];
    
    oldstdout = sys.stdout
    sys.stdout= logfile = open('maketags.log','w')
    
    print 'total cpp files: ' + str(len(cppfiles))
    includetest = re.compile(r'\s*#include\s*((<(?P<sysincludefile>.*?)>)|("(?P<userincludefile>.*?)"))')  ## *?代表不贪婪匹配
    
    #对每个C++源文件,查找它包含的头文件以及它的头文件所包含的头文件,以次递归直到全部包含
    #由于已经遍历过用户目录了,因次只需要再把系统头文件加近来即可
    for cppfile in cppfiles:
        try:
            fp = open(cppfile,'r')
            print 'finding in file: '+cppfile
            for line in fp:
                result = includetest.search(line)   #正则匹配头文件
                if result <> None:
                    print 'Matched include line is:'+result.group()
                    tmp = findsysinclude(result.group('sysincludefile'),args[1:])
                    tmp2 = findsysinclude(result.group('userincludefile'),args[1:]) #用户头文件也去找系统目录
                    if tmp<>None and cppfiles.count(tmp)==0:
                        cppfiles += [tmp]
                        print 'Added sys files: '+tmp
                    # tmp2 = path.abspath(path.dirname(cppfile)+'/'+result.group('userincludefile'))
                    if tmp2<>None and cppfiles.count(tmp2)==0:
                        cppfiles += [tmp2]
                        print 'Added user files: '+tmp2
        finally:
            fp.close()
    try:
        filelist = open('python_tags_filelist','w')
        filelist.writelines('\n'.join(cppfiles))
    finally:
        filelist.close()
    
    print 'total cpp and include files:'+str(len(cppfiles))
    # print 'after delete duplicate files: ' + str(len(set(cppfiles)))
    sys.stdout = oldstdout
    logfile.close()
    
    os.system('ctags --c++-kinds=+p --fields=+iaS --extra=+q -L python_tags_filelist')
    

  • 相关阅读:
    leetcode 279. Perfect Squares
    leetcode 546. Remove Boxes
    leetcode 312. Burst Balloons
    leetcode 160. Intersection of Two Linked Lists
    leetcode 55. Jump Game
    剑指offer 滑动窗口的最大值
    剑指offer 剪绳子
    剑指offer 字符流中第一个不重复的字符
    leetcode 673. Number of Longest Increasing Subsequence
    leetcode 75. Sort Colors (荷兰三色旗问题)
  • 原文地址:https://www.cnblogs.com/absolute8511/p/1896671.html
Copyright © 2011-2022 走看看