将include语句保留在预处理输出中

时间:2016-07-14 10:54:23

标签: c c-preprocessor

假设我有一个文件将TARGET定义转换为FEATURE定义:

// File options.h
#ifdef TARGET_A
#define FEATURE_X
#endif
#ifdef TARGET_B
#define FEATURE_Y
#endif
struct foo {
    int a;
    int b;
};

我有一堆文件ifdef'ed FEATURE定义:

// File foo.c
#include "options.h"
#ifdef FEATURE_X
int x;
#endif
#ifdef FEATURE_Y
int y;
#endif

然后,我如何预处理foo.c以便处理include语句,但是将其保存在文件中?

类似的东西:

$ some-pre-process-tool -DTARGET_A -I. -o foo.pp.c foo.c
$ cat foo.pp.c
// File foo.c
#include "options.h"
int x;
$

3 个答案:

答案 0 :(得分:2)

首先,为什么要在预处理代码中保留#include?您是打算再次通过预处理器运行它,还是在阅读结果时有用?

您可以使用gcc标志-Wp,-dI获得所需内容。此处记录了-dIhttps://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-dI-1113

请注意,输出文件还会包含您所包含文件中的#include及其所有子#include

答案 1 :(得分:0)

有更好的方法可以做到这一点 - 但我最终编写了一个小包装脚本来处理来自cpp的输出

#!/usr/bin/env ruby
# File: pp.rb

f = open("| cpp -C -dI #{ARGV.join(" ")}")

# First line
f.gets =~ /"([^"]+)"/
file = $1
ll = []

# Skip "invisible" includes
while l = f.gets
    if l =~ /^#\s*1\s*"#{file}"$/
        ll = []
    else
        ll.push l
    end
end

inc = false
skip = false
skip_line = nil
ll.each do |l|
    if inc and l =~ /^#\s*(\d+)\s*"#{file}"$/
        inc = false
        skip = true
        skip_line = $1.to_i
    elsif skip and l =~ /^#\s*(\d+)\s*"#{file}"/
        inc = false
        if $1.to_i == skip_line + 1
            skip = false
        end
    elsif skip
        inc = false
    elsif l =~ /\s*#\s*include/
        puts l
        inc = true
    elsif l =~ /^#\s*(\d+)\s*"#{file}"/
    else
        inc = false
        puts l
    end
end

我可以像这样调用:

$ ./pp.rb -DTARGET_A -I.  foo.c > foo.pp.c
$ cat foo.pp.c
// File foo.c
#include "options.h"

int x;

答案 2 :(得分:-1)

我担心预处理文件只能在char或字符串文字内部以及辅助行记录的开头包含#