Вопрос

When I edit C source files, I often find myself wanting to know which C preprocessing conditionals are effective at a given line, i.e. in

#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 */

You get the idea. I wrote a little perl script to output the active preprocessing conditionals at a given line, one per line:

#!/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;

It's easy to call this from vim, but it would be nice to have it rewritten as a vim function and not shell out to perl. My vim-fu is not yet developed enough to tackle this. Can a master even make a context window pop up with the result?

Это было полезно?

Решение

This should do the trick:

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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top