从补丁文件中去除 C 注释的方法

Posted

技术标签:

【中文标题】从补丁文件中去除 C 注释的方法【英文标题】:Method to strip C comments from patch files 【发布时间】:2012-05-11 17:12:01 【问题描述】:

我正在考虑尝试从我们的补丁文件中去除 C cmets,并查看了许多正则表达式,但如果我们从补丁中删除行 - 它会破坏它们。

您将如何编写正则表达式或 sed 命令来搜索差异补丁文件以查找 cmets 并用空格替换注释行。

这适用于 sed 正则表达式适用于 C 文件,但对于补丁我需要一些不同的东西:

sed '/^\/\*/,/\*\//d'

一个示例补丁摘录是:

@@ -382,7 +391,109 @@
        return len;
 

+/**********************************************************************************
+ * Some patch
+ * Author: Mcdoomington
+ * Do somethimg
+ * 
+ * fix me
+ **********************************************************************************/

有人有想法吗?

编辑:

使用此过滤器:

sed -e 's,^+ \*.*,+ \/\/Comment removed,' mypatch.patch > output


+/**********************************************************************************
+ //Comment removed
+ //Comment removed
+ //Comment removed

如何添加以 \ 结尾的 if 行以跳过它?

编辑:解决方案

虽然不是最干净的方式 - 我将 sed 与陪审团操纵的正则表达式一起使用。

sed -e '/[^\*\/]$/N;s,^+ \* .*,+ \* Comment removed,;' patch > output
sed -e '/[^\*\/]$/N;s,^+\\\* .*,+ \/\* Comment removed,;' patch > output

请注意,第二个命令可能有点过于贪婪,但出于清理 cmets 的目的 - 这行得通!

它是如何工作的:

1.) 第一个命令 要确定这是否是评论的结尾 /[^*/]$/ 确定它是否是 / 然后 N;s,^+\* .,+ /* 已删除评论,; ' 找到 +*(无论如何)并将其替换为 * 已删除评论。

2.) 第二个命令 要确定这是否是评论的结尾 /[^*/]$/ 确定它是否是 / 然后 N;s,^+\* .,+ /* 已删除评论,; ' 找到 + * (whatever) 并将其替换为 * Comment removed。

【问题讨论】:

补丁文件是进来的,还是你自己生成的?是要移动所有 cmets,还是只是在函数之间阻塞 cmets? 补丁文件已经创建,我正在寻找一种简单的方法来删除 cmets 或至少将它们清空。由于暂存环境,创建新补丁是一项艰巨的任务,它们的数量约为 30 多个。 有一点,正则表达式根本不够聪明或不够灵活,无法做你想做的事;这是其中一种情况。您需要能够识别/**/// 令牌并相应地解析文件。就个人而言,我只是手动破解我自己的过滤器来完成这样的工作;不应该超过几个小时。 【参考方案1】:

正则表达式很精彩,但没那么精彩。

我会在创建补丁之前删除 cmets。

如果你不能这样做,我会应用补丁。从修补和未修补的文件中删除 cmets,然后重新创建修补程序。

所以从 x.h 开始,我们将其编辑为 x1.h 并创建一个补丁:

diff -u x.h x1.h > patch

然后我们将补丁发布给拥有 x.h 的人。

cp x.h xnc.h
sed -e '/^\/\*/,/\*\//d' -i xnc.h
patch x.h patch
cp x.h xnc2.h
sed -e '/^\/\*/,/\*\//d' -i xnc2.h
diff -u xnc.h xnc2.h > patchnc

应该创建无评论补丁。

但如果我有修补和未修补的源代码树,那么

find unpatched -exec sed -e ':^/\*:,:\*/:d' -i "" \;
find patched -exec sed -e ':^/\*:,:\*/:d' -i "" \;
diff -urN unpatched patched > patch

【讨论】:

不幸的是,这是一个耗时的过程,您知道至少可以自动化其中大部分的方法吗? 您应该能够编写脚本。为什么不在制作补丁之前做呢? @mcdoomington:您希望删除所有 cmets,还是只删除补丁中出现的 cmets?你想对只影响部分块评论的补丁做什么?有 C 注释剥离程序(我写了几个;我不会是唯一的人),我倾向于修改补丁生成过程,以便新旧源没有创建补丁之前不需要的 cmets。 我同意它是可编写脚本的,您可以使用许多可用的工具来执行此操作。问题出在内核 src tarball 中的源文件上,然后是我通过它们的方式的问题 - 一些快速而肮脏的东西;)编辑:原因是这是针对 GPL 版本的 - 有人请求了材料并且它必须清洗。 所以你只需要用你的 sed 遍历两棵树,然后创建补丁【参考方案2】:

我刚刚使用了一个快速而肮脏的 hackjob,它使用了大多数 cmets 的罐头

sed -e '/[^\*\/]$/N;s,^+ \* .*,+ \* Comment removed,;' patch > output
sed -e '/[^\*\/]$/N;s,^+\\\* .*,+ \/\* Comment removed,;' patch > output

【讨论】:

【参考方案3】:

我不会使用正则表达式。一般来说,他们在一条线上工作。 您的文件将包含运行多行的 cmets。

我会用 C/C++ 或 Java 编写一个简单的解析器。

从状态 0 开始。

在状态 0 中,只需逐个字符读取(并输出),直到找到 /* 序列

然后切换到状态 1。

在状态 1 中,只需逐个字符读取(并且不要输出),直到找到 */ 序列为止

【讨论】:

以上是关于从补丁文件中去除 C 注释的方法的主要内容,如果未能解决你的问题,请参考以下文章

linux下补丁制作和使用方法

Windows 安装补丁的另外一种方法

linux之打补丁

pcapatchdbtask是啥

从邮件列表应用 git 补丁

linux查看补丁的方法