Spaces:
Sleeping
Sleeping
import os, re | |
LANGUAGE_EXT_MAP = { | |
"C": ['c', 'h', 'cc'], | |
"C++": ['cpp', 'hpp', 'cxx', 'hxx', 'c++', 'h++'], | |
"Java": ['java'], | |
"Python": ['py', 'pyx'] | |
} | |
# 拆分一个commit下的diff,拆成多个文件的变更 | |
def split_to_file_diff(diff_code : str, preserve_ext_list : list = []) -> list: | |
# 定义正则表达式匹配 diff --git 行,并提取文件路径 | |
pattern = re.compile(r"diff --git (\S+) (\S+)") # 匹配 diff --git 行 | |
files = [] | |
current_diff_content = [] | |
current_file_a, current_file_b = None, None | |
preserve_ext_list = [f".{ext}" for ext in preserve_ext_list] | |
# 遍历每行 diff 数据 | |
for line in diff_code.splitlines(): | |
match = pattern.match(line) | |
if match: | |
# 如果是新的 diff --git 行,处理前一个 diff | |
if current_file_a and current_file_b: | |
# 获取文件扩展名 | |
ext_a = os.path.splitext(current_file_a)[1] | |
ext_b = os.path.splitext(current_file_b)[1] | |
# 只保留指定扩展名的文件 | |
if len(preserve_ext_list) == 0 or ext_a in preserve_ext_list and ext_b in preserve_ext_list: | |
files.append((current_file_a, current_file_b, '\n'.join(current_diff_content))) | |
# 更新当前文件路径 | |
current_file_a = match.group(1) | |
current_file_b = match.group(2) | |
current_diff_content = [line] # 重置当前的 diff 内容,包含当前行 | |
else: | |
if current_file_a and current_file_b: | |
current_diff_content.append(line) | |
# 处理最后一个 diff | |
if current_file_a and current_file_b: | |
ext_a = os.path.splitext(current_file_a)[1] | |
ext_b = os.path.splitext(current_file_b)[1] | |
if len(preserve_ext_list) == 0 or ext_a in preserve_ext_list and ext_b in preserve_ext_list: | |
files.append((current_file_a, current_file_b, '\n'.join(current_diff_content))) | |
return files | |
# 拆分一个change为多个变更点 | |
def split_to_section(file_diff : str) -> list: | |
# 使用正则表达式匹配@@区块和其中的变更内容 | |
# 正则匹配格式:以 @@ 开始,后接变更内容 | |
pattern = re.compile(r"@@.*?@@(\r?\n?)([\s\S]*?)(?=@@|\Z)", re.MULTILINE) | |
change_blocks = [] | |
# 匹配所有变更区块 | |
for match in pattern.finditer(file_diff): | |
# 获取变更内容 | |
block = match.group(0) | |
# 按行拆分变更内容 | |
change_blocks.append(block) | |
return change_blocks | |
if __name__ == "__main__": | |
# 测试用例 | |
diff = \ | |
"""diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c | |
index 71ba18efa15b..867664918715 100644 | |
--- a/drivers/net/bonding/bond_main.c | |
+++ b/drivers/net/bonding/bond_main.c | |
@@ -1543,9 +1543,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |
bond_set_carrier(bond); | |
if (USES_PRIMARY(bond->params.mode)) { | |
+ block_netpoll_tx(); | |
write_lock_bh(&bond->curr_slave_lock); | |
bond_select_active_slave(bond); | |
write_unlock_bh(&bond->curr_slave_lock); | |
+ unblock_netpoll_tx(); | |
} | |
pr_info("%s: enslaving %s as a%s interface with a%s link.\n", | |
@@ -1571,10 +1573,12 @@ err_detach: | |
if (bond->primary_slave == new_slave) | |
bond->primary_slave = NULL; | |
if (bond->curr_active_slave == new_slave) { | |
+ block_netpoll_tx(); | |
write_lock_bh(&bond->curr_slave_lock); | |
bond_change_active_slave(bond, NULL); | |
bond_select_active_slave(bond); | |
write_unlock_bh(&bond->curr_slave_lock); | |
+ unblock_netpoll_tx(); | |
} | |
slave_disable_netpoll(new_slave); | |
@@ -2864,9 +2868,12 @@ static int bond_slave_netdev_event(unsigned long event, | |
pr_info("%s: Primary slave changed to %s, reselecting active slave.\ | |
", | |
bond->dev->name, bond->primary_slave ? slave_dev->name : | |
"none"); | |
+ | |
+ block_netpoll_tx(); | |
write_lock_bh(&bond->curr_slave_lock); | |
bond_select_active_slave(bond); | |
write_unlock_bh(&bond->curr_slave_lock); | |
+ unblock_netpoll_tx(); | |
break; | |
case NETDEV_FEAT_CHANGE: | |
bond_compute_features(bond); | |
""" | |
# 提取所有变更块 | |
changes = split_to_file_diff(diff, ['c']) | |
for file_a, file_b, diff_content in changes: | |
print(f"a: {file_a}, b: {file_b}") | |
print(diff_content) | |
print("=" * 50) | |
change_blocks = split_to_section(changes[0][2]) | |
for idx, block in enumerate(change_blocks): | |
print(f"Change Block {idx + 1}:") | |
print(block) | |
print("-" * 50) | |