脚本将命名空间添加到C ++文件

所以我有巨大的代码库需要有一个名称空间添加到它。 我想用grep,xargs和sed把命名空间添加到所有源文件中

但是我的技能还没有达到标准。 理想的情况下

namespace foo { 

在包含所有内容后添加,在.h文件的#endif之后添加'}'。

对于.cpp文件,在全部包含之后添加'using namespace foo'就足够了。

我一直在搞sed,但还没有走得很远。

任何帮助,将不胜感激。 谢谢!

这不是一件容易的事。 有问题的事情包括

  • 你不想放在你的新命名空间内的东西,比如
    • 构造像language "C" { C-stuff }
    • 转发不属于你的类的声明。 如果使用一些也不使用名称空间的外部程序包,则这会花费n倍的时间。
  • 甚至找到在哪里放置namespace Foo {和关闭'}'可以是艰难的。
    • 除了那些不属于你的东西之外,你还想附上前面的声明。
    • 你通常想把文件中的任何东西都包含在一对括号中,除了像language C这样的东西。
    • 维护程序员(如果你的代码已经足够长)将会对代码做各种不好的事情。 他们会在类或函数内部,类和函数之间,任何地方提出声明,但是顶部使得脚本变得容易。
    • 你不希望双重嵌套的东西。 令人惊讶的是,这样做很容易。
    • 出于各种原因,有些人把标题末尾看似无关紧要的东西放在一边。 这可能是一个特别讨厌的问题。
    • 如果你决定试图封装每个类,struct和枚举,你将不得不弄清楚声明的起点在哪里。 你想包装template声明,如果有的话,当然doxygen注释等。
    • 发现一个班的结束可以是讨厌的。 人们有这种讨厌的倾向,把不匹配的大括号放在注释和字符串中。

祝你好运! 一个脚本将花费半个多小时的时间来写。 这将花费比重写所有代码少得多的时间。 我建议你使用比sed更强大的东西。 Perl,python和ruby是三个不错的选择。

这让我一半:

 #!/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 "$@"; do processFile "$fn"; done 

nb,文件必须是unix换行格式