2013-11-29 4 views
1

Когда я редактирую C исходные файлы, я часто хотел бы знать, какие 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. Мой vim-fu еще недостаточно развит, чтобы справиться с этим. Может ли мастер создать окно контекста с результатом?

+5

При всем должном уважении, просто просят людей, чтобы перевести сценарий с Perl, чтобы Vim не так, как это сделано здесь. Подумайте, используя эту возможность, чтобы узнать сам сценарий Vim? Может, до тех пор, пока вы не застрянете? – glts

+0

@glts, видимо вы и я ошибаемся. – romainl

+0

@glts Ну, я считаю, что я не нарушал дух SO. Я написал фрагмент perl сегодня через час, подумав некоторое время о том, как решить проблему. Поэтому я сам решил 90% проблемы и попросил оставшиеся 10%, где мне нужна помощь. – Jens

ответ

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 
+0

Работает как очарование! Спасибо за урок по сценарию vim :-) – Jens