ctags душит исходный файл с несбалансированными скобками из-за #ifdef - PullRequest
2 голосов
/ 13 марта 2011

Я использую ctags для создания файла tags для проекта C, над которым я работаю, но в этом файле отсутствуют многие функции.По-видимому, это вызвано несбалансированными скобками в исходных файлах из-за использования #ifdef.(Упрощенный) пример:

#include <stdio.h>

struct mystruct {
        long member;
#ifndef _MSC_VER
}__attribute__ ((packed));
#else /* _MSC_VER */
};
#pragma pack(pop)
#endif /* _MSC_VER */

char* greeting_text(){
  return "Hello world\n";
}

int main( int argc, const char* argv[] ){
  char * greeting = greeting_text();
  printf(greeting);
  return 0;
}

Это компилируется и безупречно работает с gcc -Wall в Linux.Однако, если я проанализирую его с помощью ctags problem.c, файл tags содержит только записи для mystruct - функции отсутствуют.

ctags --verbose отчеты:

OPENING problem.c as C language file
problem.c: unexpected closing brace at line 8
problem.c: retrying file with fallback brace matching algorithm
OPENING problem.c as C language file
problem.c: unexpected closing brace at line 8

так что, очевидно, ctags не нравятся приемы препроцессора в файле.

Есть ли способ заставить ctags справиться с этим?

В справочной странице ctags даже явно упоминается эта проблема, но указывает ctags может обойти это.Однако это не работает ...

Это с Exuberant Ctags 5.8 (пакет Debian 1: 5.8-4).

Редактировать:

Мне также интересны альтернативы ctags, которые обрабатывают подобные конструкции.

Ответы [ 4 ]

2 голосов
/ 02 сентября 2011

Из-за проблем с ctags я вместо этого использовал cscope .

Хотя он не идеален, он обрабатывает макросы лучше, чем ctags, и может интегрироваться с vim так же, как ctags (см. http://vimdoc.sourceforge.net/htmldoc/if_cscop.html#:cscope).

1 голос
/ 16 января 2015

Вы можете запустить инструмент unifdef, чтобы выборочно (и временно) заменить неактивную часть кода пустыми строками (unifdef -l -U_MSC_VER).В результате получается

#include <stdio.h>

struct mystruct {
        long member;

}__attribute__ ((packed));





char* greeting_text(){
  return "Hello world\n";
}

int main( int argc, const char* argv[] ){
  char * greeting = greeting_text();
  printf(greeting);
  return 0;
}

Ctags не имеет проблем с синтаксическим анализом, и номера строк остаются прежними (важно, если вы создаете поиск ctags по номеру строки):

$ cat tags
!_TAG_FILE_FORMAT       2       /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED       1       /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR    Darren Hiebert  /dhiebert@users.sourceforge.net/
!_TAG_PROGRAM_NAME      Exuberant Ctags //
!_TAG_PROGRAM_URL       http://ctags.sourceforge.net    /official site/
!_TAG_PROGRAM_VERSION   5.6     //
greeting_text   y.c     /^char* greeting_text(){$/;"    f
main    y.c     /^int main( int argc, const char* argv[] ){$/;" f
member  y.c     /^        long member;$/;"      m       struct:mystruct file:
mystruct        y.c     /^struct mystruct {$/;" s       file:

unifdefдоступен во многих операционных системах как пакет (например, FreeBSD, различные дистрибутивы Linux, Cygwin).Домашняя страница: http://dotat.at/prog/unifdef/

1 голос
/ 21 марта 2011

Вы можете попробовать переписать код так, чтобы была только одна закрывающая фигурная скобка, например:

struct mystruct {
        long member;
}
#ifndef _MSC_VER
__attribute__ ((packed))
#endif
;
#ifdef _MSC_VER
#pragma pack(pop)
#endif /* _MSC_VER */

Конечно, вы можете определить некоторые удобные макросы, чтобы их было легче читать.

1 голос
/ 15 марта 2011

Я бы попробовал запустить препроцессор (gcc -E) для файлов перед передачей их в ctags. Даст ли это хороший результат, я не уверен, но стоит попробовать. Конечно, тогда должны появиться все компоненты вашего кода, но распознают ли ctags ссылки на другие файлы, которые gcc оставляет в выводе? Не уверен.

...