Vimのカバレッジを見る

この記事はVim Advent Calendar 2017の2日目の記事です。

Vimカバレッジcoveralls.iocodecov.io上で見ることができますが、手元で見たくなることもあると思います。

そんな時はMakefileに書いてある通り、次のようにしてカバレッジを計測し、生成されたhtmlから見ることができます。

# Vimのリポジトリ直下に移動

# 各種フラグに--coverageをつけてビルド、他はお好みで
CFLAGS=--coverage LDFLAGS=--coverage ./configure --with-features=huge && make

cd ./src

# まずはゼロカバレッジの初期データを作る
lcov -c -i -b . -d objects -o objects/coverage_base.info

# テストを走らせてカバレッジ情報を作る
make test
lcov -c -b . -d objects/ -o objects/coverage_test.info

# 初期データとテストのカバレッジ情報を結合する
lcov -a objects/coverage_base.info -a objects/coverage_test.info -o objects/coverage_total.info

# 結果をobjects/index.htmlとして生成する
genhtml objects/coverage_total.info -o objects

ビルド時に--coverageをつけることでgcovが有効になり、実行された行が記録されるようになります。
lcov(と付属のgenhtml)はそのフロントエンドツールです。

さて、実行された行が記録されるということは、Vimで特定の操作をした際にどの関数が呼ばれたのか調べることができる、ということです。

しかし、gcovはプログラムの終了直前に保存処理を行うため、目的の操作だけの結果を知るには

  1. Vimの起動
  2. コマンドやキー入力
  3. Vimの終了

の順で操作をしつつ、1と3は除外する必要があります。
幸いgenhtmlには-b(--baseline-file)オプションがあるので次のようにすれば実現できます。

# 上と同じ
lcov -c -i -b . -d objects -o objects/coverage_base.info

# 起動と終了のカバレッジを取得
VIMRUNTIME=../runtime ./vim --clean -c 'q'
lcov -c -b . -d objects/ -o objects/coverage_quit.info
lcov -a objects/coverage_base.info -a objects/coverage_quit.info -o objects/coverage_baseline.info

# カバレッジをリセット
lcov -z -d objects/

# 起動と:smileと終了のカバレッジを取得
VIMRUNTIME=../runtime ./vim --clean -c 'smile | q'
lcov -c -b . -d objects/ -o objects/coverage_smile.info
lcov -a objects/coverage_base.info -a objects/coverage_smile.info -o objects/coverage_result.info

# 生成されるのはcoverage_result.infoからcoverage_baseline.info分のカウントを減らした結果
genhtml -b objects/coverage_baseline.info objects/coverage_result.info -o objects

というわけで:smile*1にはsyntax.c以下のソースが使われていることがわかりました。

f:id:daisuzu:20171202170437p:plain

処理を正確に追うにはデバッガを使うのが確実だとは思いますが、ソースの構造がある程度わかっていないと難しかったりもします。

f:id:daisuzu:20171202173329p:plain

なので、さらっと概要と知りたい時やソースコードリーディングのお供にでも是非カバレッジを活用してみてください。

:smile
                            oooo$$$$$$$$$$$$oooo
                        oo$$$$$$$$$$$$$$$$$$$$$$$$o
                     oo$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$o         o$   $$ o$
     o $ oo        o$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$o       $$ $$ $$o$
  oo $ $ "$      o$$$$$$$$$    $$$$$$$$$$$$$    $$$$$$$$$o       $$$o$$o$
  "$$$$$$o$     o$$$$$$$$$      $$$$$$$$$$$      $$$$$$$$$$o    $$$$$$$$
    $$$$$$$    $$$$$$$$$$$      $$$$$$$$$$$      $$$$$$$$$$$$$$$$$$$$$$$
    $$$$$$$$$$$$$$$$$$$$$$$    $$$$$$$$$$$$$    $$$$$$$$$$$$$$  """$$$
     "$$$""""$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$     "$$$
      $$$   o$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$     "$$$o
     o$$"   $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$       $$$o
     $$$    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" "$$$$$$ooooo$$$$o
    o$$$oooo$$$$$  $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$   o$$$$$$$$$$$$$$$$$
    $$$$$$$$"$$$$   $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$     $$$$""""""""
   """"       $$$$    "$$$$$$$$$$$$$$$$$$$$$$$$$$$$"      o$$$
              "$$$o     """$$$$$$$$$$$$$$$$$$"$$"         $$$
                $$$o          "$$""$$$$$$""""           o$$$
                 $$$$o                                o$$$"
                  "$$$$o      o$$$$$$o"$$$$o        o$$$$
                    "$$$$$oo     ""$$$$o$$$$$o   o$$$$""
                       ""$$$$$oooo  "$$$o$$$$$$$$$"""
                          ""$$$$$$$oo $$$$$$$$$$
                                  """"$$$$$$$$$$$
                                      $$$$$$$$$$$$
                                       $$$$$$$$$$"
                                        "$$$""""

Press ENTER or type command to continue

*1:v8.0.1362