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