Создание списка глобальных переменных из исходного файла C ++ - PullRequest
4 голосов
/ 18 января 2012

Я сейчас работаю над проблемой, ее постановка - сгенерировать текстовый файл со списком всех объявленных глобальных переменных в файле .CPP.

Я пришел к нескольким идеям, первая:

Попробуйте использовать ctags, поэтому я написал небольшой скрипт:

while read line
do
echo $line
printf "%s" $line >> report.txt
ctags -x --c++-kinds=v --file-scope=no "{$line}" | sort | sed "/const/d" | awk '{printf " %s", $1}' >> report.txt
printf "\n" >> report.txt
done < cpp_source_file_list.txt

Этот фрагмент кода получает имя файла исходного файла .cpp из cpp_source_file_list.txt, сканирует его на наличие глобальных переменных (игнорируя const) и пишет отчет «filename [список переменных]». Основная проблема, с которой я столкнулся, заключается в том, что ctags действует очень странно, игнорируя в некоторых случаях типы STL.

Например, он может исключать строку ike "vector v;", но включать "std :: vector v;".

Есть ли способы исправить такую ​​проблему? Попытка использовать дополнительный ключ ctags -I ./id.txt и создать вручную список идентификаторов для переопределения, но это также приводит к неверным результатам.

Второй способ:

Использовать команду nm, например:

nm builtsource.o | grep '[0-9A-Fa-f]* [BCDGRS]'

Но в этом случае я получаю ненужную информацию, например:

0000000000603528 B M 
0000000000603548 B N 
0000000000603578 B _ZSt3cin@@GLIBCXX_3.4 <- (!)
0000000000603579 B _ZSt4cout@@GLIBCXX_3.4 <- (!)
0000000000603748 B t 

И теперь я понятия не имею, как заставить один из этих методов получить правильную информацию о списке объявленных глобальных переменных из произвольного исходного файла .cpp. Я был бы рад услышать любые предложения по этой проблеме.

Ответы [ 3 ]

1 голос
/ 31 января 2012

Вы можете использовать Doxygen для реализации этого. Doxygen может проанализировать файл C ++ и сгенерировать файл XML, который фиксирует все переменные, встречающиеся в файле. В частности, если вы установите следующие параметры конфигурации:

EXTRACT_ALL= YES
GENERATE_TAGFILE= doxygen.tag

С учетом входного файла, например:

#include <vector>

using namespace std;

std::vector<int> s1;
vector s2;

Вы можете сгенерировать выходной файл doxygen.tag со следующим содержимым:

<?xml version='1.0' encoding='ISO-8859-1' standalone='yes' ?>
<tagfile>
  <compound kind="file">
    <name>input.cpp</name>
    <path>C:/Users/haney/tmp/tmp55/</path>
    <filename>input_8cpp</filename>
    <namespace>std</namespace>
    <member kind="variable">
      <type>std::vector&lt; int &gt;</type>
      <name>s1</name>
      <anchorfile>input_8cpp.html</anchorfile>
      <anchor>93b3bd32f5b6bff31bc4052716ddd444</anchor>
      <arglist></arglist>
    </member>
    <member kind="variable">
      <type>vector</type>
      <name>s2</name>
      <anchorfile>input_8cpp.html</anchorfile>
      <anchor>8feb4a508135e43a72f227568b755a07</anchor>
      <arglist></arglist>
    </member>
  </compound>
  <compound kind="namespace">
    <name>std</name>
    <filename>namespacestd.html</filename>
  </compound>
</tagfile>

Получив файл XML, вы сможете извлечь информацию, которую ищете.

0 голосов
/ 31 января 2012

Вы можете рассмотреть возможность использования GCC-XML , возможно, с чем-то другим (например, pygccxml ), чтобы упростить навигацию. Я успешно использовал эту комбинацию для подобных целей извлечения кода.

0 голосов
/ 18 января 2012

Другой возможностью будет разработка плагина GCC или расширения MELT для этой конкретной цели. Вам нужно будет понять некоторые детали внутренних представлений GCC (Gimple и Tree).

Преимущество настройки GCC (с плагином в C или расширением в MELT) заключается в том, что вы работаете с точными внутренними компонентами компилятора (после предварительной обработки и анализа). Однако это потребует некоторых усилий.

...