将命名空间添加到C++文件的脚本
所以我有巨大的代码库需要添加一个名称空间。我想用grep,xargs & sed将命名空间添加到所有的源文件中...将命名空间添加到C++文件的脚本
但我的技能没有达到标准。 理想
namespace foo
{
将被添加后,所有的包括,并且在.h文件的#ENDIF后“}”补充。
对于.cpp文件,在所有包含之后添加'using namespace foo'就足够了。
我一直在搞sed,但还没有走得很远。
任何帮助,将不胜感激。谢谢!
这不是一件容易的事。的事情,使问题包括
- 东西,你不希望你的新的命名空间内放置诸如
- 结构,如中不属于自己的类
language "C" { C-stuff }
- 正向声明。如果你使用一些也不使用命名空间的外部软件包,这会比以前困难得多。
- 结构,如中不属于自己的类
- 即使找到在哪里放置
namespace Foo {
和结束'}'可能会很艰难。- 你确实想包含前向声明,除了那些不属于你的声明。
- 您通常希望在文件范围内包含任何涉及一对大括号的内容,例如
language C
之类的内容。 - 维护程序员(如果你的代码已经足够长)会为你的代码做各种不好的事情。他们会在类或函数内部,类和函数之间,任何地方提出声明,但顶部使脚本变得容易。
- 你不想双重嵌套的东西。这很容易做到。
- 由于各种原因,有些人在标题的末尾放置了看似无关的东西。这可能是一个特别讨厌的问题。
- 如果您决定试图封装每个类,struct和枚举,您将必须找出声明的起始位置。你想包装
template
声明,如果有的话,当然还有doxygen注释等等。 - 寻找课程的结束可能只是令人讨厌。人们有这种令人讨厌的倾向,把不匹配的大括号放在注释和字符串中。
祝你好运!一个脚本需要花费半个多小时才能写出来。这将比重写所有代码花费更少的时间。我建议你使用比sed更强大的东西。 Perl,python和ruby是三个不错的选择。
我结束了手动转换... – anio
这让我半路上:
#!/bin/sh
NAMESPACE=my_namespace
for x in $(find . -name "*.h"); do
sed -i "$(grep -n "^#" $x | tail -2 | head -1 | sed 's/:.*//')a\\\nnamespace $NAMESPACE {\n" $x
sed -i "$(($(grep -n "^#" $x | tail -1 | sed 's/:.*//')-1))a} // namespace $NAMESPACE\n" $x
done
for x in $(find . -name "*.cpp"); do
sed -i "$(grep -n "#include" $x | tail -1 | sed 's/:.*//')a\\\nnamespace $NAMESPACE {\n" $x
echo >> $x
echo "} // namespace $NAMESPACE" >> $x
done
它主要定位在H文件中的一个,但最后预处理指令,并增加了命名空间存在。它会在最后一个预处理器指令之前产生命名空间(我假设我的h文件末尾有一个#endif
)。如果情况并非如此,则可以相应地调整脚本。
在cpp的情况下,我寻找最后的包含来打开命名空间并关闭它在文件的末尾。
这并不完美,但面对100多个文件,它使工作更容易。
注意,这并没有考虑到结束后卫#endif
的线路,但是将它们包裹在namespace {};
似乎没有任何伤害。
根据您的喜好取消注释行。
#!/usr/bin/env bash
namespace="namespace m {"
pad=" "
function processFile {
# dos2unix "$1"
local fn=$1
local tmp="$1.tmp"
echo "Processing '$fn'"
rm -f "$tmp"
local -i skipping=1
local regSkip="^(#include.*|#pragma.*|//.*|)"'$'
local line
while IFS= read -r line
do
if ((skipping)); then
if [[ $line =~ $regSkip ]]; then :
else skipping=0; echo "$namespace" >> "$tmp"
fi
echo "$line" >> "$tmp"
else
echo "$pad$line" >> "$tmp"
fi
done < "$1"
echo "$line" >> "$tmp"
echo "};" >> "$tmp"
mv -f "$fn" "$fn.ori"
# optionally reformat
astyle --options='e:\git\sfink.ini' < "$tmp" > "$fn" && rm "$tmp"
# else just move
# mv -f "$tmp" "$fn"
}
# for fn in $(find . -name '*.h'); do processFile "$fn"; done
# for fn in $(find . -name '*.cpp'); do processFile "$fn"; done
for fn in "[email protected]"; do processFile "$fn"; done
注:另,文件必须使用UNIX换行符格式
我推荐你使用脚本语言如Ruby,正则表达式用,来完成这项工作。根据您的需求和一些Ruby示例的Google搜索,您可以在30分钟到1小时内完成此脚本。你可以使用http://rubular.com/来测试你的正则表达式。 FWIW,我只写了一个Ruby脚本来查找所有.hpp和.cpp文件之间的名称空间/模块依赖关系 - 使用正则表达式花费了大约一个小时的时间。 – kfmfe04
sed是将正则表达式用作处理文本的主要工具的早期程序之一。祝你们好运。 – shellter