2012-01-18 9 views
4

私は現在、問題、そのステートメントに取り組んでいます - .CPPファイル内の宣言されたすべてのグローバル変数のリストを含むテキストファイルを生成します。C++ソースファイルからグローバル変数のリストを作成

私は最初の1、いくつかのアイデアを思い付いた: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_source_file_listからの.cppソースファイルのファイル名を取得します.txt、グローバル変数(constを無視する)をスキャンし、 "filename [変数のリスト]のレポートを書く。 私が遭遇した主な問題は、ctagsがSTL型のいくつかのケースでは非常に奇妙な無視をするということです。

Eg it除外することができます行ike "ベクトル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 [email protected]@GLIBCXX_3.4 <- (!) 
0000000000603579 B [email protected]@GLIBCXX_3.4 <- (!) 
0000000000603748 B t 

そして今、私はどのように考えています任意の.cppソースファイルから宣言されたグローバル変数のリストに関する正しい情報を受け取るために、これらのメソッドの1つを実装する。私はこの問題の提案を聞いてうれしいです。

+2

C++は構文解析が難しいため、ctagsのような外部ツールを使用する必要があります。しかし、 'const'のためのseddingは、const globalを無視して、どこにでも置くことはできません。constへの非constポインタ、または 'constant'のような名前さえできます。 – Kos

+0

確かに、私は正規表現を埋め込むことに同意します、それは一種の純粋な解決策でした。 – Twd1024

+0

あなたは完全なASTを与えることができる良いC + +パーサで家にいるでしょう。 Eclipse CDTにはまともなパーサがありますが、スタンドアロンで動作するようには設計されていません(私を逃れてしまう理由で)。それを使用するには、Eclipseプラグインを作成する必要があります。私はGCCまたはClangの内部を使ってASTを生成することがどれほど難しいだろうかと疑問に思っています – Kos

答えて

0

別の可能性は、その正確な目的のためにGCCプラグインまたはMELT拡張を開発することです。 GCCの内部表現(GimpleとTree)の詳細を理解する必要があります。

GCC(CのプラグインまたはMELTの拡張機能)をカスタマイズする利点は、(プリプロセスと解析の後で)正確なコンパイラ内部で作業することです。しかし、これはあなたにいくつかの努力を必要とします。

0

GCC-XMLを使用することをお勧めします。ナビゲートするのが簡単になるように、恐らく上に何か他のもの(pygccxmlなど)を入れてください。私は、同様のコード抽出の目的でこの組み合わせをうまく使用しました。

1

Doxygenを活用して実装することができます。 Doxygenは、C++ファイルを解析し、ファイル内で検出されたすべての変数をキャプチャするXMLファイルを生成できます。あなたは次の構成オプションを設定した場合は具体的には、:一度

<?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> 

:あなたは以下の内容を出力doxygen.tagファイルを生成することができます

#include <vector> 

using namespace std; 

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

EXTRACT_ALL= YES 
GENERATE_TAGFILE= doxygen.tag 

は次のように入力ファイルを考えますあなたはXMLファイルを持っているので、探している情報を抽出できるはずです。

+0

素晴らしい解決策をありがとう。 Doxyに "kind"属性が "file"または "variable"とは異なるブロックを出力しないようにする方法はありますか?メンバー種別が "function"、 "typedef"などと等しい数量のブロックを取得する状況があります。これらを.tagファイルで取り除くとよいでしょう。 – fyodorananiev

+0

誰もが:Doxygentoは "int a(0);"のように宣言された変数を認識します。関数 "a"として "(0)"と入力します。 – fyodorananiev

関連する問題