简单的脚本或命令*替换* stray" \\ n"用" \ n"

时间:2014-08-18 11:02:57

标签: c regex perl c-preprocessor

好吧,我明白这个主题的标题听起来有点胡言乱语......所以我会尽可能清楚地解释它......

这与之前的帖子(已经过验证的方法)有关: multipass a source code to cpp

- 它基本上要求cpp在启动gcc编译构建过程之前预处理一次代码

采用上一篇文章的示例代码:

#include <stdio.h>
#define DEF_X   #define X           22

int main(void)
{
    DEF_X
    printf("%u", X);

    return 1;
}

现在,为了能够在任何地方自由插入DEF_X,我们需要添加换行符

这不起作用:

#define DEF_X                    \
                #define X    22

这仍然无效,但更有可能:

#define DEF_X   \n                    \
                #define X    22

如果我们让上面的后者工作,感谢C的自由格式语法和常量字符串多行连接,就C / C ++而言,它可以在任何地方工作:

"literal_str0" DEF_X "literal_str1"

现在当cpp预处理时:

# 1 "d:/Projects/Research/tests/test.c"
# 1 "<command-line>"
# 1 "d:/Projects/Research/test/test.c"
# 1 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/stdio.h" 1 3
# 19 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/stdio.h" 3
# 1 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/_mingw.h" 1 3
# 32 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/_mingw.h" 3=
# 33 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/_mingw.h" 3
# 20 "c:\\mingw\\bin\\../lib/gcc/mingw32/4.7.2/../../../../include/stdio.h" 2 3

ETC_ETC_ETC_IGNORED_FOR_BREVITY_BUT_LOTS_OF_DECLARATIONS


int main(void)
{
    \n #define X 22
    printf("%u", X);

    return 1;
}

我们在预处理文件中有一个迷路\ n。所以现在的问题是摆脱它......

现在,unix系统命令并不是我最强的套装。我已经在linux中编写了几十个软件包并编写了简单的bash脚本,只需输入多行命令(所以我不必每次都输入它们或者按下向上箭头并选择正确的命令继承)。所以我不知道流管道及其论点的细节。

话虽如此,我尝试了这些命令:

cpp $MY_DIR/test.c | perl -p -e 's/\\n/\n/g' > $MY_DIR/test0.c
gcc $MY_DIR/test0.c -o test.exe

它有效,它消除了那个迷路\ n。

哦,至于使用perl而不是sed,我对perl的正则表达式更加熟悉...它在我眼中更加一致。

无论如何,这会产生令人讨厌的副作用:在文件中吃掉任何\ n(即使在字符串文字中)...所以我需要一个脚本或一系列命令来:

删除\ n if:

  1. 如果它不在引号内 - 所以这不会被修改:&#34; hell0_there \ n&#34;
  2. 没有传递给函数调用(在参数列表中)
    • 这是安全的,因为人们永远不会传递单个\ n,它既不是关键字也不是标识符。
    • 如果我需要&#34; stringify&#34;使用\ n的表达式,我可以简单地调用函数宏QUOTE_VAR(标记)。以便封装所有必须被视为字符串的实例。
  3. 这应该包括所有应该替换的情况......至少对于我自己的编码惯例而言。

    实际上,如果我可以自己管理它,我会这样做...但我的正则表达式中的技能非常缺乏,只能用它来进行简单的替换。

1 个答案:

答案 0 :(得分:0)

更好的方法是替换\n,如果它出现在行的开头。

以下命令应该完成工作:

sed -e 's/\s*\\n/\n/g'

或发生在#

之前
sed -e 's/\\n\s*#/\n#/g'

或者您可以颠倒预处理的顺序,并在C预处理器之前使用您自己的工具替换DEF_X