当我编辑C源文件时,我经常发现自己想要知道哪些C预处理条件在给定行有效,即在
中#if FOO
/* FOO is active */
#elif BAR
/* here only BAR is active */
#else
/* here NOT BAR is active */
#endif
#if BAZ
#if ZAP
/* Here BAZ and ZAP are active */
#endif
/* Only BAZ active */
#else
/* NOT BAZ */
#endif
/* Nothing active */
你明白了。我写了一个小的perl脚本来输出给定行的活动预处理条件,每行一个:
#!/usr/bin/env perl
#
# ppcond.pl - find active preprocessing conditionals
# usage: ppcond.pl file.c line_no
use warnings;
use diagnostics;
use strict;
my ($file, $line) = @ARGV;
my $line_number = 1;
my @ppc_stack = ();
open my $FILE, '<', $file
or die "cannot open $file for reading: $!";
while (<$FILE>) {
if ($line_number++ > $line) {
print @ppc_stack;
last;
}
if (/^\s*#\s*(if|ifdef|ifndef)/) {
push @ppc_stack, $_;
}
elsif (/^\s*#\s*elif/) {
$ppc_stack[$#ppc_stack] = $_;
}
elsif (/^\s*#\s*else/) {
$ppc_stack[$#ppc_stack] = "NOT $ppc_stack[$#ppc_stack]";
}
elsif (/^\s*#\s*endif/) {
pop @ppc_stack;
}
}
close $FILE;
从vim中调用它很容易,但将它重写为vim函数而不是perl的shell会很好。我的vim-fu尚未发展到足以解决这个问题。主人甚至可以弹出一个带有结果的上下文窗口吗?
答案 0 :(得分:2)
这应该可以解决问题:
function! ConditionalsInPlay()
let ppc_stack=[]
for cline in range(1, line('.'))
let str = getline(cline)
if (match(str, '\v^\s*#\s*(if|ifdef|ifndef)') >= 0)
let ppc_stack += [str]
elseif (match(str, '\v^\s*#\s*elif') >= 0)
let ppc_stack[-1] = str
elseif (match(str, '\v^\s*#\s*else') >= 0)
let ppc_stack[-1] = 'NOT ' . ppc_stack[-1]
elseif (match(str, '\v^\s*#\s*endif') >= 0)
call remove(ppc_stack, len(ppc_stack) - 1)
endif
endfor
echo string(ppc_stack)
endfunction