使用Python自动更新(替换)C代码中头文件引用路径

在实际开发中,由于项目管理不善,经常会遇到代码路径变动的问题,如果是大改就更麻烦了,想要修改头文件引用路径只能手动修改或用工具批量。下面的代码可以根据头文件实际路径生成新路径并替换原来的路径,大大减少工作量。

#!/usr/bin/python2.7  
# -*- coding: utf-8 -*-  

# 适用场景:该脚本适用于代码都在同一个目录下的头文件引用路径更新
# 原理是获取当前目录下所有的代码文件,找到引用语句,根据语句中的头文件名查找目录中文件所在的位置生成新的路径,替换原来的路径
# 该脚本并不会修改#include< >
# #include< > 引用的是编译器的类库路径里面的头文件,忽略这种情况
import re
import io
import os

def list_all_c_files(rootdir):
    """ 获取目录下所有c代码路径 """
    _files = {}
    list = os.listdir(rootdir) #列出文件夹下所有的目录与文件,不包括子目录
    for i in range(0,len(list)):
           path = os.path.join(rootdir,list[i])
           if os.path.isdir(path):#如果是文件夹,递归调用
                _files.update(list_all_c_files(path))
           if os.path.isfile(path):#如果是c文件,路径加入到字典里
                # 判断扩展名,
                (filepath,tempfilename) = os.path.split(path)
                (filename,extension) = os.path.splitext(tempfilename)
                if extension == '.h' or extension == '.c' or extension == '.cpp':
                    _files[list[i]] = path
    return _files

def update_include_path(codePath):
    # 获取目录下所有c代码路径
    _fs = list_all_c_files(codePath)

    curWorkPath = os.getcwd()
    for file in _fs.values():
        print '------------%s Start------------'%file
        
        isUpdate = False
        file_data = ""

        # c++头文件引用语句匹配规则
        # 这里没有做 #include <> 这种形式的匹配,
        # #include< > 引用的是编译器的类库路径里面的头文件,忽略这种情况
        reg = "#include (\")(.*)(\")"

        # 读取
        with io.open(file, "rb") as f:
            # 遍历当前文件所有行
            for line in f:
                if re.match(reg, line):
                    # 去掉最后一个双引号
                    index = line.rfind("\"")
                    headerFile = line[0:index]
                    # 查找路径中的倒数第一个斜杠,如果找不到,查找倒数第一个双引号
                    index = headerFile.rfind("/")
                    if index == -1:
                        index = headerFile.rfind("\"")
                    # 截取路径中的头文件名
                    headerFile = headerFile[(index+1):]
                    # 判断该头文件在不在当前目录下
                    if headerFile in _fs:
                        # 先获取该头文件的绝对路径,通过绝对路径转换成相对路径,以确保代码正确
                        abspath = os.path.abspath(_fs[headerFile])
                        # 匹配出当前文件的所在路径文件夹
                        index = file.rfind("\\")
                        hfPath = file[0:index].replace("\\", "/")
                        # 工作目录切换到该文件夹
                        os.chdir(hfPath)
                        # 使用头文件的绝对路径与当前路径对比出头文件的相对路径,并把反斜杠替换成正斜杠
                        relpath = os.path.relpath(abspath).replace("\\", "/")
                        # 匹配出包含语句中头文件的路径并替换
                        regSearch = re.search("(\")(.*)(\")", line)
                        if regSearch != None and regSearch.group() != "\"%s\""%relpath:
                            print 'old line %s'%line
                            line = line.replace(regSearch.group(), "\"%s\""%relpath)
                            print 'new line %s'%line
                            isUpdate = True
                        # 替换完以后切换回初始工作目录
                        os.chdir(curWorkPath)
                         
                file_data += line
        if isUpdate:
            # 将新文件内容写入文件
            with io.open(file,"wb") as f:
                f.write(file_data)
        else:
            print '--------------------------No Change--------------------------'

        print '------------%s End------------'%file

if __name__ == '__main__':
    update_include_path('./codePath')

 

Guess you like

Origin blog.csdn.net/suibianlasa/article/details/86526175